da7d2a7159
- LapJoint -> MakeSideGrooveByMill, se rabbet doppio uno verso l'alto e uno verso il basso, aggiunto step extra iniziale per ripulire la lamina che potrebbe rimanere nella rabbet che guarda in alto.
3029 lines
142 KiB
Lua
3029 lines
142 KiB
Lua
-- WProcessLapJoint.lua by Egaltech s.r.l. 2023/10/02
|
|
-- Gestione calcolo mezzo-legno per Pareti
|
|
-- 2021/08/27 DS Se tre o più facce con flag PCKT=1 forzo svuotatura con fresa (per Variant).
|
|
-- 2021/08/29 DS Se svuotatura di fianco setto flag per farla dopo i tagli.
|
|
-- 2021/09/03 DS Se due facce con sottosquadra ora si restituisce mesaaggio di errore.
|
|
-- 2021/10/05 FM Gestione lavorazioni SideMill con creazione gola passaggio gambo utensile
|
|
-- 2021/11/29 DS Correzione lav.ni SideMill quando più profonde che larghe.
|
|
-- 2022/01/04 DS Se U con fondo verso basso o alto non ci possono essere spigoli verticali da pulire.
|
|
-- 2022/01/17 ES Migliorata scelta fresa per lavorazione di fianco sotto.
|
|
-- 2022/02/03 DS Gorge larga come gambo più sicurezza.
|
|
-- 2022/02/04 DS In svuotatura aggiunta gestione WD.MAXDIAM_POCK_CORNER in presenza di almeno un angolo interno.
|
|
-- 2022/09/30 In MakeSideGrooveByMill sistemato il calcolo del massimo sottosquadro dell'utensile per determinare la fattibilità della tasca.
|
|
-- 2022/10/05 In MakeSideGrooveByMill implementata l'inversione dello step se la tasca guarda verso il basso
|
|
-- 2022/11/15 DS Con lama massima inclinazione 60deg.
|
|
-- 2022/12/01 Per 2 facce con angolo > 90° implementata lavorazione principale verticale. Se da sopra, aggiunta ripresa del lato inclinato.
|
|
-- 2022/12/14 Nel caso di 2 facce piccola correzione al modo di ordinare le facce.
|
|
-- 2023/03/09 Gestito caso riconoscimento errato Stype 3.
|
|
-- 2023/03/09 In MakeMoreFaces aggiunta la possibilità di lavorare le fessure con la lama.
|
|
-- 2023/03/17 In MakeByMill gestito correttamente il caso di Workside destro.
|
|
-- 2023/04/15 Corretta scelta tipo lavorazione 'SideGroove' aggiungendo massimo spessore.
|
|
-- 2023/04/17 Sistemata gestione parametri Q, eliminando quello non usato di forzatura lama e abilitandoli anche per DoubleCut.
|
|
-- Lavorazione CleanCorner sempre forzata con lato di lavoro in centro.
|
|
-- 2023/05/25 Funzioni EgtAddMachining sostituite da WM.AddMachining in modo da trascrivere le priorità da btl alle lavorazioni.
|
|
-- 2023/06/30 Aggiunta lettura delle note esistenti dalle lavorazioni per evitare di sovrascriverle.
|
|
-- 2023/07/10 In MakeSideGrooveByMill si impedisce ora di lavorare una groove se la testa deve scendere sotto al limite superiore del grezzo.
|
|
-- 2023/07/25 Aggiunte passate laterali per SideGroove, se specificato SIDESTEP nelle note utensile.
|
|
-- 2023/08/01 Migliorato controllo testa sotto al grezzo in SieGroove.
|
|
-- 2023/08/07 Controllo testa sotto al grezzo in SideGroove escluso se richiesto il move after.
|
|
-- 2023/09/19 Controllo lavorabilità con una sola faccia ora ha limiti come FreeContour.
|
|
-- 2023/09/21 Modifica controllo lavorabilità con tre facce tipo tunnel ma non ortogonali tra loro.
|
|
-- 2023/09/21 In MakeByMill modificato SCC per correggere caso con lama su testa fresa.
|
|
-- 2023/10/02 Aggiunta segnalazione lavorazione tipo Side non trovata.
|
|
-- 2023/10/30 In VerifyPocket, per tasche in doppio forzata ricerca fresa che possa lavorare di testa.
|
|
-- 2023/10/31 In VerifyPocket, se topologia pocket, forzata ricerca fresa che possa lavorare di testa.
|
|
-- 2023/11/06 In VerifyPocket controllo massimo diametro in base a distanza pezzo più vicino demandato a FindPocketing.
|
|
-- 2023/11/07 In MakeByPocketing, se tasca che guarda davanti, aggiunta possibilità di attaccare fuori dal grezzo fino ad uno spessore di 75 mm.
|
|
-- In MakeByPocketing calcolo del massimo diametro utensile spostato in VerifyPocketing.
|
|
-- In MakeByPocketing il doppio viene ora disattivato se una tasca deve essere forzata chiusa e l'altra no.
|
|
-- 2023/11/13 In MakeSideGrooveByMill, se rabbet doppio uno verso l'alto e uno verso il basso, aggiunto step extra iniziale per ripulire la lamina che potrebbe rimanere nella rabbet che guarda in alto.
|
|
|
|
-- Tabella per definizione modulo
|
|
local WPL = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local WL = require( 'WallLib')
|
|
local FreeContour = require( 'WProcessFreeContour')
|
|
|
|
EgtOutLog( ' WProcessLapJoint started', 1)
|
|
|
|
-- Dati
|
|
local WD = require( 'WallData')
|
|
local WM = require( 'WMachiningLib')
|
|
local WHISK_OFFS = 0.1
|
|
local WHISK_SAFE = 5
|
|
local MIN_LEN_CUT = 30
|
|
|
|
-- variabili assegnazione parametri Q
|
|
local Q_SIDE_MILL = '' -- d
|
|
local Q_CORNER_CUT = '' -- i
|
|
|
|
-- variabile settaggio doppia lavorazione su angolo > 90
|
|
local bMakeTwinCut = true
|
|
-- angolo sottosquadra ammesso per fresa cono 30°
|
|
local dAngleSmall = 70
|
|
|
|
---------------------------------------------------------------------
|
|
-- Riconoscimento della feature
|
|
function WPL.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 == 30) or
|
|
( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32) or
|
|
( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34) or
|
|
( ( Proc.Grp == 4) and Proc.Prc == 39)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AssignQIdent( Proc)
|
|
|
|
-- reset assegnazione parametri Q
|
|
Q_SIDE_MILL = ''
|
|
Q_CORNER_CUT = ''
|
|
|
|
if Proc.Prc == 11 then
|
|
Q_SIDE_MILL = 'Q02' -- i
|
|
Q_CORNER_CUT = 'Q05' -- i
|
|
elseif Proc.Prc == 12 then
|
|
Q_SIDE_MILL = 'Q02' -- i
|
|
Q_CORNER_CUT = '' -- i
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then
|
|
Q_SIDE_MILL = 'Q08' -- i
|
|
Q_CORNER_CUT = 'Q05' -- i
|
|
else
|
|
Q_SIDE_MILL = 'Q03' -- i
|
|
Q_CORNER_CUT = 'Q05' -- i
|
|
end
|
|
-- le altre features gestite non hanno parametri Q
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function EvaluateQParam( Proc)
|
|
|
|
-- Verifico se utilizzare la fresa di lato :
|
|
-- 0 : niente
|
|
-- 1 : utilizzo fresa di lato (alla faccia selezionata)
|
|
local nUseSideMillAsBlade = EgtGetInfo( Proc.Id, Q_SIDE_MILL, 'i') or 0
|
|
|
|
-- Verifico il tipo di lavorazione su angolo :
|
|
-- 0 : niente
|
|
-- 1 : ripresa corner dopo pausa per rimozione sfridi (fresa 60deg)
|
|
-- 2 : ripresa corner senza pausa (fresa 30 deg)
|
|
-- 3 : scarico corner (tipo foro).
|
|
local nTypeCornerCut = EgtGetInfo( Proc.Id, Q_CORNER_CUT, 'i') or 0
|
|
|
|
return nTypeCornerCut, nUseSideMillAsBlade
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione della feature
|
|
function WPL.Classify( Proc, b3Raw)
|
|
-- se 1 faccia
|
|
if Proc.Fct == 1 then
|
|
-- dati della faccia
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT)
|
|
-- verifico se è lavorabile da sopra o di fianco
|
|
return vtN:getZ() >= -0.5
|
|
-- se 2 facce
|
|
elseif Proc.Fct == 2 then
|
|
-- 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 da sopra o di fianco
|
|
return ( vtN[1]:getZ() >= -0.028 or vtN[2]:getZ() >= -0.028)
|
|
-- se più di 2 facce
|
|
else
|
|
local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId)
|
|
-- se trovata faccia di fondo
|
|
if nFacInd >= 0 then
|
|
-- determino componente Z della normale più diretta verso il basso
|
|
local dMinNz = 1
|
|
for i = 1, Proc.Fct do
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT)
|
|
if vtN:getZ() < dMinNz then
|
|
dMinNz = vtN:getZ()
|
|
end
|
|
end
|
|
-- dati della faccia
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- per lavorare alcune superfici che sono di poco negative controllo che la minima Z sia al di sopra del punto minimo calcolato per
|
|
-- una lama da 500
|
|
local bAllowNegativeFace
|
|
if vtN:getZ() < - 0.01 then
|
|
if vtN:getZ() > - 0.088 and Proc.Box:getMin():getZ() - b3Raw:getMin():getZ() - (500 * abs(vtN:getZ())) >= 0 then
|
|
bAllowNegativeFace = true
|
|
end
|
|
end
|
|
|
|
-- conto le adiacenze delle facce
|
|
local vAdj = {}
|
|
local nFacesWithMoreThanOneAdj = 0
|
|
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 nCount > 1 then
|
|
nFacesWithMoreThanOneAdj = nFacesWithMoreThanOneAdj + 1
|
|
end
|
|
end
|
|
|
|
-- verifico se la faccia è lavorabile da sopra o di fianco
|
|
if ( vtN:getZ() >= WD.NZ_MINA or ( dMinNz < -0.866 and Proc.Fct >= 3 and ( vtN:getZ() > - 0.01 or bAllowNegativeFace))) then
|
|
Proc.Stype = 1
|
|
return true
|
|
-- altrimenti verifico la eventuale seconda faccia
|
|
elseif nFacInd2 then
|
|
-- dati della faccia
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
-- restituisco se faccia lavorabile
|
|
Proc.Stype = 2
|
|
return ( vtN2:getZ() >= WD.NZ_MINA or ( dMinNz < -0.866 and Proc.Fct >= 3 and vtN2:getZ() > - 0.01))
|
|
-- se tre facce
|
|
elseif Proc.Fct == 3 and nFacesWithMoreThanOneAdj < 2 then
|
|
-- verifico se U da sopra
|
|
-- dati della faccia
|
|
local nFac2 = EgtIf( nFacInd == 0, 1, 0)
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFac2, GDB_ID.ROOT)
|
|
Proc.Stype = 3
|
|
return ( abs( ( vtN ^ vtN2) * Z_AX()) >= WD.NZ_MINA)
|
|
-- altrimenti non lavorabile
|
|
else
|
|
return false
|
|
end
|
|
-- se altrimenti tunnel o assimilabile
|
|
elseif nFacInd == -1 or nFacInd == -2 then
|
|
-- dati delle prime tre facce
|
|
local vtN = {}
|
|
vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT)
|
|
vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT)
|
|
vtN[3] = EgtSurfTmFacetNormVersor( Proc.Id, 2, GDB_ID.ROOT)
|
|
-- verifico se è lavorabile da sopra
|
|
local vtAxN = vtN[1] ^ vtN[2]
|
|
if vtAxN:isSmall() then vtAxN = vtN[1] ^ vtN[3] end
|
|
Proc.Stype = 4
|
|
return ( abs( vtAxN:getZ()) >= WD.NZ_MINA)
|
|
-- altrimenti non lavorabile
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
-- funzione che verifica se faccia lavorabile da sopra
|
|
local function VerifyVtN( ProcId, nFct)
|
|
local nFlip0 = 0
|
|
local nFlip1 = 0
|
|
-- dati della faccia
|
|
local vtN = EgtSurfTmFacetNormVersor( ProcId, nFct, GDB_ID.ROOT)
|
|
local dVtNZ = vtN:getZ()
|
|
-- verifico se è lavorabile da sopra
|
|
nFlip0 = EgtIf( dVtNZ >= WD.NZ_MINA, 100, 0)
|
|
-- verifico se e' lavorabile da fliped: cambio segno al versore
|
|
nFlip1 = EgtIf( -dVtNZ >= WD.NZ_MINA, 100, 0)
|
|
return nFlip0, nFlip1
|
|
end
|
|
|
|
-- funzione che fa la media dei versori per assegnare punteggi flip
|
|
local function VerifyVtNMedia(ProcId, nFct1, nFct2)
|
|
local nFlip0 = 0
|
|
local nFlip1 = 0
|
|
-- dati delle facce
|
|
local vtN = {}
|
|
vtN[1] = EgtSurfTmFacetNormVersor( ProcId, nFct1, GDB_ID.ROOT)
|
|
vtN[2] = EgtSurfTmFacetNormVersor( ProcId, nFct2, GDB_ID.ROOT)
|
|
local dVtN1Z = vtN[1]:getZ()
|
|
local dVtN2Z = vtN[2]:getZ()
|
|
-- se entrambi i versori positivi
|
|
if (dVtN1Z >= - 0.01 and dVtN2Z >= - 0.01) then
|
|
-- posso lavorarlo da sopra
|
|
nFlip0 = 100
|
|
-- se almeno un versore positivo
|
|
elseif (dVtN1Z >= - 0.01 or dVtN2Z >= - 0.01) then
|
|
-- calcolo media dei versori: se positiva tende verso alto
|
|
local dVtNMedia = ( dVtN1Z + dVtN2Z) / 2
|
|
if dVtNMedia >= 0 - GEO.EPS_SMALL and dVtNMedia <= 0 + GEO.EPS_SMALL then
|
|
nFlip0 = 100
|
|
elseif dVtNMedia >= 0 + GEO.EPS_SMALL then
|
|
nFlip0 = 75
|
|
else
|
|
nFlip0 = 25
|
|
end
|
|
-- se entrambi i versori negativi, impossibile da fare
|
|
else
|
|
nFlip0 = 0
|
|
end
|
|
-- verifico se e' lavorabile da fliped: cambio segno ai versori
|
|
dVtN1Z = -dVtN1Z
|
|
dVtN2Z = -dVtN2Z
|
|
-- se entrambi i versori positivi
|
|
if (dVtN1Z >= - 0.01 and dVtN2Z >= - 0.01) then
|
|
-- posso lavorarlo da sopra
|
|
nFlip1 = 100
|
|
-- se almeno un versore positivo
|
|
elseif (dVtN1Z >= - 0.01 or dVtN2Z >= - 0.01) then
|
|
-- calcolo media dei versori: se positiva tende verso alto
|
|
local dVtNMedia = ( dVtN1Z + dVtN2Z) / 2
|
|
if dVtNMedia >= 0 - GEO.EPS_SMALL and dVtNMedia <= 0 + GEO.EPS_SMALL then
|
|
nFlip1 = 100
|
|
elseif dVtNMedia >= 0 + GEO.EPS_SMALL then
|
|
nFlip1 = 75
|
|
else
|
|
nFlip1 = 25
|
|
end
|
|
-- se entrambi i versori negativi, impossibile da fare
|
|
else
|
|
nFlip0 = 0
|
|
end
|
|
return nFlip0, nFlip1
|
|
end
|
|
|
|
-- Classificazione del flip della feature per nesting
|
|
-- return nFlip0, nFlip1
|
|
function WPL.FlipClassify( Proc)
|
|
local nFlip0 = -1
|
|
local nFlip1 = -1
|
|
-- se 1 faccia
|
|
if Proc.Fct == 1 then
|
|
-- verifico che la normale permetta la lavorazione da sopra ed assegno punteggio di conseguenza
|
|
nFlip0, nFlip1 = VerifyVtN( Proc.Id, 0)
|
|
-- se 2 facce
|
|
elseif Proc.Fct == 2 then
|
|
-- calcolo la media delle normali delle facce ed assegno punteggio maggiore se positiva
|
|
nFlip0, nFlip1 = VerifyVtNMedia(Proc.Id, 0, 1)
|
|
-- se più di 2 facce
|
|
else
|
|
local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId)
|
|
if nFacInd == -2 then return 0, 0 end
|
|
-- se 3 facce
|
|
if Proc.Fct == 3 then
|
|
-- se forma ad U
|
|
if not nFacInd2 or nFacInd2 == 0 then
|
|
-- verifico che la normale del fondo permetta la lavorazione da sopra ed assegno punteggio di conseguenza
|
|
nFlip0, nFlip1 = VerifyVtN( Proc.Id, nFacInd)
|
|
-- se non ad U
|
|
else
|
|
-- calcolo la media delle normali delle facce di fondo ed assegno punteggio maggiore se positiva
|
|
nFlip0, nFlip1 = VerifyVtNMedia(Proc.Id, nFacInd, nFacInd2)
|
|
end
|
|
-- se 4 facce
|
|
elseif Proc.Fct == 4 then
|
|
-- se senza fondo (tunnel)
|
|
if not nFacInd or nFacInd == -1 then
|
|
-- dati delle facce
|
|
local vtN = {}
|
|
vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT)
|
|
vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT)
|
|
vtN[3] = EgtSurfTmFacetNormVersor( Proc.Id, 2, GDB_ID.ROOT)
|
|
vtN[4] = EgtSurfTmFacetNormVersor( Proc.Id, 3, GDB_ID.ROOT)
|
|
-- verifico se è lavorabile da sopra
|
|
local vtAxN = vtN[1] ^ vtN[2]
|
|
if vtAxN:isSmall() then
|
|
vtAxN = vtN[1] ^ vtN[3]
|
|
end
|
|
if ( abs( vtAxN:getZ()) >= WD.NZ_MINA) then
|
|
-- calcolo la media dei versori delle facce
|
|
local dVtNMedia = ( vtN[1]:getZ() + vtN[2]:getZ() + vtN[3]:getZ() + vtN[4]:getZ()) / 4
|
|
if dVtNMedia >= 0 - GEO.EPS_SMALL and dVtNMedia <= 0 + GEO.EPS_SMALL then
|
|
nFlip0 = 100
|
|
nFlip1 = 100
|
|
elseif dVtNMedia >= 0 + GEO.EPS_SMALL then
|
|
nFlip0 = 75
|
|
nFlip1 = 25
|
|
else
|
|
nFlip0 = 25
|
|
nFlip1 = 75
|
|
end
|
|
end
|
|
-- se con fondo
|
|
else
|
|
-- calcolo la media delle normali delle facce di fondo ed assegno punteggio maggiore se positiva
|
|
local vtN = {}
|
|
vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
if vtN[1]:getZ() == -1 or vtN[2]:getZ() == -1 then return 0, 100 end
|
|
if vtN[1]:getZ() == 1 or vtN[2]:getZ() == 1 then return 100, 0 end
|
|
nFlip0, nFlip1 = VerifyVtNMedia(Proc.Id, nFacInd, nFacInd2)
|
|
end
|
|
-- se 5 facce
|
|
elseif Proc.Fct == 5 then
|
|
-- verifico che la normale del fondo permetta la lavorazione da sopra ed assegno punteggio di conseguenza
|
|
nFlip0, nFlip1 = VerifyVtN( Proc.Id, nFacInd)
|
|
end
|
|
end
|
|
return nFlip0, nFlip1
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetOtherRegions( nPartId)
|
|
local vOthers = {}
|
|
local nOtherId = EgtGetFirstPartInRawPart( EgtGetFirstRawPart() or GDB_ID.NULL)
|
|
while nOtherId do
|
|
local nRegId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nOtherId, 'Outline') or GDB_ID.NULL)
|
|
while nRegId do
|
|
local vtN = EgtSurfFrNormVersor( nRegId, GDB_ID.ROOT)
|
|
if EgtExistsInfo( nRegId, 'REGION') and vtN and AreSameVectorApprox( vtN, Z_AX()) then
|
|
local b3Reg = EgtGetBBoxGlob( nRegId, GDB_BB.STANDARD)
|
|
if b3Reg then
|
|
table.insert( vOthers, { PartId = nOtherId, RegId = nRegId, Box = b3Reg})
|
|
end
|
|
end
|
|
nRegId = EgtGetNext( nRegId)
|
|
end
|
|
nOtherId = EgtGetNextPartInRawPart( nOtherId)
|
|
end
|
|
return vOthers
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ReorderFaces( nIdSurf, nNumFacet)
|
|
-- cerco una faccia senza precedenti
|
|
local nFirstFac
|
|
for i = 1, nNumFacet do
|
|
-- centro e normale della faccia
|
|
local ptCen, vtN = EgtSurfTmFacetCenter( nIdSurf, i - 1, GDB_ID.ROOT)
|
|
-- verifico con le altre facce
|
|
local bFoundPrec
|
|
for j = 1, nNumFacet do
|
|
if j ~= i then
|
|
-- verifico se è precedente
|
|
local bAdj, ptP1, _, _ = EgtSurfTmFacetsContact( nIdSurf, i - 1, j - 1, GDB_ID.ROOT)
|
|
if bAdj and ( vtN ^ ( ptCen - ptP1)) * Z_AX() > 0 then
|
|
bFoundPrec = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if not bFoundPrec then
|
|
nFirstFac = i
|
|
break
|
|
end
|
|
end
|
|
-- se trovata, la metto al primo posto
|
|
if nFirstFac and nFirstFac ~= 1 then
|
|
EgtSurfTmSwapFacets( nIdSurf, nFirstFac - 1, 0)
|
|
end
|
|
-- ordino le facce in modo da avere una sequenza ordinata con le normali a destra
|
|
for i = 1, nNumFacet - 1 do
|
|
-- centro e normale della faccia
|
|
local ptCen, vtN = EgtSurfTmFacetCenter( nIdSurf, i - 1, GDB_ID.ROOT)
|
|
-- cerco la successiva
|
|
for j = i + 1, nNumFacet do
|
|
-- verifico se è successiva
|
|
local bAdj, ptP1, _, _ = EgtSurfTmFacetsContact( nIdSurf, i - 1, j - 1, GDB_ID.ROOT)
|
|
if bAdj and ( vtN ^ ( ptP1 - ptCen)) * Z_AX() > 0 then
|
|
EgtSurfTmSwapFacets( nIdSurf, i, j - 1)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFaceToDel)
|
|
-- copio la superfice nel gruppo ausiliario
|
|
local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
|
|
EgtSurfTmRemoveFacet( nNewProc, nFaceToDel)
|
|
local nNumFacet = EgtSurfTmFacetCount( nNewProc)
|
|
ReorderFaces( nNewProc, nNumFacet)
|
|
return nNewProc, nNumFacet
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetFacesData( nNewProc, bOpposite, bCalclForBlade, dToolDiam, dToolMaxDepth, dToolThick, nAddGrpId, nPartId)
|
|
|
|
local nNumFacet = EgtSurfTmFacetCount( nNewProc)
|
|
local vFace = {}
|
|
-- recupero i dati di tutte le facce
|
|
for i = 1, nNumFacet do
|
|
-- indici faccia corrente e precedente
|
|
local nFac = EgtIf( bOpposite, nNumFacet - i, i - 1)
|
|
local nPrecFac
|
|
if bOpposite then
|
|
nPrecFac = EgtIf( i == 1, 0, nFac + 1)
|
|
else
|
|
nPrecFac = EgtIf( i == 1, nNumFacet - 1, i - 2)
|
|
end
|
|
-- recupero centro e normale della faccia
|
|
local ptCen, vtN = EgtSurfTmFacetCenter( nNewProc, nFac, GDB_ID.ROOT)
|
|
-- recupero le dimensioni della faccia
|
|
local _, dLen, dWidth = WL.GetFaceHvRefDim( nNewProc, nFac)
|
|
-- recupero l'angolo con la faccia precedente
|
|
local bAdj, ptLocP1, ptLocP2, dAng = EgtSurfTmFacetsContact( nNewProc, nPrecFac, nFac, GDB_ID.ROOT)
|
|
-- verifico che l'adiacenza sia veramente con il precedente (percorro con normale a destra)
|
|
if bAdj then
|
|
if ( vtN ^ ( ptLocP1 - ptCen)) * Z_AX() > 0 then
|
|
bAdj = false
|
|
end
|
|
end
|
|
-- salvo i dati
|
|
vFace[i] = { Fac = nFac, Cen = ptCen, Norm = vtN, Len = dLen, Width = dWidth, AngPrev = EgtIf( bAdj, dAng, 0)}
|
|
if bAdj then
|
|
if ptLocP1:getZ() < ptLocP2:getZ() then
|
|
vFace[i].PPrev = ptLocP1
|
|
else
|
|
vFace[i].PPrev = ptLocP2
|
|
end
|
|
end
|
|
end
|
|
-- analizzo le facce
|
|
local dMaxWidth = 0
|
|
for i = 1, #vFace do
|
|
-- aggiorno la massima larghezza
|
|
if vFace[i].Width > dMaxWidth then
|
|
dMaxWidth = vFace[i].Width
|
|
end
|
|
-- verifico l'affondamento
|
|
local dDepth = WD.CUT_EXTRA
|
|
if vFace[i].Width + WD.CUT_EXTRA > dToolMaxDepth then
|
|
dDepth = dToolMaxDepth - vFace[i].Width
|
|
end
|
|
-- lunghezza baffo
|
|
local dElev = vFace[i].Width + dDepth
|
|
local dWhisk = EgtIf( bCalclForBlade, ( dElev * sqrt( dToolDiam / dElev - 1) + WHISK_SAFE), (dToolDiam/2) + WHISK_SAFE)
|
|
-- determino la lunghezza del taglio passante e il tipo di attacco e uscita
|
|
local dLen = vFace[i].Len
|
|
local nType = 0
|
|
if vFace[i].AngPrev < -0.1 then
|
|
dLen = dLen - EgtIf( bCalclForBlade, dWhisk, 0)
|
|
nType = nType + 1
|
|
end
|
|
if vFace[EgtIf( i < nNumFacet, i + 1, 1)].AngPrev < -0.1 then
|
|
dLen = dLen - EgtIf( bCalclForBlade, dWhisk, 0)
|
|
nType = nType + 2
|
|
end
|
|
-- se lunghezza non significativa, non va inserito il taglio
|
|
if dLen < MIN_LEN_CUT then
|
|
nType = 4
|
|
end
|
|
vFace[i].Depth = dDepth
|
|
vFace[i].Whisk = dWhisk
|
|
vFace[i].Type = nType
|
|
end
|
|
-- recupero le regioni degli altri pezzi
|
|
local vOthers = GetOtherRegions( nPartId)
|
|
-- verifico i baffi sporgenti dei tagli rispetto alle altre regioni
|
|
for i = 1, #vFace do
|
|
-- verifico il baffo iniziale
|
|
if vFace[i].Type ~= 4 and ( vFace[i].Type & 1) == 0 then
|
|
-- creo il rettangolo del baffo
|
|
local vtOrt = Vector3d( vFace[i].Norm:getX(), vFace[i].Norm:getY(), 0) ; vtOrt:normalize()
|
|
local vtDir = Vector3d( vtOrt) ; vtDir:rotate( Z_AX(), -90)
|
|
local vtUp = Vector3d( vtDir) ; vtUp:rotate( vFace[i].Norm, -90)
|
|
local ptIni = vFace[i].Cen + vFace[i].Width / 2 * vtUp + ( vFace[i].Len / 2 + WHISK_OFFS) * vtDir + WHISK_OFFS * vtOrt
|
|
local ptDir = ptIni + ( vFace[i].Whisk - WHISK_OFFS) * vtDir
|
|
local ptCross = ptDir + ( dToolThick - WHISK_OFFS) * vtOrt
|
|
local WhId = EgtSurfFrRectangle3P( nAddGrpId, ptIni, ptCross, ptDir, GDB_RT.GLOB)
|
|
local b3Wh = EgtGetBBoxGlob( WhId or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
-- verifico se interferisce con gli altri pezzi
|
|
for j = 1, #vOthers do
|
|
if OverlapsXY( b3Wh, vOthers[j].Box) then
|
|
local nClass = EgtSurfFrChunkSimpleClassify( WhId, 0, vOthers[j].RegId, 0)
|
|
if nClass ~= GDB_RC.OUT then
|
|
local dLen = vFace[i].Len - vFace[i].Whisk + EgtIf( ( vFace[i].Type & 2) ~= 0, -vFace[i].Whisk, 0)
|
|
if dLen >= MIN_LEN_CUT then
|
|
vFace[i].Type = vFace[i].Type + 1
|
|
else
|
|
vFace[i].Type = 4
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
EgtErase( WhId)
|
|
end
|
|
-- verifico il baffo finale
|
|
if vFace[i].Type ~= 4 and ( vFace[i].Type & 2) == 0 then
|
|
-- creo il rettangolo del baffo
|
|
local vtOrt = Vector3d( vFace[i].Norm:getX(), vFace[i].Norm:getY(), 0) ; vtOrt:normalize()
|
|
local vtDir = Vector3d( vtOrt) ; vtDir:rotate( Z_AX(), 90)
|
|
local vtUp = Vector3d( vtDir) ; vtUp:rotate( vFace[i].Norm, 90)
|
|
local ptIni = vFace[i].Cen + vFace[i].Width / 2 * vtUp + ( vFace[i].Len / 2 + WHISK_OFFS) * vtDir + WHISK_OFFS * vtOrt
|
|
local ptDir = ptIni + ( vFace[i].Whisk - WHISK_OFFS) * vtDir
|
|
local ptCross = ptDir + ( dToolThick - WHISK_OFFS) * vtOrt
|
|
local WhId = EgtSurfFrRectangle3P( nAddGrpId, ptIni, ptCross, ptDir, GDB_RT.GLOB)
|
|
local b3Wh = EgtGetBBoxGlob( WhId or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
-- verifico se interferisce con gli altri pezzi
|
|
for j = 1, #vOthers do
|
|
if OverlapsXY( b3Wh, vOthers[j].Box) then
|
|
local nClass = EgtSurfFrChunkSimpleClassify( WhId, 0, vOthers[j].RegId, 0)
|
|
if nClass ~= GDB_RC.OUT then
|
|
local dLen = vFace[i].Len - vFace[i].Whisk + EgtIf( ( vFace[i].Type & 1) ~= 0, -vFace[i].Whisk, 0)
|
|
if dLen >= MIN_LEN_CUT then
|
|
vFace[i].Type = vFace[i].Type + 2
|
|
else
|
|
vFace[i].Type = 4
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
EgtErase( WhId)
|
|
end
|
|
end
|
|
-- eventuali stampe
|
|
for i = 1, #vFace do
|
|
local Face = vFace[i]
|
|
local sOut = 'Face '..tostring( Face.Fac)..' C'..tostring( Face.Cen)..' N'..tostring( Face.Norm)..
|
|
' L='..EgtNumToString( Face.Len, 1)..' W='..EgtNumToString( Face.Width, 1)..' Ap='..EgtNumToString( Face.AngPrev, 1)..
|
|
' D='..EgtNumToString( Face.Depth, 1)..' B='..EgtNumToString( Face.Whisk, 1)..' T='..tostring( Face.Type)
|
|
EgtOutLog( sOut, 3)
|
|
end
|
|
|
|
return vFace, dMaxWidth, nNewProc
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetTunnelDimension( nId, nPartId, nAddGrpId)
|
|
-- ottengo i versori delle 4 facce e ottengo l'orientamento del tunnel
|
|
-- recupero il numero di facce
|
|
local nFacCnt = EgtSurfTmFacetCount( nId)
|
|
-- recupero l'ingombro della trave
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
-- variabili dimensioni fessura e id faccia lunga
|
|
local dDimMin
|
|
local dDimMax
|
|
local nLongIdFace = 0
|
|
local bNegFace
|
|
local bOppoFace = false
|
|
-- ottengo il versore ortogonale
|
|
local ptN1, vtN1 = EgtSurfTmFacetCenter( nId, 0, GDB_ID.ROOT)
|
|
local _, vtN2 = EgtSurfTmFacetCenter( nId, 1, GDB_ID.ROOT)
|
|
local vtOrtho = vtN1 ^ vtN2
|
|
if vtOrtho:isSmall() then
|
|
if nFacCnt >= 3 then
|
|
_, vtN2 = EgtSurfTmFacetCenter( nId, 2, GDB_ID.ROOT)
|
|
vtOrtho = vtN1 ^ vtN2
|
|
bOppoFace = true
|
|
else
|
|
return
|
|
end
|
|
end
|
|
if vtOrtho:getZ() < -0.5 then
|
|
vtOrtho = -vtOrtho
|
|
bNegFace = true
|
|
end
|
|
-- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta la profondità della fessura
|
|
local frFc = Frame3d( ptN1, vtOrtho) ;
|
|
local bBoxLoc = EgtGetBBoxRef( nId, GDB_BB.STANDARD, frFc)
|
|
local dDepth = bBoxLoc:getDimZ()
|
|
-- mi assicuro che la Z del punto utilizzato per creare la superficie sia alla Z inferiore del bounding box locale
|
|
local ptN2 = Point3d(ptN1)
|
|
ptN2:toLoc(frFc)
|
|
ptN2 = Point3d( ptN2:getX(), ptN2:getY(), bBoxLoc:getMin():getZ() + 2*GEO.EPS_SMALL)
|
|
ptN2:toGlob(frFc)
|
|
-- creo superficie intermedia
|
|
local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN2, vtOrtho, b3Solid, GDB_ID.ROOT)
|
|
-- ritaglio la superficie con le facce della fessura
|
|
for i = 1, nFacCnt do
|
|
local ptN, vtN = EgtSurfTmFacetCenter( nId, i - 1, GDB_ID.ROOT)
|
|
EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT)
|
|
end
|
|
-- sposto la geometria trovata sulla Z minima (era su di 2 * GEO.EPS_SMALL)
|
|
EgtMove( nSurfInt, Point3d(0,0,-2*GEO.EPS_SMALL) - ORIG(), GDB_RT.GLOB)
|
|
-- mi faccio dare il contorno della superfice e la ricreo in modo più corretto
|
|
local nIdCont, nIdNum = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId)
|
|
-- elimino le entità allineate dello stesso tipo
|
|
EgtMergeCurvesInCurveCompo( nIdCont, 2*GEO.EPS_SMALL)
|
|
EgtErase(nSurfInt)
|
|
nSurfInt = EgtSurfTmByFlatContour( nAddGrpId, nIdCont, 2*GEO.EPS_SMALL)
|
|
-- elimino il contorno
|
|
EgtErase(nIdCont)
|
|
-- se normale negativa inverto
|
|
_, vtN1 = EgtSurfTmFacetCenter( nSurfInt, 0, GDB_ID.ROOT)
|
|
if vtN1:getZ() < -0.5 then EgtInvertSurf( nSurfInt) end
|
|
local _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT)
|
|
dDimMin = min( DimH, DimV)
|
|
dDimMax = max( DimH, DimV)
|
|
_, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nId, nFacCnt-1, GDB_ID.ROOT)
|
|
-- se faccia pari alla larghezza fessura
|
|
if abs(DimH - dDimMax) < GEO.EPS_SMALL or abs(DimV - dDimMax) < GEO.EPS_SMALL then
|
|
nLongIdFace = nFacCnt-1
|
|
-- altrimenti verifico anche con la faccia precedente
|
|
else
|
|
local nFaceToCheck = EgtIf( bOppoFace, nFacCnt-3, nFacCnt-2)
|
|
-- prendo le dimensioni della faccia e poi confronto con il minimo
|
|
_, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nId, nFaceToCheck, GDB_ID.ROOT)
|
|
-- se trovato con il minimo, questa seconda faccia non è la più lunga
|
|
if abs(DimH - dDimMin) < GEO.EPS_SMALL or abs(DimV - dDimMin) < GEO.EPS_SMALL then
|
|
nLongIdFace = nFacCnt-1
|
|
else
|
|
nLongIdFace = nFaceToCheck
|
|
end
|
|
end
|
|
if not dDimMax then
|
|
return dDimMin, dDimMax, dDepth, nil, nil
|
|
end
|
|
return dDimMin, dDimMax, dDepth, vtOrtho, nLongIdFace, nSurfInt
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ReorderFacesFromTab( nIdSurf, vFace)
|
|
|
|
local nFacCnt = EgtSurfTmFacetCount( nIdSurf)
|
|
for i = 1, #vFace do
|
|
for j = 1, nFacCnt do
|
|
-- ottengo punto iniziale e versore della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( nIdSurf, (j-1), GDB_ID.ROOT)
|
|
-- se versore e posizione coincidono e non corrispondono al numero faccia, faccio lo swap
|
|
if AreSameVectorExact( vFace[i].Norm, vtN) and AreSamePointEpsilon( vFace[i].Cen, ptC, 50*GEO.EPS_SMALL) then
|
|
if j - 1 ~= vFace[i].Fac then
|
|
EgtSurfTmSwapFacets( nIdSurf, vFace[i].Fac, (j-1))
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
return nIdSurf
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcInterference( nNewProc, vtExtr, ptCentr, dDiam1, dDiam2,
|
|
dTall1, dTall2, dDiam3, dTall3)
|
|
|
|
local ptCentrGrid1 = ptCentr + ( vtExtr * 0.01)
|
|
local frOriTool = Frame3d( ptCentrGrid1, vtExtr)
|
|
local bColl1 = EgtCDeConeSolid( frOriTool, dDiam1/2, dDiam2/2, dTall1, nNewProc, 0, GDB_RT.GLOB)
|
|
if bColl1 then return true end
|
|
local ptCentrGrid2 = ptCentr + ( vtExtr * ( dTall1 + 0.01))
|
|
frOriTool = Frame3d( ptCentrGrid2, vtExtr)
|
|
local bColl2 = EgtCDeCylSolid( frOriTool, dDiam2/2, (dTall2-dTall1), nNewProc, 0, GDB_RT.GLOB)
|
|
if bColl2 then return true end
|
|
local ptCentrGrid3 = ptCentr + ( vtExtr * ( dTall2 + 0.01))
|
|
frOriTool = Frame3d( ptCentrGrid3, vtExtr)
|
|
local bColl3 = EgtCDeCylSolid( frOriTool, dDiam3/2, (dTall3-dTall2), nNewProc, 0, GDB_RT.GLOB)
|
|
if bColl3 then return true end
|
|
-- restituisco risultato controllo collisioni
|
|
return false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeLocalSurf( ptP1, ptP2, ptP3, nAddGrpId)
|
|
|
|
if not ptP1 or not ptP2 or not ptP3 then
|
|
return nil
|
|
end
|
|
|
|
local pAuxId = {}
|
|
local nAuxId, AuxId
|
|
nAuxId = EgtLine( nAddGrpId, ptP1, ptP2, GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
nAuxId = EgtLine( nAddGrpId, ptP2, ptP3, GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
nAuxId = EgtLine( nAddGrpId, ptP3, ptP1, GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
-- trasformo in percorso
|
|
if #pAuxId ~= 3 then
|
|
return nil
|
|
end
|
|
AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true)
|
|
-- se non c'é il percorso esco
|
|
if not AuxId then
|
|
return nil
|
|
end
|
|
-- creo la superfice piana
|
|
local nidFace = EgtSurfTmByFlatContour( nAddGrpId, AuxId, 0.01)
|
|
if not nidFace then
|
|
EgtErase(AuxId)
|
|
return nil
|
|
end
|
|
-- se normale negativa inverto
|
|
local _, vtN1 = EgtSurfTmFacetCenter( nidFace, 0, GDB_ID.ROOT)
|
|
if vtN1:getZ() < -0.5 then EgtInvertSurf( nidFace) end
|
|
|
|
EgtErase(AuxId)
|
|
return nidFace
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AddMillCornerMachining( nPartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId,
|
|
dToolDiam, dThick, sMilling, dOffsAng, dDepthMach,
|
|
bThruThick, dThSurf, dDiam1, dDiam2, dTall1,
|
|
dTall2, dDiam3, dTall3, bMakeLocSurf, vFace)
|
|
-- variabili costruzione geometria
|
|
local pAuxId = {}
|
|
local nAuxId
|
|
local ptApPoint
|
|
local AuxId
|
|
local nNewProcLoc
|
|
-- se devo creare superfice locale
|
|
if bMakeLocSurf then
|
|
-- creo superfice locale o esco
|
|
local nSurfToAdd = MakeLocalSurf( tFacAdj[7], tFacAdj[8], tFacAdj[9], nAddGrpId)
|
|
if nSurfToAdd then
|
|
local nFacCntPre = EgtSurfTmFacetCount( nNewProc)
|
|
-- creo copia del percorso principale e gli aggiungo la nuova faccia
|
|
nNewProcLoc = EgtCopyGlob( nNewProc, nAddGrpId)
|
|
nNewProcLoc = EgtSurfTmBySewing( nAddGrpId, {nNewProcLoc,nSurfToAdd} , true)
|
|
-- riordino le facce
|
|
nNewProcLoc = ReorderFacesFromTab( nNewProcLoc, vFace)
|
|
-- acquisisco il numero della faccia
|
|
local nFacCnt = EgtSurfTmFacetCount( nNewProcLoc)
|
|
nFacInd = nFacCnt - 1
|
|
else
|
|
local sErr = 'Cannot make local bottom surface'
|
|
EgtOutLog( sErr)
|
|
return true, ''
|
|
end
|
|
else
|
|
nNewProcLoc = nNewProc
|
|
end
|
|
-- prendo il primo versore
|
|
local _, vtN1 = EgtSurfTmFacetCenter( nNewProcLoc, nFacInd, GDB_ID.ROOT)
|
|
local _, vtN2 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[1], GDB_ID.ROOT)
|
|
local _, vtN3 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[2], GDB_ID.ROOT)
|
|
-- trovo il punto sulla superfice di riferimento
|
|
local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[1], GDB_ID.ROOT)
|
|
local _, ptLocP3, ptLocP4, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[2], GDB_ID.ROOT)
|
|
-- se ho creato faccia locale su copia superficie, cancella la copia
|
|
if bMakeLocSurf then
|
|
EgtErase( nNewProcLoc)
|
|
end
|
|
local nIdIniPoint
|
|
local nIdEndPoint
|
|
if ptLocP1 and ptLocP2 then
|
|
if ( dist( ptLocP1, tFacAdj[4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[4]) < GEO.EPS_SMALL) then
|
|
nIdEndPoint = 4
|
|
nIdIniPoint = 5
|
|
elseif ( dist( ptLocP1, tFacAdj[5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[5]) < GEO.EPS_SMALL) then
|
|
nIdEndPoint = 5
|
|
nIdIniPoint = 4
|
|
end
|
|
end
|
|
-- versore direzione
|
|
local vtExtr = tFacAdj[nIdIniPoint] - tFacAdj[nIdEndPoint]
|
|
vtExtr:normalize()
|
|
-- versore direzione di uscita
|
|
local vtExtrExit
|
|
-- inserisco le prime tre linee
|
|
if nIdIniPoint and nIdEndPoint then
|
|
-- se fresatura da sotto salto la lavorazione
|
|
if vtExtr:getZ() < WD.DRILL_VZ_MIN then
|
|
local sErr = 'Error : Impossible insert clean corner from bottom'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- sommo i tre versori per avere una direzione media
|
|
vtExtrExit = vtN2 + vtN3
|
|
vtExtrExit:normalize()
|
|
-- se tipo 1 calcolo angolo tilt di 45°
|
|
if nTypeConeCut == 1 then
|
|
vtExtr = vtExtrExit + Z_AX()
|
|
-- altrimenti tipo 2, calcolo angolo tilt di 33° (dalla verticale)
|
|
else
|
|
vtExtr = vtExtrExit + Vector3d(0,0,1.539865)
|
|
end
|
|
vtExtr:normalize()
|
|
local vtCheck = Vector3d(vtExtr)
|
|
-- se ho un offset angolare ruoto il percorso
|
|
if abs(dOffsAng) > 100 * GEO.EPS_SMALL then
|
|
vtCheck:rotate( Z_AX(), dOffsAng)
|
|
end
|
|
-- controllo se c'è collisione con le facce della superfice
|
|
if nTypeConeCut == 1 and CalcInterference( nNewProc, vtCheck, tFacAdj[nIdEndPoint] + Point3d( 0, 0, -dDepthMach), dDiam1, dDiam2,
|
|
dTall1, dTall2, dDiam3, dTall3) then
|
|
local sErr = 'Collision detect from clean corner tool and surface'
|
|
EgtOutLog( sErr)
|
|
return true, ''
|
|
end
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdIniPoint], tFacAdj[nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
-- se uso utensile cono 60°
|
|
if nTypeConeCut == 1 then
|
|
-- se offset angolare valido e/o negativo creo il baffo precedente
|
|
if dOffsAng < ( 100 * GEO.EPS_SMALL) then
|
|
-- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro
|
|
if dist( tFacAdj[nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then
|
|
ptApPoint = ptLocP2
|
|
else
|
|
ptApPoint = ptLocP1
|
|
end
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdEndPoint] + Point3d( 0, 0, -dDepthMach), ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB)
|
|
local dLenTrimExt = dist( tFacAdj[nIdEndPoint], ptApPoint) - (( dToolDiam/2) + 0.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 + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB)
|
|
-- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata
|
|
if abs(dOffsAng) > 100 * GEO.EPS_SMALL then
|
|
EgtRotate( nAuxId, tFacAdj[nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB)
|
|
end
|
|
-- prendo il nuovo punto finale
|
|
ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + Point3d( 0, 0, dDepthMach)
|
|
else
|
|
-- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata
|
|
if abs(dOffsAng) > 100 * GEO.EPS_SMALL then
|
|
EgtRotate( nAuxId, tFacAdj[nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB)
|
|
end
|
|
end
|
|
table.insert( pAuxId, nAuxId)
|
|
-- creo linea di ritorno
|
|
nAuxId = EgtLine( nAddGrpId, ptApPoint + Point3d( 0, 0, -dDepthMach), tFacAdj[nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
end
|
|
end
|
|
end
|
|
-- inserisco le ultime tre linee
|
|
-- trovo il secondo punto sulla superfice di riferimento
|
|
ptLocP1, ptLocP2 = ptLocP3, ptLocP4
|
|
if ptLocP1 and ptLocP2 then
|
|
-- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro
|
|
if dist( tFacAdj[nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then
|
|
ptApPoint = ptLocP2
|
|
else
|
|
ptApPoint = ptLocP1
|
|
end
|
|
-- se uso utensile cono 60°
|
|
if nTypeConeCut == 1 then
|
|
-- se offset angolare valido e/o negativo creo il baffo precedente
|
|
if dOffsAng > -( 100 * GEO.EPS_SMALL) then
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdEndPoint] + Point3d( 0, 0, -dDepthMach), ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB)
|
|
local dLenTrimExt = dist( tFacAdj[nIdEndPoint], ptApPoint) - (( dToolDiam/2) + 0.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 + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB)
|
|
-- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata
|
|
if abs(dOffsAng) > 100 * GEO.EPS_SMALL then
|
|
EgtRotate( nAuxId, tFacAdj[nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB)
|
|
end
|
|
-- prendo il nuovo punto finale
|
|
ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + Point3d( 0, 0, dDepthMach)
|
|
else
|
|
-- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata
|
|
if abs(dOffsAng) > 100 * GEO.EPS_SMALL then
|
|
EgtRotate( nAuxId, tFacAdj[nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB)
|
|
end
|
|
end
|
|
table.insert( pAuxId, nAuxId)
|
|
-- creo linea di ritorno
|
|
nAuxId = EgtLine( nAddGrpId, ptApPoint + Point3d( 0, 0, -dDepthMach), tFacAdj[nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
end
|
|
-- ultima linea di distacco (5mm in direzione utensile)
|
|
local pEnd = tFacAdj[nIdEndPoint] + Point3d( 0, 0, -dDepthMach) + ( 5 * vtExtr)
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdEndPoint] + Point3d( 0, 0, -dDepthMach), pEnd, GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
else
|
|
-- linea di distacco (2mm in direzione utensile)
|
|
local pEnd = tFacAdj[nIdEndPoint] + ( 2 * vtExtr)
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdEndPoint], pEnd, GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
-- ultima linea di risalita in Z
|
|
local pIni = pEnd
|
|
pEnd = pIni + ( dThick * Z_AX())
|
|
nAuxId = EgtLine( nAddGrpId, pIni, pEnd, GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
end
|
|
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)
|
|
-- se ho un offset angolare ruoto il percorso
|
|
if abs(dOffsAng) > 100 * GEO.EPS_SMALL then
|
|
EgtRotate( AuxId, tFacAdj[nIdEndPoint], Z_AX(), dOffsAng, GDB_RT.GLOB)
|
|
end
|
|
-- inserisco la lavorazione
|
|
local sName = 'Clean_' .. ( EgtGetName( nNewProc) or tostring( nNewProc))
|
|
local nMchId = WM.AddMachining( nNewProc, sName, sMilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', nPartId)
|
|
-- se flag lavorazione spessore passante setto la nota per spostarla dopo i tagli di lama
|
|
if bThruThick and nTypeConeCut == 1 then
|
|
EgtSetInfo( nMchId, 'MOVE_AFTER', 1)
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ AuxId, -1}})
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_ZP
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4)
|
|
-- allungo inizio e fine di 10mm
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10)
|
|
-- setto affondamento 0
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, 0)
|
|
-- forzo lato correzione a centrato
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER)
|
|
-- leggo eventuali note esistenti della lavorazione
|
|
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
|
|
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'VMRS', 0)
|
|
-- aggiungo alle note massima elevazione
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( 0.0, 1))
|
|
-- scrivo le note della lavorazione
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
if not EgtApplyMachining( 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
|
|
end
|
|
end
|
|
|
|
return true, ''
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AddMillCorner( nTypeConeCut, vFace, Proc, nRawId, b3Raw,
|
|
dToolDiam, nAddGrpId, dThick, nMasterNewProc, dDepthMach,
|
|
bThruThick)
|
|
|
|
local sMilling, dMaxDepth
|
|
-- se ripresa angolo con fresa cono 60° con ripresa
|
|
if nTypeConeCut == 1 then
|
|
-- recupero la lavorazione di fresatura
|
|
sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner60')
|
|
if not sMilling then
|
|
local sErr = 'Error : CleanCorner 60 not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- se ripresa angolo con fresa cono piccola senza ripresa
|
|
else
|
|
sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner30')
|
|
if not sMilling then
|
|
local sErr = 'Error : CleanCorner 30 not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dMillDiam = 20
|
|
local dMillTotDiam = 20
|
|
local dMillDiamTh = 20
|
|
local dToolLength = 20
|
|
local dThickTool = 20
|
|
local dSideAng = 0
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh
|
|
dMillTotDiam = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) or dMillTotDiam
|
|
dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAng
|
|
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
|
|
dThickTool = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dThickTool
|
|
dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth -- qui è la distanza dal portautensile
|
|
-- calcolo il secondo diametro del cono
|
|
dMillTotDiam = dMillDiam + ( abs(dThickTool) * tan(dSideAng)) * 2
|
|
end
|
|
end
|
|
-- copio la feature nel layer di appoggio
|
|
local nNewProc
|
|
if nMasterNewProc then
|
|
nNewProc = nMasterNewProc
|
|
else
|
|
nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
|
|
end
|
|
local nFacCnt = EgtSurfTmFacetCount( nNewProc)
|
|
local nFacInd, dDimMin, dDimMax, dDepth, nSurfInt
|
|
local bMakeLocSurf
|
|
-- RIMUOVERE
|
|
if false and nFacCnt <= 4 then
|
|
-- ottengo le dimensioni apertura, la normale e la faccia inferiore
|
|
dDimMin, dDimMax, dDepth, _, _, nSurfInt = GetTunnelDimension( nNewProc, Proc.PartId, nAddGrpId)
|
|
if nSurfInt then
|
|
-- uso la dimensione minima anche nel caso che la cava sborda perchè la lavorazione potrebbe collidere con un pezzo limitrofo
|
|
local dMinWidth = dDimMin
|
|
nNewProc = EgtSurfTmBySewing( nAddGrpId, {nNewProc,nSurfInt} , true)
|
|
-- riordino le facce
|
|
nNewProc = ReorderFacesFromTab( nNewProc, vFace)
|
|
-- acquisisco il numero della faccia
|
|
nFacCnt = EgtSurfTmFacetCount( nNewProc)
|
|
nFacInd = nFacCnt - 1
|
|
else
|
|
local sErr = 'Error : cannot create base surface'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- FINE PARTE DA RIMUOVERE
|
|
else
|
|
bMakeLocSurf = true
|
|
end
|
|
-- verifico se ciclo chiuso
|
|
local bClosed = ( abs( vFace[1].AngPrev) > 0.1)
|
|
-- ciclo di inserimento delle fresate sulle facce del contorno in esame
|
|
local i = 1
|
|
-- se faccia finale con fine non lavorato, forzo partenza da prima faccia non tutta saltata (tipo 4)
|
|
if bClosed and ( vFace[#vFace].Type == 4 or ( vFace[#vFace].Type & 2) ~= 0) then
|
|
while i <= #vFace and vFace[i].Type == 4 do
|
|
i = i + 1
|
|
end
|
|
end
|
|
-- se facce tutte da saltare, parto dall'inizio
|
|
local bAllType4 = ( i > #vFace)
|
|
if bAllType4 or bClosed then i = 1 end
|
|
while i <= #vFace do
|
|
-- se tutta la faccia o la sua fine senza taglio, inserisco una fresatura
|
|
if ( vFace[i].Type & 2) ~= 0 or vFace[i].Type == 4 then
|
|
-- variabili costruzione geometria (nFace1, nFace2, tFacAdj)
|
|
local nFace1 = vFace[i].Fac
|
|
-- ricavo i tre punti per eventuale superficie locale
|
|
local ptLoc1, ptLoc2, ptLoc3
|
|
-- aggiungo geometria
|
|
local j = EgtIf( i < #vFace, i + 1, EgtIf( bClosed, 1, nil))
|
|
if not j then return true end
|
|
local nFace2 = vFace[j].Fac
|
|
-- punto in comune tra le due facce (punto precedente della faccia [j])
|
|
ptLoc1 = vFace[j].PPrev
|
|
-- punto precedente (punto precedente della faccia [i])
|
|
if vFace[i].PPrev then
|
|
ptLoc3 = vFace[i].PPrev
|
|
else
|
|
ptLoc3 = Point3d( vFace[i].Cen:getX(), vFace[i].Cen:getY(), ptLoc1:getZ())
|
|
end
|
|
-- punto successivo ( precedente della faccia successiva)
|
|
local k = EgtIf( j < #vFace, j + 1, EgtIf( bClosed, 1, nil))
|
|
-- se è un percorso aperto prendo il punto medio della seconda faccia come punto locale 2
|
|
if not k then
|
|
ptLoc2 = Point3d( vFace[j].Cen:getX(), vFace[j].Cen:getY(), ptLoc1:getZ())
|
|
else
|
|
ptLoc2 = vFace[k].PPrev
|
|
end
|
|
-- ricavo i punti e l'angolo interno
|
|
local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( nNewProc, nFace1, nFace2, GDB_ID.ROOT)
|
|
-- se punti validi e angolo è interno e non è quasi piatto e >= 90 creo istanza
|
|
local tFacAdj = {}
|
|
if ptP1 and ptP2 and dAng < 0 and dAng < -6 and dAng > EgtIf( nTypeConeCut == 1, -(90 + 10 * GEO.EPS_SMALL), -(180-dAngleSmall + 10 * GEO.EPS_SMALL)) then
|
|
local dLen = dist( ptP1, ptP2)
|
|
tFacAdj = { nFace1, nFace2, dLen, ptP1, ptP2, dAng, ptLoc1, ptLoc2, ptLoc3}
|
|
end
|
|
-- se ho un elemento creo percorso o percorsi in base al tipo di cono e all'apertura dall'angolo rispetto ai 90°
|
|
-- con una tolleranza di 2 gradi
|
|
if #tFacAdj > 0 then
|
|
if nTypeConeCut == 1 and bMakeTwinCut and (dAng + 90) > 2 then
|
|
local dAngOffs = (dAng + 90) / 2
|
|
-- primo taglio
|
|
local bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId,
|
|
dToolDiam, dThick, sMilling, -dAngOffs, dDepthMach,
|
|
bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool),
|
|
dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace)
|
|
if not bOk then return bOk, sErr end
|
|
-- secondo taglio
|
|
bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId,
|
|
dToolDiam, dThick, sMilling, dAngOffs, dDepthMach,
|
|
bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool),
|
|
dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace)
|
|
if not bOk then return bOk, sErr end
|
|
-- altrimenti ho un solo percorso
|
|
else
|
|
local bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId,
|
|
dToolDiam, dThick, sMilling, 0, dDepthMach,
|
|
bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool),
|
|
dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace)
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
end
|
|
end
|
|
-- passo alla successiva
|
|
i = i + 1
|
|
end
|
|
-- cancello la copia della superfice
|
|
if nNewProc then
|
|
EgtErase(nNewProc)
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByChainSaw( Proc, nFacet, nRawId, b3Raw, dElev, dH, dV)
|
|
local sWarn
|
|
-- dati della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
-- Recupero le facce adiacenti alla principale
|
|
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacet)[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, nFacet, vAdj[i], GDB_ID.ROOT)
|
|
local dLen = dist( ptP1, ptP2)
|
|
local vtAdjN = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT)
|
|
if dLen > dMaxLen - 1 and vtAdjN:getZ() > -0.1 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
|
|
if not nFacAdj then
|
|
local sErr = 'Error : long adjacent face not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Recupero la lavorazione
|
|
local sSawing = WM.FindSawing( 'Sawing')
|
|
if not sSawing then
|
|
local sErr = 'Error : chainsawing 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
|
|
-- Calcolo uso faccia
|
|
local nFaceUse = WL.GetNearestParalOpposite( vtN)
|
|
-- Calcolo angolo 3° asse rot (da direz. utensile)
|
|
local sRot3Ang = 'A1=180'
|
|
if WD.GetChainSawBlockedAxis then
|
|
sRot3Ang = WD.GetChainSawBlockedAxis( 1)
|
|
end
|
|
-- Calcolo angoli iniziali suggeriti
|
|
local sStartAngs
|
|
if WD.GetChainSawStartAngs then
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT)
|
|
sStartAngs = WD.GetChainSawStartAngs( vtN2)
|
|
end
|
|
-- Lati chiusi
|
|
local bOpenStart = false
|
|
local bOpenEnd = false
|
|
-- Verifico se necessarie più passate
|
|
local nStep = ceil( ( dV - 10 * 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 = WM.AddMachining( Proc, sName, sSawing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchFId, 'Part', Proc.PartId)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}})
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- 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))
|
|
-- imposto angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, sRot3Ang)
|
|
-- imposto angoli iniziali suggeriti
|
|
if sStartAngs then
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, sStartAngs)
|
|
end
|
|
-- imposto offset radiale
|
|
local dOffs = ( i - 1) * dStep
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dOffs)
|
|
-- se necessario, limito l'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) .. ')'
|
|
local dDepth = dMaxDepth - dElev
|
|
EgtOutLog( sWarn)
|
|
EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH '..EgtNumToString( dDepth, 1))
|
|
end
|
|
-- leggo eventuali note esistenti della lavorazione
|
|
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
|
|
-- imposto elevazione
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( dElev, 2))
|
|
-- scrivo le note della lavorazione
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
elseif EgtIsMachiningEmpty() then
|
|
_, sWarn = EgtGetMachMgrWarning( 0)
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sWarn
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- restituisce true se la lavorazione potrebbe danneggiare le parti limitrofe
|
|
local function IsMachiningDamagingOtherParts( Proc, dMillDiameter, nRawId)
|
|
local bIsMachiningDamagingOtherParts = false
|
|
-- box da estendere in tutte le direzioni, compreso angolo cieco
|
|
local b3ProcExtended = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD)
|
|
-- punto minimo e massimo assoluti del box
|
|
local ptMin = b3ProcExtended:getMin()
|
|
local ptMax = b3ProcExtended:getMax()
|
|
-- estensione aggiunta ai box
|
|
local dBoxExtensionLength = dMillDiameter / 2 + 5
|
|
-- check box verso X-
|
|
if Proc.AffectedFaces.Left then
|
|
local vtMove = Vector3d( -dBoxExtensionLength, 0, 0)
|
|
ptMin:move( vtMove)
|
|
end
|
|
-- check box verso X+
|
|
if Proc.AffectedFaces.Right then
|
|
local vtMove = Vector3d( dBoxExtensionLength, 0, 0)
|
|
ptMax:move( vtMove)
|
|
end
|
|
-- check box verso Y-
|
|
if Proc.AffectedFaces.Front then
|
|
local vtMove = Vector3d( 0, -dBoxExtensionLength, 0)
|
|
ptMin:move( vtMove)
|
|
end
|
|
-- check box verso Y+
|
|
if Proc.AffectedFaces.Back then
|
|
local vtMove = Vector3d( 0, dBoxExtensionLength, 0)
|
|
ptMax:move( vtMove)
|
|
end
|
|
-- estendo il box in direzione X e Y e verifico se interseca altre parti
|
|
b3ProcExtended:Add( ptMin)
|
|
b3ProcExtended:Add( ptMax)
|
|
local nPartId = EgtGetFirstPartInRawPart( nRawId)
|
|
while nPartId do
|
|
local nBoxSolidId = EgtGetFirstNameInGroup( nPartId, 'Box')
|
|
local b3Solid = EgtGetBBoxGlob( nBoxSolidId or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
b3Solid:expand( - 10 * GEO.EPS_SMALL)
|
|
if ( nPartId ~= Proc.PartId) and OverlapsXY( b3ProcExtended, b3Solid) then
|
|
bIsMachiningDamagingOtherParts = true
|
|
end
|
|
nPartId = EgtGetNextPartInRawPart( nPartId)
|
|
end
|
|
|
|
return bIsMachiningDamagingOtherParts
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByMill( Proc, nFacet, nOthFac, nRawId, b3Raw, dSideDist)
|
|
-- dati della faccia e dell'altra
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId)
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
local dDiam = min( dH, dV)
|
|
local _, vtRef = EgtSurfTmFacetCenter( Proc.Id, nOthFac, GDB_ID.ROOT)
|
|
-- recupero la lavorazione
|
|
local sMilling = WM.FindMilling( 'Side')
|
|
if Proc.Double and Proc.Double == 2 then
|
|
local sMillingBackup = sMilling
|
|
sMilling = WM.FindMilling( 'Side', nil, nil, nil, nil, nil, nil, nil, 'H1')
|
|
if not WM.IsMachiningOkForDouble( sMilling) then
|
|
Proc.Double = 0
|
|
sMilling = sMillingBackup
|
|
end
|
|
end
|
|
if not sMilling then
|
|
local sErr = 'Error : Side not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dMillDiam = 20
|
|
local dMillLen = 10
|
|
local dMillTotLen = 30
|
|
local dMaxDepth = 0
|
|
local dThDiam = 100
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
|
|
dMillLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dMillLen
|
|
dMillTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) or dMillTotLen
|
|
dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) or dMaxDepth
|
|
dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam
|
|
end
|
|
end
|
|
if dMillDiam < dDiam or dMaxDepth < dElev then
|
|
local sErr = 'Error : Side Elevation too big'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local dMillExtra = dMillTotLen - dMillLen
|
|
if Proc.Box:getMin():getZ() - dMillExtra < b3Raw:getMin():getZ() - 10 * GEO.EPS_SMALL then
|
|
local sErr = 'Error : Tool collide with table'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- inserisco la lavorazione di contornatura
|
|
local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = WM.AddMachining( Proc, sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchFId, 'Part', Proc.PartId)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacet}})
|
|
-- sistemo i parametri di attacco e uscita
|
|
local dAddLen = ( WD.MID_GAP or 50) - ( WD.MID_SIC or 5)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) -- -dMillDiam/2 + dAddLen)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dSideDist + WD.CUT_SIC)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) -- -dMillDiam/2 + dAddLen)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, dSideDist + WD.CUT_SIC)
|
|
-- setto inversione in base al workside
|
|
local bIsWorkSideRight = ( EgtGetMachiningParam( MCH_MP.WORKSIDE) == MCH_MILL_WS.RIGHT)
|
|
local bInvert = false
|
|
if bIsWorkSideRight then
|
|
bInvert = true
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_ZP
|
|
if AreSameOrOppositeVectorApprox( vtN, Z_AX()) then
|
|
nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XM)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- imposto modo di lavorare la faccia
|
|
local nFaceUse = WL.GetNearestOrthoOpposite( vtRef, vtN)
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- leggo eventuali note esistenti della lavorazione
|
|
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
|
|
-- se lavorazione in doppio aggiungo le rispettive note
|
|
if Proc.Double and Proc.Double == 2 then
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'DOUBLE', Proc.Double)
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MirrorAx', Proc.MirrorAx)
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'DeltaZ', Proc.MirrorDeltaZ)
|
|
end
|
|
-- scrivo le note della lavorazione
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, dMaxDepthOnSide, bEnablePreMill, bMachFromDn, dAng, bAsEnablePreMill, nSinglePass, bExcludeFinishing, bDoubleCustomMach)
|
|
local sWarn
|
|
-- dati della faccia principale (la più verticale)
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId)
|
|
-- dati della faccia più orizzontale
|
|
local nOtherFacet = abs( nFacet - 1)
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nOtherFacet, GDB_ID.ROOT)
|
|
local dElevOtherFacet = WL.GetFaceElevation( Proc.Id, nOtherFacet, nRawId)
|
|
-- se lap joint 2 facce dal basso e angolo negativo
|
|
local bExcludeSideMill = Proc.Fct == 2 and vtN:getZ() < -0.01 and vtN2:getZ() < -0.01
|
|
-- dimensioni della faccia principale
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
local dThick = min( dH, dV)
|
|
local frFace = Frame3d( ptC, vtN)
|
|
local b3Proc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFace)
|
|
local dSideElev = b3Proc:getDimZ()
|
|
local sMilling
|
|
-- se ho lavorazione custom
|
|
if sCustomMach then
|
|
sMilling = sCustomMach
|
|
-- se avevo stabilito che la customMach non era adatta al double, setto per non specchiare
|
|
if not bDoubleCustomMach then Proc.Double = 0 end
|
|
-- altrimenti la cerco
|
|
else
|
|
sMilling = WM.FindMilling( 'SideGroove', nil, nil, nil, nil, min( dH, dV))
|
|
-- se Proc è settata per essere specchiata cerco la lavorazione adatta e verifico possa essere effettivamente specchiata
|
|
if Proc.Double and Proc.Double == 2 then
|
|
local sMillOnSideBackup = sMilling
|
|
sMilling = WM.FindMilling( 'SideGroove', nil, nil, nil, nil, min( dH, dV), nil, nil, 'H1')
|
|
if not WM.IsMachiningOkForDouble( sMilling) then
|
|
Proc.Double = 0
|
|
sMilling = sMillOnSideBackup
|
|
end
|
|
end
|
|
end
|
|
if not sMilling then
|
|
local sErr = 'Error : SideGroove not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local dGrooveMinZ = max( b3Raw:getMin():getZ(), Proc.Box:getMin():getZ())
|
|
local dRawMaxZ = b3Raw:getMax():getZ()
|
|
-- recupero i dati dell'utensile
|
|
local dMillDiam = 20
|
|
local dMillLen = 10
|
|
local dMillTotLen = 30
|
|
local dMaxMat = 0
|
|
local dMillDiamTh = 999
|
|
local dMillDiamThStem = 0
|
|
local dMillLenTh = 0
|
|
local dSideStep = 0
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
|
|
dMillLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dMillLen
|
|
dMillTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) or dMillTotLen
|
|
-- di default uso il diametro "alto" del portautensile come diametro del gambo
|
|
dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh
|
|
dMillDiamThStem = EgtTdbGetCurrToolParam( MCH_TP.STEMDIAM) or dMillDiamThStem
|
|
dMillLenTh = EgtTdbGetCurrToolThLength() or dMillLenTh
|
|
dSideStep = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDESTEP', 'd') or dSideStep
|
|
if ( EgtTdbGetCurrToolParam( MCH_TP.TYPE) & MCH_TF.SAWBLADE) ~= 0 then
|
|
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dMaxMat
|
|
if not dMaxDepthOnSide or dMaxDepthOnSide < 0.1 then
|
|
dMaxDepthOnSide = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT)
|
|
end
|
|
else
|
|
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
|
|
if not dMaxDepthOnSide or dMaxDepthOnSide < 0.1 then
|
|
dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd')
|
|
end
|
|
end
|
|
-- se riesco a lavorare il sottosquadro senza arrivare alla parte larga del portautensile uso la sidedepth o il diametro stretto del portautensile come diametro del gambo
|
|
if ( dMillTotLen - dMillLenTh) > ( abs( dRawMaxZ - dGrooveMinZ) + 1) then
|
|
if dMaxDepthOnSide and dMaxDepthOnSide > 0 then
|
|
dMillDiamTh = dMillDiam - dMaxDepthOnSide * 2
|
|
elseif dMillDiamThStem > 0 then
|
|
dMillDiamTh = dMillDiamThStem
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- se profondità ribasso è maggiore della capacità di sottosquadro dell'utensile
|
|
if ( dElev > 0.5 * ( dMillDiam - dMillDiamTh) - 10 * GEO.EPS_SMALL) then
|
|
if ( not bEnablePreMill and ( bMachFromDn or Proc.Fct > 2)) then
|
|
local sErr = 'Error : Side Elevation (' .. dElev .. ') bigger than max tool side depth (' .. ( 0.5 * ( dMillDiam - dMillDiamTh)) ..')'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
elseif Proc.Double then
|
|
Proc.Double = 0
|
|
end
|
|
end
|
|
local dMillExtra = dMillTotLen - dMillLen
|
|
if Proc.Box:getMin():getZ() - dMillExtra < b3Raw:getMin():getZ() - 10 * GEO.EPS_SMALL then
|
|
local sErr = 'Error : Tool collide with table'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
if Proc.Fct == 2 and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + 100 * GEO.EPS_SMALL and dMaxMat > dThick + 10 * GEO.EPS_SMALL then
|
|
local sErr = 'Error : Tool thickness is too big'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- dimensioni della testa
|
|
local dHeadMaxWidth = 250
|
|
local dHeadMinWidth = 160
|
|
local dHeadMinWidthHeight = 30
|
|
-- se la testa scende sotto al limite superiore del grezzo e non c'è sufficiente capacità di sottosquadro
|
|
-- controllo disattivato se move after
|
|
if WD.SIDEMILL_BEFORE and not ( bEnablePreMill or bAsEnablePreMill) and
|
|
( ( dMillTotLen < ( abs( dRawMaxZ - dGrooveMinZ) + 10 * GEO.EPS_SMALL) and ( dElev > 0.5 * ( dMillDiam - dHeadMinWidth) - 10 * GEO.EPS_SMALL)) or
|
|
( dMillTotLen + dHeadMinWidthHeight < ( abs( dRawMaxZ - dGrooveMinZ) + 10 * GEO.EPS_SMALL) and ( dElev > 0.5 * ( dMillDiam - dHeadMaxWidth) - 10 * GEO.EPS_SMALL))) then
|
|
local sErr = 'Error : Tool too short, head will collide with rawpart'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- verifico che la lavorazione sia passante dal grezzo
|
|
local dLongGorge = max( dH, dV)
|
|
local dExtraLongExtPlus = 0
|
|
local dExtraLongExtNeg = 0
|
|
local dExtraLongIni = 0
|
|
local dExtraLongEnd = 0
|
|
local bStartPos
|
|
local bInvertMach
|
|
local nModifyLeadInOut = 0
|
|
local nFace2ndFace
|
|
local dMaxDistToOut = EgtIf( bMachFromDn, 1800, 300)
|
|
-- se orientato lungo la Y
|
|
if abs( vtN:getX()) > 0.866 then
|
|
dExtraLongExtPlus = abs( Proc.Box:getMax():getY() - b3Raw:getMax():getY())
|
|
dExtraLongExtNeg = abs( Proc.Box:getMin():getY() - b3Raw:getMin():getY())
|
|
if dLongGorge + dMillDiamTh < b3Raw:getDimY() then
|
|
nModifyLeadInOut = 1
|
|
-- se non può sbordare da nessuna parte do errore
|
|
if dExtraLongExtPlus > dMaxDistToOut and dExtraLongExtNeg > dMaxDistToOut and dElev > dMaxDistToOut then
|
|
local sErr = 'Error : Not possible insert SideMill groove machining'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- se non sborda solo dai lati
|
|
if dElev < dExtraLongExtPlus and dElev < dExtraLongExtNeg then
|
|
nModifyLeadInOut = 2
|
|
end
|
|
end
|
|
-- se la distanza superiore è minore della distanza inferiore segno di partire dalla parte positiva
|
|
if dExtraLongExtPlus < dExtraLongExtNeg then
|
|
bStartPos = true
|
|
end
|
|
-- se normale su X positivo parte dall'alto
|
|
if vtN:getX() > 0.866 then
|
|
-- se deve partire dalla parte negativa setto il flag di inversione lavorazione
|
|
if not bStartPos then
|
|
bInvertMach = true
|
|
dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtNeg + dMillDiam/2 + 5)
|
|
dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtPlus + dMillDiam/2 + 5)
|
|
else
|
|
dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5)
|
|
dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5)
|
|
end
|
|
-- asseggno lato di lavoro seconda faccia
|
|
if bMachFromDn then
|
|
nFace2ndFace = MCH_MILL_FU.ORTUP_LEFT
|
|
else
|
|
nFace2ndFace = MCH_MILL_FU.ORTHO_LEFT
|
|
end
|
|
-- altrimenti normale su X negativa parte dal basso
|
|
else
|
|
-- se deve partire dalla parte positiva setto il flag di inversione lavorazione
|
|
if bStartPos then
|
|
bInvertMach = true
|
|
dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5)
|
|
dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5)
|
|
else
|
|
dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtNeg + dMillDiam/2 + 5)
|
|
dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtPlus + dMillDiam/2 + 5)
|
|
end
|
|
-- asseggno lato di lavoro seconda faccia
|
|
if bMachFromDn then
|
|
nFace2ndFace = MCH_MILL_FU.ORTUP_RIGHT
|
|
else
|
|
nFace2ndFace = MCH_MILL_FU.ORTHO_RIGHT
|
|
end
|
|
end
|
|
-- altrimenti orientato lungo la X
|
|
elseif abs( vtN:getY()) > 0.866 then
|
|
dExtraLongExtPlus = abs( Proc.Box:getMax():getX() - b3Raw:getMax():getX())
|
|
dExtraLongExtNeg = abs( Proc.Box:getMin():getX() - b3Raw:getMin():getX())
|
|
if dLongGorge + dMillDiamTh < b3Raw:getDimX() then
|
|
nModifyLeadInOut = 1
|
|
-- se non può sbordare da nessuna parte do errore
|
|
if dExtraLongExtPlus > dMaxDistToOut and dExtraLongExtNeg > dMaxDistToOut and dElev > dMaxDistToOut then
|
|
local sErr = 'Error : Not possible insert SideMill groove machining'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- se non sborda solo dai lati
|
|
if dElev < dExtraLongExtPlus and dElev < dExtraLongExtNeg then
|
|
nModifyLeadInOut = 2
|
|
end
|
|
end
|
|
-- se la distanza positiva è minore della distanza negativa segno di partire dalla parte positiva
|
|
if dExtraLongExtPlus < dExtraLongExtNeg then
|
|
bStartPos = true
|
|
end
|
|
-- se normale su Y positivo parte da sinistra (parte negativa)
|
|
if vtN:getY() > 0.866 then
|
|
-- se deve partire dalla parte positiva setto il flag di inversione lavorazione
|
|
if bStartPos then
|
|
bInvertMach = true
|
|
dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5)
|
|
dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5)
|
|
else
|
|
dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtNeg + dMillDiam/2 + 5)
|
|
dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtPlus + dMillDiam/2 + 5)
|
|
end
|
|
-- assegno lato di lavoro seconda faccia
|
|
if bMachFromDn then
|
|
nFace2ndFace = MCH_MILL_FU.ORTUP_FRONT
|
|
else
|
|
nFace2ndFace = MCH_MILL_FU.ORTHO_FRONT
|
|
end
|
|
-- altrimenti normale su Y negativa parte da destra (parte positiva)
|
|
else
|
|
-- se deve partire dalla parte negativa setto il flag di inversione lavorazione
|
|
if not bStartPos then
|
|
bInvertMach = true
|
|
dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtNeg + dMillDiam/2 + 5)
|
|
dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtPlus + dMillDiam/2 + 5)
|
|
else
|
|
dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5)
|
|
dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5)
|
|
end
|
|
-- assegno lato di lavoro seconda faccia
|
|
if bMachFromDn then
|
|
nFace2ndFace = MCH_MILL_FU.ORTUP_BACK
|
|
else
|
|
nFace2ndFace = MCH_MILL_FU.ORTHO_BACK
|
|
end
|
|
end
|
|
end
|
|
if not bEnablePreMill and not bAsEnablePreMill then
|
|
dExtraLongIni = 0
|
|
dExtraLongEnd = 0
|
|
end
|
|
-- se ho abilitato la lavorazione di fresatura per garantire passaggio gambo utensile, inserisco la lavorazione
|
|
local bThroughRaw = false
|
|
if bEnablePreMill then
|
|
-- verifico se feature e' passante
|
|
if ((Proc.Box:getMin():getX() < ( b3Raw:getMin():getX() + 50)) and (Proc.Box:getMax():getX() > ( b3Raw:getMax():getX() - 50))) or
|
|
((Proc.Box:getMin():getY() < ( b3Raw:getMin():getY() + 50)) and (Proc.Box:getMax():getY() > ( b3Raw:getMax():getY() - 50))) then
|
|
bThroughRaw = true
|
|
end
|
|
|
|
-- recupero la lavorazione di taglio
|
|
local sCuttingGorge = WM.FindCutting( 'Standard')
|
|
if not sCuttingGorge then
|
|
local sErr = 'Error : Sawblade not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
-- acquisisco dati utensile lama
|
|
local dSawThickness = 0
|
|
local dSawDiam = 0
|
|
if EgtMdbSetCurrMachining( sCuttingGorge) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dSawThickness = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThickness
|
|
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
|
|
end
|
|
end
|
|
|
|
-- calcolo larghezza canale
|
|
local dGorgeWidth = dMillDiam
|
|
-- verifico se elevazione minore per fare meno tagli
|
|
if dElev + 2 * WD.COLL_SIC < dGorgeWidth then
|
|
dGorgeWidth = max( dElev + 2 * WD.COLL_SIC, 0)
|
|
end
|
|
|
|
-- sottraggo lato esterno lapjoint per ottenere larghezza netta del gorge
|
|
dGorgeWidth = dGorgeWidth - dSideElev
|
|
|
|
-- calcolo quanti passi devo fare in larghezza per scaricare l'area di impegno utensile
|
|
local nNumStep = ceil( ( dGorgeWidth) / ( WD.SAWGORGE_INTERAX or 100))
|
|
-- calcolo larghezza passate
|
|
local dC = 0
|
|
if ( nNumStep - 1) > 0 then
|
|
dC = ( dGorgeWidth) / ( nNumStep)
|
|
else
|
|
nNumStep = 1
|
|
end
|
|
|
|
-- dati utensile fresa piccola
|
|
local dMillDiamFirst = 0
|
|
local dMaxMatFirst = 0
|
|
local bMillInvert = false
|
|
local bSawInvertSE = false
|
|
|
|
-- se non passante, aggiungo fresatura area della fresa
|
|
if not bThroughRaw and nNumStep - 1 > 0 then
|
|
local SquareId -- Id della composita da fresare
|
|
local dSawShortening = sqrt( b3Raw:getDimZ() * ( dSawDiam - b3Raw:getDimZ())) -- da calcolare in base a raggio lama e spessore grezzo
|
|
-- gruppo ausiliario
|
|
local nAddGrpId = WL.GetAddGroup( Proc.PartId)
|
|
-- disegno quadrato di fresatura
|
|
local p3Start
|
|
-- se orientato lungo la Y (direzione)
|
|
if abs( vtN:getX()) > 0.866 then
|
|
local dStartX = EgtIf( vtN:getX() > 0.866, Proc.Box:getMax():getX(), Proc.Box:getMin():getX())
|
|
local dStartY = EgtIf( bStartPos, Proc.Box:getMin():getY(), Proc.Box:getMax():getY())
|
|
p3Start = Point3d( dStartX, dStartY, Proc.Box:getMin():getZ())
|
|
local vtNPerp = Vector3d( vtN)
|
|
vtNPerp:rotate(-Z_AX(), 90 * EgtIf( bStartPos, 1, -1) * EgtIf( vtN:getX() > 0.866, 1, -1))
|
|
local FirstLineId = EgtLinePVL( nAddGrpId, p3Start, vtNPerp, dMillDiam / 2 , GDB_RT.GLOB) -- Y_AX()
|
|
local SecondLineId = EgtLinePVL( nAddGrpId, EgtEP( FirstLineId, GDB_RT.GLOB), vtN, dMillDiam - dSideElev, GDB_RT.GLOB) -- -X_AX()
|
|
local dThirdLineLen = min( (dMillDiam / 2) + ( Proc.Box:getMax():getY() - Proc.Box:getMin():getY()), dSawShortening + 10)
|
|
local ThirdLineId = EgtLinePVL( nAddGrpId, EgtEP( SecondLineId, GDB_RT.GLOB), -vtNPerp, dThirdLineLen, GDB_RT.GLOB) -- -Y_AX()
|
|
local FourthLineId = EgtLinePVL( nAddGrpId, EgtEP( ThirdLineId, GDB_RT.GLOB), -vtN, dMillDiam -dSideElev , GDB_RT.GLOB) -- X_AX()
|
|
SquareId = EgtCurveCompo( nAddGrpId, { FirstLineId, SecondLineId, ThirdLineId, FourthLineId})
|
|
bMillInvert = EgtIf( vtN:getX() > 0.866, not (bStartPos or false), bStartPos or false)
|
|
bSawInvertSE = EgtIf( vtN:getX() > 0.866, bStartPos or false, not (bStartPos or false))
|
|
-- altrimenti orientato lungo la X
|
|
elseif abs( vtN:getY()) > 0.866 then
|
|
local dStartX = EgtIf( bStartPos, Proc.Box:getMin():getX(), Proc.Box:getMax():getX())
|
|
local dStartY = EgtIf( vtN:getY() > 0.866, Proc.Box:getMax():getY(), Proc.Box:getMin():getY())
|
|
p3Start = Point3d( dStartX, dStartY, Proc.Box:getMin():getZ())
|
|
local vtNPerp = Vector3d( vtN)
|
|
vtNPerp:rotate(-Z_AX(), 90 * EgtIf( bStartPos, -1, 1) * EgtIf( vtN:getY() > 0.866, 1, -1))
|
|
local FirstLineId = EgtLinePVL( nAddGrpId, p3Start, vtNPerp, dMillDiam / 2 , GDB_RT.GLOB) -- Y_AX()
|
|
local SecondLineId = EgtLinePVL( nAddGrpId, EgtEP( FirstLineId, GDB_RT.GLOB), vtN, dMillDiam -dSideElev, GDB_RT.GLOB) -- -X_AX()
|
|
local dThirdLineLen = min( (dMillDiam / 2) + ( Proc.Box:getMax():getX() - Proc.Box:getMin():getX()), dSawShortening + 10)
|
|
local ThirdLineId = EgtLinePVL( nAddGrpId, EgtEP( SecondLineId, GDB_RT.GLOB), -vtNPerp, dThirdLineLen, GDB_RT.GLOB) -- -Y_AX()
|
|
local FourthLineId = EgtLinePVL( nAddGrpId, EgtEP( ThirdLineId, GDB_RT.GLOB), -vtN, dMillDiam -dSideElev , GDB_RT.GLOB) -- X_AX()
|
|
SquareId = EgtCurveCompo( nAddGrpId, { FirstLineId, SecondLineId, ThirdLineId, FourthLineId})
|
|
bMillInvert = EgtIf( vtN:getY() > 0.866, bStartPos or false, not (bStartPos or false))
|
|
bSawInvertSE = EgtIf( vtN:getY() > 0.866, not (bStartPos or false), bStartPos or false)
|
|
end
|
|
|
|
-- recupero la lavorazione
|
|
local sMillingGorge = WM.FindMilling( 'Gorge', nil, nil, nil, 80)
|
|
if not sMillingGorge then
|
|
local sErr = 'Error : Gorge not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- acquisisco dati utensile
|
|
if EgtMdbSetCurrMachining( sMillingGorge) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMillDiamFirst = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiamFirst
|
|
dMaxMatFirst = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMatFirst
|
|
end
|
|
end
|
|
-- inserisco la lavorazione di fresatura
|
|
local sNameGorge = 'Gorge_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. tostring( nFacet)
|
|
local nMchFId = WM.AddMachining( Proc, sNameGorge, sMillingGorge)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sNameGorge .. '-' .. sMillingGorge
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( SquareId)
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_ZP
|
|
if abs( vtN:getZ()) < GEO.EPS_SMALL then
|
|
nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- imposto modo di lavorare la faccia
|
|
local nFaceUse = WL.GetNearestParalOpposite( Z_AX())
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto elevazione e step
|
|
local dStep = EgtGetMachiningParam( MCH_MP.STEP)
|
|
if dStep < GEO.EPS_SMALL then dStep = dMaxMat end
|
|
---- se sto lavorando la gola centrale setto l'elevazione e l'affondamento
|
|
--if nSinglePass and nSinglePass == 0 then
|
|
-- local dZElev = b3Raw:getDimZ()
|
|
-- local dDepth = Proc.Box:getMax():getZ() - b3Raw:getMin():getZ()
|
|
-- EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dZElev, 3) .. ';')
|
|
-- EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
--end
|
|
EgtSetMachiningParam( MCH_MP.STEP, dStep)
|
|
-- imposto invert in base al lato fresa
|
|
local bWorkSide = EgtGetMachiningParam( MCH_MP.WORKSIDE)
|
|
if bWorkSide == MCH_MILL_WS.RIGHT then
|
|
bMillInvert = not bMillInvert
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.INVERT, bMillInvert)
|
|
-- aggiungo allungamenti iniziali e finali
|
|
EgtSetMachiningParam( EgtIf( bMillInvert, MCH_MP.STARTADDLEN, MCH_MP.ENDADDLEN), -dMillDiamFirst / 2 - dSawThickness / 2)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
|
|
-- inserisco la lavorazione
|
|
local nNm = 0
|
|
-- passi di allargamento
|
|
for i = 1, nNumStep - 1 do
|
|
nNm = nNm + 1
|
|
-- inserisco la lavorazione di taglio sfrido gorge
|
|
local sNameGorge = 'GorgeCut_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. tostring( nFacet) .. '_' .. tostring( nNm)
|
|
local nMchFId = WM.AddMachining( Proc, sNameGorge, sCuttingGorge)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sNameGorge .. '-' .. sCuttingGorge
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacet}})
|
|
|
|
EgtSetInfo( nMchFId, 'Part', Proc.PartId)
|
|
-- assegno invert
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- assegno affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, 0)
|
|
-- assegno il lato di lavoro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) -- EgtIf( bMillInvert, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT))
|
|
-- assegno l'attacco e l'uscita
|
|
if not bThroughRaw and bSawInvertSE then
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.CENT)
|
|
-- aggiungo allungamento finale
|
|
if not bThroughRaw then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, ( dMillDiam / 2) - ( dMillDiamFirst / 2))
|
|
end
|
|
elseif not bThroughRaw and not bSawInvertSE then
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LO.CENT)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LI.STRICT)
|
|
-- aggiungo allungamento finale
|
|
if not bThroughRaw then
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( dMillDiam / 2) - ( dMillDiamFirst / 2))
|
|
end
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LO.CENT)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LI.CENT)
|
|
end
|
|
-- aggiungo l'offset laterale
|
|
EgtSetMachiningParam( MCH_MP.OFFSL, ( dSideElev - dSawThickness + ( dC * ( i))))
|
|
-- nessun criterio per il braccio è necessario
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE)
|
|
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se la groove è rivolta verso il basso (-85°) lavoro a salire con step negativo
|
|
local bUpwardMilling = false
|
|
if Proc.Fct == 2 and vtN2:getZ() < -0.996 then
|
|
bUpwardMilling = true
|
|
end
|
|
|
|
-- step extra in caso di doppio con mix rabbet dal basso e dall'alto, per eliminare la lamina che potrebbe rimanere
|
|
if Proc.Double and Proc.Double == 2 and Proc.Topology == 'Rabbet' and
|
|
not ( Proc.AffectedFaces.Bottom and Proc.Mirror.AffectedFaces.Bottom) and not ( Proc.AffectedFaces.Top and Proc.AffectedFaces.Bottom) then
|
|
-- determino a quale delle due feature applicare la lavorazione
|
|
local bProcVsMirrorToCopy = true
|
|
local nFacetToMachine = nFacet
|
|
if Proc.AffectedFaces.Bottom then
|
|
bProcVsMirrorToCopy = false
|
|
for i = 1, Proc.Mirror.Fct do
|
|
local vtNMirror = Proc.Mirror.Face[i].VtN
|
|
if AreOppositeVectorApprox( vtN, vtNMirror) then
|
|
nFacetToMachine = Proc.Mirror.Face[i].Id
|
|
break
|
|
end
|
|
end
|
|
end
|
|
local nAddGrpId = WL.GetAddGroup( EgtIf( bProcVsMirrorToCopy, Proc.PartId, Proc.Mirror.PartId))
|
|
local nNewProc = EgtCopyGlob( EgtIf( bProcVsMirrorToCopy, Proc.Id, Proc.Mirror.Id), nAddGrpId) or GDB_ID.NULL
|
|
local NewProc = { Id = nNewProc, PartId = EgtIf( bProcVsMirrorToCopy, Proc.PartId, Proc.Mirror.PartId)}
|
|
-- lavorazione
|
|
local sName = 'PreSideMill_' .. EgtGetName( NewProc.Id) or tostring( NewProc.Id)
|
|
local nMchFId = WM.AddMachining( NewProc, sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchFId, 'Part', NewProc.PartId)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ NewProc.Id, nFacetToMachine}})
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_NEAR
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- imposto modo di lavorare la faccia
|
|
local nFaceUse = WL.GetNearestParalOpposite( Z_AX())
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto elevazione e step
|
|
local dDepth = 5
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
EgtSetMachiningParam( MCH_MP.STEP, dElev)
|
|
-- setto il lato di lavoro standard
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- setto allungamenti iniziali e finali
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd)
|
|
-- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita
|
|
if dElev > ( 0.5 * dMillDiam) then
|
|
-- setto allungamenti perpendicolari
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, 0)
|
|
end
|
|
-- se richiesto, setto la nota per spostare la lavorazione alla fine
|
|
if not WD.SIDEMILL_BEFORE then
|
|
EgtSetInfo( nMchFId, 'MOVE_AFTER', 1)
|
|
end
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
-- provo a invertire posizione braccio porta testa
|
|
nSCC = MCH_SCC.ADIR_FAR
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- se faccio lo step extra e ho rimosso la lamina, in doppio lavorerò dal basso verso l'alto
|
|
bUpwardMilling = true
|
|
end
|
|
|
|
-- lavorazione
|
|
local dStepOri
|
|
if not bExcludeSideMill then
|
|
local nSideStep = 1
|
|
if dSideStep > 0 and not ( bEnablePreMill or bAsEnablePreMill) and nModifyLeadInOut < 1 then
|
|
nSideStep = ceil( dElev / dSideStep)
|
|
dSideStep = max( dElev / nSideStep, 0)
|
|
end
|
|
for i = 1, nSideStep do
|
|
-- inserisco la lavorazione di ribasso o gola
|
|
local sName = EgtIf( bEnablePreMill ~= nil, 'SideMill_', 'Mill_') .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = WM.AddMachining( Proc, sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchFId, 'Part', Proc.PartId)
|
|
-- se ho abilitato la lavorazione di lama per garantire passaggio utensile, setto la nota per spostare la fresatura dopo i tagli di lama
|
|
if bEnablePreMill or bAsEnablePreMill then
|
|
EgtSetInfo( nMchFId, 'MOVE_AFTER', 1)
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacet}})
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_NEAR
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- imposto modo di lavorare la faccia
|
|
local nFaceUse = WL.GetNearestParalOpposite( Z_AX())
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto elevazione e step
|
|
local dStep = EgtGetMachiningParam( MCH_MP.STEP)
|
|
dStepOri = dStep
|
|
if dStep < GEO.EPS_SMALL then dStep = 0.75 * dMaxMat end
|
|
local nStep = ceil( ( dThick - dMaxMat) / dStep)
|
|
dStep = max( ( dThick - dMaxMat) / max( nStep, 1), 0)
|
|
local dMaxElev = max( ( nStep + 1) * dStep - GEO.EPS_SMALL, 0)
|
|
if nSinglePass and nSinglePass > 0 then
|
|
dStep = 0
|
|
if nSinglePass == 1 then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat)
|
|
end
|
|
end
|
|
if bUpwardMilling then
|
|
dStep = -dStep
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.STEP, dStep)
|
|
-- leggo eventuali note esistenti della lavorazione
|
|
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
|
|
-- aggiungo alle note massima elevazione
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( dMaxElev, 3))
|
|
-- se lavorazione in doppio aggiungo le rispettive note
|
|
if Proc.Double and Proc.Double == 2 then
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'DOUBLE', Proc.Double)
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MirrorAx', Proc.MirrorAx)
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'DeltaZ', Proc.MirrorDeltaZ)
|
|
end
|
|
-- scrivo le note della lavorazione
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- setto il lato di lavoro standard
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- setto offset radiale per gestire le eventuali passate in orizzontale
|
|
local dRadialOffset = dSideStep * ( nSideStep - i)
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dRadialOffset)
|
|
-- modifico ingressi e uscita
|
|
-- se ho inserito il pretaglio modifico
|
|
if bEnablePreMill or bAsEnablePreMill then
|
|
if nModifyLeadInOut > 0 then
|
|
-- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita
|
|
if dElev > ( 0.5 * dMillDiam) then
|
|
if nModifyLeadInOut == 1 then
|
|
-- setto il tipo di passo a una via
|
|
EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.ONEWAY)
|
|
-- modifico il tipo di uscita
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.PERP_TG)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 0)
|
|
-- modifico dati supplementari uscita
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, 0.5)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, -( dLongGorge + dExtraLongIni + dExtraLongEnd))
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dElev)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, dElev)
|
|
end
|
|
end
|
|
-- setto allungamenti iniziali e finali
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd)
|
|
if bInvertMach then
|
|
-- setto il lato di lavoro invertito
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
end
|
|
else
|
|
-- setto allungamenti iniziali e finali
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd)
|
|
-- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita
|
|
if dElev > ( 0.5 * dMillDiam) then
|
|
-- setto allungamenti perpendicolari
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, 0)
|
|
end
|
|
end
|
|
-- se richiesto, setto la nota per spostare la lavorazione alla fine
|
|
if not WD.SIDEMILL_BEFORE then
|
|
EgtSetInfo( nMchFId, 'MOVE_AFTER', 1)
|
|
end
|
|
else
|
|
if nModifyLeadInOut > 0 then
|
|
-- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita
|
|
if dElev > ( 0.5 * dMillDiam) then
|
|
-- setto il tipo di passo a una via
|
|
EgtSetMachiningParam( MCH_MP.STEPTYPE, 1)
|
|
end
|
|
if bInvertMach then
|
|
-- setto il lato di lavoro invertito
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
end
|
|
end
|
|
-- setto allungamenti iniziali e finali
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd)
|
|
-- se ho passate orizzontali riduco l'eventuale allungamento settato dall'utente
|
|
local dLiPerp = EgtGetMachiningParam( MCH_MP.LIPERP)
|
|
local dLoPerp = EgtGetMachiningParam( MCH_MP.LOPERP)
|
|
if dLiPerp > 0 then
|
|
dLiPerp = dLiPerp - dRadialOffset
|
|
end
|
|
if dLoPerp > 0 then
|
|
dLoPerp = dLoPerp - dRadialOffset
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dLiPerp)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, dLoPerp)
|
|
-- se richiesto, setto la nota per spostare la lavorazione alla fine
|
|
if not WD.SIDEMILL_BEFORE then
|
|
EgtSetInfo( nMchFId, 'MOVE_AFTER', 1)
|
|
end
|
|
end
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
-- provo a invertire posizione braccio porta testa
|
|
nSCC = MCH_SCC.ADIR_FAR
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
end
|
|
else
|
|
sWarn = 'Warning in LapJoint : upside down groove with obtuse angle not completed'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
|
|
-- verifico se devo lavorare anche la seconda faccia basandomi sul valore dell'angolo interno
|
|
if dAng and dAng > -90 + 10 * GEO.EPS_SMALL and not bExcludeFinishing then
|
|
-- inserisco la lavorazione di contornatura
|
|
local sName = 'Mill_Oth_Fac_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = WM.AddMachining( Proc, sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchFId, 'Part', Proc.PartId)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nOtherFacet}})
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_ZP
|
|
if AreSameOrOppositeVectorApprox( vtN2, Z_AX()) then
|
|
nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- imposto modo di lavorare la faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFace2ndFace)
|
|
local dMaxElev = dMaxMat
|
|
local dStepOtherFace = 0
|
|
local dDepthOtherFace = dMaxMat
|
|
if Proc.Fct == 2 and abs( vtN2:getZ()) > 0.99 and abs( vtN2:getZ()) < 1.01 then
|
|
dStepOtherFace = dStepOri or EgtGetMachiningParam( MCH_MP.STEP)
|
|
if dStepOtherFace < GEO.EPS_SMALL then dStepOtherFace = 0.75 * dMaxMat end
|
|
local nStepOtherFace = ceil( ( dElevOtherFacet - dMaxMat) / dStepOtherFace)
|
|
dStepOtherFace = max( ( dElevOtherFacet - dMaxMat) / max( nStepOtherFace, 1), 0)
|
|
dMaxElev = max( ( nStepOtherFace + 1) * dStepOtherFace - GEO.EPS_SMALL, 0)
|
|
dDepthOtherFace = dElevOtherFacet
|
|
end
|
|
if bUpwardMilling then
|
|
dStepOtherFace = -dStepOtherFace
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.STEP, dStepOtherFace)
|
|
-- leggo eventuali note esistenti della lavorazione
|
|
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
|
|
-- aggiungo alle note massima elevazione
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( dMaxElev, 3))
|
|
-- scrivo le note della lavorazione
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
if bMachFromDn then
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepthOtherFace)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- modifico ingressi e uscita
|
|
-- se ho inserito il pretaglio modifico
|
|
if bEnablePreMill or bAsEnablePreMill then
|
|
if nModifyLeadInOut > 0 then
|
|
-- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita
|
|
if dElev > ( 0.5 * dMillDiam) then
|
|
-- setto il tipo di passo a una via
|
|
EgtSetMachiningParam( MCH_MP.STEPTYPE, 1)
|
|
-- modifico il tipo di uscita
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 5)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 0)
|
|
-- modifico dati supplementari uscita
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, 0.5)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, -( dLongGorge + dExtraLongIni + dExtraLongEnd))
|
|
end
|
|
-- setto allungamenti iniziali e finali
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd)
|
|
if bInvertMach then
|
|
-- setto il lato di lavoro invertito
|
|
if bMachFromDn then
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
end
|
|
else
|
|
-- setto allungamenti iniziali e finali
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd)
|
|
-- Invece del numero di passi in sgrossatura confronto il raggio fresa con l'elevazione dalla normale
|
|
-- per vedere se devo modificare l'uscita
|
|
-- if nNumStep > 1 then
|
|
if dElev > ( 0.5 * dMillDiam) then
|
|
-- setto allungamenti perpendicolari
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, 0)
|
|
end
|
|
end
|
|
-- se richiesto, setto la nota per spostare la lavorazione alla fine
|
|
if bEnablePreMill or bAsEnablePreMill or not WD.SIDEMILL_BEFORE then
|
|
EgtSetInfo( nMchFId, 'MOVE_AFTER', 1)
|
|
end
|
|
else
|
|
if nModifyLeadInOut > 0 then
|
|
-- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita
|
|
if dElev > ( 0.5 * dMillDiam) then
|
|
-- setto il tipo di passo a una via
|
|
EgtSetMachiningParam( MCH_MP.STEPTYPE, 1)
|
|
end
|
|
if bInvertMach then
|
|
-- setto il lato di lavoro invertito
|
|
if bMachFromDn then
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
end
|
|
end
|
|
-- setto allungamenti iniziali e finali
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd)
|
|
-- se richiesto, setto la nota per spostare la lavorazione alla fine
|
|
if not WD.SIDEMILL_BEFORE then
|
|
EgtSetInfo( nMchFId, 'MOVE_AFTER', 1)
|
|
end
|
|
end
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
elseif bExcludeSideMill then
|
|
local sErr = 'Feature not machinable by orientation'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
return true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- trova la migliore lavorazione tasca in base a diametro utensile, elevazione, doppio e eventuale interferenza di parti vicine
|
|
-- se necessario forza la tasca a chiusa
|
|
local function VerifyPocket( Proc, nFacet, dElev, nRawId)
|
|
|
|
local bForceClosedPocket = false
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
-- verifico se la feature è sul bordo (non ci sono altri pezzi davanti alla tasca). Se è sul bordo, l'utensile potrà attaccare da fuori.
|
|
local bIsFeatureOnEdge = ( Proc.Topology == 'Groove' and Proc.Fct == 4 and Proc.DistanceToNearestParts.Front > b3Raw:getDimY())
|
|
|
|
-- trovo il massimo diametro utensile ammissibile per la tasca
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
local dStartDiameter = min( dH, dV)
|
|
local dMaxDiameter = dStartDiameter
|
|
-- se una sola faccia posso usare un utensile più grande della faccia
|
|
if Proc.Fct == 1 then
|
|
dMaxDiameter = 2 * dMaxDiameter
|
|
end
|
|
-- se forma ad L posso usare un utensile più grande della faccia
|
|
local bIsL = ( Proc.Fct == 2 or WL.TestElleShape3( Proc.Id, Proc.Fct) or WL.TestElleShape4( Proc.Id, Proc.Fct) == 2)
|
|
if bIsL then
|
|
dMaxDiameter = 2 * dMaxDiameter
|
|
end
|
|
-- se forma ad U riduco il diametro se necessario
|
|
local bIsU = ( Proc.Fct == 3 and not WL.TestElleShape3( Proc.Id, Proc.Fct))
|
|
if bIsU then
|
|
-- prendo la linea di base
|
|
local dMiddleFacetLength = 0
|
|
if abs( dElev - dH) < 1 and abs( dElev - dV) > 1 then
|
|
dMiddleFacetLength = dV
|
|
elseif abs( dElev - dV) < 1 and abs( dElev - dH) > 1 then
|
|
dMiddleFacetLength = dH
|
|
end
|
|
if dMiddleFacetLength > dMaxDiameter then
|
|
dMaxDiameter = min( 2 * dMaxDiameter, dMiddleFacetLength)
|
|
end
|
|
end
|
|
-- in presenza di angoli interni, limito secondo impostazione globale il diametro massimo utensile
|
|
if Proc.Fct == 3 and bIsL then
|
|
dMaxDiameter = min( dMaxDiameter, WD.MAXDIAM_POCK_CORNER or 1000)
|
|
elseif Proc.Fct >= 4 then
|
|
dMaxDiameter = min( dMaxDiameter, WD.MAXDIAM_POCK_CORNER or 1000)
|
|
end
|
|
|
|
-- verifico la distanza minima dalle parti vicine e nel caso il FindPocketing limiterà il diametro massimo dell'utensile
|
|
local dDistanceToNearestPart = GEO.INFINITO
|
|
if Proc.AffectedFaces.Front then
|
|
dDistanceToNearestPart = Proc.DistanceToNearestParts.Front
|
|
end
|
|
if Proc.AffectedFaces.Back then
|
|
dDistanceToNearestPart = min( dDistanceToNearestPart, Proc.DistanceToNearestParts.Back)
|
|
end
|
|
if Proc.AffectedFaces.Left then
|
|
dDistanceToNearestPart = min( dDistanceToNearestPart, Proc.DistanceToNearestParts.Left)
|
|
end
|
|
if Proc.AffectedFaces.Right then
|
|
dDistanceToNearestPart = min( dDistanceToNearestPart, Proc.DistanceToNearestParts.Right)
|
|
end
|
|
-- se la distanza è inferiore ad un valore minimo forzo la tasca chiusa per evitare che la ricerca utensile fallisca
|
|
local dMinToolDiameter = 25
|
|
if dDistanceToNearestPart < dMinToolDiameter / 2 - 10 * GEO.EPS_SMALL then
|
|
bForceClosedPocket = true
|
|
dDistanceToNearestPart = dMaxDiameter
|
|
end
|
|
|
|
local bExcludeNoTipFeed = ( Proc.Topology == 'Pocket')
|
|
-- recupero la lavorazione
|
|
local bUseDElevToFindPocketing = true
|
|
local sPocketing = WM.FindPocketing( 'Pocket', dMaxDiameter, dElev, nil, nil, bExcludeNoTipFeed, dDistanceToNearestPart)
|
|
-- se tasca troppo profonda cerco senza elevazione e limiterò la profondità
|
|
if not sPocketing then
|
|
bUseDElevToFindPocketing = false
|
|
sPocketing = WM.FindPocketing( 'Pocket', dMaxDiameter, nil, nil, nil, bExcludeNoTipFeed, dDistanceToNearestPart)
|
|
end
|
|
local dMillDiam = 20
|
|
local dMaxDepth = 0
|
|
local dThDiam = 100
|
|
local sTuuid
|
|
-- se lavorazione trovata verifico eventuale doppio, raccolgo i dati utensile e verifico collisioni dell'utensile con altre parti
|
|
if sPocketing then
|
|
-- se doppio cerco una lavorazione adatta
|
|
if Proc.Double and Proc.Double == 2 then
|
|
local sPocketingBackup = sPocketing
|
|
sPocketing = WM.FindPocketing( 'Pocket', dMaxDiameter, EgtIf( bUseDElevToFindPocketing, dElev, nil), nil, 'H1', true, dDistanceToNearestPart)
|
|
if not WM.IsMachiningOkForDouble( sPocketing) then
|
|
Proc.Double = 0
|
|
sPocketing = sPocketingBackup
|
|
end
|
|
end
|
|
-- recupero diametro utensile
|
|
if EgtMdbSetCurrMachining( sPocketing) then
|
|
sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
|
|
end
|
|
end
|
|
-- verifico se la lavorazione (o il suo eventuale mirror) potrebbe danneggiare le parti limitrofe e devo quindi forzare una tasca chiusa
|
|
local bIsMachiningDamagingOtherParts = IsMachiningDamagingOtherParts( Proc, dMillDiam, nRawId)
|
|
if bIsMachiningDamagingOtherParts then
|
|
bForceClosedPocket = true
|
|
end
|
|
-- disattivo il doppio se devo forzare una tasca chiusa ma l'altra no
|
|
if Proc.Double and Proc.Double > 0 then
|
|
local bIsMirrorMachiningDamagingOtherParts = IsMachiningDamagingOtherParts( Proc.Mirror, dMillDiam, nRawId)
|
|
if bIsMachiningDamagingOtherParts ~= bIsMirrorMachiningDamagingOtherParts then
|
|
Proc.Double = 0
|
|
end
|
|
end
|
|
-- altrimenti diametro utensile troppo piccolo: devo forzare tasca chiusa
|
|
else
|
|
bForceClosedPocket = true
|
|
end
|
|
|
|
-- se tasca chiusa cerco lavorazione con diametro massimo pari a dimensione tasca e riverifico per eventuale doppio
|
|
if bForceClosedPocket then
|
|
dMaxDiameter = dStartDiameter
|
|
bUseDElevToFindPocketing = true
|
|
sPocketing = WM.FindPocketing( 'Pocket', dMaxDiameter, dElev, nil, nil, bExcludeNoTipFeed, dDistanceToNearestPart)
|
|
if not sPocketing then
|
|
bUseDElevToFindPocketing = false
|
|
sPocketing = WM.FindPocketing( 'Pocket', dMaxDiameter, nil, nil, nil, bExcludeNoTipFeed, dDistanceToNearestPart)
|
|
end
|
|
-- se doppio cerco una lavorazione adatta
|
|
if Proc.Double and Proc.Double == 2 then
|
|
local sPocketingBackup = sPocketing
|
|
sPocketing = WM.FindPocketing( 'Pocket', dMaxDiameter, EgtIf( bUseDElevToFindPocketing, dElev, nil), nil, 'H1', true, dDistanceToNearestPart)
|
|
if not WM.IsMachiningOkForDouble( sPocketing) then
|
|
Proc.Double = 0
|
|
sPocketing = sPocketingBackup
|
|
end
|
|
end
|
|
end
|
|
|
|
-- recupero dati utensile
|
|
if sPocketing and EgtMdbSetCurrMachining( sPocketing) then
|
|
sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
|
|
dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) or dMaxDepth
|
|
dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam
|
|
end
|
|
end
|
|
|
|
return sPocketing, bForceClosedPocket, bIsFeatureOnEdge, sTuuid, dMillDiam, dMaxDepth, dThDiam
|
|
end
|
|
---------------------------------------------------------------------
|
|
local function MakeByPocketing( Proc, nFacet, nRawId, b3Raw, bCheckQPar)
|
|
-- dati della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId)
|
|
-- gruppo ausiliario
|
|
local nAddGrpId = WL.GetAddGroup( Proc.PartId)
|
|
local nNewProc = RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFacet)
|
|
-- cerco lavorazione adatta e recupero i dati utensile
|
|
local sPocketing, bForceClosedPocket, bIsFeatureOnEdge, sTuuid, dMillDiam, dMaxDepth, dThDiam = VerifyPocket( Proc, nFacet, dElev, nRawId)
|
|
if not sPocketing then
|
|
local sErr = 'Error : pocketing not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = WM.AddMachining( Proc, sName, sPocketing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchFId, 'Part', Proc.PartId)
|
|
-- se lavorazione di fianco setto la nota per spostarla dopo i tagli di lama
|
|
if vtN:getZ() < WD.NZ_MINA then
|
|
EgtSetInfo( nMchFId, 'MOVE_AFTER', 1)
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacet}})
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_ZP
|
|
if AreSameVectorApprox( vtN, Z_AX()) then
|
|
nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente
|
|
local dThElev = dThDiam / 2 * sqrt( vtN:getX() * vtN:getX() + vtN:getY() * vtN:getY())
|
|
local dDepth = 0
|
|
local sWarn = ''
|
|
if dElev + dThElev > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
dDepth = dMaxDepth - dElev - dThElev
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- leggo eventuali note della lavorazione
|
|
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
|
|
-- imposto elevazione
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( min( dElev, dMaxDepth), 1))
|
|
-- se lavorazione in doppio aggiungo le rispettive note
|
|
if Proc.Double and Proc.Double == 2 then
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'DOUBLE', Proc.Double)
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MirrorAx', Proc.MirrorAx)
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'DeltaZ', Proc.MirrorDeltaZ)
|
|
-- escludo ottimizzazioni e forzo attacco interno perchè la tasca specchiata potrebbe essere nel mezzo del pannello
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxOptSize', 0.1)
|
|
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALOUT)
|
|
end
|
|
-- setto eventuale nota per forzare tasca chiusa
|
|
if bForceClosedPocket then sUserNotes = EgtSetValInNotes( sUserNotes, 'Open', 0) end
|
|
-- setto eventuale nota per forzare attacco esterno, fino ad un certo spessore del grezzo
|
|
local dMaxRawThicknessToStartOut = 75
|
|
if bIsFeatureOnEdge and ( not Proc.Double or Proc.Double == 0) then sUserNotes = EgtSetValInNotes( sUserNotes, 'OpenMinSafe', dMaxRawThicknessToStartOut) end
|
|
-- scrivo le note della lavorazione
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
|
|
-- verifica parametro Q per pulitura spigoli
|
|
local bIsU = ( Proc.Fct == 3 and not WL.TestElleShape3( Proc.Id, Proc.Fct))
|
|
if bCheckQPar and not ( bIsU and AreSameOrOppositeVectorApprox( vtN, Z_AX())) then
|
|
-- lettura parametri (probabile/i parametro/i Q)
|
|
local nConeCut = EvaluateQParam( Proc)
|
|
-- recupero i dati di tutte le facce
|
|
local vFace, dMaxWidth = GetFacesData( nNewProc, false, false, dMillDiam, dMaxDepth, (dMillDiam/2), nAddGrpId, Proc.PartId)
|
|
-- se abilitata la lavorazione corner con stop macchina
|
|
if nConeCut == 1 then
|
|
local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw,
|
|
dMillDiam, nAddGrpId, dMaxWidth, nNewProc, dDepth)
|
|
if not bMcok then return bMcok, sMcErr end
|
|
elseif nConeCut == 2 then
|
|
local sErr = 'Clean corner 30° is not applied on pocketing'
|
|
EgtOutLog( sErr)
|
|
EgtErase( nNewProc)
|
|
else
|
|
EgtErase( nNewProc)
|
|
end
|
|
else
|
|
EgtErase( nNewProc)
|
|
end
|
|
return true, sWarn, sTuuid
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeOneFace( Proc, nRawId, b3Raw)
|
|
-- dati della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
-- dimensioni della faccia
|
|
local _, dDimH, dDimV = WL.GetFaceHvRefDim( Proc.Id, 0)
|
|
-- recupero la lavorazione di taglio con lama e i suoi parametri
|
|
local sCutting, dSawDiam, dSawThick, dSawMaxDepth = WM.FindCutting( 'Standard')
|
|
-- se non inclinata o capacità di taglio non sufficiente, provo con svuotatura
|
|
if not sCutting or vtN:getZ() > 0.866 or dSawMaxDepth < dDimV + WD.CUT_EXTRA then
|
|
-- faccio con svuotatura
|
|
local nFacet = 0
|
|
return MakeByPocketing( Proc, nFacet, nRawId, b3Raw)
|
|
end
|
|
-- eseguo il taglio di lama
|
|
local sName = 'Cut_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) .. '_' .. tostring( Proc.Id)
|
|
local nMchId = WM.AddMachining( Proc, sName, sCutting)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', Proc.PartId)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( { { Proc.Id, 0}})
|
|
-- percorso da non invertire
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- assegno affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, 0)
|
|
-- assegno il lato di lavoro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
-- assegno l'attacco e l'uscita
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.CENT)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.CENT)
|
|
-- nessun criterio per il braccio è necessario
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sErr
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeTwoFaces( Proc, nRawId, b3Raw)
|
|
-- 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)
|
|
-- determino l'intersezione tra le due facce
|
|
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
|
|
if not bAdj then
|
|
return false, 'Feature with two faces not adjacentes'
|
|
end
|
|
-- se equivalente ad un contorno
|
|
if abs( ptP1:getZ() - ptP2:getZ()) > 0.9 * b3Raw:getDimZ() then
|
|
-- verifico ordinamento (esterno a destra)
|
|
local ptPM = ( ptP1 + ptP2) / 2
|
|
if ( vtN[1] ^ ( ptPM - ptC[1])) * Z_AX() < 0 then
|
|
EgtSurfTmSwapFacets( Proc.Id, 0, 1)
|
|
end
|
|
-- applico lavorazione di contorno libero
|
|
return FreeContour.Make( Proc, nRawId, b3Raw)
|
|
end
|
|
-- versore della linea di intersezione
|
|
local vtX = ptP2 - ptP1 ; vtX:normalize()
|
|
-- larghezza delle facce ortogonalmente all'intersezione
|
|
local dDimY = {}
|
|
for i = 1, 2 do
|
|
local vtY = vtN[i] ^ vtX ; vtY:normalize()
|
|
local frRef = Frame3d( ptC[i], ptC[i] + 100 * vtX, ptC[i] + 100 * vtY)
|
|
local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, i - 1, GDB_BB.STANDARD, frRef)
|
|
dDimY[i] = b3Ref:getDimY()
|
|
end
|
|
-- recupero la lavorazione di taglio con lama e i suoi parametri
|
|
local sCutting, dSawDiam, dSawThick, dSawMaxDepth = WM.FindCutting( 'Standard')
|
|
-- se parametro Q abilita lavorazione ribasso con fresa di fianco
|
|
local _, nUseMillOnSide = EvaluateQParam( Proc)
|
|
local dMaxZVers, dMinZVers
|
|
if nUseMillOnSide >= 1 then
|
|
dMaxZVers = 0.866
|
|
dMinZVers = 0.5
|
|
else
|
|
dMaxZVers = 0.95
|
|
dMinZVers = 0.1
|
|
end
|
|
-- se di fianco in basso
|
|
local dMaxThick, dMinSideElev
|
|
if vtN[1]:getZ() < -dMaxZVers or vtN[2]:getZ() < -dMaxZVers then
|
|
if vtN[1]:getZ() < -0.5 then
|
|
dMaxThick = dDimY[2]
|
|
dMinSideElev = dDimY[1]
|
|
elseif vtN[2]:getZ() < -0.5 then
|
|
dMaxThick = dDimY[1]
|
|
dMinSideElev = dDimY[2]
|
|
end
|
|
end
|
|
local sMillOnSide = WM.FindMilling( 'SideMill', nil, nil, nil, nil, dMaxThick, nil, dMinSideElev)
|
|
-- se Proc è settata per essere specchiata cerco la lavorazione adatta e verifico possa essere effettivamente specchiata
|
|
local bDoubleMillOnSide = false
|
|
if Proc.Double and Proc.Double == 2 then
|
|
local sMillOnSideBackup = sMillOnSide
|
|
sMillOnSide = WM.FindMilling( 'SideMill', nil, nil, nil, nil, dMaxThick, nil, dMinSideElev, 'H1')
|
|
if WM.IsMachiningOkForDouble( sMillOnSide) then
|
|
bDoubleMillOnSide = true
|
|
else
|
|
sMillOnSide = sMillOnSideBackup
|
|
end
|
|
end
|
|
local bEnableMillOnSide
|
|
if sMillOnSide and nUseMillOnSide >= 1 then
|
|
dMaxZVers = 0.866
|
|
dMinZVers = 0.5
|
|
bEnableMillOnSide = true
|
|
else
|
|
dMaxZVers = 0.95
|
|
dMinZVers = 0.1
|
|
end
|
|
-- se di fianco in basso
|
|
if vtN[1]:getZ() < -dMaxZVers or vtN[2]:getZ() < -dMaxZVers then
|
|
-- cerco la faccia verticale o quasi
|
|
local nFacet = EgtIf( abs( vtN[1]:getZ()) < dMinZVers, 0, 1)
|
|
-- cerco nei parametri utensili la nota di affondamento di fianco SIDEDEPTH
|
|
local dMaxDepthOnSide = 0
|
|
local dMillDiam = 0
|
|
local dMillDiamTh = 0
|
|
if bEnableMillOnSide and EgtMdbSetCurrMachining( sMillOnSide) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
|
|
dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh
|
|
dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide
|
|
dMaxDepthOnSide = min( dMaxDepthOnSide, 0.5 * ( dMillDiam - dMillDiamTh))
|
|
end
|
|
end
|
|
local dMaxDist = 300
|
|
if bEnableMillOnSide and dMaxDepthOnSide > 0 then
|
|
dMaxDist = dMaxDepthOnSide
|
|
end
|
|
-- se vicino al bordo del grezzo e non troppo larga, provo con fresatura di fianco
|
|
local ptMid = ( ptP1 + ptP2) / 2
|
|
local bMakeFirstGroove
|
|
local bMachFromDn = true
|
|
local bInsertMach
|
|
local dSideDist
|
|
-- per evitare errori in casi di pezzi molto stretti, verifico le distanze in base alla direzione della faccia
|
|
-- se normale verso X
|
|
if vtN[nFacet+1]:getX() > 0.99 then
|
|
dSideDist = abs( ptMid:getX() - b3Raw:getMax():getX())
|
|
-- altrimenti se normale verso X-
|
|
elseif vtN[nFacet+1]:getX() < -0.99 then
|
|
dSideDist = abs( ptMid:getX() - b3Raw:getMin():getX())
|
|
-- altrimenti se normale verso Y+
|
|
elseif vtN[nFacet+1]:getY() > 0.99 then
|
|
dSideDist = abs( ptMid:getY() - b3Raw:getMax():getY())
|
|
-- altrimenti se normale verso Y-
|
|
elseif vtN[nFacet+1]:getY() < -0.99 then
|
|
dSideDist = abs( ptMid:getY() - b3Raw:getMin():getY())
|
|
end
|
|
if dSideDist and dSideDist < dMaxDist then
|
|
bInsertMach = true
|
|
bMakeFirstGroove = false
|
|
-- altrimenti la distanza è maggiore e se è sempre abilitata la lavorazione MillOnSide
|
|
elseif bEnableMillOnSide and dMaxDepthOnSide then
|
|
bInsertMach = true
|
|
bMakeFirstGroove = true
|
|
end
|
|
-- se posso eseguire la lavorazione per distanza inferiore utensile o lavorazione preceduta da sgossatura gola
|
|
if bInsertMach then
|
|
return MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, nil, nil, nil, bDoubleMillOnSide)
|
|
else
|
|
local sErr = 'Error feature not machinable (dimensions)'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- se altrimenti di fianco in alto
|
|
elseif vtN[1]:getZ() > dMaxZVers or vtN[2]:getZ() > dMaxZVers then
|
|
-- cerco la faccia con il maggior numero di adiacenze (e minor elevazione)
|
|
local nFacInd, _, nFacInd2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId)
|
|
if nFacInd == -2 then
|
|
local sErr = 'Error feature with 2 faces with undercut'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local vtNTemp = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local dSideDist
|
|
local ptMid = ( ptP1 + ptP2) / 2
|
|
-- faccia orizzontale
|
|
local nFacet = EgtIf( vtNTemp:getZ() >= WD.NZ_MINA, nFacInd, nFacInd2)
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
-- faccia verticale
|
|
local nFacetVert = EgtIf( nFacet == nFacInd, nFacInd2, nFacInd)
|
|
local vtNV = EgtSurfTmFacetNormVersor( Proc.Id, nFacetVert, GDB_ID.ROOT)
|
|
-- per evitare errori in casi di pezzi molto stretti, verifico le distanze in base alla direzione della faccia
|
|
-- local dSideDist = min( abs( ptMid:getX() - b3Raw:getMin():getX()), abs( ptMid:getX() - b3Raw:getMax():getX()),
|
|
-- abs( ptMid:getY() - b3Raw:getMin():getY()), abs( ptMid:getY() - b3Raw:getMax():getY()))
|
|
-- se normale verso X
|
|
if vtNV:getX() > 0.99 then
|
|
dSideDist = abs( ptMid:getX() - b3Raw:getMax():getX())
|
|
-- altrimenti se normale verso X-
|
|
elseif vtNV:getX() < -0.99 then
|
|
dSideDist = abs( ptMid:getX() - b3Raw:getMin():getX())
|
|
-- altrimenti se normale verso Y+
|
|
elseif vtNV:getY() > 0.99 then
|
|
dSideDist = abs( ptMid:getY() - b3Raw:getMax():getY())
|
|
-- altrimenti se normale verso Y-
|
|
elseif vtNV:getY() < -0.99 then
|
|
dSideDist = abs( ptMid:getY() - b3Raw:getMin():getY())
|
|
end
|
|
-- cerco nei parametri utensili la nota di affondamento di fianco SIDEDEPTH
|
|
local dMaxDepthOnSide = 0
|
|
local dMillDiam = 0
|
|
if bEnableMillOnSide and EgtMdbSetCurrMachining( sMillOnSide) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
|
|
dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide
|
|
end
|
|
end
|
|
-- 2021.10.08 E.S. in base a richieste del cliente:
|
|
-- Se parametro Q riduce utilizzo lavorazione di lato come lama ed elevazione laterale supera il 60% diametro utensile
|
|
-- disabilito
|
|
if nUseMillOnSide == 2 and dSideDist > 0.6 * dMillDiam then
|
|
bEnableMillOnSide = false
|
|
end
|
|
-- per il fianco in alto non ci sono problemi di inserimento massimo laterale, setto la variabile pari al raggio utensile - 1mm
|
|
dMaxDepthOnSide = ( 0.5 * dMillDiam) - 1
|
|
local dMaxDist = 300
|
|
if bEnableMillOnSide and dMaxDepthOnSide > 0 then
|
|
dMaxDist = dMaxDepthOnSide
|
|
end
|
|
-- se vicino al bordo del grezzo e non troppo larga, provo con fresatura di fianco
|
|
local bMakeFirstGroove = false
|
|
local bLikeAsMakeFirstGroove
|
|
local bMachFromDn = false
|
|
local bInsertMach
|
|
if dSideDist and dSideDist < dMaxDist then
|
|
-- se abilitata SideMill oppure se la specchiata guarda in basso e quindi l'attacco deve essere a filo
|
|
if ( bEnableMillOnSide and dMaxDepthOnSide > 0) or ( Proc.Double == 2 and Proc.MirrorDeltaZ and abs( Proc.MirrorDeltaZ) > GEO.EPS_SMALL) then
|
|
bLikeAsMakeFirstGroove = false
|
|
return MakeSideGrooveByMill( Proc, nFacetVert, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, bLikeAsMakeFirstGroove, nil, nil, bDoubleMillOnSide)
|
|
else
|
|
local bOk, sErr = MakeByMill( Proc, nFacet, 1 - nFacet, nRawId, b3Raw, dSideDist)
|
|
-- se angolo ottuso riprendo il lato quasi verticale
|
|
if bOk and dAng and dAng > -90 + 10 * GEO.EPS_SMALL then
|
|
local bOk2, sErr2 = MakeSideGrooveByMill( Proc, nFacetVert, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, false, nil, true)
|
|
end
|
|
return bOk, sErr
|
|
end
|
|
elseif bEnableMillOnSide and dMaxDepthOnSide > 0 then
|
|
bLikeAsMakeFirstGroove = true
|
|
local bOk, sErr = MakeSideGrooveByMill( Proc, nFacetVert, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, bLikeAsMakeFirstGroove, nil, nil, bDoubleMillOnSide)
|
|
if bOk then return true end
|
|
end
|
|
-- se non inclinate o capacità di taglio non sufficiente o non molto grandi (80mm), provo con contornatura o svuotatura
|
|
if vtN:getZ() > 0.866 or vtNV:getZ() > 0.866 or not sCutting or dSawMaxDepth < dDimY[1] + WD.CUT_SIC or dSawMaxDepth < dDimY[2] + WD.CUT_SIC or dDimY[1] < 80 or dDimY[2] < 80 then
|
|
-- eseguo la svuotatura
|
|
local bOk, sErr, sTuuid = MakeByPocketing( Proc, nFacet, nRawId, b3Raw)
|
|
-- se angolo ottuso riprendo il lato quasi verticale
|
|
if bOk and dAng and dAng > -90 + 10 * GEO.EPS_SMALL then
|
|
local _, dHVert, dVVert = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacetVert, GDB_ID.ROOT)
|
|
local dDepth = min( dHVert, dVVert)
|
|
local _, dHHor, dVHor = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
local dDiam = 2 * min( dHHor, dVHor)
|
|
local sMillObtuseAngle = WM.FindMilling( 'FreeContour', dDepth, sTuuid, nil, dDiam, nil, nil, nil)
|
|
if not sMillObtuseAngle then
|
|
sMillObtuseAngle = WM.FindMilling( 'FreeContour', dDepth, nil, nil, dDiam, nil, nil, nil)
|
|
end
|
|
if not sMillObtuseAngle then
|
|
local sErrMillNotFound = 'Error : Processing to finish obtuse angle not found in library'
|
|
EgtOutLog( sErrMillNotFound)
|
|
return true, sErrMillNotFound
|
|
end
|
|
local bOk2, sErr2 = MakeSideGrooveByMill( Proc, nFacetVert, nRawId, b3Raw, sMillObtuseAngle, dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, false, nil, true)
|
|
end
|
|
return bOk, sErr
|
|
end
|
|
-- se una delle due facce rivolta verso il basso
|
|
elseif vtN[1]:getZ() < -0.001 or vtN[2]:getZ() < -0.001 then
|
|
-- cerco la faccia rivolta verso l'alto
|
|
local nFacet
|
|
if vtN[1]:getZ() > 0 then
|
|
nFacet = 0
|
|
elseif vtN[2]:getZ() > 0 then
|
|
nFacet = 1
|
|
else
|
|
local sErr = 'Error feature with 2 faces facing down'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- eseguo la svuotatura
|
|
return MakeByPocketing( Proc, nFacet, nRawId, b3Raw)
|
|
end
|
|
-- ordino i tagli per fare prima quello meno inclinato
|
|
local nOrd = { 0, 1}
|
|
if vtN[2]:getZ() > vtN[1]:getZ() then
|
|
nOrd = { 1, 0}
|
|
end
|
|
-- eseguo i tagli di lama
|
|
for i = 1, 2 do
|
|
-- inserisco la lavorazione
|
|
local sName = 'Cut_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) .. '_' .. tostring( Proc.Id) .. '_' .. tostring( i)
|
|
local nMchId = WM.AddMachining( Proc, sName, sCutting)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', Proc.PartId)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( { { Proc.Id, nOrd[i]}})
|
|
-- percorso da non invertire
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- assegno affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, 0)
|
|
-- assegno il lato di lavoro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
-- assegno l'attacco e l'uscita
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.CENT)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.CENT)
|
|
-- nessun criterio per il braccio è necessario
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeMoreFaces( Proc, nRawId, b3Raw)
|
|
-- con una faccia di fondo valida
|
|
if Proc.Stype == 1 or Proc.Stype == 2 then
|
|
-- recupero eventuale flag forzatura svuotatura
|
|
local bPckt = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1)
|
|
-- cerco la faccia con il maggior numero di adiacenze
|
|
local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId)
|
|
-- se necessario scambio le facce
|
|
if Proc.Stype == 2 then
|
|
nFacInd, dElev, nFacInd2, dElev2 = nFacInd2, dElev2, nFacInd, dElev
|
|
end
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local dMaxSlotThicknessForBlade = 25
|
|
local bIsSmallSlot = ( Proc.Fct == 3 and ( min( dH, dV) < dMaxSlotThicknessForBlade + 10 * GEO.EPS_SMALL) and vtN:getZ() > -0.01)
|
|
-- se di fianco
|
|
if not bPckt and Proc.Fct >= 3 and ( ( vtN:getZ() < WD.NZ_MINA) or bIsSmallSlot) then
|
|
-- recupero elevazione faccia in feature
|
|
local dSideElev = WL.GetFaceElevation( Proc.Id, nFacInd)
|
|
-- se abilitata lavorazione ribasso con fresa di fianco e parametro Q03 abilitato
|
|
local sMillOnSide, dTMaxDepth, dMaxMat, dDiam = WM.FindMilling( 'SideMill', nil, nil, nil, nil, min( dH, dV), nil, dSideElev)
|
|
-- se Proc è settata per essere specchiata cerco la lavorazione adatta e verifico possa essere effettivamente specchiata
|
|
local bDoubleMillOnSide = false
|
|
if Proc.Double and Proc.Double == 2 then
|
|
local sMillOnSideBackup = sMillOnSide
|
|
sMillOnSide = WM.FindMilling( 'SideMill', nil, nil, nil, nil, min( dH, dV), nil, dSideElev, 'H1')
|
|
if WM.IsMachiningOkForDouble( sMillOnSide) then
|
|
bDoubleMillOnSide = true
|
|
else
|
|
sMillOnSide = sMillOnSideBackup
|
|
end
|
|
end
|
|
local _, nUseMillOnSide = EvaluateQParam( Proc)
|
|
-- se ho abilitata lavorazione di fresa di fianco
|
|
if Proc.Fct >= 3 and sMillOnSide and nUseMillOnSide >= 1 and not bIsSmallSlot then
|
|
-- cerco nei parametri utensili la nota di affondamento di fianco SIDEDEPTH
|
|
local dMaxDepthOnSide = 0
|
|
local dMillDiam = 0
|
|
if EgtMdbSetCurrMachining( sMillOnSide) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
|
|
dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide
|
|
end
|
|
end
|
|
local bMakeFirstGroove
|
|
local bLikeAsMakeFirstGroove
|
|
local bInsertMach
|
|
local dElevToPiece = WL.GetFaceElevation( Proc.Id, nFacInd, nRawId)
|
|
-- Se distanza dal grezzo è minore della Max lavorazione laterale utensile
|
|
if dElevToPiece < dMaxDepthOnSide then
|
|
bInsertMach = true
|
|
bMakeFirstGroove = false
|
|
-- altrimenti la distanza è maggiore e se è sempre abilitata la lavorazione MillOnSide
|
|
elseif dMaxDepthOnSide > 0 then
|
|
bInsertMach = true
|
|
bMakeFirstGroove = true
|
|
end
|
|
-- se posso eseguire la lavorazione per distanza inferiore utensile o lavorazione preceduta da sgossatura gola
|
|
-- e gola più grande o uguale spessore utensile
|
|
if bInsertMach and dMaxMat <= min( dH, dV) + 20 * GEO.EPS_SMALL then
|
|
local nSinglePass = 0
|
|
bLikeAsMakeFirstGroove = bMakeFirstGroove
|
|
-- se positivo setto il flag per lavorare singola passata bassa e disabilito sgrossatura
|
|
if vtN:getZ() > 20 * GEO.EPS_SMALL then
|
|
nSinglePass = 1
|
|
bMakeFirstGroove = false
|
|
-- se negativo setto il flag per lavorare singola passata alta e disabilito sgrossatura
|
|
elseif vtN:getZ() < -20 * GEO.EPS_SMALL then
|
|
nSinglePass = 2
|
|
bMakeFirstGroove = false
|
|
end
|
|
return MakeSideGrooveByMill( Proc, nFacInd, nRawId, b3Raw, EgtIf( dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, nil, nil, bLikeAsMakeFirstGroove, nSinglePass, nil, bDoubleMillOnSide)
|
|
end
|
|
else
|
|
-- fresatura (se definita); se disponibile, cerco di usare un utensile che non lavori al limite della capacità di sottosquadro
|
|
local dSideElevMultiplier = 1.2
|
|
local sMilling = WM.FindMilling( 'SideGroove', nil, nil, nil, nil, min( dH, dV), nil, dSideElevMultiplier * dSideElev)
|
|
-- se non ho trovato un utensile un po' più grande del sottosquadro richiesto, passo alla ricerca standard
|
|
if not sMilling then
|
|
sMilling = WM.FindMilling( 'SideGroove', nil, nil, nil, nil, min( dH, dV), nil, dSideElev)
|
|
dSideElevMultiplier = 1
|
|
end
|
|
-- se Proc è settata per essere specchiata cerco la lavorazione adatta e verifico possa essere effettivamente specchiata
|
|
bDoubleMillOnSide = false
|
|
if Proc.Double and Proc.Double == 2 then
|
|
local sMillOnSideBackup = sMillOnSide
|
|
sMillOnSide = WM.FindMilling( 'SideGroove', nil, nil, nil, nil, min( dH, dV), nil, dSideElevMultiplier * dSideElev, 'H1')
|
|
if WM.IsMachiningOkForDouble( sMillOnSide) then
|
|
bDoubleMillOnSide = true
|
|
else
|
|
sMillOnSide = sMillOnSideBackup
|
|
end
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dMaxMat = 1000
|
|
local dMaxDepthOnSide = 0
|
|
local bIsBlade = false
|
|
if sMilling and EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
local dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or 0
|
|
bIsBlade = EgtTdbGetCurrToolParam( MCH_TP.TYPE) & MCH_TF.SAWBLADE ~= 0
|
|
if bIsBlade then
|
|
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dMaxMat
|
|
dMaxDepthOnSide = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT)
|
|
else
|
|
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
|
|
dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd')
|
|
end
|
|
if not dMaxDepthOnSide then
|
|
local dMillDiamTh = EgtTdbGetCurrToolThDiam() or 60
|
|
dMaxDepthOnSide = ( dMillDiam - dMillDiamTh) / 2
|
|
end
|
|
end
|
|
end
|
|
if sMilling and dElev < dMaxDepthOnSide then
|
|
return MakeSideGrooveByMill( Proc, nFacInd, nRawId, b3Raw, sMilling, nil, nil, nil, nil, nil, nil, nil, bDoubleMillOnSide)
|
|
-- altrimenti sega a catena
|
|
else
|
|
return MakeByChainSaw( Proc, nFacInd, nRawId, b3Raw, dElev, dH, dV)
|
|
end
|
|
end
|
|
end
|
|
local nFacet = EgtIf( bPckt or vtN:getZ() >= WD.NZ_MINA, nFacInd, nFacInd2)
|
|
if nFacet then
|
|
-- eseguo la svuotatura
|
|
return MakeByPocketing( Proc, nFacet, nRawId, b3Raw, true)
|
|
else
|
|
local sErr = 'Side milling not possible'
|
|
EgtOutLog( sErr)
|
|
return true, sErr
|
|
end
|
|
-- fessura verticale
|
|
elseif Proc.Stype == 3 then
|
|
-- riordino le facce come contorno libero da lavorare a destra (sono una U)
|
|
-- porto la faccia centrale in seconda posizione (indice 1)
|
|
local nFacInd = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId)
|
|
if nFacInd ~= 1 then
|
|
EgtSurfTmSwapFacets( Proc.Id, 1, nFacInd)
|
|
end
|
|
-- verifico se la prima (indice 0) la deve precedere o seguire
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
local bAdj, ptAdj, _, _ = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
|
|
if bAdj and ( vtN ^ ( ptAdj - ptC)) * Z_AX() < 0 then
|
|
EgtSurfTmSwapFacets( Proc.Id, 0, 2)
|
|
end
|
|
-- applico lavorazione di contorno libero
|
|
return FreeContour.Make( Proc, nRawId, b3Raw)
|
|
-- tunnel
|
|
elseif Proc.Stype == 4 then
|
|
-- riordino le facce come contorno libero da lavorare a destra (formano un anello chiuso e quindi posso partire da una qualunque)
|
|
for i = 1, Proc.Fct - 2 do
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT)
|
|
for j = i + 1, Proc.Fct do
|
|
local bAdj, ptAdj, _, _ = EgtSurfTmFacetsContact( Proc.Id, i - 1, j - 1, GDB_ID.ROOT)
|
|
if bAdj and ( vtN ^ ( ptAdj - ptC)) * Z_AX() > 0 then
|
|
if i ~= j - 1 then
|
|
EgtSurfTmSwapFacets( Proc.Id, i, j - 1)
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
-- applico lavorazione di contorno libero
|
|
return FreeContour.Make( Proc, nRawId, b3Raw)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione
|
|
function WPL.Make( Proc, nRawId, b3Raw)
|
|
-- in base al tipo di feature attribuisco il significato dei parametri Q
|
|
AssignQIdent( Proc)
|
|
if Proc.Fct == 1 then
|
|
return MakeOneFace( Proc, nRawId, b3Raw)
|
|
elseif Proc.Fct == 2 then
|
|
return MakeTwoFaces( Proc, nRawId, b3Raw)
|
|
else
|
|
return MakeMoreFaces( Proc, nRawId, b3Raw)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return WPL
|