1277 lines
63 KiB
Lua
1277 lines
63 KiB
Lua
-- WallExec.lua by Egaltech s.r.l. 2024/02/20
|
|
-- 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'.
|
|
-- 2023/10/16 Aggiunta gestione Aree vietate (LockOut) per chiodature.
|
|
-- 2023/11/14 Modifiche sostanziali per l'aggiunta delle lavorazioni in doppio.
|
|
-- In Collect aggiunto il recupero preliminare di varie informazioni sulla feature.
|
|
-- 2023/12/11 In ClassifyTopology si passa ora anche l'Id del grezzo (allineamento Topology con Beam).
|
|
-- 2024/02/20 Aggiunta gestione DeltaX/Y/Z del pannello dall'origine da BTL.
|
|
|
|
-- 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.WFeatureTopology = 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 Topology = require( 'WFeatureTopology')
|
|
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'
|
|
local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL
|
|
if WD.GetOrigCorner then
|
|
sOrigCorner = WD.GetOrigCorner( EgtGetInfo( BtlInfoId, 'REFPOS', 'i') or 0)
|
|
end
|
|
-- offset da interfaccia
|
|
local dDeltaXFromBtl = EgtGetInfo( BtlInfoId, 'PANELDELTAY', 'd') or 0
|
|
local dDeltaYFromBtl = EgtGetInfo( BtlInfoId, 'PANELDELTAX', 'd') or 0
|
|
local dDeltaZFromBtl = EgtGetInfo( BtlInfoId, 'PANELDELTAZ', 'd') or 0
|
|
-- se da interfaccia arriva un valore > 0 si usa quello, altrimenti si legge da WallData (default 0)
|
|
local DeltaX = EgtIf( dDeltaXFromBtl > 0, dDeltaXFromBtl, WD.DELTA_X or 0)
|
|
local DeltaY = EgtIf( dDeltaYFromBtl > 0, dDeltaYFromBtl, WD.DELTA_Y or 0)
|
|
local DeltaZ = EgtIf( dDeltaZFromBtl > 0, dDeltaZFromBtl, WD.DELTA_Z or 0)
|
|
|
|
if sOrigCorner == 'TL' then
|
|
nCorner = MCH_CR.TL
|
|
OrigOnTab = Point3d( 0 + abs( DeltaX), b3Tab:getDimY() - abs( DeltaY), DeltaZ)
|
|
elseif sOrigCorner == 'BL' then
|
|
nCorner = MCH_CR.BL
|
|
OrigOnTab = Point3d( 0 + abs( DeltaX), abs( DeltaY), DeltaZ)
|
|
elseif sOrigCorner == 'TR' then
|
|
nCorner = MCH_CR.TR
|
|
OrigOnTab = Point3d( b3Tab:getDimX() - abs( DeltaX), b3Tab:getDimY() - abs( DeltaY), DeltaZ)
|
|
elseif sOrigCorner == 'BR' then
|
|
nCorner = MCH_CR.BR
|
|
OrigOnTab = Point3d( b3Tab:getDimX() - abs( DeltaX), abs( DeltaY), DeltaZ)
|
|
elseif sOrigCorner == 'TM' then
|
|
nCorner = MCH_CR.TR
|
|
OrigOnTab = Point3d( WD.MID_REF - abs( DeltaX), b3Tab:getDimY() - abs( DeltaY), DeltaZ)
|
|
elseif sOrigCorner == 'BM' then
|
|
nCorner = MCH_CR.BR
|
|
OrigOnTab = Point3d( WD.MID_REF - abs( DeltaX), abs( DeltaY), DeltaZ)
|
|
elseif sOrigCorner == 'TN' then
|
|
nCorner = MCH_CR.TL
|
|
OrigOnTab = Point3d( WD.NEW_REF + abs( DeltaX), b3Tab:getDimY() - abs( DeltaY), DeltaZ)
|
|
elseif sOrigCorner == 'BN' then
|
|
nCorner = MCH_CR.BL
|
|
OrigOnTab = Point3d( WD.NEW_REF + abs( DeltaX), abs( DeltaY), DeltaZ)
|
|
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 b3Raw then
|
|
-- recupero l'elenco delle facce della parte interessate dalla feature
|
|
Proc.AffectedFaces = WL.GetProcessAffectedFaces( Proc)
|
|
-- recupero le distanze tra la feature e le altre parti più vicine
|
|
Proc.DistanceToNearestParts = WL.GetProcessDistanceToNearestParts( Proc)
|
|
-- recupero le distanze tra la feature e il grezzo
|
|
Proc.DistanceToRawPart = WL.GetProcessDistanceToRawPart( Proc, b3Raw)
|
|
-- recupero informazioni sulle facce della feature
|
|
Proc.Face = {}
|
|
for i = 1, Proc.Fct do
|
|
Proc.Face[i] = { Id = i - 1, VtN = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT ), Elevation = WL.GetFaceElevation( Proc.Id, i - 1, PartId)}
|
|
end
|
|
end
|
|
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
|
|
-- se free contour
|
|
elseif FreeContour.Identify( Proc) then
|
|
-- recupero il tipo e il dato della lavorazione
|
|
local nCntType = EgtGetInfo( Proc.Id, 'CNT_TYPE', 'i') or 0
|
|
local nCntData = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i') or 0
|
|
-- imposto se area vietata
|
|
if nCntType == 200 then
|
|
Proc.LockOut = EgtIf( ( nCntData == 0 or ( nCntData & 1) ~= 0), 1, -1)
|
|
end
|
|
if Proc.LockOut then Proc.Flg = 0 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 ClassifyTopology( vProc, nRawId)
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
local nRecognized = 0
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
if Topology.Classify( Proc, b3Raw) then
|
|
nRecognized = nRecognized + 1
|
|
end
|
|
end
|
|
|
|
return nRecognized
|
|
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 Lo=%d Fcse=%1d,%1d Diam=%.2f Fct=%2d Dbl=%2d Dlt=%.1f Box=%s TopoName=%s',
|
|
Proc.PartId, Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId,
|
|
Proc.Flg, EgtIf( Proc.LockOut, 1, 0), Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, Proc.Double or 0, Proc.Delta or 0, tostring( Proc.Box), Proc.TopologyLongName or '')
|
|
EgtOutLog( sOut)
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function AddFeatureMachining( Proc, nRawId, b3Raw, vNLO)
|
|
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 libero
|
|
bOk, sErr = FreeContour.Make( Proc, nRawId, b3Raw, vNLO)
|
|
-- 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 da fare prima delle SideMill
|
|
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'PreSideMill_'}, true, 'MOVE_AFTER', false, false, true, true, 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 da fare prima delle SideMill
|
|
PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'PreSideMill_'}, true, 'MOVE_AFTER', true, false, true, true)
|
|
-- 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
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- funzione per l'ordinamento delle features in doppio da accoppiare
|
|
-- ordinate prima in base alla X e poi alla Y
|
|
local function SortFeaturesForMirror( Proc1, Proc2)
|
|
-- tolleranza di ricerca
|
|
local TOL = EgtIf( Proc1.TopologyLongName == 'DRILLING', WD.DOUBLE_HEAD_DRILLING_TOLERANCE or 0.1 , WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5)
|
|
-- recupero i centri dei box lungo X e Y
|
|
local Proc1X = Proc1.Box:getCenter():getX()
|
|
local Proc1Y = Proc1.Box:getCenter():getY()
|
|
local Proc2X = Proc2.Box:getCenter():getX()
|
|
local Proc2Y = Proc2.Box:getCenter():getY()
|
|
-- confronto per ordinamento
|
|
if Proc1X < Proc2X - TOL then
|
|
return true
|
|
elseif abs( Proc1X - Proc2X) < TOL then
|
|
if Proc1Y < Proc2Y - TOL then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- funzione per l'ordinamento delle operazioni in doppio da accoppiare
|
|
-- ordinate prima in base alla X e poi alla Y
|
|
local function SortOperationsForMirror( nOper1, nOper2)
|
|
-- tolleranza di ricerca
|
|
local TOL = 0.1
|
|
-- recupero il box della prima operazione
|
|
local nClId1 = EgtGetFirstNameInGroup( nOper1, 'CL')
|
|
local ptMin1 = EgtGetInfo( nClId1, 'MMIN', 'p')
|
|
local ptMax1 = EgtGetInfo( nClId1, 'MMAX', 'p')
|
|
local b3Oper1 = BBox3d( ptMin1, ptMax1)
|
|
-- recupero il box delle seconda operazione
|
|
local nClId2 = EgtGetFirstNameInGroup( nOper2, 'CL')
|
|
local ptMin2 = EgtGetInfo( nClId2, 'MMIN', 'p')
|
|
local ptMax2 = EgtGetInfo( nClId2, 'MMAX', 'p')
|
|
local b3Oper2 = BBox3d( ptMin2, ptMax2)
|
|
-- recupero i centri dei box lungo X e Y
|
|
local dOper1X = b3Oper1:getCenter():getX()
|
|
local dOper1Y = b3Oper1:getCenter():getY()
|
|
local dOper2X = b3Oper2:getCenter():getX()
|
|
local dOper2Y = b3Oper2:getCenter():getY()
|
|
-- confronto per ordinamento
|
|
if dOper1X < dOper2X - TOL then
|
|
return true
|
|
elseif abs( dOper1X - dOper2X) < TOL then
|
|
if dOper1Y < dOper2Y - TOL then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- Controlla in vProc la presenza di feature da lavorare in doppio e, se trovate, ne setta i parametri
|
|
local function SetMirroredFeatures( vProc, b3Raw)
|
|
-- interasse minimo
|
|
local dMinimumDistanceMirroredFeatures = 780
|
|
-- inizializzazione array tasche e forature
|
|
local vPockets = {}
|
|
local vDrillings = {}
|
|
|
|
-- raccolgo le feature compatibili con doppio
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
if Proc.Flg ~= 0 then
|
|
-- raccolgo le tasche compatibili
|
|
if WD.DOUBLE_HEAD_POCKET and
|
|
(
|
|
( Proc.TopologyLongName == 'Rabbet-Through-RightAngles-Parallel-2' and Proc.AffectedFaces.Left and Proc.AffectedFaces.Right) or
|
|
( Proc.TopologyLongName == 'Groove-Through-RightAngles-Parallel-3' and ( not Proc.AffectedFaces.Bottom and Proc.AffectedFaces.Left and Proc.AffectedFaces.Right)) or
|
|
( Proc.TopologyLongName == 'Groove-Blind-RightAngles-Parallel-3') or
|
|
( Proc.TopologyLongName == 'Groove-Blind-RightAngles-Parallel-4') or
|
|
( Proc.TopologyLongName == 'Pocket-Blind-RightAngles-Parallel-5' and not Proc.AffectedFaces.Bottom)
|
|
) then
|
|
table.insert( vPockets, Proc)
|
|
-- raccolgo i fori verticali e aperti verso Z+
|
|
elseif WD.DOUBLE_HEAD_DRILLING and Proc.TopologyLongName == 'DRILLING' then
|
|
-- recupero e verifico la geometria del foro
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then
|
|
return false
|
|
end
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
if Proc.AffectedFaces.Top and AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then
|
|
table.insert( vDrillings, Proc)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ordinamento delle feature raccolte secondo X e poi Y crescente
|
|
table.sort( vPockets, SortFeaturesForMirror)
|
|
table.sort( vDrillings, SortFeaturesForMirror)
|
|
|
|
-- accoppio le tasche
|
|
local nCurrentPocket = 1
|
|
while nCurrentPocket <= #vPockets do
|
|
local Proc = vPockets[nCurrentPocket]
|
|
if Proc.Flg ~= 0 then
|
|
local b3Proc = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD)
|
|
-- cerco evenutale specchiata
|
|
local nCurrentMirrorPocket = nCurrentPocket + 1
|
|
while nCurrentMirrorPocket <= #vPockets do
|
|
local ProcMirror = vPockets[nCurrentMirrorPocket]
|
|
local b3ProcMirror = EgtGetBBoxGlob( ProcMirror.Id, GDB_BB.STANDARD)
|
|
-- feature non disattivata e diversa da nCurrentPocket
|
|
local bIsMirrorIdOk = ( Proc.Id ~= ProcMirror.Id and ProcMirror.Flg ~= 0)
|
|
-- feature mirror della stessa classe topologica
|
|
local bIsMirrorTopologyOk = ( Proc.TopologyLongName == ProcMirror.TopologyLongName)
|
|
-- determino se di fianco o in mezzo al singolo pannello
|
|
local bLapVsTop = Proc.AffectedFaces.Front and
|
|
(
|
|
Proc.TopologyLongName == 'Rabbet-Through-RightAngles-Parallel-2' or
|
|
Proc.TopologyLongName == 'Groove-Through-RightAngles-Parallel-3' or
|
|
Proc.TopologyLongName == 'Groove-Blind-RightAngles-Parallel-3' or
|
|
Proc.TopologyLongName == 'Groove-Blind-RightAngles-Parallel-4' or
|
|
Proc.TopologyLongName == 'Pocket-Blind-RightAngles-Parallel-5'
|
|
)
|
|
-- se di fianco, determino se è l'ultima parte prima della fine del grezzo
|
|
local bIsFeatureOnEdge, bIsMirrorFeatureOnEdge = false, false
|
|
if bLapVsTop then
|
|
bIsFeatureOnEdge = Proc.DistanceToNearestParts.Front > b3Raw:getDimY()
|
|
bIsMirrorFeatureOnEdge = ProcMirror.DistanceToNearestParts.Back > b3Raw:getDimY()
|
|
end
|
|
-- se di fianco, si sceglie se le feature sono compatibili con il doppio e nel caso che tipo di lavorazione fare
|
|
-- -1: no doppio, 0: nessuna preferenza, 1: pocket, 2: side (scambio faccia principale)
|
|
local nDoubleType = 0
|
|
local bAllowSideOnMirror = ( ProcMirror.DistanceToRawPart.Back - Proc.DistanceToRawPart.Front < 1 + 10 * GEO.EPS_SMALL) or ( not WD.SIDEMILL_BEFORE and ( not Proc.AffectedFaces.Top or not ProcMirror.AffectedFaces.Top))
|
|
if bLapVsTop and ( Proc.AffectedFaces.Top or Proc.AffectedFaces.Bottom) then
|
|
-- side
|
|
if bIsFeatureOnEdge and bIsMirrorFeatureOnEdge then
|
|
if not ( Proc.AffectedFaces.Top and ProcMirror.AffectedFaces.Top) then
|
|
nDoubleType = 2
|
|
end
|
|
-- no doppio
|
|
elseif Proc.AffectedFaces.Bottom or ProcMirror.AffectedFaces.Bottom then
|
|
nDoubleType = -1
|
|
-- tasca
|
|
else
|
|
nDoubleType = 1
|
|
end
|
|
end
|
|
-- corrispondenza nella posizione delle feature. Se di fianco il lato master è sempre quello verso l'operatore, se sopra nessun vincolo
|
|
local bIsMirrorSideOk = ( bLapVsTop and ProcMirror.AffectedFaces.Back and bIsFeatureOnEdge and bIsMirrorFeatureOnEdge and bAllowSideOnMirror) or
|
|
Proc.TopologyLongName == 'Groove-Through-RightAngles-Parallel-3' and Proc.AffectedFaces.Top and ProcMirror.AffectedFaces.Top or
|
|
Proc.TopologyLongName == 'Groove-Blind-RightAngles-Parallel-4' and Proc.AffectedFaces.Top and Proc.AffectedFaces.Left and ProcMirror.AffectedFaces.Top and ProcMirror.AffectedFaces.Left or
|
|
Proc.TopologyLongName == 'Groove-Blind-RightAngles-Parallel-4' and Proc.AffectedFaces.Top and Proc.AffectedFaces.Right and ProcMirror.AffectedFaces.Top and ProcMirror.AffectedFaces.Right or
|
|
Proc.TopologyLongName == 'Pocket-Blind-RightAngles-Parallel-5' and Proc.AffectedFaces.Top and ProcMirror.AffectedFaces.Top
|
|
-- box delle stesse dimensioni
|
|
local bIsMirrorFeatureSameDimension = abs( b3Proc:getDimX() - b3ProcMirror:getDimX()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5) and
|
|
abs( b3Proc:getDimY() - b3ProcMirror:getDimY()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5) and
|
|
abs( b3Proc:getDimZ() - b3ProcMirror:getDimZ()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5)
|
|
-- box allineati in X
|
|
local bIsMirrorBoxXAligned = abs( Proc.Box:getCenter():getX() - ProcMirror.Box:getCenter():getX()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5)
|
|
-- box che non si intersecano
|
|
local bIsNotMirrorBoxOverlapping = not OverlapsXY( b3Proc, b3ProcMirror)
|
|
-- distanza minima tra le feature
|
|
local dYMinDistance = max( b3Proc:getMin():getY(), b3ProcMirror:getMin():getY()) - min( b3Proc:getMax():getY(), b3ProcMirror:getMax():getY())
|
|
local bIsMirrorFeatureDistanceOk = dYMinDistance > dMinimumDistanceMirroredFeatures + 10 * GEO.EPS_SMALL
|
|
-- se tutte vere le condizioni, calcolo i parametri da passare alle lavorazioni
|
|
if nDoubleType > -1 and bIsMirrorIdOk and bIsMirrorTopologyOk and bIsMirrorSideOk and bIsMirrorFeatureSameDimension and bIsMirrorBoxXAligned and bIsNotMirrorBoxOverlapping and bIsMirrorFeatureDistanceOk then
|
|
local dYMirrorAx
|
|
local b3Tab = EgtGetTableArea()
|
|
local ptOnMirrorAx = ( Proc.Box:getCenter() + ProcMirror.Box:getCenter()) / 2
|
|
dYMirrorAx = ptOnMirrorAx:getY() - b3Tab:getMin():getY()
|
|
local dDeltaZ = ProcMirror.Box:getMax():getZ() - Proc.Box:getMax():getZ()
|
|
-- forzo side o pocket, se necessario
|
|
if nDoubleType == 1 then
|
|
EgtSetInfo( Proc.Id, 'PCKT', 1)
|
|
EgtSetInfo( ProcMirror.Id, 'PCKT', 1)
|
|
elseif nDoubleType == 2 then
|
|
Proc.Stype = 2
|
|
ProcMirror.Stype = 2
|
|
end
|
|
-- scrivo i parametri nella lavorazione
|
|
-- 2: specchiatura in Y
|
|
Proc.Double = 2
|
|
Proc.Mirror = ProcMirror
|
|
-- posizione Y dell'asse di specchiatura
|
|
Proc.MirrorAx = dYMirrorAx
|
|
-- Offset Z tra le feature
|
|
Proc.MirrorDeltaZ = dDeltaZ
|
|
|
|
-- rimuovo dalla lista le pocket già assegnate
|
|
local ProcMirrorOldId = ProcMirror.Id
|
|
table.remove( vPockets, nCurrentPocket)
|
|
-- avendo rimosso un elemento dall'array, potrebbe essere cambiato l'elemento nCurrentMirrorPocket
|
|
if nCurrentMirrorPocket > #vPockets or ( vPockets[nCurrentMirrorPocket].Id ~= ProcMirrorOldId) then nCurrentMirrorPocket = nCurrentMirrorPocket - 1 end
|
|
table.remove( vPockets, nCurrentMirrorPocket)
|
|
nCurrentPocket = 0
|
|
break
|
|
end
|
|
nCurrentMirrorPocket = nCurrentMirrorPocket + 1
|
|
end
|
|
end
|
|
nCurrentPocket = nCurrentPocket + 1
|
|
end
|
|
|
|
-- accoppio le forature
|
|
local nCurrentDrilling = 1
|
|
while nCurrentDrilling <= #vDrillings do
|
|
local Proc = vDrillings[nCurrentDrilling]
|
|
if Proc.Flg ~= 0 then
|
|
local b3Proc = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD)
|
|
-- cerco evenutale specchiata
|
|
local nCurrentMirrorDrilling = nCurrentDrilling + 1
|
|
while nCurrentMirrorDrilling <= #vDrillings do
|
|
local ProcMirror = vDrillings[nCurrentMirrorDrilling]
|
|
local b3ProcMirror = EgtGetBBoxGlob( ProcMirror.Id, GDB_BB.STANDARD)
|
|
-- feature non disattivata e diversa da nCurrentDrilling
|
|
local bIsMirrorIdOk = ( Proc.Id ~= ProcMirror.Id and ProcMirror.Flg ~= 0)
|
|
-- box delle stesse dimensioni
|
|
local bIsMirrorFeatureSameDimension = abs( b3Proc:getDimX() - b3ProcMirror:getDimX()) < ( WD.DOUBLE_HEAD_DRILLING_TOLERANCE or 0.1) and
|
|
abs( b3Proc:getDimY() - b3ProcMirror:getDimY()) < ( WD.DOUBLE_HEAD_DRILLING_TOLERANCE or 0.1) and
|
|
abs( b3Proc:getDimZ() - b3ProcMirror:getDimZ()) < ( WD.DOUBLE_HEAD_DRILLING_TOLERANCE or 0.1)
|
|
-- box allineati in X
|
|
local bIsMirrorBoxXAligned = abs( Proc.Box:getCenter():getX() - ProcMirror.Box:getCenter():getX()) < ( WD.DOUBLE_HEAD_DRILLING_TOLERANCE or 0.1)
|
|
-- box che non si intersecano
|
|
local bIsNotMirrorBoxOverlapping = not OverlapsXY( b3Proc, b3ProcMirror)
|
|
-- distanza minima tra le feature
|
|
local dYMinDistance = max( b3Proc:getMin():getY(), b3ProcMirror:getMin():getY()) - min( b3Proc:getMax():getY(), b3ProcMirror:getMax():getY())
|
|
local bIsMirrorFeatureDistanceOk = dYMinDistance > dMinimumDistanceMirroredFeatures + 10 * GEO.EPS_SMALL
|
|
-- se tutte vere le condizioni, calcolo i parametri da passare alle lavorazioni
|
|
if bIsMirrorIdOk and bIsMirrorFeatureSameDimension and bIsMirrorBoxXAligned and bIsNotMirrorBoxOverlapping and bIsMirrorFeatureDistanceOk then
|
|
local dYMirrorAx
|
|
local b3Tab = EgtGetTableArea()
|
|
local ptOnMirrorAx = ( Proc.Box:getCenter() + ProcMirror.Box:getCenter()) / 2
|
|
dYMirrorAx = ptOnMirrorAx:getY() - b3Tab:getMin():getY()
|
|
-- scrivo i parametri nella lavorazione
|
|
-- 2: specchiatura in Y
|
|
Proc.Double = 2
|
|
Proc.Mirror = ProcMirror
|
|
-- posizione Y dell'asse di specchiatura
|
|
Proc.MirrorAx = dYMirrorAx
|
|
|
|
-- rimuovo dalla lista le forature già assegnate
|
|
local ProcMirrorOldId = ProcMirror.Id
|
|
table.remove( vDrillings, nCurrentDrilling)
|
|
-- avendo rimosso un elemento dall'array, potrebbe essere cambiato l'elemento nCurrentMirrorDrilling
|
|
if nCurrentMirrorDrilling > #vDrillings or ( vDrillings[nCurrentMirrorDrilling].Id ~= ProcMirrorOldId) then nCurrentMirrorDrilling = nCurrentMirrorDrilling - 1 end
|
|
table.remove( vDrillings, nCurrentMirrorDrilling)
|
|
nCurrentDrilling = 0
|
|
break
|
|
end
|
|
nCurrentMirrorDrilling = nCurrentMirrorDrilling + 1
|
|
end
|
|
end
|
|
nCurrentDrilling = nCurrentDrilling + 1
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- verifico e imposto le fresature da specchiare
|
|
local function SetMirroredOperations()
|
|
-- interasse minimo
|
|
local dMinimumDistanceMirroredOperations = 780
|
|
-- inzializzazione array
|
|
local vMillings = {}
|
|
|
|
-- raccolgo le fresature non già fatte in doppio
|
|
if WD.DOUBLE_HEAD_MILLCORNER then
|
|
local nOperId = EgtGetNextOperation( EgtGetPhaseDisposition( 1))
|
|
while nOperId do
|
|
EgtSetCurrMachining( nOperId)
|
|
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
|
|
local bIsDouble = ( EgtGetValInNotes( sUserNotes, 'DOUBLE', 'i') or 0) > 0
|
|
if EgtGetOperationMode( nOperId) and not EgtIsMachiningEmpty( nOperId) and not bIsDouble and EgtGetOperationType( nOperId) == MCH_OY.MILLING then
|
|
table.insert( vMillings, nOperId)
|
|
end
|
|
nOperId = EgtGetNextOperation( nOperId)
|
|
end
|
|
end
|
|
|
|
-- ordinamento delle operazioni raccolte secondo X e poi Y crescente
|
|
table.sort( vMillings, SortOperationsForMirror)
|
|
|
|
-- accoppio le fresature
|
|
local nCurrentMilling = 1
|
|
while nCurrentMilling <= #vMillings do
|
|
local nOperIdMaster = vMillings[nCurrentMilling]
|
|
EgtSetCurrMachining( nOperIdMaster)
|
|
local sMachining = EgtGetMachiningParam( MCH_MP.NAME, 's')
|
|
local nClId = EgtGetFirstNameInGroup( nOperIdMaster, 'CL')
|
|
local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL)
|
|
-- vettore direzione utensile e somma normali facce per lavorazione master
|
|
local vtTool = EgtGetInfo( nPathId, 'EXTR', 'v')
|
|
local vtNormSum = EgtGetInfo( nOperIdMaster, 'NORM_SUM', 'v')
|
|
local ptMin = EgtGetInfo( nClId, 'MMIN', 'p')
|
|
local ptMax = EgtGetInfo( nClId, 'MMAX', 'p')
|
|
-- box percorso lavorazione master
|
|
local b3Operation = BBox3d( ptMin, ptMax)
|
|
-- lavorazione master adatta alla specchiatura
|
|
local bIsMachiningOk = WM.IsMachiningOkForDouble( sMachining)
|
|
if bIsMachiningOk then
|
|
-- recupero la distanza tra centro di rotazione e punta dell'utensile per aumentare o ridurre l'interasse minimo
|
|
local dTipToPivot, dTipToPivotDouble = 999, 999
|
|
local dToolMasterTotLength, dToolMasterTotLengthDouble = 999, 999
|
|
local sToolMasterName = ''
|
|
if EgtMdbSetCurrMachining( sMachining) then
|
|
-- recupero l'utensile della lavorazione e il suo doppio
|
|
sToolMasterName = EgtMdbGetCurrMachiningParam( MCH_MP.TOOL)
|
|
if EgtTdbSetCurrTool( sToolMasterName or '') then
|
|
dToolMasterTotLength = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) or dToolMasterTotLength
|
|
local sToolDoubleName = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'DOUBLE', 's')
|
|
if sToolDoubleName and EgtTdbSetCurrTool( sToolDoubleName) then
|
|
dToolMasterTotLengthDouble = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) or dToolMasterTotLengthDouble
|
|
end
|
|
end
|
|
end
|
|
if WD.HEAD_PIVOT_MAIN and WD.HEAD_PIVOT_SECONDARY then
|
|
dTipToPivot = dToolMasterTotLength + WD.HEAD_PIVOT_MAIN
|
|
dTipToPivotDouble = dToolMasterTotLengthDouble + WD.HEAD_PIVOT_SECONDARY
|
|
else
|
|
local sOut = 'Error : HEAD_PIVOT_MAIN or HEAD_PIVOT_SECONDARY missing in WallData'
|
|
return false, sOut
|
|
end
|
|
-- cerco eventuale specchiata
|
|
local nCurrentMirrorMilling = nCurrentMilling + 1
|
|
while nCurrentMirrorMilling <= #vMillings do
|
|
local nOperIdMirror = vMillings[nCurrentMirrorMilling]
|
|
EgtSetCurrMachining( nOperIdMirror)
|
|
local nClIdMirror = EgtGetFirstNameInGroup( nOperIdMirror, 'CL')
|
|
local nPathIdMirror = EgtGetFirstInGroup( nClIdMirror or GDB_ID.NULL)
|
|
-- vettore direzione utensile e somma normali facce per lavorazione mirror
|
|
local vtToolMirror = EgtGetInfo( nPathIdMirror, 'EXTR', 'v')
|
|
local vtNormSumMirror = EgtGetInfo( nOperIdMirror, 'NORM_SUM', 'v')
|
|
local ptMinMirror = EgtGetInfo( nClIdMirror, 'MMIN', 'p')
|
|
local ptMaxMirror = EgtGetInfo( nClIdMirror, 'MMAX', 'p')
|
|
-- box percorso lavorazione mirror
|
|
local b3OperationMirror = BBox3d( ptMinMirror, ptMaxMirror)
|
|
-- utensile originale lavorazione specchiata
|
|
local sOriginalMirrorToolName = EgtGetMachiningParam( MCH_MP.TOOL)
|
|
local bIsOriginalMirrorToolSameSize = WM.IsToolDoubleOk( sToolMasterName, sOriginalMirrorToolName)
|
|
-- lavorazione mirror adatta alla specchiatura
|
|
local bIsMirrorMachiningOk = nOperIdMaster ~= nOperIdMirror
|
|
-- lavorazione master più a sinistra
|
|
local bIsMirrorSideOk = ( b3OperationMirror:getCenter():getY() - b3Operation:getCenter():getY()) > ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5)
|
|
-- box delle stesse dimensioni
|
|
local bIsMirrorOperationSameDimension = abs( b3Operation:getDimX() - b3OperationMirror:getDimX()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5) and
|
|
abs( b3Operation:getDimY() - b3OperationMirror:getDimY()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5) and
|
|
abs( b3Operation:getDimZ() - b3OperationMirror:getDimZ()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5)
|
|
-- box allineati in X
|
|
local bIsMirrorBoxXAligned = abs( b3Operation:getCenter():getX() - b3OperationMirror:getCenter():getX()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5) and
|
|
abs( b3Operation:getCenter():getX() - b3OperationMirror:getCenter():getX()) < ( WD.DOUBLE_HEAD_POCKET_TOLERANCE or 0.5)
|
|
-- box che non si intersecano
|
|
local bIsNotMirrorBoxOverlapping = not OverlapsXY( b3Operation, b3OperationMirror)
|
|
-- distanza minima tra le feature
|
|
local dTipToPivotProjectionOnY = dTipToPivot * vtTool:getY()
|
|
local dTipToPivotProjectionOnYDouble = dTipToPivotDouble * vtToolMirror:getY()
|
|
local dYMinDistance = max( b3Operation:getMin():getY(), b3OperationMirror:getMin():getY()) - min( b3Operation:getMax():getY(), b3OperationMirror:getMax():getY())
|
|
local bIsMirrorOperationDistanceOk = dYMinDistance > dMinimumDistanceMirroredOperations + dTipToPivotProjectionOnY - dTipToPivotProjectionOnYDouble + 10 * GEO.EPS_SMALL
|
|
-- vettori utensile e somma normali facce specchiati
|
|
local vtToolMirrored = Vector3d( vtTool)
|
|
vtToolMirrored:mirror( Y_AX())
|
|
local bIsMirrorVectorOk = false
|
|
if AreSameVectorApprox( vtToolMirrored, vtToolMirror) then
|
|
if AreSameVectorApprox(vtTool, vtToolMirror) then
|
|
if vtNormSum and vtNormSumMirror then
|
|
local vtNormSumMirrored = Vector3d( vtNormSum)
|
|
vtNormSumMirrored:mirror( Y_AX())
|
|
bIsMirrorVectorOk = AreSameVectorApprox( vtNormSumMirrored, vtNormSumMirror)
|
|
end
|
|
else
|
|
bIsMirrorVectorOk = true
|
|
end
|
|
end
|
|
-- se condizioni corrette, scrivo le note e cancello la specchiata
|
|
if bIsOriginalMirrorToolSameSize and bIsMirrorMachiningOk and bIsMirrorSideOk and bIsMirrorOperationSameDimension and bIsMirrorBoxXAligned and bIsNotMirrorBoxOverlapping and bIsMirrorOperationDistanceOk and bIsMirrorVectorOk then
|
|
-- calcolo asse di specchiatura
|
|
local dYMirrorAx
|
|
local b3Tab = EgtGetTableArea()
|
|
local ptOnMirrorAx = ( b3Operation:getCenter() + b3OperationMirror:getCenter()) / 2
|
|
dYMirrorAx = ptOnMirrorAx:getY() - b3Tab:getMin():getY()
|
|
EgtSetCurrMachining( nOperIdMaster)
|
|
-- leggo note esistenti
|
|
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
|
|
-- aggiungo note per doppio
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'DOUBLE', 2)
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MirrorAx', dYMirrorAx)
|
|
-- scrivo le note della lavorazione
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- cancello l'operazione specchiata
|
|
EgtRemoveOperation( nOperIdMirror)
|
|
-- rimuovo dalla lista le fresature già assegnate
|
|
local nCurrentMirrorMillingOldId = nCurrentMirrorMilling
|
|
table.remove( vMillings, nCurrentMilling)
|
|
-- avendo rimosso un elemento dall'array, potrebbe essere cambiato l'elemento nCurrentMirrorPocket
|
|
if nCurrentMirrorMilling > #vMillings or ( vMillings[nCurrentMirrorMilling] ~= nCurrentMirrorMillingOldId) then nCurrentMirrorMilling = nCurrentMirrorMilling - 1 end
|
|
table.remove( vMillings, nCurrentMirrorMilling)
|
|
nCurrentMilling = 0
|
|
break
|
|
end
|
|
nCurrentMirrorMilling = nCurrentMirrorMilling + 1
|
|
end
|
|
end
|
|
nCurrentMilling = nCurrentMilling + 1
|
|
end
|
|
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 topologicamente le feature
|
|
ClassifyTopology( vProc, nRawId)
|
|
-- classifico le feature
|
|
ClassifyFeatures( vProc, b3Raw)
|
|
-- recupero l'elenco delle aree vietate alle chiodature
|
|
local vNLO = WL.GetNailLockOutAreas( vProc)
|
|
-- Se non ci sono aree vietate alle chiodature, 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 #vNLO == 0 and WD.FindFeaturesInDouble then
|
|
WD.FindFeaturesInDouble( vProc, b3Raw)
|
|
end
|
|
|
|
SetMirroredFeatures( vProc, b3Raw)
|
|
|
|
-- 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, vNLO)
|
|
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 and not Proc.LockOut 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)
|
|
|
|
-- setto quali sono le lavorazioni da disattivare perchè specchiate di lavorazioni in doppio
|
|
local vProcToDisable = {}
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
if Proc.Double and Proc.Double > 0 then
|
|
for j = 1, #vProc do
|
|
local ProcMirror = vProc[j]
|
|
if Proc.Mirror.Id == ProcMirror.Id then
|
|
-- per i fori l'operazione si basa sulla geometria ausiliaria
|
|
if Proc.TopologyLongName == 'DRILLING' then
|
|
local AuxId = EgtGetInfo( ProcMirror.Id, 'AUXID', 'i') or 0
|
|
if AuxId then AuxId = AuxId + ProcMirror.Id end
|
|
table.insert( vProcToDisable, AuxId)
|
|
-- per tutte le altre lavorazioni si usa la geometria della feature
|
|
else
|
|
table.insert( vProcToDisable, ProcMirror.Id)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- cancello le operazioni legate a lavorazioni specchiate
|
|
local nOperId = EgtGetNextOperation( EgtGetPhaseDisposition( 1))
|
|
while nOperId do
|
|
EgtSetCurrMachining( nOperId)
|
|
local nOperationProcIds = EgtGetMachiningGeometry()
|
|
local nCurrentOperId = nOperId
|
|
if #nOperationProcIds > 0 then
|
|
local nOperationProcId = nOperationProcIds[1][1]
|
|
for i = 1, #vProcToDisable do
|
|
local ProcId = vProcToDisable[i]
|
|
if nOperationProcId == ProcId then
|
|
nOperId = EgtGetNextOperation( nOperId)
|
|
EgtRemoveOperation( nCurrentOperId)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if nCurrentOperId == nOperId then
|
|
nOperId = EgtGetNextOperation( nOperId)
|
|
end
|
|
end
|
|
|
|
SetMirroredOperations()
|
|
|
|
-- 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 = {}
|
|
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
|