diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d61017f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,334 @@
+# ---> VisualStudio
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+[Bb]in/
+[Oo]bj/
+32/
+64/
+OrigClientServer/
+UpdateClientServer/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+*.bat
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+
+# Windows Azure Build Output
+csx/
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# ---> C Sharp
+# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
+[Bb]in/
+[Oo]bj/
+
+# mstest test results
+TestResults
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+[Dd]ebug/
+[Rr]elease/
+x64/
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.log
+*.vspscc
+*.vssscc
+.builds
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish
+
+# Publish Web Output
+*.Publish.xml
+
+# NuGet Packages Directory
+packages
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+[Bb]in
+[Oo]bj
+sql
+TestResults
+[Tt]est[Rr]esult*
+*.Cache
+ClientBin
+[Ss]tyle[Cc]op.*
+~$*
+*.dbmdl
+Generated_Code #added for RIA/Silverlight projects
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+
diff --git a/Config.lua b/Config.lua
new file mode 100644
index 0000000..f894508
--- /dev/null
+++ b/Config.lua
@@ -0,0 +1,163 @@
+--
+-- 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.
+-- File dei parametri di configurazione by EgalTech s.r.l. 2020/08/13
+
+-- Tabella per definizione modulo
+local Config = {}
+
+-------------------------- Main -------------------------
+
+-- path chiamate REST
+Config.sRESTPath = "http://seriate.steamware.net:8082/NKC/api/"
+Config.sPathMat = Config.sRESTPath .. "Material"
+Config.sPathBatch = Config.sRESTPath .. "BatchProc"
+-- Nesting cycle waiting time
+Config.CycleDelay = 3
+
+-- Max bunk height
+Config.MaxBunkThickness = 450
+
+-- save data path
+Config.sBasePath = "c:/Users/Dell/Dropbox/SVG"
+----------------------------- NestingLib ---------------------------------------
+
+-- single nesting time for final nesting
+Config.nFinalMaxTime = 5
+-- single nesting time for estimation
+Config.nEstimMaxTime = 5
+
+-- table of association layer names to machinings -> {{"LayerName"}, {'Machining1', 'Machining2', ...}}
+Config.OutlineMachining = {{".375 ROUGHER", "ROUGHER"},
+ {'3/8 MILLING', '1/4 MILLING'}}
+Config.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'}}
+Config.RampMachining = {"RAMP", '3/8 MILLING'}
+-- list of pocketing machinings
+Config.Pocketing = {'3/8 POCKETING', '1/4 POCKETING'}
+
+
+Config.OutlineMachName = {".375 ROUGHER", "ROUGHER"}
+Config.MXOutlineMachTools = {'3/8 MILLING', '1/4 MILLING'}
+Config.NWOutlineMachTools = {'3/8 MILLING', '1/4 MILLING'}
+Config.HoleMachName = {"HOLE"}
+Config.MXHoleMachTools = {'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'}
+Config.NWHoleMachTools = {'1/2 DRILLING', '1/8 DRILLING', '3/8 DRILLING', '5/16 DRILLING', '7/16 DRILLING', '37/64 DRILLING', '1/4 DRILLING'}
+Config.RampMachName = {"RAMP"}
+Config.MXRampMachTools = {'3/8 MILLING'}
+Config.NWRampMachTools = {'3/8 MILLING'}
+Config.MXPocketingTools = {'3/8 POCKETING', '1/4 POCKETING'}
+Config.NWPocketingTools = {'3/8 POCKETING', '1/4 POCKETING'}
+
+-- tolerance betwwen start and end of a path to consider it closed
+Config.OpenPathTolerance = 0.01
+-- tolerance between part thickness and material thickness to consider a hole throught
+Config.ThicknessTolerance = 0.09
+-- remnant minimum dimension
+Config.RemnantMinDimension = 304.8
+-- minimum area in which position internal parts
+Config.IntPartMinArea = 5000
+-- tolerance between hole diameter and tool diameter
+Config.HoleTolerance = 0.1
+
+-- managing small parts (tabs,skeleton, ...)
+Config.nSkelSkinTabMode = 2 -- 0 = nothing ; 2 = Tabs ; 3 = Skeleton ; 4 = Skeleton&Tab
+Config.dSkelSkinTab_MaxArea = 36500 --- area limit
+
+-- color for paths pocketing
+Config.colPocketingPaths = Color3d( 0, 255, 255)
+-- suddivisione area pezzi in categorie per ordinamento lavorazione dei pezzi
+Config.dVerySmallPartArea = 3225
+Config.dSmallPartArea = 15200 -- 11612
+Config.dMediumPartArea = 60000
+-- lato massimo per rientrare in pezzi piccoli anche se con area grande
+Config.dSmallPartSide = 50.8
+
+-- attivazione distruzione scheletro
+Config.bSkeletonReduction = true
+Config.bSRMaxHeight = 100 * 25.4
+Config.bSRMaxWidth = 30 * 25.4
+-- quantita' di cui il taglio skeleton entra nello spazio vuoto di taglio pezzi
+Config.dSkeletonCut = 0.5
+
+-- spessore scheletro pezzi piccoli
+Config.dSkeletonWidth = 1 * 25.4
+
+-- riduzione feed su pezzi piccoli
+Config.bSmallFeedReduce = true
+Config.dSmallFeed = 8000
+
+-- variabile che indica se modalita' doppia macchina
+Config.bDoubleMach = false
+
+-- tab parameters for each material
+Config.TabParams = {{MatId = 1, MatExtCode = 6120, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 2, MatExtCode = 6110, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 3, MatExtCode = 6049, Length = 10.0, Height = 2.0, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 4, MatExtCode = 6118, Length = 10.0, Height = 2.0, Angle = 30, Distance = 50, MinCount = 6, MaxCount = 12},
+ {MatId = 5, MatExtCode = 6479, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 6, MatExtCode = 6408, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 7, MatExtCode = 6406, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 8, MatExtCode = 6478, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 9, MatExtCode = 6473, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 10, MatExtCode = 6474, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 11, MatExtCode = 6423, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 12, MatExtCode = 112268, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 13, MatExtCode = 119169, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 14, MatExtCode = 121214, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 15, MatExtCode = 111625, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 16, MatExtCode = 6127, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 17, MatExtCode = 6044, Length = 15.0, Height = 3.0, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 18, MatExtCode = 101523, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 19, MatExtCode = 6117, Length = 10.0, Height = 2.0, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 20, MatExtCode = 6119, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 21, MatExtCode = 6115, Length = 10.0, Height = 2.0, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 24, MatExtCode = 108360, Length = 10.0, Height = 2.0, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 25, MatExtCode = 124880, Length = 10.0, Height = 2.0, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ }
+
+-- parts minimum distance from raw part outline for each material
+Config.Kerf = {{MatId = 1, MatExtCode = 6120, Kerf = 8},
+ {MatId = 2, MatExtCode = 6110, Kerf = 20},
+ {MatId = 3, MatExtCode = 6049, Kerf = 20},
+ {MatId = 4, MatExtCode = 6118, Kerf = 20},
+ {MatId = 5, MatExtCode = 6479, Kerf = 20},
+ {MatId = 6, MatExtCode = 6408, Kerf = 20},
+ {MatId = 7, MatExtCode = 6406, Kerf = 20},
+ {MatId = 8, MatExtCode = 6478, Kerf = 30},
+ {MatId = 9, MatExtCode = 6473, Kerf = 20},
+ {MatId = 10, MatExtCode = 6474, Kerf = 20},
+ {MatId = 11, MatExtCode = 6423, Kerf = 20},
+ {MatId = 12, MatExtCode = 112268, Kerf = 20},
+ {MatId = 13, MatExtCode = 119169, Kerf = 20},
+ {MatId = 14, MatExtCode = 121214, Kerf = 20},
+ {MatId = 15, MatExtCode = 111625, Kerf = 20},
+ {MatId = 16, MatExtCode = 6127, Kerf = 20},
+ {MatId = 17, MatExtCode = 6044, Kerf = 20},
+ {MatId = 18, MatExtCode = 101523, Kerf = 20},
+ {MatId = 19, MatExtCode = 6117, Kerf = 20},
+ {MatId = 20, MatExtCode = 6119, Kerf = 20},
+ {MatId = 21, MatExtCode = 6115, Kerf = 20},
+ {MatId = 24, MatExtCode = 108360, Kerf = 20},
+ {MatId = 25, MatExtCode = 124880, Kerf = 20},
+ }
+
+Config.KitXModel = {{Model = '65w981', KitQty = 6},
+ {Model = '62163t', KitQty = 12},
+ {Model = '65w981s', KitQty = 6},
+ {Model = '53xhp81', KitQty = 10},
+ }
+
+---------------------------------------------------------------------
+return Config
diff --git a/Config.lua.my b/Config.lua.my
new file mode 100644
index 0000000..5646cc8
--- /dev/null
+++ b/Config.lua.my
@@ -0,0 +1,152 @@
+--
+-- 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.
+-- File dei parametri di configurazione by EgalTech s.r.l. 2020/08/13
+
+-- Tabella per definizione modulo
+local Config = {}
+
+-------------------------- Main -------------------------
+
+-- path chiamate REST
+Config.sRESTPath = "http://seriate.steamware.net:8083/NKC/api/"
+Config.sPathMat = Config.sRESTPath .. "Material"
+Config.sPathBatch = Config.sRESTPath .. "BatchProc"
+-- Nesting cycle waiting time
+Config.CycleDelay = 3
+
+-- Max bunk height
+Config.MaxBunkThickness = 450
+
+-- save data path
+Config.sBasePath = "c:/Users/Dell/Dropbox/SVG"
+
+----------------------------- NestingLib ---------------------------------------
+
+-- single nesting time for final nesting
+Config.nFinalMaxTime = 5
+-- single nesting time for estimation
+Config.nEstimMaxTime = 5
+
+-- table of association layer names to machinings -> {{"LayerName"}, {'Machining1', 'Machining2', ...}}
+Config.OutlineMachining = {{".375 ROUGHER", "ROUGHER"},
+ {'3/8 MILLING', '1/4 MILLING'}}
+Config.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'}}
+Config.RampMachining = {"RAMP", '3/8 MILLING'}
+-- list of pocketing machinings
+Config.Pocketing = {'3/8 POCKETING', '1/4 POCKETING'}
+
+
+Config.OutlineMachName = {".375 ROUGHER", "ROUGHER"}
+Config.MXOutlineMachTools = {'3/8 MILLING', '1/4 MILLING'}
+Config.NWOutlineMachTools = {'3/8 MILLING', '1/4 MILLING'}
+Config.HoleMachName = {"HOLE"}
+Config.MXHoleMachTools = {'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'}
+Config.NWHoleMachTools = {'1/2 DRILLING', '1/8 DRILLING', '3/8 DRILLING', '5/16 DRILLING', '7/16 DRILLING', '37/64 DRILLING', '1/4 DRILLING'}
+Config.RampMachName = {"RAMP"}
+Config.MXRampMachTools = {'3/8 MILLING'}
+Config.NWRampMachTools = {'3/8 MILLING'}
+Config.MXPocketingTools = {'3/8 POCKETING', '1/4 POCKETING'}
+Config.NWPocketingTools = {'3/8 POCKETING', '1/4 POCKETING'}
+
+-- tolerance betwwen start and end of a path to consider it closed
+Config.OpenPathTolerance = 0.01
+-- tolerance between part thickness and material thickness to consider a hole throught
+Config.ThicknessTolerance = 0.09
+-- remnant minimum dimension
+Config.RemnantMinDimension = 304.8
+-- minimum area in which position internal parts
+Config.IntPartMinArea = 5000
+-- tolerance between hole diameter and tool diameter
+Config.HoleTolerance = 0.1
+
+-- managing small parts (tabs,skeleton, ...)
+Config.nSkelSkinTabMode = 2 -- 0 = nothing ; 2 = Tabs ; 3 = Skeleton ; 4 = Skeleton&Tab
+Config.dSkelSkinTab_MaxArea = 36500 --- area limit
+
+-- color for paths pocketing
+Config.colPocketingPaths = Color3d( 0, 255, 255)
+-- suddivisione area pezzi in categorie per ordinamento lavorazione dei pezzi
+Config.dVerySmallPartArea = 3225
+Config.dSmallPartArea = 15200 -- 11612
+Config.dMediumPartArea = 60000
+-- lato massimo per rientrare in pezzi piccoli anche se con area grande
+Config.dSmallPartSide = 50.8
+
+-- attivazione distruzione scheletro
+Config.bSkeletonReduction = true
+Config.bSRMaxHeight = 100 * 25.4
+Config.bSRMaxWidth = 30 * 25.4
+-- quantita' di cui il taglio skeleton entra nello spazio vuoto di taglio pezzi
+Config.dSkeletonCut = 0.5
+
+-- spessore scheletro pezzi piccoli
+Config.dSkeletonWidth = 1 * 25.4
+
+-- riduzione feed su pezzi piccoli
+Config.bSmallFeedReduce = true
+Config.dSmallFeed = 8000
+
+-- tab parameters for each material
+Config.TabParams = {{MatId = 1, MatExtCode = 6120, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 2, MatExtCode = 6110, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 3, MatExtCode = 6049, Length = 10.0, Height = 2.0, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 4, MatExtCode = 6118, Length = 10.0, Height = 2.0, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 5, MatExtCode = 6479, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 6, MatExtCode = 6408, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 7, MatExtCode = 6406, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 8, MatExtCode = 6478, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 9, MatExtCode = 6473, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 10, MatExtCode = 6474, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 11, MatExtCode = 6423, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 12, MatExtCode = 112268, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 13, MatExtCode = 119169, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 14, MatExtCode = 121214, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 15, MatExtCode = 111625, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 16, MatExtCode = 6127, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 17, MatExtCode = 6044, Length = 15.0, Height = 3.0, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 18, MatExtCode = 101523, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 19, MatExtCode = 6117, Length = 10.0, Height = 2.0, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 20, MatExtCode = 6119, Length = 10.0, Height = 1.5, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ {MatId = 21, MatExtCode = 6115, Length = 10.0, Height = 2.0, Angle = 30, Distance = 60, MinCount = 3, MaxCount = 4},
+ }
+
+-- parts minimum distance from raw part outline for each material
+Config.Kerf = {{MatId = 1, MatExtCode = 6120, Kerf = 20},
+ {MatId = 2, MatExtCode = 6110, Kerf = 20},
+ {MatId = 3, MatExtCode = 6049, Kerf = 20},
+ {MatId = 4, MatExtCode = 6118, Kerf = 20},
+ {MatId = 5, MatExtCode = 6479, Kerf = 20},
+ {MatId = 6, MatExtCode = 6408, Kerf = 20},
+ {MatId = 7, MatExtCode = 6406, Kerf = 20},
+ {MatId = 8, MatExtCode = 6478, Kerf = 30},
+ {MatId = 9, MatExtCode = 6473, Kerf = 20},
+ {MatId = 10, MatExtCode = 6474, Kerf = 20},
+ {MatId = 11, MatExtCode = 6423, Kerf = 20},
+ {MatId = 12, MatExtCode = 112268, Kerf = 20},
+ {MatId = 13, MatExtCode = 119169, Kerf = 20},
+ {MatId = 14, MatExtCode = 121214, Kerf = 20},
+ {MatId = 15, MatExtCode = 111625, Kerf = 20},
+ {MatId = 16, MatExtCode = 6127, Kerf = 20},
+ {MatId = 17, MatExtCode = 6044, Kerf = 20},
+ {MatId = 18, MatExtCode = 101523, Kerf = 20},
+ {MatId = 19, MatExtCode = 6117, Kerf = 20},
+ {MatId = 20, MatExtCode = 6119, Kerf = 20},
+ {MatId = 21, MatExtCode = 6115, Kerf = 20},
+ }
+
+
+---------------------------------------------------------------------
+return Config
diff --git a/Errors.txt b/Errors.txt
new file mode 100644
index 0000000..24e0746
--- /dev/null
+++ b/Errors.txt
@@ -0,0 +1,11 @@
+E.1 -> "Can't find DXF file"
+E.2 -> "Can't find material tag in DXF"
+E.4 -> "Can't find outline"
+E.6 -> "Error in DXF reading"
+E.7 -> "Impossible running estimation!", "Error in machining!"
+E.8 -> "Open paths found"
+E.9 -> "Outline tool diameter not found!"
+E.10 -> "Error in nesting function!"
+E.12 -> "Error on control counting. Lost part, sheet, bunk, etc..."
+E.13 -> "Error, outline thickness must be negative!"
+E.14 -> "There are entities that are not CompositeCurves or Arcs"
\ No newline at end of file
diff --git a/Generate.lua b/Generate.lua
new file mode 100644
index 0000000..85d57f7
--- /dev/null
+++ b/Generate.lua
@@ -0,0 +1,73 @@
+-- necessary to find socket.core and mime.core
+package.cpath = package.cpath .. ";/EgtProg/LuaLibs/?.dll"
+
+require( 'EgtBase')
+_ENV = EgtProtectGlobal()
+EgtEnableDebug( true)
+
+local AREA = "Area"
+
+local BasePath = "c:/Users/Dell/Dropbox/SVG"
+local BatchDateId = "/2021/6/629"
+
+local MaxMatId = 25
+for MatId = 1, MaxMatId do
+ -- apro file
+ if EgtOpenFile(BasePath .. "/Nesting" .. BatchDateId .. "/" .. MatId .. ".nge") then
+ -- vado su gruppi di lavorazione
+ local nSheetGroupId = EgtGetFirstMachGroup()
+ while nSheetGroupId do
+ local sGroupName = EgtGetMachGroupName(nSheetGroupId)
+ local bOk = EgtSetCurrMachGroup(nSheetGroupId)
+ local nOp = EgtGetFirstOperation()
+-- while nOp and false do
+-- if EgtGetOperationType(nOp) == MCH_OY.MILLING then
+-- local bOk = EgtSetCurrMachining(nOp)
+-- local nOut = EgtGetMachiningGeometry()
+-- local nPart = EgtGetParent(EgtGetParent(nOut[1][1]))
+-- local dArea = EgtGetInfo(nPart, AREA, 'd')
+--
+-- --local b3Part = EgtGetBBox(nPart, 13)
+--
+-- if EgtGetMachiningParam(MCH_MP.USERNOTES) == 'Outline = 1' then -- and (b3Part:getX() < 18 * GEO.ONE_INCH or b3Part:getY() < 18 * GEO.ONE_INCH) then
+-- EgtSetMachiningParam(MCH_MP.INVERT, true)
+-- if dArea and dArea < 11652 then
+-- EgtSetMachiningParam(MCH_MP.LEAVETAB, true)
+-- EgtSetMachiningParam(MCH_MP.TABMIN, 2)
+-- EgtSetMachiningParam(MCH_MP.TABMAX, 4)
+-- EgtSetMachiningParam(MCH_MP.TABDIST, 60)
+-- elseif dArea and dArea < 36500 then
+-- EgtSetMachiningParam(MCH_MP.LEAVETAB, true)
+-- EgtSetMachiningParam(MCH_MP.TABMIN, 4)
+-- EgtSetMachiningParam(MCH_MP.TABMAX, 6)
+-- EgtSetMachiningParam(MCH_MP.TABDIST, 200)
+-- else
+-- EgtSetMachiningParam(MCH_MP.TABDIST, 50000)
+-- end
+---- else
+---- EgtSetMachiningParam(MCH_MP.DEPTH_STR, "TH+0.1")
+-- end
+-- end
+-- nOp = EgtGetNextOperation(nOp)
+-- end
+-- local nRawPart = EgtGetFirstRawPart()
+-- local nPart = EgtGetFirstPartInRawPart(nRawPart)
+-- while nPart do
+--
+-- nPart = EgtGetNextPartInRawPart(nPart)
+-- end
+ EgtApplyAllMachinings()
+ EgtApplyAllMachinings()
+ -- genero
+ local sCncPath = BasePath .. "/CNC" .. BatchDateId .. "/" .. MatId .."/" .. EgtGetMachGroupName(nSheetGroupId) .. ".cnc"
+ local sPrintPath = BasePath .. "/CNC" .. BatchDateId .. "/" .. MatId .."/" .. EgtGetMachGroupName(nSheetGroupId) .. "_2.cnc"
+ local sNewPrintPath = BasePath .. "/CNC_PRINT" .. BatchDateId .. "/" .. MatId .."/" .. EgtGetMachGroupName(nSheetGroupId) .. ".cnc"
+ bOk = EgtGenerate(sCncPath)
+ -- sposto file di stampa
+ bOk = EgtCopyFile(sPrintPath, sNewPrintPath)
+ bOk = EgtEraseFile(sPrintPath)
+ nSheetGroupId = EgtGetNextMachGroup(nSheetGroupId)
+ end
+ EgtSaveFile()
+ end
+end
\ No newline at end of file
diff --git a/Main.lua b/Main.lua
new file mode 100644
index 0000000..7ed421d
--- /dev/null
+++ b/Main.lua
@@ -0,0 +1,1118 @@
+--
+-- 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.
+-- Nesting manager by EgalTech s.r.l. 2020/08/13
+
+-- necessary to find socket.core and mime.core
+package.cpath = package.cpath .. ";/EgtProg/LuaLibs/?.dll"
+package.cpath = package.cpath .. ";/EgtDevTest/LUAREST/32/?.lua"
+
+require( 'EgtBase')
+_ENV = EgtProtectGlobal()
+EgtEnableDebug( true)
+
+-- Imposto direttorio libreria specializzata per Nesting
+local sBaseDir = EgtGetSourceDir()
+EgtOutLog("BaseDir=" .. sBaseDir)
+EgtAddToPackagePath( sBaseDir .. '?.lua')
+
+local Config = require( 'Config')
+local UtilityLib = require( 'UtilityLib')
+local RESTLib = require( 'RESTLib')
+local NestingLib = require( 'NestingLib')
+local socket = require( 'socket')
+
+------------------------------------------- PARAMETERS -------------------------------------------
+local DebugCode = false
+local ProblematicItem = 67328
+
+------------------------------------------- ************** -------------------------------------------
+
+local function ManageError(ErrorList, readBatch, Send)
+ if #ErrorList > 0 then
+ -- creo batch di risposta
+ local answ = {}
+ answ.BatchId = readBatch.BatchId
+ answ.EnvNum = readBatch.EnvNum
+ answ.ProcType = readBatch.ProcType
+ answ.MachineType = readBatch.MachineType
+ answ.OrderType = readBatch.OrderType
+ answ.ProcessNotes = ""
+ answ.EstimatedWorktime = 0
+ answ.DrawingPath = ""
+ answ.PartList = {}
+ answ.CNCPath = ""
+ answ.SurfaceWork = 0
+ answ.SurfaceTotal = 0
+ answ.BunkList = {}
+ answ.CartList = {}
+ answ.BinList = {}
+ answ.ErrorList = ErrorList
+ answ.ProcessStatus = 2
+ answ.ProcessingRuntime = EgtStopCounter() / 1000
+ -- se doppia macchina
+ if not Send and Config.bDoubleMach then
+ return true, answ
+ end
+ -- invio dati
+ local bOk = RESTLib.set(Config.sPathBatch, answ)
+ if bOk then print("OK") end
+ return true
+ end
+ return false
+end
+--
+
+-- funzione che esegue nesting finale
+function Nesting(readBatch)
+ -- imposto macchina in uso
+ NestingLib.ManageMachine(false)
+
+ -- elimino tutti i file presenti nella cartella nesting
+ EgtEmptyDirectory(Config.sBasePath .. "/Nesting" )
+
+ EgtOutText("Nesting start")
+
+ -- lista errori
+ local ErrorList = {}
+
+ -- conto tutto
+ if not readBatch.OrderList then return end
+ local OrderCount = #readBatch.OrderList
+ local KitCount = 0
+ local PartCount = 0
+ local NoDXFCount = 0
+ local NoMaterialCount = 0
+ local NoMaterialCount2 = 0
+ for Order = 1, #readBatch.OrderList do
+ KitCount = KitCount + #readBatch.OrderList[Order].KitList
+ for Kit = 1, #readBatch.OrderList[Order].KitList do
+ PartCount = PartCount + #readBatch.OrderList[Order].KitList[Kit].PartList
+ end
+ end
+
+ -- recupero lista materiali
+ local materials = RESTLib.get(Config.sPathMat)
+ for MaterialIndex = 1, #materials do
+ materials[MaterialIndex].PriorityList = {}
+ end
+
+ -- leggo materiali per tutti i pezzi, metto i verniciati con priorita' 1 sui materiali ed elimino ordini e kit dei verniciati
+ local OrderList = {}
+ local CalcReadBatch = RESTLib.get(Config.sPathBatch)
+ if not CalcReadBatch or CalcReadBatch.BatchId == 0 then
+ -- error!!
+ end
+
+ for OrderIndex = 1, #CalcReadBatch.OrderList do
+ table.insert(OrderList, CalcReadBatch.OrderList[OrderIndex])
+ end
+ NestingLib.FilterPaintedParts(OrderList, materials, ErrorList)
+
+ -- raggruppo gli ordini simili per ottimizzare l'uso del materiale
+
+ -- creo cart
+
+ -- assegno priorita' ai pezzi e li divido sui materiali
+
+
+ local Carts = {} -- lista dei cart
+ -- creo cart a partire da lista ordini e kit
+-- NestingLib.CreateCart(readBatch, Carts)
+ NestingLib.CreateCart(OrderList, Carts)
+
+ local StartCartIndex = 0
+ if readBatch.NumIndexStart then
+ StartCartIndex = readBatch.NumIndexStart
+ end
+ for CartIndex = 1, #Carts do
+ Carts[CartIndex].CartIndex = StartCartIndex + CartIndex - 1
+ end
+
+ -- se debug
+ if DebugCode then
+ -- verifico di aver messo tutti i kit sui cart
+ local KitList = {}
+ -- raccolgo tutti i kit dai cart in una lista
+ for CartIndex = 1, #Carts do
+ for OrderIndex = 1, #Carts[CartIndex].OrderList do
+ for KitIndex = 1, #Carts[CartIndex].OrderList[OrderIndex].KitList do
+ table.insert(KitList, Carts[CartIndex].OrderList[OrderIndex].KitList[KitIndex])
+ end
+ end
+ end
+ -- aggiungo i kit dei painted
+ for OrderIndex = 1, #OrderList do
+ for KitIndex = 1, #OrderList[OrderIndex].KitList do
+ if OrderList[OrderIndex].KitList[KitIndex].IsPaint then
+ table.insert(KitList, OrderList[OrderIndex].KitList[KitIndex])
+ end
+ end
+ end
+ -- passo i kit del readbatch
+ for OrderIndex = 1, #readBatch.OrderList do
+ for BKitIndex = 1, #readBatch.OrderList[OrderIndex].KitList do
+ local bFound = false
+ for VKitIndex = #KitList, 1, -1 do
+ if readBatch.OrderList[OrderIndex].KitList[BKitIndex].KitId == KitList[VKitIndex].KitId then
+ if not bFound then
+ bFound = true
+ table.remove(KitList, VKitIndex)
+ else
+ table.insert(ErrorList, {ErrType = "E.12", Uid = "KitId = " .. readBatch.OrderList[OrderIndex].KitList[BKitIndex].KitId, Description = "Kit duplicated after putting them on cart!"})
+ end
+ end
+ end
+ if not bFound then
+ table.insert(ErrorList, {ErrType = "E.12", Uid = "KitId = " .. readBatch.OrderList[OrderIndex].KitList[BKitIndex].KitId, Description = "Kit lost after putting them on cart!"})
+ end
+ end
+ end
+ -- verifico se sono rimasti elementi nella tabella kit
+ if #KitList > 0 then
+ table.insert(ErrorList, {ErrType = "E.12", Uid = "KitId = " .. KitList[1].KitId, Description = #KitList .. " kit more than in batch request after putting kit on cart!"})
+ end
+ end
+
+ -- imposto priorità sui pezzi in base ai carrelli e li divido per materiale e priorità
+ NestingLib.SetPriorityProcessMaterial(Carts, materials, ErrorList)
+
+ -- se debug
+ if DebugCode then
+ -- verifico di aver messo tutti i part su un materiale
+ local PartList = {}
+ -- raccolgo tutti i part dai materiali in una lista
+ for MaterialIndex = 1, #materials do
+ for PriorityIndex = 1, #materials[MaterialIndex].PriorityList do
+ for PartIndex = 1, #materials[MaterialIndex].PriorityList[PriorityIndex].PartList do
+ table.insert(PartList, materials[MaterialIndex].PriorityList[PriorityIndex].PartList[PartIndex])
+ end
+ end
+ end
+ -- passo i part del readbatch
+ for OrderIndex = 1, #readBatch.OrderList do
+ for KitIndex = 1, #readBatch.OrderList[OrderIndex].KitList do
+ for BPartIndex = 1, #readBatch.OrderList[OrderIndex].KitList[KitIndex].PartList do
+ local bFound = false
+ for VPartIndex = #PartList, 1, -1 do
+ if readBatch.OrderList[OrderIndex].KitList[KitIndex].PartList[BPartIndex].PartId == PartList[VPartIndex].PartId then
+ if not bFound then
+ bFound = true
+ table.remove(PartList, VPartIndex)
+ else
+ table.insert(ErrorList, {ErrType = "E.12", Uid = "PartId = " .. readBatch.OrderList[OrderIndex].KitList[KitIndex].PartList[BPartIndex].PartId, Description = "Part duplicated after distributing them on materials!"})
+ end
+ end
+ end
+ if not bFound then
+ table.insert(ErrorList, {ErrType = "E.12", Uid = "PartId = " .. readBatch.OrderList[OrderIndex].KitList[KitIndex].PartList[BPartIndex].PartId, Description = "Part lost after distributing them on materials!"})
+ end
+ end
+ end
+ end
+ -- verifico se sono rimasti elementi nella tabella kit
+ if #PartList > 0 then
+ table.insert(ErrorList, {ErrType = "E.12", Uid = "PartId = " .. PartList[1].PartId, Description = #PartList .. " part more than in batch request after distributing them on materials!"})
+ end
+ end
+
+ -- creo bin necessari
+ local Bins = {}
+ NestingLib.CreateBin(materials, Bins)
+
+ -- se debug
+ if DebugCode then
+ -- verifico di aver messo tutti i painted part su un bin
+
+ end
+
+ PartCount1 = 0
+ local MatIde = 21
+-- local MatIndex = MatIde + 1
+-- local MatCount = MatIndex
+ local MatIndex = 1
+ local MatCount = #materials
+ --for Material = 1, #materials do
+ for Material = MatIndex, MatCount do
+ --for Material = 2, 2 do
+ for Priority = 1, #materials[Material].PriorityList do
+ for Part = 1, #materials[Material].PriorityList[Priority].PartList do
+ PartCount1 = PartCount1 + 1
+ if materials[Material].PriorityList[Priority].PartList[Part].PartId == ProblematicItem then
+ local x = 2
+ end
+ end
+ end
+ end
+
+ -- contatore dei pezzi ricevuti per errori sul numero finale dei pezzi
+ --local VPartList = {}
+ --for Priority = 1, #materials[11].PartList do
+ -- for Part = 1, #materials[11].PartList[Priority].PartList do
+ -- table.insert(VPartList, materials[11].PartList[Priority].PartList[Part].PartId)
+ -- end
+ --end
+ function comparePriority(a,b)
+ return a.Priority < b.Priority
+ end
+ -- per ogni materiale riordino le priorita'
+ local SortingArray = {}
+ for MaterialIndex = 1, #materials do
+ table.sort(materials[MaterialIndex].PriorityList, comparePriority)
+ end
+
+ -- per ogni materiale creo un progetto
+ local PARTID = "PartId"
+ local PRIORITY = "Priority"
+ local ROUGHER = {".375 ROUGHER","ROUGHER"}
+ local DTMXPOS = "DATA MATRIX CODE POSITION"
+ local MatSheetList = {}
+ --for Material = 1, #materials do
+ for Material = MatIndex, MatCount do
+ --for Material = 2, 2 do
+ --for Material = 4, 4 do
+ -- se è il materiale nullo salto al prossimo
+ if materials[Material].MatId ~= 0 and #materials[Material].PriorityList > 0 then
+ EgtOutText("Material: " .. materials[Material].MatDesc)
+ EgtNewFile()
+ materials[Material].SheetList = {}
+ local LastRawId = GDB_ID.NULL
+ -- recupero lista verniciati (priorità 1)
+ local PartToBeMachined = {}
+ -- verifico se c'è lista pezzi verniciati
+-- if materials[Material].PartList[1].Priority == 1 then
+---- PartToBeMachined = materials[Material].PartList[1].PartList
+-- PartToBeMachined = {}
+-- for Part = 1, #materials[Material].PartList[1].PartList do
+-- table.insert(PartToBeMachined, materials[Material].PartList[1].PartList[Part])
+-- end
+-- -- chiamo il nesting sui verniciati
+-- LastRawId = NestingLib.NestPartInRawPart(nil, PartToBeMachined, materials[Material], ErrorList)
+-- -- recupero lista di pezzi di priorità più bassa
+-- if #materials[Material].PartList > 1 then
+---- PartToBeMachined = materials[Material].PartList[2].PartList
+-- PartToBeMachined = {}
+-- for Part = 1, #materials[Material].PartList[2].PartList do
+-- table.insert(PartToBeMachined, materials[Material].PartList[2].PartList[Part])
+-- end
+--
+-- end
+-- -- riempio con questi
+-- LastRawId = NestingLib.NestPartInRawPart(LastRawId, PartToBeMachined, materials[Material], ErrorList)
+-- end
+ -- for Index = 1, materials[Material].PartList do
+ -- if materials[Material].PartList[Index].Priority == 1 then
+ -- PartToBeMachined = materials[Material].PartList[Index].PartList
+ -- end
+ -- end
+
+ -- for Index = 1, materials[Material].PartList do
+ -- if materials[Material].PartList[Index].Priority == 2 then
+ -- PartToBeMachined = materials[Material].PartList[Index].PartList
+ -- end
+ -- end
+ -- -- riempio con quelli di priorità 2
+ -- LastRawId = NestingLib.NestPartInRawPart(LastRawId, PartToBeMachined, materials[Material])
+
+ -- se il primo gruppo ha priorita' 1, ne aggiungo i pezzi a quelli da nestare
+ if materials[Material].PriorityList[1].Priority == 1 then
+ for Part = 1, #materials[Material].PriorityList[1].PartList do
+ table.insert(PartToBeMachined, materials[Material].PriorityList[1].PartList[Part])
+ if materials[Material].PriorityList[1].PartList[Part].PartId == ProblematicItem then
+ local x = 2
+ end
+ end
+ end
+ local Counter = true
+ local PriorityCount = #materials[Material].PriorityList
+ -- ciclo sulle priorità dei pezzi
+ for Index = 1, PriorityCount do
+ -- verifico che non siano i verniciati
+ if materials[Material].PriorityList[Index].Priority ~= 1 then
+ if Counter then
+ -- annullo LastRaw perche' devo partire con un nuovo grezzo, altrimenti aggiungo pezzi sbagliati (riempimento gia' fatto!)
+ LastRawId = GDB_ID.NULL
+ for Part = 1, #materials[Material].PriorityList[Index].PartList do
+ table.insert(PartToBeMachined, materials[Material].PriorityList[Index].PartList[Part])
+ if materials[Material].PriorityList[Index].PartList[Part].PartId == ProblematicItem then
+ local x = 2
+ end
+ end
+ -- PartToBeMachined = materials[Material].PartList[Index].PartList
+ else
+ PartToBeMachined = {}
+ for Part = 1, #materials[Material].PriorityList[Index].PartList do
+ table.insert(PartToBeMachined, materials[Material].PriorityList[Index].PartList[Part])
+ if materials[Material].PriorityList[Index].PartList[Part].PartId == ProblematicItem then
+ local x = 2
+ end
+ end
+-- PartToBeMachined = materials[Material].PartList[Index].PartList
+ end
+ -- se Counter true faccio il nesting, se false completo grezzo
+ -- verifico anche che non sia il primo giro in cui dovrei prima riempire i pannelli dei pezzi painted
+ LastRawId = NestingLib.NestPartInRawPart(LastRawId, PartToBeMachined, materials[Material], ErrorList, false, false)
+ if ManageError(ErrorList, readBatch) then return end
+ Counter = not Counter
+ elseif PriorityCount == 1 then
+ LastRawId = NestingLib.NestPartInRawPart(GDB_ID.NULL, PartToBeMachined, materials[Material], ErrorList, false, false)
+ if ManageError(ErrorList, readBatch) then return end
+ end
+ -- -- se Counter true faccio il nesting, se false completo grezzo
+ -- -- verifico anche che non sia il primo giro in cui dovrei prima riempire i pannelli dei pezzi painted
+ -- if Counter and not materials[Material].PartList[Index].Priority == 2 then -- LastRawId = NestPartInRawPart(LastRawId, PartList, materials[Material])
+ -- end
+ end
+
+ -- se il numero di gruppi delle priorita' e' dispari eseguo un altro nesting sui pezzi rimasti dal riempimento
+ if materials[Material].PriorityList[1].Priority == 1 then
+ PriorityCount = PriorityCount - 1
+ end
+ if PriorityCount % 2 == 0 then
+ -- annullo LastRaw perche' devo partire con un nuovo grezzo, altrimenti aggiungo pezzi sbagliati (riempimento gia' fatto!)
+ LastRawId = GDB_ID.NULL
+ LastRawId = NestingLib.NestPartInRawPart(LastRawId, PartToBeMachined, materials[Material], ErrorList, false, false)
+ if ManageError(ErrorList, readBatch) then return end
+ end
+
+ -- calcolo lavorazioni, stime, ecc
+ NestingLib.PostNestOp(materials[Material], ErrorList, false, readBatch.BatchId, 1)
+ NestingLib.PostNestOp(materials[Material], ErrorList, false, readBatch.BatchId, 2)
+ if ManageError(ErrorList, readBatch) then return end
+
+ -- salvo il progetto di nesting
+ local sProjectPath = NestingLib.VerifyPath("Nesting", readBatch.BatchId, nil)
+ EgtSaveFile(sProjectPath .. "/" .. materials[Material].MatId .. ".nge")
+ end
+ end
+
+ EgtOutText("End sheets nest")
+
+ -- se debug
+ if DebugCode then
+ -- verifico di aver messo tutti i part su un grezzo
+ local PartList = {}
+ -- raccolgo tutti i part dai materiali in una lista
+ for MaterialIndex = 1, #materials do
+ if materials[MaterialIndex].SheetList then
+ for SheetIndex = 1, #materials[MaterialIndex].SheetList do
+ for PartIndex = 1, #materials[MaterialIndex].SheetList[SheetIndex].PartList do
+ table.insert(PartList, tonumber(materials[MaterialIndex].SheetList[SheetIndex].PartList[PartIndex].PartId))
+ end
+ end
+ end
+ end
+ -- passo i part del readbatch
+ for OrderIndex = 1, #readBatch.OrderList do
+ for KitIndex = 1, #readBatch.OrderList[OrderIndex].KitList do
+ for BPartIndex = 1, #readBatch.OrderList[OrderIndex].KitList[KitIndex].PartList do
+ local bFound = false
+ for VPartIndex = #PartList, 1, -1 do
+ if readBatch.OrderList[OrderIndex].KitList[KitIndex].PartList[BPartIndex].PartId == PartList[VPartIndex] then
+ if not bFound then
+ bFound = true
+ table.remove(PartList, VPartIndex)
+ else
+ table.insert(ErrorList, {ErrType = "E.12", Uid = "PartId = " .. readBatch.OrderList[OrderIndex].KitList[KitIndex].PartList[BPartIndex].PartId, Description = "Part duplicated after nesting!"})
+ end
+ end
+ end
+ if not bFound then
+ table.insert(ErrorList, {ErrType = "E.12", Uid = "PartId = " .. readBatch.OrderList[OrderIndex].KitList[KitIndex].PartList[BPartIndex].PartId, Description = "Part lost after nesting!"})
+ end
+ end
+ end
+ end
+ -- verifico se sono rimasti elementi nella tabella kit
+ if #PartList > 0 then
+ table.insert(ErrorList, {ErrType = "E.12", Uid = "PartId = " .. PartList[1], Description = #PartList .. " part more than in batch request after nesting!"})
+ end
+ end
+
+ local MPCount = 0
+ -- ordino fogli da mettere sui bunk
+ local SheetList = {}
+ for Material = 1, #materials do
+ if materials[Material].SheetList and #materials[Material].SheetList > 0 then
+ for Sheet = 1, #materials[Material].SheetList do
+ -- segno dimensioni materiale sul foglio
+ materials[Material].SheetList[Sheet].L_mm = materials[Material].L_mm
+ materials[Material].SheetList[Sheet].W_mm = materials[Material].W_mm
+ materials[Material].SheetList[Sheet].T_mm = materials[Material].T_mm
+ -- elimino priorita' 1
+ for PriorityIndex = 1, #materials[Material].SheetList[Sheet].PriorityList do
+ if tonumber(materials[Material].SheetList[Sheet].PriorityList[PriorityIndex]) == 1 then
+ table.remove(materials[Material].SheetList[Sheet].PriorityList, PriorityIndex)
+ if #materials[Material].SheetList[Sheet].PriorityList == 0 then
+ table.insert(materials[Material].SheetList[Sheet].PriorityList, "2")
+ end
+ end
+ end
+ -- verifico conto pezzi
+ for Part = 1, #materials[Material].SheetList[Sheet].PartList do
+ if materials[Material].SheetList[Sheet].PartList[Part].PartId == tostring(ProblematicItem) then
+ local x = 2
+ end
+ MPCount = MPCount + 1
+ end
+ -- se lista ordinata non vuota
+ if #SheetList > 0 then
+ local bInserted = false
+ -- scorro le priorita'
+ for SearchIndex = 1, #SheetList do
+ local bNotToBeInserted = false
+ local MaxList = math.min(#SheetList[SearchIndex].PriorityList, #materials[Material].SheetList[Sheet].PriorityList)
+ for PriorityIndex = 1, MaxList do
+ if not bInserted and not bNotToBeInserted and
+ ((tonumber(SheetList[SearchIndex].PriorityList[PriorityIndex]) > tonumber(materials[Material].SheetList[Sheet].PriorityList[PriorityIndex])) 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
+-- elseif ((SheetList[SearchIndex].PriorityList[PriorityIndex] == materials[Material].SheetList[Sheet].PriorityList[PriorityIndex])
+-- and PriorityIndex == MaxList) then
+-- if #SheetList[SearchIndex].PriorityList > #materials[Material].SheetList[Sheet].PriorityList then
+-- table.insert(SheetList, PriorityIndex, materials[Material].SheetList[Sheet])
+-- else
+-- table.insert(SheetList, PriorityIndex + 1, materials[Material].SheetList[Sheet])
+-- end
+ 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
+ end
+
+ -- BUNK CREATI PER PRIORITA' E ALTEZZA MASSIMA
+ -- creo bunk prendendo X fogli con priorita' piu' bassa
+ local SheetXBunk = 10
+ local BunkList = {}
+ local BunkIndex = 1
+ local CurrBunk = {BunkIndex = BunkIndex, SheetList = {}}
+ table.insert(BunkList, CurrBunk)
+ local CurrSheetOnBunk = 0
+ local CurrBunkPriority = 2
+ local CurrBunkThickness = 0
+ for Sheet = 1, #SheetList do
+-- if tonumber(SheetList[Sheet].PriorityList[1]) == 1 or tonumber(SheetList[Sheet].PriorityList[#SheetList[Sheet].PriorityList]) <= CurrBunkPriority + 1 then
+ if tonumber(SheetList[Sheet].PriorityList[#SheetList[Sheet].PriorityList]) <= CurrBunkPriority + 1 and CurrBunkThickness + SheetList[Sheet].T_mm < Config.MaxBunkThickness then
+ SheetList[Sheet].SheetIndex = CurrSheetOnBunk + 1
+ table.insert(CurrBunk.SheetList, SheetList[Sheet])
+ CurrSheetOnBunk = CurrSheetOnBunk + 1
+ CurrBunkThickness = CurrBunkThickness + SheetList[Sheet].T_mm
+ else
+ BunkIndex = BunkIndex + 1
+ SheetList[Sheet].SheetIndex = 1
+ CurrBunk = {BunkIndex = BunkIndex, SheetList = {}}
+ table.insert(CurrBunk.SheetList, SheetList[Sheet])
+ table.insert(BunkList, CurrBunk)
+ CurrSheetOnBunk = 1
+ local nSheetFirstPriority = tonumber(SheetList[Sheet].PriorityList[1])
+ for i = 2, #(SheetList[Sheet].PriorityList) do
+ nSheetFirstPriority = min(nSheetFirstPriority, tonumber(SheetList[Sheet].PriorityList[i]))
+ end
+ CurrBunkPriority = EgtIf( nSheetFirstPriority == 2, nSheetFirstPriority, nSheetFirstPriority + 1)
+ CurrBunkThickness = 0
+ end
+ end
+
+ -- BUNK CREATI CON SPESSORE MASSIMO
+-- -- creo bunk prendendo X fogli con priorita' piu' bassa
+-- local MaxBunkThickness = 500
+-- local BunkList = {}
+-- local BunkIndex = 1
+-- local CurrBunk = {BunkIndex = BunkIndex, SheetList = {}}
+-- table.insert(BunkList, CurrBunk)
+-- local CurrBunkThickness = 0
+-- local CurrSheetOnBunk = 0
+-- for Sheet = 1, #SheetList do
+-- if CurrBunkThickness < Config.MaxBunkThickness then
+-- SheetList[Sheet].SheetIndex = CurrSheetOnBunk + 1
+-- table.insert(CurrBunk.SheetList, SheetList[Sheet])
+-- CurrSheetOnBunk = CurrSheetOnBunk + 1
+-- CurrBunkThickness = CurrBunkThickness + SheetList[Sheet].T_mm
+-- else
+-- BunkIndex = BunkIndex + 1
+-- SheetList[Sheet].SheetIndex = 1
+-- CurrBunk = {BunkIndex = BunkIndex, SheetList = {}}
+-- table.insert(CurrBunk.SheetList, SheetList[Sheet])
+-- table.insert(BunkList, CurrBunk)
+-- CurrSheetOnBunk = 1
+-- CurrBunkThickness = SheetList[Sheet].T_mm
+-- end
+-- end
+
+ -- BUNK CREATI CON NUMERO MASSIMO DI FOGLI
+-- -- creo bunk prendendo X fogli con priorita' piu' bassa
+-- local SheetXBunk = 10
+-- local BunkList = {}
+-- local BunkIndex = 1
+-- local CurrBunk = {BunkIndex = BunkIndex, SheetList = {}}
+-- table.insert(BunkList, CurrBunk)
+-- local CurrSheetOnBunk = 0
+-- for Sheet = 1, #SheetList do
+-- if CurrSheetOnBunk < SheetXBunk then
+-- SheetList[Sheet].SheetIndex = CurrSheetOnBunk + 1
+-- table.insert(CurrBunk.SheetList, SheetList[Sheet])
+-- CurrSheetOnBunk = CurrSheetOnBunk + 1
+-- else
+-- BunkIndex = BunkIndex + 1
+-- SheetList[Sheet].SheetIndex = 1
+-- CurrBunk = {BunkIndex = BunkIndex, SheetList = {}}
+-- table.insert(CurrBunk.SheetList, SheetList[Sheet])
+-- table.insert(BunkList, CurrBunk)
+-- CurrSheetOnBunk = 1
+-- end
+-- end
+
+ -- Ordino fogli sui singoli BUNK per dimensione
+ for BunkIndex = 1, #BunkList do
+ local OrderedSheets = {}
+ -- divido i fogli in gruppi della stessa lunghezza
+ for SheetIndex = 1, #BunkList[BunkIndex].SheetList do
+ if #OrderedSheets > 0 then
+ local bInserted = false
+ for OrderedSheetIndex = 1, #OrderedSheets do
+ if BunkList[BunkIndex].SheetList[SheetIndex].L_mm == OrderedSheets[OrderedSheetIndex].L_mm then
+ bInserted = true
+ table.insert(OrderedSheets[OrderedSheetIndex].SheetList, BunkList[BunkIndex].SheetList[SheetIndex])
+ end
+ end
+ if not bInserted then
+ table.insert(OrderedSheets, {L_mm = BunkList[BunkIndex].SheetList[SheetIndex].L_mm, SheetList = {BunkList[BunkIndex].SheetList[SheetIndex]}})
+ end
+ else
+ table.insert(OrderedSheets, {L_mm = BunkList[BunkIndex].SheetList[SheetIndex].L_mm, SheetList = {BunkList[BunkIndex].SheetList[SheetIndex]}})
+ end
+ end
+ -- ordino i gruppi di pari lunghezza
+ function compareLenght(a,b)
+ return a.L_mm < b.L_mm
+ end
+ -- per ogni materiale riordino le priorita'
+-- for SheetIndex = 1, #OrderedSheets do
+ table.sort(OrderedSheets, compareLenght)
+ -- ordino i fogli per materiale all'interno dei gruppi
+ function compareMaterial(a,b)
+ return a.MatId < b.MatId
+ end
+ for OrderedIndex = 1, #OrderedSheets do
+ table.sort(OrderedSheets[OrderedIndex].SheetList, compareMaterial)
+ end
+-- end
+ -- rimetto in lista tutti gli sheet come ordinati
+ BunkList[BunkIndex].SheetList = {}
+ local Index = 1
+ for OrderedSheetIndex = 1, #OrderedSheets do
+ for SheetIndex = 1, #OrderedSheets[OrderedSheetIndex].SheetList do
+ OrderedSheets[OrderedSheetIndex].SheetList[SheetIndex].SheetIndex = Index
+ table.insert(BunkList[BunkIndex].SheetList, OrderedSheets[OrderedSheetIndex].SheetList[SheetIndex])
+ Index = Index + 1
+ end
+ end
+ end
+
+ -- segno info con contenuto etichetta fogli
+-- local SHEETLABEL = "SheetLabel"
+-- for Material = 1, #materials do
+-- if EgtOpenFile(Config.sBasePath .. "/Nesting/" .. materials[Material].MatId .. ".nge") then
+-- local nMachGroupId = EgtGetFirstMachGroup()
+-- while nMachGroupId do
+-- local bOk = EgtSetCurrMachGroup(nMachGroupId)
+-- local sMachGroupName = EgtGetMachGroupName(nMachGroupId)
+-- for BunkIndex = 1, #BunkList do
+-- for SheetIndex = 1, #BunkList[BunkIndex].SheetList do
+-- if BunkList[BunkIndex].SheetList[SheetIndex].MatId == materials[Material].MatId and BunkList[BunkIndex].SheetList[SheetIndex].MachGroupName == sMachGroupName then
+-- local nRaw = EgtGetFirstRawPart()
+-- local nSheetLabel = EgtGetFirstNameInGroup(nRaw, SHEETLABEL)
+-- local bOk = EgtSetInfo(nSheetLabel, SHEETLABEL, BunkIndex .. "." .. SheetIndex)
+-- end
+-- end
+-- end
+-- nMachGroupId = EgtGetNextMachGroup(nMachGroupId)
+-- end
+-- EgtSaveFile()
+-- end
+-- end
+
+ -- se debug
+ if DebugCode then
+ -- verifico di aver messo tutti gli sheet sui bunk
+ local SheetList = {}
+ -- raccolgo tutti gli sheet dai bunk in una lista
+ for BunkIndex = 1, #BunkList do
+ for SheetIndex = 1, #BunkList[BunkIndex].SheetList do
+ table.insert(SheetList, BunkList[BunkIndex].SheetList[SheetIndex])
+ end
+ end
+ -- passo gli sheet dei material
+ for MaterialIndex = 1, #materials do
+ if materials[MaterialIndex].SheetList then
+ for BSheetIndex = 1, #materials[MaterialIndex].SheetList do
+ local bFound = false
+ for VSheetIndex = 1, #SheetList do
+ if materials[MaterialIndex].SheetList[BSheetIndex] == SheetList[VSheetIndex] then
+ bFound = true
+ table.remove(SheetList, VSheetIndex)
+ end
+ end
+ if not bFound then
+ table.insert(ErrorList, {ErrType = "E.12", Uid = "SheetId = " ..materials[MaterialIndex].MaterialId .." - " .. materials[MaterialIndex].SheetList[BSheetIndex].SheetIndex,
+ Description = "Sheet lost after distribution on bunks!"})
+ end
+ end
+ end
+ end
+ -- verifico se sono rimasti elementi nella tabella kit
+ if #SheetList > 0 then
+ table.insert(ErrorList, {ErrType = "E.12", Uid = "SheetId = " .. SheetList[1].SheetIndex, Description = #PartList .. " sheet more than in materials after distribution on bunks!"})
+ end
+ end
+
+ local MPCount2 = 0
+ local TotThickness = 0
+ for CurrBunk = 1, #BunkList do
+ for CurrSheet = 1, #BunkList[CurrBunk].SheetList do
+ TotThickness = TotThickness + BunkList[CurrBunk].SheetList[CurrSheet].T_mm
+ MPCount2 = MPCount2 + 1
+ end
+ end
+
+ -- verifica assenza pezzi tra ricevuti e messi sui fogli
+ --local SVPartList = {}
+ --for Sheet = 1, #materials[11].SheetList do
+ -- for Part = 1, #materials[11].SheetList[Sheet].PartList do
+ -- table.insert(SVPartList, materials[11].SheetList[Sheet].PartList[Part].PartId)
+ -- end
+ --end
+ --table.sort(VPartList)
+ --table.sort(SVPartList)
+ --local ListCount = #VPartList
+ --local List1 = VPartList
+ --local List2 = SVPartList
+ --local Only1 = {}
+ --local Only2 = {}
+ --if #SVPartList > #VPartList then
+ -- ListCount = #SVPartList
+ -- List1 = SVPartList
+ -- List2 = VPartList
+ --end
+ --local Index1, Index2 = 1, 1
+ --while Index1 <= #List1 do
+ -- if Index2 <= #List2 then
+ -- if List1[Index1] > tonumber(List2[Index2]) then
+ -- table.insert(Only2, List2[Index2])
+ -- Index2 = Index2 + 1
+ -- elseif List1[Index1] < tonumber(List2[Index2]) then
+ -- table.insert(Only1, List2[Index2])
+ -- Index1 = Index1 + 1
+ -- Index2 = Index2 + 1
+ -- end
+ -- else
+ -- table.insert(Only1, List2[Index2])
+ -- Index1 = Index1 + 1
+ -- end
+ --end
+
+
+ -- creo batch di risposta
+ local answ = {}
+ answ.BatchId = readBatch.BatchId
+ answ.EnvNum = readBatch.EnvNum
+ answ.ProcType = readBatch.ProcType
+ answ.MachineType = readBatch.MachineType
+ answ.OrderType = readBatch.OrderType
+ answ.ProcessNotes = ""
+
+ -- sommo tempo totale di lavorazione e superficie materiale utilizzata
+ local TotTime = 0
+ local SurfaceWork = 0
+ local SurfaceTotal = 0
+
+ local ChangeSheetTime = 100
+ for Material = 1, #materials do
+ if materials[Material] and materials[Material].SheetList and #materials[Material].SheetList > 0 then
+ for Sheet = 1, #materials[Material].SheetList do
+ TotTime = TotTime + materials[Material].SheetList[Sheet].EstimatedWorktime + ChangeSheetTime
+ SurfaceWork = SurfaceWork + materials[Material].SheetList[Sheet].SurfaceWork
+ SurfaceTotal = SurfaceTotal + materials[Material].SheetList[Sheet].SurfaceTotal
+ end
+ end
+ end
+ answ.EstimatedWorktime = TotTime
+ answ.SurfaceWork = SurfaceWork
+ answ.SurfaceTotal = SurfaceTotal
+
+ -- aggiungo i bunk alla risposta
+ answ.BunkList = BunkList
+
+ -- aggiungo carrelli con kit alla risposta eliminando gli ordini
+-- local StartCartIndex = 0
+-- if readBatch.NumIndexStart then
+-- StartCartIndex = readBatch.NumIndexStart
+-- end
+ for CartIndex = 1, #Carts do
+ Carts[CartIndex].KitList = {}
+-- Carts[CartIndex].CartIndex = StartCartIndex + CartIndex - 1
+ for OrderIndex = 1, #Carts[CartIndex].OrderList do
+ for KitIndex = 1, #Carts[CartIndex].OrderList[OrderIndex].KitList do
+ table.insert(Carts[CartIndex].KitList, Carts[CartIndex].OrderList[OrderIndex].KitList[KitIndex])
+ end
+ end
+ end
+ answ.CartList = Carts
+
+ -- aggiungo bins alla risposta
+ answ.BinList = Bins
+
+ -- attacco lista errori e tempo di computazione
+ answ.ErrorList = ErrorList
+ if #ErrorList == 0 then
+ answ.ProcessStatus = 3
+ else
+ answ.ProcessStatus = 2
+ end
+ answ.ProcessingRuntime = EgtStopCounter() / 1000
+
+ -- invio dati
+ local bOk = RESTLib.set(Config.sPathBatch, answ)
+ if bOk then print("OK") end
+
+ EgtOutText("Nesting end")
+
+end
+--
+
+-- funzione che esegue calcolo stima tempi
+function Estimate(readBatch)
+
+ -- calcolo lavorazioni, stime, ecc
+ local IsOffLine = false
+ if readBatch.OrderType == 1 then
+ IsOffLine = true
+ end
+
+ -- imposto macchina in uso
+ NestingLib.ManageMachine(IsOffLine)
+
+ EgtOutText("Estimate start")
+
+ -- lista errori
+ local ErrorList = {}
+
+ -- conto tutto
+ local OrderCount = #readBatch.OrderList
+ local KitCount = 0
+ local PartCount = 0
+ local NoDXFCount = 0
+ local NoMaterialCount = 0
+ local NoMaterialCount2 = 0
+ for Order = 1, #readBatch.OrderList do
+ KitCount = KitCount + #readBatch.OrderList[Order].KitList
+ for Kit = 1, #readBatch.OrderList[Order].KitList do
+ PartCount = PartCount + #readBatch.OrderList[Order].KitList[Kit].PartList
+ end
+ end
+
+ -- recupero lista materiali
+ local materials = RESTLib.get(Config.sPathMat)
+
+ -- aggiungo liste pezzi
+ for Material = 1, #materials do
+ if not materials[Material].PartList then materials[Material].PartList = {} end
+ end
+
+ -- divido pezzi per materiale
+ local CurrOrderIndex = 1
+ local CurrOrderCount = #readBatch.OrderList
+ if Config.bDoubleMach then
+ CurrOrderIndex = readBatch.CurrOrderIndex
+ CurrOrderCount = readBatch.CurrOrderIndex
+ end
+ for Order = CurrOrderIndex, CurrOrderCount do
+ OrderCount = OrderCount + 1
+ for Kit = 1, #readBatch.OrderList[Order].KitList do
+ KitCount = KitCount + 1
+ for Part = 1, #readBatch.OrderList[Order].KitList[Kit].PartList do
+ PartCount = PartCount + 1
+ 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, TempPart.PartExtCode, true)
+ -- 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
+ local PaintVal = "NO"
+ if Paint then
+ PaintVal = "YES"
+ end
+ TempPart.OptParameters.PaintFlag = PaintVal
+ -- suddivido i pezzi per materiale
+ for Material = 1, #materials do
+ if TempPart.MatExtCode == materials[Material].MatExtCode then
+ TempPart.MatId = materials[Material].MatId
+ -- aggiungo il pezzo all'interno del materiale
+ table.insert(materials[Material].PartList, TempPart)
+ 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
+
+ PartCount1 = 0
+ local MatIde = 10
+-- local MatIndex = MatIde + 1
+-- local MatCount = MatIndex
+ local MatIndex = 1
+ local MatCount = #materials
+
+ -- per ogni materiale creo un progetto
+ local PARTID = "PartId"
+ local PRIORITY = "Priority"
+ local ROUGHER = {".375 ROUGHER","ROUGHER"}
+ local DTMXPOS = "DATA MATRIX CODE POSITION"
+ local MatSheetList = {}
+ --for Material = 1, #materials do
+ for Material = MatIndex, MatCount do
+ -- se è il materiale nullo salto al prossimo
+ if materials[Material].MatId ~= 0 and #materials[Material].PartList > 0 then
+ EgtOutText("Material: " .. materials[Material].MatDesc)
+ EgtNewFile()
+ materials[Material].SheetList = {}
+ local PartToBeMachined = {}
+ for Part = 1, #materials[Material].PartList do
+ table.insert(PartToBeMachined, materials[Material].PartList[Part])
+ end
+ local IsValidation = false
+ if readBatch.MaxTime == 1 then
+ IsValidation = true
+ end
+ NestingLib.NestPartInRawPart(nil, PartToBeMachined, materials[Material], ErrorList, true, IsValidation)
+ local bOk, answ = ManageError(ErrorList, readBatch)
+ -- se doppia macchina
+ if bOk then
+ if Config.bDoubleMach then
+ return answ
+ else
+ return
+ end
+ end
+
+ NestingLib.PostNestOp(materials[Material], ErrorList, true, readBatch.BatchId)
+ bOk, answ = ManageError(ErrorList, readBatch)
+ -- se doppia macchina
+ if bOk then
+ if Config.bDoubleMach then
+ return answ
+ else
+ return
+ end
+ end
+
+-- -- salvo il progetto di nesting
+-- EgtSaveFile(Config.sBasePath .. "/Estimate/" .. materials[Material].MatId .. ".nge")
+ -- salvo il progetto di nesting
+ local sProjectPath = NestingLib.VerifyPath("Estimate", readBatch.BatchId, nil)
+ EgtSaveFile(sProjectPath .. "/" .. materials[Material].MatId .. ".nge")
+ end
+ end
+
+ EgtOutText("End sheets estimate")
+
+
+ -- creo batch di risposta
+ local answ = {}
+ answ.BatchId = readBatch.BatchId
+ answ.EnvNum = readBatch.EnvNum
+ answ.ProcType = readBatch.ProcType
+ answ.MachineType = readBatch.MachineType
+ answ.OrderType = readBatch.OrderType
+ answ.ProcessNotes = ""
+
+ -- sommo tempo totale di lavorazione
+ local TotTime = 0
+ local ChangeSheetTime = 100
+ for Material = 1, #materials do
+ if materials[Material] and materials[Material].SheetList and #materials[Material].SheetList > 0 then
+ for Sheet = 1, #materials[Material].SheetList do
+ TotTime = TotTime + materials[Material].SheetList[Sheet].EstimatedWorktime + ChangeSheetTime
+ end
+ end
+ end
+ answ.EstimatedWorktime = TotTime + (TotTime * 0.1) -- aggiungo 10% di sicurezza
+
+ if readBatch.OrderType == 1 then
+ answ.DrawingPath = NestingLib.VerifyPath("SVG", readBatch.BatchId, nil) .. "/"
+ answ.CNCPath = NestingLib.VerifyPath("CNC", readBatch.BatchId, nil) .. "/"
+ end
+
+ -- recupero pezzi analizzati
+ answ.PartList = {}
+ for Material = MatIndex, MatCount do
+ if materials[Material].PartList and #materials[Material].PartList > 0 then
+ for Part = 1, #materials[Material].PartList do
+ table.insert(answ.PartList, materials[Material].PartList[Part])
+ end
+ end
+ end
+
+ -- attacco lista errori e tempo di computazione
+ answ.ErrorList = ErrorList
+ if #ErrorList == 0 then
+ answ.ProcessStatus = 3
+ else
+ answ.ProcessStatus = 2
+ end
+ answ.ProcessingRuntime = EgtStopCounter() / 1000
+
+ -- se doppia macchina
+ if Config.bDoubleMach then
+ return answ
+ end
+
+ -- invio dati
+ local bOk = RESTLib.set(Config.sPathBatch, answ)
+ if bOk then print("OK") end
+
+ EgtOutText("Estimate end")
+
+end
+--
+
+-- funzione che esegue calcolo stima tempi
+function ExtendedEstimate(readBatch)
+ -- creo batch di risposta
+ local answ = {}
+ answ.BatchId = readBatch.BatchId
+ answ.EnvNum = readBatch.EnvNum
+ answ.ProcType = readBatch.ProcType
+ answ.MachineType = readBatch.MachineType
+ answ.OrderType = readBatch.OrderType
+ answ.ProcessNotes = ""
+
+ -- lista errori
+ local ErrorList = {}
+ -- tempo totale stimato
+ local TotTime = 0
+
+ answ.EstOrderList = {}
+ answ.PartList = {}
+ -- chiamo stima per ogni materiale
+ for Order = 1, #readBatch.OrderList do
+ readBatch.CurrOrderIndex = Order
+ local estm = Estimate(readBatch)
+ -- aggiungo pezzi a lista pezzi del risultato
+ if #estm.ErrorList == 0 then
+ for PartIndex = 1, #estm.PartList do
+ table.insert(answ.PartList, estm.PartList[PartIndex])
+ end
+ end
+ -- accodo errori dell'ordine
+ for ErrorIndex = 1, #estm.ErrorList do
+ table.insert(ErrorList, estm.ErrorList[ErrorIndex])
+ end
+ if ManageError(ErrorList, readBatch, true) then return end
+ -- recupero lista materiali
+ local materials = RESTLib.get(Config.sPathMat)
+ for MaterialIndex = 1, #materials do
+ materials[MaterialIndex].PriorityList = {}
+ end
+ local OrderList = {}
+ local Carts = {}
+ table.insert( OrderList, readBatch.OrderList[Order])
+ -- calcolo numero carrelli
+ NestingLib.FilterPaintedParts(OrderList, materials, ErrorList)
+ NestingLib.CreateCart(OrderList, Carts)
+ -- imposto priorità sui pezzi in base ai carrelli e li divido per materiale e priorità
+ NestingLib.SetPriorityProcessMaterial(Carts, materials, ErrorList)
+ -- creo bin necessari
+ local Bins = {}
+ NestingLib.CreateBin(materials, Bins)
+ -- riporto numero pezzi, carrelli e stima tempo taglio nell'ordine
+ readBatch.OrderList[Order].NumCart = #Carts
+ readBatch.OrderList[Order].NumBin = #Bins
+ readBatch.OrderList[Order].NumPart = #estm.PartList
+ readBatch.OrderList[Order].TotTime = estm.EstimatedWorktime
+ TotTime = TotTime + estm.EstimatedWorktime
+ -- aggiungo ordine a lista ordini del risultato
+ table.insert(answ.EstOrderList, readBatch.OrderList[Order])
+ end
+
+ -- correggo e riporto tempo totale di lavorazione
+ answ.EstimatedWorktime = TotTime
+
+ -- attacco lista errori e tempo di computazione
+ answ.ErrorList = ErrorList
+ if #ErrorList == 0 then
+ answ.ProcessStatus = 3
+ else
+ answ.ProcessStatus = 2
+ end
+ answ.ProcessingRuntime = EgtStopCounter() / 1000
+
+ -- invio dati
+ local bOk = RESTLib.set(Config.sPathBatch, answ)
+ if bOk then print("OK") end
+
+ EgtOutText("ExtendedEstimate end")
+
+end
+--
+
+-- ciclo principale
+while true do
+ EgtNewFile()
+ if EgtProcessEvents( 1, 5) == 1 then
+ break
+ else
+ -- leggo un batch
+ local readBatch = RESTLib.get(Config.sPathBatch)
+ if not readBatch or readBatch.BatchId == 0 then --or #readBatch == 0 then
+ EgtPause(Config.CycleDelay)
+ -- socket.sleep(0.5)
+ -- EgtOutLog("Server connection error!")
+ else
+ EgtStartCounter()
+ -- readBatch.OrderType = 1 -> Offline
+ if readBatch.ProcType == 1 or readBatch.OrderType == 1 then
+ Estimate(readBatch)
+ elseif readBatch.ProcType == 3 then
+ Config.bDoubleMach = true
+ ExtendedEstimate(readBatch)
+ else
+ Nesting(readBatch)
+ end
+ end
+ end
+
+end
diff --git a/NestingLib.lua b/NestingLib.lua
new file mode 100644
index 0000000..e5758b0
--- /dev/null
+++ b/NestingLib.lua
@@ -0,0 +1,2498 @@
+--
+-- 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 = 67328
+
+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 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 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
+ 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 PARTID = "PartId"
+local PRIORITY = "Priority"
+local DTMXPOS = "DATA MATRIX CODE POSITION"
+local CARTBININFO = "CARTBININFO"
+local INTPART = "INTPART"
+local RAMP = "RAMP"
+local SKELETONTRACK = "SKELETONTRACK"
+local SKELETONPART = "SKELETON"
+local CUTOPT = "CUTOPT"
+-- funzione legge il dxf ed aggiunge il pezzo al nesting
+local function AddPartListToNesting(PartList, ErrorList, Material)
+ local LastId = GDB_ID.ROOT
+ for Part = 1, #PartList do
+ -- tipo di rotazione del pezzo consentita : 0 -> rotazione libera, 1 -> rotazione solo di 180°, 2 -> nessuna rotazione
+ local RotationType = 0
+ -- verifico se gia' presente per importazione precedente
+ local PartId1 = EgtGetFirstNameInGroup(GDB_ID.ROOT, PartList[Part].PartId)
+ if not PartId1 then
+ -- importo il dxf del pezzo
+ DXFpath = string.gsub(PartList[Part].CadFilePath, "\\", '/')
+ EgtImportDxf(DXFpath)
+ -- se LastId nullo carico primo pezzo
+ if LastId == GDB_ID.ROOT then
+ PartId1 = EgtGetLastInGroup(GDB_ID.ROOT)
+ LastId = PartId1
+ else
+ PartId1 = EgtGetNextPart(LastId)
+ end
+ -- verifico se è un solo pezzo
+ local PartId2 = EgtGetLastPart(LastId)
+ if PartId1 == PartId2 then
+ LastId = PartId1
+ else
+ -- ERRORE!!
+ return
+ end
+ -- assegno l'Id del pezzo e la priorità
+ EgtSetInfo(PartId1, PARTID, PartList[Part].PartId)
+ EgtSetName(PartId1, PartList[Part].PartDtmx)
+ EgtSetInfo(PartId1, PRIORITY, PartList[Part].Priority)
+ end
+ -- lista lavorazioni interne
+ local InternalMach = {}
+ -- lista percorsi interni per pezzi piccoli
+ local IntMachSmallPart = {}
+ -- regione skeleton
+ local nSkeletonRegionId = GDB_ID.NULL
+ -- spengo tutti i layer inutili
+ local LayerId = EgtGetFirstLayer(PartId1)
+ local nMaxId = GDB_ID.NULL
+ local bFound = false
+ while LayerId do
+ local layerName = EgtGetName(LayerId)
+ local bOutline = false
+ -- verifico se ha un nome di outline
+ for Mach = 1, #OutlineMachining[1] do
+ if layerName == OutlineMachining[1][Mach] then
+ bOutline = true
+ end
+ end
+ if bOutline then
+ -- prendo quello più grande che sarà l'esterno
+ local dMaxArea = 0
+ local GeomList = {}
+ local OutlineId = EgtGetFirstInGroup(LayerId)
+ while OutlineId do
+ if EgtGetType( OutlineId) == GDB_TY.CRV_COMPO or EgtGetType( OutlineId) == GDB_TY.CRV_ARC then
+ -- ne verifico lo spessore
+ local OutlineDepth = EgtCurveThickness(OutlineId)
+ if OutlineDepth >= 0 then
+ table.insert(ErrorList, {ErrType = "E.13", Uid = "PartId = " .. PartList[Part].PartId, Description = "Error, outline thickness must be negative!"})
+ EgtOutLog("Error in ".. PartList[Part].CadFilePath ..": outline thickness must be negative!")
+ return
+ end
+ -- se entro la tolleranza
+ if -OutlineDepth >= (Material.T_mm - Config.ThicknessTolerance) and -OutlineDepth <= (Material.T_mm + Config.ThicknessTolerance) then
+ EgtModifyCurveThickness(OutlineId, -Material.T_mm)
+ end
+ -- se il percorso non è chiuso
+ if not EgtCurveIsClosed(OutlineId) then
+ -- calcolo distanza tra inizio e fine
+ local StartPoint = EgtSP(OutlineId)
+ local EndPoint = EgtEP(OutlineId)
+ if abs(Vector3d.len(StartPoint - EndPoint)) <= Config.OpenPathTolerance then
+ -- accorcio estremi di mezzo decimo di millimetro per evitare successivi problemi con offset
+ EgtTrimCurveStartAtLen(OutlineId, 0.015)
+ EgtTrimCurveEndAtLen(OutlineId, EgtCurveLength(OutlineId) - 0.015)
+ EgtCloseCurveCompo(OutlineId)
+ else
+ table.insert(ErrorList, {ErrType = "E.8", Uid = "PartId = " .. PartList[Part].PartId, Description = "Open paths found"})
+ EgtOutLog("Error in ".. PartList[Part].CadFilePath ..": open paths found")
+ return
+ end
+ end
+ local dArea = EgtCurveAreaXY(OutlineId)
+ if dArea and abs(dArea) > dMaxArea then
+ dMaxArea = abs(dArea)
+ nMaxId = OutlineId
+ -- sposto entità contorno esterno per prima
+ table.insert(GeomList, 1, OutlineId)
+ else
+ table.insert(GeomList, OutlineId)
+ end
+ else
+ table.insert(ErrorList, {ErrType = "E.8", Uid = "PartId = " .. PartList[Part].PartId, Description = "There are entities that are not CompositeCurves or Arcs"})
+ EgtOutLog("Warning in ".. PartList[Part].CadFilePath ..": there is entities that are not compo or arcs")
+ end
+ OutlineId = EgtGetNext(OutlineId)
+ end
+ -- se ho trovato il contorno esterno
+ if nMaxId ~= GDB_ID.NULL then
+ -- se necessario inverto le curve per dividere contorni interni ed esterno
+ OutlineId = EgtGetFirstInGroup(LayerId)
+ while OutlineId do
+ local dArea = EgtCurveAreaXY(OutlineId)
+ if not dArea then
+ table.insert(ErrorList, {ErrType = "E.8", Uid = "PartId = " .. PartList[Part].PartId, Description = "Open paths found"})
+ EgtOutLog("Error in ".. PartList[Part].CadFilePath ..": open paths found")
+ return
+ else
+ -- se contorno esterno in senso orario o contorno interno antiorario lo inverto
+ if (OutlineId == nMaxId and dArea < 0) or (OutlineId ~= nMaxId and dArea > 0) then
+ EgtInvertCurve(OutlineId)
+ end
+ end
+ OutlineId = EgtGetNext(OutlineId)
+ end
+ -- salvo area come info
+ local dArea = EgtCurveAreaXY(nMaxId)
+ EgtSetInfo(PartId1, AREA, dArea)
+ -- scrivo carrello e gruppo carrelli a cui appartiene
+ local BBox = EgtGetBBox(nMaxId,GDB_BB.STANDARD)
+ local CartText = ""
+ if PartList[Part].Bin then
+ CartText = "B" .. PartList[Part].Bin
+ elseif PartList[Part].Cart then
+ CartText = "C" .. PartList[Part].Cart
+ end
+ if DebugCode and PartList[Part].Priority then
+ CartText = CartText .. "-" .. PartList[Part].Priority
+ end
+ local CartIndexLayer = EgtGroup(PartId1)
+ EgtSetName(CartIndexLayer, CARTBININFO)
+ EgtSetInfo(CartIndexLayer, "DTMX", PartList[Part].PartDtmx)
+ if PartList[Part].OptParameters.RoundEdge == 'YES' or PartList[Part].OptParameters.TNutFlag == 'YES' then
+ EgtSetInfo(CartIndexLayer, "TEXT", CartText .. '*')
+ else
+ EgtSetInfo(CartIndexLayer, "TEXT", CartText)
+ end
+ EgtSetInfo(CartIndexLayer, "MATID", PartList[Part].MatId)
+ EgtTextAdv(CartIndexLayer,
+ Point3d(BBox:getCenter():getX(), BBox:getCenter():getY(), BBox:getMax():getZ()),
+ 0, CartText, "Arial", 2, 'S', 30, 2, 0, GDB_TI.MC)
+ EgtSetColor(CartIndexLayer, 'WHITE')
+ -- EgtText( int nParentId, Point3d PtIni, string Text, num dH [, int nRefType = GDB_RT.LOC])
+ -- calcolo box per sapere se girare il pezzo
+ local OutlineBox = EgtGetBBox(nMaxId, GDB_BB.STANDARD)
+ local MinOutlineBox = BBox3d.getMin(OutlineBox)
+ local MaxOutlineBox = BBox3d.getMax(OutlineBox)
+ local OutlineY = Point3d.getY(MaxOutlineBox) - Point3d.getY(MinOutlineBox)
+ local OutlineX = Point3d.getX(MaxOutlineBox) - Point3d.getX(MinOutlineBox)
+ -- imposto RollerDist
+ local RollerDist = MXRollerDist
+ if IsOffline then
+ RollerDist = NWRollerDist
+ end
+ -- if dArea < Config.dVerySmallPartArea then
+ -- RotationType = 2
+ -- controllo se ha una venatura da rispettare
+ local nGrainLayerId = EgtGetFirstNameInGroup(PartId1, 'GRAIN')
+ if nGrainLayerId then
+-- -- recupero linea di direzione
+-- local nGrainId = EgtGetFirstInGroup(nGrainLayerId)
+-- if nGrainId then
+-- local vtGrain = EgtSV(nGrainId)
+-- end
+ RotationType = 1
+ elseif OutlineX <= RollerDist and OutlineY > RollerDist then
+ EgtRotate(PartId1, ORIG(), Z_AX(), 90)
+ RotationType = 1
+ elseif OutlineY <= RollerDist and OutlineX > RollerDist then
+ RotationType = 1
+ end
+ EgtSetName(nMaxId, OUTLINE)
+ -- copio outline in un layer dedicato
+ local OutlineLayer = EgtGroup(PartId1)
+ EgtSetName(OutlineLayer, OUTLINE)
+ local OutlineCopy = EgtCopy(nMaxId, OutlineLayer)
+ EgtSetName(OutlineCopy, OUTLINE)
+ -- creo regione del pezzo
+ local RegId = EgtSurfFlatRegion(OutlineLayer, GeomList)
+ EgtSetName(RegId, PartList[Part].PartDtmx)
+ EgtSetColor(RegId, Color3d(255,128,0,50))
+ EgtSetStatus(LayerId, GDB_ST.ON)
+ -- creo regione traccia utensile
+ local ToolDiam = 0
+ if EgtMdbSetCurrMachining(OutlineMachining[2][1]) then
+ local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL)
+ EgtTdbSetCurrTool(ToolName)
+ ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.DIAM)
+ end
+ -- verifico se ci sono opzioni di lavorazione
+ if PartList[Part].OptParameters.CutOpt then
+ if PartList[Part].OptParameters.CutOpt == SKELETONPART or PartList[Part].OptParameters.CutOpt == "SKELETON&TAB" then
+ -- creo regione per skeleton
+ local nSkeletonId = EgtOffsetCurveAdv(nMaxId, ToolDiam + Config.dSkeletonWidth)
+ EgtSetName(nSkeletonId, "SkeletonOutline")
+ EgtRelocateGlob(nSkeletonId, OutlineLayer)
+ local srfSkeletonId = EgtSurfFlatRegion(OutlineLayer, {nMaxId, nSkeletonId})
+ EgtSetName(srfSkeletonId, "SKELETON")
+ EgtSetStatus(nSkeletonId, GDB_ST.OFF)
+ EgtSetStatus(srfSkeletonId, GDB_ST.OFF)
+ nSkeletonRegionId = srfSkeletonId
+ end
+ -- salvo l'info per processarla in lavorazione
+ EgtSetInfo(OutlineLayer, CUTOPT, PartList[Part].OptParameters.CutOpt)
+ end
+ -- se c'e' opzione dimensione etichetta
+ if PartList[Part].OptParameters.Label then
+ -- la salvo
+ EgtSetInfo(OutlineLayer, "LABEL", PartList[Part].OptParameters.Label)
+ end
+ -- ciclo sui percorsi del pezzo
+ OutlineId = EgtGetFirstInGroup(LayerId)
+ while OutlineId do
+ -- se contorno interno
+ if OutlineId ~= nMaxId then
+ -- classifico percorsi interni come svuotature o buchi per pezzi
+ -- classifico percorso rispetto al pezzo
+ local OutlineClassification = EgtCurveWithRegionClassify(OutlineId, RegId)
+ -- verifico spessore percorsi interni
+ local OutlineDepth = EgtCurveThickness(OutlineId)
+ -- se spesso come il pezzo e area maggiore di quella minima per un buco
+ local dIntArea = EgtCurveAreaXY(OutlineId)
+ if -OutlineDepth >= (Material.T_mm - Config.ThicknessTolerance) and math.abs(dIntArea) >= Config.IntPartMinArea then
+ EgtSetInfo(OutlineId, INTPART, 1)
+ EgtSetInfo(PartId1, INTPART, 1)
+ table.insert(IntMachSmallPart, OutlineId)
+ elseif OutlineClassification == GDB_CRC.OUT or OutlineClassification == GDB_CRC.INTERS then
+ -- se contorno interno, lo aggiungo alla lista lavorazioni interne
+ table.insert(InternalMach, OutlineId)
+ end
+ end
+ -- creo regione traccia utensile
+ local ToolDiam = 0
+ if EgtMdbSetCurrMachining(OutlineMachining[2][1]) then
+ local ToolName = EgtMdbGetCurrMachiningParam(MCH_MP.TOOL)
+ EgtTdbSetCurrTool(ToolName)
+ ToolDiam = EgtTdbGetCurrToolParam(MCH_TP.DIAM)
+ end
+ if Config.bSkeletonReduction then
+ local nOffId, nOffCnt = EgtOffsetCurveAdv(OutlineId, ToolDiam + 0.01)
+ -- elimino gli offset successivi al primo risultanti da porzioni di percorso con distanza inferiore all'offset
+ for Index = 1, nOffCnt - 1 do
+ EgtErase(nOffId + Index)
+ end
+ if not nOffId then
+ table.insert(ErrorList, {ErrType = "E.8", Uid = "PartId = " .. PartList[Part].PartId, Description = "Open paths found"})
+ EgtOutLog("Error in ".. PartList[Part].CadFilePath ..": open paths found")
+ return
+ end
+ EgtSetName(nOffId, "SkeletonToolOutline")
+ EgtRelocateGlob(nOffId, OutlineLayer)
+ local srfToolId = GDB_ID.NULL
+ if OutlineId == nMaxId then
+ srfToolId = EgtSurfFlatRegion(OutlineLayer, {OutlineId, nOffId})
+ else
+ -- verifico se dimensioni minori della griglia
+ local b3Outline = EgtGetBBoxGlob(OutlineId, GDB_BB.STANDARD + GDB_BB.ONLY_VISIBLE + GDB_BB.IGNORE_TEXT + GDB_BB.IGNORE_DIM)
+ if b3Outline:getDimX() < Config.bSRMaxWidth and b3Outline:getDimY() < Config.bSRMaxHeight or nOffId == GDB_ID.NULL then
+ srfToolId = EgtSurfFlatRegion(OutlineLayer, OutlineId)
+ else
+ srfToolId = EgtSurfFlatRegion(OutlineLayer, {nOffId, OutlineId})
+ end
+ EgtInvertSurf(srfToolId)
+ end
+ EgtSetName(srfToolId, SKELETONTRACK)
+ EgtSetStatus(nOffId, GDB_ST.OFF)
+ EgtSetStatus(srfToolId, GDB_ST.OFF)
+ end
+ -- vado a percorso successivo
+ OutlineId = EgtGetNext(OutlineId)
+ end
+ bFound = true
+ -- se non ho trovato il contorno esterno do' errore
+ else
+ EgtOutLog("Error outline not found in part " .. PartList[Part].PartId)
+ table.insert(ErrorList, {ErrType = "E.4", Uid = "PartId = " .. PartList[Part].PartId, Description = "Can't find outline"})
+ return
+ end
+ elseif layerName == DTMXPOS then
+ -- recupero punti dentro questo layer
+ local bFirstPoint = true
+ local nPointId = EgtGetFirstInGroup(LayerId)
+ local dArea = EgtGetInfo(PartId1, AREA, "d")
+ while nPointId and nPointId ~= GDB_ID.NULL do
+ if bFirstPoint or (dArea and dArea > Config.dSkelSkinTab_MaxArea) then
+ -- li chiamo con nome part piu' _QR
+ EgtSetName(nPointId, "$QR$" .. PartList[Part].PartDtmx)
+ bFirstPoint = false
+ end
+ nPointId = EgtGetNext(nPointId)
+ end
+ EgtSetStatus(LayerId, GDB_ST.ON)
+ elseif layerName == OUTLINE or layerName == HOLE or layerName == CARTBININFO or layerName == RAMP then
+ EgtSetStatus(LayerId, GDB_ST.ON)
+ else
+ EgtSetStatus(LayerId, GDB_ST.OFF)
+ end
+ LayerId = EgtGetNext(LayerId)
+ end
+ -- se non ho trovato il contorno esterno do' errore
+ if not bFound then
+ EgtOutLog("Error outline not found in part " .. PartList[Part].PartId)
+ table.insert(ErrorList, {ErrType = "E.4", Uid = "PartId = " .. PartList[Part].PartId, Description = "Can't find outline"})
+ return
+ end
+ -- preparo pezzo per il nesting
+ local Priority = 0
+ if PartList[Part].Priority then
+ Priority = PartList[Part].Priority
+ end
+ local bCanRotate, dRotStep = true, 0
+ if RotationType == 1 then
+ dRotStep = 180
+ elseif RotationType == 2 then
+ bCanRotate = false
+ end
+ -- aggiungo pezzo al nesting
+ EgtAutoNestAddPart( PartId1, nMaxId, false, bCanRotate, dRotStep, Priority, 1)
+ -- EgtAutoNestAddPart( PartId, OutlineId, bCanFlip, bCanRotate, dRotStep, nPriority, nCount)
+ -- aggiungo le lavorazioni interne abbastanza grandi da poterci aggiungere pezzi
+ for IntPart = 1, #IntMachSmallPart do
+ EgtAutoNestAddHoleToPart( PartId1, IntMachSmallPart[IntPart])
+ -- EgtAutoNestAddToolOutlineToPart( int nPartId, int nToolOutlineId)
+ end
+ -- aggiungo le lavorazioni interne come possibili ingombri
+ for IntMach = 1, #InternalMach do
+ EgtAutoNestAddToolOutlineToPart( PartId1, InternalMach[IntMach])
+ -- EgtAutoNestAddToolOutlineToPart( int nPartId, int nToolOutlineId)
+ end
+ EgtAutoNestAddToolOutlineToPart( PartId1, nSkeletonRegionId)
+ end
+end
+--
+
+-- funzione che imposta le macchine multiax secondo indice
+local function SetMachineByIndex(MachId)
+ if MachId == 1 then
+ sCurrMachName = "Multiax-NE_Nest01"
+ EgtSetCurrMachine(sCurrMachName)
+ elseif MachId == 2 then
+ sCurrMachName = "Multiax-NE_Nest02"
+ EgtSetCurrMachine(sCurrMachName)
+ 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
+ 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)))
+ 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
+ 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)
+ 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 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
+ 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"
+-- 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()
+
+ -- creo pannello del materiale
+ local SheetPartId = EgtGroup(GDB_ID.ROOT)
+ EgtSetName(SheetPartId, "Sheet")
+ local SheetLayerId = EgtGroup(SheetPartId)
+ EgtSetName(SheetLayerId, OUTLINE)
+ local SheetOutlineId = EgtRectangle2P(SheetLayerId, Point3d(0,0,0), Point3d(Material.L_mm, Material.W_mm, 0), GDB_RT.GLOB)
+ EgtModifyCurveThickness(SheetOutlineId, -Material.T_mm)
+ EgtSetName(SheetOutlineId, OUTLINE)
+
+ -- ricavo Kerf di questo materiale
+ local dKerf = 9
+ for Index = 1, #Config.Kerf do
+ if Config.Kerf[Index].MatId == Material.MatId then
+ dKerf = Config.Kerf[Index].Kerf
+ end
+ end
+
+ -- verifico se ultimo grezzo non nullo
+ local LastMachGroupId = nil
+ if LastRaw and LastRaw ~= GDB_ID.NULL then
+ -- recupero Id gruppo di lavoro e lo attivo
+ LastMachGroupId = EgtGetParent(EgtGetParent(LastRaw))
+ -- recupero lista pezzi già presenti nel grezzo
+ EgtSetCurrMachGroup(LastMachGroupId)
+ -- recupero PartId dei pezzi
+ local NestedPartList = {}
+ local PartId = EgtGetFirstPartInRawPart(LastRaw)
+ while PartId do
+ local LayerOutlineId = EgtGetFirstNameInGroup(PartId, OUTLINE)
+ local OutlineId = EgtGetFirstNameInGroup(LayerOutlineId, OUTLINE)
+ table.insert(NestedPartList, OutlineId)
+ PartId = EgtGetNextPartInRawPart(PartId)
+ end
+ -- resetto gruppo di lavoro per tornare in modalità disegno a fare il nesting
+ EgtResetCurrMachGroup()
+ -- Preparo foglio per nesting
+ EgtAutoNestAddSheet( SheetPartId, SheetOutlineId, dKerf, 0, 1) -- EgtAutoNestAddSheet( SheetId, OutlineId, dKerf, nPriority, nCount)
+ -- imposto come difetti i pezzi già presenti
+ for Index = 1, #NestedPartList do
+ EgtAutoNestAddDefectToSheet(SheetPartId, NestedPartList[Index]) -- EgtAutoNestAddDefectToSheet( SheetId, DefectId)
+ end
+ -- recupero etichetta
+ local nSheetLabel = EgtGetFirstNameInGroup(LastRaw, SHEETLABEL)
+ -- la aggiungo come difetto
+ EgtAutoNestAddDefectToSheet(SheetPartId, nSheetLabel) -- EgtAutoNestAddDefectToSheet( SheetId, DefectId)
+ else
+ -- creo etichetta dello sheet
+ local dLabelW = 50
+ local dLabelH = 25
+ local dYPos = Material.W_mm
+ if Material.W_mm > 1465 then
+ dYPos = 1465 + (dLabelH)
+ end
+ local nSheetLabel = EgtRectangle2P(SheetLayerId, Point3d(0, dYPos - dLabelH,0), Point3d(dLabelW, dYPos, 0), GDB_RT.GLOB)
+ EgtSetName(nSheetLabel, SHEETLABEL)
+ -- creo foglio per nesting
+ EgtAutoNestAddSheet( SheetPartId, SheetOutlineId, dKerf, 0, 50) -- EgtAutoNestAddSheet( SheetId, OutlineId, dKerf, nPriority, nCount)
+ -- aggiungo etichetta come difetto
+ EgtAutoNestAddDefectToSheet(SheetPartId, nSheetLabel) -- EgtAutoNestAddDefectToSheet( SheetId, DefectId)
+ end
+
+ -- aggiungo tutti i pezzi al nesting
+ AddPartListToNesting(PartList, ErrorList, Material)
+ if #ErrorList > 0 then return end
+ -- recupero diametro utensile usato per outline
+ local ToolDiam = 0
+ local x = EgtGetCurrMachineName()
+ 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)
+ end
+ -- se impostata seconda macchina, reimposto la prima
+ local sMachName = EgtGetCurrMachineName()
+ if sMachName == 'Multiax-NE_Nest02' then
+ SetMachineByIndex(1)
+ end
+ else
+ table.insert(ErrorList, {ErrType = "E.10", Uid = "Generic", Description = "Error in nesting function!"})
+ end
+ -- ritorno l'ultimo grezzo utilizzato
+ return LastRaw
+end
+--
+
+-- Funzione che restituisce entità in lavorazione corrente
+function GetEntIdFromCurrMachining()
+ local Geo = EgtGetMachiningGeometry()
+ if not Geo then return GDB_ID.NULL end
+ if type( Geo) == 'table' and
+ type( Geo[1]) == 'table' and type( Geo[1][1]) == 'number' and
+ type( Geo[#Geo]) == 'table' and type( Geo[#Geo][1]) == 'number' then
+ return Geo[1][1], Geo[#Geo][1]
+ else
+ return GDB_ID.NULL
+ end
+end
+
+-- funzione che imposta le lavorazioni nelle liste per TSP
+local function InitInTSP(MachId, MachList, MachListIndex)
+ local nStartId, nEndId = GetEntIdFromCurrMachining()
+ if nStartId ~= GDB_ID.NULL and EgtExistsObj( nStartId) and nEndId ~= GDB_ID.NULL and EgtExistsObj( nEndId) then
+ local ptStart = EgtSP( nStartId, GDB_ID.ROOT)
+ local ptEnd = EgtEP( nEndId, GDB_ID.ROOT)
+ local bInvert = EgtGetMachiningParam( MCH_MP.INVERT)
+ local dAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE)
+ if not dAng then dAng = 0 end
+ if bInvert then
+ ptStart, ptEnd = ptEnd, ptStart
+ end
+ if MachListIndex and MachListIndex > 0 then
+ table.insert( MachList[MachListIndex], {Id=MachId, Start= ptStart, End = ptEnd, Ang=abs( dAng)})
+ else
+ table.insert( MachList, {Id=MachId, Start= ptStart, End = ptEnd, Ang=abs( dAng)})
+ end
+ end
+end
+--
+
+-- funzione che ordina le lavorazioni con l'algoritmo TSP
+local function SortCuts(MachiningList, LastMch)
+ if MachiningList and #MachiningList > 0 then
+ -- recupero punto finale ultima lavorazione
+ EgtSetCurrMachining(LastMch)
+ local ptEnd = EgtGetMachiningEndPoint() or Point3d( -200, -200, 0)
+ -- calcolo ordinamento
+ EgtSpInit()
+ for i = 1, #MachiningList do
+ EgtSpAddPoint( MachiningList[i].Start:getX(), MachiningList[i].Start:getY(), 0, 0, MachiningList[i].Ang,
+ MachiningList[i].End:getX(), MachiningList[i].End:getY(), 0, 0, MachiningList[i].Ang)
+ end
+ EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, ptEnd:getX(), ptEnd:getY())
+ local vOutlineOrd = EgtSpCalculate( SHP_TY.OPEN)
+ EgtSpTerminate()
+ -- applico ordinamento calcolato
+ -- parto da LastMch precedente
+ if vOutlineOrd then
+ for i = 1, #vOutlineOrd do
+ EgtRelocateGlob( MachiningList[vOutlineOrd[i]].Id, LastMch, GDB_IN.AFTER)
+ LastMch = MachiningList[vOutlineOrd[i]].Id
+ end
+ end
+ end
+ return LastMch
+end
+--
+
+-- funzione che ordina le lavorazioni con l'algoritmo TSP
+local function SortParts(PartList, bZigZagSorting)
+ local nRawId = EgtGetFirstRawPart()
+ local ptRawCenter = EgtGetRawPartCenter(nRawId)
+ -- calcolo ordinamento
+ EgtSpInit()
+ for i = 1, #PartList do
+ if bZigZagSorting then
+ EgtSpAddPoint( PartList[i].BBox:getCenter():getX(), PartList[i].BBox:getCenter():getY())
+ else
+ local dDeltaX = PartList[i].BBox:getCenter():getX() - ptRawCenter:getX()
+ local dDeltaY = PartList[i].BBox:getCenter():getY() - ptRawCenter:getY()
+ local dDistXY = sqrt( dDeltaX * dDeltaX + dDeltaY * dDeltaY)
+ EgtSpAddPoint( PartList[i].BBox:getCenter():getX(), PartList[i].BBox:getCenter():getY(), 10 * dDistXY, 0, 0,
+ PartList[i].BBox:getCenter():getX(), PartList[i].BBox:getCenter():getY(), 10 * dDistXY, 0, 0)
+ end
+ end
+ EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, -200, -200, 20000, 0, 0)
+ local vOutlineOrd
+ if bZigZagSorting then
+ -- imposto larghezza colonna zig zag
+ EgtSpSetZzOwStep(400)
+ vOutlineOrd = EgtSpCalculate( SHP_TY.ZIGZAG_Y)
+ else
+ vOutlineOrd = EgtSpCalculate( SHP_TY.OPEN)
+ end
+ EgtSpTerminate()
+ -- applico ordinamento calcolato
+ local NewPartList = {}
+ if vOutlineOrd then
+ for i = 1, #vOutlineOrd do
+ table.insert(NewPartList, PartList[vOutlineOrd[i]])
+ end
+ end
+ return NewPartList
+end
+--
+
+local function ProcessMachinings(HoleList, RampList, 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(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 then
+ local MachDirName = ''
+ if MachId == 0 then
+ MachDirName = '##REPLACEME##'
+ elseif MachId == 1 then
+ MachDirName = 'NE01'
+ elseif MachId == 2 then
+ MachDirName = 'NE02'
+ 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 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') == 2 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 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))
+ -- 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
+ -- 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
+ -- 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 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 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 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 then
+ -- salvo svg del grezzo
+ local CurrSVGPath = NestingLib.VerifyPath("SVG", BatchId, Material)
+ if not UtilityLib.FolderExists(CurrSVGPath) then
+ EgtCreateDirectory(CurrSVGPath)
+ end
+ -- salvo disegni tavola
+ CurrSVGPath = CurrSVGPath .. "/".. Material.SheetList[Sheet].MachGroupName .. ".svg"
+ -- creo file svg
+ EgtSetMachineLook( MCH_LOOK.TAB)
+ bOk = EgtExportSvg( GDB_ID.ROOT, CurrSVGPath, 447)
+ if bOk then
+ Material.SheetList[Sheet].Drawing = CurrSVGPath
+ else
+ Material.SheetList[Sheet].Drawing = ""
+ end
+ -- creo svg per ristampa etichette
+ CreateSvgForLabelPrint(CurrSVGPath, Material.SheetList[Sheet].MachGroupName, BatchId, Material)
+ end
+ end
+ end
+end
+--
+
+-- funzione che modifica svg inserendo codici qr per ristampa etichette
+function CreateSvgForLabelPrint(SVGPath, MachGroupName, BatchId, Material)
+ -- apertura file con controllo
+ local fh = io.open( SVGPath, 'r')
+ if not fh then
+ -- errore
+ return
+ end
+ -- lettura di tutte le linee del file
+ local Lines = {}
+ local OneLine = fh:read( '*l')
+ while OneLine do
+ table.insert( Lines, OneLine)
+ OneLine = fh:read( '*l')
+ end
+ fh:close()
+ -- array delle immagini qr da aggiungere alla fine
+ local QrList = {}
+ -- ciclo sulle linee
+ for i = 1, #Lines do
+ local _, _, PartDtmx, dX, dY = string.find(Lines[i], "%s*")
+ if PartDtmx or dX or dY then
+ table.insert(QrList, " ")
+ end
+ local _, _, SVGEnd = string.find(Lines[i], "%s*().*")
+ if i == 458 then
+ local x = 0
+ end
+ if SVGEnd then
+ for i2 = 1, #QrList do
+ table.insert(Lines, i + i2 - 1, QrList[i2])
+ end
+ end
+-- local _, _, PartDtmx, dX, dY = string.find(Lines[i], "%s*")
+-- if PartDtmx or dX or dY then
+-- Lines[i] = " "
+-- end
+-- local _, _, BinCartIndex = string.find(Lines[i], "%s*(%a%d*)")
+-- if BinCartIndex then
+-- Lines[i] = ""
+-- end
+end
+ -- creo path in cui salvare csv per etichette
+ local LabelSVGPath = ""
+ -- se offline
+ if IsOffline then
+ LabelSVGPath = NestingLib.VerifyPath("SVG", BatchId, nil)
+ -- salvo cartella
+ Material.OfflineDrawingFolder = LabelSVGPath .. "/"
+ if not UtilityLib.FolderExists(LabelSVGPath) then
+ EgtCreateDirectory(LabelSVGPath)
+ end
+ LabelSVGPath = LabelSVGPath .. "/" .. Material.MatId .. "_" .. MachGroupName .. "_qr.svg"
+ else
+ LabelSVGPath = NestingLib.VerifyPath("SVG", BatchId, Material)
+ if not UtilityLib.FolderExists(LabelSVGPath) then
+ EgtCreateDirectory(LabelSVGPath)
+ end
+ LabelSVGPath = LabelSVGPath .. "/".. MachGroupName .. "_qr.svg"
+ end
+ -- scrittura delle linee modificate
+ local fh2 = io.open( LabelSVGPath, 'w')
+ for i = 1, #Lines do
+ fh2:write( Lines[i] .. '\n')
+ end
+ fh2:close()
+ -- 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
+ 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, 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 = {}
+ 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, 8000)
+ 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
+ -- 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
+ -- 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
+ end
+ if bDoCalc then
+ -- ordino lavorzioni con algoritmo ts
+ return ProcessMachinings(HoleList, RampList, 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 = {}
+ 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]
+ -- 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])
+ 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])
+ Pocketing = Config.MXPocketingTools
+ IsOffline = false
+ end
+end
+--
+
+---------------------------------------------------------------------
+return NestingLib
diff --git a/RESTLib.lua b/RESTLib.lua
new file mode 100644
index 0000000..a197092
--- /dev/null
+++ b/RESTLib.lua
@@ -0,0 +1,62 @@
+--
+-- 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 REST by EgalTech s.r.l. 2020/08/13
+
+-- Tabella per definizione modulo
+local RESTLib = {}
+
+-- Include
+require( 'EgtBase')
+ltn12 = require( 'ltn12')
+http = require( 'socket.http')
+JSON = require( 'JSON')
+
+-- funzione get di chiamata REST
+function RESTLib.get(path)
+ local resp = {}
+ -- Get info from website
+ --answ, status, body = http.request{url = path, content_type = 'application/json', sink = ltn12.sink.file(io.stdout)}
+ local body, code, headers = http.request{url = path, content_type = 'application/json', sink = ltn12.sink.table(resp)}
+ -- Verify errors
+ if code == 200 then
+ -- concateno le stringhe ricevute
+ local TempData = table.concat(resp)
+ -- e le decodifico da JSON a tabella lua
+ return JSON:decode(TempData) -- decode example
+ else
+ print("Error: ".. (code or '') )
+ return {}
+ end
+end
+--
+
+-- funzione set di chiamata REST
+function RESTLib.set(path, value)
+ local resp = JSON:encode(value)
+ -- Get info from website
+ local body, code, headers = http.request{url = path, content_type = 'application/json', source = ltn12.source.string(resp), method = "POST",
+ headers = {["Content-Type"] = "application/json",
+ ["content-length"] = string.len(resp)}}
+ -- Verify errors
+ if code == 200 then
+ return true
+ else
+ print("Error: ".. (code or '') )
+ return false
+ end
+end
+--
+
+---------------------------------------------------------------------
+return RESTLib
diff --git a/UtilityLib.lua b/UtilityLib.lua
new file mode 100644
index 0000000..7529435
--- /dev/null
+++ b/UtilityLib.lua
@@ -0,0 +1,250 @@
+--
+-- 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 ausiliarie by EgalTech s.r.l. 2020/08/13
+
+-- Tabella per definizione modulo
+local UtilityLib = {}
+
+-- Include
+require( 'EgtBase')
+local Config = require( 'Config')
+
+-- path di salvataggio dati
+local PNGPath = Config.sBasePath .. "/PNG"
+
+-- list of all png created codes
+local PNGIdList = {}
+
+-- Check if folder exists --
+function UtilityLib.FolderExists(strFolderName)
+ if EgtExistsDirectory(strFolderName:gsub("\\$",""),"mode") then
+ return true
+ else
+ return false
+ end
+end
+--
+
+local OUTLINE = "Outline"
+-- Colore del grezzo
+local ColA = Color3d( 255, 165, 0, 30)
+
+local SHEETLABEL = "SheetLabel"
+-- funzione che crea il grezzo
+function UtilityLib.RawPartCreation(SheetPartId, vtOffs, IsOffLine)
+ local Pz = SheetPartId
+ local Ls = EgtGetFirstNameInGroup( Pz, OUTLINE)
+ local Er = EgtGetFirstNameInGroup( Ls, OUTLINE)
+ local SheetLabel = EgtGetFirstNameInGroup( Ls, SHEETLABEL)
+ local b3Part = EgtGetBBoxGlob( Pz or GDB_ID.NULL, GDB_BB.STANDARD)
+ local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD)
+ -- se pezzo non definito, non devo fare alcunchè
+ if not Pz then
+ DISP.ERR = 0
+ return
+ end
+ -- se pezzo vuoto, non devo fare alcunchè
+ if b3Part:isEmpty() then
+ DISP.ERR = 2
+ return
+ end
+ -- Definizione e posizionamento del grezzo
+ local nRaw
+ if Er then
+ nRaw = EgtAddRawPartWithPart( Pz, Er, 0, ColA)
+ EgtRemovePartFromRawPart(Pz)
+ EgtSetStatus( Er, GDB_ST.ON)
+ else
+ nRaw = EgtAddRawPartWithPart( Pz, GDB_ID.NULL, dOverMat, ColA)
+ EgtRemovePartFromRawPart(Pz)
+ end
+ if not nRaw then
+ EgtOutLog( 'InitDisp for NE_nest : error defining raw part')
+ DISP.ERR = 3
+ return
+ end
+ local b3Raw = EgtGetBBoxGlob(nRaw, GDB_BB.STANDARD)
+ local b3Label = EgtGetBBoxGlob(SheetLabel, GDB_BB.STANDARD)
+ local nRawLabel = EgtCopyGlob(SheetLabel, nRaw)
+ local dYPos = b3Raw:getMax():getY()
+ if b3Raw:getDimY() > 1465 then
+ dYPos = b3Raw:getMin():getY() + 1465 + (b3Label:getDimY())
+ end
+ EgtMove(nRawLabel, Point3d(b3Raw:getMin():getX(), dYPos - b3Label:getDimY(), b3Raw:getMin():getZ()) - b3Label:getMin(), GDB_RT.GLOB)
+ -- se Northwood posiziono a sinistra, altrimenti a destra
+ local nTableRefPoint = MCH_CR.BR
+ if IsOffLine then
+ nTableRefPoint = MCH_CR.BL
+ end
+ if not EgtMoveToCornerRawPart( nRaw, vtOffs, nTableRefPoint) then
+ EgtOutLog( 'InitDisp for NE_nest : error positioning raw part on table')
+-- DISP.ERR = 4
+ return
+ end
+ return nRaw
+end
+--
+
+
+-- funzione che imposta tavola macchina
+function UtilityLib.SetupMachineTable(IsOffline)
+ -- Scelta della tavola
+ local sTab = 'Tab'
+ EgtSetTable( sTab)
+ -- Dimensioni tavola
+ local b3Tab = EgtGetTableArea()
+ -- Richiesta posizione rispetto allo Zero tavola
+ local vtOffs = Vector3d( b3Tab:getDimX(), 0, 0)
+ -- se NorthWood cambio offset
+ if IsOffline then
+ vtOffs = Vector3d(0,0,0)
+ end
+ return vtOffs
+end
+--
+
+local MATERIAL = {"MATERIAL FLAG"}
+local PAINT = {"PAINT FLAG"}
+local ASSEMBLY = {"TO BE ASSEMBLED","AssemblyCell"}
+local TNUT = {"T-NUT FLAG","TNutFlag"}
+local ROUND = {"ROUND EDGE","RoundEdge"}
+local TAB = {"CHOP AT TAB","ChopAtTab"}
+local PDF = {"PDF LINK"}
+local CUTOPT = {"CUT OPT", "CutOpt"}
+local LABEL = {"LABEL", "Label"}
+local NAME = {"NAME", "Name"}
+
+local DXFFlags = {MATERIAL, PAINT, ASSEMBLY, TNUT, ROUND, TAB, PDF, CUTOPT, LABEL, NAME}
+
+-- funzione che legge i dxf
+-- valore di ritorno numero 5 e' ErrorType:
+-- 1) File not found
+-- 2) Material layer not found
+function UtilityLib.readDXF(DXFpath, PartExtCode, IsEstimation)
+ -- elimino doppie barre dalla path
+ DXFpath = string.gsub(DXFpath, "\\", '/')
+ local errorType = 0
+ local material = nil
+ local pdfPath = ""
+ local paint = false
+ local flags = {}
+ local revision = ""
+ -- apro DXF
+ EgtNewFile()
+ EgtOutLog(DXFpath)
+ local res = EgtImportDxf(DXFpath)
+ if not res then
+ errorType = 1
+ EgtOutLog("DXF file not found :" .. DXFpath)
+ return material, pdfPath, paint, flags, errorType
+ end -- GESTIRE ERRORE!!
+ -- trovo pezzo
+ local part = EgtGetFirstInGroup(GDB_ID.ROOT)
+ -- cerco i layer
+ for Flag = 1, #DXFFlags do
+ local flagLayer = EgtGetFirstNameInGroup(part, DXFFlags[Flag][1])
+ if flagLayer then
+ local textObject = EgtGetFirstInGroup(flagLayer)
+ -- leggo il testo
+ local flagText = EgtTextContent(textObject)
+ -- verifico se il flag e' material
+ if DXFFlags[Flag][1] == MATERIAL[1] then
+ -- ritaglio valore
+ local _, _, valueText = string.find(flagText, ".*:%s*(%d+)")
+ material = tonumber(valueText)
+ elseif DXFFlags[Flag][1] == PDF[1] then
+ -- ritaglio valore
+ local _, _, valueText = string.find(flagText, ".*:%s*\"(.+)\"")
+ pdfPath = valueText
+ elseif DXFFlags[Flag][1] == PAINT[1] then
+ -- ritaglio valore
+ local _, _, valueText = string.find(flagText, ".*:%s*(%a+)")
+ local PaintVal = string.lower(valueText)
+ if PaintVal == "yes" then
+ paint = true
+ else
+ paint = false
+ end
+ elseif DXFFlags[Flag][1] == NAME[1] then
+ revision = flagText
+ else
+ -- ritaglio valore
+ local _, _, valueText = string.find(flagText, ".*:%s*(%w+[&]*%w*)")
+ flags[DXFFlags[Flag][2]] = valueText
+ end
+ else
+ if Flag < 8 then
+ errorType = 2
+ EgtOutLog(DXFFlags[Flag][1] .. " layer not found :" .. DXFpath)
+ return material, pdfPath, paint, flags, errorType
+ end
+ end
+ end
+ if IsEstimation and paint then
+ -- verifico se gia' processato
+ local Index = 1
+ local bFound = false
+ while not bFound and Index <= #PNGIdList do
+ if PartExtCode == PNGIdList[Index] then
+ bFound = true
+ end
+ Index = Index + 1
+ end
+ if not bFound then
+ SavePartImage(revision)
+ table.insert(PNGIdList, PartExtCode)
+ end
+ end
+ return material, pdfPath, paint, flags, errorType, revision
+end
+--
+
+-- funzione che salva immagine per etichetta verniciati
+function SavePartImage(PartExtCode)
+ local nPartId = EgtGetFirstInGroup(GDB_ID.ROOT)
+ local nLayerId = EgtGetFirstLayer( nPartId)
+ while nLayerId and nLayerId ~= GDB_ID.NULL do
+ -- nascondo tutti i layer tranne i contorni, i buchi e le rampe
+ local sLayerName = EgtGetName(nLayerId)
+ local bOutlineLayer = false
+ for Index = 1, #Config.OutlineMachining[1] do
+ if sLayerName == Config.OutlineMachining[1][Index] then
+ bOutlineLayer = true
+ end
+ end
+ if bOutlineLayer == true or sLayerName == Config.HoleMachining[1] or sLayerName == Config.RampMachining[1] then
+ -- coloro i contorni di nero
+ local nGeomId = EgtGetFirstInGroup(nLayerId)
+ while nGeomId and nGeomId ~= GDB_ID.NULL do
+ EgtSetColor(nGeomId, BLACK())
+ nGeomId = EgtGetNext(nGeomId)
+ end
+ else
+ -- disattivo tutti gli altri layer
+ EgtSetStatus(nLayerId, GDB_ST.OFF)
+ end
+ nLayerId = EgtGetNextLayer(nLayerId)
+ end
+-- -- calcolo bbox pezzo
+-- local b3PartId = EgtGetBBox(nPartId, GDB_BB.STANDARD + GDB_BB.ONLY_VISIBLE + GDB_BB.IGNORE_TEXT + GDB_BB.IGNORE_DIM)
+-- -- lo sposto
+-- EgtMove(nPartId, Vector3d(- (b3PartId:getDimX() / 2), - (b3PartId:getDimY() / 2), 0))
+ EgtZoom(SCE_ZM.ALL)
+ EgtGetImage( SCE_SM.SH, WHITE(), WHITE(), 1600, 1000, PNGPath .. "/" .. PartExtCode .. ".png")
+-- EgtSaveFile(PNGPath .. "/" .. PartExtCode .. ".nge")
+end
+--
+
+---------------------------------------------------------------------
+return UtilityLib