-- Process.lua by Egalware s.r.l. 2024/04/02 -- Gestione calcolo disposizione e lavorazioni per Travi -- Si opera sulla macchina corrente -- 2024/04/02 PRIMA VERSIONE -- Intestazioni require( 'EgtBase') _ENV = EgtProtectGlobal() EgtEnableDebug( false) -- Imposto direttorio libreria specializzata per Travi EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua') -- Imposto direttorio strategie. N.B. Le strategie dovranno essere caricate con il nome del direttorio padre EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\Standard\\?.lua') EgtAddToPackagePath( BEAM.BASEDIR .. '\\StrategyLibs\\?.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\\BeamDataNew.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.BasicCustomerStrategies = nil _G.package.loaded.BeamExec = nil _G.package.loaded.BeamLib = nil _G.package.loaded.DiceCut = nil _G.package.loaded.FaceData = nil _G.package.loaded.FeatureLib = nil _G.package.loaded.Identity = nil _G.package.loaded.Logs = nil _G.package.loaded.MachiningLib = nil _G.package.loaded.PreSimulationLib = nil _G.package.loaded.LeadInOutLib = nil -- strategie di base sempre presenti _G.package.loaded['HEADCUT\\HEADCUT'] = nil _G.package.loaded['TAILCUT\\TAILCUT'] = nil -- libreria macchina _G.package.loaded.BeamDataNew = nil -- libreria calcolo tempo esecuzione _G.package.loaded.TimeLib = nil -- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente -- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento. -- Infatti difficile ci siano 9999 strategie. -- reset strategie caricate come librerie for i = 1, 9999 do local idSTRTemp = EgtReplaceString( EgtNumToString( i/10000, -4), '0.', '') local sLibraryToReload = "STR" .. idSTRTemp .. "\\STR" .. idSTRTemp if _G.package.loaded[sLibraryToReload] then _G.package.loaded[sLibraryToReload] = nil end end local vtCoreStrategiesNames = EgtFindAllFiles( BEAM.BASEDIR .. '\\StrategyLibs\\*.lua') for i = 1, #vtCoreStrategiesNames do local sCurrentName = EgtSplitString( vtCoreStrategiesNames[i], '.')[1] if _G.package.loaded[sCurrentName] then _G.package.loaded[sCurrentName] = nil end end -- Variabili globali PARTS = {} -- tabella contenente tutte le informazioni di ogni pezzo -- Carico i dati globali local BeamData = require( 'BeamDataNew') -- carico librerie local BeamExec = require( 'BeamExec') local BeamLib = require( 'BeamLib') -- Variabili di modulo 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, #PARTS do if PARTS[i].id == nPartId then bFound = true break end end if not bFound then table.insert( PARTS, { nInd = #PARTS + 1, id = nPartId, sName = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) end end nId = EgtGetNextSelectedObj() end if #PARTS == 0 then EgtOutBox( 'Non sono state selezionate travi', 'Lavora Travi', 'ERROR') return false else local sOut = '' for i = 1, #PARTS do sOut = sOut .. PARTS[i].sName .. ', ' end sOut = sOut:sub( 1, -3) EgtOutLog( 'Travi selezionate : ' .. sOut, 1) end -- Ne recupero e verifico le dimensioni for i = 1, #PARTS do local Ls = EgtGetFirstNameInGroup( PARTS[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 ' .. PARTS[i].sName, 'Lavora Travi', 'ERROR') return false else PARTS[i].b3PartOriginal = b3Solid end end dRawW = PARTS[1].b3PartOriginal:getDimY() dRawH = PARTS[1].b3PartOriginal:getDimZ() local vBeamErr = {} for i = 2, #PARTS do local dDimW = PARTS[i].b3PartOriginal:getDimY() local dDimH = PARTS[i].b3PartOriginal: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 .. PARTS[vBeamErr[i]].sName .. '\n' EgtDeselectPartObjs( PARTS[vBeamErr[i]].id) table.remove( PARTS, vBeamErr[i]) end EgtOutLog( sOut, 1) EgtOutBox( sOut, 'Lavora Travi', 'INFO') EgtDraw() return false end EgtDeselectAll() return true end ------------------------------------------------------------------------------------------------------------- local function GetDataConfig() -- recupero utensili dal magazzino BeamExec.GetToolsFromDB() -- TODO da gestire eventuali errori bloccanti return true end ------------------------------------------------------------------------------------------------------------- -- *** Inserimento delle travi nel grezzo *** ------------------------------------------------------------------------------------------------------------- local function MyProcessBeams() -- Determinazione minimo grezzo scaricabile BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) -- Lunghezza totale delle travi local dTotLen = 0 for i = 1, #PARTS - 1 do dTotLen = dTotLen + PARTS[i].b3PartOriginal:getDimX() end dTotLen = dTotLen + max( PARTS[#PARTS].b3PartOriginal:getDimX(), BeamData.dMinRaw) local dAddLen = BeamData.OVM_HEAD + ( #PARTS - 1) * BeamData.OVM_MID EgtOutLog( 'Ltot : '..EgtNumToString( dTotLen, 1) .. ' Lagg : '..EgtNumToString( dAddLen, 1)..' MinUnloadRaw : '.. EgtNumToString( BeamData.dMinRaw + BeamData.OVM_MID, 1), 1) -- Richiedo lunghezza del grezzo, sovramateriale di testa, forzatura verticale e ordinamento automatico secondo la lunghezza local vsVal = EgtDialogBox( 'Lavora Travi' .. ' (Ltot='..EgtNumToString( dTotLen + dAddLen + 0.5, 0).. ', Lmax='..EgtNumToString( BeamData.MAX_RAW, 0)..',MinUlr='..EgtNumToString( BeamData.dMinRaw + BeamData.OVM_MID, 0)..')', --{'Lunghezza grezzo', EgtNumToString( BeamData.STD_RAW, 0)}, -- TODO RIPRISTINARE {'Lunghezza grezzo', EgtNumToString( 0)}, {'Sovramateriale di testa', EgtNumToString( BeamData.OVM_HEAD, 0)}, {'Offset intermedio', EgtNumToString( BeamData.OVM_MID, 0)}, {'Forza sezione verticale', ' CB:true,*false'}, {'Ordina per lunghezza', ' CB:true,*false'}, {'Calcolo Lavorazioni', ' CB:*Da progetto,Ricalcolo standard,Ricalcolo IA'}) 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, BeamData.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 local dOvmMid = EgtEvalNumExpr( vsVal[3]) if not dOvmMid then local sOut = 'Offset intermedio : ' .. vsVal[3] EgtOutLog( sOut) EgtOutBox( sOut, 'Lavora Travi', 'WARNING') EgtDraw() return false end -- Sistemo sezione barra con travi local bVert = ( vsVal[4] == '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 BeamData.MAX_WIDTH2 or not BeamData.MAX_HEIGHT2 then if ( dRawW > BeamData.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BeamData.MAX_HEIGHT + 10 * GEO.EPS_SMALL) then local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. 'oltre i limiti della macchina (' .. EgtNumToString( BeamData.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BeamData.MAX_HEIGHT, 2) .. ') ' EgtOutLog( sOut) EgtOutBox( sOut, 'Lavora Travi', 'WARNING') EgtDraw() return false end else if ( dRawW > BeamData.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BeamData.MAX_HEIGHT + 10 * GEO.EPS_SMALL) and ( dRawW > BeamData.MAX_WIDTH2 + 10 * GEO.EPS_SMALL or dRawH > BeamData.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) then local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. 'oltre i limiti della macchina (' .. EgtNumToString( BeamData.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BeamData.MAX_HEIGHT, 2) .. ') ' .. 'e (' .. EgtNumToString( BeamData.MAX_WIDTH2, 2) .. ' x ' .. EgtNumToString( BeamData.MAX_HEIGHT2, 2) .. ')' EgtOutLog( sOut) EgtOutBox( sOut, 'Lavora Travi', 'WARNING') EgtDraw() return false end end -- Verifico sezione barra non troppo piccola if dRawW < BeamData.MIN_WIDTH - 10 * GEO.EPS_SMALL or dRawH < BeamData.MIN_HEIGHT - 10 * GEO.EPS_SMALL then local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. 'sotto i limiti della macchina (' .. EgtNumToString( BeamData.MIN_WIDTH, 2) .. ' x ' .. EgtNumToString( BeamData.MIN_HEIGHT, 2) .. ')' EgtOutLog( sOut) EgtOutBox( sOut, 'Lavora Travi', 'WARNING') EgtDraw() return false end -- Se richiesto, ordino le travi in senso di lunghezza crescente local bOrd = ( vsVal[5] == 'true') if bOrd then table.sort( PARTS, function( B1, B2) if abs( B1.b3PartOriginal:getDimX() - B2.b3PartOriginal:getDimX()) < 1 then return B1.nInd < B2.nInd else return B1.b3PartOriginal:getDimX() < B2.b3PartOriginal:getDimX() end end) end do local sOut = '' for i = 1, #PARTS do sOut = sOut .. PARTS[i].sName .. ', ' end sOut = sOut:sub( 1, -3) EgtOutLog( 'Travi ordinate : ' .. sOut, 1) end -- Sistemo le travi nel grezzo local bOk, sErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, nil, false) 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() BeamExec.GetProcessings( PARTS, false) BeamExec.GetCombinationMatrix( PARTS, false) BeamExec.ProcessMachinings( PARTS, false) local nErrCnt = 0 local nWarnCnt = 0 local sOutput = '' for i = 1, #RESULT do local sMsg = '' if RESULT[i].sType == 'Feature' then sMsg = RESULT[i].ChosenStrategy.sInfo elseif RESULT[i].sType == 'Part' then sMsg = RESULT[i].sMsg end sMsg = string.gsub( sMsg or '', '\n', ' ', 10) sMsg = string.gsub( sMsg or '', '\r', ' ', 10) -- trovata almeno una strategia e feature lavorata completamente if RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Completed' then sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg or '') -- trovata almeno una strategia ma nessuna applicabile oppure non trovata alcuna strategia elseif RESULT[i].sType == 'Feature' and ( ( RESULT[i].ChosenStrategy.sStatus == 'Not-Applicable') or ( not RESULT[i].ChosenStrategy.sStrategyName)) then nErrCnt = nErrCnt + 1 if #sMsg == 0 then sMsg = 'No applicable strategy found' end sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg) else -- segnalazione scarico pezzo standard, incompleto o a caduta if RESULT[i].sType == 'Part' and ( RESULT[i].nErr == -100 or RESULT[i].nErr == -101 or RESULT[i].nErr == -102) then -- nulla da segnalare -- feature incompleta e altro elseif RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Not-Completed' then nWarnCnt = nWarnCnt + 1 sMsg = 'Incomplete : Completion index ' .. RESULT[i].ChosenStrategy.dCompletionIndex .. '/5\n' .. sMsg sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg) end end end -- cancello gruppo temporaneo local idTempGroup = BeamLib.GetTempGroup() EgtErase( idTempGroup) 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 *** ------------------------------------------------------------------------------------------------------------- -- calcolo tempo esecuzione TIMER:start() EgtOutLog( ' Execution timer started') -- script principale if not MyProcessInputData() then return end -- recupero parametri generali da progetto BeamExec.GetGeneralParameters() -- creo un gruppo temporaneo dove finiranno tutte le entità che non bisogna salvare, alla fine lo si cancella BeamLib.CreateTempGroup() if not MyProcessBeams() then return end if not GetDataConfig() then return end -- Abilito Vmill EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') MyProcessFeatures() -- log tempi di esecuzione if EgtGetDebugLevel() >= 3 then TIMER:logAllElapsed() end