Files
NKCLUAScript/NestingLib.lua
T

2807 lines
136 KiB
Lua

--
-- 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, IsEstimate)
local BigPartsQty = 0
local LastId = GDB_ID.ROOT
for Part = 1, #PartList do
--if PartList[Part].PartExtCode == '14162182' or PartList[Part].PartExtCode == '14162184' then
-- x = 5
--end
-- 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
local bBigPart = 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)
-- verifico se e' grande quasi come il foglio
local dTempX = OutlineBox:getDimX()
local dTempY = OutlineBox:getDimY()
local bRotated = false
if dTempY > dTempX then
bRotated = true
dTempX = OutlineBox:getDimY()
dTempY = OutlineBox:getDimX()
end
-- ricavo Kerf del 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
if dTempX > Material.L_mm - max( 51, dKerf) - dKerf and dTempY > Material.W_mm - max( 26, dKerf) - dKerf then
-- verifico se occupa l'angolo
local nInside1 = 0
local nInside2 = 0
if not bRotated then
local LabelRegId = EgtSurfFrRectangle( EgtGetParent( nMaxId), OutlineBox:getMin() + ( OutlineBox:getDimY() - 26) * Y_AX() - 10 * X_AX(), OutlineBox:getMin() + ( OutlineBox:getDimY() + 10) * Y_AX() + 51 * X_AX(), GDB_RT.GLOB)
nInside1 = EgtCurveWithRegionClassify( nMaxId, LabelRegId)
EgtErase( LabelRegId)
LabelRegId = EgtSurfFrRectangle( EgtGetParent( nMaxId), OutlineBox:getMax() - ( OutlineBox:getDimY() - 10) * Y_AX() - 51 * X_AX(), OutlineBox:getMax() + 10 * X_AX() - ( OutlineBox:getDimY() - 26) * Y_AX(), GDB_RT.GLOB)
nInside2 = EgtCurveWithRegionClassify( nMaxId, LabelRegId)
EgtErase( LabelRegId)
--_, _, nInside1 = EgtPointCurveDistSide( OutlineBox:getMin() + ( OutlineBox:getDimY() - 26) * Y_AX() + 51 * X_AX(), nMaxId, Z_AX())
--_, _, nInside2 = EgtPointCurveDistSide( OutlineBox:getMax() - ( OutlineBox:getDimY() - 26) * Y_AX() - 51 * X_AX(), nMaxId, Z_AX())
else
local LabelRegId = EgtSurfFrRectangle( EgtGetParent( nMaxId), OutlineBox:getMin() - 10 * X_AX() - 10 * Y_AX(), OutlineBox:getMin() + 51 * Y_AX() + 26 * X_AX(), GDB_RT.GLOB)
nInside1 = EgtCurveWithRegionClassify( nMaxId, LabelRegId)
EgtErase( LabelRegId)
LabelRegId = EgtSurfFrRectangle( EgtGetParent( nMaxId), OutlineBox:getMax() - 51 * Y_AX() - 26 * X_AX(), OutlineBox:getMax() + 10 * X_AX() + 10 * Y_AX(), GDB_RT.GLOB)
nInside2 = EgtCurveWithRegionClassify( nMaxId, LabelRegId)
EgtErase( LabelRegId)
--_, _, nInside1 = EgtPointCurveDistSide( OutlineBox:getMin() + 51 * Y_AX() + 26 * X_AX(), nMaxId, Z_AX())
--_, _, nInside2 = EgtPointCurveDistSide( OutlineBox:getMax() - 51 * Y_AX() - 26 * X_AX(), nMaxId, Z_AX())
end
if nInside1 ~= GDB_CRC.OUT and nInside2 ~= GDB_CRC.OUT then
bBigPart = true
BigPartsQty = BigPartsQty + 1
end
end
-- 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 bBigPart and not IsEstimate then
Priority = 1
elseif 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
--EgtSaveFile("c:\\Temp\\TestSauderBig.nge")
return BigPartsQty
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
local BigPartsQty = 0
BigPartsQty = AddPartListToNesting(PartList, ErrorList, Material, IsEstimate) or 0
-- 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
-- se ci sono pezzi grandi
if BigPartsQty > 0 then
-- creo un ugual numero di fogli senza etichetta
local BigSheetPartId = EgtGroup(GDB_ID.ROOT)
EgtSetName(BigSheetPartId, "Sheet")
local BigSheetLayerId = EgtGroup(BigSheetPartId)
EgtSetName(BigSheetLayerId, OUTLINE)
local BigSheetOutlineId = EgtRectangle2P(BigSheetLayerId, Point3d(0,0,0), Point3d(Material.L_mm, Material.W_mm, 0), GDB_RT.GLOB)
EgtModifyCurveThickness(BigSheetOutlineId, -Material.T_mm)
EgtSetName(BigSheetOutlineId, OUTLINE)
EgtAutoNestAddSheet( BigSheetPartId, BigSheetOutlineId, dKerf, 0, BigPartsQty) -- EgtAutoNestAddSheet( SheetId, OutlineId, dKerf, nPriority, nCount)
end
-- se ci sono pezzi grandi
-- if BigPartsQty > 0 then
-- -- creo un ugual numero di fogli senza etichetta
-- local BigSheetPartId = EgtGroup(GDB_ID.ROOT)
-- EgtSetName(BigSheetPartId, "Sheet")
-- local BigSheetLayerId = EgtGroup(BigSheetPartId)
-- EgtSetName(BigSheetLayerId, OUTLINE)
-- local BigSheetOutlineId = EgtRectangle2P(BigSheetLayerId, Point3d(0,0,0), Point3d(Material.L_mm, Material.W_mm, 0), GDB_RT.GLOB)
-- EgtModifyCurveThickness(BigSheetOutlineId, -Material.T_mm)
-- EgtSetName(BigSheetOutlineId, OUTLINE)
-- EgtAutoNestAddSheet( SheetPartId, SheetOutlineId, dKerf, 0, BigPartsQty) -- EgtAutoNestAddSheet( SheetId, OutlineId, dKerf, nPriority, nCount)
-- end
-- 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, 1000) -- 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
--EgtSaveFile("c://Temp//TestSauderBigParts.nge")
-- 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*<circle%s*id=\"$QR$(%w*).*\"%s*cx=\"(%d*%.?%d+)\"%s*cy=\"(%d*%.?%d+)\".*/>")
if PartDtmx or dX or dY then
table.insert(QrList, " <image href=\"" .. sQRCodeGenPath .. "/QR_site/JSON?val={'baseUrl':'{0}','parameters':['" .. PartDtmx ..
"']}\" height=\"" .. nQRDim .. "\" width=\"" .. nQRDim .. "\" x=\"".. dX - (nQRDim / 2) .."\" y=\"".. dY - (nQRDim / 2) .."\"/>")
end
local _, _, SVGEnd = string.find(Lines[i], "%s*(</svg>).*")
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*<circle%s*id=\"$QR$(%w*).*\"%s*cx=\"(%d*%.?%d+)\"%s*cy=\"(%d*%.?%d+)\".*/>")
-- if PartDtmx or dX or dY then
-- Lines[i] = " <image href=\"https://" .. sQRCodeGenPath .. "/QR_site/JSON?val={'baseUrl':'{0}','parameters':['" .. PartDtmx .. "']}\" height=\""
-- .. nQRDim .. "\" width=\"" .. nQRDim .. "\" x=\"".. dX - (nQRDim / 2) .."\" y=\"".. dY - (nQRDim / 2) .."\"/>"
-- end
-- local _, _, BinCartIndex = string.find(Lines[i], "%s*<text.*>(%a%d*)</text>")
-- 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)
table.insert(OutsideChamferMachining, 2, Config.MXOutsideChamferMachTools)
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