4789452523
- Corrette rotazioni 90 deg per macchine con carico da destra.
1802 lines
86 KiB
Lua
1802 lines
86 KiB
Lua
-- BeamExec.lua by Egaltech s.r.l. 2022/12/23
|
|
-- Libreria esecuzione lavorazioni per Travi
|
|
-- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3.
|
|
-- 2019/09/04 Corretto controllo feature di testa e coda con sovramateriale di testa elevato.
|
|
-- 2019/09/25 Aggiunta gestione StepJoint e StepJointNotch.
|
|
-- 2020/01/21 Aggiunta gestione ScarfJoint.
|
|
-- 2020/02/10 Aggiunta gestione FrenchRidgeLap.
|
|
-- 2020/02/11 Aggiunta gestione BlockHausFront.
|
|
-- 2020/04/02 Fori di testa dal basso non danno errore e fanno ribaltare la trave.
|
|
-- 2020/04/07 Aggiunta gestione TyroleanDovetail.
|
|
-- 2020/04/14 Aggiunta gestione Dovetail.
|
|
-- 2020/05/16 Migliorie ordinamento fori.
|
|
-- 2020/05/16 Gestione rotazione di 90deg.
|
|
-- 2020/05/21 Correzione rotazione di 90deg (caso DY > DZ).
|
|
-- 2020/05/25 Correzione rotazione di 90deg dopo scarico su carico.
|
|
-- 2020/06/02 Per dati foro si chiama funzione GetData di ProcessDrill (per gestire variazioni di diametro da UserParams).
|
|
-- 2020/07/25 Ricalcolati flag head e tail della prima parte del foro dopo lo split.
|
|
-- 2020/07/27 Modifica a ordinamento fori.
|
|
-- 2020/10/07 Aggiunta distanza libera dietro il pezzo (BDST) scritta nel suo grezzo.
|
|
-- 2020/10/15 Per foro sdoppiato ricalcolo anche flag Head oltre a Tail .
|
|
-- 2020/10/23 Corretto spostamento foro per tenone quando tenone nullo.
|
|
-- 2020/12/29 Aggiunta gestione fori in doppio.
|
|
-- 2021/02/25 Aggiunta gestione eventuale ricalcolo per macchine tipo PF.
|
|
-- 2021/07/13 Aggiunta gestione posizionamento pezzo TR/BR per macchine con carico a destra e scarico a sinistra.
|
|
-- 2021/11/27 House mortise sempre prima di (dt)mortise, house tenon sempre dopo (dt)tenon.
|
|
-- 2021/12/15 Corretta CompareFeature (risultato deve essere simmetrico scambiando le feature).
|
|
-- 2021/12/20 Ulteriore correzione a CompareFeature (caso con entrambe senza geometria).
|
|
-- 2022/05/04 Nell'ordinamento quando si confrontano i box delle feature aggiunta verifica preliminare della loro validità.
|
|
-- 2022/05/31 Aggiunta gestione sovramateriale per sezioni alte e larghe e informazione di eventuale creazione nuova fase dalla AddFeatureMachining.
|
|
-- 2022/06/10 Per sezioni alte e larghe modificata la gestione del sovramateriale per considerare la presenza di feature preesistenti ed
|
|
-- eventuale parametro Q05, che determinano la presenza o meno della finitura.
|
|
-- Create le funzioni AnalyzeHeadFeatures e AnalyzeTailFeatures. Spostate più in alto le funzioni CollectFeatures, isHeadFeature e isTailFeature.
|
|
-- 2022/07/01 Aggiunta la gestione delle forature migliorate in presenza di feature testa/coda ad 1 faccia che tagliano tutta la sezione,
|
|
-- controllata tramite il parametro IMPROVE_HEAD_TAIL_DRILLINGS da BeamData. Attivata di default.
|
|
-- 2022/08/01 Tolleranza su sezione portata a 0.1 mm (100 * GEO.EPS_SMALL).
|
|
-- 2022/08/08 Modifica per macchine senza BD.MAX_WIDTH2 e BD.MAX_HEIGHT2.
|
|
-- 2022/08/18 Aggiunta gestione macchine con testa da sotto con lama da sotto disabilitata.
|
|
-- 2022/09/28 I fori vengono sempre fatti prima delle tacche.
|
|
-- 2022/09/29 Aggiunta la ricerca di feature specchiate, al momento solo per DtMortise, con le relative funzioni.
|
|
-- 2022/12/23 Corrette rotazioni 90 deg per macchine con carico da destra.
|
|
|
|
|
|
-- Tabella per definizione modulo
|
|
local BeamExec = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
|
|
-- Carico i dati globali e libero tutti gli altri
|
|
_G.package.loaded.BeamData = 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 BD = require( 'BeamData')
|
|
|
|
-- Carico le librerie
|
|
_G.package.loaded.MachiningLib = nil
|
|
_G.package.loaded.BeamLib = nil
|
|
_G.package.loaded.DiceCut = nil
|
|
_G.package.loaded.FacesBySaw = nil
|
|
_G.package.loaded.ProcessHeadCut = nil
|
|
_G.package.loaded.ProcessSplit = nil
|
|
_G.package.loaded.ProcessCut = nil
|
|
_G.package.loaded.ProcessDoubleCut = nil
|
|
_G.package.loaded.ProcessLongCut = nil
|
|
_G.package.loaded.ProcessLongDoubleCut = nil
|
|
_G.package.loaded.ProcessSawCut = nil
|
|
_G.package.loaded.ProcessRidgeLap = nil
|
|
_G.package.loaded.ProcessLapJoint = nil
|
|
_G.package.loaded.ProcessChamfer = nil
|
|
_G.package.loaded.ProcessDrill = nil
|
|
_G.package.loaded.ProcessFrenchRidgeLap = nil
|
|
_G.package.loaded.ProcessBlockHausFront = nil
|
|
_G.package.loaded.ProcessTenon = nil
|
|
_G.package.loaded.ProcessMortise = nil
|
|
_G.package.loaded.ProcessDtTenon = nil
|
|
_G.package.loaded.ProcessDtMortise = nil
|
|
_G.package.loaded.ProcessMark = nil
|
|
_G.package.loaded.ProcessText = nil
|
|
_G.package.loaded.ProcessScarfJoint = nil
|
|
_G.package.loaded.ProcessSimpleScarf = nil
|
|
_G.package.loaded.ProcessStepJoint = nil
|
|
_G.package.loaded.ProcessStepJointNotch = nil
|
|
_G.package.loaded.ProcessProfFront = nil
|
|
_G.package.loaded.ProcessProfConcave = nil
|
|
_G.package.loaded.ProcessProfConvex = nil
|
|
_G.package.loaded.ProcessProfCamb = nil
|
|
_G.package.loaded.ProcessProfHead = nil
|
|
_G.package.loaded.ProcessRoundArch = nil
|
|
_G.package.loaded.ProcessTyroleanDovetail = nil
|
|
_G.package.loaded.ProcessDovetail = nil
|
|
_G.package.loaded.ProcessFreeContour = nil
|
|
_G.package.loaded.ProcessDecor = nil
|
|
local ML = require( 'MachiningLib')
|
|
local BL = require( 'BeamLib')
|
|
local DC = require( 'DiceCut')
|
|
local Fbs = require( 'FacesBySaw')
|
|
local Hcut= require( 'ProcessHeadCut')
|
|
local Split = require( 'ProcessSplit')
|
|
local Cut = require( 'ProcessCut')
|
|
local DoubleCut = require( 'ProcessDoubleCut')
|
|
local LongCut = require( 'ProcessLongCut')
|
|
local Long2Cut = require( 'ProcessLongDoubleCut')
|
|
local SawCut = require( 'ProcessSawCut')
|
|
local RidgeLap = require( 'ProcessRidgeLap')
|
|
local LapJoint = require( 'ProcessLapJoint')
|
|
local Chamfer = require( 'ProcessChamfer')
|
|
local Drill = require( 'ProcessDrill')
|
|
local FrenchRidgeLap = require( 'ProcessFrenchRidgeLap')
|
|
local BlockHausFront = require( 'ProcessBlockHausFront')
|
|
local Tenon = require( 'ProcessTenon')
|
|
local Mortise = require( 'ProcessMortise')
|
|
local DtTenon = require( 'ProcessDtTenon')
|
|
local DtMortise = require( 'ProcessDtMortise')
|
|
local Mark = require( 'ProcessMark')
|
|
local Text = require( 'ProcessText')
|
|
local ScarfJoint = require( 'ProcessScarfJoint')
|
|
local Scarf = require( 'ProcessSimpleScarf')
|
|
local StepJoint = require( 'ProcessStepJoint')
|
|
local StJoNotch = require( 'ProcessStepJointNotch')
|
|
local ProfFront = require( 'ProcessProfFront')
|
|
local ProfConcave = require( 'ProcessProfConcave')
|
|
local ProfConvex = require( 'ProcessProfConvex')
|
|
local ProfCamb = require( 'ProcessProfCamb')
|
|
local ProfHead = require( 'ProcessProfHead')
|
|
local RoundArch = require( 'ProcessRoundArch')
|
|
local TyroleanDovetail = require( 'ProcessTyroleanDovetail')
|
|
local Dovetail = require( 'ProcessDovetail')
|
|
local FreeContour = require( 'ProcessFreeContour')
|
|
local Decor = require( 'ProcessDecor')
|
|
|
|
EgtOutLog( ' BeamExec started', 1)
|
|
EgtMdbSetGeneralParam( MCH_GP.MAXDEPTHSAFE, BD.COLL_SIC)
|
|
EgtMdbSave()
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function IsHeadFeature( Proc, b3Raw, dCurrOvmH)
|
|
-- feature sempre di testa o coda per il gruppo
|
|
if Proc.Grp == 1 or Proc.Grp == 2 then
|
|
return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX() - 0.5 * dCurrOvmH)
|
|
end
|
|
-- feature sempre di testa o coda nonostante il gruppo
|
|
if ( Proc.Grp == 3 or Proc.Grp == 4) and
|
|
( Proc.Prc == 38 or Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then
|
|
return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX() - 0.5 * dCurrOvmH)
|
|
end
|
|
-- gestioni speciali
|
|
if LapJoint.Identify( Proc) then
|
|
return LapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH)
|
|
end
|
|
if Drill.Identify( Proc) then
|
|
return Drill.IsHeadFeature( Proc, b3Raw, dCurrOvmH)
|
|
end
|
|
if RoundArch.Identify( Proc) then
|
|
return RoundArch.IsHeadFeature( Proc, b3Raw, dCurrOvmH)
|
|
end
|
|
if Dovetail.Identify( Proc) then
|
|
return Dovetail.IsHeadFeature( Proc, b3Raw, dCurrOvmH)
|
|
end
|
|
if FreeContour.Identify( Proc) then
|
|
return FreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH)
|
|
end
|
|
-- non è di testa
|
|
return false
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function IsTailFeature( Proc, b3Raw, dCurrOvmH, dCurrOvmT)
|
|
-- lunghezza di riferimento per spostare le feature di coda appena prima
|
|
local dAdvTailLen = BD.LEN_VERY_SHORT_PART or BD.LEN_SHORT_PART
|
|
-- feature sempre di testa o coda per il gruppo (se non troppo lunga)
|
|
if Proc.Grp == 1 or Proc.Grp == 2 then
|
|
-- se abilitato avanzamento lavorazione feature di coda e pezzo corto (quindi a caduta) e feature in coda
|
|
if BD.ADVANCE_TAIL_CUT and b3Raw:getDimX() < dAdvTailLen and Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH then
|
|
-- se taglio, lo avanzo
|
|
if Proc.Prc == 10 then
|
|
return false, true
|
|
end
|
|
end
|
|
-- standard
|
|
return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH and Proc.Box:getDimX() < BD.MAX_LEN_HTFEA)
|
|
end
|
|
-- feature sempre di testa o coda nonostante il gruppo
|
|
if ( Proc.Grp == 3 or Proc.Grp == 4) and
|
|
( Proc.Prc == 38 or Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then
|
|
-- se abilitato avanzamento lavorazione feature di coda e pezzo corto (quindi a caduta) e feature in coda
|
|
if BD.ADVANCE_TAIL_CUT and b3Raw:getDimX() < dAdvTailLen and Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH then
|
|
-- se profilo front solo con smusso, lo avanzo
|
|
if Proc.Prc == 100 and ProfFront.OnlyChamfer( Proc) then
|
|
return false, true
|
|
end
|
|
-- se profilo concavo solo con smusso, lo avanzo
|
|
if Proc.Prc == 101 and ProfConcave.OnlyChamfer( Proc) then
|
|
return false, true
|
|
end
|
|
-- se profilo convesso solo con smusso, lo avanzo
|
|
if Proc.Prc == 102 and ProfConvex.OnlyChamfer( Proc) then
|
|
return false, true
|
|
end
|
|
-- se profilo caudato solo con smusso, lo avanzo
|
|
if Proc.Prc == 103 and ProfCamb.OnlyChamfer( Proc) then
|
|
return false, true
|
|
end
|
|
-- se profilo head solo con smusso, lo avanzo
|
|
if Proc.Prc == 106 and ProfHead.OnlyChamfer( Proc) then
|
|
return false, true
|
|
end
|
|
end
|
|
-- standard
|
|
return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH)
|
|
end
|
|
-- gestioni speciali
|
|
if LapJoint.Identify( Proc) then
|
|
return LapJoint.IsTailFeature( Proc, b3Raw)
|
|
end
|
|
if Drill.Identify( Proc) then
|
|
return Drill.IsTailFeature( Proc, b3Raw, dCurrOvmT)
|
|
end
|
|
if DtMortise.Identify( Proc) then
|
|
return DtMortise.IsTailFeature( Proc, b3Raw)
|
|
end
|
|
if RoundArch.Identify( Proc) then
|
|
return RoundArch.IsTailFeature( Proc, b3Raw)
|
|
end
|
|
if Dovetail.Identify( Proc) then
|
|
return Dovetail.IsTailFeature( Proc, b3Raw)
|
|
end
|
|
if FreeContour.Identify( Proc) then
|
|
return FreeContour.IsTailFeature( Proc, b3Raw)
|
|
end
|
|
-- non è di coda
|
|
return false
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- restituisce vero se la feature con box b3Proc taglia l'intera sezione della barra, rappresentata dalle sue dimensioni W e H
|
|
local function IsFeatureCuttingEntireSection( b3Proc, dRawW, dRawH)
|
|
return ((abs(b3Proc:getDimY() - dRawW) < 10 * GEO.EPS_SMALL or b3Proc:getDimY() > dRawW) and (abs(b3Proc:getDimZ() - dRawH) < 10 * GEO.EPS_SMALL or b3Proc:getDimZ() > dRawH))
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function CollectFeatures( PartId, b3Raw, dCurrOvmH, dCurrOvmT)
|
|
local dRawW = b3Raw:getDimY()
|
|
local dRawH = b3Raw:getDimZ()
|
|
-- recupero le feature
|
|
local vProc = {}
|
|
local LayerId = {}
|
|
LayerId[1] = BL.GetAddGroup( PartId)
|
|
LayerId[2] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Processings')
|
|
local nMachineBeforeIntersectingDrillingsIdHead, dMachineBeforeIntersectingDrillingsXHead, nMachineBeforeIntersectingDrillingsIdTail, dMachineBeforeIntersectingDrillingsXTail = nil, GEO.INFINITO, nil, -GEO.INFINITO
|
|
local b3MachineBeforeIntersectingDrillingsBoxHead, b3MachineBeforeIntersectingDrillingsBoxTail = nil, nil
|
|
for nInd = 1, 2 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
|
|
-- leggo se ci sono feature collegate
|
|
local nAddAdjId = EgtGetInfo( ProcId, 'ADJID', 'i')
|
|
local nAddMainId = EgtGetInfo( ProcId, 'MAINID', 'i')
|
|
if nGrp and nPrc and nDo == 1 then
|
|
local Proc = {}
|
|
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
|
|
-- se ci sono feature collegate ne scrivo il riferimento nella Proc
|
|
if nAddAdjId then
|
|
Proc.AdjId = Proc.Id + nAddAdjId
|
|
elseif nAddMainId then
|
|
Proc.MainId = Proc.Id + nAddMainId
|
|
end
|
|
Proc.Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD)
|
|
if Proc.Box and not Proc.Box:isEmpty() then
|
|
Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH)
|
|
Proc.Tail, Proc.AdvTail = IsTailFeature( Proc, b3Raw, dCurrOvmH, dCurrOvmT)
|
|
if Proc.Fct == 1 and IsFeatureCuttingEntireSection( Proc.Box , dRawW, dRawH) and ( Proc.Head or Proc.Tail) and Proc.Prc ~= 340 and Proc.Prc ~= 350 then
|
|
if Proc.Head and Proc.Box:getCenter():getX() < dMachineBeforeIntersectingDrillingsXHead then
|
|
dMachineBeforeIntersectingDrillingsXHead = Proc.Box:getCenter():getX()
|
|
nMachineBeforeIntersectingDrillingsIdHead = Proc.Id
|
|
b3MachineBeforeIntersectingDrillingsBoxHead = Proc.Box
|
|
elseif Proc.Tail and Proc.Box:getCenter():getX() > dMachineBeforeIntersectingDrillingsXTail then
|
|
dMachineBeforeIntersectingDrillingsXTail = Proc.Box:getCenter():getX()
|
|
nMachineBeforeIntersectingDrillingsIdTail = Proc.Id
|
|
b3MachineBeforeIntersectingDrillingsBoxTail = Proc.Box
|
|
end
|
|
end
|
|
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
|
|
Proc.Head = Drill.IsHeadFeature( Proc, b3Raw, dCurrOvmH)
|
|
Proc.Tail = Drill.IsTailFeature( Proc, b3Raw, dCurrOvmH, dCurrOvmT)
|
|
-- definisco dati seconda parte
|
|
local Proc2 = {}
|
|
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.Head = Drill.IsHeadFeature( Proc2, b3Raw, dCurrOvmH)
|
|
Proc2.Tail = Drill.IsTailFeature( Proc2, b3Raw, dCurrOvmH)
|
|
Proc2.Fcs = Proc.Fce
|
|
Proc2.Fce = Proc.Fcs
|
|
Proc2.CutId = Proc.CutId
|
|
Proc2.TaskId = Proc.TaskId
|
|
Proc2.AdjId = Proc.AdjId
|
|
Proc2.MainId = Proc.MainId
|
|
table.insert( vProc, Proc2)
|
|
end
|
|
-- se BlockHaus HalfLap
|
|
elseif Proc.Prc == 37 then
|
|
local nFacInd = BL.GetFaceWithMostAdj( Proc.Id, PartId)
|
|
if nFacInd then
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
if vtN then
|
|
Proc.vtN = Vector3d( vtN)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
Proc.Head = false
|
|
Proc.Tail = false
|
|
Proc.Flg = 0
|
|
table.insert( vProc, Proc)
|
|
EgtOutLog( ' Feature ' .. tostring( Proc.Id) .. ' is empty (no geometry)')
|
|
end
|
|
end
|
|
end
|
|
ProcId = EgtGetNext( ProcId)
|
|
end
|
|
end
|
|
local vMachineBeforeIntersectingDrillings = {
|
|
Head = { Id = nMachineBeforeIntersectingDrillingsIdHead, Box = b3MachineBeforeIntersectingDrillingsBoxHead},
|
|
Tail = { Id = nMachineBeforeIntersectingDrillingsIdTail, Box = b3MachineBeforeIntersectingDrillingsBoxTail}
|
|
}
|
|
return vProc, vMachineBeforeIntersectingDrillings
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function AnalyzeHeadFeatures( b3Solid, vProc, dRawW, dRawH)
|
|
local nReplacedFeatureId = nil
|
|
local bHeadFinishingNeeded = true
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
-- controllo se esiste già una feature taglio di testa
|
|
if not nReplacedFeatureId then
|
|
if ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10 then
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
if ptC and vtN and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL then
|
|
nReplacedFeatureId = Proc.Id
|
|
end
|
|
end
|
|
end
|
|
if Proc.Head and Proc.Id ~= nReplacedFeatureId and Proc.Prc ~= 340 then
|
|
-- controllo se la feature taglia l'intera sezione; in caso positivo la finitura non è necessaria
|
|
bHeadFinishingNeeded = not IsFeatureCuttingEntireSection( Proc.Box, dRawW, dRawH)
|
|
end
|
|
end
|
|
return bHeadFinishingNeeded, nReplacedFeatureId
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function AnalyzeTailFeatures( b3Solid, vProc, dRawW, dRawH)
|
|
local nReplacedFeatureId = nil
|
|
local bTailFinishingNeeded = true
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
-- controllo se esistè già una feature taglio di coda
|
|
if not nReplacedFeatureId then
|
|
if ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10 then
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
if ptC and vtN and AreSameVectorApprox( vtN, -X_AX()) and abs( ptC:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL then
|
|
nReplacedFeatureId = Proc.Id
|
|
end
|
|
end
|
|
end
|
|
if Proc.Tail and Proc.Id ~= nReplacedFeatureId and Proc.Prc ~= 350 then
|
|
-- controllo se la feature taglia l'intera sezione; in caso positivo la finitura non è necessaria
|
|
bTailFinishingNeeded = not IsFeatureCuttingEntireSection( Proc.Box, dRawW, dRawH)
|
|
end
|
|
end
|
|
return bTailFinishingNeeded, nReplacedFeatureId
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- *** Inserimento delle travi nel grezzo ***
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function VerifyBigSectionCut( dRawW, dRawH)
|
|
-- lama principale
|
|
local sCutting = ML.FindCutting( 'TailSide')
|
|
local dMaxDepth = 50
|
|
if EgtMdbSetCurrMachining( sCutting or '') then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid or '') or '') then
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
end
|
|
local dMaxVertDepth = dMaxDepth - ( BD.DECR_VERT_CUT or 0)
|
|
-- eventuale lama su testa sotto
|
|
local sCutting2 = ML.FindCutting( 'TailSide_H2', false, true)
|
|
local dMaxDepth2 = 0
|
|
if sCutting2 and EgtMdbSetCurrMachining( sCutting2) then
|
|
local sTuuid2 = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid2) or '') then
|
|
dMaxDepth2 = EgtTdbGetCurrToolMaxDepth() or dMaxDepth2
|
|
end
|
|
end
|
|
-- verifiche
|
|
local dDimYRef = EgtIf( dRawH < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL, dMaxDepth, abs( BD.MAX_DIM_HTCUT_HBEAM))
|
|
local bBigSectionCut = ( dRawW > 2 * dDimYRef - BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL) and
|
|
( dRawH > EgtIf( BD.TURN, 2 * dMaxVertDepth, dMaxVertDepth + dMaxDepth2) - 2 * BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL)
|
|
return bBigSectionCut
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam, bMachGroupOk)
|
|
|
|
-- default per nuove costanti qualora non definite
|
|
BD.OVM_BLADE_HBEAM = ( BD.OVM_BLADE_HBEAM or 11)
|
|
BD.OVM_CHAIN_HBEAM = ( BD.OVM_CHAIN_HBEAM or 8)
|
|
|
|
-- Determinazione minimo grezzo scaricabile
|
|
BeamExec.CalcMinUnloadableRaw( dRawW, dRawH)
|
|
|
|
-- Creazione nuovo gruppo di lavoro
|
|
if not bMachGroupOk then
|
|
local sMgName = EgtGetMachGroupNewName( 'Mach_1')
|
|
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 TR/BR della tavola rispetto a sua origine in BL
|
|
BD.OriXR = Point3d( b3Tab:getDimX(), EgtIf( BD.RIGHT_LOAD, 0, b3Tab:getDimY()), 0)
|
|
BD.PosXR = EgtIf( BD.RIGHT_LOAD, MCH_CR.BR, MCH_CR.TR)
|
|
|
|
-- Impostazione dell'attrezzaggio di default
|
|
EgtImportSetup()
|
|
|
|
-- Inserimento dei pezzi con il loro grezzo
|
|
local Cnt = 0
|
|
local Len = dRawL
|
|
local nPrevRaw, dPrevDelta
|
|
local DeltaS = dOvmHead
|
|
local DeltaSMin = 0
|
|
local DeltaE = BD.OVM_MID
|
|
-- controllo sezione larga e alta per considerare taglio con sega a catena
|
|
local bBigSectionCut = VerifyBigSectionCut( dRawW, dRawH)
|
|
for i = 1, #vBeam do
|
|
-- assegno identificativo pezzo
|
|
local Pz = vBeam[i].Id
|
|
-- dati del pezzo
|
|
local b3Part = EgtGetBBoxGlob( Pz or GDB_ID.NULL, GDB_BB.EXACT)
|
|
local b3Solid = vBeam[i].Box
|
|
if b3Part:isEmpty() or b3Solid:isEmpty() then break end
|
|
if bBigSectionCut then
|
|
-- lascio in coda solo il materiale necessario; il resto verrà tolto nell'head cut successivo
|
|
local lastB3Solid = nil
|
|
local dOffset = dOvmHead
|
|
if i > 1 then
|
|
lastB3Solid = vBeam[i-1].Box
|
|
dOffset = vBeam[i].PosX - vBeam[i-1].PosX - lastB3Solid:getDimX()
|
|
end
|
|
-- analizzo le features per valutare l'esistenza di feature head/tail che renderebbero inutili le rispettive finiture o di tagli di testa/coda sostituiti da cui leggere il parametro Q05
|
|
local vProc = CollectFeatures( Pz, b3Solid, 0)
|
|
local bSFinishingNeeded, nReplacedHeadCutFeatureId = AnalyzeHeadFeatures( b3Solid, vProc, dRawW, dRawH)
|
|
local iSQ05Value = nil
|
|
if nReplacedHeadCutFeatureId then
|
|
iSQ05Value = EgtGetInfo( nReplacedHeadCutFeatureId, 'Q05', 'i')
|
|
end
|
|
if ( dOffset <= BD.OVM_CHAIN_HBEAM and iSQ05Value == 0) or not bSFinishingNeeded then
|
|
DeltaSMin = 0
|
|
else
|
|
DeltaSMin = BD.OVM_BLADE_HBEAM
|
|
end
|
|
local bEFinishingNeeded, nReplacedTailCutFeatureId = AnalyzeTailFeatures( b3Solid, vProc, dRawW, dRawH)
|
|
local iEQ05Value = nil
|
|
if nReplacedTailCutFeatureId then
|
|
iEQ05Value = EgtGetInfo( nReplacedTailCutFeatureId, 'Q05', 'i')
|
|
end
|
|
if iEQ05Value == 0 or not bEFinishingNeeded then
|
|
DeltaE = BD.OVM_CHAIN_HBEAM
|
|
else
|
|
DeltaE = BD.OVM_CHAIN_HBEAM + BD.OVM_BLADE_HBEAM
|
|
end
|
|
end
|
|
EgtOutLog( 'PartSez=' .. EgtNumToString( b3Part:getDimY(), 1) .. 'x' .. EgtNumToString( b3Part:getDimZ(), 1), 3)
|
|
-- se sezione compatibile e lunghezza disponibile sufficiente
|
|
local PartLen = b3Solid:getDimX()
|
|
local PartWidth = b3Solid:getDimY()
|
|
local PartHeight = b3Solid:getDimZ()
|
|
local NextLen = Len - DeltaS - PartLen - DeltaE
|
|
if (( abs( PartWidth - dRawW) < 100 * GEO.EPS_SMALL and abs( PartHeight - dRawH) < 100 * GEO.EPS_SMALL) or
|
|
( abs( PartHeight - dRawW) < 100 * GEO.EPS_SMALL and abs( PartWidth - dRawH) < 100 * GEO.EPS_SMALL)) and
|
|
NextLen + DeltaE >= 0 then
|
|
-- eventuale sovramateriale di testa
|
|
if i > 1 and vBeam[i].PosX then
|
|
DeltaS = max( vBeam[i].PosX - ( dRawL - Len), DeltaSMin)
|
|
end
|
|
-- dimensioni del grezzo
|
|
local CrawLen = min( PartLen + DeltaS + DeltaE, Len)
|
|
local Delta = CrawLen - PartLen - DeltaS
|
|
-- creo e posiziono il grezzo
|
|
local nRaw = EgtAddRawPart( Point3d(0,0,0), CrawLen, dRawW, dRawH, BD.RAWCOL)
|
|
EgtMoveToCornerRawPart( nRaw, BD.OriXR, BD.PosXR)
|
|
EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0))
|
|
-- assegno ordine in lavorazione
|
|
Cnt = Cnt + 1
|
|
EgtSetInfo( nRaw, 'ORD', Cnt)
|
|
-- creo o pulisco gruppo geometrie aggiuntive
|
|
if not BL.CreateOrEmptyAddGroup( Pz) then
|
|
local sOut = 'Error creating Additional Group in Part ' .. tostring( Pz)
|
|
return false, sOut
|
|
end
|
|
-- aggiungo faccia per taglio iniziale al pezzo
|
|
BL.AddPartStartFace( Pz, b3Solid)
|
|
-- se sovramateriale di testa, lo notifico
|
|
if DeltaS > 0.09 then
|
|
EgtSetInfo( nRaw, 'HOVM', DeltaS)
|
|
if nPrevRaw then
|
|
EgtSetInfo( nPrevRaw, 'BDST', DeltaS + dPrevDelta)
|
|
end
|
|
end
|
|
if DeltaE > 0.09 then
|
|
EgtSetInfo( nRaw, 'TOVM', DeltaE)
|
|
end
|
|
-- aggiungo faccia per taglio finale al pezzo
|
|
BL.AddPartEndFace( Pz, b3Solid)
|
|
-- inserisco il pezzo nel grezzo
|
|
EgtDeselectPartObjs( Pz)
|
|
local ptPos = b3Part:getMin() - b3Solid:getMin() + Vector3d( Delta, ( dRawW - PartWidth) / 2, ( dRawH - PartHeight) / 2)
|
|
EgtAddPartToRawPart( Pz, ptPos, nRaw)
|
|
if abs( PartWidth - dRawW) > 100 * GEO.EPS_SMALL then
|
|
-- rotazione attorno a centro geometria complessiva del pezzo
|
|
EgtRotatePartInRawPart( Pz, X_AX(), 90)
|
|
-- correggo per eccentricità solido rispetto a geometria complessiva del pezzo
|
|
local vtEccOri = b3Solid:getCenter() - b3Part:getCenter()
|
|
local vtEccRot = Vector3d( vtEccOri)
|
|
vtEccRot:rotate( X_AX(), 90)
|
|
EgtMovePartInRawPart( Pz, ( vtEccOri - vtEccRot))
|
|
end
|
|
-- aggiorno la lunghezza residua della barra
|
|
Len = Len - CrawLen
|
|
-- aggiorno grezzo precedente
|
|
nPrevRaw = nRaw
|
|
dPrevDelta = Delta
|
|
else
|
|
local sOut = 'Error: part L(' .. EgtNumToString( PartLen, 1) .. ') too big for raw part L(' .. EgtNumToString( Len - 0.1, 1) .. ')'
|
|
return false, sOut
|
|
end
|
|
-- se rimasto troppo poco grezzo, esco
|
|
--if Len < BD.MinRaw then break end
|
|
DeltaS = 0
|
|
end
|
|
if nPrevRaw then
|
|
EgtSetInfo( nPrevRaw, 'BDST', 10000)
|
|
end
|
|
|
|
-- Se rimasto materiale aggiungo grezzo dell'avanzo
|
|
if Len > 10 then
|
|
local nRaw = EgtAddRawPart( Point3d(0,0,0), Len, dRawW, dRawH, BD.RAWCOL)
|
|
EgtMoveToCornerRawPart( nRaw, BD.OriXR, BD.PosXR)
|
|
EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0))
|
|
-- assegno ordine in lavorazione
|
|
Cnt = Cnt + 1
|
|
EgtSetInfo( nRaw, 'ORD', Cnt)
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamExec.CalcMinUnloadableRaw( dRawW, dRawH)
|
|
if BD.GetMinUnloadableRaw then
|
|
BD.MinRaw = BD.GetMinUnloadableRaw( dRawW, dRawH)
|
|
else
|
|
local H_S = 200
|
|
local H_L = 400
|
|
-- Determinazione minimo grezzo scaricabile
|
|
if dRawH <= H_S then
|
|
BD.MinRaw = BD.MINRAW_S
|
|
elseif dRawH <= H_L then
|
|
local Coeff = ( dRawH - H_S) / ( H_L - H_S)
|
|
BD.MinRaw = ( 1 - Coeff) * BD.MINRAW_S + Coeff * BD.MINRAW_L
|
|
else
|
|
BD.MinRaw = BD.MINRAW_L
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- *** Inserimento delle lavorazioni nelle travi ***
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function Verify90DegRotation( nRawId)
|
|
if not nRawId then return false end
|
|
-- dimensioni sezione trave in posizione normale (rotazione 0°)
|
|
local dRawW = EgtGetRawPartBBox( nRawId):getDimY()
|
|
local dRawH = EgtGetRawPartBBox( nRawId):getDimZ()
|
|
-- verifica dell'altezza rispetto alla massima larghezza
|
|
if not BD.MAX_WIDTH2 or not BD.MAX_HEIGHT2 then
|
|
return ( dRawH < BD.MAX_WIDTH + 10 * GEO.EPS_SMALL and dRawW < BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL)
|
|
else
|
|
return ( dRawH < BD.MAX_WIDTH + 10 * GEO.EPS_SMALL and dRawW < BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) or
|
|
( dRawH < BD.MAX_WIDTH2 + 10 * GEO.EPS_SMALL and dRawW < BD.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL)
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function PrintFeatures( vProc, b3Raw)
|
|
EgtOutLog( ' RawBox=' .. tostring( b3Raw))
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
local sOut = string.format( ' Id=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Side=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s',
|
|
Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId,
|
|
Proc.Flg, EgtIf( Proc.Down, 'T', 'F'), EgtIf( Proc.Side, 'T', 'F'),
|
|
EgtIf( Proc.Head, 'T', 'F'), EgtIf( Proc.Tail, 'T', EgtIf( Proc.AdvTail, 'A', 'F')),
|
|
Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, tostring( Proc.Box))
|
|
-- info speciali per Block Haus Half Lap
|
|
if Proc.Prc == 37 then
|
|
local sSpec = string.format( ' N=%s Hd=%s', tostring( Proc.vtN or V_NULL()), EgtIf( Proc.HeadDir, 'T', 'F'))
|
|
sOut = sOut .. sSpec
|
|
end
|
|
EgtOutLog( sOut)
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function OrderFeatures( vProc, b3Raw)
|
|
|
|
local dDrillPenalty = EgtIf( BD.PRESS_ROLLER, 200, 100)
|
|
local dSmallDrillRange = EgtIf( b3Raw:getDimX() < BD.LEN_SHORT_PART, BD.DRILL_RANGE_SP or 200, BD.DRILL_RANGE or 600)
|
|
|
|
-- funzione di confronto
|
|
-- secondo centro box in X (taglio di intestazione prima di altri tagli di testa e taglio di separazione però prima di altri tagli di coda)
|
|
local function CompareFeatures( B1, B2)
|
|
-- se primo disabilitato e secondo no va dopo
|
|
if B1.Flg == 0 and B2.Flg ~= 0 then
|
|
return false
|
|
end
|
|
-- se secondo disabilitato e primo no va lasciato dopo
|
|
if B2.Flg == 0 and B1.Flg ~= 0 then
|
|
return true
|
|
end
|
|
-- se entrambi disabilitati seguo l'Id
|
|
if B1.Flg == 0 and B2.Flg == 0 then
|
|
return ( B1.Id < B2.Id)
|
|
end
|
|
-- se primo è intestazione va sempre prima
|
|
if Hcut.Identify( B1) then
|
|
return true
|
|
end
|
|
-- se l'altro è intestazione va sempre prima
|
|
if Hcut.Identify( B2) then
|
|
return false
|
|
end
|
|
-- se uno di testa e non l'altro, privilegio quello di testa
|
|
if B1.Head ~= B2.Head then
|
|
return B1.Head
|
|
end
|
|
-- se primo è foro e secondo è un ribasso, il foro va sempre prima
|
|
if Drill.Identify(B1) and LapJoint.Identify(B2) and
|
|
B1.Box:getCenter():getX() > B2.Box:getMin():getX() and B1.Box:getCenter():getX() < B2.Box:getMax():getX() then
|
|
return true
|
|
end
|
|
-- se primo è un ribasso e secondo è un foro, il ribasso va sempre dopo
|
|
if LapJoint.Identify(B1) and Drill.Identify(B2) and
|
|
B2.Box:getCenter():getX() > B1.Box:getMin():getX() and B2.Box:getCenter():getX() < B1.Box:getMax():getX() then
|
|
return false
|
|
end
|
|
-- se entrambi tenoni e si intersecano, metto prima tenone vero e poi base tenone
|
|
if ( Tenon.Identify( B1) or DtTenon.Identify( B1)) and ( Tenon.Identify( B2) or DtTenon.Identify( B2)) and
|
|
B1.Box:getMin():getX() < B2.Box:getMax():getX() + 100 * GEO.EPS_SMALL and B2.Box:getMin():getX() < B1.Box:getMax():getX() + 100 * GEO.EPS_SMALL then
|
|
return ( ( B1.Prc == 50 or B1.Prc == 55) and B2.Prc == 52)
|
|
end
|
|
-- se primo house mortise, secondo mortise e si intersecano, metto prima house mortise
|
|
if Mortise.Identify( B1) and B1.Prc == 53 and ( Mortise.Identify( B2) or DtMortise.Identify( B2)) and B2.Prc ~= 53 and
|
|
B1.Box:getMin():getX() < B2.Box:getMax():getX() + 100 * GEO.EPS_SMALL and B2.Box:getMin():getX() < B1.Box:getMax():getX() + 100 * GEO.EPS_SMALL then
|
|
return true
|
|
end
|
|
-- se primo mortise, secondo house mortise e si intersecano, metto prima house mortise
|
|
if ( Mortise.Identify( B1) or DtMortise.Identify( B1)) and B1.Prc ~= 53 and Mortise.Identify( B2) and B2.Prc == 53 and
|
|
B1.Box:getMin():getX() < B2.Box:getMax():getX() + 100 * GEO.EPS_SMALL and B2.Box:getMin():getX() < B1.Box:getMax():getX() + 100 * GEO.EPS_SMALL then
|
|
return false
|
|
end
|
|
-- se entrambi di testa e primo è scasso o mortasa e secondo no va messo dopo
|
|
if B1.Head and B2.Head and ( LapJoint.Identify( B1) or Mortise.Identify( B1) or DtMortise.Identify( B1)) and
|
|
not ( LapJoint.Identify( B2) or Mortise.Identify( B2) or DtMortise.Identify( B2)) then
|
|
return false
|
|
end
|
|
-- se entrambi di testa e secondo è scasso o mortasa e primo no va lasciato dopo
|
|
if B1.Head and B2.Head and ( LapJoint.Identify( B2) or Mortise.Identify( B2) or DtMortise.Identify( B2)) and
|
|
not ( LapJoint.Identify( B1) or Mortise.Identify( B1) or DtMortise.Identify( B1)) then
|
|
return true
|
|
end
|
|
-- se primo è feature di coda e l'altro è separazione o non è feature di coda
|
|
if B1.Tail and ( Split.Identify( B2) or not B2.Tail) then
|
|
return false
|
|
end
|
|
-- se secondo è feature di coda e l'altro è separazione o non è feature di coda
|
|
if B2.Tail and ( Split.Identify( B1) or not B1.Tail) then
|
|
return true
|
|
end
|
|
-- se primo è feature di coda anticipata e l'altro non è feature di coda
|
|
if B1.AdvTail and ( not Split.Identify( B2) or not B2.Tail) then
|
|
return false
|
|
end
|
|
-- se secondo è feature di coda anticipata e l'altro non è feature di coda
|
|
if B2.AdvTail and ( not Split.Identify( B1) or not B1.Tail) then
|
|
return true
|
|
end
|
|
-- se primo è scasso o mortasa di coda e secondo no, sempre dopo
|
|
if B1.Tail and ( LapJoint.Identify( B1) or Mortise.Identify( B1) or DtMortise.Identify( B1)) and
|
|
not ( B2.Tail and ( LapJoint.Identify( B2) or Mortise.Identify( B2) or DtMortise.Identify( B2))) then
|
|
return false
|
|
end
|
|
-- se secondo è scasso o mortasa di coda e primo no, va lasciato dopo
|
|
if B2.Tail and ( LapJoint.Identify( B2) or Mortise.Identify( B2) or DtMortise.Identify( B2)) and
|
|
not ( B1.Tail and ( LapJoint.Identify( B1) or Mortise.Identify( B1) or DtMortise.Identify( B1))) then
|
|
return true
|
|
end
|
|
-- se primo è taglio longitudinale completo o altra lav. lunga, dopo tutte le altre feature non di coda
|
|
if abs( B1.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then
|
|
-- se anche l'altra è lunga, faccio prima quello piccolo in YZ
|
|
if abs( B2.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then
|
|
if abs( B1.Box:getDimY() * B1.Box:getDimZ() - B2.Box:getDimY() * B2.Box:getDimZ()) < 10 then
|
|
return B1.Id < B2.Id
|
|
else
|
|
return B1.Box:getDimY() * B1.Box:getDimZ() < B2.Box:getDimY() * B2.Box:getDimZ()
|
|
end
|
|
else
|
|
return B2.Tail or B1.Box:getMin():getX() + 20 > B2.Box:getCenter():getX()
|
|
end
|
|
end
|
|
-- se secondo è taglio longitudinale completo o altra lav. lunga, dopo tutte le altre feature non di coda
|
|
if abs( B2.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then
|
|
return not ( B1.Tail or B2.Box:getMin():getX() + 20 > B1.Box:getCenter():getX())
|
|
end
|
|
-- se primo è foro e l'altro no, lo penalizzo
|
|
if B1.Prc == 40 and B2.Prc ~= 40 then
|
|
return ( B1.Box:getCenter():getX() > B2.Box:getMax():getX() + dDrillPenalty)
|
|
end
|
|
-- se primo è altro e secondo è foro, lo premio
|
|
if B1.Prc ~= 40 and B2.Prc == 40 then
|
|
return ( B1.Box:getMax():getX() + dDrillPenalty > B2.Box:getCenter():getX())
|
|
end
|
|
-- se entrambi fori con posizione praticamente uguale ordino secondo diametro e faccia di inizio (Fcs)
|
|
if B1.Prc == 40 and B2.Prc == 40 and abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) < dSmallDrillRange then
|
|
if abs( B1.Diam - B2.Diam) < 1.0 then
|
|
if B1.Fcs == B2.Fcs then
|
|
if abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) < 1.0 then
|
|
if abs( B1.Box:getCenter():getY() - B2.Box:getCenter():getY()) < 1.0 then
|
|
if abs( B1.Box:getCenter():getZ() - B2.Box:getCenter():getZ()) < 1.0 then
|
|
return ( B1.Id < B2.Id)
|
|
else
|
|
return ( B1.Box:getCenter():getZ() > B2.Box:getCenter():getZ())
|
|
end
|
|
else
|
|
return ( B1.Box:getCenter():getY() > B2.Box:getCenter():getY())
|
|
end
|
|
else
|
|
return ( B1.Box:getCenter():getX() > B2.Box:getCenter():getX())
|
|
end
|
|
else
|
|
return ( B1.Fcs > B2.Fcs)
|
|
end
|
|
else
|
|
return ( B1.Diam > B2.Diam)
|
|
end
|
|
end
|
|
-- confronto standard
|
|
if abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) > 0.4 * ( B1.Box:getDimX() + B2.Box:getDimX()) then
|
|
return B1.Box:getCenter():getX() > B2.Box:getCenter():getX()
|
|
elseif abs( B1.Box:getCenter():getY() - B2.Box:getCenter():getY()) > 0.2 * ( B1.Box:getDimY() + B2.Box:getDimY()) then
|
|
return B1.Box:getCenter():getY() > B2.Box:getCenter():getY()
|
|
elseif abs( B1.Box:getCenter():getZ() - B2.Box:getCenter():getZ()) > 0.1 * ( B1.Box:getDimZ() + B2.Box:getDimZ()) then
|
|
return B1.Box:getCenter():getZ() > B2.Box:getCenter():getZ()
|
|
else
|
|
return ( B1.Id < B2.Id)
|
|
end
|
|
end
|
|
|
|
-- test della funzione di ordinamento
|
|
if EgtGetDebugLevel() >= 3 then
|
|
EgtOutLog( ' CompareFeatures Test ')
|
|
local bCompTest = true
|
|
for i = 1, #vProc do
|
|
for j = i + 1, #vProc do
|
|
local bComp1 = CompareFeatures( vProc[i], vProc[j])
|
|
local bComp2 = CompareFeatures( vProc[j], vProc[i])
|
|
if bComp1 == bComp2 then
|
|
bCompTest = false
|
|
EgtOutLog( string.format( ' ProcId : %d vs %d --> ERROR', vProc[i].Id, vProc[j].Id))
|
|
end
|
|
end
|
|
end
|
|
if bCompTest then
|
|
EgtOutLog( ' ALL OK')
|
|
end
|
|
end
|
|
|
|
-- eseguo ordinamento
|
|
table.sort( vProc, CompareFeatures)
|
|
|
|
-- riunisco fori con lo stesso diametro e non troppo lontani
|
|
local dDrillRange = dSmallDrillRange
|
|
if BD.GO_FAST == 2 then
|
|
dDrillRange = 6000
|
|
elseif BD.PRESS_ROLLER then
|
|
dDrillRange = 2000
|
|
end
|
|
for i = 1, #vProc do
|
|
local ProcI = vProc[i]
|
|
if ProcI.Prc == 40 and
|
|
ProcI.Box and not ProcI.Box:isEmpty() then
|
|
for j = i + 1, #vProc do
|
|
local ProcJ = vProc[j]
|
|
if ProcJ.Prc == 40 and
|
|
ProcJ.Box and not ProcJ.Box:isEmpty() and
|
|
ProcJ.Head == ProcI.Head and ProcJ.Tail == ProcI.Tail and
|
|
abs( ProcJ.Diam - ProcI.Diam) < 1.0 and abs( ProcJ.Box:getCenter():getX() - ProcI.Box:getCenter():getX()) < dDrillRange then
|
|
if j > i + 1 then
|
|
local ProcK = vProc[i+1]
|
|
if ProcK.Prc ~= 40 or abs( ProcK.Diam - ProcJ.Diam) > 1.0 then
|
|
table.insert( vProc, i + 1, table.remove( vProc, j))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- riunisco fori da fare in doppio
|
|
local i = 1
|
|
while i < #vProc do
|
|
local ProcI = vProc[i]
|
|
if ProcI.Prc == 40 then
|
|
local DouId = EgtGetInfo( ProcI.Id, 'DOU', 'i')
|
|
if DouId then
|
|
for j = i + 1, #vProc do
|
|
if vProc[j].Id == DouId then
|
|
table.insert( vProc, i, table.remove( vProc, j))
|
|
i = i + 1
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
i = i + 1
|
|
end
|
|
-- riunisco marcature, testi e decori non troppo lontani
|
|
local dMarkRange = 300
|
|
for i = 1, #vProc do
|
|
local ProcI = vProc[i]
|
|
if ( ProcI.Prc == 60 or ProcI.Prc == 61 or ProcI.Prc == 959) and
|
|
ProcI.Box and not ProcI.Box:isEmpty() then
|
|
for j = i + 1, #vProc do
|
|
local ProcJ = vProc[j]
|
|
if ( ProcJ.Prc == 60 or ProcJ.Prc == 61 or ProcJ.Prc == 959) and
|
|
ProcJ.Box and not ProcJ.Box:isEmpty() and
|
|
ProcJ.Head == ProcI.Head and ProcJ.Tail == ProcI.Tail and
|
|
abs( ProcJ.Box:getCenter():getX() - ProcI.Box:getCenter():getX()) < dMarkRange then
|
|
if j > i + 1 then
|
|
table.insert( vProc, i + 1, table.remove( vProc, j))
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- ordino BlockHaus HalfLap vicini (davanti, sotto, dietro, sopra)
|
|
local dBHHLRange = 100
|
|
for i = 1, #vProc do
|
|
local ProcI = vProc[i]
|
|
if ProcI.Prc == 37 and
|
|
ProcI.Box and not ProcI.Box:isEmpty() then
|
|
for j = i + 1, #vProc do
|
|
local ProcJ = vProc[j]
|
|
if ProcJ.Prc == 37 and
|
|
ProcJ.Box and not ProcJ.Box:isEmpty() and
|
|
abs( ProcI.Box:getCenter():getX() - ProcJ.Box:getCenter():getX()) < dBHHLRange then
|
|
if ProcI.HeadDir then
|
|
if ProcJ.vtN:getY() < -0.5 then
|
|
table.insert( vProc, i, table.remove( vProc, j))
|
|
break
|
|
elseif ProcJ.vtN:getZ() < -0.5 and ProcI.vtN:getY() > -0.5 then
|
|
table.insert( vProc, i, table.remove( vProc, j))
|
|
ProcI = vProc[i]
|
|
elseif ProcJ.vtN:getY() > 0.5 and ProcI.vtN:getY() > -0.5 and ProcI.vtN:getZ() > -0.5 then
|
|
table.insert( vProc, i, table.remove( vProc, j))
|
|
ProcI = vProc[i]
|
|
end
|
|
else
|
|
if ProcJ.vtN:getY() > 0.5 then
|
|
table.insert( vProc, i, table.remove( vProc, j))
|
|
break
|
|
elseif ProcJ.vtN:getZ() < -0.5 and ProcI.vtN:getY() < 0.5 then
|
|
table.insert( vProc, i, table.remove( vProc, j))
|
|
ProcI = vProc[i]
|
|
elseif ProcJ.vtN:getY() < -0.5 and ProcI.vtN:getY() < 0.5 and ProcI.vtN:getZ() > -0.5 then
|
|
table.insert( vProc, i, table.remove( vProc, j))
|
|
ProcI = vProc[i]
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function ClassifyFeatures( vProc, b3Raw, Stats)
|
|
local bAllOk = true
|
|
local bSomeDown = false
|
|
local bSomeSide = false
|
|
local bSplitRot = false
|
|
local nHeading
|
|
local nSplitting
|
|
local vMachineBeforeIntersectingDrillingsId = {}
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
local bOk = true
|
|
local bDown = false
|
|
local bSide = false
|
|
local bDownSideOnHeadOk = false
|
|
|
|
if Proc.MachineBeforeIntersectingDrillings then
|
|
table.Insert ( vMachineBeforeIntersectingDrillingsId, Proc.Id)
|
|
end
|
|
|
|
-- se senza geometria (già disabilitato
|
|
if Proc.Flg == 0 then
|
|
bOk = false
|
|
-- se intestatura
|
|
elseif Hcut.Identify( Proc) then
|
|
nHeading = i
|
|
-- se separazione
|
|
elseif Split.Identify( Proc) then
|
|
nSplitting = i
|
|
-- se taglio
|
|
elseif Cut.Identify( Proc) then
|
|
bOk, bDown = Cut.Classify( Proc, b3Raw)
|
|
-- se doppio taglio
|
|
elseif DoubleCut.Identify( Proc) then
|
|
bOk, bDown = DoubleCut.Classify( Proc, b3Raw)
|
|
-- se taglio longitudinale
|
|
elseif LongCut.Identify( Proc) then
|
|
bOk, bDown = LongCut.Classify( Proc)
|
|
-- se doppio taglio longitudinale
|
|
elseif Long2Cut.Identify( Proc) then
|
|
-- se due facce longitudinali, classifico doppio taglio longitudinale
|
|
if Long2Cut.GetLongFacesCount( Proc) == 2 then
|
|
bOk, bDown = Long2Cut.Classify( Proc)
|
|
-- altrimenti eseguo singolo taglio longitudinale
|
|
else
|
|
bOk, bDown = LongCut.Classify( Proc)
|
|
end
|
|
-- se taglio con lama
|
|
elseif SawCut.Identify( Proc) then
|
|
bOk, bDown = SawCut.Classify( Proc)
|
|
-- se mezzo-legno di testa
|
|
elseif RidgeLap.Identify( Proc) then
|
|
bOk, bDown = RidgeLap.Classify( Proc, b3Raw)
|
|
-- se scanalatura, scanalatura frontale, tacca, tacca cantonale, mezzo-legno, scanalatura-battuta,
|
|
-- mezzolegno tipo chalet-tavola di chiusura, rivestimento, mezzolegno chalet, tasca, taglio triangolato
|
|
elseif LapJoint.Identify( Proc) then
|
|
bOk, bDown = LapJoint.Classify( Proc, b3Raw)
|
|
-- se foratura
|
|
elseif Drill.Identify( Proc) then
|
|
bOk, bDown, bSide = Drill.Classify( Proc, b3Raw)
|
|
bDownSideOnHeadOk = true
|
|
-- se tenone
|
|
elseif Tenon.Identify( Proc) then
|
|
bOk, bDown = Tenon.Classify( Proc, b3Raw)
|
|
-- se giunzione francese
|
|
elseif FrenchRidgeLap.Identify( Proc) then
|
|
bOk, bDown = FrenchRidgeLap.Classify( Proc)
|
|
-- se block house front
|
|
elseif BlockHausFront.Identify( Proc) then
|
|
bOk, bDown = BlockHausFront.Classify( Proc)
|
|
-- se mortasa (anche frontale)
|
|
elseif Mortise.Identify( Proc) then
|
|
bOk, bDown = Mortise.Classify( Proc)
|
|
-- se tenone a coda di rondine
|
|
elseif DtTenon.Identify( Proc) then
|
|
bOk, bDown = DtTenon.Classify( Proc, b3Raw)
|
|
-- se mortasa a coda di rondine (anche frontale)
|
|
elseif DtMortise.Identify( Proc) then
|
|
bOk, bDown = DtMortise.Classify( Proc)
|
|
-- se marcatura
|
|
elseif Mark.Identify( Proc) then
|
|
bOk, bDown = Mark.Classify( Proc)
|
|
-- se testo
|
|
elseif Text.Identify( Proc) then
|
|
bOk, bDown = Text.Classify( Proc)
|
|
-- se giunto Gerber
|
|
elseif ScarfJoint.Identify( Proc) then
|
|
bOk, bDown = ScarfJoint.Classify( Proc)
|
|
-- se giunto Gerber
|
|
elseif Scarf.Identify( Proc) then
|
|
bOk, bDown = Scarf.Classify( Proc)
|
|
-- se giunto a gradino
|
|
elseif StepJoint.Identify( Proc) then
|
|
bOk, bDown = StepJoint.Classify( Proc)
|
|
-- se tacca a gradino
|
|
elseif StJoNotch.Identify( Proc) then
|
|
bOk, bDown = StJoNotch.Classify( Proc)
|
|
-- se arco
|
|
elseif RoundArch.Identify( Proc) then
|
|
bOk, bDown = RoundArch.Classify( Proc)
|
|
-- se incastro tirolo
|
|
elseif TyroleanDovetail.Identify( Proc) then
|
|
bOk, bDown = TyroleanDovetail.Classify( Proc, b3Raw)
|
|
-- se giunto coda di rondine
|
|
elseif Dovetail.Identify( Proc) then
|
|
bOk, bDown = Dovetail.Classify( Proc, b3Raw)
|
|
-- se profilo front
|
|
elseif ProfFront.Identify( Proc) then
|
|
bOk, bDown, bSide = ProfFront.Classify( Proc, b3Raw)
|
|
-- se profilo concavo
|
|
elseif ProfConcave.Identify( Proc) then
|
|
bOk, bDown, bSide = ProfConcave.Classify( Proc, b3Raw)
|
|
-- se profilo convesso
|
|
elseif ProfConvex.Identify( Proc) then
|
|
bOk, bDown, bSide = ProfConvex.Classify( Proc, b3Raw)
|
|
-- se profilo caudato
|
|
elseif ProfCamb.Identify( Proc) then
|
|
bOk, bDown, bSide = ProfCamb.Classify( Proc, b3Raw)
|
|
-- se profilo head
|
|
elseif ProfHead.Identify( Proc) then
|
|
bOk, bDown, bSide = ProfHead.Classify( Proc, b3Raw)
|
|
-- se contorno libero
|
|
elseif FreeContour.Identify( Proc) then
|
|
bOk, bDown, bSide = FreeContour.Classify( Proc, b3Raw)
|
|
-- se decorazione
|
|
elseif Decor.Identify( Proc) then
|
|
bOk, bDown = Decor.Classify( Proc)
|
|
end
|
|
-- assegno risultato
|
|
if bOk then
|
|
-- non ammessa feature di testa da lavorare ribaltata o ruotata
|
|
if Proc.Head and ( bDown or bSide) and not bDownSideOnHeadOk then
|
|
Proc.Flg = 0
|
|
Proc.Down = true
|
|
bAllOk = false
|
|
table.insert( Stats, {Err = 1, Msg='Error : impossible to machine by orientation', CutId=Proc.CutId, TaskId=Proc.TaskId})
|
|
-- gestione feature di coda da lavorare ribaltata
|
|
elseif Proc.Tail and bDown then
|
|
Proc.Down = true
|
|
bSomeDown = true
|
|
bSplitRot = true
|
|
-- gestione feature di coda da lavorare ruotata
|
|
elseif Proc.Tail and bSide then
|
|
Proc.Side = true
|
|
bSomeSide = true
|
|
bSplitRot = true
|
|
-- caso normale
|
|
else
|
|
Proc.Down = bDown
|
|
Proc.Side = bSide
|
|
if bDown then bSomeDown = true end
|
|
if bSide then bSomeSide = true end
|
|
end
|
|
elseif Proc.Flg == 0 then
|
|
bAllOk = false
|
|
Proc.ErrMsg = 'Error : out of the part'
|
|
table.insert( Stats, {Err = 1, Msg=Proc.ErrMsg, CutId=Proc.CutId, TaskId=Proc.TaskId})
|
|
else
|
|
Proc.Flg = 0
|
|
bAllOk = false
|
|
if not Proc.ErrMsg then Proc.ErrMsg = 'Error : impossible to machine' end
|
|
table.insert( Stats, {Err = 1, Msg=Proc.ErrMsg, CutId=Proc.CutId, TaskId=Proc.TaskId})
|
|
end
|
|
end
|
|
-- se necessario ribaltamento, assegno intestatura alla fase ribaltata
|
|
if bSomeDown and nHeading then
|
|
vProc[nHeading].Down = true
|
|
-- se altrimenti necessaria rotazione (senza ribaltamento), assegno intestatura alla fase ribaltata (creata ad hoc)
|
|
elseif bSomeSide and nHeading then
|
|
vProc[nHeading].Down = true
|
|
bSomeDown = true
|
|
end
|
|
-- se necessaria separazione del ribaltato o ruotato, la assegno sempre alla fase ribaltata
|
|
if bSplitRot and nSplitting then
|
|
vProc[nSplitting].Down = true
|
|
bSomeDown = true
|
|
end
|
|
return bAllOk, bSomeDown, bSomeSide, bSplitRot
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut, b3Raw, nOrd, sDownOrSideOrStd, bPreMove, vtMove, dCurrOvmT)
|
|
local bOk = true
|
|
local sErr = ''
|
|
local nNewPhase = -1
|
|
EgtOutLog( ' * Process ' .. tostring( Proc.Id) .. ' *', 1)
|
|
-- se intestatura ( 1-340-X )
|
|
if Hcut.Identify( Proc) then
|
|
-- esecuzione taglio di testa
|
|
bOk, sErr = Hcut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut)
|
|
-- se separazione ( 2-350-X )
|
|
elseif Split.Identify( Proc) then
|
|
-- esecuzione separazione o eliminazione grezzo residuo
|
|
bOk, sErr, nNewPhase = Split.Make( Proc, nPhase, nRawId, nPartId, nOrd, sDownOrSideOrStd, bPreMove, vtMove, dCurrOvmT)
|
|
-- se taglio ( 1/2-010-X)
|
|
elseif Cut.Identify( Proc) then
|
|
-- esecuzione taglio
|
|
bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH, nil, nil, nil, nil, nil, dCurrOvmT)
|
|
-- se doppio taglio ( 1/2-011-X)
|
|
elseif DoubleCut.Identify( Proc) then
|
|
-- esecuzione doppio taglio
|
|
bOk, sErr = DoubleCut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se taglio longitudinale ( 0/3/4-010-X)
|
|
elseif LongCut.Identify( Proc) then
|
|
-- esecuzione taglio longitudinale
|
|
bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId)
|
|
-- se doppio taglio longitudinale ( 0-012-X)
|
|
elseif Long2Cut.Identify( Proc) then
|
|
-- se due facce longitudinali, eseguo doppio taglio longitudinale
|
|
if Long2Cut.GetLongFacesCount( Proc) == 2 then
|
|
bOk, sErr = Long2Cut.Make( Proc, nPhase, nRawId, nPartId)
|
|
-- altrimenti eseguo singolo taglio longitudinale
|
|
else
|
|
bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId)
|
|
end
|
|
-- se taglio con lama ( 0/3/4-013-X)
|
|
elseif SawCut.Identify( Proc) then
|
|
-- esecuzione taglio
|
|
bOk, sErr = SawCut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH, dCurrOvmT)
|
|
-- se mezzo-legno di testa ( 1/2-030-X)
|
|
elseif RidgeLap.Identify( Proc) then
|
|
-- esecuzione mezzo-legno di testa
|
|
bOk, sErr = RidgeLap.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se fessura ( 3/4-016-X) o se fessura frontale ( 3/4-017-X) o se tacca ( 3/4-020-X) o se tacca cantonale ( 3/4-025-X)
|
|
-- o se mezzo-legno ( 3/4-030-X) o se scanalatura/battuta ( 3/4-032-X) o se mezzo legno tipo chalet/tavola di chiusura ( 3/4-033-X)
|
|
-- o se rivestimento ( 3/4-034-X) o se mezzolegno chalet ( 4-037-X) o se tasca ( 4-039-X) o se taglio triangolato ( 4-120-X)
|
|
elseif LapJoint.Identify( Proc) then
|
|
-- esecuzione mezzo-legno o scanalatura
|
|
bOk, sErr = LapJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se smusso ( 3/4-036-X)
|
|
elseif Chamfer.Identify( Proc) then
|
|
-- esecuzione smusso
|
|
bOk, sErr = Chamfer.Make( Proc, nPhase, nRawId, nPartId)
|
|
-- se foratura ( 3/4-040-X)
|
|
elseif Drill.Identify( Proc) then
|
|
-- esecuzione foratura
|
|
bOk, sErr = Drill.Make( Proc, nPhase, nRawId, nPartId)
|
|
-- se giunzione francese ( 1/2-035-X)
|
|
elseif FrenchRidgeLap.Identify( Proc) then
|
|
-- esecuzione giunzione francese
|
|
bOk, sErr = FrenchRidgeLap.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH, dCurrOvmT)
|
|
-- se block house front ( 3/4-038-X)
|
|
elseif BlockHausFront.Identify( Proc) then
|
|
-- esecuzione giunzione francese
|
|
bOk, sErr = BlockHausFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH, dCurrOvmT)
|
|
-- se tenone ( 1/2-050-X)
|
|
elseif Tenon.Identify( Proc) then
|
|
-- esecuzione tenone
|
|
bOk, sErr = Tenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se mortasa ( 3/4-050-X) anche frontale ( 3/4-051-X)
|
|
elseif Mortise.Identify( Proc) then
|
|
-- esecuzione mortasa
|
|
bOk, sErr = Mortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se tenone a coda di rondine ( 1/2-055-X)
|
|
elseif DtTenon.Identify( Proc) then
|
|
-- esecuzione tenone
|
|
bOk, sErr = DtTenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se mortasa a coda di rondine ( 3/4-055-X) anche frontale ( 3/4-056-X)
|
|
elseif DtMortise.Identify( Proc) then
|
|
-- esecuzione mortasa
|
|
bOk, sErr = DtMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se marcatura ( 3/4-060-X)
|
|
elseif Mark.Identify( Proc) then
|
|
-- esecuzione marcatura
|
|
bOk, sErr = Mark.Make( Proc, nPhase, nRawId, nPartId)
|
|
-- se testo ( 4-061-X)
|
|
elseif Text.Identify( Proc) then
|
|
-- esecuzione testo
|
|
bOk, sErr = Text.Make( Proc, nPhase, nRawId, nPartId)
|
|
-- se giunto Gerber ( 1/2-071-X)
|
|
elseif ScarfJoint.Identify( Proc) then
|
|
-- esecuzione giunto Gerber
|
|
bOk, sErr = ScarfJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH, dCurrOvmT)
|
|
-- se giunto Gerber ( 1/2-070-X)
|
|
elseif Scarf.Identify( Proc) then
|
|
-- esecuzione giunto Gerber
|
|
bOk, sErr = Scarf.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH, dCurrOvmT)
|
|
-- se giunto a gradino ( 1/2-080-X)
|
|
elseif StepJoint.Identify( Proc) then
|
|
-- esecuzione giunto a gradino
|
|
bOk, sErr = StepJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se tacca a gradino ( 3/4-080-X)
|
|
elseif StJoNotch.Identify( Proc) then
|
|
-- esecuzione tacca a gradino
|
|
bOk, sErr = StJoNotch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se profilo Front ( 3/4-100-X)
|
|
elseif ProfFront.Identify( Proc) then
|
|
-- esecuzione profilo
|
|
bOk, sErr = ProfFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se profilo concavo ( 3/4-101-X)
|
|
elseif ProfConcave.Identify( Proc) then
|
|
-- esecuzione profilo
|
|
bOk, sErr = ProfConcave.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se profilo convesso ( 3/4-102-X)
|
|
elseif ProfConvex.Identify( Proc) then
|
|
-- esecuzione profilo
|
|
bOk, sErr = ProfConvex.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se profilo caudato ( 3/4-103-X)
|
|
elseif ProfCamb.Identify( Proc) then
|
|
-- esecuzione profilo
|
|
bOk, sErr = ProfCamb.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se arco ( 4-104-X)
|
|
elseif RoundArch.Identify( Proc) then
|
|
-- esecuzione arco
|
|
bOk, sErr = RoundArch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se profilo Head ( 3/4-106-X)
|
|
elseif ProfHead.Identify( Proc) then
|
|
-- esecuzione profilo
|
|
bOk, sErr = ProfHead.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se incastro tirolo ( 1/2/3/4-136-X)
|
|
elseif TyroleanDovetail.Identify( Proc) then
|
|
bOk, sErr = TyroleanDovetail.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH, dCurrOvmT)
|
|
-- se giunto coda di rondine ( 1/2/3/4-138-X)
|
|
elseif Dovetail.Identify( Proc) then
|
|
bOk, sErr = Dovetail.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH, dCurrOvmT)
|
|
-- se contorno libero ( 0/3/4-250-X)
|
|
elseif FreeContour.Identify( Proc) then
|
|
-- esecuzione contorno
|
|
bOk, sErr = FreeContour.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
|
|
-- se decorazione ( 0/3/4-959-X)
|
|
elseif Decor.Identify( Proc) then
|
|
-- esecuzione decorazione
|
|
bOk, sErr = Decor.Make( Proc, nPhase, nRawId, nPartId)
|
|
-- altrimenti feature sconosciuta
|
|
else
|
|
sErr = 'Error on process ' .. tostring( Proc.Id) .. ' unknown type (' .. tonumber( Proc.Grp) .. '-' .. tonumber( Proc.Prc) .. ')'
|
|
EgtOutLog( sErr)
|
|
bOk = false
|
|
end
|
|
return bOk, sErr, ( nNewPhase or -1)
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function VerifyNeedForHeadCut( vProc, bSomeDown, bSomeSide)
|
|
-- verifico se necessaria la rotazione di 90 gradi
|
|
if not bSomeSide then
|
|
return false
|
|
end
|
|
-- verifico se viene dopo un pezzo diviso quando ruotato (quindi con rimanenza scaricata sul carico)
|
|
local nPrevPhase = EgtGetCurrPhase() - 1
|
|
local nPrevDispId = EgtGetPhaseDisposition( nPrevPhase) or GDB_ID.NULL
|
|
local nPrevType = EgtGetInfo( nPrevDispId, 'TYPE')
|
|
if nPrevType ~= 'MID2' and nPrevType ~= 'END2' then
|
|
return false
|
|
end
|
|
-- verifico se c'è una sola lavorazione ribaltata (quindi è il taglio di testa)
|
|
local nDownCnt = 0
|
|
for i = 1, #vProc do
|
|
if vProc[i].Down then
|
|
nDownCnt = nDownCnt + 1
|
|
end
|
|
end
|
|
return ( nDownCnt == 1)
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function SetCutsOnFrontMortises( vProc)
|
|
-- ciclo sulle feature
|
|
for i = 1, #vProc do
|
|
if vProc[i].Fct > 0 and Cut.Identify( vProc[i]) then
|
|
for j = 1, #vProc do
|
|
if vProc[j].Fct > 0 and Mortise.FrontIdentify( vProc[j]) then
|
|
-- se esiste intersezione tra le due features
|
|
if vProc[i].Box:getMin():getX() < vProc[j].Box:getMax():getX() + 100 * GEO.EPS_SMALL and
|
|
vProc[j].Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL then
|
|
-- recupero il piano del taglio
|
|
local ptC1, vtN1 = Cut.GetCutPlane( vProc[i])
|
|
-- recupero il piano frontale della mortasa
|
|
local ptC2, vtN2 = Mortise.GetCutPlane( vProc[j])
|
|
-- verifico se i piani coincidono
|
|
local bSamePlane = ( ptC1 and vtN1 and ptC2 and vtN2 and AreSameVectorApprox( vtN1, vtN2) and ( ptC2 - ptC1) * vtN1 < 1.0)
|
|
if bSamePlane then
|
|
vProc[i].CutFront = vProc[j].Id
|
|
end
|
|
-- log
|
|
local sMsg = string.format( 'Cut %d meet Mortise %d', vProc[i].Id, vProc[j].Id) .. EgtIf( bSamePlane, ' with same plane', '')
|
|
EgtOutLog( sMsg, 3)
|
|
end
|
|
elseif vProc[j].Fct > 0 and DtMortise.FrontIdentify( vProc[j]) then
|
|
-- se esiste intersezione tra le due features
|
|
if vProc[i].Box:getMin():getX() < vProc[j].Box:getMax():getX() + 100 * GEO.EPS_SMALL and
|
|
vProc[j].Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL then
|
|
-- recupero il piano del taglio
|
|
local ptC1, vtN1 = Cut.GetCutPlane( vProc[i])
|
|
-- recupero il piano frontale della mortasa
|
|
local ptC2, vtN2 = DtMortise.GetCutPlane( vProc[j])
|
|
-- verifico se i piani coincidono
|
|
local bSamePlane = ( ptC1 and vtN1 and ptC2 and vtN2 and AreSameVectorApprox( vtN1, vtN2) and ( ptC2 - ptC1) * vtN1 < 1.0)
|
|
if bSamePlane then
|
|
vProc[i].CutFront = vProc[j].Id
|
|
end
|
|
-- log
|
|
local sMsg = string.format( 'Cut %d meet DtMortise %d', vProc[i].Id, vProc[j].Id) .. EgtIf( bSamePlane, ' with same plane', '')
|
|
EgtOutLog( sMsg, 3)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function MoveDrillsOnTenon( vProc)
|
|
-- se non richiesto spostamento fori su tenone, esco
|
|
if not BD.OFFSET_DRILL_TENON or abs( BD.OFFSET_DRILL_TENON) < 0.1 then return end
|
|
-- ciclo sulle feature
|
|
for i = 1, #vProc do
|
|
if vProc[i].Flg ~= 0 and Tenon.Identify( vProc[i]) then
|
|
for j = 1, #vProc do
|
|
if Drill.Identify( vProc[j]) then
|
|
-- se esiste intersezione tra tenone e foro
|
|
if vProc[i].Box:getMin():getX() < vProc[j].Box:getMax():getX() + 100 * GEO.EPS_SMALL and
|
|
vProc[j].Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL then
|
|
-- verifico se foro già spostato
|
|
if not EgtExistsInfo( vProc[j].Id, 'MOV') then
|
|
-- recupero curva ausiliaria del foro
|
|
local AuxDriId = EgtGetInfo( vProc[j].Id, 'AUXID', 'i')
|
|
AuxDriId = EgtIf( AuxDriId, AuxDriId + vProc[j].Id, nil)
|
|
-- recupero versore normale del tenone
|
|
local AuxTenId = EgtGetInfo( vProc[i].Id, 'AUXID', 'i')
|
|
AuxTenId = EgtIf( AuxTenId, AuxTenId + vProc[i].Id, GDB_ID.NULL)
|
|
local vtExtr = EgtCurveExtrusion( AuxTenId, GDB_RT.GLOB)
|
|
-- se tutto ok, eseguo spostamento
|
|
if AuxDriId and vtExtr then
|
|
local vtMove = -vtExtr * BD.OFFSET_DRILL_TENON
|
|
EgtMove( AuxDriId, vtMove, GDB_RT.GLOB)
|
|
EgtSetInfo( vProc[j].Id, 'MOV', vtMove)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- Estrazione parametri P da lavorazioni di tipo DtMortise
|
|
local function GetPParametersDtMortise( Proc)
|
|
local vPParameters = {
|
|
{ 'P01', 'd'},
|
|
{ 'P02', 'd'},
|
|
{ 'P03', 'd'},
|
|
{ 'P04', 'i'},
|
|
{ 'P05', 'i'},
|
|
{ 'P06', 'd'},
|
|
{ 'P07', 'd'},
|
|
{ 'P09', 'd'},
|
|
{ 'P10', 'd'},
|
|
{ 'P11', 'd'},
|
|
{ 'P12', 'd'},
|
|
{ 'P13', 'd'},
|
|
{ 'P14', 'd'},
|
|
{ 'P15', 'd'}
|
|
}
|
|
for i = 1, #vPParameters do
|
|
vPParameter = vPParameters[i]
|
|
vPParameter[3] = EgtGetInfo( Proc.Id, vPParameter[1], vPParameter[2])
|
|
end
|
|
return vPParameters
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- Controlla se la feature ProcMirror è la specchiata di Proc, per feature di tipo DtMortise
|
|
local function CheckMirrorDtMortise( Proc, ProcMirror, dHBeam)
|
|
local bIsMirror = true
|
|
local vPParametersProc = GetPParametersDtMortise( Proc)
|
|
local vPParametersMirror = GetPParametersDtMortise( ProcMirror)
|
|
local nP02, nP06 = 2, 6
|
|
-- controllo che i parametri P delle due feature, tranne P02 e P06, siano uguali
|
|
for i = 1, #vPParametersProc do
|
|
local vPParameterProc = vPParametersProc[i]
|
|
local vPParameterMirror = vPParametersMirror[i]
|
|
if vPParameterProc[1] ~= 'P02' and vPParameterProc[1] ~= 'P06'then
|
|
bIsMirror = ( abs( vPParameterProc[3] - vPParameterMirror[3]) < 100 * GEO.EPS_SMALL)
|
|
if bIsMirror == false then break end
|
|
elseif vPParameterProc[1] == 'P02' then
|
|
nP02 = i
|
|
elseif vPParameterProc[1] == 'P06' then
|
|
nP06 = i
|
|
end
|
|
end
|
|
-- se gli altri parametri P sono uguali, verifico che P02 e P06 siano compatibili con feature specchiate
|
|
if bIsMirror == true then
|
|
bIsMirror = ( ( vPParametersProc[nP02][3] == 0 and abs( vPParametersMirror[nP02][3] - dHBeam) < 100 * GEO.EPS_SMALL) and
|
|
( vPParametersProc[nP06][3] == 90 and vPParametersMirror[nP06][3] == -90)) or
|
|
( ( vPParametersMirror[nP02][3] == 0 and abs( vPParametersProc[nP02][3] - dHBeam) < 100 * GEO.EPS_SMALL) and
|
|
( vPParametersMirror[nP06][3] == 90 and vPParametersProc[nP06][3] == -90))
|
|
end
|
|
return bIsMirror
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- Cerca se esiste una feature specchiata di Proc e nel caso ne restituisce la posizione in vProc
|
|
local function FindMirrorFeature( vProc, Proc, sFeatureType, dHBeam)
|
|
local nProcMirror
|
|
-- se mortasa a coda di rondine
|
|
if sFeatureType == 'DtMortise' then
|
|
Proc.Side = EgtGetInfo( Proc.Id, 'SIDE', 'i')
|
|
for i = 1, #vProc do
|
|
local ProcMirror = vProc[i]
|
|
if DtMortise.SideIdentify(ProcMirror) then
|
|
ProcMirror.Side = EgtGetInfo( ProcMirror.Id, 'SIDE', 'i')
|
|
if ( Proc.Side == 1 and ProcMirror.Side == 3) or ( Proc.Side == 3 and ProcMirror.Side == 1) or
|
|
( Proc.Side == 2 and ProcMirror.Side == 4) or ( Proc.Side == 4 and ProcMirror.Side == 2) then
|
|
local bIsMirror = CheckMirrorDtMortise( Proc, ProcMirror, dHBeam)
|
|
if bIsMirror then nProcMirror = i end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- se foratura (da implementare)
|
|
return nProcMirror
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- Cerca in vProc la presenza di feature specchiate. Se le trova scrive in Proc e nelle info l'Id della specchiata.
|
|
local function SetMirroredFeatures( vProc, dHBeam)
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
local sFeatureType
|
|
if DtMortise.SideIdentify(Proc) then
|
|
sFeatureType = 'DtMortise'
|
|
elseif Drill.Identify(Proc) then
|
|
sFeatureType = 'Drill'
|
|
end
|
|
if ( sFeatureType == 'DtMortise' or sFeatureType == 'Drill') and not Proc.MirrorId then
|
|
local nProcMirror = FindMirrorFeature( vProc, Proc, sFeatureType, dHBeam)
|
|
if nProcMirror then
|
|
Proc.MirrorId = vProc[nProcMirror].Id
|
|
vProc[nProcMirror].MirrorId = Proc.Id
|
|
EgtSetInfo( Proc.Id, 'MIRRORID', vProc[nProcMirror].Id)
|
|
EgtSetInfo( vProc[nProcMirror].Id, 'MIRRORID', Proc.Id)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- verifica se ci sono forature da lavorare dopo tagli di testa o coda e nel caso le classifica come Head o Tail e gli assegna l'Id della rispettiva feature di taglio
|
|
local function SetDrillingsToMachineAfterHeadOrTailCut( vProc, vMachineBeforeIntersectingDrillings)
|
|
for i = 1, #vProc do
|
|
if Drill.Identify( vProc[i]) then
|
|
-- recupero e verifico l'entità foro
|
|
local AuxId = EgtGetInfo( vProc[i].Id, 'AUXID', 'i')
|
|
if AuxId then AuxId = AuxId + vProc[i].Id end
|
|
if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then
|
|
return false
|
|
end
|
|
-- recupero il vettore estrusione
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local bOpen = ( vProc[i].Fcs ~= 0 and vProc[i].Fce ~= 0)
|
|
local ptCen = EgtCP( AuxId, GDB_RT.GLOB)
|
|
local vDistHead, vDistTail
|
|
-- check intersezione con feature di testa
|
|
if vMachineBeforeIntersectingDrillings.Head.Id then
|
|
-- verifico che ci sia intersezione tra la feature foro e la feature taglio di testa
|
|
local bIntersectionWithHead =
|
|
vMachineBeforeIntersectingDrillings.Head.Box and vProc[i].Box:getMin():getX() < vMachineBeforeIntersectingDrillings.Head.Box:getMax():getX() + 100 * GEO.EPS_SMALL and
|
|
vMachineBeforeIntersectingDrillings.Head.Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL
|
|
-- verifico che ci sia intersezione tra la direzione di estrusione e la faccia della feature taglio di testa
|
|
if bIntersectionWithHead then
|
|
_, _, vDistHead = EgtLineSurfTmInters( ptCen, -vtExtr, vMachineBeforeIntersectingDrillings.Head.Id, GDB_RT.GLOB)
|
|
end
|
|
end
|
|
-- check intersezione con feature di coda
|
|
if vMachineBeforeIntersectingDrillings.Tail.Id then
|
|
-- verifico che ci sia intersezione tra la feature foro e la feature taglio di coda
|
|
local bIntersectionWithTail =
|
|
vMachineBeforeIntersectingDrillings.Tail.Box and vProc[i].Box:getMin():getX() < vMachineBeforeIntersectingDrillings.Tail.Box:getMax():getX() + 100 * GEO.EPS_SMALL and
|
|
vMachineBeforeIntersectingDrillings.Tail.Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL
|
|
-- verifico che ci sia intersezione tra la direzione di estrusione e la faccia della feature taglio di coda
|
|
if bIntersectionWithTail then
|
|
_, _, vDistTail = EgtLineSurfTmInters( ptCen, -vtExtr, vMachineBeforeIntersectingDrillings.Tail.Id, GDB_RT.GLOB)
|
|
end
|
|
end
|
|
-- se esiste intersezione tra il foro e la feature di testa
|
|
if vDistHead and #vDistHead > 0 then
|
|
-- verifico che il foro sia di testa
|
|
if ( bOpen or ( not bOpen and vtExtr:getX() > 0 and vProc[i].Fcs ~= 0) or ( not bOpen and vtExtr:getX() < 0 and vProc[i].Fce ~= 0)) then
|
|
vProc[i].MachineAfterHeadCutId = vMachineBeforeIntersectingDrillings.Head.Id
|
|
vProc[i].Head = true
|
|
end
|
|
-- se esiste intersezione tra il foro e la feature di coda
|
|
elseif vDistTail and #vDistTail > 0 then
|
|
-- verifico che il foro sia di coda
|
|
if ( bOpen or ( not bOpen and vtExtr:getX() < 0 and vProc[i].Fcs ~= 0) or ( not bOpen and vtExtr:getX() > 0 and vProc[i].Fce ~= 0)) then
|
|
vProc[i].MachineAfterTailCutId = vMachineBeforeIntersectingDrillings.Tail.Id
|
|
vProc[i].Tail = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamExec.ProcessFeatures()
|
|
if BD.IMPROVE_HEAD_TAIL_DRILLINGS == nil then
|
|
BD.IMPROVE_HEAD_TAIL_DRILLINGS = true
|
|
end
|
|
-- verifica se possibile rotazione di 90 gradi
|
|
BD.ROT90 = BD.ROT90 and Verify90DegRotation( EgtGetFirstRawPart())
|
|
-- ciclo sui pezzi
|
|
local nTotErr = 0
|
|
local Stats = {}
|
|
local nOrd = 1
|
|
local nRawId = EgtGetFirstRawPart()
|
|
while nRawId do
|
|
-- verifico che il grezzo contenga pezzi oppure sia abbastanza lungo da essere scaricato coi carrelli
|
|
local nPartId = EgtGetFirstPartInRawPart( nRawId)
|
|
if not nPartId and EgtGetRawPartBBox( nRawId):getDimX() < BD.MinRaw then break end
|
|
-- aggiungo la fase, se non è la prima
|
|
if nOrd == 1 then
|
|
EgtSetCurrPhase( 1)
|
|
else
|
|
BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, 0)
|
|
end
|
|
local nPhase = EgtGetCurrPhase()
|
|
local nDispId = EgtGetPhaseDisposition( nPhase)
|
|
EgtSetInfo( nDispId, 'TYPE', EgtIf( nPartId, 'START', 'REST'))
|
|
EgtSetInfo( nDispId, 'ORD', nOrd)
|
|
EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( nRawId) .. ' Part=' .. tostring( nPartId) .. ' ***', 1)
|
|
-- ingombro del grezzo e sovramateriale di testa
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
local dCurrOvmH = EgtGetInfo( nRawId, 'HOVM', 'd') or 0
|
|
local dCurrOvmT = EgtGetInfo( nRawId, 'TOVM', 'd') or 0
|
|
-- recupero le feature di lavorazione della trave
|
|
local vProc, vMachineBeforeIntersectingDrillings = CollectFeatures( nPartId, b3Raw, dCurrOvmH, dCurrOvmT)
|
|
-- verifica presenza forature influenzate da lavorazioni di testa o coda
|
|
if BD.IMPROVE_HEAD_TAIL_DRILLINGS then
|
|
SetDrillingsToMachineAfterHeadOrTailCut( vProc, vMachineBeforeIntersectingDrillings)
|
|
end
|
|
-- verifica presenza di feature specchiate per eventuali lavorazioni simultanee
|
|
local bConcurrentDoubleHead = BD.DOUBLE_HEAD_MIRRORED_FEATURES and ( BD.TWO_EQUAL_HEADS or BD.TWO_UP_DOWN_HEADS)
|
|
if bConcurrentDoubleHead then
|
|
SetMirroredFeatures( vProc, EgtGetRawPartBBox( nRawId):getDimZ())
|
|
end
|
|
-- le ordino lungo X
|
|
OrderFeatures( vProc, b3Raw)
|
|
-- le classifico
|
|
local bAllOk, bSomeDown, bSomeSide, bSplitRot = ClassifyFeatures( vProc, b3Raw, Stats)
|
|
if not bAllOk then
|
|
nTotErr = nTotErr + 1
|
|
end
|
|
-- debug
|
|
if EgtGetDebugLevel() >= 1 then
|
|
PrintFeatures( vProc, b3Raw)
|
|
end
|
|
EgtOutLog( ' *** AddMachinings ***', 1)
|
|
-- verifico se comunque necessario taglio di testa
|
|
local bNeedHCut = VerifyNeedForHeadCut( vProc, bSomeDown, bSomeSide)
|
|
-- inserisco corrispondenze di tagli coincidenti con mortase normali o a coda di rondine di testa
|
|
SetCutsOnFrontMortises( vProc)
|
|
-- eventuale spostamento fori sui tenoni
|
|
MoveDrillsOnTenon( vProc)
|
|
-- identifico la condizione di lavorazione, in base a bSomeDown e bSomeSide
|
|
local sDownOrSideOrStd = 'STD'
|
|
-- se richiesto ribaltamento (oppure rotazione)
|
|
if ( bSomeDown or bSomeSide) and not BD.DOWN_HEAD and not BD.TURN then
|
|
sDownOrSideOrStd = 'DOWN'
|
|
-- ribalto le travi della fase corrente
|
|
local nRId = nRawId
|
|
while nRId do
|
|
EgtRotateRawPart( nRId, X_AX(), 180)
|
|
nRId = EgtGetNextRawPart( nRId)
|
|
end
|
|
EgtSetInfo( nDispId, 'ROT', -2)
|
|
-- inserisco le lavorazioni da lavorare ribaltate
|
|
for i = 1, #vProc do
|
|
-- creo la lavorazione
|
|
local Proc = vProc[i]
|
|
if Proc.Flg ~= 0 and Proc.Down then
|
|
local bOk, sMsg, nNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut, b3Raw, nOrd, sDownOrSideOrStd, nil, nil, dCurrOvmT)
|
|
if not bOk then
|
|
nTotErr = nTotErr + 1
|
|
table.insert( Stats, {Err=1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId})
|
|
elseif sMsg and #sMsg > 0 then
|
|
table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId})
|
|
else
|
|
table.insert( Stats, {Err=0, Msg='', Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId})
|
|
end
|
|
-- se è taglio di separazione, verifico se ha già aggiunto una nuova fase oppure se è da creare
|
|
if nNewPhase > 0 then
|
|
nPhase = nNewPhase
|
|
elseif nNewPhase == 0 then
|
|
BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, BD.RAW_OFFSET)
|
|
EgtRotateRawPart( nRawId, X_AX(), 180)
|
|
-- se grezzo successivo senza pezzi e finale, va tolto
|
|
local nNextRawId = EgtGetNextRawPart( nRawId)
|
|
if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then
|
|
EgtRemoveRawPartFromCurrPhase( nNextRawId)
|
|
end
|
|
nPhase = EgtGetCurrPhase()
|
|
nDispId = EgtGetPhaseDisposition( nPhase)
|
|
EgtSetInfo( nDispId, 'TYPE', 'MID2')
|
|
EgtSetInfo( nDispId, 'ORD', nOrd)
|
|
EgtSetInfo( nDispId, 'ROT', -2)
|
|
end
|
|
end
|
|
end
|
|
-- se separazione non ancora effettuata, aggiungo nuova fase con le travi in posizione standard
|
|
if not bSplitRot then
|
|
BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, 0)
|
|
-- altrimenti
|
|
else
|
|
-- aggiungo nuova fase con le travi in posizione standard
|
|
BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, BD.RAW_OFFSET)
|
|
-- se grezzo successivo senza pezzi e finale, va tolto
|
|
local nNextRawId = EgtGetNextRawPart( nRawId)
|
|
if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then
|
|
EgtRemoveRawPartFromCurrPhase( nNextRawId)
|
|
end
|
|
end
|
|
nPhase = EgtGetCurrPhase()
|
|
nDispId = EgtGetPhaseDisposition( nPhase)
|
|
local nType = 'MID'
|
|
if bSplitRot then nType = EgtIf( bSomeSide, 'MID2', 'END2') end
|
|
EgtSetInfo( nDispId, 'TYPE', nType)
|
|
EgtSetInfo( nDispId, 'ORD', nOrd)
|
|
end
|
|
-- se richiesta rotazione
|
|
if bSomeSide and not BD.DOWN_HEAD and not BD.TURN then
|
|
sDownOrSideOrStd = 'SIDE'
|
|
-- vettore movimento grezzi per rotazione di 90deg
|
|
local dDeltaYZ = EgtGetRawPartBBox( nRawId):getDimY() - EgtGetRawPartBBox( nRawId):getDimZ()
|
|
local vtMove = Vector3d( 0, dDeltaYZ / 2 * EgtIf( BD.RIGHT_LOAD, -1, 1), dDeltaYZ / 2)
|
|
local bPreMove = ( dDeltaYZ < 0)
|
|
-- ruoto le travi della fase corrente
|
|
local nRId = nRawId
|
|
while nRId do
|
|
if bPreMove then EgtMoveRawPart( nRId, vtMove) end
|
|
EgtRotateRawPart( nRId, X_AX(), EgtIf( BD.RIGHT_LOAD, -90, 90))
|
|
if not bPreMove then EgtMoveRawPart( nRId, vtMove) end
|
|
nRId = EgtGetNextRawPart( nRId)
|
|
end
|
|
EgtSetInfo( nDispId, 'ROT', -1)
|
|
-- inserisco le lavorazioni da lavorare ruotate
|
|
local nSideMchOk = 0
|
|
for i = 1, #vProc do
|
|
-- creo la lavorazione
|
|
local Proc = vProc[i]
|
|
if Proc.Flg ~= 0 and Proc.Side then
|
|
local bOk, sMsg, nNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, false, b3Raw, nOrd, sDownOrSideOrStd, bPreMove, vtMove, dCurrOvmT)
|
|
if not bOk then
|
|
nTotErr = nTotErr + 1
|
|
table.insert( Stats, {Err=1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId})
|
|
elseif sMsg and #sMsg > 0 then
|
|
table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId})
|
|
else
|
|
table.insert( Stats, {Err=0, Msg='', Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId})
|
|
end
|
|
if bOk then nSideMchOk = nSideMchOk + 1 end
|
|
-- se era taglio di separazione, aggiungo nuova fase
|
|
if nNewPhase > 0 then
|
|
nPhase = nNewPhase
|
|
elseif nNewPhase == 0 then
|
|
BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, BD.RAW_OFFSET)
|
|
if bPreMove then EgtMoveRawPart( nRawId, vtMove) end
|
|
EgtRotateRawPart( nRawId, X_AX(), EgtIf( BD.RIGHT_LOAD, -90, 90))
|
|
if not bPreMove then EgtMoveRawPart( nRawId, vtMove) end
|
|
-- se grezzo successivo senza pezzi e finale, va tolto
|
|
local nNextRawId = EgtGetNextRawPart( nRawId)
|
|
if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then
|
|
EgtRemoveRawPartFromCurrPhase( nNextRawId)
|
|
end
|
|
nPhase = EgtGetCurrPhase()
|
|
nDispId = EgtGetPhaseDisposition( nPhase)
|
|
EgtSetInfo( nDispId, 'TYPE', 'MID2')
|
|
EgtSetInfo( nDispId, 'ORD', nOrd)
|
|
EgtSetInfo( nDispId, 'ROT', -1)
|
|
end
|
|
end
|
|
end
|
|
-- se non sono state inserite lavorazioni di fianco, elimino la fase perchè inutile e dannosa
|
|
if nSideMchOk == 0 then
|
|
EgtRemoveLastPhase()
|
|
end
|
|
-- se separazione non ancora effettuata, aggiungo nuova fase con le travi in posizione standard
|
|
if not bSplitRot then
|
|
BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, 0)
|
|
-- altrimenti
|
|
else
|
|
BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, BD.RAW_OFFSET)
|
|
-- se grezzo successivo senza pezzi e finale, va tolto
|
|
local nNextRawId = EgtGetNextRawPart( nRawId)
|
|
if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then
|
|
EgtRemoveRawPartFromCurrPhase( nNextRawId)
|
|
end
|
|
end
|
|
nPhase = EgtGetCurrPhase()
|
|
nDispId = EgtGetPhaseDisposition( nPhase)
|
|
EgtSetInfo( nDispId, 'TYPE', EgtIf( not bSplitRot, 'MID', 'END2'))
|
|
EgtSetInfo( nDispId, 'ORD', nOrd)
|
|
end
|
|
sDownOrSideOrStd = 'STD'
|
|
-- inserisco le lavorazioni non ribaltate della trave
|
|
for i = 1, #vProc do
|
|
-- creo la lavorazione
|
|
local Proc = vProc[i]
|
|
if Proc.Flg ~= 0 and ( not ( Proc.Down or Proc.Side) or BD.DOWN_HEAD or BD.TURN) then
|
|
local bOk, sMsg, nNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, false, b3Raw, nOrd, sDownOrSideOrStd, nil, nil, dCurrOvmT)
|
|
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
|
|
-- se era taglio di separazione, aggiungo nuova fase
|
|
if nNewPhase > 0 then
|
|
nPhase = nNewPhase
|
|
elseif nNewPhase == 0 then
|
|
BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, BD.RAW_OFFSET)
|
|
-- se grezzo successivo senza pezzi e finale, va tolto
|
|
local nNextRawId = EgtGetNextRawPart( nRawId)
|
|
if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then
|
|
EgtRemoveRawPartFromCurrPhase( nNextRawId)
|
|
end
|
|
nPhase = EgtGetCurrPhase()
|
|
nDispId = EgtGetPhaseDisposition( nPhase)
|
|
EgtSetInfo( nDispId, 'TYPE', 'END')
|
|
EgtSetInfo( nDispId, 'ORD', nOrd)
|
|
end
|
|
end
|
|
end
|
|
EgtOutLog( ' *** End AddMachinings ***', 1)
|
|
-- passo al grezzo successivo
|
|
nOrd = nOrd + 1
|
|
nRawId = EgtGetNextRawPart( nRawId)
|
|
end
|
|
|
|
-- Aggiornamento finale di tutto
|
|
EgtSetCurrPhase( 1)
|
|
local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings()
|
|
-- eventuale ricalcolo per macchine tipo PF (ma tengo warning del primo calcolo)
|
|
if EgtExistsInfo( EgtGetCurrMachGroup(), 'RECALC') then
|
|
EgtOutLog( ' **** RECALC ****')
|
|
bApplOk, sApplErrors, _ = EgtApplyAllMachinings()
|
|
EgtRemoveInfo( EgtGetCurrMachGroup(), 'RECALC')
|
|
end
|
|
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
|
|
local vLine = EgtSplitString( sApplWarns, '\r\n')
|
|
for i = 1, #vLine do
|
|
local nPos = vLine[i]:find( '(WRN', 1, true)
|
|
if nPos then
|
|
local sData = vLine[i]:sub( nPos + 1, -2)
|
|
local vVal = EgtSplitString( sData, ',')
|
|
local nWarn = EgtGetVal( vVal[1] or '', 'WRN', 'i')
|
|
local nCutId = EgtGetVal( vVal[2] or '', 'CUTID', 'i')
|
|
if nWarn and nCutId then
|
|
table.insert( Stats, { Err=-nWarn, Msg=vLine[i], Rot=0, CutId=nCutId, TaskId=0})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return ( nTotErr == 0), Stats
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
return BeamExec
|