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