-- BeamNestProcess.lua by Egalware s.r.l. 2026/05/11 -- Gestione nesting automatico travi anche oblique -- Intestazioni require( 'EgtBase') _ENV = EgtProtectGlobal() EgtEnableDebug( true) -- Include ---------------------------------------------------------------------------------------------------------- -- inventario grezzi local RawInventory = { Stock = {}, ActiveBeams = {} } function RawInventory:BuildStock() if #LEN ~= #QTY then error( 'NestProcess: invalid stock data') end for i = 1, #LEN do self.Stock[#self.Stock + 1] = { dLength = LEN[i], nCount = QTY[i] } end return RawInventory end -- aggiunge una nuova barra attiva rimuovendo il corrispondente dalla lista stock disponibili function RawInventory:AddActiveBeam( nStockIndex) local CurrentStock = self.Stock[nStockIndex] -- se barra disponibile posso aggiungerla a quelle attive if CurrentStock and CurrentStock.nCount > 0 then -- update quantità a stock CurrentStock.nCount = CurrentStock.nCount - 1 -- aggiungo una nuova barra attiva local NewBeam = { dTotalLength = CurrentStock.dLength, dResidual = CurrentStock.dLength, LastOffsetX = { 0, 0, 0, 0}, LastVtN = Vector3d( 1, 0, 0), NestedParts = {} } table.insert( self.ActiveBeams, NewBeam) return NewBeam end return nil end ---------------------------------------------------------------------------------------------------------- -- PartTemplates (informazioni geometriche pezzi univoci) e JobPool (lista di tutti i singoli pezzi, multipli compresi, da nestare) local PartTemplates = {} local JobPool = {} function PartTemplates:GetInfoFromPart( id, sStateWithSide) local OffsetX = {} local vtN local sInfo = EgtGetInfo( id, sStateWithSide) if not sInfo then return end local Info = EgtSplitString( sInfo, ';') OffsetX = EgtSplitString( Info[1], ',') vtN = VectorFromString( Info[2]) -- si convertono gli offset in numeri for i = 1, #OffsetX do OffsetX[i] = tonumber( OffsetX[i]) or 0 end return OffsetX, vtN end function PartTemplates:AddPart( id) self[id] = {} self[id].dLength = EgtGetInfo( id, 'L', 'd') self[id].States = {} local States = { '1000', '0010', '1000_INV', '0010_INV' } for _, sState in ipairs(States) do local OffsetXHead, vtNHead = self:GetInfoFromPart( id, 'ALT' .. sState .. '_H') local OffsetXTail, vtNTail = self:GetInfoFromPart( id, 'ALT' .. sState .. '_T') if OffsetXHead or OffsetXTail then if not OffsetXHead then OffsetXHead = { 0, 0, 0, 0} vtNHead = Vector3d( 1, 0, 0) end if not OffsetXTail then OffsetXTail = { 0, 0, 0, 0} vtNTail = Vector3d( -1, 0, 0) end self[id].States[sState] = {} local State = self[id].States[sState] State.Head = { OffsetX = OffsetXHead, vtN = vtNHead } State.Tail = { OffsetX = OffsetXTail, vtN = vtNTail } end end end -- creazione combinata (si cicla una sola volta) di entrambe le tabelle local function BuildPartTemplatesAndJobPool() for id, nCount in pairs( PART) do PartTemplates:AddPart( id) for _ = 1, nCount do table.insert( JobPool, { id = id, bNested = false}) end end return PartTemplates, JobPool end ---------------------------------------------------------------------------------------------------------- -- script principale -- costruzione lista grezzi a stock disponibili RawInventory:BuildStock() -- costruzione lista pezzi template con proprietà geometriche e lista pezzi fisici da nestare BuildPartTemplatesAndJobPool() -- loop principale: scorre le barre, si già attive che a stock, e le riempie nel modo migliore possibile while true do local BestMove local HighestScore = GEO.INFINITO -- 1 Si provano le barre già attive -- 2 Si provano le barre ancora a stock for i = 1, #RawInventory.Stock do if RawInventory.Stock[i].nCount > 0 then end end -- 3 Procedi con nesting end