-- -- EEEEEEEEEE GGGGGG TTTTTTTTTTTTTT -- EEEEEEEEEE GGGGGGGGGG TTTTTTTTTTTTTT -- EEEE GGGG GGGG TTTT -- EEEE GGGG TTTT -- EEEEEEE GGGG GGGGGGG TTTT -- EEEEEEE GGGG GGGGGGG TTTT -- EEEE GGGG GGGG TTTT -- EEEE GGGG GGGG TTTT -- EEEEEEEEEE GGGGGGGGGG TTTT -- EEEEEEEEEE GGGGGG TTTT -- -- by EgalTech s.r.l. -- Libreria delle funzioni di nesting by EgalTech s.r.l. 2020/08/13 -- Tabella per definizione modulo local NestingLib = {} -- Include require( 'EgtBase') local Config = require( 'Config') local UtilityLib = require( 'UtilityLib') ------------------------------------------- PARAMETERS ------------------------------------------- local DebugCode = false local ProblematicItem = 138284 local OrderXCart = 1 -- ordini che si possono mettere su un carrello local KitXCart = 6 -- kit che si possono mettere su un carrello local CartActiveUnload = 4 -- carrelli attivi tra quelli disponibili allo scarico local TotCartUnload = 6 -- carrelli totali disponibili allo scarico -- distanza tra i rulli pressori local MXRollerDist = 400 local NWRollerDist = 300 -- dati skin local dSkinThickness = 1 -- ordinare lavorazioni per tipo o pezzo local nMachOrderType = 3 -- 1 = per tipologia lavorazione ; 2 = per pezzo ; 3 = per tipologia ordinando pezzi -- dimensione codici QR su second screen local nQRDim = 50 -- path generatore codici QR local sQRCodeGenPath = "https://qrcode.steamware.net/HOME" ------------------------------------------- ************** ------------------------------------------- -- liste lavorazioni local OutlineMachining = {} --{{".375 ROUGHER", "ROUGHER"}, {'3/8 MILLING', '1/4 MILLING'}} local HoleMachining = {} --{"HOLE", {'3/16 DRILLING', '1/4 DRILLING', '1/2 DRILLING', '1/8 DRILLING', '11/32 DRILLING', '13/32 DRILLING', -- '3/8 DRILLING', '5/16 DRILLING', '7/16 DRILLING', '17/32 DRILLING', '37/64 DRILLING'}} local RampMachining = {} -- {"RAMP", '3/8 MILLING'} --, '1/4 MILLING'}} local OutsideChamferMachining = {} -- {"COUNTERSINK", '45 DEG'} --, '1/4 MILLING'}} local InsideChamferMachining = {} -- {"COUNTERSINK", '45 DEG'} --, '1/4 MILLING'}} local CountersinkMachining = {} -- {"COUNTERSINK", '45 DEG'} --, '1/4 MILLING'}} local Pocketing = {} -- {'3/8 POCKETING', '1/4 POCKETING'} local sCurrMachName = "" local IsOffline = false -- liste lavorazioni divise per tipo ed utensile per ottimizzazione algoritmo tsp local OutlineList = {} local SmallOutlineList = {} local IntIntOutlineList = {} local SkinOutlineList = {} local IntExtOutlineList = {} local InternalOutlineList = {} local PocketingList = {} local RampList = {} local ChamferList = {} local HoleList = {} -- funzione che legge i dxf con le proprieta' dei pezzi function NestingLib.FilterPaintedParts(OrderList, materials, ErrorList) local DeleteOrder = {} for Order = 1, #OrderList do OrderList[Order].IsPaint = true local DeleteKit = {} for Kit = 1, #OrderList[Order].KitList do OrderList[Order].KitList[Kit].IsPaint = true for Part = 1, #OrderList[Order].KitList[Kit].PartList do local TempPart = OrderList[Order].KitList[Kit].PartList[Part] -- leggo le proprietà dal dxf e le imposto local MatExtCode, PdfLink, Paint, OptParameters, ErrorType, Revision = UtilityLib.readDXF(TempPart.CadFilePath, TempPart.PartExtCode, false) -- solo se trovo il materiale vado avanti per questo pezzo if ErrorType == 0 and MatExtCode then TempPart.MatExtCode = MatExtCode TempPart.OptParameters = OptParameters TempPart.OptParameters.PdfLink = PdfLink TempPart.PartRev = Revision local PaintVal = "NO" if Paint then PaintVal = "YES" end TempPart.OptParameters.PaintFlag = PaintVal -- se pezzo pitturato if Paint then PaintVal = "YES" -- cerco il suo materiale for Material = 1, #materials do if TempPart.MatExtCode == materials[Material].MatExtCode then TempPart.MatId = materials[Material].MatId -- gli do' priorita' 1 perchè i pitturati devono essere fatti per primi TempPart.Priority = 1 -- se non esiste gia' lista priorita' if #materials[Material].PriorityList == 0 then -- la creo e gli aggiungo il pezzo materials[Material].PriorityList = {{Priority = 1, PartList = {TempPart}}} else table.insert(materials[Material].PriorityList[1].PartList, TempPart) end end end else OrderList[Order].KitList[Kit].IsPaint = false OrderList[Order].IsPaint = false end elseif ErrorType == 1 then table.insert(ErrorList, {ErrType = "E.1", Uid = "PartId = " .. TempPart.PartId, Description = "Can't find DXF file"}) EgtOutLog("Part skipped: " .. TempPart.PartId) elseif ErrorType == 2 then table.insert(ErrorList, {ErrType = "E.2", Uid = "PartId = " .. TempPart.PartId, Description = "Can't find material tag in DXF"}) EgtOutLog("Part skipped: " .. TempPart.PartId) else table.insert(ErrorList, {ErrType = "E.6", Uid = "PartId = " .. TempPart.PartId, Description = "Error in DXF reading"}) EgtOutLog("Part skipped: " .. TempPart.PartId) end end end end -- ordino per modelli kit local function compareOrderExtCode(a,b) return a.OrderCod < b.OrderCod end table.sort(OrderList, compareOrderExtCode) end -- funzione che distribuisce ordini e kit sui cart function NestingLib.CreateCart(OrderList, Carts) local CurrCartIndex = 0 local OrderOnCart = 0 local KitOnCart = 0 local bFirstKit = true -- suddivido ordini e kit sui cart for Order = 1, #OrderList do -- verifico che non sia un ordine di painted parts if not OrderList[Order].IsPaint then -- leggo quantita' kit per modello local KitXOrderModel = KitXCart for Model = 1, #Config.KitXModel do if OrderList[Order].OrderCod == Config.KitXModel[Model].Model then KitXOrderModel = Config.KitXModel[Model].KitQty end end -- verifico se ho completato il carrello con il numero necessario di ordini o kit if OrderOnCart > 0 and OrderOnCart < OrderXCart and KitOnCart < KitXOrderModel then OrderOnCart = OrderOnCart + 1 table.insert(Carts[CurrCartIndex].OrderList, {OrderId = OrderList[Order].OrderId, KitList = {}}) -- se e' completo passo al carrello successivo else CurrCartIndex = CurrCartIndex + 1 table.insert(Carts, {CartIndex = CurrCartIndex, OrderList = {}}) table.insert(Carts[CurrCartIndex].OrderList, {OrderId = OrderList[Order].OrderId, KitList = {}}) KitOnCart = 0 OrderOnCart = 1 end for Kit = 1, #OrderList[Order].KitList do -- verifico che non sia un kit di painted parts if not OrderList[Order].KitList[Kit].IsPaint then -- se c'e' spazio per altri kit, lo aggiungo if KitOnCart < KitXOrderModel then table.insert(Carts[CurrCartIndex].OrderList[OrderOnCart].KitList, OrderList[Order].KitList[Kit]) KitOnCart = KitOnCart + 1 -- altrimenti creo un nuovo carrello e vi aggiungo il kit else CurrCartIndex = CurrCartIndex + 1 KitOnCart = 1 OrderOnCart = 1 table.insert(Carts, {CartIndex = CurrCartIndex, OrderList = {}}) table.insert(Carts[CurrCartIndex].OrderList, {OrderId = OrderList[Order].OrderId, KitList = {}}) table.insert(Carts[CurrCartIndex].OrderList[OrderOnCart].KitList, OrderList[Order].KitList[Kit]) end end end end end end -- -- funzione che distribuisce ordini e kit sui cart --function NestingLib.CreateCart(readBatch, Carts) -- local CurrCartIndex = 1 -- local OrderOnCart = 0 -- local KitOnCart = 0 -- -- aggiungo primo elemento -- table.insert(Carts, {CartIndex = 1, OrderList = {}}) -- -- suddivido ordini e kit sui cart -- for Order = 1, #readBatch.OrderList do -- -- verifico se ho completato il carrello con il numero necessario di ordini o kit -- if OrderOnCart < OrderXCart and KitOnCart < KitXCart then -- OrderOnCart = OrderOnCart + 1 -- table.insert(Carts[CurrCartIndex].OrderList, {OrderId = readBatch.OrderList[Order].OrderId, KitList = {}}) -- -- se e' completo passo al carrello successivo -- else -- CurrCartIndex = CurrCartIndex + 1 -- table.insert(Carts, {CartIndex = CurrCartIndex, OrderList = {}}) -- table.insert(Carts[CurrCartIndex].OrderList, {OrderId = readBatch.OrderList[Order].OrderId, KitList = {}}) -- KitOnCart = 0 -- OrderOnCart = 1 -- end -- for Kit = 1, #readBatch.OrderList[Order].KitList do -- -- se c'e' spazio per altri kit, lo aggiungo -- if KitOnCart < KitXCart then -- table.insert(Carts[CurrCartIndex].OrderList[OrderOnCart].KitList, readBatch.OrderList[Order].KitList[Kit]) -- KitOnCart = KitOnCart + 1 -- -- altrimenti creo un nuovo carrello e vi aggiungo il kit -- else -- CurrCartIndex = CurrCartIndex + 1 -- KitOnCart = 1 -- OrderOnCart = 1 -- table.insert(Carts, {CartIndex = CurrCartIndex, OrderList = {}}) -- table.insert(Carts[CurrCartIndex].OrderList, {OrderId = readBatch.OrderList[Order].OrderId, KitList = {}}) -- table.insert(Carts[CurrCartIndex].OrderList[OrderOnCart].KitList, readBatch.OrderList[Order].KitList[Kit]) -- end -- end -- end --end -- -- funzione che riordina gli ordini secondo i materiali utilizzati --function NestingLib.SortOrderList(readBatch, Orders) -- local CurrCartIndex = 1 -- local OrderOnCart = 0 -- local KitOnCart = 0 -- -- suddivido ordini e kit sui cart -- for Order = 1, #readBatch.OrderList do -- readBatch.OrderList[Order].MaterialList = {} -- for Kit = 1, #readBatch.OrderList[Order].KitList do -- for Part = 1, #readBatch.OrderList[Order].KitList[Kit].PartList do -- local TempPart = readBatch.OrderList[Order].KitList[Kit].PartList[Part] -- -- leggo le proprietà dal dxf e le imposto -- local MatExtCode, PdfLink, Paint, OptParameters, ErrorType = UtilityLib.readDXF(TempPart.CadFilePath) -- -- solo se trovo il materiale vado avanti per questo pezzo -- if ErrorType == 0 and MatExtCode then -- TempPart.MatExtCode = MatExtCode -- TempPart.PdfLink = PdfLink -- TempPart.OptParameters = OptParameters -- local PaintVal = "NO" -- if Paint then -- PaintVal = "YES" -- end -- TempPart.OptParameters.PaintFlag = PaintVal -- -- verifico se il materiale di questo pezzo e' gia' tra quelli dell'ordine -- local bMaterialFound = false -- for MaterialIndex = 1, #Orders.MaterialList do -- if readBatch.OrderList[Order].MaterialList[MaterialIndex] == MatExtCode then -- bMaterialFound = true -- end -- end -- if not bMaterialFound then -- table.insert(readBatch.OrderList[Order].MaterialList, MatExtCode) -- end -- elseif ErrorType == 1 then -- table.insert(ErrorList, {ErrType = "E.1", Uid = "PartId = " .. TempPart.PartId, Description = "Can't find DXF file"}) -- EgtOutLog("Part skipped: " .. TempPart.PartId) -- elseif ErrorType == 2 then -- table.insert(ErrorList, {ErrType = "E.2", Uid = "PartId = " .. TempPart.PartId, Description = "Can't find material tag in DXF"}) -- EgtOutLog("Part skipped: " .. TempPart.PartId) -- else -- table.insert(ErrorList, {ErrType = "E.6", Uid = "PartId = " .. TempPart.PartId, Description = "Error in DXF reading"}) -- EgtOutLog("Part skipped: " .. TempPart.PartId) -- end -- end -- end -- end -- -- local Orders = {} -- for OrderIndex = 1, #readBatch.OrderList do -- -- se lista ordinata non vuota -- if #Orders > 0 then -- local bInserted = false -- -- scorro le priorita' -- for SearchIndex = 1, #Orders do -- local bNotToBeInserted = false -- local MaxList = math.min(#readBatch.OrderList[OrderIndex].MaterialList, #Orders[SearchIndex].MaterialList) -- for MaterialIndex = 1, MaxList do -- if not bInserted and not bNotToBeInserted and -- ((tonumber(Orders[SearchIndex].MaterialList[MaterialIndex]) > tonumber(readBatch.OrderList[OrderIndex].MaterialList[MaterialIndex])) or -- (tonumber(SheetList[SearchIndex].PriorityList[PriorityIndex]) == tonumber(materials[Material].SheetList[Sheet].PriorityList[PriorityIndex]) and -- PriorityIndex == MaxList and #SheetList[SearchIndex].PriorityList > #materials[Material].SheetList[Sheet].PriorityList)) then -- table.insert(SheetList, SearchIndex, materials[Material].SheetList[Sheet]) -- bInserted = true -- elseif -- (tonumber(SheetList[SearchIndex].PriorityList[PriorityIndex]) < tonumber(materials[Material].SheetList[Sheet].PriorityList[PriorityIndex])) then -- bNotToBeInserted = true -- end -- end -- end -- if not bInserted then -- table.insert(SheetList, materials[Material].SheetList[Sheet]) -- end -- else -- table.insert(SheetList, materials[Material].SheetList[Sheet]) -- end -- end --end -- -- funzione che dati i Cart setta le priorità e divide i pezzi per materiale function NestingLib.SetPriorityProcessMaterial(Carts, materials, ErrorList) -- assegno priorità ai carrelli/pezzi local ActiveCartIndex = 0 local TotCartIndex = 0 local Priority = 2 local PartDoneCount = 0 for Cart = 1, #Carts do for Order = 1, #Carts[Cart].OrderList do for Kit = 1, #Carts[Cart].OrderList[Order].KitList do for Part = 1, #Carts[Cart].OrderList[Order].KitList[Kit].PartList do local TempPart = Carts[Cart].OrderList[Order].KitList[Kit].PartList[Part] if TempPart.OptParameters.PaintFlag == "NO" then if TempPart.PartId == ProblematicItem then local x = 2 end -- segno su quale cart va il pezzo TempPart.Cart = Carts[Cart].CartIndex if TempPart.MatExtCode then -- suddivido i pezzi per materiale for Material = 1, #materials do -- aggiungo liste pezzi if not materials[Material].PriorityList then materials[Material].PriorityList = {} end if TempPart.MatExtCode == materials[Material].MatExtCode then TempPart.MatId = materials[Material].MatId TempPart.Priority = Priority -- aggiungo il pezzo alla lista della sua priorita' all'interno del materiale local bFound = false for Index = 1, #materials[Material].PriorityList do if materials[Material].PriorityList[Index].Priority == TempPart.Priority then table.insert(materials[Material].PriorityList[Index].PartList, TempPart) bFound = true end end if not bFound then local Item = {Priority = TempPart.Priority, PartList = {TempPart}} table.insert(materials[Material].PriorityList, Item) end end end else table.insert(ErrorList, {ErrType = "E.10", Uid = "PartId = " .. TempPart.PartId, Description = "Material not found!"}) end end end end end -- se arrivo al numero di carrelli attivo allo scarico incremento la priorità di uno local bPriorityIncrement = false ActiveCartIndex = ActiveCartIndex + 1 if ActiveCartIndex == CartActiveUnload then bPriorityIncrement = true ActiveCartIndex = 0 end -- dopo il primo gruppo di cart totali if Cart > TotCartUnload - CartActiveUnload then TotCartIndex = TotCartIndex + 1 -- se arrivo al numero totale di carrelli disponibili allo scarico incremento la priorità di uno if TotCartIndex == CartActiveUnload then bPriorityIncrement = true TotCartIndex = 0 end end if bPriorityIncrement then Priority = Priority + 1 end end end -- -- funzione che dati i Cart setta le priorità e divide i pezzi per materiale --function NestingLib.SetPriorityProcessMaterial(Carts, materials, ErrorList) -- local OrderCount = 0 -- local KitCount = 0 -- local PartCount = 0 -- -- assegno priorità ai carrelli/pezzi -- local ActiveCartIndex = 0 -- local TotCartIndex = 0 -- local Priority = 2 -- local PartDoneCount = 0 -- for Cart = 1, #Carts do -- for Order = 1, #Carts[Cart].OrderList do -- OrderCount = OrderCount + 1 -- for Kit = 1, #Carts[Cart].OrderList[Order].KitList do -- KitCount = KitCount + 1 -- for Part = 1, #Carts[Cart].OrderList[Order].KitList[Kit].PartList do -- PartCount = PartCount + 1 -- local TempPart = Carts[Cart].OrderList[Order].KitList[Kit].PartList[Part] -- -- segno su quale cart va il pezzo -- TempPart.Cart = Carts[Cart].CartIndex -- -- leggo le proprietà dal dxf e le imposto -- local MatExtCode, PdfLink, Paint, OptParameters, ErrorType = UtilityLib.readDXF(TempPart.CadFilePath) -- -- solo se trovo il materiale vado avanti per questo pezzo -- if ErrorType == 0 and MatExtCode then -- PartDoneCount = PartDoneCount + 1 -- TempPart.MatExtCode = MatExtCode -- TempPart.PdfLink = PdfLink -- TempPart.OptParameters = OptParameters -- local PaintVal = "NO" -- if Paint then -- PaintVal = "YES" -- end -- TempPart.OptParameters.PaintFlag = PaintVal -- -- suddivido i pezzi per materiale -- for Material = 1, #materials do -- -- aggiungo liste pezzi -- if not materials[Material].PartList then materials[Material].PartList = {} end -- if TempPart.MatExtCode == materials[Material].MatExtCode then -- TempPart.MatId = materials[Material].MatId -- -- do priorità 0 ai pezzi pitturati perchè devono essere fatti per primi -- if Paint == true then -- TempPart.Priority = 1 -- else -- TempPart.Priority = Priority -- end -- -- aggiungo il pezzo alla lista della sua priorita' all'interno del materiale -- local bFound = false -- for Index = 1, #materials[Material].PartList do -- if materials[Material].PartList[Index].Priority == TempPart.Priority then -- table.insert(materials[Material].PartList[Index].PartList, TempPart) -- bFound = true -- end -- end -- if not bFound then -- local Item = {Priority = TempPart.Priority, PartList = {TempPart}} -- table.insert(materials[Material].PartList, Item) -- end -- end -- end -- elseif ErrorType == 1 then -- table.insert(ErrorList, {ErrType = "E.1", Uid = "PartId = " .. TempPart.PartId, Description = "Can't find DXF file"}) -- EgtOutLog("Part skipped: " .. TempPart.PartId) -- elseif ErrorType == 2 then -- table.insert(ErrorList, {ErrType = "E.2", Uid = "PartId = " .. TempPart.PartId, Description = "Can't find material tag in DXF"}) -- EgtOutLog("Part skipped: " .. TempPart.PartId) -- else -- table.insert(ErrorList, {ErrType = "E.6", Uid = "PartId = " .. TempPart.PartId, Description = "Error in DXF reading"}) -- EgtOutLog("Part skipped: " .. TempPart.PartId) -- end -- end -- end -- end -- -- -- se arrivo al numero di carrelli attivo allo scarico incremento la priorità di uno -- local bPriorityIncrement = false -- ActiveCartIndex = ActiveCartIndex + 1 -- if ActiveCartIndex == CartActiveUnload then -- bPriorityIncrement = true -- ActiveCartIndex = 0 -- end -- -- dopo il primo gruppo di cart totali -- if Cart > TotCartUnload - CartActiveUnload then -- TotCartIndex = TotCartIndex + 1 -- -- se arrivo al numero totale di carrelli disponibili allo scarico incremento la priorità di uno -- if TotCartIndex == CartActiveUnload then -- bPriorityIncrement = true -- TotCartIndex = 0 -- end -- end -- if bPriorityIncrement then -- Priority = Priority + 1 -- end ---- -- se arrivo al numero di carrelli attivo allo scarico incremento la priorità di uno ---- if ActiveCartIndex == CartActiveUnload then ---- Priority = Priority + 1 ---- ActiveCartIndex = 0 ---- end ---- -- se arrivo al numero totale di carrelli disponibili allo scarico incremento la priorità di uno ---- if TotCartIndex == TotCartUnload then ---- Priority = Priority + 1 ---- TotCartIndex = 0 ---- end -- end --end -- -- funzione che dati i materiali prende tutti i pezzi di priorita' 1 e crea i bin function NestingLib.CreateBin(materials, Bins) -- per ogni materiale for materialIndex = 1, #materials do -- cerco il gruppo di pezzi a priorita' 1 for PriorityIndex = 1, #materials[materialIndex].PriorityList do if materials[materialIndex].PriorityList[PriorityIndex] and materials[materialIndex].PriorityList[PriorityIndex].Priority == 1 then -- ciclo sui pezzi a priorita' 1 for PartIndex = 1, #materials[materialIndex].PriorityList[PriorityIndex].PartList do -- ciclo sui bin local BinFound = false for BinIndex = 1, #Bins do if materials[materialIndex].PriorityList[PriorityIndex].PartList[PartIndex].PartExtCode == Bins[BinIndex].PartExtCode then table.insert(Bins[BinIndex].PartList, {PartId = materials[materialIndex].PriorityList[PriorityIndex].PartList[PartIndex].PartId}) -- scrivo indice bin sul pezzo materials[materialIndex].PriorityList[PriorityIndex].PartList[PartIndex].Bin = BinIndex BinFound = true end end if not BinFound then table.insert(Bins, {BinIndex = #Bins + 1, PartExtCode = materials[materialIndex].PriorityList[PriorityIndex].PartList[PartIndex].PartExtCode, PartRev = materials[materialIndex].PriorityList[PriorityIndex].PartList[PartIndex].PartRev, PartList = {{PartId = materials[materialIndex].PriorityList[PriorityIndex].PartList[PartIndex].PartId}}}) -- scrivo indice bin sul pezzo materials[materialIndex].PriorityList[PriorityIndex].PartList[PartIndex].Bin = #Bins end end end end end end -- key per info area local AREA = "Area" local OUTLINE = "Outline" local HOLE = "HOLE" local INSIDECHAMFER = "INSIDE CHAMFER" local OUTSIDECHAMFER = "OUTSIDE CHAMFER" local COUNTERSINK = "COUNTERSINK" local PARTID = "PartId" local PRIORITY = "Priority" local DTMXPOS = "DATA MATRIX CODE POSITION" local CARTBININFO = "CARTBININFO" local INTPART = "INTPART" local RAMP = "RAMP" local SKELETONTRACK = "SKELETONTRACK" local SKELETONPART = "SKELETON" local CUTOPT = "CUTOPT" -- funzione legge il dxf ed aggiunge il pezzo al nesting local function AddPartListToNesting(PartList, ErrorList, Material) local LastId = GDB_ID.ROOT for Part = 1, #PartList do -- tipo di rotazione del pezzo consentita : 0 -> rotazione libera, 1 -> rotazione solo di 180°, 2 -> nessuna rotazione local RotationType = 0 -- verifico se gia' presente per importazione precedente local PartId1 = EgtGetFirstNameInGroup(GDB_ID.ROOT, PartList[Part].PartDtmx) if not PartId1 then -- importo il dxf del pezzo DXFpath = string.gsub(PartList[Part].CadFilePath, "\\", '/') EgtImportDxf(DXFpath) -- se LastId nullo carico primo pezzo if LastId == GDB_ID.ROOT then PartId1 = EgtGetLastInGroup(GDB_ID.ROOT) LastId = PartId1 else PartId1 = EgtGetNextPart(LastId) end -- verifico se è un solo pezzo local PartId2 = EgtGetLastPart(LastId) if PartId1 == PartId2 then LastId = PartId1 else -- ERRORE!! return end -- assegno l'Id del pezzo e la priorità EgtSetInfo(PartId1, PARTID, PartList[Part].PartId) EgtSetName(PartId1, PartList[Part].PartDtmx) EgtSetInfo(PartId1, PRIORITY, PartList[Part].Priority) end -- lista lavorazioni interne local InternalMach = {} -- lista percorsi interni per pezzi piccoli local IntMachSmallPart = {} -- regione skeleton local nSkeletonRegionId = GDB_ID.NULL -- spengo tutti i layer inutili local LayerId = EgtGetFirstLayer(PartId1) local nMaxId = GDB_ID.NULL local bFound = false while LayerId do local layerName = EgtGetName(LayerId) local bOutline = false -- verifico se ha un nome di outline for Mach = 1, #OutlineMachining[1] do if layerName == OutlineMachining[1][Mach] then bOutline = true end end if bOutline then -- prendo quello più grande che sarà l'esterno local dMaxArea = 0 local GeomList = {} local OutlineId = EgtGetFirstInGroup(LayerId) while OutlineId do if EgtGetType( OutlineId) == GDB_TY.CRV_COMPO or EgtGetType( OutlineId) == GDB_TY.CRV_ARC then -- ne verifico lo spessore local OutlineDepth = EgtCurveThickness(OutlineId) if OutlineDepth >= 0 then table.insert(ErrorList, {ErrType = "E.13", Uid = "PartId = " .. PartList[Part].PartId, Description = "Error, outline thickness must be negative!"}) EgtOutLog("Error in ".. PartList[Part].CadFilePath ..": outline thickness must be negative!") return end -- se entro la tolleranza if -OutlineDepth >= (Material.T_mm - Config.ThicknessTolerance) and -OutlineDepth <= (Material.T_mm + Config.ThicknessTolerance) then EgtModifyCurveThickness(OutlineId, - Material.T_mm) end -- se il percorso non è chiuso if not EgtCurveIsClosed(OutlineId) then -- calcolo distanza tra inizio e fine local StartPoint = EgtSP(OutlineId) local EndPoint = EgtEP(OutlineId) if abs(Vector3d.len(StartPoint - EndPoint)) <= Config.OpenPathTolerance then -- accorcio estremi di mezzo decimo di millimetro per evitare successivi problemi con offset EgtTrimCurveStartAtLen(OutlineId, 0.015) EgtTrimCurveEndAtLen(OutlineId, EgtCurveLength(OutlineId) - 0.015) EgtCloseCurveCompo(OutlineId) else table.insert(ErrorList, {ErrType = "E.8", Uid = "PartId = " .. PartList[Part].PartId, Description = "Open paths found"}) EgtOutLog("Error in ".. PartList[Part].CadFilePath ..": open paths found") return end end local dArea = EgtCurveAreaXY(OutlineId) if dArea and abs(dArea) > dMaxArea then dMaxArea = abs(dArea) nMaxId = OutlineId -- sposto entità contorno esterno per prima table.insert(GeomList, 1, OutlineId) else table.insert(GeomList, OutlineId) end else table.insert(ErrorList, {ErrType = "E.8", Uid = "PartId = " .. PartList[Part].PartId, Description = "There are entities that are not CompositeCurves or Arcs"}) EgtOutLog("Warning in ".. PartList[Part].CadFilePath ..": there is entities that are not compo or arcs") end OutlineId = EgtGetNext(OutlineId) end -- se ho trovato il contorno esterno if nMaxId ~= GDB_ID.NULL then -- se necessario inverto le curve per dividere contorni interni ed esterno OutlineId = EgtGetFirstInGroup(LayerId) while OutlineId do local dArea = EgtCurveAreaXY(OutlineId) if not dArea then table.insert(ErrorList, {ErrType = "E.8", Uid = "PartId = " .. PartList[Part].PartId, Description = "Open paths found"}) EgtOutLog("Error in ".. PartList[Part].CadFilePath ..": open paths found") return else -- se contorno esterno in senso orario o contorno interno antiorario lo inverto if (OutlineId == nMaxId and dArea < 0) or (OutlineId ~= nMaxId and dArea > 0) then EgtInvertCurve(OutlineId) end end OutlineId = EgtGetNext(OutlineId) end -- salvo area come info local dArea = EgtCurveAreaXY(nMaxId) EgtSetInfo(PartId1, AREA, dArea) -- scrivo carrello e gruppo carrelli a cui appartiene local BBox = EgtGetBBox(nMaxId,GDB_BB.STANDARD) local CartText = "" if PartList[Part].Bin then CartText = "B" .. PartList[Part].Bin elseif PartList[Part].Cart then CartText = "C" .. PartList[Part].Cart end if DebugCode and PartList[Part].Priority then CartText = CartText .. "-" .. PartList[Part].Priority end local CartIndexLayer = EgtGroup(PartId1) EgtSetName(CartIndexLayer, CARTBININFO) EgtSetInfo(CartIndexLayer, "DTMX", PartList[Part].PartDtmx) if PartList[Part].OptParameters.RoundEdge == 'YES' or PartList[Part].OptParameters.TNutFlag == 'YES' then EgtSetInfo(CartIndexLayer, "TEXT", CartText .. '*') else EgtSetInfo(CartIndexLayer, "TEXT", CartText) end EgtSetInfo(CartIndexLayer, "MATID", PartList[Part].MatId) EgtTextAdv(CartIndexLayer, Point3d(BBox:getCenter():getX(), BBox:getCenter():getY(), BBox:getMax():getZ()), 0, CartText, "Arial", 2, 'S', 30, 2, 0, GDB_TI.MC) EgtSetColor(CartIndexLayer, 'WHITE') -- EgtText( int nParentId, Point3d PtIni, string Text, num dH [, int nRefType = GDB_RT.LOC]) -- calcolo box per sapere se girare il pezzo local OutlineBox = EgtGetBBox(nMaxId, GDB_BB.STANDARD) local MinOutlineBox = BBox3d.getMin(OutlineBox) local MaxOutlineBox = BBox3d.getMax(OutlineBox) local OutlineY = Point3d.getY(MaxOutlineBox) - Point3d.getY(MinOutlineBox) local OutlineX = Point3d.getX(MaxOutlineBox) - Point3d.getX(MinOutlineBox) -- imposto RollerDist local RollerDist = MXRollerDist if IsOffline then RollerDist = NWRollerDist end -- if dArea < Config.dVerySmallPartArea then -- RotationType = 2 -- controllo se ha una venatura da rispettare local nGrainLayerId = EgtGetFirstNameInGroup(PartId1, 'GRAIN') if nGrainLayerId then -- -- recupero linea di direzione -- local nGrainId = EgtGetFirstInGroup(nGrainLayerId) -- if nGrainId then -- local vtGrain = EgtSV(nGrainId) -- end RotationType = 1 elseif OutlineX <= RollerDist and OutlineY > RollerDist then EgtRotate(PartId1, ORIG(), Z_AX(), 90) RotationType = 1 elseif OutlineY <= RollerDist and OutlineX > RollerDist then RotationType = 1 end EgtSetName(nMaxId, OUTLINE) -- copio outline in un layer dedicato local OutlineLayer = EgtGroup(PartId1) EgtSetName(OutlineLayer, OUTLINE) local OutlineCopy = EgtCopy(nMaxId, OutlineLayer) EgtSetName(OutlineCopy, OUTLINE) -- creo regione del pezzo local RegId = EgtSurfFlatRegion(OutlineLayer, GeomList) EgtSetName(RegId, PartList[Part].PartDtmx) EgtSetColor(RegId, Color3d(255,128,0,50)) EgtSetStatus(LayerId, GDB_ST.ON) -- creo regione traccia utensile local ToolDiam = 0 if EgtMdbSetCurrMachining(OutlineMachining[2][1]) then local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL) EgtTdbSetCurrTool(ToolName) ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.DIAM) end -- verifico se ci sono opzioni di lavorazione if PartList[Part].OptParameters.CutOpt then if PartList[Part].OptParameters.CutOpt == SKELETONPART or PartList[Part].OptParameters.CutOpt == "SKELETON&TAB" then -- creo regione per skeleton local nSkeletonId = EgtOffsetCurveAdv(nMaxId, ToolDiam + Config.dSkeletonWidth) EgtSetName(nSkeletonId, "SkeletonOutline") EgtRelocateGlob(nSkeletonId, OutlineLayer) local srfSkeletonId = EgtSurfFlatRegion(OutlineLayer, {nMaxId, nSkeletonId}) EgtSetName(srfSkeletonId, "SKELETON") EgtSetStatus(nSkeletonId, GDB_ST.OFF) EgtSetStatus(srfSkeletonId, GDB_ST.OFF) nSkeletonRegionId = srfSkeletonId end -- salvo l'info per processarla in lavorazione EgtSetInfo(OutlineLayer, CUTOPT, PartList[Part].OptParameters.CutOpt) end -- se c'e' opzione dimensione etichetta if PartList[Part].OptParameters.Label then -- la salvo EgtSetInfo(OutlineLayer, "LABEL", PartList[Part].OptParameters.Label) end -- ciclo sui percorsi del pezzo OutlineId = EgtGetFirstInGroup(LayerId) while OutlineId do -- se contorno interno if OutlineId ~= nMaxId then -- classifico percorsi interni come svuotature o buchi per pezzi -- classifico percorso rispetto al pezzo local OutlineClassification = EgtCurveWithRegionClassify(OutlineId, RegId) -- verifico spessore percorsi interni local OutlineDepth = EgtCurveThickness(OutlineId) -- se spesso come il pezzo e area maggiore di quella minima per un buco local dIntArea = EgtCurveAreaXY(OutlineId) if -OutlineDepth >= (Material.T_mm - Config.ThicknessTolerance) and math.abs(dIntArea) >= Config.IntPartMinArea then EgtSetInfo(OutlineId, INTPART, 1) EgtSetInfo(PartId1, INTPART, 1) table.insert(IntMachSmallPart, OutlineId) elseif OutlineClassification == GDB_CRC.OUT or OutlineClassification == GDB_CRC.INTERS then -- se contorno interno, lo aggiungo alla lista lavorazioni interne table.insert(InternalMach, OutlineId) end end -- creo regione traccia utensile local ToolDiam = 0 if EgtMdbSetCurrMachining(OutlineMachining[2][1]) then local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL) EgtTdbSetCurrTool(ToolName) ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.DIAM) end if Config.bSkeletonReduction then local nOffId, nOffCnt = EgtOffsetCurveAdv(OutlineId, ToolDiam + 0.01) -- elimino gli offset successivi al primo risultanti da porzioni di percorso con distanza inferiore all'offset for Index = 1, nOffCnt - 1 do EgtErase(nOffId + Index) end if not nOffId then table.insert(ErrorList, {ErrType = "E.8", Uid = "PartId = " .. PartList[Part].PartId, Description = "Open paths found"}) EgtOutLog("Error in ".. PartList[Part].CadFilePath ..": open paths found") return end EgtSetName(nOffId, "SkeletonToolOutline") EgtRelocateGlob(nOffId, OutlineLayer) local srfToolId = GDB_ID.NULL if OutlineId == nMaxId then srfToolId = EgtSurfFlatRegion(OutlineLayer, {OutlineId, nOffId}) else -- verifico se dimensioni minori della griglia local b3Outline = EgtGetBBoxGlob(OutlineId, GDB_BB.STANDARD + GDB_BB.ONLY_VISIBLE + GDB_BB.IGNORE_TEXT + GDB_BB.IGNORE_DIM) if b3Outline:getDimX() < Config.bSRMaxWidth and b3Outline:getDimY() < Config.bSRMaxHeight or nOffId == GDB_ID.NULL then srfToolId = EgtSurfFlatRegion(OutlineLayer, OutlineId) else srfToolId = EgtSurfFlatRegion(OutlineLayer, {nOffId, OutlineId}) end EgtInvertSurf(srfToolId) end EgtSetName(srfToolId, SKELETONTRACK) EgtSetStatus(nOffId, GDB_ST.OFF) EgtSetStatus(srfToolId, GDB_ST.OFF) end -- vado a percorso successivo OutlineId = EgtGetNext(OutlineId) end bFound = true -- se non ho trovato il contorno esterno do' errore else EgtOutLog("Error outline not found in part " .. PartList[Part].PartId) table.insert(ErrorList, {ErrType = "E.4", Uid = "PartId = " .. PartList[Part].PartId, Description = "Can't find outline"}) return end elseif layerName == DTMXPOS then -- recupero punti dentro questo layer local bFirstPoint = true local nPointId = EgtGetFirstInGroup(LayerId) local dArea = EgtGetInfo(PartId1, AREA, "d") while nPointId and nPointId ~= GDB_ID.NULL do if bFirstPoint or (dArea and dArea > Config.dSkelSkinTab_MaxArea) then -- li chiamo con nome part piu' _QR EgtSetName(nPointId, "$QR$" .. PartList[Part].PartDtmx) bFirstPoint = false end nPointId = EgtGetNext(nPointId) end EgtSetStatus(LayerId, GDB_ST.ON) elseif layerName == OUTSIDECHAMFER then if PartList[Part].OptParameters.OutsideChamferWidth then local nChamferId = EgtGetFirstInGroup( LayerId) while nChamferId do EgtSetInfo( nChamferId, 'ChamferWidth', PartList[Part].OptParameters.OutsideChamferWidth) nChamferId = EgtGetNext(nChamferId) end end elseif layerName == INSIDECHAMFER then if PartList[Part].OptParameters.InsideChamferWidth then local nChamferId = EgtGetFirstInGroup( LayerId) while nChamferId do EgtSetInfo( nChamferId, 'ChamferWidth', PartList[Part].OptParameters.InsideChamferWidth) nChamferId = EgtGetNext(nChamferId) end end EgtSetStatus(LayerId, GDB_ST.ON) elseif layerName == OUTLINE or layerName == HOLE or layerName == CARTBININFO or layerName == RAMP or layerName == COUNTERSINK then EgtSetStatus(LayerId, GDB_ST.ON) else EgtSetStatus(LayerId, GDB_ST.OFF) end LayerId = EgtGetNext(LayerId) end -- se non ho trovato il contorno esterno do' errore if not bFound then EgtOutLog("Error outline not found in part " .. PartList[Part].PartId) table.insert(ErrorList, {ErrType = "E.4", Uid = "PartId = " .. PartList[Part].PartId, Description = "Can't find outline"}) return end -- preparo pezzo per il nesting local Priority = 0 if PartList[Part].Priority then Priority = PartList[Part].Priority end local bCanRotate, dRotStep = true, 0 if RotationType == 1 then dRotStep = 180 elseif RotationType == 2 then bCanRotate = false end -- aggiungo pezzo al nesting EgtAutoNestAddPart( PartId1, nMaxId, false, bCanRotate, dRotStep, Priority, 1) -- EgtAutoNestAddPart( PartId, OutlineId, bCanFlip, bCanRotate, dRotStep, nPriority, nCount) -- aggiungo le lavorazioni interne abbastanza grandi da poterci aggiungere pezzi for IntPart = 1, #IntMachSmallPart do EgtAutoNestAddHoleToPart( PartId1, IntMachSmallPart[IntPart]) -- EgtAutoNestAddToolOutlineToPart( int nPartId, int nToolOutlineId) end -- aggiungo le lavorazioni interne come possibili ingombri for IntMach = 1, #InternalMach do EgtAutoNestAddToolOutlineToPart( PartId1, InternalMach[IntMach]) -- EgtAutoNestAddToolOutlineToPart( int nPartId, int nToolOutlineId) end EgtAutoNestAddToolOutlineToPart( PartId1, nSkeletonRegionId) end end -- -- funzione che imposta le macchine multiax secondo indice local function SetMachineByIndex(MachId) if MachId == 1 then sCurrMachName = "Multiax-NE_Nest01" EgtSetCurrMachine(sCurrMachName) elseif MachId == 2 then sCurrMachName = "Multiax-NE_Nest02" EgtSetCurrMachine(sCurrMachName) elseif MachId == 3 then sCurrMachName = "Multiax-NE_Nest03" EgtSetCurrMachine(sCurrMachName) end end -- -- funzione che crea gruppi di lavorazione con grezzi e pezzi secondo nesting local function CreateMachSheets(LastMachGroupId, SheetPartId, Material, PartList, MachId, nRaw1Id, FirstMachIndex) -- imposto macchina secondo indice, se NE if not IsOffline then SetMachineByIndex(MachId) end -- disposizione sheet e parts local SheetId = GDB_ID.NULL local vtAdd = V_NULL() local nRawId = GDB_ID.NULL -- local SheetCounter = 0 local Sheet = {PartList = {}} local bFirstSheet = true local nMach2SheetId = FirstMachIndex local nMach3SheetId = FirstMachIndex 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 -- SheetCounter = SheetCounter + 1 if LastMachGroupId then if bFirstSheet then bFirstSheet = false -- attivo gruppo di lavorazione EgtSetCurrMachGroup(LastMachGroupId) -- imposto grezzo nRawId = EgtGetFirstRawPart() -- se seconda macchina, recupero il grezzo corretto if MachId == 2 then nRawId = EgtGetInfo(nRawId, 'LastRaw2') EgtSetCurrMachGroup(EgtGetParent(EgtGetParent(nRawId))) elseif MachId == 3 then nRawId = EgtGetInfo(nRawId, 'LastRaw3') EgtSetCurrMachGroup(EgtGetParent(EgtGetParent(nRawId))) end -- imposto foglio Sheet = Material.SheetList[#Material.SheetList] else nRawId = nil end else -- creo gruppo di lavorazione local MachGroupName if MachId == 2 then nMach2SheetId = nMach2SheetId + 1 --MachGroupName = "Sheet" .. nMach2SheetId .. "_2" --MachGroupName = "Sheet" .. nRaw1Id MachGroupName = EgtGetMachGroupNewName("M2_Sheet") MachGroupName = "M2Sheet" .. nMach2SheetId elseif MachId == 3 then nMach3SheetId = nMach3SheetId + 1 MachGroupName = EgtGetMachGroupNewName("M3_Sheet") MachGroupName = "M3Sheet" .. nMach3SheetId else MachGroupName = "Sheet" .. #Material.SheetList + 1 --SheetCounter end -- local sMachine = "Multiax-NE_Nest" -- if IsOffline then -- sMachine = "Northwood-RHD" -- end local bOk = EgtAddMachGroup(MachGroupName, sCurrMachName) -- se macchina 2 aggiungo info e riferimento a foglio della macchina 1 if MachId == 2 then EgtSetInfo(EgtGetCurrMachGroup(), 'MachId', MachId) local nOrigSheetId = EgtGetMachGroupId("Sheet" .. nMach2SheetId) EgtSetInfo(EgtGetCurrMachGroup(), 'OrigSheetId', nOrigSheetId) elseif MachId == 3 then EgtSetInfo(EgtGetCurrMachGroup(), 'MachId', MachId) local nOrigSheetId = EgtGetMachGroupId("Sheet" .. nMach3SheetId) EgtSetInfo(EgtGetCurrMachGroup(), 'OrigSheetId', nOrigSheetId) end -- imposto tavola local vtOffs = UtilityLib.SetupMachineTable(IsOffline) -- creo grezzo if bOk then nRawId = UtilityLib.RawPartCreation(SheetPartId, vtOffs, IsOffline) -- creo foglio e lo aggiungo a lista Sheet = {MachGroupName = MachGroupName, PartList = {}} if MachId == 1 then table.insert(Material.SheetList, Sheet) end else nRawId = nil --SheetCounter = SheetCounter - 1 end end --EgtOutLog( string.format( 'Sheet %d mult=%d parts=%d', nId, nType, nFlag)) -- altrimenti pezzo else --EgtOutLog( string.format( ' Part %d pos=%f,%f rot=%f flip=%d', nId, dX, dY, dAngRot, nFlag)) -- se ho un grezzo valido metto i pezzi local PartId = nId if MachId ~= 2 and MachId ~= 3 then if nFlag ~= 0 then EgtMirror( PartId, ORIG(), Y_AX(), GDB_RT.GLOB) end EgtRotate( PartId, ORIG(), Z_AX(), dAngRot, GDB_RT.GLOB) EgtMove( PartId, Vector3d( dX, dY, 0) + vtAdd, GDB_RT.GLOB) end -- se c'e' un grezzo valido if nRawId then local PartBBox = EgtGetBBoxGlob(PartId, GDB_BB.STANDARD) local ptPos = Point3d(PartBBox:getMin():getX(), PartBBox:getMin():getY(), 0) local bOk = EgtAddPartToRawPart(PartId, ptPos, nRawId) -- se pezzo aggiunto al grezzo if bOk and MachId == 1 then -- lo aggiungo alla lista pezzi del foglio table.insert(Sheet.PartList, {PartId = EgtGetInfo(PartId, PARTID)}) if tonumber(EgtGetInfo(PartId, PARTID)) == ProblematicItem then local x = 2 --EgtSaveFile("c:/Temp/ProvaNesting2.nge") end -- lo elimino dalla lista pezzi local PartIndex = 0 for Index = 1, #PartList do if PartList[Index].PartId == tonumber(EgtGetInfo(PartId, PARTID)) then PartIndex = Index end end table.remove(PartList, PartIndex) end end end end -- aggiorno visualizzazione EgtZoom( SCE_ZM.ALL) return nRawId end -- local SHEETLABEL = "SheetLabel" local REMNANTLABEL = "RemnantLabel" -- funzione che nesta i pezzi passatigli dato un grezzo di partenza e/o un materiale -- LastRaw: grezzo incompleto da riempire -- PartList: lista dei pezzi da nestare -- Material: materiale su cui nestare i pezzi function NestingLib.NestPartInRawPart(LastRaw, PartList, Material, ErrorList, IsEstimate, IsValidation) -- inizio nesting automatico EgtAutoNestStart() local nOldMachGroup = EgtGetCurrMachGroup() EgtResetCurrMachGroup() -- aggiungo tutti i pezzi al nesting AddPartListToNesting(PartList, ErrorList, Material) -- ripristino MachGroup EgtSetCurrMachGroup(nOldMachGroup) -- 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(Material.L_mm, Material.W_mm, 0), GDB_RT.GLOB) EgtModifyCurveThickness(SheetOutlineId, -Material.T_mm) EgtSetName(SheetOutlineId, OUTLINE) -- ricavo Kerf di questo materiale local dKerf = 9 for Index = 1, #Config.Kerf do if Config.Kerf[Index].MatId == Material.MatId then dKerf = Config.Kerf[Index].Kerf end end -- verifico se ultimo grezzo non nullo local LastMachGroupId = nil if LastRaw and LastRaw ~= GDB_ID.NULL then -- recupero Id gruppo di lavoro e lo attivo LastMachGroupId = EgtGetParent(EgtGetParent(LastRaw)) -- recupero lista pezzi già presenti nel grezzo EgtSetCurrMachGroup(LastMachGroupId) -- recupero PartId dei pezzi local NestedPartList = {} local PartId = EgtGetFirstPartInRawPart(LastRaw) while PartId do local LayerOutlineId = EgtGetFirstNameInGroup(PartId, OUTLINE) local OutlineId = EgtGetFirstNameInGroup(LayerOutlineId, OUTLINE) table.insert(NestedPartList, OutlineId) PartId = EgtGetNextPartInRawPart(PartId) end -- resetto gruppo di lavoro per tornare in modalità disegno a fare il nesting EgtResetCurrMachGroup() -- Preparo foglio per nesting EgtAutoNestAddSheet( SheetPartId, SheetOutlineId, dKerf, 0, 1) -- EgtAutoNestAddSheet( SheetId, OutlineId, dKerf, nPriority, nCount) -- imposto come difetti i pezzi già presenti for Index = 1, #NestedPartList do EgtAutoNestAddDefectToSheet(SheetPartId, NestedPartList[Index]) -- EgtAutoNestAddDefectToSheet( SheetId, DefectId) end -- recupero etichetta local nSheetLabel = EgtGetFirstNameInGroup(LastRaw, SHEETLABEL) -- la aggiungo come difetto EgtAutoNestAddDefectToSheet(SheetPartId, nSheetLabel) -- EgtAutoNestAddDefectToSheet( SheetId, DefectId) else -- creo etichetta dello sheet local dLabelW = 50 local dLabelH = 25 local dYPos = Material.W_mm if Material.W_mm > 1465 then dYPos = 1465 + (dLabelH) end local nSheetLabel = EgtRectangle2P(SheetLayerId, Point3d(0, dYPos - dLabelH,0), Point3d(dLabelW, dYPos, 0), GDB_RT.GLOB) EgtSetName(nSheetLabel, SHEETLABEL) -- creo foglio per nesting EgtAutoNestAddSheet( SheetPartId, SheetOutlineId, dKerf, 0, 50) -- EgtAutoNestAddSheet( SheetId, OutlineId, dKerf, nPriority, nCount) -- aggiungo etichetta come difetto EgtAutoNestAddDefectToSheet(SheetPartId, nSheetLabel) -- EgtAutoNestAddDefectToSheet( SheetId, DefectId) end if #ErrorList > 0 then return end -- recupero diametro utensile usato per outline local ToolDiam = 0 if EgtMdbSetCurrMachining(OutlineMachining[2][1]) then local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL) EgtTdbSetCurrTool(ToolName) ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.DIAM) end -- imposto distanza tra i pezzi if ToolDiam and ToolDiam > 0 then EgtAutoNestSetInterpartGap(ToolDiam + 1.6) else table.insert(ErrorList, {ErrType = "E.9", Uid = "Generic", Description = "Outline tool diameter not found!"}) end local nMaxTime = 5 if IsEstimate then nMaxTime = Config.nEstimMaxTime else nMaxTime = Config.nFinalMaxTime end if IsValidation then nMaxTime = 2 end -- imposto tempo di nesting e lo avvio EgtAutoNestCompute(true, nMaxTime) -- 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 / nMaxTime * 100, 995) == 1 then bOk = EgtAutoNestCancelComputation() break end end -- se nesting andato bene --if false then if bOk then -- calcolo gruppi di lavorazione local FirstMachIndex = #Material.SheetList LastRaw = CreateMachSheets(LastMachGroupId, SheetPartId, Material, PartList, 1) if not IsOffline and not IsEstimate and not IsValidation then LastRaw2 = CreateMachSheets(LastMachGroupId, SheetPartId, Material, PartList, 2, LastRaw, FirstMachIndex) EgtSetInfo(LastRaw, 'LastRaw2', LastRaw2) LastRaw3 = CreateMachSheets(LastMachGroupId, SheetPartId, Material, PartList, 3, LastRaw, FirstMachIndex) EgtSetInfo(LastRaw, 'LastRaw3', LastRaw3) end -- se impostata seconda macchina, reimposto la prima local sMachName = EgtGetCurrMachineName() if sMachName == 'Multiax-NE_Nest02' or sMachName == 'Multiax-NE_Nest03' then SetMachineByIndex(1) end else table.insert(ErrorList, {ErrType = "E.10", Uid = "Generic", Description = "Error in nesting function!"}) end -- ritorno l'ultimo grezzo utilizzato return LastRaw end -- -- Funzione che restituisce entità in lavorazione corrente function GetEntIdFromCurrMachining() local Geo = EgtGetMachiningGeometry() if not Geo then return GDB_ID.NULL end if type( Geo) == 'table' and type( Geo[1]) == 'table' and type( Geo[1][1]) == 'number' and type( Geo[#Geo]) == 'table' and type( Geo[#Geo][1]) == 'number' then return Geo[1][1], Geo[#Geo][1] else return GDB_ID.NULL end end -- funzione che imposta le lavorazioni nelle liste per TSP local function InitInTSP(MachId, MachList, MachListIndex) local nStartId, nEndId = GetEntIdFromCurrMachining() if nStartId ~= GDB_ID.NULL and EgtExistsObj( nStartId) and nEndId ~= GDB_ID.NULL and EgtExistsObj( nEndId) then local ptStart = EgtSP( nStartId, GDB_ID.ROOT) local ptEnd = EgtEP( nEndId, GDB_ID.ROOT) local bInvert = EgtGetMachiningParam( MCH_MP.INVERT) local dAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE) if not dAng then dAng = 0 end if bInvert then ptStart, ptEnd = ptEnd, ptStart end if MachListIndex and MachListIndex > 0 then table.insert( MachList[MachListIndex], {Id=MachId, Start= ptStart, End = ptEnd, Ang=abs( dAng)}) else table.insert( MachList, {Id=MachId, Start= ptStart, End = ptEnd, Ang=abs( dAng)}) end end end -- -- funzione che ordina le lavorazioni con l'algoritmo TSP local function SortCuts(MachiningList, LastMch) if MachiningList and #MachiningList > 0 then -- recupero punto finale ultima lavorazione EgtSetCurrMachining(LastMch) local ptEnd = EgtGetMachiningEndPoint() or Point3d( -200, -200, 0) -- calcolo ordinamento EgtSpInit() for i = 1, #MachiningList do EgtSpAddPoint( MachiningList[i].Start:getX(), MachiningList[i].Start:getY(), 0, 0, MachiningList[i].Ang, MachiningList[i].End:getX(), MachiningList[i].End:getY(), 0, 0, MachiningList[i].Ang) end EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, ptEnd:getX(), ptEnd:getY()) local vOutlineOrd = EgtSpCalculate( SHP_TY.OPEN) EgtSpTerminate() -- applico ordinamento calcolato -- parto da LastMch precedente if vOutlineOrd then for i = 1, #vOutlineOrd do EgtRelocateGlob( MachiningList[vOutlineOrd[i]].Id, LastMch, GDB_IN.AFTER) LastMch = MachiningList[vOutlineOrd[i]].Id end end end return LastMch end -- -- funzione che ordina le lavorazioni con l'algoritmo TSP local function SortParts(PartList, bZigZagSorting) local nRawId = EgtGetFirstRawPart() local ptRawCenter = EgtGetRawPartCenter(nRawId) -- calcolo ordinamento EgtSpInit() for i = 1, #PartList do if bZigZagSorting then EgtSpAddPoint( PartList[i].BBox:getCenter():getX(), PartList[i].BBox:getCenter():getY()) else local dDeltaX = PartList[i].BBox:getCenter():getX() - ptRawCenter:getX() local dDeltaY = PartList[i].BBox:getCenter():getY() - ptRawCenter:getY() local dDistXY = sqrt( dDeltaX * dDeltaX + dDeltaY * dDeltaY) EgtSpAddPoint( PartList[i].BBox:getCenter():getX(), PartList[i].BBox:getCenter():getY(), 10 * dDistXY, 0, 0, PartList[i].BBox:getCenter():getX(), PartList[i].BBox:getCenter():getY(), 10 * dDistXY, 0, 0) end end EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, -200, -200, 20000, 0, 0) local vOutlineOrd if bZigZagSorting then -- imposto larghezza colonna zig zag EgtSpSetZzOwStep(400) vOutlineOrd = EgtSpCalculate( SHP_TY.ZIGZAG_Y) else vOutlineOrd = EgtSpCalculate( SHP_TY.OPEN) end EgtSpTerminate() -- applico ordinamento calcolato local NewPartList = {} if vOutlineOrd then for i = 1, #vOutlineOrd do table.insert(NewPartList, PartList[vOutlineOrd[i]]) end end return NewPartList end -- local function ProcessMachinings(HoleList, RampList, ChamferList, PocketingList, IntIntOutlineList, SkinOutlineList, IntExtOutlineList, InternalOutlineList, SmallOutlineList, OutlineList, LastMch) if not LastMch then local nPhase = EgtGetCurrPhase() LastMch = EgtGetPhaseDisposition( nPhase) end -- Ordino i tagli esterni ---------- for HoleMach = 1, #HoleList do LastMch = SortCuts(HoleList[HoleMach], LastMch) end LastMch = SortCuts(RampList, LastMch) LastMch = SortCuts(ChamferList, LastMch) LastMch = SortCuts(PocketingList, LastMch) LastMch = SortCuts(IntIntOutlineList, LastMch) LastMch = SortCuts(SkinOutlineList, LastMch) LastMch = SortCuts(IntExtOutlineList, LastMch) LastMch = SortCuts(InternalOutlineList, LastMch) LastMch = SortCuts(SmallOutlineList, LastMch) LastMch = SortCuts(OutlineList, LastMch) return LastMch end function NestingLib.VerifyPath(Folder, BatchId, Material, MachId) local dateNow = os.date("*t") local Year = dateNow.year local Month = dateNow.month local Day = dateNow.day local CurrPath = Config.sBasePath .. "/" .. Folder if not UtilityLib.FolderExists(CurrPath) then EgtCreateDirectory(CurrPath) end CurrPath = CurrPath .. "/".. Year if not UtilityLib.FolderExists(CurrPath) then EgtCreateDirectory(CurrPath) end CurrPath = CurrPath .. "/".. Month if not UtilityLib.FolderExists(CurrPath) then EgtCreateDirectory(CurrPath) end CurrPath = CurrPath .. "/".. BatchId if not UtilityLib.FolderExists(CurrPath) then EgtCreateDirectory(CurrPath) end if Material then CurrPath = CurrPath .. "/".. Material.MatId if not UtilityLib.FolderExists(CurrPath) then EgtCreateDirectory(CurrPath) end end -- scelgo nome cartella macchina if MachId == 0 or MachId == 1 or MachId == 2 or MachId == 3 then local MachDirName = '' if MachId == 0 then MachDirName = '##REPLACEME##' elseif MachId == 1 then MachDirName = 'NE01' elseif MachId == 2 then MachDirName = 'NE02' elseif MachId == 3 then MachDirName = 'NE03' end CurrPath = CurrPath .. "/".. MachDirName if not UtilityLib.FolderExists(CurrPath) then EgtCreateDirectory(CurrPath) end end return CurrPath end -- local MACHTYPE = "MachType" -- chiave del tipo di lavorazione per dividerle ed ordinarle local MACHPATH = "MachPath" -- info per percorso utensile rampa local SKELETON = "SKELETON" local PARTCUTSUM = "PartCutSum" -- funzione che esegue tutte le operazioni post nesting (lavorazioni, stime, svg, ecc) function NestingLib.PostNestOp(Material, ErrorList, IsEstimate, BatchId, MachId) -- ciclo sui fogli/gruppi di lavorazione creati for Sheet = 1, #Material.SheetList do local PartsArea = 0 local PartsPriority = {} local CurrMachGroupId = EgtGetMachGroupId(Material.SheetList[Sheet].MachGroupName) -- se seconda macchina, imposto gruppo di lavorazione copia if MachId == 2 or MachId == 3 then -- recupero id grezzo originale local nRawPartId = EgtGetFirstRawPart() -- cerco gruppo copia con id grezzo originale local nMachGroupId = EgtGetFirstMachGroup() while nMachGroupId do if EgtGetInfo(nMachGroupId, 'OrigSheetId', 'i') == CurrMachGroupId and EgtGetInfo(nMachGroupId, 'MachId', 'i') == MachId then EgtSetCurrMachGroup(nMachGroupId) end nMachGroupId = EgtGetNextMachGroup(nMachGroupId) end if not EgtGetCurrMachGroup() then EgtSetCurrMachGroup(CurrMachGroupId) end else EgtSetCurrMachGroup(CurrMachGroupId) end -- imposto SetUp di default EgtImportSetup() -- recupero grezzo local CurrRawPart = EgtGetFirstRawPart() -- scrivo note materiale per riportarlo sul file cn EgtSetInfo(CurrRawPart, 'MatId', Material.MatExtCode) EgtSetInfo(CurrRawPart, 'MatDesc', Material.MatDesc) -- BBox globale per calcolo remnant local PartsBBox = BBox3d() local nSkeletonGroupId = EgtGroup(GDB_ID.ROOT) EgtSetStatus(nSkeletonGroupId, GDB_ST.OFF) EgtSetName(nSkeletonGroupId, SKELETON) local nSkeletonLayerId = EgtGroup(nSkeletonGroupId) EgtSetStatus(nSkeletonLayerId, GDB_ST.OFF) EgtSetName(nSkeletonLayerId, SKELETON) -- creo lavorazioni if nMachOrderType == 1 then PartsArea = CreateMachByType(Material, CurrRawPart, PartsBBox, nSkeletonLayerId, PartsPriority, 1, ErrorList) elseif nMachOrderType == 2 then PartsArea = CreateMachByPart(Material, CurrRawPart, PartsBBox, nSkeletonLayerId, PartsPriority, 1, ErrorList) else PartsArea = CreateMachByOrderedType(Material, CurrRawPart, PartsBBox, nSkeletonLayerId, PartsPriority, ErrorList) end if MachId ~= 2 and MachId ~= 3 then -- imposto area totale dei pezzi Material.SheetList[Sheet].SurfaceWork = PartsArea -- calcolo area esterna Material.SheetList[Sheet].SurfaceTotal = Material.L_mm * Material.W_mm -- assegno al foglio le priorita' Material.SheetList[Sheet].PriorityList = PartsPriority end -- calcolo bbox del grezzo local SheetBBox = EgtGetRawPartBBox(CurrRawPart) -- se offline if IsOffline then -- calcolo dimensioni area occupata dai pezzi local CutPartsArea = EgtGetFirstNameInGroup(nSkeletonLayerId, PARTCUTSUM) local b3Parts = EgtGetBBox(CutPartsArea, GDB_BB.EXACT) -- scrivo note dimensione area dei pezzi per riportarlo sul file cn EgtSetInfo(CurrRawPart, 'PartsArea', tostring(math.ceil(b3Parts:getMax():getX() - SheetBBox:getMin():getX())) .. " x " .. tostring(math.ceil(b3Parts:getMax():getY() - SheetBBox:getMin():getY()))) end -- recupero diametro utensile usato taglio di separazione local ToolDiam = 0 if EgtMdbSetCurrMachining(OutlineMachining[2][1]) then local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL) EgtTdbSetCurrTool(ToolName) ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.DIAM) end -- verifico se c'è spazio per un multiplo della dimensione minima local RemnantMultiple = math.floor((SheetBBox:getMax():getX() - PartsBBox:getMax():getX() - ToolDiam) / Config.RemnantMinDimension) if not IsOffline and RemnantMultiple >= 1 then -- calcolo posizione in X local RemnantCutXPos = SheetBBox:getDimX() - (RemnantMultiple * Config.RemnantMinDimension) - ToolDiam -- creo taglio per remnant local RemnantCutPart = EgtGroup(GDB_ID.ROOT) EgtSetName(RemnantCutPart, "REMNANT") local RemnantCutLayer = EgtGroup(RemnantCutPart) local RemnantCutLine = EgtLine(RemnantCutLayer, Point3d(0, 0, 0), Point3d(0, SheetBBox:getDimY(), 0)) -- aggiungo etichetta remnant local dLabelW = 50 local dLabelH = 25 local dYPos = Material.W_mm if Material.W_mm > 1465 then dYPos = 1465 + (dLabelH) end local nRemnantLabel = EgtRectangle2P(RemnantCutLayer, Point3d(20, dYPos - dLabelH, 0), Point3d(20 + dLabelW, dYPos, 0), GDB_RT.GLOB) EgtSetName(nRemnantLabel, REMNANTLABEL) local sMaterial = string.format('%08d', Material.MatExtCode) local sRemnantDim = string.format('%08d', tointeger(floor(RemnantMultiple * Config.RemnantMinDimension * 1000))) EgtSetInfo(RemnantCutLayer, "DTMX", "MT" .. sMaterial .. "-" .. sRemnantDim) local sRemnantDimText = string.format('%.1f', RemnantMultiple * Config.RemnantMinDimension / 25.4) EgtSetInfo(RemnantCutLayer, "TEXT", sRemnantDimText) -- lo aggiungo come pezzo al grezzo EgtAddPartToRawPart(RemnantCutPart, Point3d(RemnantCutXPos, 0, 0), CurrRawPart) -- lo lavoro local NewMachId = EgtAddMachining("RemnantSeparationCut", OutlineMachining[2][1]) -- applico geometria di lavorazione EgtSetMachiningGeometry(RemnantCutLine) -- applico la lavorazione if not EgtApplyMachining() then table.insert(ErrorList, {ErrType = "E.7", Uid = "Remnant separation cut", Description = "Error in remnant machining!"}) end -- salvo dati remnant in sheet Material.SheetList[Sheet].Remnant = {L_mm = RemnantMultiple * Config.RemnantMinDimension, W_mm = Material.W_mm} -- lo tolgo dallo skeleton local nRemnantOutlineId = EgtRectangle2P(RemnantCutLayer, Point3d(SheetBBox:getMax():getX() - (RemnantMultiple * Config.RemnantMinDimension) - ToolDiam, SheetBBox:getMin():getY(), SheetBBox:getMax():getZ()), SheetBBox:getMax(), GDB_RT.GLOB) local nRemnantSurfId = EgtSurfFlatRegion(RemnantCutLayer, nRemnantOutlineId) local CutPartsArea = EgtGetFirstNameInGroup(nSkeletonLayerId, PARTCUTSUM) EgtSurfFrAdd(CutPartsArea, nRemnantSurfId) EgtSetStatus(nRemnantOutlineId, GDB_ST.OFF) EgtSetStatus(nRemnantSurfId, GDB_ST.OFF) end -- se riduzione dello scheletro attiva if not IsOffline and Config.bSkeletonReduction then -- recupero contorno grezzo local nRawOutlineId = EgtRectangle2P(nSkeletonLayerId, Point3d(SheetBBox:getMin():getX(), SheetBBox:getMin():getY(), SheetBBox:getMax():getZ()), SheetBBox:getMax()) -- ne creo la superficie local nRawSurfId = EgtSurfFlatRegion(nSkeletonLayerId, nRawOutlineId) local CutPartsArea = EgtGetFirstNameInGroup(nSkeletonLayerId, PARTCUTSUM) EgtSetName(nRawSurfId, SKELETON) -- calcolo area rimanente per tagli scheletro EgtSurfFrSubtract(nRawSurfId, CutPartsArea) -- elimino residui piu' piccoli della minima distanza -- copio flat region local nSkeletonFRId = nil local nCopyRawSurfId =EgtCopy(nRawSurfId, nSkeletonLayerId) local SkeletonPartId, Count = EgtExplodeSurf(nCopyRawSurfId) for Index = 0, Count -1 do local b3SkeletonPart = EgtGetBBoxGlob(SkeletonPartId + Index, GDB_BB.STANDARD + GDB_BB.IGNORE_TEXT + GDB_BB.IGNORE_DIM) if b3SkeletonPart:getDimX() > Config.bSRMaxWidth or b3SkeletonPart:getDimY() > Config.bSRMaxHeight then if not nSkeletonFRId then nSkeletonFRId = SkeletonPartId + Index EgtSetName(nSkeletonFRId, "SkeletonSumPart") else EgtSurfFrAdd( nSkeletonFRId, SkeletonPartId + Index) end end end -- se c'e' uno scheletro da tagliare, procedo if nSkeletonFRId then -- calcolo griglia local nSRColumn = math.ceil(SheetBBox:getDimX() / Config.bSRMaxWidth) local nSRRow = math.ceil(SheetBBox:getDimY() / Config.bSRMaxHeight) local dSRColumnSP = (SheetBBox:getDimX() - ((nSRColumn - 2) * Config.bSRMaxWidth)) / 2 local dSRRowSP = (SheetBBox:getDimY() - ((nSRRow - 2) * Config.bSRMaxHeight)) / 2 -- la disegno local nSkeletonGridLayerId = EgtGroup(nSkeletonGroupId) EgtSetStatus(nSkeletonGridLayerId, GDB_ST.OFF) EgtSetName(nSkeletonGridLayerId, "GRID") local SkeletonLineList = {} for CLineIndex = 0, nSRColumn - 2 do local CLineId = EgtLine(nSkeletonGridLayerId, Point3d(SheetBBox:getMin():getX() + dSRColumnSP + (Config.bSRMaxWidth * CLineIndex), SheetBBox:getMin():getY(), SheetBBox:getMax():getZ()), Point3d(SheetBBox:getMin():getX() + dSRColumnSP + (Config.bSRMaxWidth * CLineIndex), SheetBBox:getMax():getY(), SheetBBox:getMax():getZ())) -- taglio griglia con superficie rimanente -- int, int EgtTrimCurveWithRegion( int nCrvId, int nRegId, bool bInVsOut, bool bOn) local nFirstId, nCountId = EgtTrimCurveWithRegion(CLineId, nSkeletonFRId, true, false) for CountIndex = 0, nCountId - 1 do local dSkeletonCutLength = math.abs((EgtEP(nFirstId + CountIndex) - EgtSP(nFirstId + CountIndex)):getY()) local nPartId = EgtGroup(GDB_ID.ROOT) EgtSetName(nPartId, "SKELETON_".. CLineIndex + 1 .. "_" .. CountIndex + 1) local nLayerId = EgtGroup(nPartId) EgtRelocateGlob(nFirstId + CountIndex, nLayerId) EgtModifyCurveThickness(nFirstId + CountIndex, -SheetBBox:getDimZ()) table.insert(SkeletonLineList, nPartId) -- lo aggiungo come pezzo al grezzo EgtAddPartToRawPart(nPartId, EgtSP(nFirstId + CountIndex) - Point3d(SheetBBox:getMin():getX(), SheetBBox:getMin():getY(), SheetBBox:getMax():getZ()), CurrRawPart) -- lo lavoro local NewMachId = EgtAddMachining("SkeletonCut", OutlineMachining[2][1]) -- applico geometria di lavorazione EgtSetMachiningGeometry(nFirstId + CountIndex) EgtSetMachiningParam(MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER) if ToolDiam < dSkeletonCutLength then EgtSetMachiningParam(MCH_MP.STARTADDLEN , - (ToolDiam / 2) + Config.dSkeletonCut) EgtSetMachiningParam(MCH_MP.ENDADDLEN , - (ToolDiam / 2) + Config.dSkeletonCut) else EgtSetMachiningParam(MCH_MP.STARTADDLEN , (- dSkeletonCutLength + 1) / 2) EgtSetMachiningParam(MCH_MP.ENDADDLEN , (- dSkeletonCutLength + 1) / 2) end -- aggiungo ingresso a zig zag EgtSetMachiningParam(MCH_MP.LEADINTYPE , MCH_MILL_LI.ZIGZAG) -- applico la lavorazione if not EgtApplyMachining() then table.insert(ErrorList, {ErrType = "E.7", Uid = "Skeleton separation cut", Description = "Error in horizontal skeleton machining!"}) end -- nascondo il pezzo EgtSetStatus(nFirstId + CountIndex, GDB_ST.OFF) end end -- se altezza riga minore dell'altezza tavola if Config.bSRMaxHeight < 80 * 25.4 then -- calcolo rghe della griglia for RLineIndex = 0, nSRRow - 2 do local RLineId = EgtLine(nSkeletonGridLayerId, Point3d(SheetBBox:getMin():getX(), SheetBBox:getMin():getY() + dSRRowSP + (Config.bSRMaxHeight * RLineIndex), SheetBBox:getMax():getZ()), Point3d(SheetBBox:getMax():getX(), SheetBBox:getMin():getY() + dSRRowSP + (Config.bSRMaxHeight * RLineIndex), SheetBBox:getMax():getZ())) -- taglio griglia con superficie rimanente -- int, int EgtTrimCurveWithRegion( int nCrvId, int nRegId, bool bInVsOut, bool bOn) local nFirstId, nCountId = EgtTrimCurveWithRegion(RLineId, nSkeletonFRId, true, false) for CountIndex = 0, nCountId - 1 do local dSkeletonCutLength = math.abs((EgtEP(nFirstId + CountIndex) - EgtSP(nFirstId + CountIndex)):getY()) local nPartId = EgtGroup(GDB_ID.ROOT) EgtSetName(nPartId, "SKELETON_" .. nSRColumn + RLineIndex .. "_" .. CountIndex + 1) local nLayerId = EgtGroup(nPartId) EgtRelocateGlob(nFirstId + CountIndex, nLayerId) EgtModifyCurveThickness(nFirstId + CountIndex, -SheetBBox:getDimZ()) table.insert(SkeletonLineList, nPartId) -- lo aggiungo come pezzo al grezzo EgtAddPartToRawPart(nPartId, EgtSP(nFirstId + CountIndex) - Point3d(SheetBBox:getMin():getX(), SheetBBox:getMin():getY(), SheetBBox:getMax():getZ()), CurrRawPart) -- lo lavoro local NewMachId = EgtAddMachining("SkeletonCut", OutlineMachining[2][1]) -- applico geometria di lavorazione EgtSetMachiningGeometry(nFirstId + CountIndex) EgtSetMachiningParam(MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER) if ToolDiam < dSkeletonCutLength then EgtSetMachiningParam(MCH_MP.STARTADDLEN , - (ToolDiam / 2) + Config.dSkeletonCut) EgtSetMachiningParam(MCH_MP.ENDADDLEN , - (ToolDiam / 2) + Config.dSkeletonCut) else EgtSetMachiningParam(MCH_MP.STARTADDLEN , (- dSkeletonCutLength + 1) / 2) EgtSetMachiningParam(MCH_MP.ENDADDLEN , (- dSkeletonCutLength + 1) / 2) end -- aggiungo ingresso a zig zag EgtSetMachiningParam(MCH_MP.LEADINTYPE , MCH_MILL_LI.ZIGZAG) -- applico la lavorazione if not EgtApplyMachining() then table.insert(ErrorList, {ErrType = "E.7", Uid = "Skeleton separation cut", Description = "Error in vertical skeleton machining!"}) end -- nascondo il pezzo EgtSetStatus(nFirstId + CountIndex, GDB_ST.OFF) end end end end end -- aggiorno lavorazioni dopo spostamenti e calcolo remnant EgtApplyAllMachinings() -- aggiorno lavorazione un'altra volta per migliorare posizioni eventuali tab EgtApplyAllMachinings() if MachId ~= 2 and MachId ~= 3 then -- ricavo stime local CurrEstimatePath = NestingLib.VerifyPath("Estimate", BatchId, Material) if not UtilityLib.FolderExists(CurrEstimatePath) then EgtCreateDirectory(CurrEstimatePath) end CurrEstimatePath = CurrEstimatePath .. "/" .. Material.SheetList[Sheet].MachGroupName .. ".html" EgtEstimate(CurrEstimatePath) local EstimatedTime = EgtGetInfo(CurrMachGroupId, "Ttot") if EstimatedTime then Material.SheetList[Sheet].EstimatedWorktime = EstimatedTime else Material.SheetList[Sheet].EstimatedWorktime = 0 table.insert(ErrorList, {ErrType = "E.7", Uid = "Generic", Description = "Impossible running estimation!"}) end -- salvo materiale su foglio Material.SheetList[Sheet].MatId = Material.MatId end -- se nesting finale if not IsEstimate or (IsEstimate and IsOffline) then -- salvo file cnc local CurrCNCPath = NestingLib.VerifyPath("CNC", BatchId, Material, MachId) local DBCurrCNCPath = NestingLib.VerifyPath("CNC", BatchId, Material, 0) if not UtilityLib.FolderExists(CurrCNCPath) then EgtCreateDirectory(CurrCNCPath) end CurrPrintCNCPath = CurrCNCPath .. "/" .. Material.SheetList[Sheet].MachGroupName .. "_2.cnc" -- creo path con estensione diversa per offline e non if IsOffline then CurrCNCPath = CurrCNCPath .. "/" .. Material.SheetList[Sheet].MachGroupName .. ".txt" else CurrCNCPath = CurrCNCPath .. "/" .. Material.SheetList[Sheet].MachGroupName .. ".cnc" end if MachId == 2 or MachId == 3 then Material.SheetList[Sheet].MachiningProgram = DBCurrCNCPath .. "/" .. Material.SheetList[Sheet].MachGroupName .. ".cnc" else Material.SheetList[Sheet].MachiningProgram = CurrCNCPath end local bOk = EgtGenerate(CurrCNCPath) -- if not bOk then -- table.insert(ErrorList, {ErrType = "E.7", Uid = "Program generation", Description = "Error in program generation!"}) -- return -- end -- se non offline, genero file di stampa if not IsOffline then -- salvo file cnc print local CurrPrintPath = NestingLib.VerifyPath("CNC_PRINT", BatchId, Material, MachId) local DBCurrPrintPath = NestingLib.VerifyPath("CNC_PRINT", BatchId, Material, 0) if not UtilityLib.FolderExists(CurrPrintPath) then EgtCreateDirectory(CurrPrintPath) end CurrPrintPath = CurrPrintPath .. "/" .. Material.SheetList[Sheet].MachGroupName .. ".cnc" if MachId == 2 or MachId == 3 then Material.SheetList[Sheet].PrintProgram = DBCurrPrintPath .. "/" .. Material.SheetList[Sheet].MachGroupName .. ".cnc" else Material.SheetList[Sheet].PrintProgram = CurrPrintPath end bOk = EgtCopyFile(CurrPrintCNCPath, CurrPrintPath) bOk = EgtEraseFile(CurrPrintCNCPath) end if MachId ~= 2 and MachId ~= 3 then -- salvo svg del grezzo local CurrSVGPath = NestingLib.VerifyPath("SVG", BatchId, Material) if not UtilityLib.FolderExists(CurrSVGPath) then EgtCreateDirectory(CurrSVGPath) end -- salvo disegni tavola CurrSVGPath = CurrSVGPath .. "/".. Material.SheetList[Sheet].MachGroupName .. ".svg" -- creo file svg EgtSetMachineLook( MCH_LOOK.TAB) bOk = EgtExportSvg( GDB_ID.ROOT, CurrSVGPath, 447) if bOk then Material.SheetList[Sheet].Drawing = CurrSVGPath else Material.SheetList[Sheet].Drawing = "" end -- creo svg per ristampa etichette CreateSvgForLabelPrint(CurrSVGPath, Material.SheetList[Sheet].MachGroupName, BatchId, Material) end end end end -- -- funzione che modifica svg inserendo codici qr per ristampa etichette function CreateSvgForLabelPrint(SVGPath, MachGroupName, BatchId, Material) -- apertura file con controllo local fh = io.open( SVGPath, 'r') if not fh then -- errore return end -- lettura di tutte le linee del file local Lines = {} local OneLine = fh:read( '*l') while OneLine do table.insert( Lines, OneLine) OneLine = fh:read( '*l') end fh:close() -- array delle immagini qr da aggiungere alla fine local QrList = {} -- ciclo sulle linee for i = 1, #Lines do local _, _, PartDtmx, dX, dY = string.find(Lines[i], "%s*") if PartDtmx or dX or dY then table.insert(QrList, " ") end local _, _, SVGEnd = string.find(Lines[i], "%s*().*") if i == 458 then local x = 0 end if SVGEnd then for i2 = 1, #QrList do table.insert(Lines, i + i2 - 1, QrList[i2]) end end -- local _, _, PartDtmx, dX, dY = string.find(Lines[i], "%s*") -- if PartDtmx or dX or dY then -- Lines[i] = " " -- end -- local _, _, BinCartIndex = string.find(Lines[i], "%s*(%a%d*)") -- if BinCartIndex then -- Lines[i] = "" -- end end -- creo path in cui salvare csv per etichette local LabelSVGPath = "" -- se offline if IsOffline then LabelSVGPath = NestingLib.VerifyPath("SVG", BatchId, nil) -- salvo cartella Material.OfflineDrawingFolder = LabelSVGPath .. "/" if not UtilityLib.FolderExists(LabelSVGPath) then EgtCreateDirectory(LabelSVGPath) end LabelSVGPath = LabelSVGPath .. "/" .. Material.MatId .. "_" .. MachGroupName .. "_qr.svg" else LabelSVGPath = NestingLib.VerifyPath("SVG", BatchId, Material) if not UtilityLib.FolderExists(LabelSVGPath) then EgtCreateDirectory(LabelSVGPath) end LabelSVGPath = LabelSVGPath .. "/".. MachGroupName .. "_qr.svg" end -- scrittura delle linee modificate local fh2 = io.open( LabelSVGPath, 'w') if fh2 then for i = 1, #Lines do fh2:write( Lines[i] .. '\n') end fh2:close() end -- fine end -- funzione che crea le lavorazioni raggruppandole per tipologia ed ordinando i pezzi function CreateMachByOrderedType(Material, CurrRawPart, PartsBBox, nSkeletonLayerId, PartsPriority, ErrorList) -- chiamo funzione che lavora per tipologia dicendogli di considerare tutte le lavorazioni tranne i contorni local PartsArea = CreateMachByType(Material, CurrRawPart, PartsBBox, nSkeletonLayerId, PartsPriority, 3, ErrorList) -- chiamo funzione che lavora pezzi ordinati dicendogli di considerare solo i contorni CreateMachByPart(Material, CurrRawPart, PartsBBox, nSkeletonLayerId, PartsPriority, 2, ErrorList) return PartsArea end -- funzione che crea le lavorazioni raggruppandole per tipologia function CreateMachByType(Material, CurrRawPart, PartsBBox, nSkeletonLayerId, PartsPriority, nMachType, ErrorList) local PartsArea = 0 -- liste lavorazioni divise per tipo ed utensile per ottimizzazione algoritmo tsp -- local OutlineList = {} -- local SmallOutlineList = {} -- local IntIntOutlineList = {} -- local SkinOutlineList = {} -- local IntExtOutlineList = {} -- local InternalOutlineList = {} -- local PocketingList = {} -- local RampList = {} -- local HoleList = {} -- for HoleMach = 1, (#HoleMachining[2] + #Pocketing) do -- table.insert(HoleList, {}) -- end -- Recupero pezzi con possibili pezzi interni e ne calcolo il BBox local IntPathParts = {} local CurrPart = EgtGetFirstPartInRawPart(CurrRawPart) while CurrPart do if EgtGetInfo(CurrPart, INTPART, "d") == 1 then local LayerId = EgtGetFirstGroupInGroup(CurrPart) while LayerId do local layerName = EgtGetName(LayerId) local bOutline = false -- verifico se ha un nome di outline for Mach = 1, #OutlineMachining[1] do if layerName == OutlineMachining[1][Mach] then bOutline = true end end if bOutline then -- ciclo sui percorsi local PathId = EgtGetFirstInGroup(LayerId) while PathId do -- se è percorso interno con possibili pezzi if EgtGetInfo(PathId, INTPART, "d") == 1 then -- ne creo il bbox local b3IntPathPart = EgtGetBBoxGlob(PathId, 13) table.insert(IntPathParts, {PartId = CurrPart, PathId = PathId, BBox = b3IntPathPart}) end PathId = EgtGetNext(PathId) end end LayerId = EgtGetNextGroup(LayerId) end end -- passo al pezzo successivo CurrPart = EgtGetNextPartInRawPart(CurrPart) end -- applico lavorazioni ai gruppi di lavorazione -- local CurrRawPart = EgtGetFirstRawPart() -- local CurrPart = EgtGetFirstPartInRawPart(CurrRawPart) CurrPart = EgtGetFirstPartInRawPart(CurrRawPart) local bMachOk = true local LastMch = GDB_ID.NULL ResetSPMachList() while CurrPart do -- calcolo BBox part e lo aggiungo al globale per calcolo remnant local CurrPartBBox = EgtGetBBoxGlob(CurrPart, GDB_BB.STANDARD + GDB_BB.ONLY_VISIBLE + GDB_BB.IGNORE_TEXT + GDB_BB.IGNORE_DIM) if CurrPartBBox and not CurrPartBBox:isEmpty() then if not PartsBBox:Add( CurrPartBBox) then local x = 2 end else local x = 2 end -- calcolo area totale occupata local CutPartsArea = EgtGetFirstNameInGroup(nSkeletonLayerId, PARTCUTSUM) local OutlineLayer = EgtGetFirstNameInGroup(CurrPart, OUTLINE) local nPartSurfId = EgtGetFirstNameInGroup(OutlineLayer, EgtGetName(CurrPart)) if nPartSurfId ~= GDB_ID.NULL then if not CutPartsArea or CutPartsArea == GDB_ID.NULL then CutPartsArea = EgtCopyGlob(nPartSurfId, nSkeletonLayerId) EgtSetName(CutPartsArea, PARTCUTSUM) else if not nPartSurfId then local x = 2 end EgtSurfFrAdd(CutPartsArea, nPartSurfId) end end local nTrakSurfId = EgtGetFirstNameInGroup(OutlineLayer, SKELETONTRACK) while nTrakSurfId and nTrakSurfId ~= GDB_ID.NULL do if not CutPartsArea or CutPartsArea == GDB_ID.NULL then CutPartsArea = EgtCopyGlob(nTrakSurfId, nSkeletonLayerId) EgtSetName(CutPartsArea, PARTCUTSUM) else EgtSurfFrAdd(CutPartsArea, nTrakSurfId) end nTrakSurfId = EgtGetNextName(nTrakSurfId, SKELETONTRACK) end -- lo confronto con bbox percorsi interni per verificare se e' un pezzo interno local Index = 1 local bIntPathFound = false local bInternalPart = false while Index < #IntPathParts and not bIntPathFound do if EnclosesXY(IntPathParts[Index].BBox, CurrPartBBox) then bIntPathFound = true bInternalPart = true end Index = Index + 1 end CalcPartMachinings(Material, CurrPart, bInternalPart, LastMch, nMachType, bDoCalc, ErrorList) -- recupero e sommo aree di tutti i pezzi sul foglio local CurrArea = EgtGetInfo(CurrPart, AREA) PartsArea = PartsArea + CurrArea -- segno priorita' pezzo su lista delle priorita' del foglio local PartPriority = EgtGetInfo(CurrPart, PRIORITY) local bFound = false for PriorityIndex = 0, #PartsPriority do if PartPriority == PartsPriority[PriorityIndex] then bFound = true end end if not bFound then table.insert(PartsPriority, PartPriority) end -- passo al pezzo successivo CurrPart = EgtGetNextPartInRawPart(CurrPart) end -- ordino lavorzioni con algoritmo ts ProcessMachinings(HoleList, RampList, ChamferList, PocketingList, IntIntOutlineList, SkinOutlineList, IntExtOutlineList, InternalOutlineList, SmallOutlineList, OutlineList) return PartsArea end -- funzione che crea le lavorazioni raggruppandole per pezzo -- nMachType -> 1: All ; 2: only outline ; 3 all away from outline function CreateMachByPart(Material, CurrRawPart, PartsBBox, nSkeletonLayerId, PartsPriority, nMachType, ErrorList) local PartsArea = 0 -- lista pezzi per lavorazioni local VerySmallMachPartList = {} local SmallMachPartList = {} local MediumMachPartList = {} local MachPartList = {} -- Recupero pezzi con possibili pezzi interni e ne calcolo il BBox local CurrPart = EgtGetFirstPartInRawPart(CurrRawPart) while CurrPart do if EgtGetInfo(CurrPart, INTPART, "d") == 1 then local LayerId = EgtGetFirstGroupInGroup(CurrPart) local bOutline = false while LayerId and not bOutline do local layerName = EgtGetName(LayerId) -- verifico se ha un nome di outline for Mach = 1, #OutlineMachining[1] do if layerName == OutlineMachining[1][Mach] then bOutline = true end end if bOutline then -- ciclo sui percorsi local bIntPart = false local PathId = EgtGetFirstInGroup(LayerId) while PathId do -- se è percorso interno con possibili pezzi if EgtGetInfo(PathId, INTPART, "d") == 1 then bIntPart = true -- ne creo il bbox local b3IntPathPart = EgtGetBBoxGlob(PathId, 13) if not bIntPart then table.insert(MachPartList, {PartId = CurrPart, IntPathId = PathId, BBox = b3IntPathPart, bIntParts = true, IntPartList = {}}) end end PathId = EgtGetNext(PathId) end end LayerId = EgtGetNextGroup(LayerId) end end -- recupero e sommo aree di tutti i pezzi sul foglio local CurrArea = EgtGetInfo(CurrPart, AREA) PartsArea = PartsArea + CurrArea -- segno priorita' pezzo su lista delle priorita' del foglio local PartPriority = EgtGetInfo(CurrPart, PRIORITY) local bFound = false for PriorityIndex = 0, #PartsPriority do if PartPriority == PartsPriority[PriorityIndex] then bFound = true end end if not bFound then table.insert(PartsPriority, PartPriority) end -- passo al pezzo successivo CurrPart = EgtGetNextPartInRawPart(CurrPart) end -- ciclo sui pezzi per inserirli nella lista CurrPart = EgtGetFirstPartInRawPart(CurrRawPart) while CurrPart do -- calcolo area totale occupata -- local CutPartsArea = EgtGetFirstNameInGroup(nSkeletonLayerId, PARTCUTSUM) -- local OutlineLayer = EgtGetFirstNameInGroup(CurrPart, OUTLINE) -- local nPartSurfId = EgtGetFirstNameInGroup(OutlineLayer, EgtGetName(CurrPart)) -- local nTrakSurfId = EgtGetFirstNameInGroup(OutlineLayer, TOOLTRACK) -- if nPartSurfId ~= GDB_ID.NULL then -- if not CutPartsArea or CutPartsArea == GDB_ID.NULL then -- CutPartsArea = EgtCopy(nPartSurfId, nSkeletonLayerId) -- EgtSetName(CutPartsArea, PARTCUTSUM) -- else -- EgtSurfFrAdd(CutPartsArea, nPartSurfId) -- end -- end -- if nTrakSurfId ~= GDB_ID.NULL then -- if not CutPartsArea or CutPartsArea == GDB_ID.NULL then -- CutPartsArea = EgtCopy(nTrakSurfId, nSkeletonLayerId) -- EgtSetName(CutPartsArea, PARTCUTSUM) -- else -- EgtSurfFrAdd(CutPartsArea, nTrakSurfId) -- end -- end -- calcolo BBox part e lo aggiungo al globale per calcolo remnant local CurrPartBBox = EgtGetBBoxGlob(CurrPart, GDB_BB.STANDARD + GDB_BB.ONLY_VISIBLE + GDB_BB.IGNORE_TEXT + GDB_BB.IGNORE_DIM) -- lo aggiungo a bbox generico per calcolo remnant PartsBBox:Add( CurrPartBBox) -- lo confronto con bbox percorsi interni per verificare se e' un pezzo interno local Index = 1 local bIntPathFound = false local bExtPathFound = false while Index < #MachPartList and not bExtPathFound and not bIntPathFound do -- se già in lista perchè può contenere interni, lo segno per saltarlo if MachPartList[Index].PartId == CurrPart then bExtPathFound = true end if MachPartList[Index].bIntParts and EnclosesXY(MachPartList[Index].BBox, CurrPartBBox) then table.insert(MachPartList[Index].IntPartList, {PartId = CurrPart, BBox = CurrPartBBox}) bIntPathFound = true end Index = Index + 1 end -- se non può avere interni e non è interno, lo aggiungo alla lista if not bExtPathFound and not bIntPathFound then -- se pezzo piccolo local dGeomArea = EgtGetInfo(CurrPart, AREA, 'd') local dMinSideArea = CurrPartBBox:getDimX() if CurrPartBBox:getDimY() < dMinSideArea then dMinSideArea = CurrPartBBox:getDimY() end if dGeomArea < Config.dVerySmallPartArea then table.insert(VerySmallMachPartList, {PartId = CurrPart, BBox = CurrPartBBox, bIntParts = false}) elseif dGeomArea < Config.dSmallPartArea or dMinSideArea < Config.dSmallPartSide then table.insert(SmallMachPartList, {PartId = CurrPart, BBox = CurrPartBBox, bIntParts = false}) elseif dGeomArea < Config.dMediumPartArea then table.insert(MediumMachPartList, {PartId = CurrPart, BBox = CurrPartBBox, bIntParts = false}) else table.insert(MachPartList, {PartId = CurrPart, BBox = CurrPartBBox, bIntParts = false}) end end -- passo al pezzo successivo CurrPart = EgtGetNextPartInRawPart(CurrPart) end -- ordino liste pezzi VerySmallMachPartList = SortParts(VerySmallMachPartList, false) SmallMachPartList = SortParts(SmallMachPartList, false) MediumMachPartList = SortParts(MediumMachPartList, true) MachPartList = SortParts(MachPartList, true) local LastMch = GDB_ID.NULL -- lavoro pezzi molto piccoli for CurrPart = 1, #VerySmallMachPartList do -- ne calcolo le lavorazioni LastMch = CalcPartMachinings(Material, VerySmallMachPartList[CurrPart].PartId, false, LastMch, nMachType, true, ErrorList) end -- lavoro pezzi piccoli for CurrPart = 1, #SmallMachPartList do -- ne calcolo le lavorazioni LastMch = CalcPartMachinings(Material, SmallMachPartList[CurrPart].PartId, false, LastMch, nMachType, true, ErrorList) end -- lavoro pezzi medi for CurrPart = 1, #MediumMachPartList do -- ne calcolo le lavorazioni LastMch = CalcPartMachinings(Material, MediumMachPartList[CurrPart].PartId, false, LastMch, nMachType, true, ErrorList) end -- ciclo per ordinare i pezzi interni for CurrPart = 1, #MachPartList do -- se ci sono pezzi interni if MachPartList[CurrPart].bIntParts then -- li ordino MachPartList[CurrPart].IntPartList = SortParts(MachPartList[CurrPart].IntPartList, true) -- ciclo su questi for CurrIntPart = 1, #MachPartList[CurrPart].IntPartList do -- ne calcolo le lavorazioni LastMch = CalcPartMachinings(Material, MachPartList[CurrPart].IntPartList[CurrIntPart].PartId, true, LastMch, nMachType, true, ErrorList) end end -- ne calcolo le lavorazioni LastMch = CalcPartMachinings(Material, MachPartList[CurrPart].PartId, true, LastMch, nMachType, true, ErrorList) end return PartsArea end -- funzione che resetta le liste lavorazioni function ResetSPMachList() OutlineList = {} SmallOutlineList = {} IntIntOutlineList = {} SkinOutlineList = {} IntExtOutlineList = {} InternalOutlineList = {} PocketingList = {} RampList = {} ChamferList = {} HoleList = {} for HoleMach = 1, (#HoleMachining[2] + #Pocketing) do table.insert(HoleList, {}) end end -- funzione che crea le lavorazioni raggruppandole per pezzo -- nMachType -> 1: All ; 2: only outline ; 3 all away from outline -- bDoCalc -> se vero avvia algoritmo Sp, altrimenti raggruppa solo tutte le lavorazioni presenti nel pezzo function CalcPartMachinings(Material, CurrPart, bInternalPart, LastMch, nMachType, bDoCalc, ErrorList) if bDoCalc then ResetSPMachList() end -- cerco tra i nomi di outline for OutMach = 1, #OutlineMachining[1] do local CurrLayer = EgtGetFirstNameInGroup(CurrPart, OutlineMachining[1][OutMach]) -- se ne trovo uno valido if CurrLayer then -- aggiungo lavorazioni local CurrGeom = EgtGetFirstInGroup(CurrLayer) while CurrGeom do -- verifico spessore local Depth = EgtCurveThickness(CurrGeom) -- if -Depth >= (Material.T_mm - Config.ThicknessTolerance) and -Depth <= (Material.T_mm + Config.ThicknessTolerance) then if -Depth >= (Material.T_mm - Config.ThicknessTolerance) then -- verifico se e' outline local bValidOutlineMach = false local MachToDo = false local GeomName = EgtGetName(CurrGeom) local CurrGeomColor = EgtGetCalcColor(CurrGeom) if GeomName == OUTLINE then if nMachType == 1 or nMachType == 2 then MachToDo = true for OutlineMachIndex = 1, #OutlineMachining[2] do if not bValidOutlineMach then local NewMachId = EgtAddMachining(OutlineMachining[1][OutMach], OutlineMachining[2][OutlineMachIndex]) EgtSetMachiningGeometry(CurrGeom) local nOutlineLayerId = EgtGetFirstNameInGroup(CurrPart, OUTLINE) local nCurrMode = 0 if EgtGetInfo(nOutlineLayerId, CUTOPT) == "TAB" then nCurrMode = 2 elseif EgtGetInfo(nOutlineLayerId, CUTOPT) == "SKIN" then nCurrMode = 1 elseif EgtGetInfo(nOutlineLayerId, CUTOPT) == "SKELETON" then nCurrMode = 3 elseif EgtGetInfo(nOutlineLayerId, CUTOPT) == "SKELETON&TAB" then nCurrMode = 4 end local dGeomArea = EgtGetInfo(CurrPart, AREA, 'd') if nCurrMode == 0 and dGeomArea < Config.dSkelSkinTab_MaxArea then nCurrMode = Config.nSkelSkinTabMode end -- se modalità skin if nCurrMode == 1 then local SkinMachId = EgtAddMachining(OutlineMachining[1][OutMach], OutlineMachining[2][OutlineMachIndex]) EgtSetMachiningGeometry(CurrGeom) -- abilito tab EgtSetMachiningParam(MCH_MP.DEPTH_STR, "TH-" .. dSkinThickness) -- applico la lavorazione principale sopraelevata if EgtApplyMachining() then InitInTSP(SkinMachId, SkinOutlineList, 0) end -- rendo corrente lavorazione principale EgtSetCurrMachining(NewMachId) -- se modalità tab o skeleton&tab elseif nCurrMode == 2 or nCurrMode == 4 then -- abilito tab EgtSetMachiningParam(MCH_MP.LEAVETAB, true) EgtSetMachiningParam(MCH_MP.FEED, Config.dTabFeed) for CurrMat = 1, #Config.TabParams do if Config.TabParams[CurrMat].MatExtCode == Material.MatExtCode then EgtSetMachiningParam(MCH_MP.TABLEN, Config.TabParams[CurrMat].Length) EgtSetMachiningParam(MCH_MP.TABHEIGHT, Config.TabParams[CurrMat].Height) EgtSetMachiningParam(MCH_MP.TABANGLE, Config.TabParams[CurrMat].Angle) EgtSetMachiningParam(MCH_MP.TABDIST, Config.TabParams[CurrMat].Distance) EgtSetMachiningParam(MCH_MP.TABMAX, Config.TabParams[CurrMat].MaxCount) EgtSetMachiningParam(MCH_MP.TABMIN, Config.TabParams[CurrMat].MinCount) end end -- if dGeomArea < 32 then -- 3225 then -- EgtSetMachiningParam(MCH_MP.FEED, 8000) -- EgtSetMachiningParam(MCH_MP.TABMIN, 2) -- EgtSetMachiningParam(MCH_MP.TABMAX, 3) -- EgtSetMachiningParam(MCH_MP.TABDIST, 60) -- elseif dGeomArea < 11612 then -- EgtSetMachiningParam(MCH_MP.FEED, 8000) -- EgtSetMachiningParam(MCH_MP.TABMIN, 0) --2) -- EgtSetMachiningParam(MCH_MP.TABMAX, 16) --4) -- EgtSetMachiningParam(MCH_MP.TABDIST, 10000) --100) -- else -- EgtSetMachiningParam(MCH_MP.TABMIN, 0) --2) -- EgtSetMachiningParam(MCH_MP.TABMAX, 16) --4) -- EgtSetMachiningParam(MCH_MP.TABDIST, 10000) --100) -- end else EgtSetMachiningParam(MCH_MP.LEAVETAB, true) EgtSetMachiningParam(MCH_MP.TABMIN, 0) EgtSetMachiningParam(MCH_MP.TABMAX, 16) EgtSetMachiningParam(MCH_MP.TABDIST, 30000) end -- se pezzo piccolo if Config.bSmallFeedReduce and dGeomArea < 11612 then -- 3225 then EgtSetMachiningParam(MCH_MP.FEED, Config.dSmallFeed) end -- imposto elevazione a spessore + 2 -- EgtSetMachiningParam(MCH_MP.LIELEV, Material.T_mm + 2) -- applico la lavorazione if EgtApplyMachining() then bValidOutlineMach = true if bInternalPart then InitInTSP(NewMachId, IntExtOutlineList, 0) elseif dGeomArea < Config.dSkelSkinTab_MaxArea then InitInTSP(NewMachId, SmallOutlineList, 0) else InitInTSP(NewMachId, OutlineList, 0) end EgtSetMachiningParam(MCH_MP.USERNOTES,'Outline = 1') else EgtRemoveOperation(NewMachId) end end end end elseif AreSameColor(Config.colPocketingPaths, CurrGeomColor, 10) then -- EgtCurveIsACircle(CurrGeom) then if nMachType == 1 or nMachType == 3 then MachToDo = true for PocketingIndex = 1, #Pocketing do if not bValidOutlineMach then local NewMachId = EgtAddMachining(Pocketing[PocketingIndex], Pocketing[PocketingIndex]) EgtSetMachiningGeometry(CurrGeom) -- applico la lavorazione if EgtApplyMachining() then bValidOutlineMach = true InitInTSP(NewMachId, PocketingList, 0) else EgtRemoveOperation(NewMachId) end end end end else -- percorso interno if nMachType == 1 or nMachType == 2 then MachToDo = true for OutlineMachIndex = 1, #OutlineMachining[2] do if not bValidOutlineMach then local NewMachId = EgtAddMachining(OutlineMachining[1][OutMach], OutlineMachining[2][OutlineMachIndex]) EgtSetMachiningGeometry(CurrGeom) -- if EgtGetInfo(CurrPart, AREA, 'd') < Config.dSkelSkinTab_MaxArea then EgtSetMachiningParam(MCH_MP.LEAVETAB, true) EgtSetMachiningParam(MCH_MP.TABMIN, 0) EgtSetMachiningParam(MCH_MP.TABMAX, 16) EgtSetMachiningParam(MCH_MP.TABDIST, 30000) -- end -- imposto elevazione a spessore + 2 -- EgtSetMachiningParam(MCH_MP.LIELEV, Material.T_mm + 2) -- applico la lavorazione if EgtApplyMachining() then bValidOutlineMach = true if bInternalPart then InitInTSP(NewMachId, IntIntOutlineList, 0) else InitInTSP(NewMachId, InternalOutlineList, 0) end else EgtRemoveOperation(NewMachId) end end end end end if MachToDo and not bValidOutlineMach then local PartId = EgtGetInfo(CurrPart, PARTID) if not PartId then PartId = "" end table.insert(ErrorList, {ErrType = "E.7", Uid = "PartId = " .. PartId, Description = "Error in outline machining!"}) end -- se spessore pezzo è maggiore del materiale do errore if -Depth >= (Material.T_mm + Config.ThicknessTolerance) then local PartId = EgtGetInfo(CurrPart, PARTID) if not PartId then PartId = "" end table.insert(ErrorList, {ErrType = "E.7", Uid = "PartId = " .. PartId, Description = "Error in machining! Part(" .. -Depth .. ") thicker than material(" .. Material.T_mm .. ")"}) end else if nMachType == 1 or nMachType == 3 then local bValidPocketing = false for PocketingIndex = 1, #Pocketing do if not bValidPocketing then local NewMachId = EgtAddMachining(Pocketing[PocketingIndex], Pocketing[PocketingIndex]) EgtSetMachiningGeometry(CurrGeom) -- applico la lavorazione if EgtApplyMachining() then bValidPocketing = true InitInTSP(NewMachId, PocketingList, 0) else EgtRemoveOperation(NewMachId) end end end if not bValidPocketing then local PartId = EgtGetInfo(CurrPart, PARTID) if not PartId then PartId = "" end table.insert(ErrorList, {ErrType = "E.7", Uid = "PartId = " .. PartId, Description = "Error in machining!"}) end end end CurrGeom = EgtGetNext(CurrGeom) end end end if nMachType == 1 or nMachType == 3 then -- cerco layer fori local HoleLayer = EgtGetFirstNameInGroup(CurrPart, HoleMachining[1]) -- se lo trovo if HoleLayer then -- verifico le geometrie presenti local CurrGeom = EgtGetFirstInGroup(HoleLayer) while CurrGeom do if EgtGetType(CurrGeom) == GDB_TY.CRV_ARC then local OperationName = "" local MachName = "" -- variabile necessaria per differenziare le varie forature e pocketing local HoleMachIndex = 0 local CurrRad = EgtArcRadius(CurrGeom) for HoleMach = 1, #HoleMachining[2] do if EgtMdbSetCurrMachining(HoleMachining[2][HoleMach]) then local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL) EgtTdbSetCurrTool(ToolName) local ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.DIAM) if ToolDiam and ToolDiam > 0 then if CurrRad * 2 <= ToolDiam + (GEO.EPS_SMALL * 1000 * Config.HoleTolerance) and CurrRad * 2 >= ToolDiam - (GEO.EPS_SMALL * 1000 * Config.HoleTolerance) then MachName = HoleMachining[2][HoleMach] OperationName = HoleMachining[1] HoleMachIndex = HoleMach end end end end -- se non ho trovato una punta per farlo if MachName == "" and (CurrRad * 2) > 6.35 then -- -- prendo il pocketing con diametro più grande tra quelli più piccoli del foro -- local DiamOffset = 100 -- for PocketingIndex = 1, #Pocketing do -- if EgtMdbSetCurrMachining(Pocketing[PocketingIndex]) then -- local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL) -- EgtTdbSetCurrTool(ToolName) -- local ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.DIAM) -- if ToolDiam and ToolDiam > 0 then -- local CurrOffset = (CurrRad * 2) - ToolDiam -- if CurrOffset > 0 and CurrOffset < DiamOffset then -- MachName = Pocketing[PocketingIndex] -- OperationName = Pocketing[PocketingIndex] -- HoleMachIndex = #HoleMachining[2] + PocketingIndex -- DiamOffset = CurrOffset -- end -- end -- end -- end -- provo a fare il pocketing con diametro 1/4 for PocketingIndex = 1, #Pocketing do if EgtMdbSetCurrMachining(Pocketing[PocketingIndex]) then local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL) EgtTdbSetCurrTool(ToolName) local ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.DIAM) if ToolDiam and ToolDiam > 0 and 6.35 <= ToolDiam + (GEO.EPS_SMALL * 10) and 6.35 >= ToolDiam - (GEO.EPS_SMALL * 10) then MachName = Pocketing[PocketingIndex] OperationName = Pocketing[PocketingIndex] HoleMachIndex = #HoleMachining[2] + PocketingIndex end end end end -- se non ho trovato nemmeno un pocketing per farlo if MachName == "" then -- faccio un foro da 1/8 for HoleMach = 1, #HoleMachining[2] do if EgtMdbSetCurrMachining(HoleMachining[2][HoleMach]) then local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL) EgtTdbSetCurrTool(ToolName) local ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.DIAM) if ToolDiam and ToolDiam > 0 and 3.175 <= ToolDiam + (GEO.EPS_SMALL * 10) and 3.175 >= ToolDiam - (GEO.EPS_SMALL * 10) then MachName = HoleMachining[2][HoleMach] OperationName = HoleMachining[1] HoleMachIndex = HoleMach end end end end if MachName ~= "" then local NewMachId = EgtAddMachining(OperationName, MachName) EgtSetMachiningGeometry(CurrGeom) -- applico la lavorazione if not EgtApplyMachining() then table.insert(ErrorList, {ErrType = "E.7", Uid = "Generic", Description = "Error in hole machining!"}) else InitInTSP(NewMachId, HoleList, HoleMachIndex) end end end CurrGeom = EgtGetNext(CurrGeom) end end -- cerco layer rampe local RampLayer = EgtGetFirstNameInGroup(CurrPart, RampMachining[1]) -- se lo trovo if RampLayer then -- verifico le geometrie presenti local CurrGeom = EgtGetFirstInGroup(RampLayer) while CurrGeom do -- se non e' gia' percorso di lavorazione if not EgtGetInfo(CurrGeom, MACHPATH) then -- se e' curva composita if EgtGetType(CurrGeom) == GDB_TY.CRV_COMPO then -- creo percorso di lavorazione local MachRampGeom = EgtCopyGlob(CurrGeom, RampLayer) local nMachPath = CreateRampMachPath(MachRampGeom, RampLayer) local bValidOutlineMach = false if nMachPath and nMachPath ~= GDB_ID.NULL then local NewMachId = EgtAddMachining(RampMachining[1], RampMachining[2]) EgtSetMachiningGeometry(nMachPath) EgtSetMachiningParam(MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER) EgtSetMachiningParam(MCH_MP.INVERT, false) -- applico la lavorazione if EgtApplyMachining() then bValidOutlineMach = true InitInTSP(NewMachId, InternalOutlineList, 0) end if not bValidOutlineMach then local PartId = EgtGetInfo(CurrPart, PARTID) if not PartId then PartId = "" end table.insert(ErrorList, {ErrType = "E.7", Uid = "PartId = " .. PartId, Description = "Error in ramp machining!"}) end end end end CurrGeom = EgtGetNext(CurrGeom) end end -- cerco layer Countersink local CountersinkLayer = EgtGetFirstNameInGroup(CurrPart, CountersinkMachining[1]) -- se lo trovo if CountersinkLayer then -- verifico le geometrie presenti local CurrGeom = EgtGetFirstInGroup(CountersinkLayer) while CurrGeom do -- se non e' gia' percorso di lavorazione if not EgtGetInfo(CurrGeom, MACHPATH) then -- se e' arco if EgtGetType(CurrGeom) == GDB_TY.CRV_ARC then local NewMachId = EgtAddMachining(CountersinkMachining[1], CountersinkMachining[2]) EgtSetMachiningGeometry(CurrGeom) local dRadius = EgtArcRadius( CurrGeom) local dMaxWidth = ( dRadius * 2) - 1 local ToolDiam = 0 local ToolHeight = 0 if EgtMdbSetCurrMachining(OutsideChamferMachining[2]) then local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL) EgtTdbSetCurrTool(ToolName) ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.TOTDIAM) ToolHeight = EgtTdbGetCurrToolParam(MCH_TP.MAXMAT) end local dDepth = min( dMaxWidth / 2, Material.T_mm, ToolDiam / 2, ToolHeight) local dRadial = dDepth EgtSetMachiningParam(MCH_MP.DEPTH, dDepth) EgtSetMachiningParam(MCH_MP.OFFSR, dRadial) EgtSetMachiningParam(MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) -- applico la lavorazione local bValidOutlineMach = false if EgtApplyMachining() then bValidOutlineMach = true InitInTSP(NewMachId, InternalOutlineList, 0) end if not bValidOutlineMach then local PartId = EgtGetInfo(CurrPart, PARTID) if not PartId then PartId = "" end table.insert(ErrorList, {ErrType = "E.7", Uid = "PartId = " .. PartId, Description = "Error in Countersink machining!"}) end end end CurrGeom = EgtGetNext(CurrGeom) end end -- cerco layer Outside Chamfer local OutsideChamferLayer = EgtGetFirstNameInGroup(CurrPart, OutsideChamferMachining[1]) -- se lo trovo if OutsideChamferLayer then -- verifico le geometrie presenti local CurrGeom = EgtGetFirstInGroup(OutsideChamferLayer) while CurrGeom do -- se non e' gia' percorso di lavorazione if not EgtGetInfo(CurrGeom, MACHPATH) then -- se e' curva composita if EgtGetType(CurrGeom) == GDB_TY.CRV_COMPO then local dChamferWidth = EgtGetInfo( CurrGeom, 'ChamferWidth', 'd') -- se trovo info spessore del chamfer if dChamferWidth then -- creo lavorazione local NewMachId = EgtAddMachining(OutsideChamferMachining[1], OutsideChamferMachining[2]) EgtSetMachiningGeometry(CurrGeom) -- calcolo affondamento ed offset radiale dChamferWidth = dChamferWidth local dMaxWidth = dChamferWidth + 8 local ToolDiam = 0 if EgtMdbSetCurrMachining(OutsideChamferMachining[2]) then local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL) EgtTdbSetCurrTool(ToolName) ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.TOTDIAM) end local dDepth = min( dMaxWidth / 2, Material.T_mm, ToolDiam / 2) local dRadial = dDepth - dChamferWidth EgtSetMachiningParam(MCH_MP.DEPTH, dDepth) EgtSetMachiningParam(MCH_MP.OFFSR, dRadial) EgtSetMachiningParam(MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) -- applico la lavorazione local bValidOutlineMach = false if EgtApplyMachining() then bValidOutlineMach = true InitInTSP(NewMachId, InternalOutlineList, 0) end if not bValidOutlineMach then local PartId = EgtGetInfo(CurrPart, PARTID) if not PartId then PartId = "" end table.insert(ErrorList, {ErrType = "E.7", Uid = "PartId = " .. PartId, Description = "Error in OutsideChamfer machining!"}) end end end end CurrGeom = EgtGetNext(CurrGeom) end end -- cerco layer Inside Chamfer local InsideChamferLayer = EgtGetFirstNameInGroup(CurrPart, InsideChamferMachining[1]) -- se lo trovo if InsideChamferLayer then -- verifico le geometrie presenti local CurrGeom = EgtGetFirstInGroup(InsideChamferLayer) while CurrGeom do -- se non e' gia' percorso di lavorazione if not EgtGetInfo(CurrGeom, MACHPATH) then -- se e' curva composita if EgtGetType(CurrGeom) == GDB_TY.CRV_COMPO then local dChamferWidth = EgtGetInfo( CurrGeom, 'ChamferWidth', 'd') -- se trovo info spessore del chamfer if dChamferWidth then -- creo lavorazione local NewMachId = EgtAddMachining(InsideChamferMachining[1], InsideChamferMachining[2]) EgtSetMachiningGeometry(CurrGeom) -- calcolo affondamento ed offset radiale dChamferWidth = dChamferWidth local dMaxWidth = dChamferWidth + 8 local ToolDiam = 0 if EgtMdbSetCurrMachining(InsideChamferMachining[2]) then local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL) EgtTdbSetCurrTool(ToolName) ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.TOTDIAM) end local dDepth = min( dMaxWidth / 2, Material.T_mm, ToolDiam / 2) local dRadial = dDepth - dChamferWidth EgtSetMachiningParam(MCH_MP.DEPTH, dDepth) EgtSetMachiningParam(MCH_MP.OFFSR, dRadial) EgtSetMachiningParam(MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) -- applico la lavorazione local bValidOutlineMach = false if EgtApplyMachining() then bValidOutlineMach = true InitInTSP(NewMachId, InternalOutlineList, 0) end if not bValidOutlineMach then local PartId = EgtGetInfo(CurrPart, PARTID) if not PartId then PartId = "" end table.insert(ErrorList, {ErrType = "E.7", Uid = "PartId = " .. PartId, Description = "Error in InsideChamfer machining!"}) end end end end CurrGeom = EgtGetNext(CurrGeom) end end end if bDoCalc then -- ordino lavorzioni con algoritmo ts return ProcessMachinings(HoleList, RampList, ChamferList, PocketingList, IntIntOutlineList, SkinOutlineList, IntExtOutlineList, InternalOutlineList, SmallOutlineList, OutlineList, LastMch) end end -- funzione che crea i percorsi di lavorazione per le rampe function CreateRampMachPath(CurrGeom, RampLayer) -- rendo il percorso antiorario if EgtCurveAreaXY(CurrGeom) < 0 then EgtInvertCurve(CurrGeom) end -- riconosco i vari segmenti local nFirstLine, nLines = EgtExplodeCurveCompo(CurrGeom) local nTopBorder = 0 local dTopZ = 0 local nBottomBorder = 0 local nLeftBorder = 0 local nRightBorder = 0 for LineIndex = 0, nLines - 1 do local dDeltaZ = EgtEP(nFirstLine + LineIndex):getZ() - EgtSP(nFirstLine + LineIndex):getZ() if abs(dDeltaZ) < 10 * GEO.EPS_SMALL then if nTopBorder == 0 then nTopBorder = nFirstLine + LineIndex dTopZ = EgtEP(nFirstLine + LineIndex):getZ() elseif EgtEP(nFirstLine + LineIndex):getZ() > dTopZ then nBottomBorder = nTopBorder nTopBorder = nFirstLine + LineIndex else nBottomBorder = nFirstLine + LineIndex end elseif dDeltaZ < 0 then nLeftBorder = nFirstLine + LineIndex elseif dDeltaZ > 0 then nRightBorder = nFirstLine + LineIndex end end -- recupero diametro utensile di lavorazione local dToolDiam = 0 if EgtMdbSetCurrMachining(RampMachining[2]) then local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL) EgtTdbSetCurrTool(ToolName) dToolDiam = EgtTdbGetCurrToolParam(MCH_TP.DIAM) end -- verifico quante passate servono local nDiamInLength = EgtCurveLength(nTopBorder) / (dToolDiam - (10 * GEO.EPS_SMALL)) local nMachinePaths = 0 if nDiamInLength >= 1 then nMachinePaths = math.ceil(EgtCurveLength(nTopBorder) / (dToolDiam - (10 * GEO.EPS_SMALL))) end local dDeltaPaths = 0 if nMachinePaths > 1 then dDeltaPaths = (EgtCurveLength(nTopBorder) - dToolDiam) / (nMachinePaths - 1) end -- creo le passate aggiuntive come copie e le posiziono local vtDirection = (EgtEP(nRightBorder) - EgtSP(nLeftBorder)) vtDirection:normalize() local ptLast local nCompoPath = 0 if nMachinePaths >=1 then for PathIndex = 0, nMachinePaths - 1 do if PathIndex % 2 == 0 then if PathIndex == 0 then local nPath = EgtCopy(nLeftBorder, nLeftBorder, GDB_IN.AFTER) EgtMove(nPath, vtDirection * dToolDiam / 2) -- creo curva composita nCompoPath = EgtCurveCompo(RampLayer, nPath) ptLast = EgtEP(nPath) else local nPath = EgtCopy(nLeftBorder, nLeftBorder, GDB_IN.AFTER) EgtMove(nPath, (vtDirection * dToolDiam / 2) + (vtDirection * dDeltaPaths * PathIndex / 2)) -- creo collegamento e lo aggiungo a composita local nLinkPath = EgtLine(RampLayer, ptLast, EgtSP(nPath)) -- fisso punto finale per prossimo collegamento ptLast = EgtEP(nPath) EgtAddCurveCompoCurve(nCompoPath, nLinkPath) EgtAddCurveCompoCurve(nCompoPath, nPath) end else if PathIndex == 1 then local nPath = EgtCopy(nRightBorder, nRightBorder, GDB_IN.AFTER) EgtMove(nPath, -vtDirection * dToolDiam / 2) -- creo collegamento e lo aggiungo a composita local nLinkPath = EgtLine(RampLayer, ptLast, EgtSP(nPath)) -- fisso punto finale per prossimo collegamento ptLast = EgtEP(nPath) EgtAddCurveCompoCurve(nCompoPath, nLinkPath) EgtAddCurveCompoCurve(nCompoPath, nPath) else local nPath = EgtCopy(nRightBorder, nRightBorder, GDB_IN.AFTER) EgtMove(nPath, -((vtDirection * dToolDiam / 2) + (vtDirection * dDeltaPaths * (PathIndex - 1) / 2))) -- creo collegamento e lo aggiungo a composita local nLinkPath = EgtLine(RampLayer, ptLast, EgtSP(nPath)) -- fisso punto finale per prossimo collegamento ptLast = EgtEP(nPath) EgtAddCurveCompoCurve(nCompoPath, nLinkPath) EgtAddCurveCompoCurve(nCompoPath, nPath) end end end else return GDB_ID.NULL end -- scrivo info per lavorazione EgtSetInfo(nCompoPath, MACHPATH, 1) return nCompoPath end -- -- funzione che salva immagine per etichetta verniciati function NestingLib.ManageMachine(CurrIsOffline) -- svuoto tutto OutlineMachining = {} HoleMachining = {} RampMachining = {} CountersinkMachining = {} OutsideChamferMachining = {} InsideChamferMachining = {} Pocketing = {} IsOffline = false -- aggiungo liste nomi layer in prima posizione table.insert(OutlineMachining, 1, Config.OutlineMachName) -- table.insert(HoleMachining, 1, Config.HoleMachName) -- table.insert(RampMachining, 1, Config.RampMachName) HoleMachining[1] = Config.HoleMachName[1] RampMachining[1] = Config.RampMachName[1] CountersinkMachining[1] = Config.CountersinkMachName[1] OutsideChamferMachining[1] = Config.OutsideChamferMachName[1] InsideChamferMachining[1] = Config.InsideChamferMachName[1] -- se offline imposto lavorazioni macchina NorthWood if CurrIsOffline then sCurrMachName = "Northwood-RHD" EgtSetCurrMachine(sCurrMachName) table.insert(OutlineMachining, 2, Config.NWOutlineMachTools) table.insert(HoleMachining, 2, Config.NWHoleMachTools) table.insert(RampMachining, 2, Config.NWRampMachTools[1]) table.insert(CountersinkMachining, 2, Config.NWCountersinkMachTools[1]) table.insert(OutsideChamferMachining, 2, Config.MXOutsideChamferMachTools[1]) table.insert(InsideChamferMachining, 2, Config.NWInsideChamferMachTools[1]) Pocketing = Config.NWPocketingTools IsOffline = true else sCurrMachName = "Multiax-NE_Nest01" EgtSetCurrMachine(sCurrMachName) table.insert(OutlineMachining, 2, Config.MXOutlineMachTools) table.insert(HoleMachining, 2, Config.MXHoleMachTools) table.insert(RampMachining, 2, Config.MXRampMachTools[1]) table.insert(CountersinkMachining, 2, Config.MXCountersinkMachTools[1]) table.insert(OutsideChamferMachining, 2, Config.MXOutsideChamferMachTools[1]) table.insert(InsideChamferMachining, 2, Config.MXInsideChamferMachTools[1]) Pocketing = Config.MXPocketingTools IsOffline = false end end -- --------------------------------------------------------------------- return NestingLib