-- PanelSaw.lua by Egalware s.r.l. 2025/09/02 -- Creazione lista taglio e/o programmi di taglio per sezionatrici -- Intestazioni require( 'EgtBase') -- Dati local WL = require ( 'WallLib') local PanelSaw = {} local function GetPanelList() local PanelList = {} local idMachGroup = EgtGetFirstMachGroup() local nMachGroupCount = EgtGetMachGroupCount() -- nessun MachGroup ossia nessun pannello: si esce subito if ( not idMachGroup) or ( nMachGroupCount == 0) then return nil end -- per ogni MachGroup si estraggono le informazioni del pannello for i = 1, nMachGroupCount do local vPartInfo = EgtSplitString( EgtGetInfo( idMachGroup, 'PART1', 's')) local idPart = vPartInfo[1] table.insert( PanelList, {}) PanelList[i].dLength = EgtGetInfo( idMachGroup, 'PANELLEN', 'd') PanelList[i].dWidth = EgtGetInfo( idMachGroup, 'PANELWIDTH', 'd') PanelList[i].dThickness = EgtGetInfo( idMachGroup, 'PANELHEIGHT', 'd') PanelList[i].sMaterialFullName = EgtGetInfo( idMachGroup, 'MATERIAL', 's') or '0000-MATERIAL' PanelList[i].sMaterialPlusThickness = PanelList[i].sMaterialFullName .. '_' .. tostring( string.format( '%.1f', PanelList[i].dThickness)) local vMaterialInfo = EgtSplitString( PanelList[i].sMaterialFullName, '-') PanelList[i].idMaterial = vMaterialInfo[1] PanelList[i].idProd = EgtGetInfo( idMachGroup, 'PRODID', 'i') PanelList[i].idPatt = EgtGetInfo( idMachGroup, 'PATTID', 'i') PanelList[i].nPdn = EgtGetInfo( idPart, 'PDN', 'i') PanelList[i].sName = EgtGetInfo( idPart, 'NAM', 's') PanelList[i].sDescription = PanelList[i].sName local sGrainInfo = EgtGetInfo( idPart, "GRAINDIRECTION", 's') PanelList[i].sGrainDirection = 'None' if sGrainInfo then local bUseGrain = ( string.sub( sGrainInfo, 7) == '1') local sGrainDirection = string.sub( sGrainInfo, 1, 5) if bUseGrain then if sGrainDirection == "1,0,0" then PanelList[i].sGrainDirection = 'Length' elseif sGrainDirection == "0,1,0" then PanelList[i].sGrainDirection = 'Width' end end end -- in questa modalità ogni MachGroup è 1 pezzo, non esistono multipli -- TODO valutare se raggruppare i pannelli uguali per la cutting list PanelList[i].nQuantity = 1 -- TODO le informazioni di edgebanding devono arrivare dal btl PanelList[i].sEdgeMaterialLeft = '' PanelList[i].sEdgeMaterialRight = '' PanelList[i].sEdgeMaterialTop = '' PanelList[i].sEdgeMaterialBottom = '' -- TODO il barcode deve arrivare dal btl PanelList[i].sBarcode = '' idMachGroup = EgtGetNextMachGroup( idMachGroup) end return PanelList end local function GetSheetList() local SheetList = { { dLength = 2800, dWidth = 2070, dThickness = 8, }, { dLength = 2800, dWidth = 2070, dThickness = 18, } } return SheetList end local function GetProjectInfo() local ProjectInfo = {} local idBtlInfo = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL _, ProjectInfo.sProjectName = EgtSplitPath( EgtGetInfo( idBtlInfo, 'PROJECTNAME', 's') or '') return ProjectInfo end local function BuildCuttingList_Cutty( PanelList, SheetList, ProjectInfo) -- se il numero di pezzi supera il limite, si devono creare più liste local nMaxPanelsCount = 30 local SplittedPanelList = WL.SplitTableInChunks( PanelList, nMaxPanelsCount) local LinesToWriteList = {} for nCurrentPanelList = 1, #SplittedPanelList do local Lines = {} local CurrentPanelList = SplittedPanelList[nCurrentPanelList] LinesToWriteList[nCurrentPanelList] = {} local F0 = { Header = { 'F0'}, HeaderPlaceholders = { '%-53s'}, Values = { ' 7.70', '210700', '150300'}, ValuesPlaceholders = { '%s', '%s', '%s'} } local F0b = { Header = { 'F0b', '""', '""', '""', '""'}, HeaderPlaceholders = { '%s', '%s', '%s', '%s', '%s'} } local F1 = { Header = { 'F1', CurrentPanelList[1].dThickness, 0, 0, 0, ''}, HeaderPlaceholders = { '%s', '%.3f', '%.3f', '%.3f', '%.3f', '%-20s'}, ValuesList = {}, ValuesPlaceholders = { '%.3f', '%.3f', '%d', '%d', '%d', '%-29d', '%-50s', '%d', '%.3f', '%d', '%d', '%d', '%d'}, } for i = 1, #SheetList do F1.ValuesList[i] = { SheetList[i].dLength, SheetList[i].dWidth, 99, 200, 1, 1, CurrentPanelList[1].sMaterialFullName, 0, 1, 0, 0, 0, 0} end local F2 = { Header = { 'F2', 0, 0, 0}, HeaderPlaceholders = { '%s', '%d', '%d', '%d'}, ValuesList = {}, ValuesPlaceholders = { '%.3f', '%.3f', '%d', '%d', '%d', '%d', '%d', '%-20s', '%d', '%d', '%d', '%d', '%-50s', '%d', '%d', '%d', '%d', '%d', '%d', '%.3f', '%d', '%d', '%-85d', '%.3f', '%.3f'}, } for i = 1, #CurrentPanelList do local nGrain = 0 if PanelList[i].sGrainDirection == 'Length' then nGrain = 1 elseif PanelList[i].sGrainDirection == 'Width' then nGrain = 1 CurrentPanelList[i].dLength, CurrentPanelList[i].dWidth = CurrentPanelList[i].dWidth, CurrentPanelList[i].dLength end F2.ValuesList[i] = { CurrentPanelList[i].dLength, CurrentPanelList[i].dWidth, CurrentPanelList[i].nQuantity, 0, nGrain, 0, 0, CurrentPanelList[i].nPdn, 0, 0, 0, 0, CurrentPanelList[i].sDescription, 0, 0, 0, 0, 1, 0, 1500, 0, 0, 0, 0, 0} end local F7 = { Header = { 'F7', 3052, 0}, HeaderPlaceholders = { '%s', '%s', '%d'}, ValuesList = { { 218, 436}, { 167, 669}, { 204, 408}, { 204, 204}, { 204, 204}, { 209, 209}, { 167, 167}, { 213, 213}, { 229, 229}, { 164, 164}, { 150, 150} }, ValuesPlaceholders = { { '%s', '%s'}, { '%s', '%s'}, { '%s', '%s'}, { '%s', '%s'}, { '%s', '%s'}, { '%s', '%s'}, { '%s', '%s'}, { '%s', '%s'}, { '%s', '%s'}, { '%s', '%s'}, { '%s', '%s'} } } local F7b = { Header = { 'F7b', 0, 0, 0, 0}, HeaderPlaceholders = { '%s', '%.3f', '%.3f', '%.3f', '%.3f'}, Values = {}, ValuesPlaceholders = {} } local F8 = { Header = { 'F8', 0, 0, 20, 20, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, HeaderPlaceholders = { '%s', '%.3f', '%.3f', '%d', '%d', '%d', '%d', '%.3f', '%d', '%d', '%d', '%d', '%d', '%d', '%.3f', '%d', '%d', '%d', '%d', '%d', '%d', '%.3f', '%.3f', '%.3f'} } local F9 = { Header = { 'F9', 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4.3, 0, 0, 0, 2, 0, 2450, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, HeaderPlaceholders = { '%s', '%d', '%.3f', '%d', '%.3f', '%.3f', '%.3f', '%.3f', '%.3f', '%d', '%d', '%.3f', '%d', '%d', '%d', '%d', '%.3f', '%.3f', '%d', '%d', '%.3f', '%.3f', '%.3f', '%.3f', '%d', '%d', '%.3f', '%.3f'} } local F3 = { Header = { 'F3'}, HeaderPlaceholders = { '%s'} } local E0 = { Header = { 'E0'}, HeaderPlaceholders = { '%s'} } -- F0 table.insert( Lines, string.format( table.concat( F0.HeaderPlaceholders, ' '), table.unpack( F0.Header))) table.insert( Lines, string.format( table.concat( F0.ValuesPlaceholders, ' '), table.unpack( F0.Values))) -- linea vuota table.insert( Lines, '') -- F0b table.insert( Lines, string.format( table.concat( F0b.HeaderPlaceholders, ' '), table.unpack( F0b.Header))) -- linea vuota table.insert( Lines, '') -- F1 - sheets table.insert( Lines, string.format( table.concat( F1.HeaderPlaceholders, ' '), table.unpack( F1.Header))) for i = 1, #F1.ValuesList do local Values = F1.ValuesList[i] local Placeholders = F1.ValuesPlaceholders table.insert( Lines, string.format( table.concat( Placeholders, ' '), table.unpack( Values))) end -- linea vuota table.insert( Lines, '') -- F2 - panels table.insert( Lines, string.format( table.concat( F2.HeaderPlaceholders, ' '), table.unpack( F2.Header))) for i = 1, #F2.ValuesList do local Values = F2.ValuesList[i] local Placeholders = F2.ValuesPlaceholders table.insert( Lines, string.format( table.concat( Placeholders, ' '), table.unpack( Values))) end -- linea vuota table.insert( Lines, '') -- F7 table.insert( Lines, string.format( table.concat( F7.HeaderPlaceholders, ' '), table.unpack( F7.Header))) for i = 1, #F7.ValuesList do local Values = F7.ValuesList[i] local Placeholders = F7.ValuesPlaceholders[i] table.insert( Lines, string.format( table.concat( Placeholders, ' '), table.unpack( Values))) end -- linea vuota table.insert( Lines, '') -- F7b table.insert( Lines, string.format( table.concat( F7b.HeaderPlaceholders, ' '), table.unpack( F7b.Header))) -- linea vuota table.insert( Lines, '') -- F8 table.insert( Lines, string.format( table.concat( F8.HeaderPlaceholders, ' '), table.unpack( F8.Header))) -- linea vuota table.insert( Lines, '') -- F9 table.insert( Lines, string.format( table.concat( F9.HeaderPlaceholders, ' '), table.unpack( F9.Header))) -- linea vuota table.insert( Lines, '') -- F3 table.insert ( Lines, string.format( table.concat( F3.HeaderPlaceholders, ' '), table.unpack( F3.Header))) -- E0 table.insert( Lines, string.format( table.concat( E0.HeaderPlaceholders, ' '), table.unpack( E0.Header))) -- linea vuota table.insert( Lines, '') LinesToWriteList[nCurrentPanelList] = Lines end return LinesToWriteList end local function BuildCuttingList_Homag( PanelList, ActualSheetList, ProjectInfo) local LinesToWriteList = {} local sExtension = 'csv' local Lines = {} local Header = { Values = { 'Description', 'Quantity', 'Length', 'Width', 'Material', 'Grain', 'EdgeLeft', 'EdgeRight', 'EdgeTop', 'EdgeBottom', 'OrderNumber', 'BarCode'}, ValuesPlaceholders = { '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'} } local Panels = { ValuesList = {}, ValuesPlaceholders = { '%s', '%d', '%.1f', '%.1f', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' } } for i = 1, #PanelList do local sGrain = PanelList[i].sGrainDirection -- TODO questo dipenderà dalla lingua dell'esportazione; andrà fatto un tipo di esportazione specifica per ogni lingua (es: HOMAG_NL, HOMAG_ENG, ...) if sGrain == 'None' then sGrain = 'Geen' elseif sGrain == 'Length' then sGrain = 'Lengte' elseif sGrain == 'Width' then sGrain = 'Breedte' end Panels.ValuesList[i] = { PanelList[i].sDescription, PanelList[i].nQuantity, PanelList[i].dLength, PanelList[i].dWidth, PanelList[i].sMaterialPlusThickness, sGrain, PanelList[i].sEdgeMaterialLeft, PanelList[i].sEdgeMaterialRight, PanelList[i].sEdgeMaterialTop, PanelList[i].sEdgeMaterialBottom, ProjectInfo.sProjectName, PanelList[i].sBarcode} end -- Intestazione table.insert( Lines, string.format( table.concat( Header.ValuesPlaceholders, ','), table.unpack( Header.Values))) -- Lista Pannelli for i = 1, #Panels.ValuesList do local Values = Panels.ValuesList[i] local Placeholders = Panels.ValuesPlaceholders table.insert( Lines, string.format( table.concat( Placeholders, ','), table.unpack( Values))) end LinesToWriteList[1] = Lines return LinesToWriteList, sExtension end local function BuildCuttingList( PanelList, sOutputType) local LinesToWriteList = {} local sExtension = '' local SheetList = GetSheetList() local ProjectInfo = GetProjectInfo() local dRequiredThickness = PanelList[1].dThickness -- solo gli sheets dello spessore corretto vanno considerati local ActualSheetList = {} for i = 1, #SheetList do if abs( SheetList[i].dThickness - dRequiredThickness) < 10 * GEO.EPS_SMALL then ActualSheetList[#ActualSheetList+1] = { dLength = SheetList[i].dLength, dWidth = SheetList[i].dWidth, dThickness = SheetList[i].dThickness, sMaterial = SheetList[i].sMaterial } end end -- Casadei if sOutputType == 'CUTTY' then LinesToWriteList = BuildCuttingList_Cutty( PanelList, ActualSheetList, ProjectInfo) -- Homag elseif sOutputType == 'HOMAG' then LinesToWriteList, sExtension = BuildCuttingList_Homag( PanelList, ActualSheetList, ProjectInfo) end return LinesToWriteList, sExtension end -- restituisce i pannelli raggruppati per coppia materiale-spessore univoca local function GroupByMaterial( PanelList) local PanelsGroupedByMaterial = {} for i = 1, #PanelList do local idMaterial = PanelList[i].idMaterial local dMaterialThickness = PanelList[i].dThickness -- si crea una chiave unica dalla coppia local key = idMaterial .. "_" .. tostring( dMaterialThickness) -- se la chiave non esiste già nella tabella, si crea if not PanelsGroupedByMaterial[key] then PanelsGroupedByMaterial[key] = {} end -- aggiunta del pezzo corrente al gruppo chiave corrispondente table.insert( PanelsGroupedByMaterial[key], PanelList[i]) end return PanelsGroupedByMaterial end function PanelSaw.GenerateCuttingList( sOutputType) local PanelList = GetPanelList() local PanelsGroupedByMaterial = GroupByMaterial( PanelList) for key, PanelListSingleMaterial in pairs( PanelsGroupedByMaterial) do -- path in cui scrivere i file local sCurrentNgePath, sCurrentNgeName = EgtSplitPath( EgtGetCurrFilePath()) if sOutputType then -- costruzione lista istruzioni local LinesToWriteList, sExtension = BuildCuttingList( PanelListSingleMaterial, sOutputType) for i = 1, #LinesToWriteList do -- scrittura file local sFilename = sCurrentNgePath .. 'CutList-' .. sCurrentNgeName .. '-' .. key .. '-' .. i .. sOutputType sFilename = sFilename:gsub( '%.', '_') -- aggiunta eventuale estensione sFilename = sFilename .. '.' .. sExtension local hFile, nFileErr = io.open( sFilename, 'w') if not hFile then EgtOutLog( 'Error creating cutting list : IO error ' .. tostring( nFileErr)) return false end hFile:write( table.concat( LinesToWriteList[i], "\n")) hFile:close() end -- se nessun tipo si deve scrivere un json semplice else end end return end return PanelSaw