123a983c75
- in LapJoint->MakeDrillOnCorner aggiunto controllo distanza di sicurezza minima
5812 lines
278 KiB
Lua
5812 lines
278 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.
|
|
-- 2023/02/06 Alla MakeDrillOnCorner aggiunto controllo distanza di sicurezza minima.
|
|
|
|
-- 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)
|
|
-- imposto il valore della distanza di sicurezza per l'attacco. Se il valore del db utensili è troppo basso lo alzo a 10.
|
|
local dToolDbStartPos = EgtGetMachiningParam( MCH_MP.STARTPOS)
|
|
local dMinStartPos = 10
|
|
local dStartPos = max( dMinStartPos, dToolDbStartPos)
|
|
EgtSetMachiningParam( MCH_MP.STARTPOS, dStartPos)
|
|
-- 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
|