2648 lines
128 KiB
Lua
2648 lines
128 KiB
Lua
-- BeamExec.lua by Egaltech s.r.l. 2023/12/26
|
|
-- 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.
|
|
-- 2022/12/28 Implementata gestione forature e code di rondine in doppio.
|
|
-- 2023/01/31 Implementata gestione mortase in doppio.
|
|
-- 2023/01/31 Nelle lavorazioni in doppio aggiunta la minima distanza tra le feature.
|
|
-- 2023/02/17 Ora le forature che intersecano le mortase sono sempre fatte prima della mortasa stessa.
|
|
-- 2023/02/17 Nelle tasche in doppio, la distanza minima ammessa tra le feature è stata portata a 50.
|
|
-- 2023/02/20 Ora le mortase a coda di rondine laterali sono sempre fatte prima dei tagli longitudinali.
|
|
-- 2023/03/31 Corretto ordinamento per fori di coda da lasciare in coda.
|
|
-- 2023/07/31 Corretto errore nelle mortase in doppio.
|
|
-- 2023/09/13 Aggiunta ClassifyTopology per la classificazione topologica delle feature. In CollectFeatures aggiunta la raccolta preliminare di alcune informazioni.
|
|
-- 2023/09/26 Funzione IsFeatureCuttingEntireSection spostata in BeamLib
|
|
-- 2023/09/26 In ClassifyTopology aggiunto passaggio del parametro nRawId
|
|
-- 2023/10/24 Aggiunta scrittura parametro BARLEN nelle info del mach group
|
|
-- 2023/11/08 Aggiunta gestione processi Variant.
|
|
-- 2023/11/30 Migliorato il calcolo elevazione con l'utilizzo della nuova funzione EgtSurfTmFacetElevationInBBox.
|
|
-- 2023/12/26 Modifiche per centrare i pezzi in Y sulla tavola.
|
|
-- 2024/02/26 Migliorata 'CompareFeatures' per ordine lavorazioni
|
|
-- Migliorata 'CompareFeatures' per ordine forature
|
|
-- 2024/02/19 In Collect aggiunta la scrittura nella Proc di Width e Height delle facce.
|
|
-- 2024/02/29 Migliorata 'CompareFeatures' per ordine forature
|
|
-- 2024/03/04 Creata funzione calcolo dipendenze tra feature con calcolo topologia.
|
|
-- 2024/03/07 Implementate le lavorazioni in doppio per fori specchiati non passanti e DrillPocket.
|
|
-- 2024/03/11 In CollectFeatures si scrive ora Width e Height della faccia sia trimmate con il grezzo che intere.
|
|
-- 2024/03/13 In CollectFeatures si scrive lunghezza foro su Proc e si controla se serve Predrill
|
|
-- In OrderFeature, preforo sempre prima del foro
|
|
-- 2024/04/11 In CollectFeatures aggiunta lettura info PRID, scritta in Proc.FeatureId
|
|
-- 2024/09/04 Gestione dipendenza foro-tasca in caso di fase con pezzo ribaltato
|
|
|
|
-- 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.ProcessProbing = 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
|
|
_G.package.loaded.ProcessVariant = nil
|
|
local ML = require( 'MachiningLib')
|
|
local BL = require( 'BeamLib')
|
|
local Topology = require( 'FeatureTopology')
|
|
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')
|
|
local Variant = require( 'ProcessVariant')
|
|
|
|
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 StJoNotch.Identify( Proc) then
|
|
return StJoNotch.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 StJoNotch.Identify( Proc) then
|
|
return StJoNotch.IsTailFeature( Proc, b3Raw)
|
|
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
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function NeedTopologyFeature( Proc)
|
|
-- richiedono calcolo topologia
|
|
if Cut.Identify( Proc) then
|
|
return true
|
|
end
|
|
if DoubleCut.Identify( Proc) then
|
|
return true
|
|
end
|
|
if LongCut.Identify( Proc) then
|
|
return true
|
|
end
|
|
if Long2Cut.Identify( Proc) then
|
|
return true
|
|
end
|
|
if SawCut.Identify( Proc) then
|
|
return true
|
|
end
|
|
if RidgeLap.Identify( Proc) then
|
|
return true
|
|
end
|
|
if LapJoint.Identify( Proc) then
|
|
return true
|
|
end
|
|
if FrenchRidgeLap.Identify( Proc) then
|
|
return true
|
|
end
|
|
if Chamfer.Identify( Proc) then
|
|
return true
|
|
end
|
|
-- tutte le altre non richiedono calcolo topologia
|
|
return false
|
|
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')
|
|
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')
|
|
local nFeatureId = EgtGetInfo( ProcId, 'PRID', 'i')
|
|
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.FeatureId = nFeatureId or Proc.TaskId
|
|
-- 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 b3Raw then
|
|
-- recupero l'elenco delle facce della parte interessate dalla feature
|
|
Proc.AffectedFaces = BL.GetProcessAffectedFaces( Proc)
|
|
-- recupero informazioni sulle facce della feature
|
|
if not Proc.Face then
|
|
Proc.Face = BL.GetFacetsInfo( Proc, b3Raw)
|
|
end
|
|
end
|
|
if Proc.Box and not Proc.Box:isEmpty() then
|
|
Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH)
|
|
Proc.Tail, Proc.AdvTail = IsTailFeature( Proc, b3Raw, dCurrOvmH, dCurrOvmT)
|
|
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.Len, Proc.Fcs, Proc.Fce = Drill.GetData( Proc, b3Raw)
|
|
-- verifico se devo inserire i prefori
|
|
if Drill.IsPredrillNeeded( Proc) then
|
|
local bAddProc, PredrillProc= Drill.AddPredrillFromDrillProc( Proc)
|
|
if bAddProc then
|
|
table.insert( vProc, PredrillProc)
|
|
end
|
|
end
|
|
-- 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.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.Len = Proc.Len
|
|
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
|
|
-- recupero l'elenco delle facce della parte interessate dalla feature
|
|
Proc2.AffectedFaces = BL.GetProcessAffectedFaces( Proc2)
|
|
table.insert( vProc, Proc2)
|
|
-- verifico se devo inserire i prefori
|
|
if Drill.IsPredrillNeeded( Proc2) then
|
|
local bAddProc, PredrillProc= Drill.AddPredrillFromDrillProc( Proc2)
|
|
if bAddProc then
|
|
table.insert( vProc, PredrillProc)
|
|
end
|
|
end
|
|
end
|
|
-- se BlockHaus HalfLap
|
|
elseif Proc.Prc == 37 then
|
|
local nFacInd = BL.GetFaceWithMostAdj( Proc, 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
|
|
return vProc
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function CalcHeadTailMachBeforeIntersDrillings( vProc, b3Raw)
|
|
local nHeadId
|
|
local dHeadX = GEO.INFINITO
|
|
local nTailId
|
|
local dTailX = -GEO.INFINITO
|
|
local b3HeadBox
|
|
local b3TailBox
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
if Proc.Box and not Proc.Box:isEmpty() then
|
|
if Proc.Fct == 1 and BL.IsFeatureCuttingEntireSection( Proc.Box, b3Raw:getDimY(), b3Raw:getDimZ()) and ( Proc.Head or Proc.Tail) and Proc.Prc ~= 340 and Proc.Prc ~= 350 then
|
|
if Proc.Head and Proc.Box:getCenter():getX() < dHeadX then
|
|
dHeadX = Proc.Box:getCenter():getX()
|
|
nHeadId = Proc.Id
|
|
b3HeadBox = Proc.Box
|
|
elseif Proc.Tail and Proc.Box:getCenter():getX() > dTailX then
|
|
dTailX = Proc.Box:getCenter():getX()
|
|
nTailId = Proc.Id
|
|
b3TailBox = Proc.Box
|
|
end
|
|
end
|
|
end
|
|
end
|
|
local vMachBeforeIntersDrillings = {
|
|
Head = { Id = nHeadId, Box = b3HeadBox},
|
|
Tail = { Id = nTailId, Box = b3TailBox}
|
|
}
|
|
return vMachBeforeIntersDrillings
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function AnalyzeHeadFeatures( b3Solid, vProc, dRawW, dRawH)
|
|
local nReplacedFeatureId = nil
|
|
local bHeadFinishingNeeded = true
|
|
local nCuttingFeatureId = nil
|
|
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 BL.IsFeatureCuttingEntireSection( Proc.Box, dRawW, dRawH)
|
|
if not bHeadFinishingNeeded and ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10) and ( Proc.Flg > 0) then
|
|
nCuttingFeatureId = Proc.Id
|
|
end
|
|
end
|
|
end
|
|
return bHeadFinishingNeeded, nReplacedFeatureId, nCuttingFeatureId
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function AnalyzeTailFeatures( b3Solid, vProc, dRawW, dRawH)
|
|
local nReplacedFeatureId = nil
|
|
local bTailFinishingNeeded = true
|
|
local nCuttingFeatureId = nil
|
|
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 BL.IsFeatureCuttingEntireSection( Proc.Box, dRawW, dRawH)
|
|
if not bTailFinishingNeeded and ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10) and ( Proc.Flg > 0) then
|
|
nCuttingFeatureId = Proc.Id
|
|
end
|
|
end
|
|
end
|
|
return bTailFinishingNeeded, nReplacedFeatureId, nCuttingFeatureId
|
|
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, dOvmMid, 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)
|
|
|
|
-- sovramateriale intermedio nullo se non definito
|
|
dOvmMid = ( dOvmMid or 0)
|
|
|
|
-- 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')
|
|
|
|
-- salvo nota con lunghezza grezzo
|
|
-- Recupero l'identificativo del gruppo di lavoro corrente
|
|
local nMGrpId = EgtGetCurrMachGroup()
|
|
|
|
-- Area tavola
|
|
local b3Tab = EgtGetTableArea()
|
|
-- Calcolo posizione estremo TR/BR della tavola rispetto a sua origine in BL
|
|
local dPosY = EgtIf( BD.CENTER_BEAM, ( b3Tab:getDimY() + dRawW * EgtIf( BD.RIGHT_LOAD, -1, 1)) / 2, EgtIf( BD.RIGHT_LOAD, 0, b3Tab:getDimY()))
|
|
BD.OriXR = Point3d( b3Tab:getDimX(), dPosY, 0)
|
|
BD.PosXR = EgtIf( BD.RIGHT_LOAD, MCH_CR.BR, MCH_CR.TR)
|
|
|
|
-- Impostazione dell'attrezzaggio di default
|
|
EgtImportSetup()
|
|
|
|
-- se pretagli di coda sono attivi, aumento di 10mm la lunghezza del grezzo per fare effettivamente tagliare del materiale.
|
|
-- Altrimenti le lavorazioni pensano di essere nel vuoto e si muovono in rapido
|
|
if BD.PRECUT_TAIL and VerifyBigSectionCut( dRawW, dRawH) then
|
|
dRawL = dRawL + 10
|
|
end
|
|
|
|
-- Lunghezza della barra
|
|
local dBarLen = EgtGetInfo( nMGrpId, 'BARLEN', 'd')
|
|
if not dBarLen then
|
|
EgtSetInfo( nMGrpId, 'BARLEN', dRawL)
|
|
end
|
|
|
|
-- 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
|
|
-- 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
|
|
-- 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, nHeadCuttingFeatureId = AnalyzeHeadFeatures( b3Solid, vProc, dRawW, dRawH)
|
|
local bEFinishingNeeded, nReplacedTailCutFeatureId, nTailCuttingFeatureId = AnalyzeTailFeatures( b3Solid, vProc, dRawW, dRawH)
|
|
-- Scrivo gli id delle facce di taglio custom: serviranno dopo per calcolare l'elevazione rispetto a queste
|
|
if nHeadCuttingFeatureId then
|
|
EgtSetInfo( vBeam[i].Id, 'HEADCUTFEATUREID', nHeadCuttingFeatureId)
|
|
else
|
|
EgtRemoveInfo( vBeam[i].Id, 'HEADCUTFEATUREID')
|
|
end
|
|
if nTailCuttingFeatureId then
|
|
EgtSetInfo( vBeam[i].Id, 'TAILCUTFEATUREID', nTailCuttingFeatureId)
|
|
else
|
|
EgtRemoveInfo( vBeam[i].Id, 'TAILCUTFEATUREID')
|
|
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
|
|
if vBeam[i].PosX then
|
|
lastB3Solid = vBeam[i-1].Box
|
|
dOffset = vBeam[i].PosX - vBeam[i-1].PosX - lastB3Solid:getDimX()
|
|
else
|
|
dOffset = dOvmMid
|
|
end
|
|
end
|
|
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 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 then
|
|
if vBeam[i].PosX then
|
|
DeltaS = max( vBeam[i].PosX - ( dRawL - Len), DeltaSMin)
|
|
else
|
|
DeltaS = max( dOvmMid - DeltaE, 0)
|
|
end
|
|
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)
|
|
|
|
-- 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 TopoName=%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), Proc.TopologyLongName or '')
|
|
-- 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
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- mi assicuro che i tagli di testa e coda troncanti (usati per ridurre i percorsi utensile in testa e coda) siano sempre fatti per primi
|
|
local function ReorderTruncatingCuts( vProc, nPartId)
|
|
if not nPartId or #vProc == 0 then return end
|
|
|
|
local nHeadCuttingFeatureId = EgtGetInfo( nPartId, 'HEADCUTFEATUREID', 'i')
|
|
local nTailCuttingFeatureId = EgtGetInfo( nPartId, 'TAILCUTFEATUREID', 'i')
|
|
|
|
-- tagli di testa
|
|
-- 1: si trovano gli indici del taglio di testa e del rispettivo taglio troncante
|
|
local nHeadCutIndex, nHeadCuttingFeatureIndex
|
|
for index, value in ipairs( vProc) do
|
|
if value.Prc == 340 then
|
|
nHeadCutIndex = index
|
|
end
|
|
if value.Id == nHeadCuttingFeatureId then
|
|
nHeadCuttingFeatureIndex = index
|
|
end
|
|
end
|
|
|
|
-- 2: se non c'è il taglio di testa, il taglio troncante è il primo. Se c'è il taglio di testa, il taglio troncante lo deve seguire.
|
|
if not nHeadCutIndex and nHeadCuttingFeatureIndex then
|
|
local HeadCuttingFeature = vProc[ nHeadCuttingFeatureIndex]
|
|
table.remove( vProc, nHeadCuttingFeatureIndex)
|
|
table.insert( vProc, 1, HeadCuttingFeature)
|
|
elseif nHeadCutIndex and nHeadCuttingFeatureIndex then
|
|
if abs( nHeadCutIndex - nHeadCuttingFeatureIndex) ~= 1 then
|
|
local HeadCut = vProc[ nHeadCutIndex]
|
|
local HeadCuttingFeature = vProc[ nHeadCuttingFeatureIndex]
|
|
|
|
table.remove( vProc, nHeadCutIndex)
|
|
-- rimuovere il primo potrebbe aver cambiato l'indice del secondo
|
|
if nHeadCutIndex < nHeadCuttingFeatureIndex then
|
|
nHeadCuttingFeatureIndex = nHeadCuttingFeatureIndex - 1
|
|
end
|
|
table.remove( vProc, nHeadCuttingFeatureIndex)
|
|
|
|
table.insert( vProc, nHeadCutIndex, HeadCut)
|
|
table.insert( vProc, nHeadCutIndex + 1, HeadCuttingFeature)
|
|
end
|
|
end
|
|
|
|
-- tagli di coda
|
|
-- 1: si trovano gli indici del taglio di coda e del rispettivo taglio troncante
|
|
local nTailCutIndex, nTailCuttingFeatureIndex
|
|
for index, value in ipairs( vProc) do
|
|
if value.Prc == 350 then
|
|
nTailCutIndex = index
|
|
end
|
|
if value.Id == nTailCuttingFeatureId then
|
|
nTailCuttingFeatureIndex = index
|
|
end
|
|
end
|
|
|
|
-- 2: il taglio di coda c'è sempre. Il taglio troncante lo deve seguire.
|
|
if nTailCutIndex and nTailCuttingFeatureIndex then
|
|
if abs( nTailCutIndex - nTailCuttingFeatureIndex) ~= 1 then
|
|
local TailCut = vProc[ nTailCutIndex]
|
|
local TailCuttingFeature = vProc[ nTailCuttingFeatureIndex]
|
|
|
|
table.remove( vProc, nTailCutIndex)
|
|
-- rimuovere il primo potrebbe aver cambiato l'indice del secondo
|
|
if nTailCutIndex < nTailCuttingFeatureIndex then
|
|
nTailCuttingFeatureIndex = nTailCuttingFeatureIndex - 1
|
|
end
|
|
table.remove( vProc, nTailCuttingFeatureIndex)
|
|
|
|
table.insert( vProc, nTailCutIndex, TailCut)
|
|
table.insert( vProc, nTailCutIndex + 1, TailCuttingFeature)
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- mi assicuro che vengano rispettate le dipendenze tra le feature
|
|
local function ReorderFeatureWithDependency( vProc)
|
|
-- si riordina considerando le dipendenze con alcuni limiti:
|
|
-- * se ci sono dipendenze incrociate il risultato finale non è controllato ( A->B e B->C e C->A)
|
|
-- * se ci sono dipendenze opposte va in errore ( A->B e B->A)
|
|
|
|
-- si sistemano le feature da lavorare prima
|
|
local i = 1
|
|
local nMaxIter = ( #vProc * #vProc) + 1
|
|
local nIter = 0
|
|
while i <= #vProc do
|
|
nIter = nIter + 1
|
|
if nIter > nMaxIter then
|
|
error( "UNEXPECTED ERROR ON DEPENDENCY")
|
|
end
|
|
|
|
-- si controllano solo i fori
|
|
if Drill.Identify( vProc[i]) and vProc[i].Dependency and vProc[i].Dependency.ExecBefore and vProc[i].Dependency.ExecBefore.Id then
|
|
local nRefId = vProc[i].Dependency.ExecBefore.Id
|
|
local nRefIndex
|
|
|
|
for j = 1, #vProc do
|
|
if i ~= j and vProc[j].Id == nRefId then
|
|
nRefIndex = j
|
|
break
|
|
end
|
|
end
|
|
|
|
-- se il processo deve stare prima, ma ora è dopo
|
|
if nRefIndex and nRefIndex < i then
|
|
table.insert( vProc, nRefIndex, table.remove( vProc, i))
|
|
i = max( nRefIndex - 1, 1)
|
|
end
|
|
end
|
|
i = i + 1
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function OrderFeatures( vProc, b3Raw, nPartId)
|
|
|
|
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 dipende dall'altro
|
|
if B1.Dependency and B1.Dependency.ExecBefore and B1.Dependency.ExecBefore.Id == B2.Id then
|
|
return true
|
|
end
|
|
if B2.Dependency and B2.Dependency.ExecBefore and B2.Dependency.ExecBefore.Id == B1.Id then
|
|
return false
|
|
end
|
|
-- se uno di testa e non l'altro, privilegio quello di testa (a meno che non siano dei fori)
|
|
if B1.Head ~= B2.Head and not Drill.Identify(B1) and not Drill.Identify(B2) then
|
|
return B1.Head
|
|
end
|
|
-- se entrambi di testa e intersecano stesse facce e primo è scasso a due facce e secondo è un profilo caudato, lo scasso è una riduzione e va fatto prima
|
|
if ( ( B1.Head and B2.Head) or ( B1.Tail and B2.Tail)) and B1.Topology == 'Rabbet' and ( ProfCamb.Identify( B2) or ProfConcave.Identify( B2) or ProfConvex.Identify( B2)) then
|
|
return true
|
|
end
|
|
-- se entrambi di testa e intersecano stesse facce e primo è un profilo caudato e secondo è scasso a due facce, lo scasso è una riduzione e va lasciato dopo
|
|
if ( ( B1.Head and B2.Head) or ( B1.Tail and B2.Tail)) and B2.Topology == 'Rabbet' and ( ProfCamb.Identify( B1) or ProfConcave.Identify( B1) or ProfConvex.Identify( B1)) 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 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 è foro e secondo è un ribasso o tenone, il foro va sempre prima a meno che il ribasso non sia di testa
|
|
if Drill.Identify(B1) and ( LapJoint.Identify(B2) or Mortise.Identify(B2) or Tenon.Identify(B2)) and B2.PassedByHole 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 o tenone, il ribasso va sempre dopo a meno che il ribasso non sia di testa
|
|
if ( LapJoint.Identify(B1) or Mortise.Identify(B1) or Tenon.Identify(B1)) and B1.PassedByHole 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 primo è ribasso e secondo è una mortasa a coda di rondine, il ribasso va sempre prima a meno che la mortasa a coda di rondine non sia di testa
|
|
if LapJoint.Identify(B1) and B1.PassedByDtMortise and DtMortise.SideIdentify(B2) and
|
|
B2.Box:getCenter():getX() > B1.Box:getMin():getX() and B2.Box:getCenter():getX() < B1.Box:getMax():getX() then
|
|
return true
|
|
end
|
|
-- se primo è mortasa a coda di rondine e secondo è ribasso, la mortasa a coda di rondine va sempre dopo a meno che la mortasa a coda di rondine non sia di testa
|
|
if DtMortise.SideIdentify(B1) and LapJoint.Identify(B2) and B2.PassedByDtMortise and
|
|
B1.Box:getCenter():getX() > B2.Box:getMin():getX() and B1.Box:getCenter():getX() < B2.Box:getMax():getX() then
|
|
return false
|
|
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 è 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 entrambi di coda e il primo è una feature taglio di lama e il secondo no, feature taglio lama sempre prima
|
|
if B1.Tail and B2.Tail and ( Cut.Identify( B1) or DoubleCut.Identify( B1)) and ( not Cut.Identify( B2) and not DoubleCut.Identify( B2)) then
|
|
return true
|
|
end
|
|
-- se entrambi di coda e il secondo è una feature taglio di lama e il primo no, feature taglio lama sempre prima
|
|
if B1.Tail and B2.Tail and ( Cut.Identify( B2) or DoubleCut.Identify( B2)) and ( not Cut.Identify( B1) and not DoubleCut.Identify( B1)) then
|
|
return false
|
|
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 (a patto che il foro non attraversi nessuna feature)
|
|
if Drill.Identify(B1) and not B1.Dependency and not Drill.Identify(B2) then
|
|
return ( B1.Box:getCenter():getX() > B2.Box:getMax():getX() + dDrillPenalty)
|
|
end
|
|
-- se primo è altro e secondo è foro, lo premio (a patto che il foro non attraversi nessuna feature)
|
|
if not Drill.Identify(B1) and not B2.Dependency and Drill.Identify(B2) then
|
|
return ( B1.Box:getMax():getX() + dDrillPenalty > B2.Box:getCenter():getX())
|
|
end
|
|
-- se prima è mortasa coda di rondine sul fianco e secondo taglio longitudinale, la coda di rondine va sempre prima
|
|
if DtMortise.SideIdentify(B1) and ( LongCut.Identify(B2) or Long2Cut.Identify(B2)) and
|
|
OverlapsX( B1.Box, B2.Box) then
|
|
return true
|
|
end
|
|
-- se primo è taglio longitudinale e seconda è mortasa coda di rondine sul fianco, il taglio longitudinale va sempre dopo
|
|
if ( LongCut.Identify(B1) or Long2Cut.Identify(B1)) and DtMortise.SideIdentify(B2) and
|
|
OverlapsX( B1.Box, B2.Box) 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 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 B1.IsPredrill and not B2.IsPredrill then
|
|
return true
|
|
elseif not B1.IsPredrill and B2.IsPredrill then
|
|
return false
|
|
elseif 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
|
|
|
|
ReorderTruncatingCuts( vProc, nPartId)
|
|
|
|
-- si riverificano feature con dipendenze
|
|
ReorderFeatureWithDependency( vProc)
|
|
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 and not Proc.Double 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, bDownSideOnHeadOk = FreeContour.Classify( Proc, b3Raw)
|
|
-- se decorazione
|
|
elseif Decor.Identify( Proc) then
|
|
bOk, bDown = Decor.Classify( Proc)
|
|
-- se Variant
|
|
elseif Variant.Identify( Proc) then
|
|
bOk, bDown = Variant.Classify( Proc, b3Raw)
|
|
end
|
|
-- assegno risultato
|
|
if bOk then
|
|
-- non ammessa feature di testa da lavorare ribaltata o ruotata (lettura laser)
|
|
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, ProcId = Proc.Id})
|
|
-- 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, ProcId = Proc.Id})
|
|
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, ProcId = Proc.Id})
|
|
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
|
|
|
|
-- si cerca di riclassificare le feature che dipendono da altre (in caso siano su rotazioni diverse)
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
-- FORATURA
|
|
if Drill.Identify( Proc) and Proc.Dependency then
|
|
if Proc.Dependency.ExecBefore then
|
|
if Proc.Dependency.ExecBefore.Down then
|
|
local bMachiningSideChanged = Drill.Classify( Proc, b3Raw, 'DOWN')
|
|
end
|
|
end
|
|
end
|
|
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
|
|
local AddedIds
|
|
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, _, AddedIds = 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, _, AddedIds = 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)
|
|
-- se Variant
|
|
elseif Variant.Identify( Proc) then
|
|
-- esecuzione variante custom
|
|
bOk, sErr = Variant.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), AddedIds
|
|
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
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- Controlla se la feature ProcMirror è la specchiata di Proc, per feature di tipo tasca o simile
|
|
local function CheckMirrorPocket( Proc, ProcMirror, b3Raw, AuxId)
|
|
|
|
-- recupero i dati geometrici della curva Proc
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local ptBC = EgtGP( AuxId, GDB_RT.GLOB)
|
|
local rfDtMrt = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_RT.GLOB)
|
|
local b3DtMrt = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfDtMrt)
|
|
local b3Proc = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD)
|
|
|
|
-- recupero e verifico l'entità curva ProcMirror
|
|
local AuxIdMirror = EgtGetInfo( ProcMirror.Id, 'AUXID', 'i')
|
|
if AuxIdMirror then AuxIdMirror = AuxIdMirror + ProcMirror.Id end
|
|
if not AuxIdMirror or ( EgtGetType( AuxIdMirror) & GDB_FY.GEO_CURVE) == 0 then
|
|
return false
|
|
end
|
|
-- se Mortise, se curva di contorno aperta la rendo chiusa
|
|
if Mortise.SideIdentify( ProcMirror) then
|
|
BL.ConvertToClosedCurve( ProcMirror, AuxIdMirror)
|
|
end
|
|
-- recupero i dati geometrici della curva ProcMirror
|
|
local vtExtrMirror = EgtCurveExtrusion( AuxIdMirror, GDB_RT.GLOB)
|
|
local ptBCMirror = EgtGP( AuxIdMirror, GDB_RT.GLOB)
|
|
local b3DtMrtMirror = EgtGetBBoxRef( ProcMirror.Id, GDB_BB.STANDARD, rfDtMrt)
|
|
local b3ProcMirror = EgtGetBBoxGlob( ProcMirror.Id, GDB_BB.STANDARD)
|
|
|
|
-- verifico se le mortase sono specchiate :
|
|
-- devono avere estrusioni opposte
|
|
if not AreOppositeVectorApprox( vtExtr, vtExtrMirror) then
|
|
return false
|
|
end
|
|
-- se di tipo Dt, devono avere l'asse allineato
|
|
if DtMortise.SideIdentify( Proc) or DtMortise.SideIdentify( ProcMirror) then
|
|
local vtAx = EgtEV( AuxId, GDB_RT.GLOB) - EgtSV( AuxId, GDB_RT.GLOB)
|
|
local vtAxMirror = EgtEV( AuxIdMirror, GDB_RT.GLOB) - EgtSV( AuxIdMirror, GDB_RT.GLOB)
|
|
if not AreSameVectorApprox( vtAx, vtAxMirror) then
|
|
return false
|
|
end
|
|
end
|
|
-- devono avere il centro allineato, essere equidistanti dalla mezzeria trave e non essere troppo vicine
|
|
local vtDisplacement = ptBC - ptBCMirror
|
|
local ptCenRaw = b3Raw:getCenter()
|
|
if AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then
|
|
local dYMinDistance = max( b3Proc:getMin():getY(), b3ProcMirror:getMin():getY()) - min( b3Proc:getMax():getY(), b3ProcMirror:getMax():getY())
|
|
if not ( abs( vtDisplacement:getX()) < 500 * GEO.EPS_SMALL and abs( vtDisplacement:getZ()) < 500 * GEO.EPS_SMALL and
|
|
( abs( ptBC:getY() - ptCenRaw:getY()) - abs( ptBCMirror:getY() - ptCenRaw:getY())) < 500 * GEO.EPS_SMALL and
|
|
dYMinDistance > MIRROR_POCKETS_MIN_DISTANCE + 10 * GEO.EPS_SMALL) then
|
|
return false
|
|
end
|
|
elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then
|
|
local dZMinDistance = max( b3Proc:getMin():getZ(), b3ProcMirror:getMin():getZ()) - min( b3Proc:getMax():getZ(), b3ProcMirror:getMax():getZ())
|
|
if not ( abs( vtDisplacement:getX()) < 500 * GEO.EPS_SMALL and abs( vtDisplacement:getY()) < 500 * GEO.EPS_SMALL and
|
|
( abs( ptBC:getZ() - ptCenRaw:getZ()) - abs( ptBCMirror:getZ() - ptCenRaw:getZ())) < 500 * GEO.EPS_SMALL and
|
|
dZMinDistance > MIRROR_POCKETS_MIN_DISTANCE + 10 * GEO.EPS_SMALL) then
|
|
return false
|
|
end
|
|
else
|
|
return false
|
|
end
|
|
-- devono avere box con le stesse dimensioni
|
|
if not ( abs( b3DtMrt:getDimX() - b3DtMrtMirror:getDimX()) < 500 * GEO.EPS_SMALL and
|
|
abs( b3DtMrt:getDimY() - b3DtMrtMirror:getDimY()) < 500 * GEO.EPS_SMALL and
|
|
abs( b3DtMrt:getDimZ() - b3DtMrtMirror:getDimZ()) < 500 * GEO.EPS_SMALL) then
|
|
return false
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- Verifica se Proc (mortasa) è lavorabile in doppio e nel caso ne imposta i dati.
|
|
local function VerifyMortiseMirrored( Proc, vProc, b3Raw)
|
|
-- recupero e verifico l'entità curva
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
|
|
if AuxId then
|
|
AuxId = AuxId + Proc.Id
|
|
end
|
|
if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then
|
|
local sErr = 'Error : missing profile geometry'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero versore estrusione della curva supplementare
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT)
|
|
-- Se curva di contorno aperta la converto in curva chiusa
|
|
BL.ConvertToClosedCurve( Proc, AuxId)
|
|
-- recupero i dati della faccia di fondo
|
|
local frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT)
|
|
-- determino larghezza della mortasa
|
|
if dL < dW then dL, dW = dW, dL end
|
|
local ptC = ORIG()
|
|
local vtN = V_NULL()
|
|
if frMor then
|
|
ptC = frMor:getOrigin()
|
|
vtN = frMor:getVersZ()
|
|
end
|
|
-- se mortasa passante esco
|
|
local bOpenBtm = not AreSameVectorApprox( vtExtr, vtN)
|
|
if bOpenBtm then
|
|
return
|
|
end
|
|
-- determino altezza della mortasa
|
|
local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor)
|
|
local dMorH = b3Mor:getDimZ()
|
|
-- elevazione del punto centrale
|
|
local _, dCenElev = BL.GetPointDirDepth( nPartId, ptC, vtN)
|
|
dMorH = max( dMorH, dCenElev or 0)
|
|
-- recupero lavorazione adatta
|
|
local sPockType = 'Mortise'
|
|
local sPocketing
|
|
if Proc.Prc ~= 53 then
|
|
sPocketing = Mortise.VerifyMortiseOrPocket( Proc, dW, dMorH, nil, sPockType, false, true)
|
|
end
|
|
if not sPocketing then
|
|
sPockType = 'Pocket'
|
|
sPocketing = Mortise.VerifyMortiseOrPocket( Proc, dW, dMorH, nil, sPockType, false, true)
|
|
end
|
|
if not sPocketing or not EgtMdbSetCurrMachining( sPocketing) then
|
|
return
|
|
end
|
|
-- recupero il suo utensile
|
|
if not EgtTdbSetCurrTool( EgtMdbGetCurrMachiningParam( MCH_MP.TOOL) or '') then
|
|
return
|
|
end
|
|
-- recupero eventuale utensile in doppio e suo diametro
|
|
local sToolDoubleName = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'DOUBLE', 's')
|
|
if not sToolDoubleName or not EgtTdbSetCurrTool( sToolDoubleName) or not EgtFindToolInCurrSetup( sToolDoubleName) then
|
|
return
|
|
end
|
|
local dToolDoubleDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM, 'd')
|
|
-- verifico se possibile in doppio (diametro utensile e direzione feature)
|
|
if dToolDoubleDiam < dW + GEO.EPS_SMALL and ( AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) or AreSameVectorApprox( vtExtr, Z_AX())) then
|
|
for i = 1, #vProc do
|
|
local ProcMirror = vProc[i]
|
|
if Mortise.SideIdentify( ProcMirror) and ProcMirror.Id ~= Proc.Id and ProcMirror.Flg ~= 0 then
|
|
if CheckMirrorPocket( Proc, ProcMirror, b3Raw, AuxId) then
|
|
if ( not BD.DOWN_HEAD and AreSameVectorApprox( vtExtr, Y_AX())) or
|
|
( BD.DOWN_HEAD and AreOppositeVectorApprox( vtExtr, Y_AX())) then
|
|
Proc.Double = 2
|
|
Proc.MirrorId = ProcMirror.Id
|
|
Proc.MirrorCutId = ProcMirror.CutId
|
|
Proc.MirrorTaskId = ProcMirror.TaskId
|
|
ProcMirror.Flg = 0
|
|
ProcMirror.Double = 0
|
|
elseif BD.DOWN_HEAD and AreSameVectorApprox( vtExtr, Z_AX()) then
|
|
Proc.Double = 3
|
|
Proc.MirrorId = ProcMirror.Id
|
|
Proc.MirrorCutId = ProcMirror.CutId
|
|
Proc.MirrorTaskId = ProcMirror.TaskId
|
|
ProcMirror.Flg = 0
|
|
ProcMirror.Double = 0
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- Verifica se Proc (mortasa a coda di rondine) è lavorabile in doppio e nel caso ne imposta i dati.
|
|
local function VerifyDtMortiseMirrored( Proc, vProc, b3Raw)
|
|
-- verifico se con tasca
|
|
local bPocket = ( EgtGetInfo( Proc.Id, 'P05', 'i') == 1)
|
|
if bPocket then
|
|
return
|
|
end
|
|
-- recupero e verifico l'entità curva ausiliaria
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then
|
|
return
|
|
end
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
-- recupero il raggio minimo della mortasa
|
|
local dMinRad = 1000
|
|
local nSt, nEnd = EgtCurveDomain( AuxId)
|
|
for i = nSt, nEnd - 1 do
|
|
local dRad = EgtCurveCompoRadius( AuxId, i)
|
|
if dRad > 0 and dRad < dMinRad then
|
|
dMinRad = dRad
|
|
end
|
|
end
|
|
-- recupero lavorazione adatta
|
|
local dMaxDiam = 2 * dMinRad
|
|
local sMilling = ML.FindMilling( 'DtMortise', nil, nil, dMaxDiam, nil, true, false, true)
|
|
if not sMilling or not EgtMdbSetCurrMachining( sMilling) then
|
|
return
|
|
end
|
|
-- recupero il suo utensile
|
|
if not EgtTdbSetCurrTool( EgtMdbGetCurrMachiningParam( MCH_MP.TOOL) or '') then
|
|
return
|
|
end
|
|
-- recupero eventuale utensile in doppio e suo diametro
|
|
local sToolDoubleName = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'DOUBLE', 's')
|
|
if not sToolDoubleName or not EgtTdbSetCurrTool( sToolDoubleName) or not EgtFindToolInCurrSetup( sToolDoubleName) then
|
|
return
|
|
end
|
|
local dToolDoubleDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM, 'd')
|
|
-- verifico se possibile in doppio (diametro utensile e direzione feature)
|
|
if dToolDoubleDiam < dMaxDiam + GEO.EPS_SMALL and ( AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) or AreSameVectorApprox( vtExtr, Z_AX())) then
|
|
for i = 1, #vProc do
|
|
local ProcMirror = vProc[i]
|
|
if DtMortise.SideIdentify( ProcMirror) and ProcMirror.Id ~= Proc.Id and ProcMirror.Flg ~= 0 then
|
|
if CheckMirrorPocket( Proc, ProcMirror, b3Raw, AuxId) then
|
|
if ( not BD.DOWN_HEAD and AreSameVectorApprox( vtExtr, Y_AX())) or
|
|
( BD.DOWN_HEAD and AreOppositeVectorApprox( vtExtr, Y_AX())) then
|
|
Proc.Double = 2
|
|
Proc.MirrorId = ProcMirror.Id
|
|
Proc.MirrorCutId = ProcMirror.CutId
|
|
Proc.MirrorTaskId = ProcMirror.TaskId
|
|
ProcMirror.Flg = 0
|
|
ProcMirror.Double = 0
|
|
elseif BD.DOWN_HEAD and AreSameVectorApprox( vtExtr, Z_AX()) then
|
|
Proc.Double = 3
|
|
Proc.MirrorId = ProcMirror.Id
|
|
Proc.MirrorCutId = ProcMirror.CutId
|
|
Proc.MirrorTaskId = ProcMirror.TaskId
|
|
ProcMirror.Flg = 0
|
|
ProcMirror.Double = 0
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- Disabilita la foratura dall'altra parte dello stesso foro
|
|
local function DisableOtherDrilling( Proc, vProc)
|
|
local ProcMirror
|
|
for i = 1, #vProc do
|
|
if vProc[i].Id == Proc.Id and not vProc[i].Double then
|
|
ProcMirror = vProc[i]
|
|
break
|
|
end
|
|
end
|
|
if ProcMirror then
|
|
ProcMirror.Flg = 0
|
|
ProcMirror.Double = 0
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- Verifica se Proc (foratura) è lavorabile in doppio e nel caso ne restituisce la direzione di specchiatura.
|
|
local function VerifyDrillMirrored( Proc, vProc, b3Raw)
|
|
-- recupero e verifico l'entità foro
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then
|
|
return
|
|
end
|
|
-- verifico se foratura splittata oppure da specchiare
|
|
local bIsDrillingOkForMirror = abs( Proc.Flg) == 2 or ( Proc.Mirror ~= nil)
|
|
if not bIsDrillingOkForMirror then return end
|
|
-- recupero direzione e dimensioni del foro
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local dDiam = 2 * EgtArcRadius( AuxId)
|
|
local dLen = abs( EgtCurveThickness( AuxId))
|
|
local dMachiningDepth = EgtIf( abs( Proc.Flg) == 2, dLen / 2 + BD.DRILL_OVERLAP, dLen)
|
|
-- recupero lavorazione adatta
|
|
local sDrilling, sType, dMaxDepth = ML.FindDrilling( dDiam, dMachiningDepth, true, false, true)
|
|
if not sDrilling then
|
|
sDrilling, sType, dMaxDepth = ML.FindDrilling( dDiam, 0, true, false, true)
|
|
dMachiningDepth = dMaxDepth or dMachiningDepth
|
|
end
|
|
if not sDrilling or not EgtMdbSetCurrMachining( sDrilling) then
|
|
return
|
|
end
|
|
local dDrillingStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP)
|
|
-- recupero il suo utensile
|
|
if not EgtTdbSetCurrTool( EgtMdbGetCurrMachiningParam( MCH_MP.TOOL) or '') then
|
|
return
|
|
end
|
|
-- recupero diametro utensile e lunghezza della parte inclinata della punta
|
|
local dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM, 'd')
|
|
local dToolTipLength = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) - EgtTdbGetCurrToolParam( MCH_TP.LEN)
|
|
-- recupero eventuale utensile in doppio, suo diametro e massima lavorazione
|
|
local sToolDoubleName = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'DOUBLE', 's')
|
|
if not sToolDoubleName or not EgtTdbSetCurrTool( sToolDoubleName) or not EgtFindToolInCurrSetup( sToolDoubleName) then
|
|
return
|
|
end
|
|
local dToolDoubleDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM, 'd')
|
|
local dToolDoubleMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT)
|
|
dMachiningDepth = min( dMachiningDepth, dToolDoubleMaxDepth)
|
|
-- recupero la lunghezza della parte inclinata della punta
|
|
local dToolDoubleTipLength = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) - EgtTdbGetCurrToolParam( MCH_TP.LEN)
|
|
-- se foratura splittata, verifico che la distanza minima tra le due punte sia rispettata
|
|
local dTipDistance = 2 * dDrillingStep - dToolTipLength - dToolDoubleTipLength
|
|
if abs( Proc.Flg) == 2 and not ( ( dTipDistance - MIRROR_DRILLINGS_MIN_DISTANCE) > 10 * GEO.EPS_SMALL) then
|
|
EgtOutLog( 'Double drilling skipped, tip distance too small ( ' .. dTipDistance .. ' mm) ')
|
|
return
|
|
end
|
|
-- verifico se in doppio
|
|
if ( abs( dToolDiam - dToolDoubleDiam) < 10 * GEO.EPS_SMALL) then
|
|
if Proc.Fce ~= 0 or Proc.Mirror then
|
|
if Proc.Flg == -2 then vtExtr = -vtExtr end
|
|
local ProcToDisable = EgtIf( abs( Proc.Flg) == 2, Proc, Proc.Mirror)
|
|
if ( not BD.DOWN_HEAD and AreSameVectorApprox( vtExtr, Y_AX())) or
|
|
( BD.DOWN_HEAD and AreOppositeVectorApprox( vtExtr, Y_AX())) then
|
|
Proc.Double = 2
|
|
Proc.MachDepthDouble = dMachiningDepth
|
|
Proc.MirrorId = ProcToDisable.Id
|
|
Proc.MirrorCutId = ProcToDisable.CutId
|
|
Proc.MirrorTaskId = ProcToDisable.TaskId
|
|
DisableOtherDrilling( ProcToDisable, vProc)
|
|
elseif BD.DOWN_HEAD and AreSameVectorApprox( vtExtr, Z_AX()) then
|
|
Proc.Double = 3
|
|
Proc.MachDepthDouble = dMachiningDepth
|
|
Proc.MirrorId = ProcToDisable.Id
|
|
Proc.MirrorCutId = ProcToDisable.CutId
|
|
Proc.MirrorTaskId = ProcToDisable.TaskId
|
|
DisableOtherDrilling( ProcToDisable, vProc)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- Cerca in vProc la presenza di feature da lavorare in doppio. Se le trova scrive in Proc la direzione di specchiatura e l'utensile da utilizzare.
|
|
local function SetMirroredFeatures( vProc, b3Raw)
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
if Proc.Flg ~= 0 then
|
|
-- Proc.Double -> 0: nessuna specchiatura, 1: specchiatura X, 2: specchiatura Y, 3: specchiatura Z
|
|
-- Proc.MirrorId -> Id della feature mirrorata
|
|
if DtMortise.SideIdentify( Proc) and BD.DOUBLE_HEAD_DOVETAIL then
|
|
VerifyDtMortiseMirrored( Proc, vProc, b3Raw)
|
|
elseif Mortise.SideIdentify( Proc) and BD.DOUBLE_HEAD_MORTISE then
|
|
VerifyMortiseMirrored( Proc, vProc, b3Raw)
|
|
elseif Drill.Identify( Proc) and BD.DOUBLE_HEAD_DRILLING then
|
|
VerifyDrillMirrored( Proc, vProc, b3Raw)
|
|
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
|
|
if vProc[i].Dependency and vProc[i].Dependency.ExecAfter and vProc[i].Dependency.ExecAfter.Id == vMachineBeforeIntersectingDrillings.Head.Id then
|
|
vProc[i].MachineAfterHeadCutId = vMachineBeforeIntersectingDrillings.Head.Id
|
|
end
|
|
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
|
|
if vProc[i].Dependency and vProc[i].Dependency.ExecAfter and vProc[i].Dependency.ExecAfter.Id == vMachineBeforeIntersectingDrillings.Tail.Id then
|
|
vProc[i].MachineAfterTailCutId = vMachineBeforeIntersectingDrillings.Tail.Id
|
|
end
|
|
vProc[i].Tail = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function AreDrillingsMirrored( Proc, ProcMirror, b3Raw)
|
|
if Proc.Id == ProcMirror.Id then return false end
|
|
|
|
-- geometria ausiliaria foro principale
|
|
AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or EgtGetType( AuxId ) ~= GDB_TY.CRV_ARC then return false end
|
|
-- geometria ausiliaria foro specchiato
|
|
local AuxIdMirror = EgtGetInfo( ProcMirror.Id, 'AUXID', 'i')
|
|
if AuxIdMirror then AuxIdMirror = AuxIdMirror + ProcMirror.Id end
|
|
if not AuxIdMirror or EgtGetType( AuxIdMirror ) ~= GDB_TY.CRV_ARC then return false end
|
|
-- dati del foro principale
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local ptBC = EgtGP( AuxId, GDB_RT.GLOB)
|
|
-- dati del foro specchiato
|
|
local vtExtrMirror = EgtCurveExtrusion( AuxIdMirror, GDB_RT.GLOB)
|
|
local ptBCMirror = EgtGP( AuxIdMirror, GDB_RT.GLOB)
|
|
|
|
-- direzione fori
|
|
local nDouble
|
|
if AreOppositeVectorApprox( vtExtr, vtExtrMirror) then
|
|
-- fori lungo Y
|
|
-- per macchine tipo PF il foro principale è sul lato back, per macchine tipo PF1250 è sul lato front
|
|
if ( BD.TWO_EQUAL_HEADS and AreSameVectorApprox( vtExtr, Y_AX())) or
|
|
( BD.DOWN_HEAD and AreOppositeVectorApprox( vtExtr, Y_AX())) then
|
|
nDouble = 2
|
|
-- fori lungo Z
|
|
elseif BD.DOWN_HEAD and AreSameVectorApprox( vtExtr, Z_AX()) then
|
|
nDouble = 3
|
|
else
|
|
return false
|
|
end
|
|
else
|
|
return false
|
|
end
|
|
|
|
-- centri allineati, equidistanti dalla mezzeria trave, non troppo vicini
|
|
local vtDisplacement = ptBC - ptBCMirror
|
|
local ptCenRaw = b3Raw:getCenter()
|
|
if nDouble == 2 then
|
|
local dYMinDistance = max( Proc.Box:getMin():getY(), ProcMirror.Box:getMin():getY()) - min( Proc.Box:getMax():getY(), ProcMirror.Box:getMax():getY())
|
|
if not ( abs( vtDisplacement:getX()) < 100 * GEO.EPS_SMALL and abs( vtDisplacement:getZ()) < 100 * GEO.EPS_SMALL and
|
|
( abs( ptBC:getY() - ptCenRaw:getY()) - abs( ptBCMirror:getY() - ptCenRaw:getY())) < 100 * GEO.EPS_SMALL and
|
|
dYMinDistance > MIRROR_DRILLINGS_MIN_DISTANCE + 10 * GEO.EPS_SMALL) then
|
|
return false
|
|
end
|
|
else
|
|
local dZMinDistance = max( Proc.Box:getMin():getZ(), ProcMirror.Box:getMin():getZ()) - min( Proc.Box:getMax():getZ(), ProcMirror.Box:getMax():getZ())
|
|
if not ( abs( vtDisplacement:getX()) < 100 * GEO.EPS_SMALL and abs( vtDisplacement:getY()) < 100 * GEO.EPS_SMALL and
|
|
( abs( ptBC:getZ() - ptCenRaw:getZ()) - abs( ptBCMirror:getZ() - ptCenRaw:getZ())) < 100 * GEO.EPS_SMALL and
|
|
dZMinDistance > MIRROR_DRILLINGS_MIN_DISTANCE + 10 * GEO.EPS_SMALL) then
|
|
return false
|
|
end
|
|
end
|
|
|
|
-- fori della stessa profondità
|
|
if abs( Proc.Len - ProcMirror.Len) > 10 * GEO.EPS_SMALL then
|
|
return false
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function GetFeatureInfoAndDependency( vProc, b3Raw, nPartId)
|
|
if vProc and #vProc > 0 and nPartId then
|
|
-- recupero ID per tagli troncanti testa e coda
|
|
local nHeadCuttingFeatureId = EgtGetInfo( nPartId, 'HEADCUTFEATUREID', 'i') or 0
|
|
local nTailCuttingFeatureId = EgtGetInfo( nPartId, 'TAILCUTFEATUREID', 'i') or 0
|
|
-- ciclo tutte le feature
|
|
for i = 1, #vProc do
|
|
local Proc = vProc[i]
|
|
-- calcolo topologia della feature
|
|
if NeedTopologyFeature( Proc) then
|
|
Topology.Classify( Proc, b3Raw)
|
|
-- se non richiesto, setto 'SPECIAL'
|
|
else
|
|
Proc.Topology = 'SPECIAL'
|
|
Proc.TopologyLongName = Proc.Topology
|
|
end
|
|
-- controllo la feature con tutte le altre per recuperare le dipendenze
|
|
for j = 1, #vProc do
|
|
-- non si controlla feature con sé stessa
|
|
if i ~= j then
|
|
local ProcB = vProc[j]
|
|
-- verifico se feature tipo LapJoint è attraversata da almeno un foro
|
|
if ( Proc.Topology == 'Pocket' or Proc.Topology == 'Tunnel' or Proc.Topology == 'Groove' or Mortise.Identify( Proc)) and Drill.Identify( ProcB) and Overlaps( Proc.Box, ProcB.Box) then
|
|
-- se foro in coda non setto la dipendenza
|
|
if not ProcB.AffectedFaces.Left then
|
|
Proc.PassedByHole = true
|
|
ProcB.Dependency = {}
|
|
ProcB.Dependency.ExecBefore = Proc
|
|
end
|
|
end
|
|
-- verifico se feature tipo LapJoint è attraversata da almeno una mortasa a coda di rondine
|
|
if ( Proc.Topology == 'Pocket' or Proc.Topology == 'Tunnel' or Proc.Topology == 'Groove')
|
|
and DtMortise.SideIdentify( ProcB) and Overlaps( Proc.Box, ProcB.Box) and DtMortise.IsDeeper( ProcB, b3Raw) then
|
|
Proc.PassedByDtMortise = true
|
|
end
|
|
-- se tenone è attraversato da foro allora il foro deve essere fatto prima
|
|
if Tenon.Identify( Proc) and Drill.Identify( ProcB) and Overlaps( Proc.Box, ProcB.Box) then
|
|
Proc.PassedByHole = true
|
|
end
|
|
-- se taglio attraversato da foro, si definisce precedenza in base ad angolo
|
|
if Drill.Identify( Proc) and Cut.Identify( ProcB) and Overlaps( Proc.Box, ProcB.Box) then
|
|
-- recupero e verifico l'entità foro
|
|
local DrillAuxId = ( EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0) + Proc.Id
|
|
local vtDrillExtr = EgtCurveExtrusion( DrillAuxId, GDB_RT.GLOB)
|
|
local bOpen = ( Proc.Fce ~= 0) and ( Proc.Fce ~= Proc.Fcs)
|
|
local ptCut, vtCutN = EgtSurfTmFacetCenter( ProcB.Id, 0, GDB_ID.ROOT)
|
|
local dMaxAngleDrillOnCut = BD.MAX_ANGLE_DRILL_CUT or 10
|
|
if GetAngle( vtDrillExtr, vtCutN) > dMaxAngleDrillOnCut then
|
|
if bOpen and GetAngle( -vtDrillExtr, vtCutN) < dMaxAngleDrillOnCut then
|
|
ProcB.Dependency = {}
|
|
ProcB.Dependency.ExecBefore = Proc
|
|
Proc.Dependency = {}
|
|
Proc.Dependency.ExecAfter = ProcB
|
|
else
|
|
Proc.Dependency = {}
|
|
Proc.Dependency.ExecBefore = ProcB
|
|
ProcB.Dependency = {}
|
|
ProcB.Dependency.ExecAfter = Proc
|
|
end
|
|
else
|
|
ProcB.Dependency = {}
|
|
ProcB.Dependency.ExecBefore = Proc
|
|
Proc.Dependency = {}
|
|
Proc.Dependency.ExecAfter = ProcB
|
|
end
|
|
end
|
|
-- verifiche per specchiature
|
|
if BD.DOWN_HEAD or BD.TWO_EQUAL_HEADS then
|
|
-- forature
|
|
if BD.DOUBLE_HEAD_DRILLING and Drill.Identify( Proc) and Drill.Identify( ProcB) and not Proc.Mirror then
|
|
if AreDrillingsMirrored( Proc, ProcB, b3Raw) then
|
|
Proc.Mirror = ProcB
|
|
end
|
|
end
|
|
end
|
|
-- verifiche per tagli troncanti testa e coda: devono sempre essere subito dopo il taglio di testa e il taglio di coda, rispettivamente
|
|
if Proc.Prc == 340 and ProcB == nHeadCuttingFeatureId then
|
|
Proc.Dependency = {}
|
|
Proc.Dependency.ExecBefore = ProcB
|
|
elseif Proc == nHeadCuttingFeatureId and ProcB.Prc == 340 then
|
|
ProcB.Dependency = {}
|
|
ProcB.Dependency.ExecBefore = Proc
|
|
elseif Proc.Prc == 350 and ProcB == nTailCuttingFeatureId then
|
|
Proc.Dependency = {}
|
|
Proc.Dependency.ExecBefore = ProcB
|
|
elseif Proc == nTailCuttingFeatureId and ProcB.Prc == 350 then
|
|
ProcB.Dependency = {}
|
|
ProcB.Dependency.ExecBefore = Proc
|
|
end
|
|
-- se una feature deve essere lavorata prima dei tagli troncanti, si setta che non esiste taglio troncante
|
|
if Proc.Dependency and Proc.Dependency.ExecBefore and Proc.Dependency.ExecBefore.Id == nHeadCuttingFeatureId then
|
|
-- EgtRemoveInfo( nPartId, 'HEADCUTFEATUREID')
|
|
end
|
|
if Proc.Dependency and Proc.Dependency.ExecBefore and Proc.Dependency.ExecBefore.Id == nTailCuttingFeatureId then
|
|
-- EgtRemoveInfo( nPartId, 'TAILCUTFEATUREID')
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function BeamExec.ProcessFeatures()
|
|
if BD.IMPROVE_HEAD_TAIL_DRILLINGS == nil then
|
|
BD.IMPROVE_HEAD_TAIL_DRILLINGS = true
|
|
end
|
|
-- costanti per doppio
|
|
MIRROR_DRILLINGS_MIN_DISTANCE = 40
|
|
MIRROR_POCKETS_MIN_DISTANCE = EgtIf( BD.DOWN_HEAD, 35, 50)
|
|
-- 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 = CollectFeatures( nPartId, b3Raw, dCurrOvmH, dCurrOvmT)
|
|
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
|
|
GetFeatureInfoAndDependency( vProc, b3Raw, nPartId)
|
|
|
|
-- verifica presenza forature influenzate da lavorazioni di testa o coda
|
|
if BD.IMPROVE_HEAD_TAIL_DRILLINGS then
|
|
local vMachBeforeIntersDrillings = CalcHeadTailMachBeforeIntersDrillings( vProc, b3Raw)
|
|
SetDrillingsToMachineAfterHeadOrTailCut( vProc, vMachBeforeIntersDrillings)
|
|
end
|
|
-- verifica presenza di feature specchiate per eventuali lavorazioni simultanee
|
|
if BD.TWO_EQUAL_HEADS or BD.DOWN_HEAD then
|
|
SetMirroredFeatures( vProc, b3Raw)
|
|
end
|
|
-- le ordino lungo X
|
|
OrderFeatures( vProc, b3Raw, nPartId)
|
|
-- 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)
|
|
-- scrivo nel RawPart se ci sono feature lavorate con trave ruotata a 90 o 180 deg
|
|
if bSomeSide then
|
|
EgtSetInfo( nRawId, 'ROTATE90', 1)
|
|
else
|
|
EgtSetInfo( nRawId, 'ROTATE90', 0)
|
|
end
|
|
if bSomeDown then
|
|
EgtSetInfo( nRawId, 'ROTATE180', 1)
|
|
else
|
|
EgtSetInfo( nRawId, 'ROTATE180', 0)
|
|
end
|
|
-- 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)
|
|
-- flag feature precedente in doppio
|
|
local nPrevDouble = 0
|
|
-- inserisco le lavorazioni da lavorare ribaltate
|
|
local i = 1
|
|
while i <= #vProc do
|
|
-- creo la lavorazione
|
|
local Proc = vProc[i]
|
|
if Proc.Flg ~= 0 and Proc.Down then
|
|
-- dato che ho ruotato, aggiorno alcune proprietà della feature
|
|
Proc.Box = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD)
|
|
Proc.Face = BL.GetFacetsInfo( Proc, b3Raw)
|
|
Proc.AffectedFaces = BL.GetProcessAffectedFaces( Proc)
|
|
Proc.DistanceToNextPart = BL.GetDistanceToNextPart( nRawId, nPhase)
|
|
Proc.PrevDouble = nPrevDouble
|
|
nPrevDouble = Proc.Double
|
|
local bOk, sMsg, nNewPhase, AddedIds = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut, b3Raw, nOrd, sDownOrSideOrStd, nil, nil, dCurrOvmT)
|
|
-- lavorazioni da fare dopo separazione
|
|
if AddedIds and #AddedIds > 0 then
|
|
for j = 1, #AddedIds do
|
|
table.insert( vProc, AddedIds[j])
|
|
end
|
|
end
|
|
if not bOk then
|
|
nTotErr = nTotErr + 1
|
|
table.insert( Stats, {Err=1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId, ProcId = Proc.Id, PartId = nPartId})
|
|
if Proc.Double == 2 or Proc.Double == 3 then
|
|
table.insert( Stats, {Err=1, Msg=sMsg, Rot=-2, CutId=Proc.MirrorCutId, TaskId=Proc.MirrorTaskId, ProcId = Proc.MirrorId, PartId = nPartId})
|
|
end
|
|
elseif sMsg and #sMsg > 0 then
|
|
table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId, ProcId = Proc.Id, PartId = nPartId})
|
|
if Proc.Double == 2 or Proc.Double == 3 then
|
|
table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-2, CutId=Proc.MirrorCutId, TaskId=Proc.MirrorTaskId, ProcId = Proc.MirrorId, PartId = nPartId})
|
|
end
|
|
else
|
|
table.insert( Stats, {Err=0, Msg='', Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId, ProcId = Proc.Id, PartId = nPartId})
|
|
if Proc.Double == 2 or Proc.Double == 3 then
|
|
table.insert( Stats, {Err=0, Msg='', Rot=-2, CutId=Proc.MirrorCutId, TaskId=Proc.MirrorTaskId, ProcId = Proc.MirrorId, PartId = nPartId})
|
|
end
|
|
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
|
|
i = i + 1
|
|
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)
|
|
-- flag feature precedente in doppio
|
|
local nPrevDouble = 0
|
|
-- inserisco le lavorazioni da lavorare ruotate
|
|
local nSideMchOk = 0
|
|
local i = 1
|
|
while i <= #vProc do
|
|
-- creo la lavorazione
|
|
local Proc = vProc[i]
|
|
if Proc.Flg ~= 0 and Proc.Side then
|
|
-- dato che ho ruotato, aggiorno alcune proprietà della feature
|
|
Proc.Box = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD)
|
|
Proc.Face = BL.GetFacetsInfo( Proc, b3Raw)
|
|
Proc.AffectedFaces = BL.GetProcessAffectedFaces( Proc)
|
|
Proc.DistanceToNextPart = BL.GetDistanceToNextPart( nRawId, nPhase)
|
|
Proc.PrevDouble = nPrevDouble
|
|
nPrevDouble = Proc.Double
|
|
local bOk, sMsg, nNewPhase, AddedIds = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, false, b3Raw, nOrd, sDownOrSideOrStd, bPreMove, vtMove, dCurrOvmT)
|
|
-- lavorazioni da fare dopo separazione
|
|
if AddedIds and #AddedIds > 0 then
|
|
for j = 1, #AddedIds do
|
|
table.insert( vProc, AddedIds[j])
|
|
end
|
|
end
|
|
if not bOk then
|
|
nTotErr = nTotErr + 1
|
|
table.insert( Stats, {Err=1, Msg=sMsg, Rot=-1, CutId=Proc.CutId, TaskId=Proc.TaskId, ProcId = Proc.Id, PartId = nPartId})
|
|
if Proc.Double == 2 or Proc.Double == 3 then
|
|
table.insert( Stats, {Err=1, Msg=sMsg, Rot=-1, CutId=Proc.MirrorCutId, TaskId=Proc.MirrorTaskId, ProcId = Proc.MirrorId, PartId = nPartId})
|
|
end
|
|
elseif sMsg and #sMsg > 0 then
|
|
table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-1, CutId=Proc.CutId, TaskId=Proc.TaskId, ProcId = Proc.Id, PartId = nPartId})
|
|
if Proc.Double == 2 or Proc.Double == 3 then
|
|
table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-1, CutId=Proc.MirrorCutId, TaskId=Proc.MirrorTaskId, ProcId = Proc.MirrorId, PartId = nPartId})
|
|
end
|
|
else
|
|
table.insert( Stats, {Err=0, Msg='', Rot=-1, CutId=Proc.CutId, TaskId=Proc.TaskId, ProcId = Proc.Id, PartId = nPartId})
|
|
if Proc.Double == 2 or Proc.Double == 3 then
|
|
table.insert( Stats, {Err=0, Msg='', Rot=-1, CutId=Proc.MirrorCutId, TaskId=Proc.MirrorTaskId, ProcId = Proc.MirrorId, PartId = nPartId})
|
|
end
|
|
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
|
|
i = i + 1
|
|
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'
|
|
-- flag feature precedente in doppio
|
|
local nPrevDouble = 0
|
|
-- inserisco le lavorazioni non ribaltate della trave
|
|
local i = 1
|
|
while i <= #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
|
|
-- dato che ho ruotato, aggiorno alcune proprietà della feature
|
|
Proc.Box = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD)
|
|
Proc.Face = BL.GetFacetsInfo( Proc, b3Raw)
|
|
Proc.AffectedFaces = BL.GetProcessAffectedFaces( Proc)
|
|
Proc.DistanceToNextPart = BL.GetDistanceToNextPart( nRawId, nPhase)
|
|
Proc.PrevDouble = nPrevDouble
|
|
nPrevDouble = Proc.Double
|
|
local bOk, sMsg, nNewPhase, AddedIds = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, false, b3Raw, nOrd, sDownOrSideOrStd, nil, nil, dCurrOvmT)
|
|
-- lavorazioni da fare dopo separazione
|
|
if AddedIds and #AddedIds > 0 then
|
|
for j = 1, #AddedIds do
|
|
table.insert( vProc, AddedIds[j])
|
|
end
|
|
end
|
|
if not bOk then
|
|
nTotErr = nTotErr + 1
|
|
table.insert( Stats, {Err=1, Msg=sMsg, Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId, ProcId = Proc.Id, PartId = nPartId})
|
|
if Proc.Double == 2 or Proc.Double == 3 then
|
|
table.insert( Stats, {Err=1, Msg=sMsg, Rot=0, CutId=Proc.MirrorCutId, TaskId=Proc.MirrorTaskId, ProcId = Proc.MirrorId, PartId = nPartId})
|
|
end
|
|
elseif sMsg and #sMsg > 0 then
|
|
table.insert( Stats, {Err=-1, Msg=sMsg, Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId, ProcId = Proc.Id, PartId = nPartId})
|
|
if Proc.Double == 2 or Proc.Double == 3 then
|
|
table.insert( Stats, {Err=-1, Msg=sMsg, Rot=0, CutId=Proc.MirrorCutId, TaskId=Proc.MirrorTaskId, ProcId = Proc.MirrorId, PartId = nPartId})
|
|
end
|
|
else
|
|
table.insert( Stats, {Err=0, Msg='', Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId, ProcId = Proc.Id, PartId = nPartId})
|
|
if Proc.Double == 2 or Proc.Double == 3 then
|
|
table.insert( Stats, {Err=0, Msg='', Rot=0, CutId=Proc.MirrorCutId, TaskId=Proc.MirrorTaskId, ProcId = Proc.MirrorId, PartId = nPartId})
|
|
end
|
|
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
|
|
i = i + 1
|
|
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
|