6eef34f1ef
- in longCut/longDoubleCut rimossa la pulitura della faccia laterale nel caso in cui la feature abbia almeno una faccia rivolta verso il basso
5806 lines
277 KiB
Lua
5806 lines
277 KiB
Lua
-- ProcessLapJoint.lua by Egaltech s.r.l. 2022/12/21
|
|
-- Gestione calcolo mezzo-legno per Travi
|
|
-- 2019/10/08 Agg. gestione OpenPocket.
|
|
-- 2021/01/24 Con sega a catena ora sempre impostato asse A.
|
|
-- 2021/02/03 Corretto riconoscimento feature di coda.
|
|
-- 2021/02/04 Razionalizzata gestione forzatura lama. Corretta gestione diametro minimo utensile per svuotatura.
|
|
-- 2021/03/04 Due facce con testa da sotto.
|
|
-- 2021/03/20 Piccole correzioni.
|
|
-- 2021/03/22 Modificata gestione caso due facce lunghe come la trave con trave corta.
|
|
-- 2021/04/13 Modificata gestione fessura U con sega a catena (corta ora ok, lunga ancora da correggere).
|
|
-- 2021/04/14 Correzioni ribasso a U con fresa da sotto.
|
|
-- 2021/04/15 Aggiunta gestione massima lunghezza fresa da sotto su svuotature.
|
|
-- 2021/04/21 Anche feature lunga con due facce con opzione lama ora si taglia con lama.
|
|
-- 2021/04/23 Corretto caso con antischeggia non inseriti perchè inutili.
|
|
-- 2021/04/27 Antischeggia solo se feature trasversali.
|
|
-- 2021/05/12 Semplificata gestione diametro minimo utensile per svuotatura.
|
|
-- 2021/06/04 Su U passante con faccia perpendicolare aggiunta si forza Pocket.
|
|
-- 2021/06/11 Su U passante e profonda se non bastano due svuotature su faccia ortogonale si fa anche la faccia di fondo per quanto possibile.
|
|
-- 2021/06/21 Nel caso precedente si fa la terza svuotatura anche se è possibile fare una sola delle prime due (altra da sotto).
|
|
-- 2021/06/21 Gestione ripresa spigoli o contorno con fresa più piccola ( diametro < 3/4 utensile svuotatura) attivata da parametro Q.
|
|
-- 2021/07/02 Migliorie e correzioni su svuotature e pulitura spigoli.
|
|
-- 2021/07/15 Aggiunti antischeggia con fresa.
|
|
-- 2021/09/08 Aggiunta gestione parametro Q04 per i tagli di lama lungo facce lunghe (con o senza facce di chiusura)
|
|
-- 2021/09/21 Aggiunta lavorazione/opzione "lamello" con le feature 16, 30, 32, 39,
|
|
-- che si attiva abilitando il check al tipo milling: SideMillAsBlade (SideMillAsBlade_2)
|
|
-- 2021/09/23 Gestione migliorata lavorazioni BH (blockhaus) su macchina fast BH,
|
|
-- migliorata applicazione lavorazioni BH su feature lunghe lavorte a passi
|
|
-- 2021/10/06 Ad antischeggia con lama in presenza di testa da sotto aggiunta preferenza a testa da sopra.
|
|
-- 2021/10/19 Corretta gestione inversione per Tunnel. OpenPocket anche se spezzato ma 1 o 2 facce. Introdotta lunghezza minima per lamello.
|
|
-- 2021/10/21 Migliorato controllo affondamento utensile in U lavorato da 3 parti (anche da sotto).
|
|
-- 2021/10/27 Migliorato calcolo asse tunnel o similare.
|
|
-- 2021/11/02 In svuotatura con lati aperti diametro fresa non superiore al doppio del lato piccolo.
|
|
-- 2021/11/15 Quando si usa sega a catena uso Q10 come massima elevazione.
|
|
-- 2021/11/22 Corretta segnalazione warning su foro di L20 e L25.
|
|
-- 2022/01/19 Cambiata % lunghezza pezzo per spezzatura. Tolta correzione spessore fresa a disco con superficie da lavorare verso Z-.
|
|
-- 2022/01/26 Migliorato controllo uso testa da sotto nel caso due facce con lama.
|
|
-- 2022/02/07 Corretto caso con due facce che non è un LongDoubleCut ma che veniva identificato come tale.
|
|
-- 2022/02/14 Introdotto uso svuotature ZigZag ottimizzate.
|
|
-- 2022/03/18 Corretta lavorazione BH.
|
|
-- 2022/03/21 Quando si usa lama uso Q10 come massima elevazione.
|
|
-- 2022/03/29 Aggiunta gestione antischeggia con Q06 anche su 3/4-033-X.
|
|
-- 2022/04/28 Lavorazione BH forzata sempre OneWay.
|
|
-- 2022/05/04 Corretta classificazione due facce sotto. Modificati criteri assegnazione due facce alla coda.
|
|
-- 2022/05/24 Miglioramenti vari per BH, compreso controlli per lavorazione da sotto.
|
|
-- 2022/06/13 Modifiche per feature lunga con due facce non equivalenti a taglio long. doppio o singolo con faccia terminale.
|
|
-- 2022/06/15 Correzione calcolo normale alla faccia per sega catena di fianco.
|
|
-- 2022/06/16 Implemento lavorazioni con fresatura di lato per L30 (al momento solo passanti) se parametro Q03=2. Modificate funzioni Make, MakeMoreFaces, Classify.
|
|
-- 2022/06/21 Implemento di lavorazioni non passanti con fresatura di lato per L30 se parametro Q03=2. Modificate funzioni MakeMoreFaces, Classify.
|
|
-- 2022/06/29 Migliorate lavorazioni con fresatura di lato per L30 se parametro Q03=2. Ora con 4 facce / 3 facce a L può entrare una fresa grande fino al doppio dell'altezza della tasca / doppio della dimensione minima.
|
|
-- 2022/07/05 Modifiche per sega a catena di testa e relativa MaxElev.
|
|
-- 2022/07/12 In MakeByChainOrSaw aggiunto check per feature L20 usata in modo improprio e, nel caso, si passa a una lavorazione tasca.
|
|
-- 2022/08/11 Aggiunta lavorazione tunnel splittata con sega a catena per tutte le macchine ad esclusione della Fast.
|
|
-- 2022/09/01 Spostate le funzioni GetTunnelDimension, CalcCollisionSafety, SetOpenSide in BeamLib.
|
|
-- 2022/09/15 Implementata gestione feature Planing L090, gestita come LapJoint
|
|
-- Implementata, in caso di fresatura di lato con altezza tasca molto bassa, la contornatura con unica passata
|
|
-- Migliorata gestione AntiSplint (Mill e Saw)
|
|
-- 2022/09/27 Aggiunta gestione SCC per svuotature con TURN (solo dopo applicazione lavorazione).
|
|
-- 2022/10/20 In MakeByChainOrSaw modificato check per trovare la faccia adiacente sul lato più lungo.
|
|
-- 2022/12/12 Default 1000 per BD.MIN_LEN_LAMELLO. In MachineByMill migliorata ricerca utensile e gestione inversione in funzione del lato di lavoro.
|
|
-- 2022/12/16 Implementato parametro Q_SIDE_ROUGH_TOOL anche per L20
|
|
-- 2022/12/21 Sistemata gestione SideMillAsSaw.
|
|
-- 2023/01/19 In MakeMoreFaces -> MakeBySideMill aggiunto controllo che lo step finale non superi lo spessore utensile.
|
|
-- 2023/01/24 In MakeByPocket gestito caso il caso in cui veniva applicata una fresatura con percorso vuoto. Ora viene rimossa e la tasca viene fatta con lama.
|
|
|
|
-- Tabella per definizione modulo
|
|
local ProcessLapJoint = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local BL = require( 'BeamLib')
|
|
local Fbs = require( 'FacesBySaw')
|
|
local Cut = require( 'ProcessCut')
|
|
local DoubleCut = require( 'ProcessDoubleCut')
|
|
local LongCut = require( 'ProcessLongCut')
|
|
local Long2Cut = require( 'ProcessLongDoubleCut')
|
|
|
|
EgtOutLog( ' ProcessLapJoint started', 1)
|
|
|
|
-- Dati
|
|
local BD = require( 'BeamData')
|
|
local ML = require( 'MachiningLib')
|
|
|
|
-- variabili assegnazione parametri Q
|
|
local Q_FORCE_BLADE = '' -- i
|
|
local Q_DEPTH_CHAMFER = '' -- d
|
|
local Q_ONLY_CHAMFER = '' -- i
|
|
local Q_USE_MILL = '' -- i
|
|
local Q_USE_ROUGH_TOOL = '' -- i
|
|
local Q_BORE_ON_CORNER = '' -- 1
|
|
local Q_CONTOUR_SMALL_TOOL = '' -- i
|
|
local Q_ONLY_CONTOUR = '' -- i
|
|
local Q_SIDE_ROUGH_TOOL = '' -- i
|
|
local Q_ANTISPLINT_TYPE = '' -- i
|
|
local Q_BLADE_ON_ALONG_FACE = '' -- i
|
|
local Q_MAX_ELEVATION = '' -- d
|
|
|
|
-- variabile smussi
|
|
local bMadeChamfer
|
|
|
|
-- Settaggi interni
|
|
local bTrySidePocketAtFirst = true
|
|
|
|
---------------------------------------------------------------------
|
|
-- Riconoscimento della feature
|
|
function ProcessLapJoint.Identify( Proc)
|
|
return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 33) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 90) or
|
|
( Proc.Grp == 4 and Proc.Prc == 37) or
|
|
( Proc.Grp == 4 and Proc.Prc == 39) or
|
|
( Proc.Grp == 4 and Proc.Prc == 120))
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AssignQIdent( Proc)
|
|
|
|
-- reset assegnazione parametri Q
|
|
Q_FORCE_BLADE = ''
|
|
Q_DEPTH_CHAMFER = ''
|
|
Q_ONLY_CHAMFER = ''
|
|
Q_USE_MILL = ''
|
|
Q_USE_ROUGH_TOOL = ''
|
|
Q_BORE_ON_CORNER = ''
|
|
Q_CONTOUR_SMALL_TOOL = ''
|
|
Q_ONLY_CONTOUR = ''
|
|
Q_SIDE_ROUGH_TOOL = ''
|
|
Q_ANTISPLINT_TYPE = ''
|
|
Q_MAX_ELEVATION = 'Q10'
|
|
|
|
if ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16 then
|
|
Q_FORCE_BLADE = 'Q01' -- i
|
|
Q_DEPTH_CHAMFER = 'Q04' -- d
|
|
Q_ONLY_CHAMFER = 'Q05' -- i
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17 then
|
|
Q_DEPTH_CHAMFER = 'Q01' -- d
|
|
Q_ONLY_CHAMFER = 'Q02' -- i
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20 then
|
|
Q_DEPTH_CHAMFER = 'Q01' -- d
|
|
Q_USE_MILL = 'Q02' -- i
|
|
Q_USE_ROUGH_TOOL = 'Q03' -- i
|
|
Q_SIDE_ROUGH_TOOL = 'Q04' -- i
|
|
Q_BORE_ON_CORNER = 'Q06' -- i
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25 then
|
|
Q_BORE_ON_CORNER = 'Q01' -- i
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then
|
|
Q_CONTOUR_SMALL_TOOL = 'Q01' -- i
|
|
Q_ONLY_CONTOUR = 'Q02' -- i
|
|
Q_SIDE_ROUGH_TOOL = 'Q03' -- i
|
|
Q_BLADE_ON_ALONG_FACE = 'Q04' -- i
|
|
Q_ANTISPLINT_TYPE = 'Q06' -- i
|
|
Q_DEPTH_CHAMFER = 'Q07' -- d
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32 then
|
|
Q_SIDE_ROUGH_TOOL = 'Q01' -- i
|
|
Q_CONTOUR_SMALL_TOOL = 'Q02' -- i
|
|
Q_ANTISPLINT_TYPE = 'Q06' -- i
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 33 then
|
|
Q_ANTISPLINT_TYPE = 'Q06' -- i
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34 then
|
|
Q_CONTOUR_SMALL_TOOL = 'Q01' -- i
|
|
Q_USE_MILL = 'Q02' -- i
|
|
Q_ANTISPLINT_TYPE = 'Q06' -- i
|
|
elseif ( Proc.Grp == 4) and Proc.Prc == 37 then
|
|
Q_ANTISPLINT_TYPE = 'Q06' -- i
|
|
elseif ( Proc.Grp == 4) and Proc.Prc == 39 then
|
|
Q_CONTOUR_SMALL_TOOL = 'Q01' -- i
|
|
Q_USE_MILL = 'Q02' -- i
|
|
Q_ANTISPLINT_TYPE = 'Q06' -- i
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 90 then
|
|
Q_ANTISPLINT_TYPE = 'Q03' -- i
|
|
Q_SIDE_ROUGH_TOOL = 'Q04' -- i
|
|
end
|
|
-- le altre features gestite non hanno parametri Q
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function EvaluateQParam( Proc)
|
|
-- verifico che lo smusso sia richiesto
|
|
local nChamfer = 0
|
|
local dDepth = EgtGetInfo( Proc.Id, Q_DEPTH_CHAMFER, 'd') or 0
|
|
if dDepth > 0 then
|
|
nChamfer = 1
|
|
end
|
|
-- verifico se posso fare solo lo smusso
|
|
if EgtGetInfo( Proc.Id, Q_ONLY_CHAMFER, 'i') == 1 then
|
|
if dDepth > 0 then
|
|
nChamfer = nChamfer + 1
|
|
-- altrimenti se non ho l'affondamento esco
|
|
else
|
|
local sErr = 'Error : no chamfer depth'
|
|
EgtOutLog( sErr)
|
|
return -1, dDepth, sErr
|
|
end
|
|
end
|
|
-- verifico se devo usare lama invece della sega-catena
|
|
-- 2020-03-20 forzata abilitazione uso lama se parametro Q non è presente
|
|
-- xxxx-xx-xx tolta la preferenza alla lama in favore della sega-catena per un caso particolare
|
|
-- 2021-02-15 re-introdotta la preferenza alla lama se non c'è il parametro Q. Rimane da
|
|
-- implementare un ulteriore parametro per poter scegliere di prediligere la sega-catena o no al fine di continuare
|
|
-- a cambiare il codice per gestire il caso particolare
|
|
local bForceUseBlade = false
|
|
if #Q_FORCE_BLADE == 0 or EgtGetInfo( Proc.Id, Q_FORCE_BLADE, 'i') == 1 then
|
|
bForceUseBlade = true
|
|
end
|
|
|
|
return nChamfer, dDepth, sErr, bForceUseBlade
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TestElleShape3( Proc, bNotProc)
|
|
-- se non passato il Proc vero e proprio
|
|
local nNumFacet
|
|
local nProcId
|
|
if bNotProc then
|
|
nProcId = Proc
|
|
nNumFacet = EgtSurfTmFacetCount( nProcId)
|
|
else
|
|
nProcId = Proc.Id
|
|
nNumFacet = Proc.Fct
|
|
end
|
|
-- valida solo nel caso di tre facce
|
|
if nNumFacet ~= 3 then return false end
|
|
-- determino se L con una faccia terminale o U con tre facce
|
|
local bIsL = true
|
|
for i = 1, 3 do
|
|
local vFacAdj = EgtSurfTmFacetAdjacencies( nProcId, i - 1)[1]
|
|
-- le conto
|
|
local nCount = 0
|
|
for j = 1, #vFacAdj do
|
|
if vFacAdj[j] >= 0 then
|
|
nCount = nCount + 1
|
|
end
|
|
end
|
|
if nCount == 1 then
|
|
bIsL = false
|
|
break
|
|
end
|
|
end
|
|
return bIsL
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TestElleShape4( Proc)
|
|
-- valida solo nel caso di quattro facce
|
|
if Proc.Fct ~= 4 then return false end
|
|
-- determino se L con due facce terminali o O
|
|
local nFac3Adj = 0
|
|
local dMinArea3 = GEO.INFINITO * GEO.INFINITO
|
|
local dMaxArea2 = 0
|
|
for i = 1, 4 do
|
|
local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1]
|
|
-- le conto
|
|
local nCount = 0
|
|
for j = 1, #vFacAdj do
|
|
if vFacAdj[j] >= 0 then
|
|
nCount = nCount + 1
|
|
end
|
|
end
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, i - 1, GDB_ID.ROOT)
|
|
local dArea = dH * dV
|
|
if nCount == 2 then
|
|
dMaxArea2 = max( dMaxArea2, dArea)
|
|
elseif nCount == 3 then
|
|
dMinArea3 = min( dMinArea3, dArea)
|
|
nFac3Adj = nFac3Adj + 1
|
|
end
|
|
end
|
|
if nFac3Adj ~= 2 then return false end
|
|
-- verifico se L profonda oppure lunga
|
|
if dMinArea3 < 2 * dMaxArea2 then
|
|
return 1
|
|
else
|
|
return 2
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifyChainSaw( Proc, dMinDim, dMaxDim)
|
|
local bUseChainSaw = false
|
|
local sMchFind = 'Sawing'
|
|
local sSawing = ML.FindSawing( sMchFind)
|
|
local dMaxMat = 0
|
|
local dSawCornerRad = 0
|
|
local dSawThick = 0
|
|
local dMaxDepth = 200
|
|
-- se non trova una lavorazione di sawing esco
|
|
if not sSawing then
|
|
return bUseChainSaw
|
|
else
|
|
-- recupero i dati dell'utensile
|
|
local dToolLength = 0
|
|
local dSawWidth = 75
|
|
if EgtMdbSetCurrMachining( sSawing) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength
|
|
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
|
|
dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth
|
|
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
|
|
dSawCornerRad = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) or dSawCornerRad
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
if dSawThick < dMinDim + 10 * GEO.EPS_SMALL and dSawWidth < dMaxDim + 10 * GEO.EPS_SMALL then
|
|
bUseChainSaw = true
|
|
end
|
|
end
|
|
end
|
|
return bUseChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick, dMaxDepth
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifyPocket( Proc, dDiam, dDepth, dMaxTotLen, sMchFindMaster, bPocketDown)
|
|
-- tipo di svuotatura
|
|
local sMchFind = EgtIf( sMchFindMaster and #sMchFindMaster > 0, sMchFindMaster, 'Pocket')
|
|
-- ricerca della svuotatura
|
|
local sPocketing
|
|
if dDepth then
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam, dDepth, dMaxTotLen, not bPocketDown, bPocketDown) or
|
|
ML.FindPocketing( sMchFind, dDiam, 0.8 * dDepth, dMaxTotLen, not bPocketDown, bPocketDown) or
|
|
ML.FindPocketing( sMchFind, dDiam, 0.6 * dDepth, dMaxTotLen, not bPocketDown, bPocketDown) or
|
|
ML.FindPocketing( sMchFind, dDiam, 0.4 * dDepth, dMaxTotLen, not bPocketDown, bPocketDown) or
|
|
ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen)
|
|
else
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen)
|
|
end
|
|
if not sPocketing then
|
|
return false
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local bUsePocketing = false
|
|
local dMaxDepth = 0
|
|
local dToolDiam = 0
|
|
if EgtMdbSetCurrMachining( sPocketing) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
bUsePocketing = true
|
|
end
|
|
return bUsePocketing, sPocketing, dMaxDepth, dToolDiam
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifyBHSideMill( Proc, bIsU, bIsL, bSinglePart, bPrevBhSideMill)
|
|
|
|
-- se non feature BlockHausHalfLap e non abilitato parametro Q per lavorarlo di fianco e non macchina BH esco
|
|
local nUseSideTool = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0
|
|
if Proc.Prc ~= 37 and nUseSideTool == 0 and not BD.BH_MACHINE then
|
|
return false
|
|
end
|
|
|
|
-- recupero l'ingombro della trave
|
|
local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL)
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
if not b3Solid then
|
|
return false
|
|
end
|
|
|
|
-- verifico se la funzione è lanciata da IsTailFeature o Classify
|
|
if bSinglePart == nil then
|
|
-- se lunghezza non richiede spezzatura setto la variabile bSinglePart
|
|
if not( ( Proc.Box:getDimX() > BD.LONGCUT_MAXLEN) or
|
|
( Proc.Box:getDimX() > 0.8 * b3Solid:getDimX() and Proc.Box:getDimX() > BD.LONGCUT_ENDLEN)) then
|
|
bSinglePart = true
|
|
end
|
|
end
|
|
|
|
-- determino se U o L(anche con 1 o 2 facce di terminazione)
|
|
bIsU = ( bIsU or ( Proc.Fct == 3 and not TestElleShape3( Proc)))
|
|
bIsL = ( bIsL or ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2))
|
|
|
|
-- le facce devono contenere X e quelle di chiusura devono essere perpendicolari a X
|
|
local bStopY, bStopZ
|
|
for i = 1, Proc.Fct do
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT)
|
|
if abs( vtN:getX()) > 0.001 and abs( vtN:getX()) < 0.999962 then
|
|
return false
|
|
end
|
|
if abs( vtN:getY()) > 0.866 then bStopY = true end
|
|
if abs( vtN:getZ()) > 0.866 then bStopZ = true end
|
|
end
|
|
if bStopY and bStopZ then
|
|
return false
|
|
end
|
|
|
|
-- se non U o L o singola faccia di multipla, non accettata
|
|
if not ( ( bIsU or bIsL or ( Proc.Fct == 1 and not bSinglePart)) and Proc.Box:getDimX() <= BD.LONGCUT_MAXLEN) then
|
|
return false
|
|
end
|
|
|
|
-- se risultato precedente di passo multiplo negativo, riporto il risultato del passo precedente
|
|
if bPrevBhSideMill ~= nil and not bPrevBhSideMill then
|
|
return false
|
|
end
|
|
|
|
-- recupero la lavorazione
|
|
local sMilling = ML.FindMilling( 'BHSideMill')
|
|
if not sMilling then
|
|
return false
|
|
end
|
|
|
|
-- recupero i dati dell'utensile
|
|
local dToolLength = 0
|
|
local dToolDiam = 0
|
|
local dToolMaxDepth = 0
|
|
local dToolThick = 0
|
|
local dToolFreeLen = 0
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength
|
|
dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam
|
|
local dToolThDiam = EgtTdbGetCurrToolThDiam() or 150
|
|
if ( EgtTdbGetCurrToolParam( MCH_TP.TYPE) & MCH_TF.SAWBLADE) ~= 0 then
|
|
dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() or dToolMaxDepth
|
|
dToolThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dToolThick
|
|
dToolFreeLen = dToolLength
|
|
else
|
|
dToolMaxDepth = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or 0.5 * ( dToolDiam - dToolThDiam)
|
|
dToolThick = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT)
|
|
dToolFreeLen = EgtTdbGetCurrToolMaxDepth() or dToolFreeLen
|
|
end
|
|
end
|
|
end
|
|
|
|
-- verifico se abbastanza larga (oppure L) rispetto all'utensile
|
|
if Proc.Box:getDimX() < dToolThick - 15 * GEO.EPS_SMALL and not bIsL then
|
|
return false
|
|
end
|
|
|
|
-- limiti trasversali
|
|
local dDepth = min( Proc.Box:getDimY(), Proc.Box:getDimZ())
|
|
if dDepth > dToolMaxDepth then
|
|
return false
|
|
end
|
|
|
|
-- limiti longitudinali
|
|
local dMinXF = Proc.Box:getMin():getX()
|
|
local dMaxXF = Proc.Box:getMax():getX()
|
|
local dMinT = b3Solid:getMin():getX()
|
|
local dMaxT = b3Solid:getMax():getX()
|
|
|
|
-- determino se è più vicino alla testa o alla coda (con offset per evitare problemi a metà)
|
|
local bHeadDir = ( dMaxT - dMinXF) < ( dMaxXF - dMinT) + 50
|
|
local bHead = bHeadDir
|
|
|
|
-- verifico se raggiungibile con la testa senza collisioni
|
|
local bUseBHSideMill = EgtIf( bHead, ( dMaxT - dMinXF), ( dMaxXF - dMinT)) < dToolFreeLen
|
|
-- se diametro utensile maggiore della testa
|
|
if BD.HEAD_DIM_FOR_BH and dToolDiam - 2 * dDepth > BD.HEAD_DIM_FOR_BH then
|
|
bHead = true
|
|
bUseBHSideMill = true
|
|
end
|
|
|
|
return bUseBHSideMill, bHead, bHeadDir, sMilling, dToolThick, dToolDiam
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifySideMillAsSaw( Proc, nAddGrpId, vtN, dDiam, dFacElev)
|
|
-- Verifico sia feature L016, L030, L032, L039
|
|
if not ( Proc.Prc == 16 or Proc.Prc == 30 or Proc.Prc == 32 or Proc.Prc == 39) then
|
|
return false
|
|
end
|
|
-- Verifico sia gola lungo X con 3 facce più eventuali terminali
|
|
local nTestId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
|
|
local bNewIsU
|
|
local nFaces = EgtSurfTmFacetCount( nTestId)
|
|
while nFaces >= 3 do
|
|
local bDeleteFace
|
|
local nInt = 0
|
|
while not bDeleteFace and nInt < nFaces do
|
|
nInt = nInt + 1
|
|
local b3Facet = EgtSurfTmGetFacetBBoxGlob( nTestId, nInt-1, GDB_BB.STANDARD)
|
|
local vtN = EgtSurfTmFacetNormVersor( nTestId, nInt-1, GDB_ID.ROOT)
|
|
-- se dimensione faccia sulla X
|
|
if b3Facet:getDimX() < 1 or abs( vtN:getX()) > 0.1 then
|
|
EgtSurfTmRemoveFacet( nTestId, nInt-1)
|
|
bDeleteFace = true
|
|
end
|
|
end
|
|
nFaces = EgtSurfTmFacetCount( nTestId)
|
|
-- se non ho cancellato una faccia faccio il test per forma ad U
|
|
if not bDeleteFace then
|
|
-- ottengo il numero di facce rimanenti
|
|
bNewIsU = ( nFaces == 3 and not TestElleShape3( nTestId, true))
|
|
-- verifico che gola allineata su X
|
|
if bNewIsU then
|
|
local vtN1 = EgtSurfTmFacetNormVersor( nTestId, 0, GDB_ID.ROOT)
|
|
bNewIsU = ( abs( vtN1:getX()) < 0.01)
|
|
end
|
|
-- esco dal ciclo
|
|
break
|
|
end
|
|
end
|
|
-- cancello la copia del percorso
|
|
EgtErase( nTestId)
|
|
-- eseguo test
|
|
if not bNewIsU then
|
|
return false
|
|
end
|
|
-- Verifico sia abbastanza lunga
|
|
if not (( Proc.TotBox and Proc.TotBox:getDimX() > ( BD.MIN_LEN_LAMELLO or 1000)) or
|
|
( not Proc.TotBox and Proc.Box:getDimX() > ( BD.MIN_LEN_LAMELLO or 1000))) then
|
|
return false
|
|
end
|
|
-- Recupero la lavorazione
|
|
local bDownHead = ( BD.DOWN_HEAD and vtN:getZ() < BD.NZ_MINA)
|
|
local sMillingOnSide = ML.FindMilling( 'SideMillAsBlade', nil, nil, nil, nil, not bDownHead, bDownHead)
|
|
if not sMillingOnSide then
|
|
return false
|
|
end
|
|
-- Recupero i dati dell'utensile
|
|
local dToolDiamOnSide = 0
|
|
local dThickMillOnSide = 0
|
|
local dMaxDepthOnSide = 0
|
|
if EgtMdbSetCurrMachining( sMillingOnSide) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dToolDiamOnSide = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiamOnSide
|
|
dThickMillOnSide = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dThickMillOnSide
|
|
dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide
|
|
end
|
|
end
|
|
local bSpecialMillOnSide = ( dDiam > dThickMillOnSide - 10 * GEO.EPS_SMALL and dFacElev < dMaxDepthOnSide + 10 * GEO.EPS_SMALL)
|
|
-- Restituisco i dati
|
|
return bSpecialMillOnSide, sMillingOnSide, dThickMillOnSide, dToolDiamOnSide, dMaxDepthOnSide
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetFaceAdj( Proc, nFacInd, dH, dV)
|
|
|
|
-- Recupero le facce adiacenti alla principale
|
|
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
|
|
if not vAdj or #vAdj == 0 then
|
|
local sErr = 'Error : main face without adjacencies'
|
|
return -1, sErr
|
|
end
|
|
EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 4)
|
|
-- Riordino le dimensioni per avere dH > dV
|
|
if dH < dV then
|
|
dH, dV = dV, dH
|
|
end
|
|
-- Cerco una faccia adiacente alla principale sul lato lungo
|
|
local nFacAdj
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] >= 0 then
|
|
local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
local dLen = dist( ptP1, ptP2)
|
|
if dLen > 0.5 * dH then
|
|
nFacAdj = vAdj[i]
|
|
EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 4)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if not nFacAdj then
|
|
local sErr = 'Error : main face without long adjacent face'
|
|
return -1, sErr
|
|
end
|
|
return nFacAdj
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function UpdateEncumbrance( Proc, nRawId, b3Raw, b3Solid)
|
|
-- verifico siano una o due facce
|
|
if Proc.Fct > 2 then return end
|
|
-- eventuale segnalazione ingombro di testa o coda
|
|
local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ())
|
|
if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then
|
|
if Proc.Head then
|
|
local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX()
|
|
BL.UpdateHCING( nRawId, dOffs)
|
|
elseif Proc.Tail then
|
|
local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX()
|
|
BL.UpdateTCING( nRawId, dOffs)
|
|
elseif Proc.Fct > 1 and Proc.Box:getCenter():getX() > b3Solid:getCenter():getX() then
|
|
local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX()
|
|
local dDist = b3Solid:getMax():getX() - Proc.Box:getMax():getX()
|
|
-- sempre concavo aumento la distanza (rimane una punta...)
|
|
dDist = dDist + 10
|
|
BL.UpdateHCING( nRawId, dOffs, dDist)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Verifica se feature di testa
|
|
function ProcessLapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH)
|
|
-- se una sola faccia
|
|
if Proc.Fct == 1 then
|
|
local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
if vtN0:getX() > 0.1 then
|
|
return true
|
|
end
|
|
end
|
|
-- verifico se è in testa
|
|
if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then
|
|
return false
|
|
end
|
|
-- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave
|
|
if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 *b3Raw:getDimX()) then
|
|
return false
|
|
end
|
|
-- recupero identificativo del pezzo
|
|
local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL)
|
|
-- se una o due facce e interessa veramente la testa, allora di testa
|
|
if Proc.Fct <= 2 then
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
if Proc.Box:getMax():getX() > b3Solid:getMax():getX() - 1. then
|
|
return true
|
|
elseif Proc.Box:getMax():getX() < b3Solid:getMax():getX() - 5. then
|
|
return false
|
|
end
|
|
end
|
|
-- deve avere la normale principale diretta verso la testa
|
|
local nFacInd, dElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
if vtN and vtN:getX() < 0.499 then
|
|
return false
|
|
elseif Proc.Fct >= 5 then
|
|
return true
|
|
end
|
|
-- deve occupare la maggior parte dell'area
|
|
if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then
|
|
return true
|
|
end
|
|
-- non è di testa
|
|
return false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Verifica se feature di coda
|
|
function ProcessLapJoint.IsTailFeature( Proc, b3Raw)
|
|
-- se una sola faccia
|
|
if Proc.Fct == 1 then
|
|
local vtN0 = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT)
|
|
if vtN0:getX() < -0.1 then
|
|
return true
|
|
end
|
|
end
|
|
-- in base al tipo di feature attribuisco il significato dei parametri Q
|
|
AssignQIdent( Proc)
|
|
-- se può essere fatto con utensile tipo lama
|
|
local bUseBHSideMill, bHead, bHeadDir = VerifyBHSideMill( Proc)
|
|
if bUseBHSideMill then
|
|
Proc.HeadDir = bHeadDir
|
|
end
|
|
-- recupero box del pezzo
|
|
local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL)
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
-- verifico se è in coda
|
|
local dEndDist = Proc.Box:getMin():getX() - b3Solid:getMin():getX()
|
|
if dEndDist > BD.MAX_DIST_HTFEA then
|
|
return false
|
|
end
|
|
-- se lunga come trave, oppure non è trave corta e la sua lunghezza supera il massimo o il 70% della lunghezza della trave
|
|
if Proc.Box:getDimX() > b3Solid:getDimX() - 1 or
|
|
( b3Solid:getDimX() > BD.LEN_SHORT_PART and Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.7 * b3Solid:getDimX())) then
|
|
return false
|
|
end
|
|
-- se una o due facce e interessa veramente la coda, allora di coda
|
|
if Proc.Fct <= 2 then
|
|
if Proc.Box:getMin():getX() < b3Solid:getMin():getX() + 1. then
|
|
return true
|
|
elseif Proc.Box:getMin():getX() > b3Solid:getMin():getX() + 5. then
|
|
return false
|
|
end
|
|
end
|
|
-- deve avere la normale principale diretta verso la coda (oppure tunnel)
|
|
local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
if vtN and vtN:getZ() < BD.NZ_MINA and nFacInd2 then
|
|
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
nFacInd, nFacInd2 = nFacInd2, nFacInd
|
|
dElev, dElev2 = dElev2, dElev
|
|
end
|
|
if not vtN or vtN:getX() > -0.001 or dEndDist + vtN:getX() * dElev > 0 then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione della feature
|
|
function ProcessLapJoint.Classify( Proc, b3Raw)
|
|
-- se 1 faccia
|
|
if Proc.Fct == 1 then
|
|
return true, false
|
|
-- se 2 facce
|
|
elseif Proc.Fct == 2 then
|
|
-- se può essere fatto con utensile tipo lama
|
|
local bUseBHSideMill = VerifyBHSideMill( Proc)
|
|
if bUseBHSideMill then
|
|
return true, false
|
|
end
|
|
-- dati delle facce
|
|
local vtN = {}
|
|
vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT)
|
|
vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT)
|
|
-- verifico se è lavorabile solo dal basso
|
|
local vtParX = vtN[1] ^ vtN[2] ; vtParX:normalize()
|
|
local bParX = ( abs( vtParX:getX()) > 0.985)
|
|
local bSmall = ( ( Proc.Head or Proc.Tail) and Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) or
|
|
( not ( Proc.Head or Proc.Tail) and bParX and Proc.Box:getDimY() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()))
|
|
local bDown = ( vtN[1]:getZ() < BD.NZ_MINB and vtN[2]:getZ() < BD.NZ_MINB) or
|
|
( vtN[1]:getZ() < BD.NZ_MINA and vtN[2]:getZ() < 0.5 and ( vtN[2]:getZ() < -0.1 or not bSmall)) or
|
|
( vtN[2]:getZ() < BD.NZ_MINA and vtN[1]:getZ() < 0.5 and ( vtN[1]:getZ() < -0.1 or not bSmall))
|
|
-- se forzata la lavorazione con fresa di lato da parametro Q03=2/3 non devo ruotare
|
|
local bForceSideMill = ( EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'd') == 2 or EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'd') == 3)
|
|
bDown = ( bDown and not BD.DOWN_HEAD and not BD.TURN and not bForceSideMill)
|
|
return true, bDown
|
|
-- se più di 2 facce
|
|
else
|
|
local bClosedOrthoFaces
|
|
local nDeletedFace
|
|
-- recupero la faccia con il maggior numero di adiacenze e minor elevazione
|
|
local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL)
|
|
local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
|
|
if not nFacInd or nFacInd < 0 then
|
|
if nFacInd == -1 then
|
|
bClosedOrthoFaces = nFacInd2
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
-- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche
|
|
if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then
|
|
-- recupero gruppo per geometria addizionale
|
|
local nAddGrpId = BL.GetAddGroup( nPartId)
|
|
if not nAddGrpId then
|
|
return false
|
|
end
|
|
-- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura
|
|
for i = 1, Proc.Fct do
|
|
local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
|
|
-- elimino una faccia
|
|
nDeletedFace = i - 1
|
|
if EgtSurfTmRemoveFacet( nNewProc, nDeletedFace) then
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( nNewProc, nPartId)
|
|
if not nFacInd or nFacInd < 0 then
|
|
if nFacInd == -1 then
|
|
bClosedOrthoFaces = nFacInd2
|
|
EgtErase( nNewProc)
|
|
break
|
|
else
|
|
EgtErase( nNewProc)
|
|
return false
|
|
end
|
|
end
|
|
-- altrimenti esco
|
|
else
|
|
EgtErase( nNewProc)
|
|
break
|
|
end
|
|
end
|
|
-- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo
|
|
if bClosedOrthoFaces then
|
|
nFacInd = nDeletedFace
|
|
-- rendo nulla la faccia opzionale perchè si tratta di una fessura
|
|
nFacInd2 = nil
|
|
dElev = BL.GetFaceElevation( Proc.Id, nFacInd)
|
|
bClosedOrthoFaces = false -- non lo setto come tunnel
|
|
end
|
|
end
|
|
-- se facce formano un tunnel e sono ortogonali
|
|
if bClosedOrthoFaces then
|
|
-- ottengo le dimensioni del tunnel
|
|
local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = BL.GetTunnelDimension( Proc, nPartId)
|
|
EgtErase( nSurfInt)
|
|
-- verifico se può essere fatto con svuotatura
|
|
if VerifyPocket( Proc, dDimMin) then
|
|
return true, false
|
|
elseif VerifyChainSaw( Proc, dDimMin, dDimMax) then
|
|
return true, false
|
|
else
|
|
return false
|
|
end
|
|
else
|
|
-- dati della faccia
|
|
local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- se può essere fatto con utensile tipo lama
|
|
local bUseBHSideMill, _, _, _, _, dTDiam = VerifyBHSideMill( Proc)
|
|
if bUseBHSideMill then
|
|
if vtN:getZ() > -0.5 or b3Raw:getDimZ() - Proc.Box:getDimZ() < ( BD.MAX_DIST_BH_FROM_BOTTOM or 395) - dTDiam / 2 then
|
|
return true, false
|
|
else
|
|
return true, true
|
|
end
|
|
-- altrimenti controllo se deve essere ruotato con le altre lavorazioni
|
|
else
|
|
-- cerco se c'è faccia adiacente sul lato più lungo
|
|
local nFaceAdj = GetFaceAdj( Proc, nFacInd, dH, dV) or -1
|
|
local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2)
|
|
-- verifico se è lavorabile solo dal basso
|
|
local bDown = ( vtN:getZ() < BD.NZ_MINA and not BD.DOWN_HEAD and not BD.TURN)
|
|
-- se verso il basso, verifico se utilizzabile seconda faccia
|
|
if bDown then
|
|
local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc))
|
|
-- se forzata la lavorazione con fresa di lato da parametro Q03=2/3 non devo ruotare
|
|
local nSideRoughTool = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'd')
|
|
local bForceSideMill = ( ( nSideRoughTool == 2 or nSideRoughTool == 3) and ( Proc.Fct == 3 or Proc.Fct == 4))
|
|
if bForceSideMill then
|
|
bDown = false
|
|
elseif nFacInd2 and dElev2 < 160 and dElev2 < 2 * dElev then
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
bDown = ( vtN2:getZ() < BD.NZ_MINB)
|
|
elseif not nFacInd2 and bIsL and nFaceAdj >= 0 then
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFaceAdj, GDB_ID.ROOT)
|
|
bDown = ( vtN2:getZ() < BD.NZ_MINB)
|
|
end
|
|
-- verifico se la faccia principale è sottosquadra, ha forma L ed esiste la faccia adiacente
|
|
elseif vtN:getZ() < -0.2589 and bIsL and nFaceAdj >= 0 then
|
|
-- box del pezzo
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
-- se più di 2 facce o il box della feature supera una certa distanza dalle teste allora controllo Nz della faccia ausiiaria
|
|
if Proc.Fct > 2 or ( Proc.Box:getMax():getX() < b3Solid:getMin():getX() - 150) or ( Proc.Box:getMin():getX() > b3Solid:getMax():getX() + 150) then
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFaceAdj, GDB_ID.ROOT)
|
|
bDown = ( vtN2:getZ() < BD.NZ_MINB)
|
|
end
|
|
end
|
|
return true, bDown
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Lavorazione con fresa
|
|
---------------------------------------------------------------------
|
|
local function MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId)
|
|
-- recupero l'ingombro del grezzo di appartenenza
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
-- recupero l'ingombro della trave
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
if not b3Solid then
|
|
local sErr = 'Error : part box not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- verifico il numero di facce della tacca
|
|
assert( ( Proc.Fct == 1), 'Error : MakeOneFaceByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces')
|
|
-- dati della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
-- verifico se orientata verso l'alto
|
|
local bUp = ( vtN:getZ() >= BD.NZ_MINA)
|
|
-- scelta faccia da lavorare
|
|
local nFacInd = 0
|
|
-- recupero la lavorazione
|
|
local sMilling = ML.FindMilling( 'BirdsMouth')
|
|
if not sMilling then
|
|
local sErr = 'Error : BirdsMouth not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- inserisco la lavorazione di fresatura
|
|
local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
|
|
-- imposto uso faccia e lato correzione
|
|
if vtN:getX() > 0 then
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_LEFT, MCH_MILL_FU.PARAL_LEFT))
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.PARAL_RIGHT))
|
|
end
|
|
-- imposto lato di correzione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
if not bUp then EgtSetMachiningParam( MCH_MP.INVERT, true) end
|
|
-- imposto posizione braccio porta testa
|
|
if vtN:getY() < GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
|
|
end
|
|
-- dichiaro non si generano sfridi per VMill
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;')
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
-- eventuale segnalazione ingombro di testa o coda
|
|
UpdateEncumbrance( Proc, nRawId, b3Raw, b3Solid)
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId, bDownHead)
|
|
-- recupero l'ingombro del grezzo di appartenenza
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
-- recupero l'ingombro della trave
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
if not b3Solid then
|
|
local sErr = 'Error : part box not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- verifico il numero di facce della tacca
|
|
assert( ( Proc.Fct == 2), 'Error : MakeTwoFacesByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces')
|
|
-- recupero il parametro Q per uso fresa
|
|
local nUseRM = EgtGetInfo( Proc.Id, Q_USE_MILL, 'i')
|
|
-- recupero la lavorazione
|
|
local sMilling
|
|
if nUseRM and nUseRM == 1 then
|
|
sMilling = ML.FindMilling( 'LongSmallCut', nil, nil, nil, nil, not bDownHead, bDownHead)
|
|
else
|
|
sMilling = ML.FindMilling( 'BirdsMouth', nil, nil, nil, nil, not bDownHead, bDownHead)
|
|
end
|
|
if not sMilling then
|
|
local sErr = 'Error : LongSmallCut & BirdsMouth not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 0
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam
|
|
end
|
|
-- dati delle facce
|
|
local ptC = {}
|
|
local vtN = {}
|
|
ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
|
|
-- dati medi
|
|
local ptM = ( ptC[1] + ptC[2]) / 2
|
|
-- verifico non siano orientate verso il basso
|
|
local bFaceOk = {}
|
|
bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB)
|
|
bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB)
|
|
if not bDownHead and not BD.TURN and not bFaceOk[1] and not bFaceOk[2] then
|
|
local sErr = 'Error : LapJoint from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- scelta faccia da lavorare
|
|
local nFacInd
|
|
-- se entrambe possibili
|
|
if bFaceOk[1] and bFaceOk[2] then
|
|
-- se in testa, scelgo quella orientata verso la testa
|
|
if Proc.Head then
|
|
if vtN[1]:getX() > vtN[2]:getX() then
|
|
nFacInd = 0
|
|
else
|
|
nFacInd = 1
|
|
end
|
|
-- se altrimenti in coda, scelgo quella orientata verso la coda
|
|
elseif Proc.Tail then
|
|
if vtN[1]:getX() < vtN[2]:getX() then
|
|
nFacInd = 0
|
|
else
|
|
nFacInd = 1
|
|
end
|
|
-- altrimenti, scelgo quella con la normale più perpendicolare all'asse trave (se uguali, quella verso X+)
|
|
else
|
|
if abs( abs( vtN[1]:getX()) - abs( vtN[2]:getX())) < GEO.EPS_SMALL then
|
|
if ptM:getX() > b3Raw:getCenter():getX() then
|
|
nFacInd = EgtIf( vtN[1]:getX() > vtN[2]:getX(), 0, 1)
|
|
else
|
|
nFacInd = EgtIf( vtN[1]:getX() < vtN[2]:getX(), 0, 1)
|
|
end
|
|
else
|
|
nFacInd = EgtIf( abs( vtN[1]:getX()) < abs( vtN[2]:getX()), 0, 1)
|
|
end
|
|
end
|
|
elseif bFaceOk[1] then
|
|
nFacInd = 0
|
|
else
|
|
nFacInd = 1
|
|
end
|
|
local nOthInd = 1 - nFacInd
|
|
local sName
|
|
local nMchFId
|
|
local nFaceUse
|
|
-- se forzato uso fresa controllo se posso fare in una o più passate
|
|
if nUseRM and nUseRM == 1 then
|
|
-- prendo la larghezza della faccia
|
|
local _, pPt1, pPt2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nOthInd, GDB_ID.ROOT)
|
|
local dDistPoint = dist( pPt1, pPt2)
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local dWidth = EgtIf( abs( dDistPoint - dH) < abs( dDistPoint - dV), dV, dH)
|
|
-- se larghezza faccia maggiore diametro utensile aggiungo una lavorazione
|
|
if dTDiam > 0 and dWidth > dTDiam then
|
|
-- inserisco la lavorazione di fresatura
|
|
sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_1'
|
|
nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
|
|
-- imposto uso faccia e lato correzione
|
|
nFaceUse = BL.GetNearestOrthoOpposite( vtN[nOthInd+1])
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto lato di correzione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- tolgo l'inversione
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- aggiungo offset laterale
|
|
EgtSetMachiningParam( MCH_MP.OFFSR , (dTDiam/2))
|
|
-- imposto posizione braccio porta testa
|
|
if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
|
|
end
|
|
-- dichiaro non si generano sfridi per VMill
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;')
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
end
|
|
-- inserisco la lavorazione di fresatura
|
|
sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
|
|
-- imposto uso faccia e lato correzione
|
|
nFaceUse = BL.GetNearestOrthoOpposite( vtN[nOthInd+1])
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto lato di correzione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- tolgo l'inversione
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- imposto posizione braccio porta testa
|
|
if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
|
|
end
|
|
-- dichiaro non si generano sfridi per VMill
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;')
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
-- eventuale segnalazione ingombro di testa o coda
|
|
UpdateEncumbrance( Proc, nRawId, b3Raw, b3Solid)
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakePreCuts( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, nChamfer)
|
|
-- se interessa l'intera sezione della trave, necessaria sgrossatura
|
|
if nChamfer < 2 and Proc.Box:getDimY() > 0.9 * b3Raw:getDimY() and Proc.Box:getDimZ() > 0.9 * b3Raw:getDimZ() then
|
|
-- recupero gruppo per geometria addizionale
|
|
local nAddGrpId = BL.GetAddGroup( nPartId)
|
|
if not nAddGrpId then
|
|
local sErr = 'Error : missing AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo sgrossatura e la lavoro
|
|
local AddId = EgtSurfTmConvexHullInBBox( nAddGrpId, Proc.Id, b3Raw, GDB_RT.GLOB)
|
|
if AddId then
|
|
EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id))
|
|
-- applico lavorazione
|
|
local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg,
|
|
Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId}
|
|
local nCutFacet = EgtSurfTmFacetCount( AddId)
|
|
if nCutFacet == 1 then
|
|
return Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead)
|
|
elseif nCutFacet == 2 then
|
|
return DoubleCut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead)
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev, dCollSic, bSpecialApp, sMillMaster, nFacInd2, dFacElev2)
|
|
-- Cerco una faccia adiacente alla principale sul lato lungo
|
|
local nFacAdj, sErr = GetFaceAdj( Proc, nFacInd, dH, dV)
|
|
if nFacAdj < 0 then
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Determino se estremi aperti o chiusi e faccia adiacente da aggiungere alla lavorazione
|
|
local bOpenStart = false
|
|
local bOpenEnd = false
|
|
local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1]
|
|
EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3)
|
|
local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacAdj, GDB_ID.ROOT)
|
|
-- Riordino le dimensioni per avere dH > dV
|
|
if dH2 < dV2 then
|
|
dH2, dV2 = dV2, dH2
|
|
end
|
|
local nFacAdj2
|
|
for j = 1, #vAdj2 do
|
|
if vAdj2[j] == nFacInd then
|
|
-- Se non esiste faccia adiacente a lato precedente -> inizio aperto
|
|
local i = EgtIf( j > 1, j - 1, #vAdj2)
|
|
while vAdj2[i] == nFacInd do
|
|
i = EgtIf( i > 1, i - 1, #vAdj2)
|
|
end
|
|
bOpenStart = ( vAdj2[i] < 0)
|
|
-- Se non esiste faccia adiacente a lato successivo -> fine aperto
|
|
local k = EgtIf( j < #vAdj2, j + 1, 1)
|
|
while vAdj2[k] == nFacInd do
|
|
k = EgtIf( k < #vAdj2, k + 1, 1)
|
|
end
|
|
bOpenEnd = ( vAdj2[k] < 0)
|
|
end
|
|
-- decommentare questa parte per concatenare due facce
|
|
--if bSpecialApp and vAdj2[j] >= 0 then
|
|
-- local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacAdj, vAdj2[j], GDB_ID.ROOT)
|
|
-- local dLen = dist( ptP1, ptP2)
|
|
-- if abs( dLen - dV2) < 10 * GEO.EPS_SMALL then
|
|
-- nFacAdj2 = vAdj2[j]
|
|
-- end
|
|
--end
|
|
end
|
|
-- Recupero la lavorazione di fresa
|
|
local sMilling
|
|
if bSpecialApp then
|
|
sMilling = sMillMaster
|
|
else
|
|
sMilling = ML.FindMilling( 'LongSmallCut')
|
|
if not sMilling then
|
|
sErr = 'Error : LongSmallCut not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 50
|
|
local dMaxMat = 0
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam
|
|
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
|
|
end
|
|
end
|
|
-- Se massimo materiale utensile è molto inferiore dell'elevazione non faccio la lavorazione e do un warning
|
|
if dMaxMat > 0 and dMaxMat + 15 < dElev + dCollSic then
|
|
sWarn = 'Warning : skipped milling; elevation bigger than max tool depth'
|
|
return true, sWarn, dMaxMat
|
|
end
|
|
-- Calcolo uso faccia
|
|
local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ())
|
|
-- inserisco la lavorazione di fresatura
|
|
local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
if nFacAdj2 then
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj},{ Proc.Id, nFacAdj2}})
|
|
else
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}})
|
|
end
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_YM
|
|
if rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- lato di lavoro e direzione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
-- tipo di attacco e uscita
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.LINEAR)
|
|
-- imposto accorciamento iniziale/finale per estremi aperti/chiusi
|
|
if bSpecialApp then
|
|
-- applico gli allungamenti o accorciamenti considerando che la lavorazione è invertita
|
|
if nFacAdj2 then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, dTDiam / 2, - dTDiam / 2))
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, dTDiam / 2, - dTDiam / 2))
|
|
-- confronto la faccia applicata nella lavorazione(faccia adiacente) con la seconda faccia passata nella funzione
|
|
-- se corrispondono allora aggiungo una estensione nei lati chiusi pari all'elevazione della stessa faccia corrispondente
|
|
if nFacAdj == nFacInd2 then
|
|
if not bOpenStart then
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, dFacElev2)
|
|
end
|
|
if not bOpenEnd then
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dFacElev2)
|
|
end
|
|
end
|
|
end
|
|
-- applico elevazione
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, 0, - dTDiam / 2))
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, 0, - dTDiam / 2))
|
|
end
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
_, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
return true, '', dTDiam
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ChooseCorner( Proc, nFacInd)
|
|
-- Recupero le adiacenze della faccia principale
|
|
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
|
|
-- Cerco i corner tra le facce adiacenti alla principale
|
|
local tFacAdj = {}
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] >= 0 then
|
|
for j = i+1, #vAdj do
|
|
if vAdj[j] >= 0 then
|
|
local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vAdj[i], vAdj[j], GDB_ID.ROOT)
|
|
if ptP1 and ptP2 and dAng < 0 then
|
|
local dLen = dist( ptP1, ptP2)
|
|
table.insert( tFacAdj, { vAdj[i], vAdj[j], dLen, ptP1, ptP2, dAng})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- Tra le linee dei corner determino la più lunga
|
|
local dMaxLen = 0
|
|
local nIdLine
|
|
for i = 1, #tFacAdj do
|
|
if tFacAdj[i][3] > dMaxLen then
|
|
nIdLine = i
|
|
dMaxLen = tFacAdj[i][3]
|
|
end
|
|
end
|
|
|
|
return dMaxLen, nIdLine, tFacAdj
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ChooseContour( Proc, nFacInd, bVerifyCorner)
|
|
-- Recupero le adiacenze della faccia principale
|
|
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
|
|
-- Se richiesto, verifico che ci siano facce adiacenti consecutive (sicuramente con angolo)
|
|
if bVerifyCorner then
|
|
local bCorner = false
|
|
for i = 1, #vAdj do
|
|
local j = EgtIf( i > 1, i - 1, #vAdj)
|
|
if vAdj[i] >= 0 and vAdj[j] >= 0 then
|
|
bCorner = true
|
|
break
|
|
end
|
|
end
|
|
if not bCorner then return {} end
|
|
end
|
|
-- Cerco le facce adiacenti con angolo convesso
|
|
local tFacAdjMain = {}
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] >= 0 then
|
|
local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
if ptP1 and ptP2 and dAng < 0 then
|
|
local dLen = dist( ptP1, ptP2)
|
|
table.insert( tFacAdjMain, { vAdj[i], dLen, ptP1, ptP2, dAng})
|
|
end
|
|
end
|
|
end
|
|
|
|
return tFacAdjMain
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CheckToInvert( AuxId, bPositive)
|
|
|
|
-- recupero versore estrusione
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT)
|
|
-- faccio una copia del percorso
|
|
local sParnt = EgtGetParent( AuxId)
|
|
local nNewEntId = EgtCopyGlob( AuxId, sParnt)
|
|
-- chiudo il percorso
|
|
if EgtCloseCurveCompo( nNewEntId) then
|
|
local vtMPlane, dDist, dArea = EgtCurveArea( nNewEntId)
|
|
-- cancello percorso copia
|
|
EgtErase( nNewEntId)
|
|
if dArea and abs(dArea) > 1 then
|
|
local frEnt = EgtGetGlobFrame( AuxId)
|
|
if vtMPlane then
|
|
vtMPlane:toGlob(frEnt)
|
|
if dArea and dArea * ( vtMPlane * vtExtr) < 0 then
|
|
if bPositive then
|
|
return true
|
|
end
|
|
elseif dArea and dArea * ( vtMPlane * vtExtr) > 0 then
|
|
if not bPositive then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
-- cancello percorso copia
|
|
EgtErase(nNewEntId)
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeRoundCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacInd, nAddGrpId, dDiam, bMillDown, bDoubleSide)
|
|
|
|
-- recupero la lavorazione senza considerare l'elevazione
|
|
local sMilling = ML.FindMilling( 'SmallToolContour', nil, nil, nil, nil, not ( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide)
|
|
if not sMilling then
|
|
local sMyWarn = 'Warning : SmallToolContour not found in library'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 50
|
|
local dTMaxDepth = 0
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam
|
|
dTMaxDepth = EgtTdbGetCurrToolMaxDepth() or dTMaxDepth
|
|
end
|
|
|
|
-- se il diametro trovato non è minore dei 3/4 del diametro utilizzato in precedenza, esco
|
|
if dTDiam > ( 0.75 * dDiam) then
|
|
local sMyWarn = 'Warning : tool diameter not enough small'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
|
|
-- ottengo gli angoli dove applicare il percorso con fresa più piccola
|
|
local _, _, tFacAdj = ChooseCorner( Proc, nFacInd)
|
|
-- se non trovato nessun angolo interno valido esco
|
|
if #tFacAdj == 0 then
|
|
return true
|
|
end
|
|
|
|
-- recupero la normale della faccia di fondo
|
|
local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- se fresatura da sotto salto la lavorazione
|
|
if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then
|
|
local sErr = 'Error : milling from bottom '
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
-- ciclo su tutti gli angoli trovati
|
|
local sMyWarn = ''
|
|
for i = 1, #tFacAdj do
|
|
local pAuxId = {}
|
|
-- le 2 facce di contatto devono essere perpendicolari e non sottosquadra rispetto alla faccia di fondo
|
|
local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][1], GDB_ID.ROOT)
|
|
local _, ptP1x, ptP2x, dAngx = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][2], GDB_ID.ROOT)
|
|
if dAng >= 0 or dAng < -90 - 10 * GEO.EPS_SMALL or dAngx >= 0 or dAngx < -90 - 10 * GEO.EPS_SMALL then
|
|
goto continue
|
|
end
|
|
-- prendo la lunghezza di adiacenza delle due linee
|
|
local dLen1 = dist( ptP1, ptP2)
|
|
local dLen2 = dist( ptP1x, ptP2x)
|
|
-- cerco il punto tra le 3 facce: nIdEndPoint
|
|
local nIdIniPoint
|
|
local nIdEndPoint
|
|
if ptP1 and ptP2 then
|
|
if dist( ptP1, tFacAdj[i][4]) < GEO.EPS_SMALL or dist( ptP2, tFacAdj[i][4]) < GEO.EPS_SMALL then
|
|
nIdEndPoint = 4
|
|
nIdIniPoint = 5
|
|
elseif dist( ptP1, tFacAdj[i][5]) < GEO.EPS_SMALL or dist( ptP2, tFacAdj[i][5]) < GEO.EPS_SMALL then
|
|
nIdEndPoint = 5
|
|
nIdIniPoint = 4
|
|
end
|
|
end
|
|
-- devo avere un punto comune
|
|
if not nIdEndPoint then
|
|
goto continue
|
|
end
|
|
-- calcolo lunghezza minima in base all'angolo tra le due pareti
|
|
local dMinDist = (( dDiam / 2) / tan( ( 180 + tFacAdj[i][6]) / 2)) + 2
|
|
-- verifico che entrambe le linee siano maggiori delle lunghezza minima
|
|
if dLen1 <= dMinDist or dLen2 <= dMinDist then
|
|
sMyWarn = 'Warning : impossible make clean corner path'
|
|
goto continue
|
|
end
|
|
-- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro
|
|
local ptApPoint = EgtIf( dist( tFacAdj[i][nIdEndPoint], ptP1) < 10 * GEO.EPS_SMALL, ptP2, ptP1)
|
|
-- prima linea
|
|
local nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[i][nIdEndPoint], GDB_RT.GLOB)
|
|
-- calcolo arretramento
|
|
local dTrimDist = dLen1 - dMinDist
|
|
-- se arretramento valido
|
|
if dTrimDist > 100 * GEO.EPS_SMALL then
|
|
EgtTrimExtendCurveByLen( nAuxId , -dTrimDist, ptApPoint , GDB_RT.GLOB)
|
|
end
|
|
table.insert( pAuxId, nAuxId)
|
|
-- se il punto finale corrisponde con il punto comune, uso l'altro
|
|
ptApPoint = EgtIf( dist( tFacAdj[i][nIdEndPoint], ptP1x) < 10 * GEO.EPS_SMALL, ptP2x, ptP1x)
|
|
-- seconda linea
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[i][nIdEndPoint], ptApPoint, GDB_RT.GLOB)
|
|
-- calcolo arretramento
|
|
dTrimDist = dLen2 - dMinDist
|
|
-- se arretramento valido
|
|
if dTrimDist > 100 * GEO.EPS_SMALL then
|
|
EgtTrimExtendCurveByLen( nAuxId , -dTrimDist, ptApPoint , GDB_RT.GLOB)
|
|
end
|
|
table.insert( pAuxId, nAuxId)
|
|
-- trasformo in percorso
|
|
local AuxId
|
|
if #pAuxId > 0 then
|
|
AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true)
|
|
end
|
|
-- deve esserci il percorso
|
|
if not AuxId then
|
|
sMyWarn = 'Warning : impossible make clean corner path'
|
|
goto continue
|
|
end
|
|
-- modifico versore direzione
|
|
EgtModifyCurveExtrusion( AuxId, vtN1, GDB_RT.GLOB)
|
|
-- inserisco la lavorazione
|
|
local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchId = EgtAddMachining( sName, sMilling)
|
|
if not nMchId then
|
|
sMyWarn = 'Warning : impossible add machining ' .. sName .. '-' .. sMilling
|
|
goto continue
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ AuxId, -1}})
|
|
-- imposto lato di lavoro sinistro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if AreSameOrOppositeVectorApprox( vtN1, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtN1:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtN1:getY() < GEO.EPS_SMALL then
|
|
nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
else
|
|
nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- tipo attacco e uscita
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.NONE)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI)
|
|
-- annullo allungamenti iniziale e finale
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
|
|
-- setto massimo affondamento possibile
|
|
local dDepth = 0
|
|
if tFacAdj[i][3] > dTMaxDepth then
|
|
dDepth = dTMaxDepth - tFacAdj[i][3]
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- setto se devo invertire il percorso
|
|
local bInvert = CheckToInvert( AuxId, true)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
|
|
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione
|
|
local sUserNotes = 'VMRS=0;'
|
|
sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( ( tFacAdj[i][3] + dDepth), 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- eseguo
|
|
if ML.ApplyMachining( true, false) then
|
|
_, sMyWarn = EgtGetMachMgrWarning( 0)
|
|
if EgtIsMachiningEmpty() then
|
|
EgtSetOperationMode( nMchId, false)
|
|
end
|
|
-- altrimenti lavorazione non applicata
|
|
else
|
|
_, sMyWarn = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
end
|
|
::continue::
|
|
end
|
|
if #sMyWarn > 0 then
|
|
EgtOutLog( sMyWarn)
|
|
end
|
|
|
|
return true, sMyWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeRoundCleanContour( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacInd, nAddGrpId, dDiam, nFunction, bMillDown,
|
|
bDoubleSide, vtOrtho, nPathInt, nSurfInt, b3Solid,
|
|
dDepth, bOneShot)
|
|
|
|
-- recupero la lavorazione senza considerare l'elevazione perché viene calcolata l'elevazione utile
|
|
local sMilling = ML.FindMilling( 'SmallToolContour', nil, nil, nil, nil, not( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide)
|
|
if not sMilling then
|
|
local sMyWarn = 'Warning : SmallToolContour not found in library'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 50
|
|
local dTMaxDepth = 0
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam
|
|
dTMaxDepth = EgtTdbGetCurrToolMaxDepth() or dTMaxDepth
|
|
end
|
|
|
|
local sMillingDn = ML.FindMilling( 'SmallToolContour', nil, nil, nil, nil, not( bMillDown and bDoubleSide), bMillDown and bDoubleSide)
|
|
if not sMillingDn then
|
|
local sMyWarn = 'Warning : Opposite SmallToolContour not found in library'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
-- recupero i dati dell'utensile testa da sotto
|
|
local dTDiamDn = 50
|
|
local dTMaxDepthDn = 0
|
|
if EgtMdbSetCurrMachining( sMillingDn) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
dTDiamDn = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiamDn
|
|
dTMaxDepthDn = EgtTdbGetCurrToolMaxDepth() or dTMaxDepthDn
|
|
end
|
|
|
|
-- se il diametro trovato non è minore dei 3/4 del diametro utilizzato in precedenza, esco
|
|
if dTDiam > ( 0.75 * dDiam) then
|
|
local sMyWarn = 'Warning : tool diameter not enough small'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
|
|
local vtN1
|
|
local nFirstId, nNumId
|
|
local dMaxElev
|
|
local dCollSic = 0
|
|
local dExtraDepth = 0
|
|
|
|
-- se non ho la faccia aggiunta
|
|
if not nPathInt then
|
|
-- cerco gli angoli dove applicare il percorso con fresa piú piccola e i lati in comune
|
|
local tFacAdjMain = ChooseContour( Proc, nFacInd, true)
|
|
-- se non trovato nessun angolo interno da pulire esco
|
|
if #tFacAdjMain == 0 then
|
|
return true
|
|
end
|
|
-- normale alla faccia di fondo
|
|
vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- se fresatura da sotto salto la lavorazione
|
|
if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then
|
|
local sErr = 'Error : milling from bottom'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- distanza di sicurezza per evitare collisioni
|
|
dCollSic = BL.CalcCollisionSafety( vtN1)
|
|
-- elevazione massima della faccia
|
|
dMaxElev = BL.GetFaceElevation( Proc.Id, nFacInd, nPartId)
|
|
-- ciclo tutta la tabella
|
|
local tPaths = {}
|
|
local ptIniPath
|
|
local ptMidDist
|
|
local dMaxLen = 0
|
|
for i = 1, #tFacAdjMain do
|
|
-- le 2 facce di contatto devono essere perpendicolari o non sottosquadra rispetto alla faccia di fondo
|
|
local ptP1, ptP2, dAng
|
|
ptP1 = tFacAdjMain[i][3]
|
|
ptP2 = tFacAdjMain[i][4]
|
|
dAng = tFacAdjMain[i][5]
|
|
if ( dAng < 0 and dAng >= -90 - 10 * GEO.EPS_SMALL) then
|
|
-- creo la linea da P1 a P2
|
|
local nAuxId = EgtLine( nAddGrpId, ptP1, ptP2, GDB_RT.GLOB)
|
|
table.insert( tPaths, nAuxId)
|
|
-- prendo la lunghezza massima e il punto medio
|
|
if tFacAdjMain[i][2] > dMaxLen then
|
|
ptIniPath = ptP1
|
|
dMaxLen = tFacAdjMain[i][2]
|
|
ptMidDist = ( ptP1 + ptP2) / 2
|
|
end
|
|
end
|
|
end
|
|
-- costruisco il/i percorso/i
|
|
nFirstId, nNumId = EgtCurveCompoByReorder( nAddGrpId, tPaths, ptIniPath, true, GDB_RT.GLOB)
|
|
if nFirstId then
|
|
-- se un solo percorso e chiuso cambio il punto di inizio nell'entitá piú lunga
|
|
if nNumId == 1 and EgtCurveIsClosed( nFirstId) then
|
|
EgtChangeClosedCurveStartPoint( nFirstId, ptMidDist, GDB_RT.GLOB)
|
|
end
|
|
-- modifico versore direzione
|
|
for i = 1, nNumId do
|
|
EgtModifyCurveExtrusion( nFirstId + i - 1, vtN1, GDB_RT.GLOB)
|
|
end
|
|
end
|
|
|
|
-- alrimenti ho la faccia aggiunta
|
|
else
|
|
-- assegno il percorso
|
|
nFirstId = EgtCopyGlob( nPathInt, nAddGrpId)
|
|
nNumId = 1
|
|
-- distanza di sicurezza per evitare collisioni
|
|
dCollSic = BL.CalcCollisionSafety( vtOrtho)
|
|
-- calcolo elevazione dalla faccia trasversale aggiunta
|
|
local dSurfIntElev = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
if bDoubleSide then
|
|
dMaxElev = dSurfIntElev
|
|
else
|
|
dMaxElev = dDepth
|
|
-- se la precedente svuotatura è stata fatta completamente in una sola volta
|
|
-- valuto di nuovo se devo fare due passate o una sola
|
|
if bOneShot then
|
|
-- se non è possibile svuotare completamente da una sola parte
|
|
if dTMaxDepth <= ( dMaxElev + BD.CUT_EXTRA + dCollSic) then
|
|
bDoubleSide = true
|
|
dMaxElev = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
else
|
|
dExtraDepth = dMaxElev - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
end
|
|
-- altrimenti non è stata fatta completamente calcolo la distanza tra faccia aggiunta e profondità superficie
|
|
else
|
|
dExtraDepth = dMaxElev - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
end
|
|
end
|
|
-- normale alla faccia aggiunta
|
|
vtN1 = Vector3d( vtOrtho)
|
|
-- imposto i lati aperti
|
|
BL.SetOpenSide( nFirstId, vtOrtho, b3Solid, nAddGrpId, 2)
|
|
end
|
|
|
|
-- se non trovato il percorso, esco
|
|
if not nFirstId then
|
|
local sMyWarn = 'Warning : impossible make clean corner path'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
|
|
-- assegno lavorazioni ad ogni percorso
|
|
local sMyWarn = ''
|
|
for i = 1, nNumId do
|
|
local nIdPath = nFirstId + i - 1
|
|
local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchId = EgtAddMachining( sName, sMilling)
|
|
if not nMchId then
|
|
sMyWarn = 'Warning : impossible add machining ' .. sName .. '-' .. sMilling
|
|
goto continue
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ nIdPath, -1}})
|
|
-- imposto lato di lavoro sinistro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- inversione direzione utensile
|
|
local bInvertMach = false
|
|
if nPathInt then
|
|
-- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale)
|
|
if vtN1:getZ() < BD.NZ_MINA and abs(vtN1:getZ()) >= 0.707 then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
bInvertMach = true
|
|
-- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti
|
|
elseif not bDoubleSide and vtN1:getY() > GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
bInvertMach = true
|
|
end
|
|
end
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if AreSameOrOppositeVectorApprox( vtN1, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtN1:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtN1:getY() < GEO.EPS_SMALL then
|
|
nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
else
|
|
nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- gestione attacco e uscita
|
|
if EgtCurveIsClosed( nIdPath) then
|
|
-- attacco e uscita a quarto di cerchio senza allungamenti a inizio e fine
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.TANGENT)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 0.5 * dTDiam)
|
|
EgtSetMachiningParam( MCH_MP.LIELEV, 0)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
|
|
else
|
|
-- nessun attacco e uscita, allungo inizio e fine di raggio utensile + 5mm (per evitare controllo collisioni)
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.NONE)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2 + 5)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2 + 5)
|
|
end
|
|
-- setto massimo affondamento possibile
|
|
local dMachDepth = 0
|
|
if ( dMaxElev + dCollSic) > dTMaxDepth then
|
|
dMachDepth = dTMaxDepth - ( dMaxElev + dCollSic)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth + dExtraDepth)
|
|
-- setto se devo invertire il percorso
|
|
local bInvert = CheckToInvert( nIdPath, true)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bInvertMach, not bInvert, bInvert))
|
|
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione
|
|
local sUserNotes = 'VMRS=0;'
|
|
sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( ( dMaxElev + dMachDepth), 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- eseguo
|
|
if ML.ApplyMachining( true, false) then
|
|
_, sMyWarn = EgtGetMachMgrWarning( 0)
|
|
if EgtIsMachiningEmpty() then
|
|
EgtSetOperationMode( nMchId, false)
|
|
end
|
|
-- altrimenti lavorazione non applicata
|
|
else
|
|
_, sMyWarn = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
end
|
|
-- se devo applicare la contornatura anche sul lato opposto
|
|
if bDoubleSide then
|
|
if bMillDown then
|
|
sMilling = sMillingDn
|
|
dTDiam = dTDiamDn
|
|
dTMaxDepth = dTMaxDepthDn
|
|
end
|
|
sName = 'CleanOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
nMchId = EgtAddMachining( sName, sMilling)
|
|
if not nMchId then
|
|
sMyWarn = 'Warning : impossible add machining ' .. sName .. '-' .. sMilling
|
|
goto continue
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ nIdPath, -1}})
|
|
-- imposto lato di lavoro sinistro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- imposto direzione utensile opposta
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if AreSameVectorApprox( vtN1, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtN1:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtN1:getY() < GEO.EPS_SMALL then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
else
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- tipo attacco e uscita
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.NONE)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI)
|
|
-- allungo inizio e fine di 3/4 del diametro utensile
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam * 0.75)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam * 0.75)
|
|
-- setto massimo affondamento possibile
|
|
local dMachDepth = 0
|
|
if ( dMaxElev + dCollSic) > dTMaxDepth then
|
|
dMachDepth = dTMaxDepth - ( dMaxElev + dCollSic)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth)
|
|
-- setto se devo invertire il percorso
|
|
local bInvert = CheckToInvert( nIdPath, true)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, not bInvert)
|
|
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione
|
|
local sUserNotes = 'VMRS=0;'
|
|
sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( ( dMaxElev + dMachDepth), 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- eseguo
|
|
if ML.ApplyMachining( true, false) then
|
|
_, sMyWarn = EgtGetMachMgrWarning( 0)
|
|
if EgtIsMachiningEmpty() then
|
|
EgtSetOperationMode( nMchId, false)
|
|
end
|
|
-- altrimenti lavorazione non applicata
|
|
else
|
|
_, sMyWarn = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
end
|
|
end
|
|
::continue::
|
|
end
|
|
if #sMyWarn > 0 then
|
|
EgtOutLog( sMyWarn)
|
|
end
|
|
|
|
return true, sMyWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeRoundCleanCornerOrContour( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacInd, nAddGrpId, dDiam, nFunction, bMillDown,
|
|
bDoubleSide, vtOrtho, nPathInt, nSurfInt, b3Solid,
|
|
dDepth, bOneShot)
|
|
|
|
-- se modalitá pulitura spigoli e lavorazione di lato forzo a fare il contorno
|
|
if nFunction == 2 and nPathInt then
|
|
nFunction = 1
|
|
end
|
|
-- se richiesta pulitura del contorno
|
|
if nFunction == 1 then
|
|
return MakeRoundCleanContour( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacInd, nAddGrpId, dDiam, nFunction, bMillDown,
|
|
bDoubleSide, vtOrtho, nPathInt, nSurfInt, b3Solid,
|
|
dDepth, bOneShot)
|
|
-- se richiesta pulitura dei soli corner
|
|
elseif nFunction == 2 then
|
|
return MakeRoundCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacInd, nAddGrpId, dDiam, bMillDown, bDoubleSide)
|
|
-- altri casi non previsti
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeSharpCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam)
|
|
|
|
local sMyWarn = ''
|
|
local pAuxId = {}
|
|
local nAuxId
|
|
local AuxId
|
|
local ptApPoint
|
|
local dLenTrimExt
|
|
local sMilling
|
|
local dMaxDepth = 0
|
|
|
|
-- cerco l'angolo di riferimento dove applicare il percorso di pulitura, altrimenti esco
|
|
local _, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd)
|
|
if #tFacAdj == 0 then
|
|
return true
|
|
end
|
|
-- prendo il primo versore
|
|
local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT)
|
|
local vtN3 = EgtSurfTmFacetNormVersor( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT)
|
|
-- trovo il punto sulla superfice di riferimento
|
|
local _, ptLocP1, ptLocP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT)
|
|
local nIdIniPoint
|
|
local nIdEndPoint
|
|
if ptLocP1 and ptLocP2 then
|
|
if dist( ptLocP1, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL or dist( ptLocP2, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL then
|
|
nIdEndPoint = 4
|
|
nIdIniPoint = 5
|
|
elseif dist( ptLocP1, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL or dist( ptLocP2, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL then
|
|
nIdEndPoint = 5
|
|
nIdIniPoint = 4
|
|
end
|
|
end
|
|
-- versore direzione
|
|
local vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint]
|
|
vtExtr:normalize()
|
|
-- inserisco le prime tre linee
|
|
if nIdIniPoint and nIdEndPoint then
|
|
-- se fresatura da sotto salto la lavorazione
|
|
if vtExtr:getZ() < BD.DRILL_VZ_MIN then
|
|
local sErr = 'Error : clean corner milling from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- sommo i tre versori per avre una direzione media
|
|
vtExtr = vtN1 + vtN2 + vtN3
|
|
vtExtr:normalize()
|
|
-- recupero la lavorazione non calcolando l'elevazione
|
|
sMilling = ML.FindMilling( 'CleanCorner', ( 0.5 * dDiam))
|
|
if not sMilling then
|
|
local sErr = 'Error : CleanCorner not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile ( temporaneo, per compensare errore nella lavorazione)
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth
|
|
end
|
|
-- l'altezza di taglio del tagliente corrisponde al raggio del raccordo che si riesce a coprire
|
|
-- quindi confronto l'elevazione con il raggio utensile utilizzato per la svuotatura
|
|
if dMaxDepth < ( dDiam * 0.5) - 100 * GEO.EPS_SMALL then
|
|
sMyWarn = 'Warning : skip clean corner (the cut heigth is smaller to machine the corner radius)'
|
|
EgtOutLog( sMyWarn)
|
|
return false, sMyWarn
|
|
end
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdIniPoint], tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
-- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro
|
|
if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then
|
|
ptApPoint = ptLocP2
|
|
else
|
|
ptApPoint = ptLocP1
|
|
end
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB)
|
|
dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - (( dDiam/2) + 2)
|
|
-- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta
|
|
if dLenTrimExt > 10 * GEO.EPS_SMALL then
|
|
EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint , GDB_RT.GLOB)
|
|
-- prendo il nuovo punto finale
|
|
ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB)
|
|
end
|
|
table.insert( pAuxId, nAuxId)
|
|
-- creo linea di ritorno
|
|
nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
end
|
|
-- inserisco le ultime tre linee + uscita discostata rispetto all'ingresso
|
|
-- trovo il secondo punto sulla superfice di riferimento
|
|
_, ptLocP1, ptLocP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][2], GDB_ID.ROOT)
|
|
if ptLocP1 and ptLocP2 then
|
|
-- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro
|
|
if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then
|
|
ptApPoint = ptLocP2
|
|
else
|
|
ptApPoint = ptLocP1
|
|
end
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB)
|
|
dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - (( dDiam/2) + 2)
|
|
-- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta
|
|
if dLenTrimExt > 10 * GEO.EPS_SMALL then
|
|
EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint , GDB_RT.GLOB)
|
|
-- prendo il nuovo punto finale
|
|
ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB)
|
|
end
|
|
table.insert( pAuxId, nAuxId)
|
|
-- creo linea di ritorno
|
|
nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
-- piccolo scostamento di 2mm dall'angolo
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
-- ultima linea di risalita
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), tFacAdj[nIdLine][nIdIniPoint] + ( 2 * vtExtr), GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
end
|
|
-- trasformo in percorso
|
|
if #pAuxId > 0 then
|
|
AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true)
|
|
end
|
|
-- se non c'é il percorso do errore
|
|
if not AuxId then
|
|
local sErr = 'Error : impossible make clean corner path'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- modifico versore direzione
|
|
EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB)
|
|
-- inserisco la lavorazione
|
|
local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchId = EgtAddMachining( sName, sMilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ AuxId, -1}})
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if AreSameVectorApprox( vtN1, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtN1:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtN1:getY() < GEO.EPS_SMALL then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
else
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- tipo attacco e uscita
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.NONE)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI)
|
|
-- allungo inizio e fine di 10mm
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10)
|
|
-- setto affondamento 0
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, 0)
|
|
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione
|
|
local sUserNotes = 'VMRS=0;MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sErr
|
|
else
|
|
local _, sWarn = EgtGetMachMgrWarning( 0)
|
|
if EgtIsMachiningEmpty() then
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sWarn
|
|
else
|
|
return true, ( sMyWarn or sWarn)
|
|
end
|
|
end
|
|
|
|
return true, sMyWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam, bSpecialMach)
|
|
local sMyWarn = ''
|
|
-- ottengo l'angolo dove applicare il foro
|
|
local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd)
|
|
-- se non trovato nessun angolo interno valido esco
|
|
if #tFacAdj == 0 then
|
|
return true, sMyWarn
|
|
end
|
|
-- trovo il punto sulla superfice di riferimento
|
|
local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT)
|
|
local nIdIniPoint
|
|
local nIdEndPoint
|
|
if ptLocP1 and ptLocP2 then
|
|
if ( dist( ptLocP1, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) then
|
|
nIdEndPoint = 4
|
|
nIdIniPoint = 5
|
|
elseif ( dist( ptLocP1, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) then
|
|
nIdEndPoint = 5
|
|
nIdIniPoint = 4
|
|
end
|
|
end
|
|
-- inserisco foro
|
|
if nIdIniPoint and nIdEndPoint then
|
|
local vtExtr
|
|
if bSpecialMach then
|
|
local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT)
|
|
local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT)
|
|
vtExtr = vtN0 + vtN1 + vtN2
|
|
else
|
|
-- versore direzione
|
|
vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint]
|
|
end
|
|
vtExtr:normalize()
|
|
-- se foratura da sotto salto la lavorazione
|
|
if vtExtr:getZ() < BD.DRILL_VZ_MIN then
|
|
local sErr = 'Error : drilling from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero la lavorazione
|
|
local sDrilling, nType = ML.FindDrilling( dDiam)
|
|
if not sDrilling then
|
|
local sErr = 'Error : drilling not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dMaxDepth = 20
|
|
local dDiamTool = 20
|
|
local dDiamTh = 35
|
|
local bIsDrilling
|
|
if EgtMdbSetCurrMachining( sDrilling) then
|
|
bIsDrilling = ( EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) == MCH_MY.DRILLING)
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
if bIsDrilling then
|
|
dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth
|
|
else
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
|
|
dDiamTh = EgtTdbGetCurrToolThDiam()
|
|
end
|
|
end
|
|
-- se foro inclinato, limito il massimo affondamento
|
|
local CosB = abs( vtExtr:getX())
|
|
if CosB < BD.DRILL_VX_MAX then
|
|
local TgA = CosB / sqrt( 1 - CosB * CosB)
|
|
dMaxDepth = dMaxDepth - dDiamTh / 2 * TgA
|
|
else
|
|
dMaxDepth = 0
|
|
end
|
|
-- setto griglia
|
|
if bSpecialMach then
|
|
EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdEndPoint], vtExtr))
|
|
else
|
|
EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdIniPoint], vtExtr))
|
|
end
|
|
-- creo geometria
|
|
local AuxId = EgtCircle( nAddGrpId, {0,0,0}, EgtIf( bIsDrilling, dDiamTool/2, ( dDiamTool/2) + 0.1), GDB_RT.GRID)
|
|
-- riporto la griglia a globale
|
|
EgtSetGridFrame()
|
|
-- calcolo spessore
|
|
local dDepthBore = dMaxLen
|
|
if bSpecialMach then
|
|
-- calcolo l'elevazione
|
|
local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, tFacAdj[nIdLine][nIdEndPoint], vtExtr)
|
|
if dLenIn > 0 then
|
|
dDepthBore = dLenIn
|
|
elseif dLedOut then
|
|
dDepthBore = dLedOut
|
|
end
|
|
EgtModifyCurveThickness( AuxId, dDepthBore)
|
|
else
|
|
EgtModifyCurveThickness( AuxId, -dMaxLen)
|
|
end
|
|
-- inserisco la lavorazione
|
|
local sName = 'Drill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchId = EgtAddMachining( sName, sDrilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sDrilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ AuxId, -1}})
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_YM
|
|
if vtExtr:getY() > 100 * GEO.EPS_ZERO then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- aggiusto l'affondamento
|
|
local dDepth
|
|
if bSpecialMach then
|
|
dDepth = dDepthBore
|
|
else
|
|
dDepth = dMaxLen
|
|
if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
sMyWarn = 'Warning in drill : depth (' .. EgtNumToString( dDepth, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')'
|
|
dDepth = dMaxDepth
|
|
EgtOutLog( sMyWarn)
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill
|
|
local sUserNotes = 'VMRS=0;'
|
|
-- aggiungo alle note massima elevazione (coincide con affondamento)
|
|
sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dDepth, 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sErr
|
|
else
|
|
local _, sWarn = EgtGetMachMgrWarning( 0)
|
|
if EgtIsMachiningEmpty() then
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sWarn
|
|
else
|
|
return true, ( sMyWarn or sWarn)
|
|
end
|
|
end
|
|
end
|
|
|
|
return true, sMyWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ExtractExternalPaths( nPathInt, nNumIdAux, vtOrtho, b3Solid, nAddGrpId)
|
|
local nAuxId1, nAuxId2
|
|
if nNumIdAux == 1 then
|
|
-- fondo tra loro le curve compatibili
|
|
EgtMergeCurvesInCurveCompo( nPathInt)
|
|
-- esplodo il percorso in modo da avere entià separate per poterle controllare
|
|
local nStartId, nNumIds = EgtExplodeCurveCompo( nPathInt)
|
|
if nStartId then
|
|
local sDeleteByDir
|
|
-- Se normale lungo la Z elimino le entità che hanno differenza in Z
|
|
if abs(vtOrtho:getZ()) > 0.7 then
|
|
sDeleteByDir = 'Z'
|
|
-- altrimenti se normale lungo la Y elimino le entità che hanno variazione in Y
|
|
-- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getY()) > 0.7 then
|
|
elseif abs(vtOrtho:getY()) > 0.7 then
|
|
sDeleteByDir = 'Y'
|
|
-- caso che non dovrebbe mai capitare ma gestito per completezza
|
|
-- altrimenti se normale lungo la X elimino le entità che hanno variazione in X
|
|
-- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getX()) > 0.7 then
|
|
elseif abs(vtOrtho:getX()) > 0.7 then
|
|
sDeleteByDir = 'X'
|
|
end
|
|
if sDeleteByDir then
|
|
for i = 1, nNumIds do
|
|
local ptP1 = EgtSP( ( nStartId + i - 1), GDB_RT.GLOB)
|
|
local ptP2 = EgtEP( ( nStartId + i - 1), GDB_RT.GLOB)
|
|
if sDeleteByDir == 'Z' then
|
|
-- se hanno variazione in Z cancello l'entità
|
|
if abs( ptP1:getZ() - ptP2:getZ()) > 10 * GEO.EPS_SMALL then
|
|
EgtErase( nStartId + i - 1)
|
|
end
|
|
elseif sDeleteByDir == 'Y' then
|
|
-- se hanno variazione in Y cancello l'entità
|
|
if abs( ptP1:getY() - ptP2:getY()) > 10 * GEO.EPS_SMALL then
|
|
EgtErase( nStartId + i - 1)
|
|
end
|
|
elseif sDeleteByDir == 'X' then
|
|
-- se hanno variazione in X cancello l'entità
|
|
if abs( ptP1:getX() - ptP2:getX()) > 10 * GEO.EPS_SMALL then
|
|
EgtErase( nStartId + i - 1)
|
|
end
|
|
end
|
|
end
|
|
-- ricreo i vari percorsi
|
|
local dLocalVal
|
|
local tPaths = {}
|
|
local nNumPaths
|
|
local dMaxVal
|
|
local dMinVal
|
|
for i = 1, nNumIds do
|
|
local ptP1 = EgtSP( ( nStartId + i - 1), GDB_RT.GLOB)
|
|
if ptP1 then
|
|
if sDeleteByDir == 'Z' then
|
|
local bInsTab
|
|
for j = 1, #tPaths do
|
|
local dLocalVal = tPaths[j][2]
|
|
if abs( ptP1:getZ() - dLocalVal) < 10 * GEO.EPS_SMALL then
|
|
local tLocIds = tPaths[j][1]
|
|
table.insert( tLocIds, ( nStartId + i - 1))
|
|
tPaths[j][1] = tLocIds
|
|
bInsTab = true
|
|
end
|
|
end
|
|
-- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella
|
|
if not bInsTab then
|
|
table.insert( tPaths, {{( nStartId + i - 1)}, ptP1:getZ()})
|
|
dMaxVal = b3Solid:getMax():getZ()
|
|
dMinVal = b3Solid:getMin():getZ()
|
|
end
|
|
elseif sDeleteByDir == 'Y' then
|
|
local bInsTab
|
|
for j = 1, #tPaths do
|
|
local dLocalVal = tPaths[j][2]
|
|
if abs( ptP1:getY() - dLocalVal) < 10 * GEO.EPS_SMALL then
|
|
local tLocIds = tPaths[j][1]
|
|
table.insert( tLocIds, ( nStartId + i - 1))
|
|
tPaths[j][1] = tLocIds
|
|
bInsTab = true
|
|
end
|
|
end
|
|
-- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella
|
|
if not bInsTab then
|
|
table.insert( tPaths, {{( nStartId + i - 1)}, ptP1:getY()})
|
|
dMaxVal = b3Solid:getMax():getY()
|
|
dMinVal = b3Solid:getMin():getY()
|
|
end
|
|
elseif sDeleteByDir == 'X' then
|
|
local bInsTab
|
|
for j = 1, #tPaths do
|
|
local dLocalVal = tPaths[j][2]
|
|
if abs( ptP1:getX() - dLocalVal) < 10 * GEO.EPS_SMALL then
|
|
local tLocIds = tPaths[j][1]
|
|
table.insert( tLocIds, ( nStartId + i - 1))
|
|
tPaths[j][1] = tLocIds
|
|
bInsTab = true
|
|
end
|
|
end
|
|
-- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella
|
|
if not bInsTab then
|
|
table.insert( tPaths, {{( nStartId + i - 1)}, ptP1:getX()})
|
|
dMaxVal = b3Solid:getMax():getX()
|
|
dMinVal = b3Solid:getMin():getX()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if tPaths then
|
|
local tChamPath = {}
|
|
-- elimino quelle che non corrispondono agli estremi
|
|
for i = 1, #tPaths do
|
|
-- se non corrisponde ai limiti elimino l'elemento
|
|
if abs( tPaths[i][2] - dMaxVal) > 10 * GEO.EPS_SMALL and abs( tPaths[i][2] - dMinVal) > 10 * GEO.EPS_SMALL then
|
|
tPaths[i] = nil
|
|
end
|
|
end
|
|
|
|
for i = 1, #tPaths do
|
|
if tPaths[i] then
|
|
local tNoMatch = {}
|
|
local tPathLoc = tPaths[i][1]
|
|
local pIniLoc = EgtSP( tPathLoc[1], GDB_RT.GLOB)
|
|
local pEndLoc = EgtEP( tPathLoc[1], GDB_RT.GLOB)
|
|
-- ciclo sui percorsi per trovare i punti non coincidenti (se percorso non chiuso)
|
|
for j = 2, #tPathLoc do
|
|
-- prendo i punti del percorso successivo
|
|
local pAddIni = EgtSP( tPathLoc[j], GDB_RT.GLOB)
|
|
local pAddEnd = EgtEP( tPathLoc[j], GDB_RT.GLOB)
|
|
-- se consecutivi
|
|
if AreSamePointApprox( pEndLoc, pAddIni) then
|
|
pEndLoc = pAddEnd
|
|
elseif AreSamePointApprox( pIniLoc, pAddEnd) then
|
|
pIniLoc = pAddIni
|
|
else
|
|
table.insert( tNoMatch, tPathLoc[j])
|
|
end
|
|
end
|
|
-- controllo eventuali percorsi scartati
|
|
for j = 1, #tNoMatch do
|
|
-- prendo i punti del percorso successivo
|
|
local pAddIni = EgtSP( tNoMatch[j], GDB_RT.GLOB)
|
|
local pAddEnd = EgtEP( tNoMatch[j], GDB_RT.GLOB)
|
|
-- se consecutivi
|
|
if AreSamePointApprox( pEndLoc, pAddIni) then
|
|
pEndLoc = pAddEnd
|
|
elseif AreSamePointApprox( pIniLoc, pAddEnd) then
|
|
pIniLoc = pAddIni
|
|
end
|
|
end
|
|
-- creo concatenamento partendo dal punto iniziale
|
|
local nIdLoc = EgtCurveCompoByReorder( nAddGrpId, tPathLoc, pIniLoc, true)
|
|
if nIdLoc then
|
|
table.insert( tChamPath, nIdLoc)
|
|
end
|
|
end
|
|
end
|
|
for i = 1, #tChamPath do
|
|
local ptP1 = EgtSP( tChamPath[i], GDB_RT.GLOB)
|
|
-- modifico estrusione percorso
|
|
if sDeleteByDir == 'Z' then
|
|
if abs(ptP1:getZ() - dMaxVal) < 10 * GEO.EPS_SMALL then
|
|
EgtModifyCurveExtrusion( tChamPath[i], Z_AX(), GDB_RT.GLOB)
|
|
else
|
|
EgtModifyCurveExtrusion( tChamPath[i], -Z_AX(), GDB_RT.GLOB)
|
|
end
|
|
elseif sDeleteByDir == 'Y' then
|
|
if abs(ptP1:getY() - dMaxVal) < 10 * GEO.EPS_SMALL then
|
|
EgtModifyCurveExtrusion( tChamPath[i], Y_AX(), GDB_RT.GLOB)
|
|
else
|
|
EgtModifyCurveExtrusion( tChamPath[i], -Y_AX(), GDB_RT.GLOB)
|
|
end
|
|
elseif sDeleteByDir == 'X' then
|
|
if abs(ptP1:getX() - dMaxVal) < 10 * GEO.EPS_SMALL then
|
|
EgtModifyCurveExtrusion( tChamPath[i], X_AX(), GDB_RT.GLOB)
|
|
else
|
|
EgtModifyCurveExtrusion( tChamPath[i], -X_AX(), GDB_RT.GLOB)
|
|
end
|
|
end
|
|
end
|
|
if #tChamPath == 1 then
|
|
return tChamPath[1], 1, nil
|
|
elseif #tChamPath == 2 then
|
|
return tChamPath[1], 2, tChamPath[2]
|
|
else
|
|
for i = 1, nNumIds do
|
|
EgtErase( nStartId + i - 1)
|
|
end
|
|
for i = 1, #tChamPath do
|
|
EgtErase( tChamPath[i])
|
|
end
|
|
end
|
|
else
|
|
for i = 1, nNumIds do
|
|
EgtErase( nStartId + i - 1)
|
|
end
|
|
end
|
|
-- altrimenti cancello tutte le emtità e restituisco nil
|
|
else
|
|
for i = 1, nNumIds do
|
|
EgtErase( nStartId + i - 1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return nil, 0, nil
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeChamfer( Proc, bIs3Faces, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham)
|
|
|
|
-- Se variabile globale indica che lo smusso è gi stato fatto, esco
|
|
if bMadeChamfer then
|
|
return 0
|
|
end
|
|
bMadeChamfer = true
|
|
-- recupero la lavorazione
|
|
local sMilling = ML.FindMilling( 'Mark')
|
|
if not sMilling then
|
|
local sErr = 'Error : Mark not found in library'
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
-- ottengo le curve di contorno libero
|
|
local nAuxId1, nAuxId2, nNumIdAux
|
|
if bIs3Faces then
|
|
-- nAuxId1, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId)
|
|
-- EgtModifyCurveExtrusion( nAuxId1, vtOrtho, GDB_RT.GLOB)
|
|
-- BL.SetOpenSide( nAuxId1, vtOrtho, b3Solid, nAddGrpId, 1)
|
|
-- nNumIdAux = 2
|
|
|
|
-- estraggo i percorsi
|
|
nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, nAddGrpId)
|
|
-- se percorso creato estraggo solo i percorsi delle facce interessate, non di testa
|
|
if nAuxId1 then
|
|
nAuxId1, nNumIdAux, nAuxId2 = ExtractExternalPaths( nAuxId1, nNumIdAux, vtOrtho, b3Solid, nAddGrpId)
|
|
end
|
|
else
|
|
nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, nAddGrpId)
|
|
if not nNumIdAux then nNumIdAux = 0 end
|
|
end
|
|
|
|
local dExtra = 2
|
|
for i = 1, nNumIdAux do
|
|
local AuxId
|
|
local vtExtr
|
|
if bIs3Faces then
|
|
if i == 1 then
|
|
AuxId = nAuxId1
|
|
else
|
|
-- faccio la copia del percorso
|
|
-- AuxId = EgtCopyGlob( nAuxId1, nAddGrpId)
|
|
AuxId = nAuxId2
|
|
end
|
|
if AuxId then
|
|
vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
end
|
|
else
|
|
AuxId = nAuxId1 + i - 1
|
|
vtExtr, _, _ = EgtCurveArea( AuxId)
|
|
end
|
|
if vtExtr then
|
|
if not bIs3Faces then
|
|
local fFrCurve = EgtGetGlobFrame( AuxId)
|
|
vtExtr:toGlob( fFrCurve)
|
|
end
|
|
-- if bIs3Faces and i == nNumIdAux then
|
|
-- vtExtr = -vtExtr
|
|
-- end
|
|
-- Se normale entro certi limiti
|
|
-- if vtExtr:getZ() > -0.707 and ( abs(vtOrtho:getX()) > 0.99 or abs(vtOrtho:getY()) > 0.99 or abs(vtOrtho:getZ()) > 0.99) then
|
|
if vtExtr:getZ() > -0.707 and ( abs(vtExtr:getX()) > 0.99 or abs(vtExtr:getY()) > 0.99 or abs(vtExtr:getZ()) > 0.99) then
|
|
-- inserisco la lavorazione
|
|
local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i)
|
|
local nMchId = EgtAddMachining( sNameCh, sMilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
-- modifico estrusione percorso
|
|
EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ AuxId, -1}})
|
|
-- imposto posizione braccio porta testa
|
|
if vtExtr:getY() < GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- assegno affondamento e offset radiale
|
|
-- EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra - EgtIf( bIs3Faces, (dDepth / 2), 0))
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra)
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dExtra)
|
|
-- se opero su 3 facce e sono al secondo e ultimo percorso inverto la lavorazione
|
|
-- if bIs3Faces and i == nNumIdAux then
|
|
-- EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
-- end
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return -1, sErr
|
|
end
|
|
-- se non perpendicolare emetto un warning
|
|
-- else
|
|
-- sWarn = 'Warning : chamfer skipped because not perpendicular to face or from bottom'
|
|
-- EgtOutLog( sWarn)
|
|
end
|
|
--emetto un warning
|
|
-- else
|
|
-- sWarn = 'Warning : chamfer skipped because not perpendicular to face'
|
|
-- EgtOutLog( sWarn)
|
|
end
|
|
end
|
|
|
|
return 0
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByMillAsSaw( Proc, nPhase, nRawId, nPartId, nFacInd,
|
|
rfFac, dH, dV, dElev,
|
|
nBottomFace, nAddGrpId, b3Solid, dSawMaxDepth, sMillingOnSide,
|
|
dSawDiam, dSawThick, bIgnoreCaps)
|
|
local sWarn
|
|
-- ingombro del grezzo
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
-- ottengo la distanza tra la fine del pezzo e il pezzo successivo
|
|
local dDistToNextPiece = BL.GetDistanceToNextPart( nRawId, nPhase)
|
|
-- verifico definizione faccia con il maggior numero di adiacenze
|
|
if not nFacInd then
|
|
local sErr = 'Error : MakeByMillAsSaw could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Recupero le facce adiacenti alla principale
|
|
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
|
|
if not vAdj or #vAdj == 0 then
|
|
local sErr = 'Error : main face without adjacencies'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3)
|
|
-- Cerco una faccia adiacente alla principale sul lato più lungo
|
|
local nFacAdj
|
|
local dMaxLen = 0
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] >= 0 then
|
|
local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
local dLen = dist( ptP1, ptP2)
|
|
if abs( dLen - dMaxLen) < 5 then
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT)
|
|
if vtN:getY() > 0.5 or vtN:getZ() > 0.5 then
|
|
nFacAdj = vAdj[i]
|
|
dMaxLen = dLen
|
|
end
|
|
elseif dLen > dMaxLen then
|
|
nFacAdj = vAdj[i]
|
|
dMaxLen = dLen
|
|
end
|
|
end
|
|
end
|
|
if not nFacAdj then
|
|
local sErr = 'Error : long adjacent face not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT)
|
|
if abs( vtN * rfFac:getVersX()) > abs( vtN * rfFac:getVersY()) then
|
|
dH, dV = dV, dH
|
|
end
|
|
-- Determino se estremi aperti o chiusi
|
|
local bOpenStart = bIgnoreCaps
|
|
local bOpenEnd = bIgnoreCaps
|
|
local vtNS, vtNE
|
|
-- se non ho la faccia di fondo ( che comporta essere una fessura) e non da ignorare verifico se ho lati aperti
|
|
if not nBottomFace and not bIgnoreCaps then
|
|
local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1]
|
|
EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3)
|
|
for j = 1, #vAdj2 do
|
|
if vAdj2[j] == nFacInd then
|
|
-- Se non esiste faccia adiacente a lato precedente -> inizio aperto
|
|
local i = EgtIf( j > 1, j - 1, #vAdj2)
|
|
while vAdj2[i] == nFacInd do
|
|
i = EgtIf( i > 1, i - 1, #vAdj2)
|
|
end
|
|
bOpenStart = ( vAdj2[i] < 0)
|
|
-- se è chiusa acquisisco vettore faccia tappo
|
|
if not bOpenStart and vAdj2[i] >= 0 then
|
|
vtNS = EgtSurfTmFacetNormVersor( Proc.Id, vAdj2[i], GDB_ID.ROOT)
|
|
end
|
|
-- Se non esiste faccia adiacente a lato successivo -> fine aperto
|
|
local k = EgtIf( j < #vAdj2, j + 1, 1)
|
|
while vAdj2[k] == nFacInd do
|
|
k = EgtIf( k < #vAdj2, k + 1, 1)
|
|
end
|
|
bOpenEnd = ( vAdj2[k] < 0)
|
|
-- se è chiusa acquisisco vettore faccia tappo
|
|
if not bOpenEnd and vAdj2[k] >= 0 then
|
|
vtNE = EgtSurfTmFacetNormVersor( Proc.Id, vAdj2[k], GDB_ID.ROOT)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- Recupero la lavorazione di lama
|
|
local sCutting = sMillingOnSide
|
|
-- Calcolo uso faccia
|
|
local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ())
|
|
local dStartDist = -1
|
|
local dEndDist = -1
|
|
-- calcolo eventuali arretramenti lama
|
|
if not bOpenStart then
|
|
local dRadius = dSawDiam / 2
|
|
local dCat1 = dRadius - dElev
|
|
dStartDist = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1))
|
|
end
|
|
if not bOpenEnd then
|
|
if not bOpenStart then
|
|
dEndDist = dStartDist
|
|
else
|
|
local dRadius = dSawDiam / 2
|
|
local dCat1 = dRadius - dElev
|
|
dEndDist = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1))
|
|
end
|
|
end
|
|
-- Eseguo i tagli
|
|
local nStep = ceil( ( dV - 100 * GEO.EPS_SMALL) / dSawThick)
|
|
local dStep = 0
|
|
if nStep > 1 then
|
|
dStep = ( dV - dSawThick) / ( nStep - 1)
|
|
end
|
|
local dVzLimDwnUp = -0.01
|
|
for i = 1, nStep do
|
|
local dOffs = ( i - 1) * dStep
|
|
if vtN:getZ() < dVzLimDwnUp then dOffs = dOffs + dSawThick end
|
|
local bOk, sErr, nMchId = Fbs.MakeOne( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, dVzLimDwnUp, 0, BD.CUT_SIC, dOffs, dStartDist, dEndDist, nil, b3Raw)
|
|
if not bOk then return bOk, sErr end
|
|
-- setto l'elevazione
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( 0, 1) .. ';'
|
|
-- applico elevazione
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- tolgo eventuale step
|
|
EgtSetMachiningParam( MCH_MP.STEP, 0)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- in base all'elevazione calcolo l'impronta della lama
|
|
local dUsedBladeLen = sqrt( ((dSawDiam / 2)*(dSawDiam / 2)) - ( ( (dSawDiam / 2) - dElev) * ( (dSawDiam / 2) - dElev)))
|
|
-- controllo direzione taglio e se il minimo della feature sborda in coda
|
|
if abs( vtN:getX()) < GEO.EPS_SMALL and abs( b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then
|
|
-- do avviso che la lama può sbordare nel pezzo successivo
|
|
sWarn = 'Warning on mill side as blade : Cut machining can damage next piece'
|
|
EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')')
|
|
end
|
|
|
|
return true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd,
|
|
rfFac, dH, dV, dElev, bForceUseBlade,
|
|
dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace,
|
|
bOrthoFacesMaster, nBottomFace, nChamfer, nAddGrpId, b3Solid,
|
|
dDepthCham, nSurfInt)
|
|
local sWarn
|
|
-- ingombro del grezzo
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
-- ottengo la distanza tra la fine del pezzo e il pezzo successivo
|
|
local dDistToNextPiece = BL.GetDistanceToNextPart( nRawId, nPhase)
|
|
-- verifico se fessura con 3 facce o tunnel
|
|
local bOrthoFaces
|
|
local bIs3Faces = ( Proc.Fct == 3)
|
|
if bIs3Faces then
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
local nFacInd1, dFacElev1, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, bIs3Faces)
|
|
if not nFacInd1 or nFacInd1 < 0 then
|
|
if nFacInd1 == -1 then
|
|
bOrthoFaces = nFacInd2
|
|
else
|
|
local sErr = 'Error : MakeByChainOrSaw could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
else
|
|
bOrthoFaces = bOrthoFacesMaster
|
|
end
|
|
-- eventuale massima elevazione imposta dall'utente
|
|
local dMaxElev = EgtGetInfo( Proc.Id, Q_MAX_ELEVATION, 'd')
|
|
if dMaxElev and dMaxElev < 1 then dMaxElev = nil end
|
|
dElev = dMaxElev or dElev
|
|
|
|
if bOrthoFaces then
|
|
-- ottengo le dimensioni del tunnel
|
|
dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = BL.GetTunnelDimension( Proc, nPartId)
|
|
-- verifico la direzione
|
|
-- se devo inserire il chamfer
|
|
if nChamfer > 0 then
|
|
local nOk, sErr = MakeChamfer( Proc, bIs3Faces, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham)
|
|
if nOk < 0 then return false, sErr end
|
|
end
|
|
end
|
|
-- Recupero le facce adiacenti alla principale
|
|
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
|
|
if not vAdj or #vAdj == 0 then
|
|
local sErr = 'Error : main face without adjacencies'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3)
|
|
-- Cerco una faccia adiacente alla principale sul lato più lungo
|
|
local nFacAdj
|
|
local dMaxLen = 0
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] >= 0 then
|
|
local vtAdjN = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT)
|
|
if not bIs3Faces or abs( rfFac:getVersZ():getY()) < 0.174 or abs( rfFac:getVersZ():getY()) > 0.984 or vtAdjN:getY() * rfFac:getVersZ():getY() > -0.1 then
|
|
local _, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
local dLen = dist( ptP1, ptP2)
|
|
if dLen > dMaxLen then
|
|
nFacAdj = vAdj[i]
|
|
dMaxLen = dLen
|
|
EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if not nFacAdj then
|
|
local sErr = 'Error : long adjacent face not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare
|
|
local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT)
|
|
if abs( vtN * rfFac:getVersX()) > abs( vtN * rfFac:getVersY()) then
|
|
dH, dV = dV, dH
|
|
end
|
|
-- Determino se estremi aperti o chiusi
|
|
local bOpenStart = false
|
|
local bOpenEnd = false
|
|
local vtNS, vtNE
|
|
-- se non ho la faccia di fondo ( che comporta essere una fessura) verifico se ho lati aperti
|
|
if not nBottomFace then
|
|
local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1]
|
|
EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3)
|
|
for j = 1, #vAdj2 do
|
|
if vAdj2[j] == nFacInd then
|
|
-- Se non esiste faccia adiacente a lato precedente -> inizio aperto
|
|
local i = EgtIf( j > 1, j - 1, #vAdj2)
|
|
while vAdj2[i] == nFacInd do
|
|
i = EgtIf( i > 1, i - 1, #vAdj2)
|
|
end
|
|
bOpenStart = ( vAdj2[i] < 0)
|
|
-- se è chiusa acquisisco vettore faccia tappo
|
|
if not bOpenStart and vAdj2[i] >= 0 then
|
|
_, vtNS = EgtSurfTmFacetCenter( Proc.Id, vAdj2[i], GDB_ID.ROOT)
|
|
end
|
|
-- Se non esiste faccia adiacente a lato successivo -> fine aperto
|
|
local k = EgtIf( j < #vAdj2, j + 1, 1)
|
|
while vAdj2[k] == nFacInd do
|
|
k = EgtIf( k < #vAdj2, k + 1, 1)
|
|
end
|
|
bOpenEnd = ( vAdj2[k] < 0)
|
|
-- se è chiusa acquisisco vettore faccia tappo
|
|
if not bOpenEnd and vAdj2[k] >= 0 then
|
|
_, vtNE = EgtSurfTmFacetCenter( Proc.Id, vAdj2[k], GDB_ID.ROOT)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- escludo caso per L20 che porterebbe ad una lavorazione con lama non corretta; ritorno anche 'MNF' in modo da forzare una lavorazione tasca
|
|
if Proc.Prc == 20 and Proc.Fct >= 4 and bOpenStart and bOpenEnd and #vAdj >= 3 then
|
|
local sErr = 'Error: improper use of L020 feature'
|
|
return false, sErr, 'MNF'
|
|
end
|
|
-- verifico se uso lama da sotto
|
|
local bCutDown = ( BD.DOWN_HEAD and rfFac:getVersZ():getZ() < - 0.5)
|
|
-- Recupero il massimo affondamento possibile con la lama
|
|
local dSawMaxDepth = 0
|
|
local sCutting = ML.FindCutting( 'HeadSide', not bCutDown, bCutDown)
|
|
if sCutting then
|
|
if EgtMdbSetCurrMachining( sCutting) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dSawMaxDepth = EgtTdbGetCurrToolMaxDepth() or dSawMaxDepth
|
|
end
|
|
end
|
|
end
|
|
-- se lavorazione sulle teste e altezza trave supera il limite ( che causa collisione con la forcella) e direzione taglio lungo la Z
|
|
-- e limite profondità BeamData è maggiore del taglio massimo lama, assegno il massimo affondamento pari al limite profondità del BeamData
|
|
if bOpenStart and bOpenEnd and bForceUseBlade and ( Proc.Head or Proc.Tail) and abs(rfFac:getVersY():getY()) > 0.866 and
|
|
b3Solid:getDimZ() > BD.MIN_DIM_HBEAM and dSawMaxDepth > BD.MAX_DIM_HTCUT_HBEAM then
|
|
dSawMaxDepth = BD.MAX_DIM_HTCUT_HBEAM
|
|
end
|
|
-- Se entrambi gli estremi sono aperti e possibile, lavoro con la lama
|
|
if bOpenStart and bOpenEnd and bForceUseBlade and dElev < dSawMaxDepth + 10 * GEO.EPS_SMALL then
|
|
-- recupero altri dati dell'utensile
|
|
local dSawDiam = 400
|
|
local dSawThick = 4
|
|
if EgtMdbSetCurrMachining( sCutting) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
|
|
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
|
|
end
|
|
end
|
|
if dSawThick > dV + 10 * GEO.EPS_SMALL then
|
|
local sErr = 'Error : sawblade too thick'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Calcolo uso faccia
|
|
local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ())
|
|
-- Eseguo i tagli
|
|
local nStep = ceil( ( dV - 100 * GEO.EPS_SMALL) / dSawThick)
|
|
local dStep = 0
|
|
if nStep > 1 then
|
|
dStep = ( dV - dSawThick) / ( nStep - 1)
|
|
end
|
|
for i = 1, nStep do
|
|
local dOffs = ( i - 1) * dStep
|
|
local bOk, sErr = Fbs.MakeOne( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, 0, 0, nil, b3Raw)
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
-- in base all'elevazione calcolo l'impronta della lama
|
|
local dUsedBladeLen = sqrt( ((dSawDiam / 2)*(dSawDiam / 2)) - ( ( (dSawDiam / 2) - dElev) * ( (dSawDiam / 2) - dElev)))
|
|
-- controllo direzione taglio e se il minimo della feature sborda in coda
|
|
if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then
|
|
-- do avviso che la lama può sbordare nel pezzo successivo
|
|
sWarn = 'Warning on saw cut : Cut machining can damage next piece'
|
|
EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')')
|
|
end
|
|
-- altrimenti con sega a catena
|
|
else
|
|
-- Recupero la lavorazione
|
|
local sSawing = ML.FindSawing( 'Sawing')
|
|
if not sSawing then
|
|
local sErr = 'Error : Sawing not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr, 'MNF'
|
|
end
|
|
-- Recupero i dati dell'utensile
|
|
local dSawWidth = 75
|
|
local dSawThick = 8
|
|
local dMaxDepth = 200
|
|
if EgtMdbSetCurrMachining( sSawing) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth
|
|
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
end
|
|
if dSawThick > dV + 10 * GEO.EPS_SMALL then
|
|
local sErr = 'Error : chainsaw too thick'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local bGoFromHead = true
|
|
-- se la lunghezza utensile non riesce ad arrivare sul fondo assegno la possibilità di lavorare di fianco (se possibile)
|
|
if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
-- continuo di testa se fessura con tre facce o non è tunnel
|
|
bGoFromHead = (( bIs3Faces and dMaxElev) or not bOrthoFaces)
|
|
end
|
|
-- se continuo a lavorare di testa
|
|
if bGoFromHead then
|
|
-- Calcolo normale faccia adiacente
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT)
|
|
-- Calcolo uso faccia
|
|
local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ(), vtN)
|
|
-- Verifico se necessarie più passate
|
|
local nStep = ceil( ( dV - 100 * GEO.EPS_SMALL) / dSawThick)
|
|
local dStep = 0
|
|
if nStep > 1 then
|
|
dStep = ( dV - dSawThick) / ( nStep - 1)
|
|
end
|
|
for i = 1, nStep do
|
|
-- Applico la lavorazione con sega a catena a questa faccia
|
|
local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i)
|
|
local nMchFId = EgtAddMachining( sName, sSawing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}})
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- controllo direzione taglio e se il minimo della feature sborda in coda
|
|
if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL then
|
|
-- se ho lato partenza aperto e lato uscita chiuso e direzione lato chiuso è negativa, allora controllo uscita lama
|
|
if bOpenStart and not bOpenEnd and vtNE:getX() < -0.99 and dDistToNextPiece < (dSawWidth / 2) then
|
|
-- imposto accorciamento iniziale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dDistToNextPiece - 1 - (dSawWidth / 2))
|
|
else
|
|
-- imposto accorciamento iniziale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2))
|
|
end
|
|
-- se ho lato uscita aperto e lato partenza chiuso e direzione lato partenza è negativa, allora controllo uscita lama
|
|
if bOpenEnd and not bOpenStart and vtNS:getX() < -0.99 and dDistToNextPiece < (dSawWidth / 2) then
|
|
-- imposto accorciamento finale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dDistToNextPiece - 1 - (dSawWidth / 2))
|
|
else
|
|
-- imposto accorciamento finale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2))
|
|
end
|
|
else
|
|
-- imposto accorciamento iniziale/finale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2))
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2))
|
|
end
|
|
-- imposto angolo 3° asse rot e eventuale angolo suggerito per inizio
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, BL.GetChainSawBlockedAxis( 1))
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, BL.GetChainSawInitAngs( vtN, rfFac:getVersZ(), 1))
|
|
-- imposto offset radiale
|
|
local dOffs = ( i - 1) * dStep
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dOffs)
|
|
-- se necessario, avverto limitazioneo dell'affondamento
|
|
if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
sWarn = 'Warning in LapJoint : elevation (' .. EgtNumToString( dElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')'
|
|
EgtOutLog( sWarn)
|
|
--local dDepth = dMaxDepth - dElev
|
|
--EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH '..EgtNumToString( dDepth, 1))
|
|
end
|
|
-- imposto massima elevazione
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 2) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
if EgtGetOutstrokeInfo() then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
-- impostazione alternativa angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, BL.GetChainSawBlockedAxis( 2))
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, BL.GetChainSawInitAngs( vtN, rfFac:getVersZ(), 2))
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
if EgtIsMachiningEmpty() then
|
|
_, sWarn = EgtGetMachMgrWarning( 0)
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sWarn
|
|
end
|
|
end
|
|
-- altrimenti sega a catena di fianco
|
|
else
|
|
-- verifico se posso farlo con la sega-catena
|
|
local bMakeChainSaw, sSawing2, dMaxMat2, dSawCornerRad2, dSawThick2 = VerifyChainSaw( Proc, dDimMin, dDimMax)
|
|
if bMakeChainSaw then
|
|
-- Calcolo normale faccia da lavorare
|
|
local vtNL = EgtSurfTmFacetNormVersor( Proc.Id, nLundIdFace, GDB_ID.ROOT)
|
|
-- Calcolo uso faccia
|
|
local vtRef = Vector3d( vtOrtho)
|
|
if vtRef:getY() > 0.5 or vtRef:getZ() < -0.1 then vtRef = -vtRef end
|
|
local nFaceUse = BL.GetNearestParalOpposite( vtRef, vtNL)
|
|
-- Verifico se necessarie più passate
|
|
local nStep = ceil( ( dDimMin - 100 * GEO.EPS_SMALL) / dSawThick2)
|
|
local dStep = 0
|
|
if nStep > 1 then
|
|
dStep = ( dDimMin - dSawThick2) / ( nStep - 1)
|
|
end
|
|
for i = 1, nStep do
|
|
-- inserisco la lavorazione di sawing
|
|
local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i)
|
|
local nMchFId = EgtAddMachining( sName, sSawing2)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing2
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nLundIdFace}})
|
|
-- imposto uso del lato faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, BL.GetChainSawBlockedAxis( 1))
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, BL.GetChainSawInitAngs( vtNL, vtOrtho, 1))
|
|
-- imposto offset radiale
|
|
local dOffs = ( i - 1) * dStep
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dOffs)
|
|
-- se possibile aumento l'affondamento pari al raggio corner + 1
|
|
if dMaxMat2 > ( dDepth + dSawCornerRad2 + 1) then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, (dDepth + dSawCornerRad2 + 1))
|
|
-- se massimo affondamento supera altezza fessura, uso massimo affondamento
|
|
elseif dMaxMat2 > (dDepth + 1) then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, (dMaxMat2 - 1))
|
|
-- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning
|
|
elseif dMaxMat2 < dDepth then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat2)
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
-- considero estremi inizio/fine chiusi
|
|
-- imposto massima elevazione
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
if EgtGetOutstrokeInfo() then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
-- impostazione alternativa angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, BL.GetChainSawBlockedAxis( 2))
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, BL.GetChainSawInitAngs( vtNL, vtOrtho, 2))
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
if EgtIsMachiningEmpty() then
|
|
_, sWarn = EgtGetMachMgrWarning( 0)
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sWarn
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw, nFacInd, bReduceDepth, bMillDown)
|
|
-- Recupero la lavorazione di lama
|
|
local sCutting = ML.FindCutting( 'HeadSide', not bMillDown, bMillDown)
|
|
if not sCutting then
|
|
local sErr = 'Error : HeadSide (cutting) not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- valuto l'angolo tra le due facce
|
|
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacet, GDB_ID.ROOT)
|
|
local ptPm = (ptP1+ptP2)/2
|
|
-- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta l'elevazione della faccia
|
|
-- laterale sul punto medio della linea in comune
|
|
local frFc = Frame3d( ptPm, vtN) ;
|
|
local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc)
|
|
dDepth = b3BoxLoc:getDimZ() or 0
|
|
-- recupero i dati dell'utensile
|
|
local dSawDiam = 400
|
|
local dSawThick = 0
|
|
local dMaxDepth = 0
|
|
if EgtMdbSetCurrMachining( sCutting) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
|
|
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
end
|
|
local dExtraOffs = 0
|
|
-- se profondità superiore al massimo lama modifico elevazione
|
|
if dDepth > dMaxDepth then
|
|
dExtraOffs = dMaxDepth - dDepth
|
|
end
|
|
-- se devo ridurre l'affondamento
|
|
if bReduceDepth then
|
|
local dLimitDepth = 100
|
|
-- se ho ridotto l'affondamento ne riduco ulteriormente l'affondamento (50mm)
|
|
if abs(dExtraOffs) > 0 then
|
|
if dMaxDepth > dLimitDepth then
|
|
dExtraOffs = dLimitDepth - dDepth
|
|
end
|
|
else
|
|
if dDepth > dLimitDepth then
|
|
dExtraOffs = dLimitDepth - dDepth
|
|
else
|
|
dExtraOffs = - (dDepth/2)
|
|
end
|
|
end
|
|
end
|
|
-- eseguo il taglio
|
|
local dVzLimDwnUp = EgtIf( BD.TURN, -2, nil)
|
|
local bMadeASbyBld, sWarn, nIdMach = Fbs.MakeOne( Proc.Id, nFacet, sCutting, dSawDiam, vtN, dVzLimDwnUp, ( -0.5 + dExtraOffs), BD.CUT_SIC, 0, 0, 0, nil, b3Raw)
|
|
if bMadeASbyBld then
|
|
sWarn = nil
|
|
if not bReduceDepth and abs(dExtraOffs) > 0 then
|
|
sWarn = 'Warning : antisplint elevation is bigger than max tool depth'
|
|
end
|
|
end
|
|
return bMadeASbyBld, sWarn, nIdMach, dSawThick, dMaxDepth, bAdj, dAng, dExtraOffs
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakePocket( Proc, nPartId, b3Solid, ptPs, tvtN, nFaceRef, sMchFind, nUseRoughTool, sMasterPocket, dPrevFaceElev, tDimAndRef, dAng, bOpenOutRaw)
|
|
|
|
-- calcolo l'elevazione dal punto medio
|
|
local dElev
|
|
local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, tvtN[2])
|
|
if dLenIn > 0 then
|
|
dElev = dLenIn
|
|
elseif dLedOut then
|
|
dElev = dLedOut
|
|
end
|
|
local dCollSic = 2 * BD.COLL_SIC
|
|
-- calcolo il diametro utensile
|
|
local dFaceDiamTool
|
|
if tDimAndRef then
|
|
-- prendo il valore dalle dimensioni minime delle facce
|
|
dFaceDiamTool = min( tDimAndRef[2][1], tDimAndRef[2][2])
|
|
end
|
|
-- se ho lavorazione precedente ricalcolo grossolanamente l'elevazione
|
|
if dPrevFaceElev and dPrevFaceElev > 0 and dAng then
|
|
dElev = dElev + ( sqrt( ( dElev * dElev) - ( dPrevFaceElev * dPrevFaceElev)) * sin(dAng))
|
|
elseif dPrevFaceElev and dPrevFaceElev > dElev then
|
|
dElev = dPrevFaceElev
|
|
end
|
|
local sPocketing
|
|
if sMasterPocket then
|
|
sPocketing = sMasterPocket
|
|
else
|
|
sPocketing = ML.FindPocketing( sMchFind, dFaceDiamTool, dElev + dCollSic)
|
|
end
|
|
if not sPocketing then
|
|
local sErr = 'Error : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local sTuuidPk
|
|
local dDiamTool = 20
|
|
local dMaxDepth = 0
|
|
local bTipMill = false
|
|
if EgtMdbSetCurrMachining( sPocketing) then
|
|
sTuuidPk = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidPk) or '') then
|
|
dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dDiamTool
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
bTipMill = (( EgtTdbGetCurrToolParam( MCH_TP.TIPFEED) or 0) > 1)
|
|
end
|
|
end
|
|
-- se nome svuotatura non è stato ricalcolato, confronto il diametro utensile utilizzato con il minimo faccia e se non sono compatibili esco
|
|
if sMasterPocket and dFaceDiamTool and dDiamTool >= dFaceDiamTool then
|
|
return false, '', sTuuidPk, dDiamTool, dElev
|
|
end
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef)
|
|
local nMchFId = EgtAddMachining( sName, sPocketing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, (nFaceRef)}})
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT)
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM and not BD.TURN then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
if AreSameVectorApprox( tvtN[2], Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( tvtN[2]:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( EgtGetCurrPhase()), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif tvtN[2]:getY() > 0.1 then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- se tasca aperta e non lavorata col truciolatore, imposto opportuno attacco
|
|
if sMchFind == 'OpenPocket' and nUseRoughTool == 0 then
|
|
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
|
|
end
|
|
if sMchFind == 'OpenPocket' and dDiamTool < 90 then
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFaceRef, GDB_ID.ROOT)
|
|
local bL = ( Proc.Fct < 4 or TestElleShape4( Proc) == 2)
|
|
if bL and min( dH, dV) < 1.5 * dDiamTool then
|
|
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.ZIGZAG)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
if not bTipMill then
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_POCK_LI.HELIX)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, dDiamTool)
|
|
EgtSetMachiningParam( MCH_MP.LIELEV, 2)
|
|
end
|
|
end
|
|
end
|
|
-- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente
|
|
local sWarn
|
|
local dDepth = dElev
|
|
if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
dDepth = dMaxDepth - dElev
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
dElev = dMaxDepth
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
-- imposto elevazione e dichiaro non si generano sfridi per VMill
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';'
|
|
sNotes = sNotes .. 'VMRS=0;'
|
|
if bOpenOutRaw then
|
|
sNotes = sNotes .. 'OpenOutRaw=1;'
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
if not ML.ApplyMachining( true, false) then
|
|
-- provo ad allargare leggermente la tasca
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, -0.1)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
if BD.TURN then
|
|
-- centro del pezzo
|
|
local ptCen = ORIG()
|
|
if b3Solid then ptCen = b3Solid:getCenter() end
|
|
-- punto inizio lavorazione
|
|
local ptStart = EgtGetMachiningStartPoint() or ORIG()
|
|
-- orientamento braccio
|
|
local nSCC = MCH_SCC.NONE
|
|
-- se faccia verso alto o basso
|
|
if abs( tvtN[2]:getZ()) > abs( tvtN[2]:getY()) then
|
|
nSCC = EgtIf( ptStart:getY() > ptCen:getY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
-- altrimenti faccia verso davanti o dietro
|
|
else
|
|
nSCC = EgtIf( ptStart:getZ() > ptCen:getZ(), MCH_SCC.ADIR_ZP, MCH_SCC.ADIR_ZM)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
ML.ApplyMachining( true, false)
|
|
end
|
|
return true, sWarn, sTuuidPk, dDiamTool, dDepth
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, tvtN, nBaseFace, nSideFace, ptPs, tDimAndRef,
|
|
b3Raw, nDiffWidth, nUseRoughTool, dAng, sPocketing, sTuuidPk, dPrevFaceElev)
|
|
|
|
local sMchFind = 'Pocket'
|
|
local dAngLimit = 40
|
|
|
|
-- se feature é larga come trave imposto openpocket
|
|
if nDiffWidth == 0 then
|
|
sMchFind = 'OpenPocket'
|
|
-- altrimenti non è passante disabilito il truciolatore
|
|
else
|
|
nUseRoughTool = 0
|
|
end
|
|
-- se angolo tra le facce maggiore di 90, inserisco la contornatura o svuotatura del lato più corto
|
|
if ( 180 + dAng) > 90.1 then
|
|
-- calcolo l'angolo dalla verticale dall'angolo tra le due facce, perchè la feature potrebbe essere ruotata sulla Z locale della
|
|
-- faccia principale e quindi la componente X del versore della faccia potrebbe dare un valore non coerente
|
|
local dDiffFromSqAng = dAng + 90
|
|
-- se l'angolo dalla verticale si discosta di più dell'angolo limite impostato, utilizzo la svuotatura
|
|
if cos( dDiffFromSqAng) < cos( dAngLimit) then
|
|
-- applico la svuotatura
|
|
local bOk, sWarn, sTuuidPk, dDiamTool, dElev = MakePocket( Proc, nPartId, b3Solid, ptPs, tvtN, nSideFace, sMchFind, nUseRoughTool, sPocketing, dPrevFaceElev, tDimAndRef, dAng)
|
|
if not bOk then
|
|
-- se ho id utensile e diametro è perchè non ha fatto svuotatura perchè la faccia è più stretta del diametro utensile
|
|
-- e provo ad inserire singola passata di testa
|
|
if sTuuidPk and dDiamTool then
|
|
-- recupero la lavorazione
|
|
local sMilling = ML.FindMilling( 'Long2Cut', dElev, sTuuidPk)
|
|
if not sMilling then
|
|
local sErr = 'Error : Long2Cut not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- inserisco la lavorazione
|
|
local sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchId = EgtAddMachining( sName, sMilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nSideFace}})
|
|
-- imposto uso faccia
|
|
local nFaceUse = BL.GetNearestOrthoOpposite(tvtN[1])
|
|
-- aggiusto i parametri
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH')
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, 0)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, 1)
|
|
-- imposto posizione braccio porta testa
|
|
if tvtN[2]:getY() < GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
|
|
end
|
|
-- imposto elevazione e dichiaro non si generano sfridi per VMill
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';'
|
|
sNotes = sNotes .. 'VMRS=0;'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
else
|
|
return false, sWarn
|
|
end
|
|
else
|
|
return bOk, sWarn
|
|
end
|
|
-- altrimenti contornatura di fianco
|
|
else
|
|
local bOpenStart = false
|
|
local bOpenEnd = false
|
|
if nDiffWidth == 0 then
|
|
bOpenStart = true
|
|
bOpenEnd = true
|
|
else
|
|
local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, (nBaseFace))[1]
|
|
for j = 1, #vAdj2 do
|
|
if vAdj2[j] == (nSideFace) then
|
|
-- Se non esiste faccia adiacente a lato precedente -> inizio aperto
|
|
local i = EgtIf( j > 1, j - 1, #vAdj2)
|
|
while vAdj2[i] == (nSideFace) do
|
|
i = EgtIf( i > 1, i - 1, #vAdj2)
|
|
end
|
|
bOpenStart = ( vAdj2[i] < 0)
|
|
-- Se non esiste faccia adiacente a lato successivo -> fine aperto
|
|
local k = EgtIf( j < #vAdj2, j + 1, 1)
|
|
while vAdj2[k] == (nSideFace) do
|
|
k = EgtIf( k < #vAdj2, k + 1, 1)
|
|
end
|
|
bOpenEnd = ( vAdj2[k] < 0)
|
|
end
|
|
end
|
|
end
|
|
local sMilling
|
|
if nUseRoughTool > 0 then
|
|
sMilling = ML.FindMilling( 'Long2Cut', nil, sTuuidPk)
|
|
if not sMilling then sMilling = ML.FindMilling( 'Long2Cut') end
|
|
else
|
|
sMilling = ML.FindMilling( 'LongSmallCut', nil, sTuuidPk)
|
|
if not sMilling then sMilling = ML.FindMilling( 'LongSmallCut') end
|
|
end
|
|
if not sMilling then
|
|
local sErr = 'Error : Long2Cut & LongSmallCut not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 50
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam
|
|
end
|
|
end
|
|
-- Calcolo uso faccia
|
|
local nFaceUse = BL.GetNearestParalOpposite( tDimAndRef[1][3]:getVersZ())
|
|
-- inserisco la lavorazione di fresatura
|
|
local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, (nSideFace)}})
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- sistemazione inversione del percorso
|
|
local nWrkSide = EgtGetMachiningParam( MCH_MP.WORKSIDE)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, ( nWrkSide ~= MCH_MILL_WS.RIGHT))
|
|
-- setto a 0 eventuali offset
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, 0)
|
|
-- calcolo elevazione per allungamenti attacchi con fianchi chiusi
|
|
local dElev
|
|
local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, tvtN[2])
|
|
if dLenIn > 0 then
|
|
dElev = dLenIn
|
|
elseif dLedOut then
|
|
dElev = dLedOut
|
|
end
|
|
-- applico gli allungamenti o accorciamenti
|
|
if bOpenStart then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dTDiam / 2)
|
|
-- forzo attacco lineare
|
|
if dElev > 0 then
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LI.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dElev)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, dElev)
|
|
end
|
|
end
|
|
if bOpenEnd then
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dTDiam / 2)
|
|
-- forzo attacco lineare
|
|
if dElev > 0 then
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LI.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dElev)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, dElev)
|
|
end
|
|
end
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetUShapeWidth( Proc, nFacInd)
|
|
-- Recupero le facce adiacenti alla principale
|
|
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
|
|
-- se non ho facce adiacenti esco subito
|
|
if not vAdj or #vAdj == 0 then return 0 end
|
|
-- Normale della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- Cerco le facce adiacenti alla principale con angolo concavo >= 90
|
|
local dWidth = 0
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] >= 0 then
|
|
-- verifico l'angolo tra le facce ( esco se angolo compreso < 90)
|
|
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
if bAdj and dAng < -90 - 20 * GEO.EPS_ANG_SMALL then return nil end
|
|
-- larghezza della faccia ortogonalmente alla adiacente
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT)
|
|
local vtX = vtN2 ^ vtN
|
|
local frRef = Frame3d( ptC, ptC + 100 * vtX, ptC + 100 * vtN2)
|
|
local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, nFacInd, GDB_BB.STANDARD, frRef)
|
|
if b3Ref then
|
|
dWidth = max( dWidth, b3Ref:getDimY())
|
|
end
|
|
end
|
|
end
|
|
return dWidth
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMchFindMaster, bIs3Faces, b3Solid, bOrthoFacesMaster, bMillDown, bSetOpenBorders, bIsU, bIsL)
|
|
|
|
local nFirstMachId
|
|
local bOrthoFaces
|
|
local sWarn
|
|
local sMchFind = 'Pocket'
|
|
local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt
|
|
local bBadMach = false
|
|
-- minima altezza della tasca sotto alla quale fa una contornatura invece di una svuotatura
|
|
local dMinFaceElevForPocket = 20
|
|
if sMchFindMaster and #sMchFindMaster > 0 then
|
|
sMchFind = sMchFindMaster
|
|
end
|
|
if bIs3Faces then
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
local nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, bIs3Faces)
|
|
if not nFacInd or nFacInd < 0 then
|
|
if nFacInd == -1 then
|
|
bOrthoFaces = nFacInd2
|
|
else
|
|
local sErr = 'Error : MakeByPockets could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
end
|
|
else
|
|
bOrthoFaces = bOrthoFacesMaster
|
|
end
|
|
|
|
-- se è un tunnel verifico se è possibile usare la svuotatura
|
|
if bOrthoFaces then
|
|
-- ottengo le dimensioni del tunnel
|
|
dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = BL.GetTunnelDimension( Proc, nPartId)
|
|
-- se due facce posso utilizzare utensile con diametro doppio della dimensione minima
|
|
if Proc.Fct == 2 then
|
|
dDimMin = 2 * dDimMin
|
|
-- se tre facce aumento il diametro di quanto possibile
|
|
elseif Proc.Fct == 3 then
|
|
local nFacInd = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false)
|
|
local dWidth = GetUShapeWidth( Proc, nFacInd or -1)
|
|
if dWidth > dDimMin then
|
|
dDimMin = min( 2 * dDimMin, dWidth)
|
|
end
|
|
end
|
|
-- se devo inserire il chamfer
|
|
if nChamfer > 0 then
|
|
local nOk, sErr = MakeChamfer( Proc, bIs3Faces, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham)
|
|
if nOk < 0 then return -1, sErr end
|
|
end
|
|
-- se smusso non è esclusivo
|
|
local nPathInt
|
|
if nChamfer < 2 then
|
|
-- ricalcolo se è lavorabile da sotto
|
|
bMillDown = ( BD.DOWN_HEAD == true)
|
|
-- verifico se può essere fatto con svuotatura
|
|
local bMakePocket, sPocketing, dMaxDepth, dDiamTool = VerifyPocket( Proc, dDimMin, dDepth / 2, nil, sMchFind)
|
|
local bMakePocketDn, sPocketingDn, dMaxDepthDn, dDiamToolDn
|
|
if bMillDown then
|
|
bMakePocketDn, sPocketingDn, dMaxDepthDn, dDiamToolDn = VerifyPocket( Proc, dDimMin, dDepth / 2, nil, sMchFind, true)
|
|
-- se è negativo inverto il versore e la faccia
|
|
if vtOrtho:getZ() < 0 then
|
|
vtOrtho = -vtOrtho
|
|
EgtInvertSurf( nSurfInt)
|
|
end
|
|
end
|
|
local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local bMakeContour = false
|
|
local sMilling
|
|
if dFacElev < dMinFaceElevForPocket and ( bIsU or bIsL) and ( Proc.Fct == 2 or Proc.Fct == 3) and abs( vtN:getZ()) > 0.996 then
|
|
bMakeContour = true
|
|
-- recupero la lavorazione di contornatura
|
|
sMilling = ML.FindMilling( 'Prof', nil, nil, nil, nil, not bMillDown, bMillDown)
|
|
if not sMilling then
|
|
local sMyWarn = 'Warning : Prof not found in library'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
dDiamTool = 50
|
|
dMaxDepth = 0
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dToolMaxDepth
|
|
end
|
|
end
|
|
end
|
|
if bMakePocket or bMakeContour then
|
|
-- gestione svuotatura da un solo lato o anche dal lato opposto (se non verticale)
|
|
-- estraggo il contorno dalla superfice per evitare i problemi con la svuotatura
|
|
-- e assegno l'estrusione
|
|
nPathInt = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId)
|
|
EgtModifyCurveExtrusion( nPathInt, vtOrtho, GDB_RT.GLOB)
|
|
-- se ho 3 facce oppure se forzato, ciclo sulle entià del percorso per segnare quelle che sono aperte.
|
|
if bIs3Faces or bSetOpenBorders then
|
|
BL.SetOpenSide( nPathInt, vtOrtho, b3Solid, nAddGrpId)
|
|
end
|
|
-- variabili per parametri lavorazione
|
|
local dMachDepth
|
|
local dElev = 0
|
|
local bDoubleSide
|
|
local bOneShot
|
|
local bComplete = true
|
|
-- imposto altezza aggiuntiva di elevazione
|
|
local dCollSic = BL.CalcCollisionSafety( vtOrtho)
|
|
-- se possibile svuotare completamente da una sola parte
|
|
if dMaxDepth > ( dDepth + BD.CUT_EXTRA + dCollSic) then
|
|
dMachDepth = ( dDepth / 2) + BD.CUT_EXTRA
|
|
dElev = dDepth + BD.CUT_EXTRA
|
|
bOneShot = true
|
|
else
|
|
-- se direzione verso la verticale setto max affondamento possibile ed
|
|
-- emetto messaggio di warning perché non lavorabile interamente
|
|
if abs( vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD and not bMakeContour then
|
|
dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic
|
|
dElev = dMaxDepth
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
bComplete = false
|
|
-- altrimenti setto il flag per fare la svuotatura da due parti
|
|
else
|
|
-- se l'altezza utensile riesce a lavorare completamente da due parti
|
|
if dMaxDepth > ( dDepth / 2) + dCollSic + BD.CUT_EXTRA_MIN then
|
|
dMachDepth = BD.CUT_EXTRA_MIN
|
|
dElev = ( dDepth / 2) + BD.CUT_EXTRA_MIN
|
|
-- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione
|
|
else
|
|
dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic
|
|
dElev = dMaxDepth
|
|
-- se molto inclinato rispetto alla normale della faccia di riferimento, lavorazione non idonea per probabili collisioni
|
|
local vtRef = Y_AX()
|
|
if abs( vtOrtho:getX()) > abs( vtOrtho:getY()) and abs( vtOrtho:getX()) > abs( vtOrtho:getZ()) then
|
|
vtRef = X_AX()
|
|
elseif abs( vtOrtho:getZ()) > abs( vtOrtho:getX()) and abs( vtOrtho:getZ()) > abs( vtOrtho:getY()) then
|
|
vtRef = Z_AX()
|
|
end
|
|
if abs( vtOrtho * vtRef) < 0.5 then
|
|
bBadMach = true
|
|
end
|
|
end
|
|
bDoubleSide = true
|
|
end
|
|
end
|
|
-- se lavorazione non idonea esco
|
|
if bIs3Faces and bBadMach then
|
|
local sErr = 'Impossible apply perpendicular pocketing: ' .. sPocketing
|
|
return -2, sErr
|
|
end
|
|
local sName
|
|
local nMchFId
|
|
if bMakeContour then
|
|
-- inserisco la lavorazione di contornatura
|
|
sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
else
|
|
-- altrimenti inserisco la lavorazione di svuotatura
|
|
sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
nMchFId = EgtAddMachining( sName, sPocketing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
end
|
|
-- prendo l'id della prima lavorazione inserita
|
|
if not nFirstMachId then
|
|
nFirstMachId = nMchFId
|
|
end
|
|
if bMakeContour then
|
|
-- aggiungo geometria per contornatura
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
|
|
else
|
|
-- altrimenti aggiungo geometria per svuotatura
|
|
EgtSetMachiningGeometry( {{ nPathInt, -1}})
|
|
end
|
|
-- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale)
|
|
local bInvertMach
|
|
if not bMakeContour then
|
|
if vtOrtho:getZ() < BD.NZ_MINA and abs(vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
bInvertMach = true
|
|
-- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti
|
|
elseif not bDoubleSide and vtOrtho:getY() > GEO.EPS_SMALL and not ( -(vtOrtho:getZ()) < BD.NZ_MINA) then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
bInvertMach = true
|
|
end
|
|
end
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if AreSameOrOppositeVectorApprox( vtOrtho, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtOrtho:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtOrtho:getY() < GEO.EPS_SMALL then
|
|
nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
else
|
|
nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- se tasca aperta, imposto opportuno attacco
|
|
if sMchFind == 'OpenPocket' or sMchFind == 'OpenPocket_H2' then
|
|
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
|
|
end
|
|
-- inverto il percorso di lavorazione per lavorare sinistro
|
|
if not bMakeContour then
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
end
|
|
-- imposto affondamento
|
|
if not bMakeContour then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth)
|
|
end
|
|
-- se contornatura doppia anticipo la fine della lavorazione a metà trave
|
|
if bMakeContour and bDoubleSide then
|
|
EgtSetMachiningParam( MCH_MP.OFFSL, dDepth / 2)
|
|
end
|
|
-- se contornatura cerco la direzione di lavoro migliore e setto attacco e allungamenti
|
|
if bMakeContour then
|
|
local nFaceUse = BL.GetNearestParalOpposite( vtOrtho)
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- quantità di cui allargare la contornatura per andare in tangenza con lo spigolo, nel caso di altezza tasca minore di D/2 fresa
|
|
local dAddWorkWidth = EgtIf( dFacElev < dDiamTool / 2, -sqrt( dFacElev * dDiamTool - dFacElev * dFacElev), -dDiamTool / 2)
|
|
EgtSetMachiningParam( MCH_MP.LIELEV, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOELEV, 0)
|
|
if bIsU then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAddWorkWidth)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAddWorkWidth)
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LI.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 30)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, 30)
|
|
elseif bIsL then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 30)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAddWorkWidth)
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.TANGENT)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LI.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 30)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, 30)
|
|
end
|
|
end
|
|
-- imposto elevazione e dichiaro non si generano sfridi per VMill
|
|
local sNotes = ''
|
|
if not bMakeContour then
|
|
sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';'
|
|
end
|
|
sNotes = sNotes .. 'VMRS=0;'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) or EgtIsMachiningEmpty() then
|
|
-- provo ad allargare leggermente la tasca
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, -0.1)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return -1, sErr
|
|
elseif EgtIsMachiningEmpty() then
|
|
EgtRemoveOperation( nMchFId)
|
|
local sErr = 'Impossible to machine (empty toolpath)'
|
|
return -3, sErr
|
|
end
|
|
end
|
|
-- se posso applicare la svuotatura sul lato opposto
|
|
if bDoubleSide then
|
|
-- se ho la lavorazione da sotto ricalcolo in base a questa lavorazione
|
|
if bMakePocketDn then
|
|
-- sPocketing = sPocketingDn
|
|
-- dMaxDepth = dMaxDepthDn
|
|
-- dDiamTool = dDiamToolDn
|
|
-- se l'altezza utensile riesce a lavorare completamente da due parti
|
|
if dMaxDepthDn > ( dDepth / 2) + dCollSic + BD.CUT_EXTRA_MIN then
|
|
dMachDepth = BD.CUT_EXTRA_MIN
|
|
dElev = ( dDepth / 2) + BD.CUT_EXTRA_MIN
|
|
-- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione
|
|
else
|
|
dMachDepth = dMaxDepthDn - ( dDepth / 2) - dCollSic
|
|
dElev = dMaxDepthDn
|
|
bComplete = false
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
else
|
|
-- se anche lavorando dal lato opposto non riesco a svuotare completamente la fessura
|
|
-- setto i parametri affondamento ed emetto warning
|
|
if dMaxDepth < ( dDepth / 2) + BD.CUT_EXTRA + dCollSic then
|
|
dMachDepth = dMaxDepth - (dDepth / 2) - dCollSic
|
|
dElev = dMaxDepth
|
|
bComplete = false
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
end
|
|
if bMakeContour then
|
|
-- inserisco la lavorazione di contornatura
|
|
sName = 'ProfOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
else
|
|
-- inserisco la lavorazione di svuotatura
|
|
sName = 'PockOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
nMchFId = EgtAddMachining( sName, EgtIf( bMakePocketDn, sPocketingDn, sPocketing))
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. EgtIf( bMakePocketDn, sPocketingDn, sPocketing)
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
end
|
|
-- prendo l'id della prima lavorazione inserita
|
|
if not nFirstMachId then
|
|
nFirstMachId = nMchFId
|
|
end
|
|
if bMakeContour then
|
|
-- aggiungo geometria per contornatura
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
|
|
else
|
|
-- altrimenti aggiungo geometria per svuotatura
|
|
EgtSetMachiningGeometry( {{ nPathInt, -1}})
|
|
end
|
|
-- imposto direzione utensile opposta
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if AreSameVectorApprox( vtOrtho, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtOrtho:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtOrtho:getY() < GEO.EPS_SMALL then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
else
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- se tasca aperta, imposto opportuno attacco
|
|
if sMchFind == 'OpenPocket' or sMchFind == 'OpenPocket_H2' then
|
|
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
|
|
end
|
|
-- inverto il percorso di lavorazione per lavorare sinistro
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
-- imposto affondamento
|
|
if not bMakeContour then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth)
|
|
end
|
|
-- se contornatura doppia anticipo la fine della lavorazione a metà trave
|
|
if bMakeContour and bDoubleSide then
|
|
EgtSetMachiningParam( MCH_MP.OFFSL, dDepth / 2)
|
|
end
|
|
-- se contornatura cerco la direzione di lavoro migliore
|
|
if bMakeContour then
|
|
local nFaceUse = BL.GetNearestParalOpposite( vtOrtho)
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- quantità di cui allargare la contornatura per andare in tangenza con lo spigolo, nel caso di altezza tasca minore di D/2 fresa
|
|
local dAddWorkWidth = EgtIf( dFacElev < dDiamTool / 2, -sqrt( dFacElev * dDiamTool - dFacElev * dFacElev), -dDiamTool / 2)
|
|
EgtSetMachiningParam( MCH_MP.LIELEV, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOELEV, 0)
|
|
if bIsU then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAddWorkWidth)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAddWorkWidth)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAddWorkWidth)
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LI.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 30)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, 30)
|
|
elseif bIsL then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAddWorkWidth)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 30)
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LI.TANGENT)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, 30)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 30)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, 0)
|
|
end
|
|
end
|
|
-- imposto elevazione e dichiaro non si generano sfridi per VMill
|
|
sNotes = ''
|
|
if not bMakeContour then
|
|
sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';'
|
|
end
|
|
sNotes = sNotes .. 'VMRS=0;'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
-- provo ad allargare leggermente la tasca
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, -0.1)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return -1, sErr
|
|
end
|
|
end
|
|
end
|
|
-- se non completo e U, cerco di lavorare anche la faccia di fondo (con il massimo affondamento possibile)
|
|
if not bComplete and bIs3Faces then
|
|
-- recupero la faccia da lavorare
|
|
local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
|
|
local vtN
|
|
local bPock3rd = false
|
|
if nFacInd then
|
|
vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
bPock3rd = ( vtN and ( vtN:getZ() >= BD.NZ_MINA or bMakePocketDn))
|
|
end
|
|
if bPock3rd then
|
|
-- recupero la distanza di sicurezza aggiuntiva
|
|
local dFacCollSic = BL.CalcCollisionSafety( vtN)
|
|
-- scelgo se lavorare da sotto
|
|
local bFacPocketDn = ( bMakePocketDn and vtN:getZ() < -0.174)
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = EgtIf( bDoubleSide, 'Pock3rd_', 'Pock2nd_') .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, EgtIf( bFacPocketDn, sPocketingDn, sPocketing))
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
-- prendo l'id della prima lavorazione inserita
|
|
if not nFirstMachId then
|
|
nFirstMachId = nMchFId
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if AreSameOrOppositeVectorApprox( vtN, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtN:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtN:getY() < GEO.EPS_SMALL then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
else
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- se tasca aperta, imposto opportuno attacco
|
|
if sMchFind == 'OpenPocket' or sMchFind == 'OpenPocket_H2' then
|
|
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
|
|
end
|
|
-- inverto il percorso di lavorazione per lavorare sinistro
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
-- imposto affondamento
|
|
local dDepth = 0
|
|
local dActMaxDepth = EgtIf( bFacPocketDn, dMaxDepthDn, dMaxDepth)
|
|
if dActMaxDepth < dFacElev + dFacCollSic then
|
|
dDepth = dActMaxDepth - ( dFacElev + dFacCollSic)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- dichiaro non si generano sfridi per VMill
|
|
local sNotes = 'VMRS=0;'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
-- provo ad allargare leggermente la tasca
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, -0.1)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return -1, sErr
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return 1, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId
|
|
end
|
|
end
|
|
end
|
|
|
|
return 0, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId, bOrthoFaces
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ManageAntiSplintBySaw( Proc, b3Raw, bIsU, vtN, nFacInd, sWarn, bMillDown, bReduceDepth)
|
|
|
|
local bMadeASbyBld = false
|
|
local nNumFac = EgtIf( bIsU, 2, 1)
|
|
local nPrefSide = 1 -- di preferenza il motore è meglio tenerlo sinistra
|
|
-- se a U cerco di ottimizzare il lato di lavoro della lama
|
|
if bIsU then
|
|
if abs( vtN:getY()) > 0.996 then
|
|
nPrefSide = 0
|
|
elseif abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then
|
|
-- se X è negativa allora devo tenere il motore a destra
|
|
if vtN:getX() < 0.087 then
|
|
nPrefSide = 2
|
|
end
|
|
end
|
|
end
|
|
-- va eseguito sulle facce diverse dalla principale
|
|
local nPrevSCC = nil
|
|
for nFacet = 0, nNumFac do
|
|
if nFacet ~= nFacInd then
|
|
-- lavoro
|
|
local dSawThick = 0
|
|
local dMaxDepth = 200
|
|
local bAdj, dAng, dExtraOffs, sWarn2, nIdMach
|
|
bMadeASbyBld, sWarn2, nIdMach, dSawThick, dMaxDepth, bAdj, dAng, dExtraOffs = MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw, nFacInd, bReduceDepth, bMillDown)
|
|
if not bMadeASbyBld then return bMadeASbyBld, false, sWarn2 end
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
-- se antischeggia veramente inserito perchè necessario
|
|
if nIdMach then
|
|
-- verifico se da invertire
|
|
local bInvertMach = false
|
|
local dDepth = 0
|
|
if bIsU then
|
|
-- prendo il vettore normale alla faccia
|
|
local vtNFc = EgtSurfTmFacetNormVersor( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
if abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then
|
|
-- se superficie principale parallela al piano XZ
|
|
if nPrefSide == 0 then
|
|
-- se facce praticamente verticali || mandrino a destra
|
|
if abs( vtNFc:getZ()) < 0.1 then
|
|
nPrefSide = 2
|
|
-- se facce inclinate \\ allora mandrino a destra (per essere verso l'alto)
|
|
elseif vtNFc:getX() * vtNFc:getZ() > 0 then
|
|
nPrefSide = 2
|
|
-- altrimenti facce inclinate // quindi mandrino a sinistra (per essere ancora verso l'alto)
|
|
else
|
|
nPrefSide = 1
|
|
end
|
|
end
|
|
-- se faccia verso X+ e mandrino verso sinistra
|
|
if vtNFc:getX() > 0 and nPrefSide == 1 then
|
|
-- se angolo interno e circa -90
|
|
if abs( dAng + 90) < 5 then
|
|
bInvertMach = true
|
|
end
|
|
-- se faccia verso X- e mandrino verso destra
|
|
elseif vtNFc:getX() < 0 and nPrefSide == 2 then
|
|
-- se angolo interno e circa -90
|
|
if abs( dAng + 90) < 5 then
|
|
bInvertMach = true
|
|
end
|
|
end
|
|
end
|
|
-- eseguo inversione
|
|
if bInvertMach then
|
|
local bToolInvert = EgtGetMachiningParam( MCH_MP.TOOLINVERT)
|
|
local nWS = EgtGetMachiningParam( MCH_MP.WORKSIDE)
|
|
local nInvWS = EgtIf( nWS == MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)
|
|
local nFaceUse = EgtGetMachiningParam( MCH_MP.FACEUSE)
|
|
local bOrtUp = ( nFaceUse >= MCH_MILL_FU.ORTUP_DOWN and nFaceUse <= MCH_MILL_FU.ORTUP_RIGHT)
|
|
if not bOrtUp then
|
|
-- assegno i parametri invertiti
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, nInvWS)
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, not bToolInvert)
|
|
-- setto l'offset pari allo spessore lama
|
|
EgtSetMachiningParam( MCH_MP.OFFSL, -dSawThick)
|
|
end
|
|
end
|
|
-- per diminuire scheggiature su facce davanti
|
|
if nPrefSide == 2 then
|
|
local dSpeed = EgtGetMachiningParam( MCH_MP.SPEED)
|
|
if dSpeed < 0 and vtN:getY() < -0.996 then
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, vtNFc:getX() > 0)
|
|
elseif dSpeed > 0 and vtN:getY() > 0.996 then
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, vtNFc:getX() < 0)
|
|
elseif dSpeed < 0 and vtN:getZ() > 0.996 then
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, vtNFc:getX() > 0)
|
|
elseif dSpeed > 0 and vtN:getZ() > 0.996 then
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, vtNFc:getX() < 0)
|
|
end
|
|
end
|
|
end
|
|
-- posizione del braccio : se primo taglio la recupero, altrimenti la imposto
|
|
if not nPrevSCC then
|
|
nPrevSCC = EgtGetMachiningParam( MCH_MP.SCC)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, nPrevSCC)
|
|
end
|
|
-- rieseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nIdMach, false)
|
|
return false, false, sErr
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return bMadeASbyBld, true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakePathsOnExtremPoints( nAddGrpId, nIdPath, pPaths, dTDiam)
|
|
|
|
local dLength = 2
|
|
if not nIdPath then return pPaths end
|
|
|
|
-- prendo i punti iniziali e finali del percorso e i versori direzione
|
|
local ptIni = EgtSP( nIdPath, GDB_RT.GLOB)
|
|
local ptEnd = EgtEP( nIdPath, GDB_RT.GLOB)
|
|
|
|
-- se distanza tra i punti è <= del diametro utensile esco
|
|
if dist( ptIni, ptEnd) <= dTDiam then return pPaths end
|
|
|
|
-- prendo i versori iniziali e finali
|
|
local vtIni = EgtSV( nIdPath, GDB_RT.GLOB)
|
|
local vtEnd = EgtEV( nIdPath, GDB_RT.GLOB)
|
|
|
|
local ptIniP = ptIni
|
|
local ptEndP = ptIniP + (vtIni * dLength)
|
|
local nAuxId = EgtLine( nAddGrpId, ptIniP, ptEndP, GDB_RT.GLOB)
|
|
table.insert( pPaths, { nAuxId, 1, ptIniP})
|
|
|
|
ptIniP = ptEnd
|
|
ptEndP = ptEnd - ( vtEnd * dLength)
|
|
nAuxId = EgtLine( nAddGrpId, ptIniP, ptEndP, GDB_RT.GLOB)
|
|
table.insert( pPaths, { nAuxId, 2, ptIniP})
|
|
|
|
return pPaths
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeAntiSplintByMill( Proc, nPartId, pPaths, nPathInt, vtN1,
|
|
bDoubleSide, bOppoSide, sMilling, nPhase, sMyWarn,
|
|
dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId)
|
|
|
|
local sMyWarn2
|
|
|
|
-- assegno lavorazioni ad ogni percorso
|
|
for i = 1, #pPaths do
|
|
|
|
local nIdPath = pPaths[i][1]
|
|
local nSide = pPaths[i][2]
|
|
-- modifico versore direzione
|
|
EgtModifyCurveExtrusion( nIdPath, vtN1, GDB_RT.GLOB)
|
|
local sName
|
|
if bOppoSide then
|
|
sName = 'AntiSplintOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
else
|
|
sName = 'AntiSplint_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
end
|
|
local nMchId = EgtAddMachining( sName, sMilling)
|
|
if nMchId then
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ nIdPath, -1}})
|
|
if ( bOppoSide and nSide == 1) or ( not bOppoSide and nSide == 2) then
|
|
-- imposto lato di lavoro destro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
else
|
|
-- imposto lato di lavoro sinistro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
end
|
|
local nSCC
|
|
if bOppoSide then
|
|
-- imposto direzione utensile opposta
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
-- imposto posizione braccio porta testa
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
if not BD.C_SIMM then
|
|
if AreSameVectorApprox( vtN1, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtN1:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtN1:getY() < GEO.EPS_SMALL then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
else
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
end
|
|
end
|
|
else
|
|
local bInvertMach = false
|
|
if not nPathInt then
|
|
-- imposto posizione braccio porta testa
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
if vtN1:getY() > 100 * GEO.EPS_ZERO then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
end
|
|
else
|
|
-- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale)
|
|
if vtN1:getZ() < BD.NZ_MINA and abs(vtN1:getZ()) >= 0.707 then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
bInvertMach = true
|
|
-- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti
|
|
elseif not bDoubleSide and vtN1:getY() > GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
bInvertMach = true
|
|
end
|
|
-- imposto posizione braccio porta testa
|
|
nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if AreSameOrOppositeVectorApprox( vtN1, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtN1:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtN1:getY() < GEO.EPS_SMALL then
|
|
nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
else
|
|
nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- parametri attacco
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, 1)
|
|
-- allungo inizio
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 2)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 10)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, -5)
|
|
-- parametri uscita
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
|
|
local dMachDepth = 0
|
|
local dExtraElev = 0
|
|
if bDoubleSide then
|
|
dExtraElev = BL.GetFaceElevationFromPointDir( Proc.Id, nPartId, pPaths[i][3], EgtIf( bOppoSide, -vtN1, vtN1)) - dMaxElevMaster
|
|
end
|
|
local dMaxElev = dMaxElevMaster + dExtraElev
|
|
if ( dMaxElev + BD.CUT_EXTRA + dCollSic) > dMaxDepth then
|
|
dMachDepth = dMaxDepth - ( dMaxElev + dCollSic)
|
|
end
|
|
-- setto se devo invertire il percorso
|
|
local bInvert = CheckToInvert( nIdPath, true)
|
|
if bOppoSide then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, (dMachDepth+dExtraDepth))
|
|
EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bInvertMach, not bInvert, bInvert))
|
|
end
|
|
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill
|
|
local sUserNotes = 'VMRS=0;'
|
|
-- aggiungo alle note massima elevazione
|
|
sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( ( dMaxElev + dMachDepth), 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- eseguo
|
|
if ML.ApplyMachining( true, false) then
|
|
_, sMyWarn2 = EgtGetMachMgrWarning( 0)
|
|
if EgtIsMachiningEmpty() then
|
|
EgtSetOperationMode( nMchId, false)
|
|
else
|
|
-- se ho la lavorazione di svuotatura riloco la lavorazione antischeggia prima di questa
|
|
if nFirstMachId then
|
|
EgtRelocateGlob( nMchId, nFirstMachId, GDB_IN.BEFORE)
|
|
end
|
|
end
|
|
-- altrimenti lavorazione non applicata
|
|
else
|
|
_, sMyWarn2 = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
end
|
|
-- altrimenti non è stata inserita lavorazione
|
|
else
|
|
sMyWarn2 = 'warning adding machining ' .. sName .. '-' .. sMilling
|
|
end
|
|
end
|
|
|
|
if sMyWarn2 and #sMyWarn2 > 0 then
|
|
sMyWarn = sMyWarn .. '\n' .. sMyWarn2
|
|
end
|
|
return sMyWarn
|
|
end
|
|
|
|
|
|
---------------------------------------------------------------------
|
|
local function ManageAntiSplintByMill( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacInd, nAddGrpId, bMillDown, dDiam, bDoubleSide,
|
|
vtOrtho, nPathInt, nSurfInt, b3Solid, dDepth,
|
|
bOneShot, nFirstMachId)
|
|
|
|
local sMyWarn = ''
|
|
local pPaths = {}
|
|
local nAuxId
|
|
local sMilling
|
|
|
|
-- recupero la lavorazione tenendo conto dell'elevazione
|
|
local dCheckDepth
|
|
if bDoubleSide then
|
|
dCheckDepth = 0.5 * dDepth
|
|
else
|
|
if not nPathInt then
|
|
dCheckDepth = BL.GetFaceElevation( Proc.Id, nFacInd)
|
|
else
|
|
dCheckDepth = dDepth
|
|
end
|
|
end
|
|
sMilling = ML.FindMilling( 'AntiSplintMillCut', dCheckDepth, nil, nil, nil, not( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide) or
|
|
ML.FindMilling( 'AntiSplintMillCut', 2/3 * dCheckDepth, nil, nil, nil, not( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide) or
|
|
ML.FindMilling( 'AntiSplintMillCut', nil, nil, nil, nil, not( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide)
|
|
|
|
if sMilling then
|
|
|
|
local vtN1
|
|
local nFirstId, nNumId
|
|
local dMaxElevMaster
|
|
local dExtraDepth = 0
|
|
local dCollSic
|
|
local ptMidDist
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 50
|
|
local dMaxDepth = 0
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
|
|
-- se non ho la faccia aggiunta
|
|
if not nPathInt then
|
|
-- ottengo i percorsi da cui estrapolare il percorso di antischeggia
|
|
local tFacAdjMain = ChooseContour( Proc, nFacInd, false)
|
|
local tPaths = {}
|
|
-- se non trovato nessun angolo interno valido esco
|
|
if #tFacAdjMain == 0 then
|
|
return true, sMyWarn
|
|
end
|
|
-- prendo il primo versore
|
|
_, vtN1 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
dCollSic = BL.CalcCollisionSafety( vtN1) or 0
|
|
-- se direzione tende verso una delle alle 3 direzioni azzero l'altezza extra
|
|
if abs( vtN1:getX()) > 0.7 or abs( vtN1:getY()) > 0.7 or abs( vtN1:getZ()) > 0.7 then dCollSic = 0 end
|
|
|
|
-- se fresatura da sotto salto la lavorazione
|
|
if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then
|
|
local sErr = 'Error : milling from bottom '
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local ptIniPath
|
|
local nMaxLen = 0
|
|
dMaxElevMaster = BL.GetFaceElevation( Proc.Id, nFacInd)
|
|
-- ciclo tutta la tabella
|
|
for i = 1, #tFacAdjMain do
|
|
-- le 2 facce di contatto devono essere perpendicolari o non sottosquadra rispetto alla faccia di fondo
|
|
local ptP1, ptP2, dAng
|
|
ptP1 = tFacAdjMain[i][3]
|
|
ptP2 = tFacAdjMain[i][4]
|
|
dAng = tFacAdjMain[i][5]
|
|
if ( dAng < 0 and 180 + dAng >= 90 - 10 * GEO.EPS_SMALL) then
|
|
-- creo la linea da P1 a P2
|
|
nAuxId = EgtLine( nAddGrpId, ptP1, ptP2, GDB_RT.GLOB)
|
|
table.insert( tPaths, nAuxId)
|
|
-- prendo la lunghezza massima e il puto medio
|
|
if tFacAdjMain[i][2] > nMaxLen then
|
|
ptIniPath = ptP1
|
|
nMaxLen = tFacAdjMain[i][2]
|
|
ptMidDist = ( ptP1 + ptP2) / 2
|
|
end
|
|
end
|
|
end
|
|
-- cotruisco il/i percorso/i
|
|
nFirstId, nNumId = EgtCurveCompoByReorder( nAddGrpId, tPaths, ptIniPath, true, GDB_RT.GLOB)
|
|
local bOkPath = true
|
|
for i = 1, nNumId do
|
|
local nIdPath = nFirstId + i - 1
|
|
if EgtCurveIsClosed( nIdPath) then
|
|
bOkPath = false
|
|
end
|
|
end
|
|
-- se ho un percorso chiuso cancello tutto
|
|
if not bOkPath then
|
|
for i = 1, nNumId do
|
|
local nIdPath = nFirstId + i - 1
|
|
EgtErase(nIdPath)
|
|
end
|
|
else
|
|
-- creo percorsi antisplint dagli estremi dei percorsi di contorno trovati
|
|
for i = 1, nNumId do
|
|
local nIdPath = nFirstId + i - 1
|
|
pPaths = MakePathsOnExtremPoints( nAddGrpId, nIdPath, pPaths, dTDiam)
|
|
end
|
|
end
|
|
-- alrimenti ho la faccia aggiunta
|
|
else
|
|
|
|
dCollSic = BL.CalcCollisionSafety( vtOrtho)
|
|
nFirstId = EgtCopyGlob( nPathInt, nAddGrpId)
|
|
nNumId = 1
|
|
-- calcolo elevazione dalla faccia trasversale aggiunta
|
|
if bDoubleSide then
|
|
dMaxElevMaster = 0.5 * dDepth
|
|
else
|
|
dMaxElevMaster = dDepth
|
|
-- se la precedente svuotatura è stata fatta completamente in una sola volta
|
|
-- valuto di nuovo se devo fare due passate o una sola
|
|
if bOneShot then
|
|
-- se non è possibile svuotare completamente da una sola parte
|
|
if dMaxDepth <= ( dMaxElevMaster + BD.CUT_EXTRA + dCollSic) then
|
|
bDoubleSide = true
|
|
dMaxElevMaster = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
else
|
|
dExtraDepth = dMaxElevMaster - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
end
|
|
-- altrimenti non è stata fatta completamente calcolo la distanza tra faccia aggiunta e profondità superficie
|
|
else
|
|
dExtraDepth = dMaxElevMaster - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
end
|
|
end
|
|
vtN1 = Vector3d(vtOrtho)
|
|
local bOkPath = BL.SetOpenSide( nFirstId, vtOrtho, b3Solid, nAddGrpId, 2)
|
|
-- se non ho un percorso chiuso estraggo i percorsi
|
|
if bOkPath then
|
|
-- creo percorsi antisplint dagli estremi dei percorsi di contorno trovati
|
|
pPaths = MakePathsOnExtremPoints( nAddGrpId, nFirstId, pPaths, dTDiam)
|
|
end
|
|
EgtErase(nFirstId)
|
|
end
|
|
|
|
if #pPaths > 0 then
|
|
|
|
sMyWarn = MakeAntiSplintByMill( Proc, nPartId, pPaths, nPathInt, vtN1,
|
|
bDoubleSide, false, sMilling, nPhase, sMyWarn,
|
|
dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId)
|
|
if bDoubleSide then
|
|
if bMillDown then
|
|
local sMillingDn = ML.FindMilling( 'AntiSplintMillCut_H2', dCheckDepth) or
|
|
ML.FindMilling( 'AntiSplintMillCut_H2', 2/3 * dCheckDepth) or
|
|
ML.FindMilling( 'AntiSplintMillCut_H2')
|
|
sMilling = sMillingDn
|
|
-- controllo dati lavorazione
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
end
|
|
-- se lavorazione valida
|
|
if sMilling then
|
|
sMyWarn = MakeAntiSplintByMill( Proc, nPartId, pPaths, nPathInt, vtN1,
|
|
bDoubleSide, true, sMilling, nPhase, sMyWarn,
|
|
dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId)
|
|
else
|
|
sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library'
|
|
end
|
|
end
|
|
-- altrimenti non c'è il percorso
|
|
else
|
|
sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path'
|
|
end
|
|
-- altrimenti non è stata trovata lavorazione
|
|
else
|
|
sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library'
|
|
end
|
|
if #sMyWarn > 0 then
|
|
EgtOutLog( sMyWarn)
|
|
end
|
|
|
|
return true, sMyWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeTunnelByChainSaw( Proc, sSawing, nLundIdFace, vtOrtho, dWorkDepth, dMaxMat, nStep, dStep, sFaceUse, bOpposite)
|
|
for i = 1, nStep do
|
|
-- inserisco la lavorazione di sawing
|
|
local sName = ''
|
|
if bOpposite then
|
|
sName = 'Csaw_Opp_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i)
|
|
else
|
|
sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i)
|
|
end
|
|
local nMchFId = EgtAddMachining( sName, sSawing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nLundIdFace}})
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nLundIdFace, GDB_ID.ROOT)
|
|
-- imposto angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, BL.GetChainSawBlockedAxis( 1))
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, BL.GetChainSawInitAngs( vtN, vtOrtho, 1))
|
|
-- imposto offset radiale
|
|
local dOffs = ( i - 1) * dStep
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dOffs)
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, sFaceUse)
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dWorkDepth)
|
|
-- modifico la distanza di attacco per considerare anche tunnel inclinati
|
|
EgtSetMachiningParam( MCH_MP.STARTPOS, 50)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
if EgtGetOutstrokeInfo() then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, BL.GetChainSawBlockedAxis( 2))
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, BL.GetChainSawInitAngs( vtN, vtOrtho, 2))
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
if EgtIsMachiningEmpty() then
|
|
_, sWarn = EgtGetMachMgrWarning( 0)
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sWarn
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, bSinglePart, bPrevBhSideMill, bAllWithEndCap)
|
|
if not BD.MAXDIAM_POCK_CORNER then
|
|
BD.MAXDIAM_POCK_CORNER = 30
|
|
end
|
|
local sWarn
|
|
-- recupero l'ingombro del grezzo di appartenenza
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
-- recupero l'ingombro della trave
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
if not b3Solid then
|
|
local sErr = 'Error : part box not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero gruppo per geometria addizionale
|
|
local nAddGrpId = BL.GetAddGroup( nPartId)
|
|
if not nAddGrpId then
|
|
local sErr = 'Error : missing AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local bClosedOrthoFaces
|
|
local nFacInd, dFacElev, nFacInd2, dFacElev2
|
|
local nBottomFace
|
|
local sMchFindBackUp
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
|
|
if not nFacInd or nFacInd < 0 then
|
|
if nFacInd == -1 then
|
|
bClosedOrthoFaces = nFacInd2
|
|
else
|
|
local sErr = 'Error : MakeMoreFaces could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche
|
|
if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then
|
|
-- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura
|
|
for i = 1, Proc.Fct do
|
|
local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
|
|
-- elimino una faccia
|
|
nBottomFace = i - 1
|
|
if EgtSurfTmRemoveFacet( nNewProc, nBottomFace) then
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( nNewProc, nPartId)
|
|
if not nFacInd or nFacInd < 0 then
|
|
if nFacInd == -1 then
|
|
bClosedOrthoFaces = nFacInd2
|
|
EgtErase( nNewProc)
|
|
break
|
|
else
|
|
EgtErase( nNewProc)
|
|
local sErr = 'Error : MakeMoreFaces could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- altrimenti esco
|
|
else
|
|
EgtErase( nNewProc)
|
|
break
|
|
end
|
|
end
|
|
-- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo
|
|
if bClosedOrthoFaces then
|
|
nFacInd = nBottomFace
|
|
-- rendo nulla la faccia opzionale perchè si tratta di una fessura
|
|
nFacInd2 = nil
|
|
dFacElev = BL.GetFaceElevation( Proc.Id, nFacInd)
|
|
bClosedOrthoFaces = false -- non setto come tunnel
|
|
end
|
|
end
|
|
-- se proviene da divisione in parti lungo X ed è un tunnel non è fattibile
|
|
if not bSinglePart and bClosedOrthoFaces then
|
|
local sErr = 'Error : long splitted tunnel not feasible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- verifico se sono presenti i parametri Q per la profondità smusso e
|
|
-- per eseguire in esclusiva solo lo smusso
|
|
local nChamfer, dDepthCham, sErrCham, bForceUseBlade = EvaluateQParam( Proc)
|
|
-- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer
|
|
-- genero errore e non faccio nulla
|
|
if nChamfer < 0 then
|
|
return false, sErrCham
|
|
end
|
|
-- se è un tunnel provo a vedere se è possibile lavorarlo con la svuotatura o con la sega catena
|
|
if bClosedOrthoFaces then
|
|
local bTryWithBlades = true
|
|
-- lavoro fessura con svuotature (singola o doppia contrapposta)
|
|
local sMyMchFind = 'Pocket'
|
|
local nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho,
|
|
nLundIdFace = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMyMchFind, false, b3Solid, bClosedOrthoFaces)
|
|
if nOk < 0 then
|
|
return false, sErr
|
|
elseif nOk > 0 then
|
|
bTryWithBlades = false
|
|
end
|
|
-- Se la svuotatura precedente non è stata fatta e chamfer non è mutuamente esclusivo provo con la sega-catena
|
|
if bTryWithBlades and nChamfer < 2 then
|
|
-- verifico se posso farlo con la sega-catena
|
|
local bMakeChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick = VerifyChainSaw( Proc, dDimMin, dDimMax)
|
|
if bMakeChainSaw then
|
|
-- Ricalcolo l'affondamento tenendo conto di eventuale inclinazione
|
|
local dSlDepth
|
|
local frSlDh = Frame3d( Proc.Box:getCenter(), vtOrtho)
|
|
for i = 1, Proc.Fct do
|
|
local b3Fac = EgtSurfTmGetFacetBBoxRef( Proc.Id, i - 1, GDB_BB.STANDARD, frSlDh)
|
|
if b3Fac and ( not dSlDepth or b3Fac:getDimZ() < dSlDepth) then
|
|
dSlDepth = b3Fac:getDimZ()
|
|
end
|
|
end
|
|
if dSlDepth then dDepth = dSlDepth end
|
|
-- Verifico se necessarie più passate
|
|
local nStep = ceil( ( dDimMin - 100 * GEO.EPS_SMALL) / dSawThick)
|
|
local dStep = 0
|
|
if nStep > 1 then
|
|
dStep = ( dDimMin - dSawThick) / ( nStep - 1)
|
|
end
|
|
local bSplit = false
|
|
local sFaceUse, sFaceUseOtherSide
|
|
-- imposto il lato di lavorazione, da sopra oppure di fronte
|
|
-- se è di fronte, non è una Fast e il tagliente non arriva splitto la lavorazione
|
|
-- Questa feature non è applicata su facce di testa e quindi non controllo l'entrata in X
|
|
if abs(vtOrtho:getZ()) >= 0.707 then
|
|
sFaceUse = MCH_MILL_FU.PARAL_DOWN
|
|
else
|
|
sFaceUse = MCH_MILL_FU.PARAL_BACK
|
|
-- per escludere la Fast controllo C_SIMM
|
|
if BD.C_SIMM and dMaxMat < dDepth then
|
|
bSplit = true
|
|
sFaceUseOtherSide = MCH_MILL_FU.PARAL_FRONT
|
|
dDepth = dDepth / 2 + BD.CUT_EXTRA
|
|
end
|
|
end
|
|
local dWorkDepth = dDepth
|
|
-- cerco di estendere il taglio considerando la parte arrotondata della lama + 1
|
|
if dMaxMat > dDepth + dSawCornerRad + 1 then
|
|
dWorkDepth = dDepth + dSawCornerRad + 1
|
|
-- se massimo affondamento utensile inferiore alla profondità da lavorare, setto la profondità di lavoro e emetto warning
|
|
elseif dMaxMat < dDepth then
|
|
dWorkDepth = dMaxMat
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
-- lavoro da un lato
|
|
local bOk, sErr = MakeTunnelByChainSaw( Proc, sSawing, nLundIdFace, vtOrtho, dWorkDepth, dMaxMat, nStep, dStep, sFaceUse, false)
|
|
if not bOk then return false, sErr end
|
|
-- se è da lavorare anche dall'altro lato
|
|
if bSplit then
|
|
bOk, sErr = MakeTunnelByChainSaw( Proc, sSawing, nLundIdFace, vtOrtho, dWorkDepth, dMaxMat, nStep, dStep, sFaceUseOtherSide, true)
|
|
if not bOk then return false, sErr end
|
|
end
|
|
end
|
|
end
|
|
-- altrimenti non è una fessura
|
|
else
|
|
-- dati della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- larghezza della faccia
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
if Proc.Box:getDimX() > Proc.Box:getDimY() then
|
|
if dH > dV then dH, dV = dV, dH end
|
|
else
|
|
if dH < dV then dH, dV = dV, dH end
|
|
end
|
|
-- se due o più facce (recupero la larghezza della faccia perpendicolarmente alle altre)
|
|
if Proc.Fct >= 2 then
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, EgtIf( nFacInd == 0, 1, 0), GDB_ID.ROOT)
|
|
local vtX = vtN2 ^ vtN
|
|
if not vtX:isSmall() then
|
|
local frRef = Frame3d( ptC, ptC + 100 * vtX, ptC + 100 * vtN2)
|
|
local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, nFacInd, GDB_BB.STANDARD, frRef)
|
|
if b3Ref then
|
|
dH = b3Ref:getDimX()
|
|
dV = b3Ref:getDimY()
|
|
end
|
|
end
|
|
end
|
|
-- verifico se U
|
|
local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc))
|
|
-- verifico se due facce o L con una o due facce di terminazione
|
|
local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2)
|
|
-- se parametro Q03=2 forzo la fresatura di lato; con Q03=3 forzo solo se la faccia di lavoro non è rivolta verso l'alto +/-10°
|
|
local bForceSideMill = ( EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') == 2 or ( EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') == 3 and vtN:getZ() < 0.985)) and ( Proc.Fct == 4 or Proc.Fct == 3 or Proc.Fct == 2)
|
|
-- se fattibile con fresa BH di fianco e spessore utensile inferiore alla larghezza faccia
|
|
local bMakeBySideMill, bHead, bHeadDir, sMilling, dMaxMat, dToolDiam = VerifyBHSideMill( Proc, bIsU, bIsL, bSinglePart, bPrevBhSideMill)
|
|
if bPrevBhSideMill == nil then
|
|
bPrevBhSideMill = bMakeBySideMill
|
|
end
|
|
if bMakeBySideMill then
|
|
-- se smusso non è esclusivo
|
|
if nChamfer < 2 then
|
|
-- verifico che la faccia non sia diretta come X, altrimenti cerco di cambiarla
|
|
if abs( vtN:getX()) > 0.866 and nFacInd2 then
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
if vtN2 and abs( vtN2:getX()) < 0.866 then
|
|
nFacInd, nFacInd2 = nFacInd2, nFacInd
|
|
dFacElev, dFacElev2 = dFacElev2, dFacElev
|
|
vtN, vtN2 = vtN2, vtN
|
|
end
|
|
end
|
|
-- se lavorazione da sotto e lunga, va divisa in due metà
|
|
local bDouble = ( vtN:getZ() < -0.5 and dH > ( BD.MAX_LEN_BH_FROM_BOTTOM or 200) and not BD.TURN)
|
|
-- inserisco la lavorazione di fresatura
|
|
local sName = 'BHMill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
sName = EgtGetName( nMchFId)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
|
|
-- imposto uso del lato faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHeadDir, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT))
|
|
-- calcolo step effettivo ed elevazione
|
|
local dVcalc = dV - dMaxMat
|
|
if abs( dVcalc) < 0.1 then dVcalc = 0 end
|
|
local dStep = min( EgtMdbGetCurrMachiningParam( MCH_MP.STEP), dMaxMat)
|
|
local nStep = ceil( dVcalc / dStep)
|
|
if nStep > 0 then
|
|
dStep = dVcalc / nStep + 0.1
|
|
else
|
|
dStep = 0
|
|
end
|
|
-- lo step finale non deve mai superare lo spessore utensile
|
|
dStep = min( dStep, dMaxMat)
|
|
EgtSetMachiningParam( MCH_MP.STEP, dStep)
|
|
-- imposto elevazione e dichiaro non si generano sfridi per VMill
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( dVcalc + dStep, 2) .. ';'
|
|
sNotes = sNotes .. 'VMRS=0;'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- attacchi e uscite
|
|
if vtN:getZ() > -0.5 or BD.TURN then
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dFacElev + BD.CUT_SIC)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + BD.CUT_SIC)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 0)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.PERP_TG)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, -( dToolDiam / 2 + b3Raw:getDimY() + BD.CUT_SIC))
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, EgtIf( vtN:getZ() > -0.5, dFacElev + BD.COLL_SIC, BD.COLL_SIC))
|
|
if bDouble then
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dH / 2)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, -( dToolDiam / 2 + dH / 2 + BD.CUT_SIC))
|
|
end
|
|
end
|
|
-- tipo passate multiple
|
|
local nStepType = MCH_MILL_ST.ONEWAY
|
|
EgtSetMachiningParam( MCH_MP.STEPTYPE, nStepType)
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.TURN then
|
|
nSCC = EgtIf( ( vtN:getY() > 0.5 or ( bHeadDir and vtN:getZ() > 0.5 ) or ( not bHeadDir and vtN:getZ() < -0.5)), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
else
|
|
if vtN:getY() > 0.707 then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
elseif vtN:getY() < -0.707 then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif vtN:getZ() > 0.707 then
|
|
nSCC = MCH_SCC.ADIR_ZP
|
|
elseif vtN:getZ() < -0.707 then
|
|
nSCC = MCH_SCC.ADIR_ZM
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
-- se divisa in due metà
|
|
if bDouble then
|
|
local nMchFNId = EgtCopyMachining( sName .. '_2', sName)
|
|
if not nMchFNId then
|
|
local sErr = 'Error copying machining ' .. sName
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- inverto direzione e lato di lavoro e direzione ausiliaria
|
|
local bInvert = EgtGetMachiningParam( MCH_MP.INVERT)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, not bInvert)
|
|
local nWorkSide = EgtGetMachiningParam( MCH_MP.WORKSIDE)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nWorkSide == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT))
|
|
EgtSetMachiningParam( MCH_MP.SCC, EgtIf( nSCC == MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP))
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFNId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
end
|
|
-- altrimenti lavoro con svuotatura
|
|
else
|
|
local bSpecial3faces = false
|
|
-- verifico se lavorando la faccia principale rimane esclusa molta sezione trasversale complessiva della feature (da box)
|
|
local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local bBoxF = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfFac)
|
|
if dH * dV < 0.9 * ( bBoxF:getDimX() * bBoxF:getDimY()) and nFacInd2 and dFacElev2 < 1.5 * dFacElev then
|
|
bSpecial3faces = true
|
|
end
|
|
-- se riconosciuta gestione 3 facce (limitatamente per ora alla feature 20)
|
|
if bSpecial3faces and Proc.Prc == 20 then
|
|
-- se smusso non è esclusivo
|
|
if nChamfer < 2 then
|
|
-- entrambe le facce non devono essere orientate verso il basso
|
|
local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
-- se orientata verso il basso, verifico l'alternativa
|
|
if vtN:getZ() < BD.NZ_MINA and vtN2:getZ() < BD.NZ_MINA then
|
|
local sErr = 'Error : special LapJoint from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
-- eventuali tagli preliminari
|
|
do
|
|
local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, nChamfer)
|
|
if not bOk then return false, sErr end
|
|
end
|
|
-- Recupero la lavorazione di fresa
|
|
local sMilling = ML.FindMilling( 'LongSmallCut')
|
|
if not sMilling then
|
|
local sErr = 'Error : LongSmallCut not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Recupero la lavorazione di svuotatura
|
|
local sMchFind = 'Pocket'
|
|
-- se forzato uso truciolatore
|
|
if EgtGetInfo( Proc.Id, Q_USE_ROUGH_TOOL, 'i') == 1 then
|
|
sMchFind = 'OpenPocket'
|
|
end
|
|
local dDiam = min( dH, dV)
|
|
local dDiam2 = min( dH2, dV2)
|
|
local dCollSic = 2 * BD.COLL_SIC
|
|
local dCollSic2 = 2 * BD.COLL_SIC
|
|
if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end
|
|
if abs( vtN2:getX()) > 0.7 or abs( vtN2:getY()) > 0.7 or abs( vtN2:getZ()) > 0.7 then dCollSic2 = 0 end
|
|
local sPocketing = ML.FindPocketing( sMchFind, dDiam2, dFacElev2 + dCollSic2)
|
|
-- se non trova una svuotatura adatta provo ad assegnarla all'altra faccia
|
|
if not sPocketing then
|
|
dDiam, dDiam2 = dDiam2, dDiam
|
|
dCollSic, dCollSic2 = dCollSic2, dCollSic
|
|
nFacInd, nFacInd2 = nFacInd2, nFacInd
|
|
dH, dH2 = dH2, dH
|
|
dV, dV2 = dV2, dV
|
|
dFacElev, dFacElev2 = dFacElev2, dFacElev
|
|
rfFac, rfFac2 = rfFac2, rfFac
|
|
vtN, vtN2 = vtN2, vtN
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam2, dFacElev2 + dCollSic2)
|
|
if not sPocketing then
|
|
local sErr = 'Error : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- provo con contornatura
|
|
local dDiamTool = 20
|
|
if bIsL then
|
|
local bOk, sErr
|
|
bOk, sWarn, dDiamTool = MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev, dCollSic, true, sMilling, nFacInd2, dFacElev2)
|
|
if not bOk then return bOk, sWarn end
|
|
else
|
|
local sErr = 'Error : Impossible mill special LapJoint'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sPocketing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd2}})
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT)
|
|
-- imposto posizione braccio porta testa
|
|
if vtN:getY() < GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
|
|
end
|
|
-- se tasca aperta, imposto opportuno attacco
|
|
if sMchFind == 'OpenPocket' then
|
|
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
|
|
end
|
|
-- imposto elevazione
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev2, 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
-- provo ad allargare leggermente la tasca
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, -0.1)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- se abilitato dal parametro Q inserisco foro sullo spigolo
|
|
if EgtGetInfo( Proc.Id, Q_BORE_ON_CORNER, 'i') == 1 then
|
|
local bOk
|
|
bOk, sWarn = MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, 0, nAddGrpId, dDiamTool, true)
|
|
if not bOk then return false, sWarn end
|
|
-- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura
|
|
elseif EgtGetInfo( Proc.Id, Q_BORE_ON_CORNER, 'i') == 2 then
|
|
local bOk
|
|
bOk, sWarn = MakeSharpCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, 0, nAddGrpId, dDiamTool)
|
|
if not bOk then return false, sWarn end
|
|
end
|
|
end
|
|
-- altrimenti lavorazione di svuotatura o contornatura
|
|
else
|
|
local bUseOtherFace
|
|
-- se orientata verso il basso e non c'è testa da sotto, verifico l'alternativa
|
|
if vtN:getZ() < BD.NZ_MINA and not BD.DOWN_HEAD and nFacInd2 then
|
|
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
nFacInd, nFacInd2 = nFacInd2, nFacInd
|
|
dFacElev, dFacElev2 = dFacElev2, dFacElev
|
|
bUseOtherFace = true
|
|
end
|
|
-- verifico non sia orientata verso il basso o ci sia una testa dal basso o la lavorazione sia dal lato.
|
|
local bFaceDown = ( vtN:getZ() < BD.NZ_MINA)
|
|
if bFaceDown and not BD.DOWN_HEAD and not BD.TURN and not bForceSideMill then
|
|
local sErr = 'Error : LapJoint from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- se forma a L e la componente in X è maggiore di 60° e non in testa allora verifico se posso utilizzare la faccia secondaria
|
|
if bIsL and abs( vtN:getX()) > 0.866 and
|
|
( Proc.Box:getMax():getX() < b3Solid:getMax():getX() - 10 or vtN:getX() < 0) and
|
|
( not Proc.Tail or vtN:getX() > 0) then
|
|
-- se non ho scambiato la faccia
|
|
if not bUseOtherFace then
|
|
if nFacInd2 then
|
|
nFacInd, nFacInd2 = nFacInd2, nFacInd
|
|
dFacElev, dFacElev2 = dFacElev2, dFacElev
|
|
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- altrimenti cerco la faccia secondaria per adiacenza alla principale
|
|
else
|
|
-- Cerco una faccia adiacente alla principale sul lato lungo
|
|
local nFacAdj, sErr = GetFaceAdj( Proc, nFacInd, dH, dV)
|
|
if nFacAdj < 0 then
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
nFacInd = nFacAdj
|
|
dFacElev = BL.GetFaceElevation( Proc.Id, nFacInd)
|
|
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
end
|
|
-- altrimenti se ho già cambiato faccia do errore per impossibilità di lavorazione
|
|
else
|
|
local sErr = 'Error : impossible to machine by side angle too big that cause collision'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- eventuali tagli preliminari
|
|
do
|
|
local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, nChamfer)
|
|
if not bOk then return false, sErr end
|
|
end
|
|
-- imposto altezza aggiuntiva di elevazione
|
|
local dCollSic = BL.CalcCollisionSafety( vtN)
|
|
-- abilitazione lavorazione da sotto
|
|
local bMillUp = ( BD.DOWN_HEAD and vtN:getZ() > -0.259)
|
|
local bMillDown = ( BD.DOWN_HEAD and vtN:getZ() < 0.342)
|
|
-- settaggio voluto da Alessandro/Fabio (per fare angoli con fresa piccola)
|
|
sMchFind = 'Pocket'
|
|
local dDiam = min( dH, dV)
|
|
local bTailOnSide = ( Proc.Box:getMin():getX() - b3Solid:getMin():getX() < 0.1 and not Proc.Tail and not bAllWithEndCap)
|
|
if ( Proc.Fct == 1) or (( Proc.Fct == 2 or Proc.Fct == 3) and bIsL) or ((( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 4 and not bTailOnSide)) and bSinglePart) then
|
|
sMchFind = 'OpenPocket'
|
|
if bIsU then
|
|
dDiam = GetUShapeWidth( Proc, nFacInd) or dDiam
|
|
elseif Proc.Fct == 4 then
|
|
-- se non angoli fittizi, per rifinire gli angoli premio utensile diam 25 o da BD
|
|
if not bAllWithEndCap then
|
|
dDiam = min( dDiam, BD.MAXDIAM_POCK_CORNER)
|
|
end
|
|
elseif Proc.Fct == 3 and bIsL then
|
|
-- per rifinire gli angoli premio utensile diam 25 o da BD
|
|
dDiam = min( ( 2 * dDiam) + 10 * GEO.EPS_SMALL, BD.MAXDIAM_POCK_CORNER)
|
|
else
|
|
dDiam = 2 * dDiam
|
|
end
|
|
end
|
|
sMchFindBackUp = sMchFind
|
|
local nUseRoughTool = EgtIf( bSinglePart, 0, 1)
|
|
local nUseRT
|
|
-- 04/08/2020 Se settato parametro uso truciolatore (parametro Q), non si devono prendere altre frese, si da errore (Fabio)
|
|
-- Questa opzione si scontra facilmente con altre interpretazioni dello stasso parametro Q (per tornare indietro bNewCheck = false)
|
|
local bNewCheck = true
|
|
-- se processo 20 e non sto usando il truciolatore
|
|
if bNewCheck and Proc.Prc == 20 and nUseRoughTool == 0 then
|
|
-- verifico se forzato uso truciolatore
|
|
nUseRT = EgtGetInfo( Proc.Id, Q_USE_ROUGH_TOOL, 'i')
|
|
if nUseRT and nUseRT ~= 0 then
|
|
sMchFind = 'OpenPocket'
|
|
nUseRoughTool = 1
|
|
end
|
|
end
|
|
-- 03/12/2020 aggiunto controllo su feature 30 senza uso truciolatore
|
|
if bNewCheck and Proc.Prc == 30 and nUseRoughTool == 0 then
|
|
-- verifico se forzato uso truciolatore
|
|
nUseRT = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i')
|
|
if nUseRT and nUseRT ~= 0 then
|
|
sMchFind = 'OpenPocket'
|
|
nUseRoughTool = 1
|
|
end
|
|
end
|
|
-- se processo 20 e non sto usando il truciolatore
|
|
if Proc.Prc == 20 and nUseRoughTool == 0 then
|
|
if nUseRT and nUseRT ~= 0 then
|
|
sMchFind = 'OpenPocket'
|
|
nUseRoughTool = 1
|
|
end
|
|
end
|
|
-- se da sotto, imposto massima lunghezza secondo la direzione
|
|
local dMaxTotLen
|
|
if bMillDown and BD.GetBottomToolMaxTotLen then
|
|
dMaxTotLen = BD.GetBottomToolMaxTotLen( vtN)
|
|
end
|
|
-- ricerca lavorazione
|
|
local sPocketing
|
|
local _, sMyPocketing, dMyTMaxDepth, dMyTDiam = VerifyPocket( Proc, dDiam, dFacElev + dCollSic, dMaxTotLen, sMchFind, bMillDown)
|
|
if not sMyPocketing and bMillUp then
|
|
_, sMyPocketing, dMyTMaxDepth, dMyTDiam = VerifyPocket( Proc, dDiam, dFacElev + dCollSic, dMaxTotLen, sMchFind)
|
|
bMillDown = false
|
|
end
|
|
if sMyPocketing and
|
|
( dMyTMaxDepth > dFacElev + dCollSic - 10 * GEO.EPS_SMALL or ( dMyTMaxDepth > 0.8 * dFacElev + dCollSic and not bIsU) or
|
|
( bIsL and nUseRoughTool == 0) or
|
|
( Proc.Prc == 25 and not bIsU and not bIsL)) then
|
|
sPocketing = sMyPocketing
|
|
end
|
|
if bMillDown then
|
|
sMchFind = sMchFind ..'_H2'
|
|
end
|
|
-- Verifico se lavorazione "Lamello":
|
|
local bSpecialMillOnSide, sMillingOnSide, dThickMillOnSide, dToolDiamOnSide, dMaxDepthOnSide = VerifySideMillAsSaw( Proc, nAddGrpId, vtN, dDiam, dFacElev)
|
|
if bSpecialMillOnSide then
|
|
sPocketing = nil
|
|
end
|
|
-- se feature 16 e forzata lama e forma ad U, annulla la svuotatura
|
|
if Proc.Prc == 16 and bForceUseBlade and Proc.Fct == 3 and bIsU then
|
|
sPocketing = nil
|
|
end
|
|
-- se richiesta fresatura di lato
|
|
if bForceSideMill then
|
|
sPocketing = nil
|
|
end
|
|
-- leggo parametro Q
|
|
local nQAntisplintResult = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') or 0
|
|
-- se lavorazione fresa come lama disabilito eventuale antischeggia
|
|
if bSpecialMillOnSide then nQAntisplintResult = 0 end
|
|
-- se non trovata una svuotatura adatta
|
|
if not sPocketing then
|
|
-- se forma a L provo con contornatura
|
|
if bIsL and not bSpecialMillOnSide and not bForceSideMill then
|
|
-- se smusso non è esclusivo
|
|
if nChamfer < 2 then
|
|
return MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev, dCollSic)
|
|
end
|
|
-- altrimenti, in base alla forma, provo con svuotature di fianco o con la sega a catena o lama
|
|
else
|
|
local bTryWithBlades = true
|
|
local nOk, bOk, sStat, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces, nSurfInt
|
|
if bSpecialMillOnSide then
|
|
-- eseguo
|
|
bOk, sWarn = MakeByMillAsSaw( Proc, nPhase, nRawId, nPartId, nFacInd,
|
|
rfFac, dH, dV, dFacElev,
|
|
nBottomFace, nAddGrpId, b3Solid, dMaxDepthOnSide, sMillingOnSide,
|
|
dToolDiamOnSide, dThickMillOnSide, bAllWithEndCap)
|
|
if bOk then
|
|
return true, sWarn
|
|
end
|
|
end
|
|
-- se feature 16 o 17 e se forzata lama provo prima con questa e poi con la fresa
|
|
if ( Proc.Prc == 16 or Proc.Prc == 17) and bForceUseBlade then
|
|
-- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame
|
|
if bTryWithBlades and nChamfer < 2 then
|
|
-- anche su macchine con testa da sotto, la sega a catena è solo da sopra
|
|
if vtN:getZ() < BD.NZ_MINA and BD.DOWN_HEAD and nFacInd2 then
|
|
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
nFacInd, nFacInd2 = nFacInd2, nFacInd
|
|
dFacElev, dFacElev2 = dFacElev2, dFacElev
|
|
bUseOtherFace = true
|
|
rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
end
|
|
-- eseguo
|
|
bOk, sWarn, sStat = MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd,
|
|
rfFac, dH, dV, dFacElev, bForceUseBlade,
|
|
dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace,
|
|
bOrthoFaces, nBottomFace, nChamfer, nAddGrpId, b3Solid,
|
|
dDepthCham, nSurfInt)
|
|
if not bOk then
|
|
-- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e
|
|
-- se non è possibile allora provo in seguito con lama o segacatena
|
|
-- o passare subito dalla lavorazione con lama/sega catena
|
|
if Proc.Fct == 3 and bIsU then
|
|
-- lavoro con svuotature (singola o doppia contrapposta)
|
|
local sMyMchFind = 'Pocket'
|
|
nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, _, _, _, _, _, _, _,
|
|
bOrthoFaces = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMyMchFind, true, b3Solid, nil, bMillDown)
|
|
-- se lavorazione non idonee ( asse della feature troppo inclinato e impossibile lavorare completamente da due parti)
|
|
if nOk == -2 then
|
|
if not sMchFind then
|
|
sMchFind = sMchFindBackUp
|
|
end
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam, nil, nil, not bMillDown, bMillDown)
|
|
if not sPocketing then
|
|
local sErr = 'Error : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
elseif nOk < 0 then
|
|
return false, sErr
|
|
elseif nOk == 0 then
|
|
if sStat == 'MNF' then
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam, nil, nil, not bMillDown, bMillDown)
|
|
if not sPocketing then
|
|
local sErr = 'Error : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
else
|
|
return bOk, sWarn
|
|
end
|
|
else
|
|
bOk = true
|
|
return bOk, sErr
|
|
end
|
|
else
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam, nil, nil, not bMillDown, bMillDown)
|
|
if not sPocketing then
|
|
local sErr = 'Error : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
else
|
|
return bOk, sWarn
|
|
end
|
|
else
|
|
-- se devo inserire il chamfer
|
|
if ( ( Proc.Fct == 3 and bIsU) or (Proc.Fct == 2 and bIsL)) and nChamfer > 0 then
|
|
-- ottengo le dimensioni dello pseudotunnel
|
|
local _, _, _, vtOrtho, _, nSurfInt = BL.GetTunnelDimension( Proc, nPartId)
|
|
local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham)
|
|
if nOk < 0 then return false, sErr end
|
|
end
|
|
bOk = true
|
|
return bOk, sWarn
|
|
end
|
|
else
|
|
-- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo
|
|
-- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa
|
|
-- 2021.04.27 esegue antischeggia di lama se forma U o L con feature passante in Y o Z
|
|
-- 2021.07.16 Per poter eseguire antischeggia di lama su feature che non sono passanti da faccia a faccia
|
|
-- ma che sono su un angolo (coinvolgono 2 facce contigue) è stato modificato il confronto in:
|
|
-- esegue antischeggia di lama se forma U o L con feature passante in Y o Z, oppure se feature a furma U e con 3 facce oppore a forma a L e con 2 facce
|
|
-- non fa mai antischeggia di lama se la faccia è rivolta verso il basso, a meno che ci sia una testa sotto
|
|
local bMadeASbyBld = false
|
|
local bPassThrou = ( Proc.Box:getDimY() > b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > b3Raw:getDimZ() - 1)
|
|
local bPassEdge = ((( bIsU and Proc.Fct == 3) or ( bIsL and Proc.Fct == 2)) and bSinglePart and Proc.Box:getDimX() < 0.9 * b3Raw:getDimX())
|
|
local nFacIndOri = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
|
|
local vtNOri = EgtSurfTmFacetNormVersor( Proc.Id, nFacIndOri, GDB_ID.ROOT)
|
|
if nChamfer < 2 and nQAntisplintResult == 1 and (( bIsU or bIsL) and ( bPassThrou or bPassEdge)) and ( vtNOri:getZ() > -0.087 or BD.DOWN_HEAD or BD.TURN) then
|
|
local bOk
|
|
local bSawDown = ( bMillDown and not bMillUp)
|
|
bMadeASbyBld, bOk, sWarn = ManageAntiSplintBySaw( Proc, b3Raw, bIsU, vtNOri, nFacIndOri, sWarn, bSawDown, true)
|
|
if not bOk then return false, sWarn end
|
|
end
|
|
-- in base al flag interno e al numero di facce e se ha forma ad U
|
|
-- oppure se richiesta lavorazione di lato:
|
|
-- provo prima la svuotatura sul fianco e
|
|
-- se non è possibile allora provo in seguito con lama o segacatena
|
|
-- o passare subito dalla lavorazione con lama/sega catena
|
|
if ( bTrySidePocketAtFirst and Proc.Fct == 3 and bIsU) or bForceSideMill then
|
|
-- lavoro con svuotature (singola o doppia contrapposta)
|
|
local sMyMchFind = EgtIf( bForceSideMill, 'OpenPocket', 'Pocket')
|
|
local dDiamTool = 100
|
|
local nPathInt, nSurfInt, bOneShot, nFirstMachId
|
|
local bIs3Faces = true
|
|
local bOrthoFacesMaster = nil
|
|
local bSetOpenBorders = nil
|
|
-- trovo la faccia con normale più inclinata verso Y
|
|
local nFacApproxY, ptCFacApproxY, vtNFacApproxY = BL.FindFaceBestOrientedAsAxis( Proc, Y_AX())
|
|
-- se Q03 = 2 e
|
|
-- 3 facce a L, oppure
|
|
-- 3 facce non a L ma con una faccia favorevole a Y, oppure
|
|
-- 4 facce
|
|
-- lancio la MakePocket ( lavorazione solo da un lato, fondo della tasca la faccia più favorevole a Y)
|
|
if bForceSideMill and (( Proc.Fct == 3 and bIsL) or ( ( Proc.Fct == 3 or Proc.Fct == 2) and abs( vtNFacApproxY:getY()) >= 0.707 ) or Proc.Fct == 4) then
|
|
nFacInd, vtN, ptC = nFacApproxY, vtNFacApproxY, ptCFacApproxY
|
|
local tvtNx = {}
|
|
tvtNx[2] = vtN
|
|
local ptPs = ptC
|
|
dFacElev = BL.GetFaceElevation( Proc.Id, nFacInd)
|
|
dCollSic = BL.CalcCollisionSafety( tvtNx[2])
|
|
local dMachDepth = dFacElev + dCollSic
|
|
local frFacRec, dFacDim1, dFacDim2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- limito il diametro utensile massimo a 100 per queste lavorazioni
|
|
dToolTargetDiam = min( BD.MAXDIAM_POCK_CORNER, 100)
|
|
-- se è 4 facce devo capire quale è il lato libero e settare dH e dV di conseguenza
|
|
if Proc.Fct == 4 then
|
|
local vAdj = {}
|
|
local vtN2
|
|
for i = 1, Proc.Fct do
|
|
-- recupero le adiacenze del loop esterno
|
|
local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1]
|
|
-- le conto
|
|
local nCount = 0
|
|
for j = 1, #vFacAdj do
|
|
if vFacAdj[j] >= 0 then
|
|
nCount = nCount + 1
|
|
end
|
|
end
|
|
vAdj[i] = nCount
|
|
if vAdj[i] == Proc.Fct - 1 and i ~= nFacInd + 1 then
|
|
dV = BL.GetFaceElevation( Proc.Id, i - 1)
|
|
vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT)
|
|
end
|
|
end
|
|
local vtRes = vtN2 ^ vtN
|
|
if AreSameOrOppositeVectorApprox( frFacRec:getVersX(), vtRes) then
|
|
dH = dFacDim1
|
|
else
|
|
dH = dFacDim2
|
|
end
|
|
-- se la tasca ha dimensioni adeguate cerco di usare una fresa con raggio fino a metà altezza
|
|
dToolMaxDiam = EgtIf( dH >= dToolTargetDiam and dV > 0.5 * dToolTargetDiam, dToolTargetDiam, min( dH, dV, dToolTargetDiam))
|
|
-- per le L a 3 facce, avendo due lati aperti per l'attacco, si considera un diametro utensile pari al doppio della dimensione minima; il "- 1" è un accorgimento per impedire bug derivanti da dimensione della tasca uguale a D\2 utensile
|
|
elseif Proc.Fct == 3 and bIsL then
|
|
dToolMaxDiam = min ( ( min( dFacDim1, dFacDim2) * 2) - 1, dToolTargetDiam)
|
|
-- in tutti gli altri casi l'utensile dovrà essere grande al massimo come il lato più piccolo
|
|
else
|
|
dToolMaxDiam = min ( dFacDim1, dFacDim2, dToolTargetDiam)
|
|
end
|
|
local _, sPocketing = VerifyPocket( Proc, dToolMaxDiam, dFacElev, nil, sMyMchFind)
|
|
bOk, sWarn2, sTuuidPk, dDiamTool, dDepth = MakePocket( Proc, nPartId, b3Solid, ptPs, tvtNx, nFacInd, sMyMchFind, nUseRoughTool, sPocketing, dMachDepth, nil, nil, bAllWithEndCap)
|
|
if not bOk then return false, sWarn2 end
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
bTryWithBlades = false
|
|
-- se ho antischeggia con fresa le inserisco
|
|
-- if nChamfer < 2 and nQAntisplintResult == 2 and ( bIsU or bIsL) then
|
|
if nChamfer < 2 and nQAntisplintResult == 2 then
|
|
local bOk, sWarn2 = ManageAntiSplintByMill( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacInd, nAddGrpId, bMillDown, dDiamTool, nil,
|
|
nil, nil, nil, b3Solid, dDepth,
|
|
bOneShot, nFirstMachId)
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
end
|
|
-- se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola
|
|
local nContourSmallTool = EgtGetInfo( Proc.Id, Q_CONTOUR_SMALL_TOOL, 'i') or 0
|
|
if nContourSmallTool > 0 then
|
|
local bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacInd, nAddGrpId, dDiamTool, nContourSmallTool, bMillDown,
|
|
bDoubleSide, vtOrtho, nPathInt, nSurfInt, b3Solid,
|
|
dDepth, bOneShotm)
|
|
if not bOk then return false, sWarn2 end
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
end
|
|
-- in tutti gli altri casi lancio la MakeByPockets (lavorazione singola o doppia contrapposta, fondo della tasca una faccia fittizia perpendicolare al lato lungo)
|
|
else
|
|
-- se 2 facce setto i parametri corretti per la MakeByPockets
|
|
if bForceSideMill and Proc.Fct == 2 then
|
|
bIs3Faces = false
|
|
bOrthoFacesMaster = true
|
|
bSetOpenBorders = true
|
|
end
|
|
nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId,
|
|
bOrthoFaces = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMyMchFind, bIs3Faces, b3Solid, bOrthoFacesMaster, bMillDown, bSetOpenBorders, bIsU, bIsL)
|
|
if nOk == -3 then
|
|
bTryWithBlades = true
|
|
elseif nOk == -2 then
|
|
if not sMchFind then
|
|
sMchFind = sMchFindBackUp
|
|
end
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam, nil, nil, not bMillDown, bMillDown)
|
|
if not sPocketing then
|
|
local sErr2 = 'Error : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr2)
|
|
return false, sErr2
|
|
end
|
|
bTryWithBlades = false
|
|
sWarn = sErr
|
|
elseif nOk < 0 then
|
|
return false, sErr
|
|
elseif nOk > 0 then
|
|
bTryWithBlades = false
|
|
sWarn = sErr
|
|
-- se ho antischeggia con fresa le inserisco
|
|
-- if nChamfer < 2 and nQAntisplintResult == 2 and ( bIsU or bIsL) then
|
|
local nFacIndOri, dFacElevOri = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
|
|
if nChamfer < 2 and nQAntisplintResult == 2 then
|
|
local bOk, sWarn2 = ManageAntiSplintByMill( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacIndOri, nAddGrpId, bMillDown, dDiamTool, nil,
|
|
nil, nil, nil, b3Solid, dFacElevOri,
|
|
bOneShot, nFirstMachId)
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
end
|
|
-- se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola
|
|
local nContourSmallTool = EgtGetInfo( Proc.Id, Q_CONTOUR_SMALL_TOOL, 'i') or 0
|
|
if nContourSmallTool > 0 then
|
|
local bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacInd, nAddGrpId, dDiamTool, nContourSmallTool, bMillDown,
|
|
bDoubleSide, vtOrtho, nPathInt, nSurfInt, b3Solid,
|
|
dDepth, bOneShotm)
|
|
if not bOk then return false, sWarn2 end
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
end
|
|
end
|
|
bOk = true
|
|
end
|
|
end
|
|
-- 03/09/2020 da conferma di Fabio Squaratti: Per ora solo sulla feature 016:
|
|
-- se ha fallito la fresatura (qua sopra) allora di defalut ( anche se il flag Q della lama è disattivato) prima provo la lama
|
|
if Proc.Prc == 16 then
|
|
bForceUseBlade = true
|
|
end
|
|
-- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame
|
|
if bTryWithBlades and nChamfer < 2 then
|
|
-- anche su macchine con testa da sotto, la sega a catena è solo da sopra
|
|
if vtN:getZ() < BD.NZ_MINA and BD.DOWN_HEAD and nFacInd2 then
|
|
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
nFacInd, nFacInd2 = nFacInd2, nFacInd
|
|
dFacElev, dFacElev2 = dFacElev2, dFacElev
|
|
bUseOtherFace = true
|
|
rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
end
|
|
-- eseguo
|
|
bOk, sWarn, sStat = MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd,
|
|
rfFac, dH, dV, dFacElev, bForceUseBlade,
|
|
dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace,
|
|
bOrthoFaces, nBottomFace, nChamfer, nAddGrpId, b3Solid,
|
|
dDepthCham, nSurfInt)
|
|
if not bOk and sStat == 'MNF' then
|
|
_, sPocketing = VerifyPocket( Proc, dDiam, dFacElev + dCollSic, nil, sMchFind)
|
|
if sPocketing then
|
|
sWarn = ''
|
|
else
|
|
local sErr2 = 'Error : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr2)
|
|
return false, sErr2
|
|
end
|
|
else
|
|
-- se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola
|
|
local nContourSmallTool = EgtGetInfo( Proc.Id, Q_CONTOUR_SMALL_TOOL, 'i') or 0
|
|
if nContourSmallTool > 0 then
|
|
local bOk, sWarn2
|
|
bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacInd, nAddGrpId, 100, nContourSmallTool, bMillDown)
|
|
if not bOk then return false, sWarn2 end
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
end
|
|
return bOk, sWarn
|
|
end
|
|
-- altrimenti verifico se ho già svuotato dal fianco, se si esco
|
|
else
|
|
-- se non ho annullato la/le svuotatura/e dal fianco
|
|
if nOk ~= -2 then
|
|
return bOk, sWarn
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
-- se devo inserire il chamfer
|
|
if ( ( Proc.Fct == 3 and bIsU) or (Proc.Fct == 2 and bIsL)) and nChamfer > 0 then
|
|
-- ottengo le dimensioni dello pseudotunnel
|
|
local _, _, _, vtOrtho, _, nSurfInt = BL.GetTunnelDimension( Proc, nPartId)
|
|
local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham)
|
|
if nOk < 0 then return false, sErr end
|
|
end
|
|
end
|
|
-- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo
|
|
-- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa
|
|
-- 2021.04.27 esegue antischeggia di lama se forma U o L con feature passante in Y o Z
|
|
-- 2021.07.16 Per poter eseguire antischeggia di lama su feature che non sono passanti da faccia a faccia
|
|
-- ma che sono su un angolo (coinvolgono 2 facce contigue) è stato modificato il confronto in:
|
|
-- esegue antischeggia di lama se forma U o L con feature passante in Y o Z, oppure se feature a furma U e con 3 facce oppore a forma a L e con 2 facce
|
|
-- non fa mai antischeggia di lama se la faccia è rivolta verso il basso, a meno che ci sia una testa sotto
|
|
local bMadeASbyBld = false
|
|
local bPassThrou = ( Proc.Box:getDimY() > b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > b3Raw:getDimZ() - 1)
|
|
local bPassEdge = ((( bIsU and Proc.Fct == 3) or ( bIsL and Proc.Fct == 2)) and bSinglePart and Proc.Box:getDimX() < 0.9 * b3Raw:getDimX())
|
|
local nFacIndOri = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
|
|
local vtNOri = EgtSurfTmFacetNormVersor( Proc.Id, nFacIndOri, GDB_ID.ROOT)
|
|
if nChamfer < 2 and nQAntisplintResult == 1 and (( bIsU or bIsL) and ( bPassThrou or bPassEdge)) and ( vtNOri:getZ() > -0.087 or BD.DOWN_HEAD or BD.TURN) then
|
|
local bOk
|
|
local bSawDown = ( bMillDown and not bMillUp)
|
|
bMadeASbyBld, bOk, sWarn = ManageAntiSplintBySaw( Proc, b3Raw, bIsU, vtNOri, nFacIndOri, sWarn, bSawDown)
|
|
if not bOk then return false, sWarn end
|
|
end
|
|
if nChamfer < 2 and nQAntisplintResult == 2 then
|
|
local bOk, sWarn2
|
|
bOk, sWarn2 = ManageAntiSplintByMill( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacInd, nAddGrpId, bMillDown)
|
|
if not bOk then return false, sWarn2 end
|
|
end
|
|
-- se smusso non esclusivo
|
|
if nChamfer < 2 then
|
|
-- eseguo la svuotatura della faccia principale, mi restituisce id utensile, il diametro utensile per il foro opzionale
|
|
local tvtNx = {}
|
|
tvtNx[2] = vtN
|
|
local bOk, sWarn2
|
|
bOk, sWarn2, sTuuidPk, dDiamTool = MakePocket( Proc, nPartId, b3Solid, ptC, tvtNx, nFacInd, sMchFind, nUseRoughTool, sPocketing, dFacElev + dCollSic, nil, nil, bAllWithEndCap)
|
|
if not bOk then return false, sWarn2 end
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
-- se ho più di 3 facce e non di forma ad u oppure ho 3 facce e di forma ad u
|
|
-- e non sono stati inseriti antischeggia di lama
|
|
-- controllo se c'è una faccia non ortogonale alla principale e la lavoro con una contornatura o svuotatura
|
|
if ( ( Proc.Fct > 3 and not bIsU) or ( Proc.Fct == 3 and bIsU)) and not bMadeASbyBld then
|
|
-- Recupero le facce adiacenti alla principale
|
|
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
|
|
if not vAdj or #vAdj == 0 then
|
|
local sErr = 'Error : main face without adjacencies'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Cerco una faccia adiacente alla principale con angolo > 90
|
|
local nFacAdj
|
|
local tDimAndRef = {}
|
|
tvtNx = {}
|
|
tvtNx[1] = vtN
|
|
tDimAndRef[1] = {dH, dV, rfFac}
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] >= 0 then
|
|
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
if bAdj and dAng < 0 and 180 + dAng > 90.1 then
|
|
local rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vAdj[i], GDB_ID.ROOT)
|
|
_, tvtNx[2] = EgtSurfTmFacetCenter( Proc.Id, vAdj[i], GDB_ID.ROOT)
|
|
tDimAndRef[2] = {dH2, dV2, rfFac2}
|
|
local ptPs = ( ptP1 + ptP2) / 2
|
|
local bOk, sWarn2
|
|
bOk, sWarn2 = MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, tvtNx, nFacInd, vAdj[i], ptPs, tDimAndRef,
|
|
b3Raw, EgtIf( ( Proc.Fct == 3 and bIsU), 0, 2), nUseRoughTool, dAng, sPocketing, sTuuidPk, dFacElev)
|
|
if not bOk then return bOk, sWarn2 end
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
local nBoreOnCorner = EgtGetInfo( Proc.Id, Q_BORE_ON_CORNER, 'i') or 0
|
|
local nContourSmallTool = EgtGetInfo( Proc.Id, Q_CONTOUR_SMALL_TOOL, 'i') or 0
|
|
-- se abilitato dal parametro Q inserisco foro sullo spigolo
|
|
if nBoreOnCorner == 1 then
|
|
local bOk, sWarn2
|
|
bOk, sWarn2 = MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool)
|
|
if not bOk then return false, sWarn2 end
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
-- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura
|
|
elseif nBoreOnCorner == 2 then
|
|
local bOk, sWarn2
|
|
bOk, sWarn2 = MakeSharpCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool)
|
|
if not bOk then return false, sWarn2 end
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
-- altrimenti se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola
|
|
elseif nContourSmallTool > 0 then
|
|
local bOk, sWarn2
|
|
bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, nPhase, nRawId, nPartId, b3Raw,
|
|
nFacInd, nAddGrpId, dDiamTool, nContourSmallTool, bMillDown)
|
|
if not bOk then return false, sWarn2 end
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- eventuale segnalazione ingombro di testa o coda
|
|
UpdateEncumbrance( Proc, nRawId, b3Raw, b3Solid)
|
|
end
|
|
|
|
return true, sWarn, bPrevBhSideMill
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
-- recupero gruppo per geometria addizionale
|
|
local nAddGrpId = BL.GetAddGroup( nPartId)
|
|
if not nAddGrpId then
|
|
local sErr = 'Error : missing AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero l'ingombro del grezzo di appartenenza
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
-- ottengo la distanza tra la fine del pezzo e il pezzo successivo
|
|
local dDistToNextPiece = BL.GetDistanceToNextPart( nRawId, nPhase)
|
|
-- verifico se applicare gestione speciale delle giunzioni (U diretta come asse X)
|
|
local bAddEndCap = false
|
|
local dAddLen = 0
|
|
local bIsOpenU = ( Proc.Fct == 3 and not TestElleShape3( Proc))
|
|
if bIsOpenU then
|
|
local ptC0, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
|
|
local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, 2, GDB_ID.ROOT)
|
|
if vtN0:getX() < 0.0175 and vtN1:getX() < 0.0175 and vtN2:getX() < 0.0175 then
|
|
local dWidth = 0
|
|
if vtN0 * vtN1 < -0.9998 then
|
|
bAddEndCap = true
|
|
dWidth = ( ptC1 - ptC0) * vtN0
|
|
elseif vtN0 * vtN2 < -0.9998 then
|
|
bAddEndCap = true
|
|
dWidth = ( ptC2 - ptC0) * vtN0
|
|
elseif vtN1 * vtN2 < -0.9998 then
|
|
bAddEndCap = true
|
|
dWidth = ( ptC2 - ptC1) * vtN1
|
|
end
|
|
dAddLen = min( dWidth, 100) / 2
|
|
end
|
|
end
|
|
-- la divido in parti lungo X
|
|
local vAddId = {}
|
|
local bAllWithEndCap = bAddEndCap
|
|
local nPart = max( ceil( Proc.Box:getDimX() / BD.LONGCUT_MAXLEN), 2)
|
|
local dPartLen = Proc.Box:getDimX() / nPart
|
|
local Xmin = Proc.Box:getMin():getX()
|
|
for i = 1, nPart do
|
|
-- eseguo divisione
|
|
local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
|
|
if i > 1 or bAddEndCap then
|
|
-- definizione del piano
|
|
local dAdd = EgtIf( i > 1, dAddLen, 0)
|
|
local ptOn = Point3d( Xmin - dAdd + ( i - 1) * dPartLen, 0, 0)
|
|
local vtN = -X_AX()
|
|
-- se richiesto, creazione tappo
|
|
local CapId
|
|
if bAddEndCap then
|
|
local nFirstId, nPnt, nCrv, nSrf = EgtPlaneSurfTmInters( ptOn, vtN, AddId, nAddGrpId, GDB_RT.GLOB)
|
|
if nPnt == 0 and nCrv == 1 and nSrf == 0 then
|
|
EgtCloseCurveCompo( nFirstId)
|
|
CapId = EgtSurfTmByFlatContour( nAddGrpId, nFirstId)
|
|
if not CapId then bAllWithEndCap = false end
|
|
end
|
|
if nFirstId then
|
|
for nId = nFirstId, nFirstId + nPnt + nCrv + nSrf - 1 do
|
|
EgtErase( nId)
|
|
end
|
|
end
|
|
end
|
|
-- taglio della superficie
|
|
EgtCutSurfTmPlane( AddId, ptOn, vtN, true, GDB_RT.GLOB)
|
|
-- se esiste, aggiunta del tappo
|
|
if CapId then
|
|
AddId = EgtSurfTmBySewing( nAddGrpId, { AddId, CapId})
|
|
-- se prima spezzatura, allungamento per non lasciare archi
|
|
if i == 1 then
|
|
local b3Box = EgtGetBBoxGlob( AddId, GDB_BB.STANDARD)
|
|
local dCoeffX = 1 + min( dAddLen, dDistToNextPiece) / b3Box:getDimX()
|
|
EgtScale( AddId, Frame3d( b3Box:getMax()), dCoeffX, 1, 1, GDB_RT.GLOB)
|
|
end
|
|
end
|
|
end
|
|
if i < nPart then
|
|
local ptOn = Point3d( Xmin + i * dPartLen, 0, 0)
|
|
local vtN = X_AX()
|
|
EgtCutSurfTmPlane( AddId, ptOn, vtN, true, GDB_RT.GLOB)
|
|
end
|
|
EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i))
|
|
-- eseguo inserimento in modo da ordinare da X+ a X-
|
|
table.insert( vAddId, 1, AddId)
|
|
end
|
|
-- applico le lavorazioni sulle diverse parti
|
|
local sWarn
|
|
local bPrevBhSideMill
|
|
for i = 1, #vAddId do
|
|
local b3Box = EgtGetBBoxGlob( vAddId[i], GDB_BB.STANDARD)
|
|
local nFct = EgtSurfTmFacetCount( vAddId[i])
|
|
local AddProc = { Id = vAddId[i], Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Box, TotBox = Proc.Box, Fct = nFct, Flg = Proc.Flg}
|
|
-- lasciare il false nel sesto parametro (perchè internamente viene verificato se diverso da nil)
|
|
local bOk, sMyWarn
|
|
bOk, sMyWarn, bPrevBhSideMill = MakeMoreFaces( AddProc, nPhase, nRawId, nPartId, dOvmHead, bAllWithEndCap, bPrevBhSideMill, bAllWithEndCap)
|
|
if not sWarn then sWarn = sMyWarn end
|
|
if not bOk then return bOk, sWarn end
|
|
end
|
|
return true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TestTwoFacesDownHead( Proc)
|
|
-- verifico ci siano due facce
|
|
if Proc.Fct ~= 2 then return false end
|
|
-- verifico se da lavorare con testa da sotto
|
|
local bDownHead = false
|
|
if BD.DOWN_HEAD then
|
|
local ptC = {}
|
|
local vtN = {}
|
|
ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
|
|
local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize()
|
|
bDownHead = ( vtNm:getZ() < -0.5)
|
|
end
|
|
return bDownHead
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione
|
|
---------------------------------------------------------------------
|
|
function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
-- setto a nil la variabile smussi
|
|
bMadeChamfer = nil
|
|
-- limiti di fresatura semplice
|
|
local MAX_MILL_LIN = 80
|
|
-- recupero l'ingombro del grezzo di appartenenza
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
-- recupero l'ingombro della trave
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
if not b3Solid then
|
|
local sErr = 'Error : part box not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- in base al tipo di feature attribuisco il significato dei parametri Q
|
|
AssignQIdent( Proc)
|
|
-- se non forzate frese, uso la lama
|
|
local bUseBlade = EgtIf( Proc.Prc == 90, false, EgtGetInfo( Proc.Id, Q_USE_ROUGH_TOOL, 'i') ~= 1 and EgtGetInfo( Proc.Id, Q_USE_MILL, 'i') ~= 1)
|
|
local nForceUseBladeOnNotContinueFace
|
|
-- se ho attivo la lama e ho la feature 30, verifico i parametri Q propri della feature
|
|
if bUseBlade then
|
|
if Proc.Prc == 30 or Proc.Prc == 20 then
|
|
local nBladeAntisplint = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') or 0
|
|
local nUseRoughToolOnSide = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0
|
|
nForceUseBladeOnNotContinueFace = EgtGetInfo( Proc.Id, Q_BLADE_ON_ALONG_FACE, 'i') or 0
|
|
-- se antischeggia di fresa o abilitato sgrossatore di fianco
|
|
if nBladeAntisplint == 2 or nUseRoughToolOnSide > 0 then
|
|
bUseBlade = false
|
|
end
|
|
-- se ho attivo la lama e ho la feature 32, verifico i parametri Q propri della feature
|
|
elseif Proc.Prc == 32 then
|
|
local nBladeAntisplint = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') or 0
|
|
local nUseRoughToolOnSide = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0
|
|
-- se antischeggia di fresa o abilitato sgrossatore di fianco
|
|
if nBladeAntisplint == 2 or nUseRoughToolOnSide == 1 then
|
|
bUseBlade = false
|
|
end
|
|
-- se ho attivo la lama e ho la feature 34, verifico i parametri Q propri della feature
|
|
elseif Proc.Prc == 34 then
|
|
local nBladeAntisplint = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') or 0
|
|
-- se antischeggia di fresa o abilitato sgrossatore di fianco
|
|
if nBladeAntisplint == 2 then
|
|
bUseBlade = false
|
|
end
|
|
end
|
|
end
|
|
-- se lunghezza richiede spezzatura
|
|
if ( Proc.Box:getDimX() > BD.LONGCUT_MAXLEN) or
|
|
( Proc.Box:getDimX() > 0.7 * b3Solid:getDimX() and Proc.Box:getDimX() > BD.LONGCUT_ENDLEN) then
|
|
-- una faccia
|
|
if Proc.Fct == 1 then
|
|
if bUseBlade then
|
|
if nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then
|
|
return LongCut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nForceUseBladeOnNotContinueFace)
|
|
else
|
|
return LongCut.Make( Proc, nPhase, nRawId, nPartId)
|
|
end
|
|
else
|
|
return LongCut.Make( Proc, nPhase, nRawId, nPartId)
|
|
end
|
|
-- due facce
|
|
elseif Proc.Fct == 2 then
|
|
-- verifico se da lavorare con testa da sotto
|
|
local bDownHead = TestTwoFacesDownHead( Proc)
|
|
-- dati delle facce
|
|
local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD)
|
|
local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD)
|
|
local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT)
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT)
|
|
-- determino se due facce lunghe oppure una lunga e l'altra terminale
|
|
if abs( b3Fac1:getDimX() - b3Fac2:getDimX()) < 50 and abs( b3Fac1:getCenter():getX() - b3Fac2:getCenter():getX()) < 50 and
|
|
abs( vtN1:getX()) < GEO.EPS_SMALL and abs( vtN2:getX()) < GEO.EPS_SMALL then
|
|
-- leggo i parametri Q per utilizzare la fresa di fianco e/o lama
|
|
local nUseSideTool = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0
|
|
local bUseBlade = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') == 1
|
|
return Long2Cut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nUseSideTool)
|
|
-- prima faccia terminale
|
|
elseif b3Fac1:getDimX() < 1 and abs( vtN2:getX()) < GEO.EPS_SMALL then
|
|
-- la faccia 0 deve essere quella lunga
|
|
EgtSurfTmSwapFacets( Proc.Id, 0, 1)
|
|
if bUseBlade then
|
|
if nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then
|
|
return LongCut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nForceUseBladeOnNotContinueFace)
|
|
else
|
|
return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead)
|
|
end
|
|
else
|
|
return LongCut.Make( Proc, nPhase, nRawId, nPartId)
|
|
end
|
|
-- seconda faccia terminale
|
|
elseif b3Fac2:getDimX() < 1 and abs( vtN1:getX()) < GEO.EPS_SMALL then
|
|
if bUseBlade then
|
|
if nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then
|
|
return LongCut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nForceUseBladeOnNotContinueFace)
|
|
else
|
|
return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead)
|
|
end
|
|
else
|
|
return LongCut.Make( Proc, nPhase, nRawId, nPartId)
|
|
end
|
|
-- altrimenti
|
|
else
|
|
if bUseBlade and ( abs( vtN1:getX()) > 0.5 or abs( vtN2:getX()) > 0.5) then
|
|
return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead)
|
|
else
|
|
return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
end
|
|
end
|
|
-- tre facce
|
|
elseif Proc.Fct == 3 then
|
|
-- determino se due facce lunghe oppure una lunga e l'altra terminale
|
|
local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD)
|
|
local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD)
|
|
local b3Fac3 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 2, GDB_BB.STANDARD)
|
|
local bApplyBladeOnLongNotContinueFace
|
|
|
|
if b3Fac1:getDimX() < 1 and b3Fac3:getDimX() < 1 then
|
|
-- la faccia 0 deve essere quella lunga
|
|
EgtSurfTmSwapFacets( Proc.Id, 0, 1)
|
|
bApplyBladeOnLongNotContinueFace = true
|
|
elseif b3Fac1:getDimX() < 1 and b3Fac2:getDimX() < 1 then
|
|
-- la faccia 0 deve essere quella lunga
|
|
EgtSurfTmSwapFacets( Proc.Id, 0, 2)
|
|
bApplyBladeOnLongNotContinueFace = true
|
|
elseif b3Fac2:getDimX() < 1 and b3Fac3:getDimX() < 1 then
|
|
bApplyBladeOnLongNotContinueFace = true
|
|
end
|
|
|
|
if bApplyBladeOnLongNotContinueFace and bUseBlade and nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then
|
|
return LongCut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nForceUseBladeOnNotContinueFace)
|
|
else
|
|
return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
end
|
|
-- più facce
|
|
else
|
|
return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
end
|
|
-- altrimenti lavorazione unica
|
|
else
|
|
-- una faccia
|
|
if Proc.Fct == 1 then
|
|
-- se piccola, con fresa
|
|
if not bUseBlade and ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then
|
|
return MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId)
|
|
-- se è una spianatura a una faccia richiamo la LongCut
|
|
elseif Proc.Prc == 90 then
|
|
return LongCut.Make( Proc, nPhase, nRawId, nPartId)
|
|
-- altrimenti, con lama
|
|
else
|
|
return Cut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
end
|
|
-- due facce
|
|
elseif Proc.Fct == 2 then
|
|
-- se praticamente è lunga come la trave e sono due facce lunghe
|
|
local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD)
|
|
local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD)
|
|
if Proc.Box:getDimX() > 0.8 * b3Solid:getDimX() and
|
|
abs( b3Fac1:getDimX() - b3Fac2:getDimX()) < 50 and abs( b3Fac1:getCenter():getX() - b3Fac2:getCenter():getX()) < 50 then
|
|
local nUseSideTool = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0
|
|
return Long2Cut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nUseSideTool)
|
|
-- altrimenti
|
|
else
|
|
-- verifico se da lavorare con testa da sotto
|
|
local bDownHead = TestTwoFacesDownHead( Proc)
|
|
-- determino l'angolo tra le facce
|
|
local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
|
|
-- se con BH
|
|
if VerifyBHSideMill( Proc) then
|
|
return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, true)
|
|
-- se ortogonali e non forzata lama, con fresa
|
|
elseif not bUseBlade and bAdj and abs( dAng + 90) < 1 then
|
|
-- se piccole
|
|
if Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN) then
|
|
return MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId, bDownHead)
|
|
else
|
|
return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, true)
|
|
end
|
|
-- altrimenti, con lama
|
|
else
|
|
-- verifico se devo fare prima gli smussi
|
|
-- recupero gruppo per geometria addizionale
|
|
local nAddGrpId = BL.GetAddGroup( nPartId)
|
|
if not nAddGrpId then
|
|
local sErr = 'Error : missing AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- verifiche per smusso
|
|
local nChamfer, dDepthCham, sErrCham = EvaluateQParam( Proc)
|
|
-- se smusso da fare
|
|
if nChamfer > 0 then
|
|
local _, _, _, vtOrtho, _, nSurfInt = BL.GetTunnelDimension( Proc, nPartId)
|
|
local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham)
|
|
if nOk < 0 then return false, sErr end
|
|
end
|
|
-- se smusso non esclusivo
|
|
if nChamfer < 2 then
|
|
return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead or BD.TURN)
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
-- tre o più facce
|
|
else
|
|
return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, true)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return ProcessLapJoint
|