da7d2a7159
- LapJoint -> MakeSideGrooveByMill, se rabbet doppio uno verso l'alto e uno verso il basso, aggiunto step extra iniziale per ripulire la lamina che potrebbe rimanere nella rabbet che guarda in alto.
1264 lines
63 KiB
Lua
1264 lines
63 KiB
Lua
-- WallExec.lua by Egaltech s.r.l. 2023/10/16
|
|
-- 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/10 In SetMirroredFeatures doppio disattivato se side e la lavorazione mirror è troppo distante dal grezzo.
|
|
-- 2023/11/13 Aggiunte le lavorazioni PreSideMill che vengono sempre fatte prima delle SideMill.
|
|
|
|
-- 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'
|
|
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 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)
|
|
local nRecognized = 0
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
if Topology.Classify( Proc) 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)
|
|
-- 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
|