Files
DataWall/LuaLibs/WallExec.lua
T
Dario Sassi f2a066192f DataWall 2.5i2 :
- corretta impostazione allargamento aree disposizone grezzi su tavola
- in LapJoint con una sola faccia controllo lavorabilità ora come per FreeContour
- in CleanCorner ora AuxDir (SCC) sempre Z+.
2023-09-20 10:12:51 +02:00

765 lines
34 KiB
Lua

-- WallExec.lua by Egaltech s.r.l. 2023/07/04
-- Libreria esecuzione lavorazioni per Pareti
-- 2023/05/25 Aggiunto ordinamento in base a priorità da btl.
-- 2023/06/07 Nel caso di outline con priorità aggiunta la rimozione degli sfridi nella lavorazione successiva.
-- 2023/06/27 Aggiunte origini TN e BN.
-- 2023/07/04 Se c'è funzione di macchina WD.GetOrigCorner si lascia scegliere posizione default a questa impostando 0 se non c'è 'REFPOS'.
-- Tabella per definizione modulo
local WallExec = {}
-- Include
require( 'EgtBase')
-- Carico i dati globali e libero tutti gli altri
_G.package.loaded.WallData = nil
_G.package.loaded.CutData = nil
_G.package.loaded.MillingData = nil
_G.package.loaded.PocketingData = nil
_G.package.loaded.DrillData = nil
_G.package.loaded.SawingData = nil
local WD = require( 'WallData')
if WALL and WALL.NESTINGCORNERBL then WD.NESTING_CORNER = 'BL' end
-- Carico le librerie
_G.package.loaded.WMachiningLib = nil
_G.package.loaded.WallLib = nil
_G.package.loaded.WProcessCut = nil
_G.package.loaded.WProcessDoubleCut = nil
_G.package.loaded.WProcessSawCut = nil
_G.package.loaded.WProcessLapJoint = nil
_G.package.loaded.WProcessDrill = nil
_G.package.loaded.WProcessMortise = nil
_G.package.loaded.WProcessDtMortise = nil
_G.package.loaded.WProcessMark = nil
_G.package.loaded.WProcessText = nil
_G.package.loaded.WProcessFreeContour = nil
_G.package.loaded.WProcessVariant = nil
local WM = require( 'WMachiningLib')
local WL = require( 'WallLib')
local Cut = require( 'WProcessCut')
local DoubleCut = require( 'WProcessDoubleCut')
local SawCut = require( 'WProcessSawCut')
local LapJoint = require( 'WProcessLapJoint')
local Drill = require( 'WProcessDrill')
local Mortise = require( 'WProcessMortise')
local DtMortise = require( 'WProcessDtMortise')
local Mark = require( 'WProcessMark')
local Text = require( 'WProcessText')
local FreeContour = require( 'WProcessFreeContour')
local Variant = require( 'WProcessVariant')
-------------------------------------------------------------------------------------------------------------
-- *** Inserimento delle pareti nel pannello ***
-------------------------------------------------------------------------------------------------------------
function WallExec.ProcessWalls( dRawL, dRawW, dRawH, vWall, bMachGroupOk, bNewProcess, nRawOutlineId)
-- Creazione nuovo gruppo di lavoro
if not bMachGroupOk then
local sMgName = EgtGetMachGroupNewName( 'Mach')
local NewMgId = EgtAddMachGroup( sMgName)
if not NewMgId then
local sOut = 'Errore nella creazione del gruppo di lavoro ' .. sMgName
return false, sOut
end
end
-- Impostazione della tavola
EgtSetTable( 'Tab')
-- Area tavola
local b3Tab = EgtGetTableArea()
-- Calcolo posizione estremo di riferimento della tavola rispetto a sua origine in BL
local OrigOnTab
local nCorner
local sOrigCorner = WD.ORIG_CORNER or 'BR'
if WD.GetOrigCorner then
sOrigCorner = WD.GetOrigCorner( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'REFPOS', 'i') or 0)
end
if sOrigCorner == 'TL' then
nCorner = MCH_CR.TL
OrigOnTab = Point3d( 0 + abs( WD.DELTA_X or 0), b3Tab:getDimY() - abs( WD.DELTA_Y or 0), ( WD.DELTA_Z or 0))
elseif sOrigCorner == 'BL' then
nCorner = MCH_CR.BL
OrigOnTab = Point3d( 0 + abs( WD.DELTA_X or 0), abs( WD.DELTA_Y or 0), ( WD.DELTA_Z or 0))
elseif sOrigCorner == 'TR' then
nCorner = MCH_CR.TR
OrigOnTab = Point3d( b3Tab:getDimX() - abs( WD.DELTA_X or 0), b3Tab:getDimY() - abs( WD.DELTA_Y or 0), ( WD.DELTA_Z or 0))
elseif sOrigCorner == 'BR' then
nCorner = MCH_CR.BR
OrigOnTab = Point3d( b3Tab:getDimX() - abs( WD.DELTA_X or 0), abs( WD.DELTA_Y or 0), ( WD.DELTA_Z or 0))
elseif sOrigCorner == 'TM' then
nCorner = MCH_CR.TR
OrigOnTab = Point3d( WD.MID_REF - abs( WD.DELTA_X or 0), b3Tab:getDimY() - abs( WD.DELTA_Y or 0), ( WD.DELTA_Z or 0))
elseif sOrigCorner == 'BM' then
nCorner = MCH_CR.BR
OrigOnTab = Point3d( WD.MID_REF - abs( WD.DELTA_X or 0), abs( WD.DELTA_Y or 0), ( WD.DELTA_Z or 0))
elseif sOrigCorner == 'TN' then
nCorner = MCH_CR.TL
OrigOnTab = Point3d( WD.NEW_REF + abs( WD.DELTA_X or 0), b3Tab:getDimY() - abs( WD.DELTA_Y or 0), ( WD.DELTA_Z or 0))
elseif sOrigCorner == 'BN' then
nCorner = MCH_CR.BL
OrigOnTab = Point3d( WD.NEW_REF + abs( WD.DELTA_X or 0), abs( WD.DELTA_Y or 0), ( WD.DELTA_Z or 0))
end
-- Impostazione dell'attrezzaggio di default
EgtImportSetup()
-- Impostazione eventuale allargamento area disponibile per grezzo
EgtSetTableAreaOffset( WD.TAB_EXTRA_XP or 0, WD.TAB_EXTRA_YP or 0, WD.TAB_EXTRA_XM or 0, WD.TAB_EXTRA_YM or 0)
-- Creazione del grezzo e suo posizionamento in macchina
local nRaw = GDB_ID.NULL
if nRawOutlineId and nRawOutlineId ~= GDB_ID.NULL then
nRaw = EgtAddRawPartWithPart( 0, nRawOutlineId, 0, WD.RAWCOL)
else
nRaw = EgtAddRawPart( Point3d( 0, 0, 0), dRawL, dRawW, dRawH, WD.RAWCOL)
end
EgtMoveToCornerRawPart( nRaw, OrigOnTab, nCorner)
EgtSetInfo( nRaw, 'ORD', 1)
-- Inserimento dei pezzi nel grezzo
for i = 1, #vWall do
-- assegno identificativo pezzo
local Pz = vWall[i].Id
-- dati del pezzo
local b3Part = EgtGetBBoxGlob( Pz or GDB_ID.NULL, GDB_BB.EXACT)
local b3Solid = vWall[i].Box
if b3Part:isEmpty() or b3Solid:isEmpty() then break end
local PartLen = b3Solid:getDimX()
local PartWidth = b3Solid:getDimY()
local PartHeight = b3Solid:getDimZ()
local vtOffs = b3Part:getMin() - b3Solid:getMin()
-- creo o pulisco gruppo geometrie aggiuntive
if not WL.CreateOrEmptyAddGroup( Pz) then
local sOut = 'Error creating Additional Group in Part ' .. tostring( Pz)
return false, sOut
end
-- inserisco il pezzo nel grezzo
EgtDeselectPartObjs( Pz)
local ptPos
if bNewProcess then
local sNestingRef = ( WALL.NESTING_REF or WD.NESTING_CORNER)
if sNestingRef == 'TL' then
ptPos = Point3d( vWall[i].PosX, dRawW - PartWidth - vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs
elseif sNestingRef == 'TR' then
ptPos = Point3d( dRawL - PartLen - vWall[i].PosX, dRawW - PartWidth - vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs
elseif sNestingRef == 'BR' then
ptPos = Point3d( dRawL - PartLen - vWall[i].PosX, vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs
else -- 'BL'
ptPos = Point3d( vWall[i].PosX, vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs
end
else
local dPosH = EgtIf( vWall[i].PosY < 0.1, ( dRawH - PartHeight) / 2, vWall[i].PosY)
ptPos = Point3d( dRawL - vWall[i].PosX - PartLen, vWall[i].PosZ, dPosH) + vtOffs
end
EgtAddPartToRawPart( Pz, ptPos, nRaw)
end
return true
end
-------------------------------------------------------------------------------------------------------------
-- *** Inserimento delle lavorazioni nelle pareti ***
-------------------------------------------------------------------------------------------------------------
function WallExec.CollectFeatures( PartId, b3Raw)
-- recupero le feature
local vProc = {}
local LayerId = {}
LayerId[1] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Outline')
LayerId[2] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Processings')
for nInd = 1, #LayerId do
local ProcId = EgtGetFirstInGroup( LayerId[nInd] or GDB_ID.NULL)
while ProcId do
local nEntType = EgtGetType( ProcId)
if nEntType == GDB_TY.SRF_MESH or nEntType == GDB_TY.EXT_TEXT or
nEntType == GDB_TY.CRV_LINE or nEntType == GDB_TY.CRV_ARC or nEntType == GDB_TY.CRV_BEZ or nEntType == GDB_TY.CRV_COMPO then
local nGrp = EgtGetInfo( ProcId, 'GRP', 'i')
local nPrc = EgtGetInfo( ProcId, 'PRC', 'i')
local nDo = EgtGetInfo( ProcId, 'DO', 'i') or 1
local nCutId = EgtGetInfo( EgtGetParent( EgtGetParent( ProcId)), 'CUTID', 'i') or 0
local nTaskId = EgtGetInfo( ProcId, 'TASKID', 'i') or 0
if nGrp and nPrc and nDo == 1 then
local Proc = {}
Proc.PartId = PartId
Proc.Id = ProcId
Proc.Grp = nGrp
Proc.Prc = nPrc
Proc.Flg = 1
Proc.Fct = EgtSurfTmFacetCount( ProcId) or 0
Proc.Diam = 0
Proc.Fcs = 0
Proc.Fce = 0
Proc.CutId = nCutId
Proc.TaskId = nTaskId
Proc.Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD)
Proc.IsOutline = ( Proc.Prc == 251 or Proc.Prc == 252)
if Proc.Box and not Proc.Box:isEmpty() then
table.insert( vProc, Proc)
-- se foro
if Drill.Identify( Proc) then
-- assegno diametro e facce di ingresso e uscita (dati tabelle sempre per riferimento)
Proc.Diam, Proc.Fcs, Proc.Fce = Drill.GetData( Proc, b3Raw)
-- verifico se necessaria seconda lavorazione da parte opposta per foro più lungo della punta
if Drill.Split( Proc, b3Raw) then
-- aggiorno flags prima parte foro (dati tabelle sempre per riferimento)
Proc.Flg = 2
-- definisco dati seconda parte
local Proc2 = {}
Proc2.PartId = PartId
Proc2.Id = ProcId
Proc2.Grp = nGrp
Proc2.Prc = nPrc
Proc2.Flg = -2
Proc2.Box = BBox3d( Proc.Box)
Proc2.Fct = Proc.Fct
Proc2.Diam = Proc.Diam
Proc2.Fcs = Proc.Fce
Proc2.Fce = Proc.Fcs
Proc2.CutId = Proc.CutId
Proc2.TaskId = Proc.TaskId
table.insert( vProc, Proc2)
end
end
else
EgtOutLog( ' Feature ' .. tostring( Proc.Id) .. ' is empty (no geometry)')
end
end
end
ProcId = EgtGetNext( ProcId)
end
end
return vProc
end
-------------------------------------------------------------------------------------------------------------
local function ClassifyFeatures( vProc, b3Raw)
for i = 1, #vProc do
local Proc = vProc[i]
-- se taglio
if Cut.Identify( Proc) then
local bOk = Cut.Classify( Proc, b3Raw)
if not bOk then Proc.Flg = 0 end
-- se taglio doppio
elseif DoubleCut.Identify( Proc) then
local bOk = DoubleCut.Classify( Proc, b3Raw)
if not bOk then Proc.Flg = 0 end
-- se taglio con lama
elseif SawCut.Identify( Proc) then
local bOk = SawCut.Classify( Proc, b3Raw)
if not bOk then Proc.Flg = 0 end
-- se tasca
elseif LapJoint.Identify( Proc) then
local bOk = LapJoint.Classify( Proc, b3Raw)
if not bOk then Proc.Flg = 0 end
-- se foratura
elseif Drill.Identify( Proc) then
local bOk = Drill.Classify( Proc, b3Raw)
if not bOk then Proc.Flg = 0 end
-- se mortasatura
elseif Mortise.Identify( Proc) then
local bOk = Mortise.Classify( Proc, b3Raw)
if not bOk then Proc.Flg = 0 end
-- se mortasatura a coda di rondine
elseif DtMortise.Identify( Proc) then
local bOk = DtMortise.Classify( Proc, b3Raw)
if not bOk then Proc.Flg = 0 end
-- se marcatura
elseif Mark.Identify( Proc) then
local bOk = Mark.Classify( Proc, b3Raw)
if not bOk then Proc.Flg = 0 end
-- se testo
elseif Text.Identify( Proc) then
local bOk = Text.Classify( Proc, b3Raw)
if not bOk then Proc.Flg = 0 end
-- se contorno libero, outile o aperture
elseif FreeContour.Identify( Proc) then
local bOk = FreeContour.Classify( Proc, b3Raw)
if not bOk then Proc.Flg = 0 end
-- se feature custom (Variant)
elseif Variant.Identify( Proc) then
local bOk = Variant.Classify( Proc, b3Raw)
if not bOk then Proc.Flg = 0 end
end
end
end
-------------------------------------------------------------------------------------------------------------
local function PrintFeatures( vProc)
EgtOutLog( ' *** Feature List ***')
for i = 1, #vProc do
local Proc = vProc[i]
local sOut = string.format( 'Part=%3d Proc=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Fcse=%1d,%1d Diam=%.2f Fct=%2d Dbl=%2d Dlt=%.1f Box=%s',
Proc.PartId, Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId,
Proc.Flg, Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, Proc.Double or 0, Proc.Delta or 0, tostring( Proc.Box))
EgtOutLog( sOut)
end
end
-------------------------------------------------------------------------------------------------------------
local function AddFeatureMachining( Proc, nRawId, b3Raw)
local bOk = true
local sErr = ''
EgtOutLog( ' * Process ' .. tostring( Proc.Id) .. ' *', 1)
-- se taglio (1/2-010-X) o taglio longitudinale (0/3/4-010-X)
if Cut.Identify( Proc) then
-- esecuzione taglio
bOk, sErr = Cut.Make( Proc, nRawId, b3Raw)
-- se taglio doppio (1/2-011-X) o taglio doppio longitudinale (0-012-X)
elseif DoubleCut.Identify( Proc) then
-- esecuzione taglio
bOk, sErr = DoubleCut.Make( Proc, nRawId, b3Raw)
-- se taglio con lama (0/3/4-013-X)
elseif SawCut.Identify( Proc) then
-- esecuzione taglio
bOk, sErr = SawCut.Make( Proc, nRawId, b3Raw)
-- se tasca (3/4-030-X) o similari
elseif LapJoint.Identify( Proc) then
-- esecuzione tasca
bOk, sErr = LapJoint.Make( Proc, nRawId, b3Raw)
-- se foratura ( 3/4-040-X)
elseif Drill.Identify( Proc) then
-- esecuzione foratura
bOk, sErr = Drill.Make( Proc, nRawId, b3Raw)
-- se mortasatura (3/4-050-X) o similari
elseif Mortise.Identify( Proc) then
-- esecuzione mortasatura
bOk, sErr = Mortise.Make( Proc, nRawId, b3Raw)
-- se mortasatura a coda di rondine (3/4-055-X)
elseif DtMortise.Identify( Proc) then
-- esecuzione mortasatura a coda di rondine
bOk, sErr = DtMortise.Make( Proc, nRawId, b3Raw)
-- se marcatura (3/4-060-X)
elseif Mark.Identify( Proc) then
-- esecuzione marcatura
bOk, sErr = Mark.Make( Proc, nRawId, b3Raw)
-- se testo (4-061-X)
elseif Text.Identify( Proc) then
-- esecuzione incisione testo
bOk, sErr = Text.Make( Proc, nRawId, b3Raw)
-- se contorno libero, outline o apertura ( 0/3/4-250/251/252-X)
elseif FreeContour.Identify( Proc) then
-- esecuzione contorno
bOk, sErr = FreeContour.Make( Proc, nRawId, b3Raw)
-- se feature custom (Variant)
elseif Variant.Identify( Proc) then
-- esecuzione
bOk, sErr = Variant.Make( Proc, nRawId, b3Raw)
-- altrimenti feature non riconosciuta
else
bOk = false
sErr = 'Feature type non recognized for machining'
end
return bOk, sErr
end
-------------------------------------------------------------------------------------------------------------
local function MoveMachiningsAtEnd( nPhase, nType, sStartName, sProperty)
local nOperId = EgtGetPhaseDisposition( nPhase)
local nLastId = EgtGetLastOperation()
local nInsertId = nLastId
while nOperId do
local nNextOperId = EgtGetNextOperation( nOperId)
if EgtGetOperationPhase( nOperId) == nPhase and EgtGetOperationType( nOperId) == nType and
( ( EgtGetInfo( nOperId, 'MOVE_AFTER', 'i') == 1 ) or
( not sStartName or string.sub( EgtGetName( nOperId), 1, #sStartName) == sStartName)) then
EgtRelocateGlob( nOperId, nInsertId, GDB_IN.AFTER)
nInsertId = nOperId
end
if nOperId == nLastId then
break
end
nOperId = nNextOperId
end
end
------ Ordinamento dei tagli, delle fresature e delle forature -------
local function SpSorting( TabCut, PrevMch, nType, bOneWay)
-- ordino le lavorazioni (in gruppi di max 1000 entità se 32bit 10000 se 64bit)
--EgtOutLog('Dati per ShortestPath :')
local SP_MAX_ENT = EgtIf( EgtIs64bit(), 10000, 1000)
local nBase = 0
while nBase < #TabCut do
-- calcolo ordinamento
EgtSpInit()
for i = 1, min( #TabCut - nBase, SP_MAX_ENT) do
local ptS = TabCut[nBase+i].Start
local ptE = TabCut[nBase+i].End
EgtSpAddPoint( ptS:getX(), ptS:getY(), ptS:getZ(), 0, 0,
ptE:getX(), ptE:getY(), ptE:getZ(), 0, 0)
end
EgtSpSetAngularParams( 1000, 40, 2000, 60)
EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, 50000, 0, 0, 0, 0)
if WD.BEAM_MACHINE and (nType & MCH_OY.SAWING) == MCH_OY.SAWING then
EgtSpSetOpenBound( false, SHP_OB.NEAR_PNT, -50000, 0, 0, 0, 0)
end
EgtSpSetZzOwStep( 10)
local nType = EgtIf( bOneWay, SHP_TY.ONEWAY_YM, SHP_TY.OPEN)
local vOrd = EgtSpCalculate( nType)
EgtSpTerminate()
-- applico ordinamento calcolato
if vOrd then
for i = 1, #vOrd do
EgtRelocateGlob( TabCut[nBase+vOrd[i]].Mch, PrevMch, GDB_IN.AFTER)
PrevMch = TabCut[nBase+vOrd[i]].Mch
end
end
-- incremento la base
nBase = nBase + SP_MAX_ENT
end
return PrevMch
end
local function ContainsStartName( nOperId, StartNames)
local bFound = false
for i = 1, #StartNames do
local sStartName = StartNames[i]
if string.sub( EgtGetName( nOperId), 1, #sStartName) == sStartName then
bFound = true
end
end
return bFound
end
------ Ordinamento dei tagli, delle fresature e delle forature -------
local function SortMach( nPhase, PrevMch, nPartId, nType, StartNames, bExistName, sInfo, bExistInfo, bOneWay, bByTool, bByToolAngle, nPriority)
-- dichiarazione tabella
local TabCut = {}
-- Recupero gli identificativi delle lavorazioni e annullo eventuali allungamenti e Id di altre lavorazioni rappresentate
local nOperId = EgtGetNextOperation( PrevMch)
while nOperId do
local nOperType = EgtGetOperationType( nOperId)
-- Se appartiene alla fase corrente e taglio con lama non da sopra (sempre su 1 sola entità)
if EgtGetOperationPhase( nOperId) == nPhase and ( nType & nOperType) == nOperType and
( not nPartId or EgtGetInfo( nOperId, 'Part', 'i') == nPartId) and
( not nPriority or EgtGetInfo( nOperId, 'PRIORITY', 'i') == nPriority ) and
( not StartNames or ( bExistName and ContainsStartName( nOperId, StartNames)) or
( not bExistName and not ContainsStartName( nOperId, StartNames))) and
( not sInfo or ( bExistInfo and EgtGetInfo( nOperId, sInfo, 'i') == 1) or
( not bExistInfo and EgtGetInfo( nOperId, sInfo, 'i') ~= 1)) then
-- non si deve cambiare lo stato di attivazione della lavorazione (se disabilitata errata)
EgtSetCurrMachining( nOperId)
if not EgtIsMachiningEmpty() then
-- punto iniziale e finale e direzione della lavorazione
local ptStart = EgtGetMachiningStartPoint()
local ptEnd = EgtGetMachiningEndPoint()
local sTUUID = ''
local nToolType = 0
local nToolDiam = 0
local nToolDir = 0
if bByTool then
sTUUID = EgtGetMachiningParam( MCH_MP.TUUID)
local sToolName = EgtTdbGetToolFromUUID( sTUUID)
if EgtTdbSetCurrTool( sToolName) then
nToolType = EgtTdbGetCurrToolParam( MCH_TP.TYPE)
nToolDiam = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM)
else
sTUUID = ''
end
end
if bByToolAngle then
local nClId = EgtGetFirstNameInGroup( nOperId, 'CL')
local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL)
local vtTool = EgtGetInfo( nPathId, 'EXTR', 'v')
nToolDir = EgtIf( vtTool:getZ() > 0.999999, 1, 0)
end
table.insert( TabCut, {Mch=nOperId, Ent=nEntId, Start=ptStart, End=ptEnd, Tool=sTUUID, ToolType=nToolType, ToolDiam=nToolDiam, ToolDir=nToolDir})
end
end
-- Passo alla operazione successiva
nOperId = EgtGetNextOperation( nOperId)
end
if bByTool then
function ToolCompare(a,b)
if a.ToolType < b.ToolType then
return true
elseif a.ToolType == b.ToolType then
if a.ToolDiam > b.ToolDiam then
return true
elseif a.ToolDiam == b.ToolDiam then
if a.Tool < b.Tool then
return true
elseif a.Tool == b.Tool then
if bByToolAngle then
if a.ToolDir > b.ToolDir then
return true
elseif a.ToolDir == b.ToolDir then
return a.Mch < b.Mch
end
else
return a.Mch < b.Mch
end
end
end
end
return false
end
-- test della funzione di ordinamento
if EgtGetDebugLevel() >= 3 then
EgtOutLog( ' CompareFeatures Test ')
local bCompTest = true
for i = 1, #TabCut do
for j = i + 1, #TabCut do
local bComp1 = ToolCompare( TabCut[i], TabCut[j])
local bComp2 = ToolCompare( TabCut[j], TabCut[i])
if bComp1 == bComp2 then
bCompTest = false
EgtOutLog( string.format( ' ProcId : %d vs %d --> ERROR', TabCut[i].Mch, TabCut[j].Mch))
end
end
end
if bCompTest then
EgtOutLog( ' ALL OK')
end
end
table.sort(TabCut, ToolCompare)
-- table.sort(TabCut, function(a,b) return a.ToolType < b.ToolType and a.ToolDiam > b.ToolDiam and a.Tool < b.Tool end)
local SupportTabCut = {}
local nPrevTUUID = 0
local nPrevTDirZ = 1
for i = 1, #TabCut do
-- se tuuid uguale al precedente, lo aggiungo alla lista
if nPrevTUUID == TabCut[i].Tool and ( not bByToolAngle or nPrevTDirZ == TabCut[i].ToolDir) then
table.insert( SupportTabCut, TabCut[i])
-- se tuuid diverso,
else
-- faccio calcolare la lista
PrevMch = SpSorting( SupportTabCut, PrevMch, nType, bOneWay)
-- cancello la lista e aggiorno tuuid corrente
SupportTabCut = {}
nPrevTUUID = TabCut[i].Tool
if bByToolAngle then
nPrevTDirZ = TabCut[i].ToolDir
end
table.insert( SupportTabCut, TabCut[i])
end
end
-- calcolo ultima lista
if #SupportTabCut > 0 then
PrevMch = SpSorting( SupportTabCut, PrevMch, nType, bOneWay)
end
else
PrevMch = SpSorting( TabCut, PrevMch, nType, bOneWay)
end
return PrevMch
end
-------------------------------------------------------------------------------------------------------------
local function SortMachinings( nPhase, PrevMch, nPartId, nPriority)
-- Chiodature
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Nail_'}, true, nil, nil, nil, true, nil, nPriority)
-- Tagli con sega a catena che sono rifiniture di spigoli
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MORTISING, { 'Csaw_'}, false, nil, nil, nil, nil, nil, nPriority)
-- Forature orizzontali con punte lunghe
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.DRILLING, { 'LhDrill_'}, true, 'MOVE_AFTER', false, true, nil, nil, nPriority)
-- Preforature per fori inclinati
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.POCKETING, { 'PreDrill_'}, true, nil, nil, nil, nil, nil, nPriority)
-- Forature e Svuotature
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.DRILLING + MCH_OY.POCKETING + MCH_OY.MILLING, { 'SideMill_', 'Clean_'}, false, 'MOVE_AFTER', false, false, true, nil, nPriority)
-- -- Forature ***
-- PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.DRILLING, nil, nil, 'MOVE_AFTER', false)
-- -- Svuotature ***
-- PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.POCKETING, nil, nil, 'MOVE_AFTER', false)
-- -- Fresature che sono rifiniture di spigoli
-- PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Clean_'}, false, 'MOVE_AFTER', false, false, true)
-- Lavorazioni di superficie
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_MY.SURFFINISHING, nil, nil, 'MOVE_AFTER', false, nil, nil, nil, nPriority)
-- Fresature per gole
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Gorge_'}, true, 'MOVE_AFTER', false, nil, nil, nil, nPriority)
-- Fresature che sono rifiniture di spigoli
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'SideMill_'}, true, 'MOVE_AFTER', false, false, true, true, nPriority)
-- Fresature che sono puliture di spigoli
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Clean_'}, true, 'MOVE_AFTER', false, false, true, nil, nPriority)
-- Tagli per gole
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.SAWING, { 'GorgeCut_'}, true, nil, nil, nil, nil, nil, nPriority)
-- Tagli con lama
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.SAWING, nil, nil, nil, nil, nil, nil, nil, nPriority)
-- Qui rimozione sfridi (se ci sono lavorazioni successive)
if not nPriority then
-- Fresature dei lapjoint che necessitano di gorge
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'SideMill_'}, true, 'MOVE_AFTER', true, false, true, true)
-- Tagli con sega a catena che vanno fatti dopo i tagli con lama
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MORTISING, { 'Csaw_'}, true)
-- Fresature (puliture di spigoli) che vanno fatte dopo i tagli con lama
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, nil, nil, 'MOVE_AFTER', true)
-- Forature che vanno fatte dopo i tagli con lama
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.DRILLING, nil, nil, 'MOVE_AFTER', true)
-- Svuotature che vanno fatte dopo i tagli con lama
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.POCKETING, nil, nil, 'MOVE_AFTER', true)
-- Lavorazioni di superficie che vanno fatte dopo i tagli con lama
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_MY.SURFFINISHING, nil, nil, 'MOVE_AFTER', true)
end
return PrevMch
end
-------------------------------------------------------------------------------------------------------------
-- setto la rimozione sfridi dopo le lavorazioni di outline
function InsertScrapRemoval( nPhase)
local nCurrentOperationId = EgtGetNextOperation( EgtGetPhaseDisposition( nPhase))
local nActiveMachiningId = EgtGetCurrMachining()
while nCurrentOperationId do
local bIsCurrentOperationOutline = ( EgtGetInfo( nCurrentOperationId or GDB_ID.NULL, 'ISOUTLINE', 'b' ) == true)
local bIsCurrentOperationWithPriority = ( ( EgtGetInfo( nCurrentOperationId or GDB_ID.NULL, 'PRIORITY', 'i' ) or 0) > 0)
local nNextOperationId = EgtGetNextOperation (nCurrentOperationId)
local bIsNextOperationOutline = ( EgtGetInfo( nNextOperationId or GDB_ID.NULL, 'ISOUTLINE', 'b' ) == true)
if bIsCurrentOperationOutline and bIsCurrentOperationWithPriority and nNextOperationId and not bIsNextOperationOutline then
EgtSetCurrMachining( nNextOperationId)
local sMachiningNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
sMachiningNotes = sMachiningNotes .. 'ScrapRemove=1;'
EgtSetMachiningParam( MCH_MP.USERNOTES, sMachiningNotes)
end
nCurrentOperationId = EgtGetNextOperation( nCurrentOperationId)
end
EgtSetCurrMachining( nActiveMachiningId or GDB_ID.NULL)
end
-------------------------------------------------------------------------------------------------------------
function WallExec.ProcessFeatures()
-- errori e stato
local nTotErr = 0
local Stats = {}
-- recupero il grezzo e il suo box
local nRawId = EgtGetFirstRawPart()
local b3Raw = EgtGetRawPartBBox( nRawId)
-- raccolgo l'elenco dei pezzi
local vPart = {}
local nPartId = EgtGetFirstPartInRawPart( nRawId)
while nPartId do
local Ls = EgtGetFirstNameInGroup( nPartId, 'Box')
local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD)
table.insert( vPart, {Id=nPartId, Box=b3Solid})
nPartId = EgtGetNextPartInRawPart( nPartId)
end
-- raccolgo l'elenco delle feature da lavorare, ciclando sui pezzi
local vProc = {}
for i = 1, #vPart do
-- recupero le feature di lavorazione della parete
local vPartProc = WallExec.CollectFeatures( vPart[i].Id, b3Raw)
vProc = EgtJoinTables( vProc, vPartProc)
end
-- classifico le feature
ClassifyFeatures( vProc, b3Raw)
-- Eventuale determinazione delle feature lavorabili in parallelo (implementata nella configurazione macchina)
-- si impostano i flag Double (nil/0=no, 1=su X, 2=su Y) e Delta (offset tra T14 e T12 positivo o negativo)
if WD.FindFeaturesInDouble then
WD.FindFeaturesInDouble( vProc, b3Raw)
end
-- debug
if EgtGetDebugLevel() >= 1 then
PrintFeatures( vProc)
end
EgtOutLog( ' *** AddMachinings ***', 1)
-- inserisco le lavorazioni
for i = 1, #vProc do
-- creo la lavorazione
local Proc = vProc[i]
if Proc.Flg ~= 0 then
local bOk, sMsg = AddFeatureMachining( Proc, nRawId, b3Raw)
if not bOk then
nTotErr = nTotErr + 1
table.insert( Stats, {Err=1, Msg=sMsg, Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId})
elseif sMsg and #sMsg > 0 then
table.insert( Stats, {Err=-1, Msg=sMsg, Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId})
else
table.insert( Stats, {Err=0, Msg='', Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId})
end
elseif not Proc.Double then
local sMsg = 'Feature not machinable by orientation'
table.insert( Stats, {Err=1, Msg=sMsg, Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId})
end
end
EgtOutLog( ' *** End AddMachinings ***', 1)
-- se macchina pareti
if not WD.BEAM_MACHINE then
-- riordino le lavorazioni tra tutti i pezzi
local nPhase = 1
local PrevMch = EgtGetPhaseDisposition( nPhase)
-- abilitazione ordinamento con priorità da btl: 0 = no, 1 = ordine crescente, 2 = ordine decrescente
-- le lavorazioni con priorità 0 o senza priorità saranno lasciate per ultime
local nGetPriorityFromBtl = WD.BTL_PRIORITY or 0
if nGetPriorityFromBtl > 0 then
local vPriority = {}
local nOperId = EgtGetNextOperation( PrevMch)
local nCurrentPriorityId = 1
while nOperId do
local nPriority = EgtGetInfo( nOperId or GDB_ID.NULL, 'PRIORITY', 'i')
if nPriority and nPriority ~= 0 then
vPriority[nCurrentPriorityId] = nPriority
nCurrentPriorityId = nCurrentPriorityId + 1
end
nOperId = EgtGetNextOperation( nOperId)
end
-- sorting delle priorità
-- ordine crescente
if nGetPriorityFromBtl == 1 then
table.sort( vPriority)
-- ordine decrescente
else
table.sort( vPriority, function( a, b) return a > b end)
end
-- riordino le lavorazioni per priorità
for i = 1, #vPriority do
if i == 1 or ( vPriority[i] ~= vPriority[i - 1]) then
PrevMch = SortMachinings( nPhase, PrevMch, nil, vPriority[i])
end
end
end
-- ordinamento standard
SortMachinings( nPhase, PrevMch)
-- Aggiornamento finale di tutto
if nGetPriorityFromBtl > 0 then
InsertScrapRemoval( nPhase)
end
EgtSetCurrPhase( 1)
EgtApplyAllMachinings()
-- altrimenti macchina travi
else
-- dichiaro lavorazione pareti
EgtSetInfo( EgtGetCurrMachGroup() or GDB_ID.NULL, 'Wall', '1')
-- ordino i pezzi secondo le X decrescenti
local function CompareParts( P1, P2)
return P1.Box:getCenter():getX() > P2.Box:getCenter():getX()
end
table.sort( vPart, CompareParts)
-- riordino le lavorazioni sui singoli pezzi
local nPhase = 1
local PrevMch = EgtGetPhaseDisposition( nPhase)
for i = 1, #vPart do
PrevMch = SortMachinings( nPhase, PrevMch, vPart[i].Id)
end
-- aggiungo dati su prima disposizione
local nDispId = EgtGetPhaseDisposition( 1)
EgtSetInfo( nDispId, 'TYPE', 'START')
EgtSetInfo( nDispId, 'ORD', 1)
-- aggiungo flag su ultima lavorazione
local nLastMchId = EgtGetLastActiveOperation()
EgtSetCurrMachining( nLastMchId)
EgtSetMachiningParam( MCH_MP.USERNOTES, 'Cut;')
-- aggiungo disposizione per lo scarico
EgtAddPhase()
local nRawId = EgtGetFirstRawPart()
EgtKeepRawPart( nRawId, 1)
local nDisp2Id = EgtGetPhaseDisposition( 2)
EgtSetInfo( nDisp2Id, 'TYPE', 'END')
EgtSetInfo( nDisp2Id, 'ORD', 1)
-- Aggiornamento finale di tutto
EgtSetCurrPhase( 1)
local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings()
if not bApplOk then
nTotErr = nTotErr + 1
table.insert( Stats, {Err = 1, Msg=sApplErrors, Rot=0, CutId=0, TaskId=0})
elseif sApplWarns and #sApplWarns > 0 then
-- non interessano perchè riguardano lo scarico delle travi
end
end
-- restituzione risultati
return ( nTotErr == 0), Stats
end
-------------------------------------------------------------------------------------------------------------
return WallExec