-- 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 local sLog = 'BatchProcess : ' .. NEST.FILE .. ', ' .. NEST.MACHINE .. ', ' .. NEST.LEN .. ', ' .. NEST.WIDTH 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 -- 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 -- 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 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') _G.package.loaded.WallLib = nil local WL = require( 'WallLib') _G.package.loaded.WProcessLapJoint = nil local LapJoint = require( 'WProcessLapJoint') -- Inizializzo contatori errori e avvisi local nErrCnt = 0 local nWarnCnt = 0 -- inizio nesting automatico EgtAutoNestStart() local OUTLINE = "Outline" -- creo pannello del materiale local SheetPartId = EgtGroup(GDB_ID.ROOT) EgtSetName(SheetPartId, "Sheet") local SheetLayerId = EgtGroup(SheetPartId) EgtSetName(SheetLayerId, OUTLINE) local SheetOutlineId = EgtRectangle2P(SheetLayerId, Point3d(0,0,0), Point3d(NEST.LEN, NEST.WIDTH, 0), GDB_RT.GLOB) -- EgtModifyCurveThickness(SheetOutlineId, -Material.T_mm) EgtSetName(SheetOutlineId, OUTLINE) -- creo foglio per nesting EgtAutoNestAddSheet( SheetPartId, SheetOutlineId, NEST.KERF, 0, NEST.QTY) -- EgtAutoNestAddSheet( SheetId, OutlineId, dKerf, nPriority, nCount) -- ciclo su pezzi per aggiungerli al nesting for nPartId, nCount in pairs( PART) do -- verifico se ruotare pareti -- 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 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 contorno local nOutlineLayer = EgtGetFirstNameInGroup(nPartId, "Outline") 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 if nOutline then -- aggiungo pezzo al nesting EgtAutoNestAddPart( nPartId, nOutline, false, true, 90, 0, nCount) -- EgtAutoNestAddPart( PartId, OutlineId, bCanFlip, bCanRotate, dRotStep, nPriority, nCount) end end -- aggiungo offset tra pezzi EgtAutoNestSetInterpartGap(NEST.OFFSET) -- Impostazione corner di inizio del nesting (NST_CORNER.BL, TL, BR, TR) EgtAutoNestSetStartCorner( NST_CORNER.BR) local nMaxTime = 5 -- imposto tempo di nesting e lo avvio EgtAutoNestCompute(true, NEST.TIME) -- Variabili di calcolo local nNestedParts, nParts, nSheets, nNestings, dTotFillRatio -- Attesa fine calcolo local bOk = true local nTime = 0 while bOk do bOk, 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 bOk = EgtAutoNestCancelComputation() break end end -- se nesting andato bene if bOk then -- disposizione sheet e parts local SheetId = GDB_ID.NULL local vtAdd = V_NULL() local nMachGroup = GDB_ID.NULL 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 -- creo gruppo di lavorazione local MachGroupName = NewMachGroupName() nMachGroup = EgtAddMachGroup(MachGroupName, sCurrMachName) EgtSetInfo(nMachGroup, "PANELLEN", NEST.LEN) EgtSetInfo(nMachGroup, "PANELWIDTH", NEST.WIDTH) EgtSetInfo(nMachGroup, "MATERIAL", NEST.MATERIAL) EgtSetInfo(nMachGroup, "AUTONEST", 1) nPartCount = 0 -- altrimenti pezzo else local PartId = nId nPartCount = nPartCount + 1 -- se c'e' un grezzo valido if nMachGroup and nMachGroup ~= GDB_ID.NULL then -- creo pezzo copia local nPartDuploId = EgtDuploNew( nId) EgtRotate( nPartDuploId, ORIG(), Z_AX(), dAngRot, GDB_RT.GLOB) EgtMove( nPartDuploId, Vector3d( dX, dY, 0), GDB_RT.GLOB) local PartBBox = EgtGetBBoxGlob( nPartDuploId, GDB_BB.STANDARD) local ptPos = Point3d( PartBBox:getMin():getX(), PartBBox:getMin():getY(), 0) EgtSetInfo( nMachGroup, "PART" .. nPartCount, nPartDuploId .. "," .. EgtNumToString( ptPos:getX(), 3) .. "," .. EgtNumToString( ptPos:getY(), 3) .. "," .. 0 .. "," .. 0) EgtSetInfo( nPartDuploId, "POSX", ptPos:getX()) EgtSetInfo( nPartDuploId, "POSY", ptPos:getY()) EgtSetInfo( nPartDuploId, "ROT", 0) EgtSetInfo( nPartDuploId, "FLIP", 0) end end end -- creo grezzi per ogni gruppo di lavorazione _G.WALL = {} WALL.FILE = NEST.FILE WALL.MACHINE = NEST.MACHINE WALL.FLAG = 6 -- CREATE_PANEL nMachGroup = EgtGetFirstMachGroup() while nMachGroup do EgtSetCurrMachGroup(nMachGroup) if EgtGetInfo(nMachGroup, "AUTONEST",'i') == 1 then EgtRemoveInfo(nMachGroup, "AUTONEST") EgtSetInfo(nMachGroup, "UPDATEUI", 1) dofile(EgtGetSourceDir() .. "BatchProcessNew.lua") end nMachGroup = EgtGetNextMachGroup(nMachGroup) end else EgtOutLog("Errore: nesting fallito") end EgtResetCurrMachGroup() -- nascondo rettangolo del materiale per nesting EgtErase(SheetPartId) -- EgtSaveFile("c:\\Temp\\Prova1.nge") EgtOutLog( ' +++ NestProcess completed')