2807 lines
136 KiB
Lua
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
|