2628 lines
119 KiB
Lua
2628 lines
119 KiB
Lua
-- ProcessFreeContour.lua by Egaltech s.r.l. 2023/04/17
|
|
-- Gestione calcolo profilo libero per Pareti
|
|
-- 2021/11/15 Penna e chiodature sono sempre riportate sulla faccia sopra anche se nel progetto sono sotto.
|
|
-- 2021/12/10 In taglio con lama aggiunta gestione SCC per testa Gearbox.
|
|
-- 2022/01/13 Aggiunta gestione massimo affondamento in Z anche per pulizia spigoli con fresa 60deg (WD.MAX_CLEAN_CRN60).
|
|
-- 2022/02/03 Corretto controllo massimo affondamento nella tavola.
|
|
-- 2022/02/21 Corretti allungamenti/accorciamenti tagli inclinati con fresa. Migliorata gestione tagli trasversali per macchine travi.
|
|
-- 2022/03/14 Corretto riconoscimento lato esterno per percorsi aperti.
|
|
-- 2022/03/16 Ulteriore modifica per riconoscimento lato esterno (aggiunto uso vExtr a GetFacesExternalSide).
|
|
-- 2022/04/03 Correzioni e modifiche per pulitura spigoli tipo 2 e 3.
|
|
-- 2022/04/19 Aggiunta passibilita' fresatura ad affondamento ridotto quando non possibile completa o sega a catena.
|
|
-- 2022/04/26 Migliorata gestione caso pocketing.
|
|
-- 2022/08/05 Aggiunta segnalazione aree vietate non gestite.
|
|
-- 2022/08/29 Corretta gestione tipo Pocket senza fondo (sono lavorabili da entrambe le parti con fresatura).
|
|
-- 2022/12/13 Aggiunta la funzione Is3EdgesApprox per riconoscere come 3 lati anche facce con lati aggiuntivi molto corti (<15 mm)
|
|
-- 2022/12/14 Aggiunto l'accorciamento della lama in caso di facce vicine orientate verso il basso
|
|
-- 2023/02/28 In lavorazioni con sega a catena per invertire lato mandrino ora Invert + Left invece di MCH_SCC.OPPOSITE.
|
|
-- 2023/03/08 In lavorazione con fresa, se imposto Tool_ID non si controlla più possa lavorare di testa.
|
|
-- 2023/04/14 Aggiunta pulitura spigoli Q05=1 anche su sole fresature.
|
|
-- 2023/04/17 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/06 Aggiunta gestione lavorazione per lamatura speciale affondata con Tool_ID specifico.
|
|
-- 2023/07/26 In MakeByCut migliorata la scelta della fresa secondaria nel caso non sia disponibile una fresa di lunghezza sufficiente.
|
|
|
|
-- Tabella per definizione modulo
|
|
local WPF = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local WL = require( 'WallLib')
|
|
|
|
EgtOutLog( ' WProcessFreeContour started', 1)
|
|
|
|
-- Dati
|
|
local WD = require( 'WallData')
|
|
local WM = require( 'WMachiningLib')
|
|
if WD.CHECK_MIN_Z_SAW == nil then WD.CHECK_MIN_Z_SAW = true end
|
|
if not WD.MIN_Z_SAW then WD.MIN_Z_SAW = 0 end
|
|
if not WD.MAX_CLEAN_CRN60 then WD.MAX_CLEAN_CRN60 = 150 end
|
|
if not WD.MAX_CLEAN_CRN30 then WD.MAX_CLEAN_CRN30 = 68 end
|
|
local WHISK_OFFS = 0.1
|
|
local WHISK_SAFE = 5
|
|
local MIN_LEN_CUT = 250
|
|
|
|
-- variabili assegnazione parametri Q
|
|
local sTypeCornerCut = 'Q05' -- i
|
|
-- variabile settaggio doppia lavorazione su angoo > 90
|
|
local bMakeTwinCut = true
|
|
-- variabile per valore sfondamento spigolo
|
|
local dExtraCorner = 1
|
|
-- angolo sottosquadra ammesso per fresa cono 30°
|
|
local dAngleSmall = 70
|
|
|
|
---------------------------------------------------------------------
|
|
-- Riconoscimento della feature
|
|
function WPF.Identify( Proc)
|
|
return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and ( Proc.Prc == 250 or Proc.Prc == 251 or Proc.Prc == 252))
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione della feature
|
|
function WPF.Classify( Proc, b3Raw)
|
|
-- verifico se di tipo pocket
|
|
local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1)
|
|
-- recupero la curva associata
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
|
|
if not AuxId then return false end
|
|
AuxId = AuxId + Proc.Id
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
-- recupero il tipo di lavorazione
|
|
local nCntType = EgtGetInfo( Proc.Id, 'CNT_TYPE', 'i') or 0
|
|
local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i')
|
|
-- se tasca
|
|
if bPocket then
|
|
-- cerco la faccia di fondo della superfice (deve avere direzione circa quella di estrusione della curva)
|
|
local nFacet
|
|
for i = 1, Proc.Fct do
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT)
|
|
if abs( vtN * vtExtr) > 0.99 then
|
|
nFacet = i - 1
|
|
vtExtr = vtN
|
|
break
|
|
end
|
|
end
|
|
local bDown = ( nFacet and vtExtr:getZ() < - 0.5)
|
|
return not bDown
|
|
-- se altrimenti profilo orizzontale
|
|
elseif abs( vtExtr:getZ()) < 0.5 then
|
|
return false
|
|
-- se penna o chiodatura va sempre bene (vengono sempre riportati sopra)
|
|
elseif nCntType == 10 or nCntType == 20 then
|
|
return true
|
|
-- se altrimenti profilo verticale che non interessa tutta la sezione e non caso speciale con lamatura affondata
|
|
elseif ( Proc.Box:getMax():getZ() < b3Raw:getMax():getZ() - 2) and ( not nTool_ID or ( nTool_ID ~= ( WD.RECESSED_COUNTERBORE_TOOLID or 0)) or ( not EgtCurveIsACircle( AuxId))) then
|
|
return false
|
|
-- altrimenti è profilo verticale che interessa tutta la sezione o caso speciale con lamatura affondata
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
----------------------------------------------------------------------
|
|
-- Classificazione del flip della feature per nesting
|
|
-- return nFlip0, nFlip1
|
|
function WPF.FlipClassify( Proc, b3Raw)
|
|
local nFlip0 = 0
|
|
local nFlip1 = 0
|
|
|
|
-- verifico se di tipo pocket
|
|
local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1)
|
|
-- recupero la curva associata se esiste
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
|
|
if not AuxId then return false end
|
|
AuxId = AuxId + Proc.Id
|
|
local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local dVtNZ = vtN:getZ()
|
|
-- se tasca
|
|
if bPocket then
|
|
-- verifico se è lavorabile da sopra
|
|
nFlip0 = EgtIf( dVtNZ < -0.5, 0, 100)
|
|
-- verifico se e' lavorabile da fliped: cambio segno al versore
|
|
nFlip1 = EgtIf( -dVtNZ < -0.5, 0, 100)
|
|
|
|
-- se altrimenti profilo orizzontale
|
|
elseif abs( dVtNZ) < WD.NZ_MINA then
|
|
return 0, 0
|
|
-- se altrimenti profilo verticale che non interessa tutta la sezione
|
|
elseif Proc.Box:getMax():getZ() < b3Raw:getMax():getZ() - 2 then
|
|
return 0 , 0
|
|
-- altrimenti è profilo verticale che interessa tutta la sezione
|
|
else
|
|
local dVtNZMedia = 0
|
|
for i = 1, Proc.Fct do
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT)
|
|
dVtNZMedia = dVtNZMedia + vtN:getZ()
|
|
end
|
|
dVtNZMedia = dVtNZMedia / Proc.Fct
|
|
if abs( dVtNZMedia) <= GEO.EPS_SMALL then
|
|
nFlip0 = 100
|
|
nFlip1 = 100
|
|
elseif dVtNZMedia >= 0 + GEO.EPS_SMALL then
|
|
nFlip0 = 75
|
|
nFlip1 = 50
|
|
else
|
|
nFlip0 = 50
|
|
nFlip1 = 75
|
|
end
|
|
end
|
|
return nFlip0, nFlip1
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TestElleShape3( nIdGeom, nNumFacet)
|
|
-- valida solo nel caso di tre facce
|
|
if nNumFacet ~= 3 then return false end
|
|
-- determino se L con una faccia terminale o U con tre facce
|
|
local bIsL = true
|
|
for i = 1, 3 do
|
|
local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1]
|
|
-- le conto
|
|
local nCount = 0
|
|
for j = 1, #vFacAdj do
|
|
if vFacAdj[j] >= 0 then
|
|
nCount = nCount + 1
|
|
end
|
|
end
|
|
if nCount == 1 then
|
|
bIsL = false
|
|
break
|
|
end
|
|
end
|
|
return bIsL
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TestElleShape4( nIdGeom, nNumFacet)
|
|
-- valida solo nel caso di quattro facce
|
|
if nNumFacet ~= 4 then return false end
|
|
-- determino se L con due facce terminali o O
|
|
local nFac3Adj = 0
|
|
local dMinArea3 = GEO.INFINITO * GEO.INFINITO
|
|
local dMaxArea2 = 0
|
|
for i = 1, 4 do
|
|
local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1]
|
|
-- le conto
|
|
local nCount = 0
|
|
for j = 1, #vFacAdj do
|
|
if vFacAdj[j] >= 0 then
|
|
nCount = nCount + 1
|
|
end
|
|
end
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( nIdGeom, i - 1, GDB_ID.ROOT)
|
|
local dArea = dH * dV
|
|
if nCount == 2 then
|
|
dMaxArea2 = max( dMaxArea2, dArea)
|
|
elseif nCount == 3 then
|
|
dMinArea3 = min( dMinArea3, dArea)
|
|
nFac3Adj = nFac3Adj + 1
|
|
end
|
|
end
|
|
if nFac3Adj ~= 2 then return false end
|
|
-- verifico se L profonda oppure lunga
|
|
if dMinArea3 < dMaxArea2 then
|
|
return 1
|
|
else
|
|
return 2
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifyCornerType( Proc)
|
|
-- 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 nVal = EgtGetInfo( Proc.Id, sTypeCornerCut, 'i')
|
|
return ( nVal or 0)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function IsPointOnRawLongEdges( ptCen, b3Raw)
|
|
return ( abs( ptCen:getY() - b3Raw:getMin():getY()) < 0.1 or abs( ptCen:getY() - b3Raw:getMax():getY()) < 0.1)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetOtherRegions( nPartId)
|
|
local vOthers = {}
|
|
-- ciclo sui pezzi
|
|
local nOtherId = EgtGetFirstPartInRawPart( EgtGetFirstRawPart() or GDB_ID.NULL)
|
|
while nOtherId do
|
|
-- cerco le regioni marcate
|
|
local nCount = 0
|
|
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
|
|
nCount = nCount + 1
|
|
table.insert( vOthers, { PartId = nOtherId, RegId = nRegId, Box = b3Reg})
|
|
end
|
|
end
|
|
nRegId = EgtGetNext( nRegId)
|
|
end
|
|
-- se non trovate regioni marcate, cerco regioni con la normale corretta
|
|
if nCount == 0 then
|
|
local nRegId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nOtherId, 'Outline') or GDB_ID.NULL)
|
|
while nRegId do
|
|
local vtN = EgtSurfFrNormVersor( nRegId, GDB_ID.ROOT)
|
|
if EgtGetType( nRegId) == GDB_TY.SRF_FRGN 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
|
|
end
|
|
-- passo al pezzo successivo
|
|
nOtherId = EgtGetNextPartInRawPart( nOtherId)
|
|
end
|
|
return vOthers
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ReorderFaces( nIdSurf, nNumFacet)
|
|
-- recupero le adiacenze di tutte le facce
|
|
local vAdj = {}
|
|
for i = 1, nNumFacet do
|
|
-- recupero le adiacenze della faccia
|
|
local vFacAdj = EgtSurfTmFacetAdjacencies( nIdSurf, 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
|
|
end
|
|
-- sposto le facce isolate alla fine
|
|
for i = #vAdj, 1, -1 do
|
|
if vAdj[i] == 0 then
|
|
if vAdj[#vAdj] == 0 then
|
|
table.remove( vAdj, i)
|
|
end
|
|
EgtSurfTmSwapFacets( nIdSurf, i - 1, #vAdj)
|
|
end
|
|
end
|
|
-- se facce tutte isolate, esco
|
|
if #vAdj == 0 then return end
|
|
-- cerco la faccia non isolata con il minor numero di adiacenze
|
|
local nIdFace
|
|
local nAdjMin = 1000
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] < nAdjMin then
|
|
nAdjMin = vAdj[i]
|
|
nIdFace = i
|
|
end
|
|
end
|
|
-- se la faccia non isolata con minori adiacenze non è in prima posizione, eseguo scambio
|
|
if nIdFace and nIdFace ~= 1 and nAdjMin == 1 then
|
|
EgtSurfTmSwapFacets( nIdSurf, nIdFace-1, 0)
|
|
end
|
|
-- ordino le facce in modo da avere una sequenza di facce concatenate
|
|
for i = 1, #vAdj - 1 do
|
|
-- recupero l'angolo con la faccia successiva
|
|
local bAdj, _, _, _ = EgtSurfTmFacetsContact( nIdSurf, i-1, i, GDB_ID.ROOT)
|
|
-- se non ho adiacenza
|
|
if not bAdj then
|
|
for j = i+1, #vAdj do
|
|
bAdj, _, _, _ = EgtSurfTmFacetsContact( nIdSurf, i-1, j-1, GDB_ID.ROOT)
|
|
-- se ho adiacenza scambio le facce
|
|
if bAdj then
|
|
EgtSurfTmSwapFacets( nIdSurf, i, (j-1))
|
|
break
|
|
end
|
|
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 GetFacesExternalSide( Proc, vtExtr)
|
|
-- 3=sinistra, 4=destra
|
|
-- se meno di due facce considero esterno come dichiarato dal gruppo
|
|
local nNumFacet = EgtSurfTmFacetCount( Proc.Id)
|
|
if nNumFacet < 2 then return Proc.Grp end
|
|
-- se facce isolate, considero esterno come dichiarato dal gruppo
|
|
local bAdj, ptV1, ptV2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
|
|
if not bAdj then return Proc.Grp end
|
|
-- calcolo dell'esterno rispetto all'avanzamento
|
|
local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
local ptV = ( ptV1 + ptV2) / 2
|
|
local vtDir1 = ptV - ptC1
|
|
if ( vtN1 ^ vtDir1) * vtExtr > 0 then
|
|
return 4
|
|
else
|
|
return 3
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetFacesData( Proc, bOpposite, bCalclForBlade, dToolDiam, dToolMaxDepth, dToolThick, nAddGrpId, b3Raw, nMasterNewProc)
|
|
--se richiesto, copio la superficie nel gruppo ausiliario
|
|
local nNewProc
|
|
if nMasterNewProc then
|
|
nNewProc = nMasterNewProc
|
|
else
|
|
nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
|
|
end
|
|
-- recupero i dati di tutte le facce
|
|
local vFace = {}
|
|
local nNumFacet = EgtSurfTmFacetCount( nNewProc)
|
|
for i = 1, nNumFacet do
|
|
-- indice faccia corrente e precedente
|
|
local nFac = EgtIf( bOpposite, nNumFacet - i, i - 1)
|
|
local nPrecFac
|
|
if bOpposite then
|
|
if nNumFacet > 2 then
|
|
nPrecFac = EgtIf( i == 1, 0, nFac + 1)
|
|
else
|
|
nPrecFac = EgtIf( i == 1, -1, nFac + 1)
|
|
end
|
|
else
|
|
if nNumFacet > 2 then
|
|
nPrecFac = EgtIf( i == 1, nNumFacet - 1, i - 2)
|
|
else
|
|
nPrecFac = EgtIf( i == 1, - 1, i - 2)
|
|
end
|
|
end
|
|
-- recupero centro e normale della faccia
|
|
local vtN = EgtSurfTmFacetNormVersor( nNewProc, nFac, GDB_ID.ROOT)
|
|
-- recupero le dimensioni della faccia
|
|
local frHV, 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)
|
|
local dPrevAng = EgtIf( bAdj, dAng, 0)
|
|
-- se angolo con faccia precedente negativo, calcolo anche angolo tra le facce nel piano
|
|
local dPlanePrevAng = 0
|
|
if dPrevAng < 0 then
|
|
local vtPrevN = EgtSurfTmFacetNormVersor( nNewProc, nPrecFac, GDB_ID.ROOT)
|
|
local dCosA = ( Z_AX() ^ vtPrevN) * ( Z_AX() ^ vtN)
|
|
dPlanePrevAng = -acos( dCosA)
|
|
end
|
|
-- calcolo l'angolo di inclinazione (dalla verticale)
|
|
local dSideAng = asin( vtN:getZ())
|
|
-- salvo i dati
|
|
vFace[i] = { Fac = nFac, Cen = frHV:getOrigin(), Norm = vtN, Len = dLen, Width = dWidth, PrevAng = dPrevAng, PlPrevAng = dPlanePrevAng, SideAng = dSideAng}
|
|
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 dLenY = dLen * abs( vFace[i].Norm:getX()) / sqrt( 1 - vFace[i].Norm:getZ() * vFace[i].Norm:getZ())
|
|
local nType = 0
|
|
if vFace[i].PrevAng < -0.1 or
|
|
( WD.BEAM_MACHINE and not IsPointOnRawLongEdges( vFace[i].Cen, b3Raw) and ( dLen > 0.5 * WD.CUT_MAX_LENGTH or dLenY > 0.4 * b3Raw:getDimY())) then
|
|
dLen = dLen - EgtIf( bCalclForBlade, dWhisk, 0)
|
|
nType = nType + 1
|
|
end
|
|
if vFace[EgtIf( i < nNumFacet, i + 1, 1)].PrevAng < -0.1 or
|
|
( WD.BEAM_MACHINE and not IsPointOnRawLongEdges( vFace[i].Cen, b3Raw) and ( dLen > 0.5 * WD.CUT_MAX_LENGTH or dLenY > 0.4 * b3Raw:getDimY())) 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
|
|
-- numero dei lati
|
|
local nEdges = #(EgtSurfTmFacetAdjacencies( nNewProc, i - 1)[1])
|
|
-- assegno i nuovi dati
|
|
vFace[i].Depth = dDepth
|
|
vFace[i].Whisk = dWhisk
|
|
vFace[i].Type = nType
|
|
vFace[i].Edges = nEdges
|
|
end
|
|
-- recupero le regioni degli altri pezzi
|
|
local vOthers = GetOtherRegions( Proc.PartId)
|
|
-- 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 - 2 * WHISK_OFFS) * vtDir
|
|
local ptCross = ptDir + ( dToolThick - 2 * 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 - 2 * WHISK_OFFS) * vtDir
|
|
local ptCross = ptDir + ( dToolThick - 2 * 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
|
|
-- se ciclo chiuso
|
|
if abs( vFace[1].PrevAng) > 0.1 then
|
|
-- verifico se c'è un solo tipo 3 e nessun tipo 0, 1 o 2
|
|
local nInd3
|
|
local nTot3 = 0
|
|
local nTot012 = 0
|
|
for i = 1, #vFace do
|
|
local Face = vFace[i]
|
|
if Face.Type == 0 or Face.Type == 1 or Face.Type == 2 then
|
|
nTot012 = nTot012 + 1
|
|
elseif Face.Type == 3 then
|
|
nTot3 = nTot3 + 1
|
|
nInd3 = i
|
|
end
|
|
end
|
|
-- se trovato il caso, trasformo il 3 in 4 (per evitare problemi con fresature con la stessa faccia a inizio e fine)
|
|
if nTot3 == 1 and nTot012 == 0 then
|
|
vFace[nInd3].Type = 4
|
|
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.PrevAng, 1)..
|
|
' App='..EgtNumToString( Face.PlPrevAng, 1)..' D='..EgtNumToString( Face.Depth, 1)..' B='..EgtNumToString( Face.Whisk, 1)..
|
|
' As='..EgtNumToString( Face.SideAng, 1)..' T='..tostring( Face.Type)..' E='..tostring( Face.Edges)
|
|
EgtOutLog( sOut)
|
|
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)
|
|
if nFacCnt < 2 then return end
|
|
-- 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 = EgtSurfTmFacetNormVersor( nId, 1, GDB_ID.ROOT)
|
|
local vtOrtho = vtN1 ^ vtN2
|
|
if vtOrtho:isSmall() then
|
|
vtN2 = EgtSurfTmFacetNormVersor( nId, 2, GDB_ID.ROOT) or V_NULL()
|
|
vtOrtho = vtN1 ^ vtN2
|
|
bOppoFace = true
|
|
end
|
|
if not vtOrtho:normalize() then return 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)
|
|
if not nSurfInt then return end
|
|
-- 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)
|
|
if not nIdCont then return end
|
|
-- 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 MakeCustomPath( vGeom, nConeCut, dMillDiam, nAddGrpId, dThick, bClosed)
|
|
|
|
local nPath = {}
|
|
local nPathData = {}
|
|
|
|
for i = 1, #vGeom do
|
|
local dAng
|
|
-- ottengo curva inferiore 1
|
|
local ptP1, ptP2, ptP3, vtV1, vtV2, dDim1, dDim2 = EgtSurfTmFacetOppositeSide( vGeom[i][1], vGeom[i][2], Z_AX() , GDB_ID.ROOT)
|
|
if i < #vGeom then
|
|
-- ricavo i punti e l'angolo interno
|
|
_, _, _, dAng = EgtSurfTmFacetsContact( vGeom[i][1], vGeom[i][2], vGeom[i+1][2], GDB_ID.ROOT)
|
|
elseif bClosed then
|
|
-- ricavo i punti e l'angolo interno
|
|
_, _, _, dAng = EgtSurfTmFacetsContact( vGeom[i][1], vGeom[i][2], vGeom[1][2], GDB_ID.ROOT)
|
|
else
|
|
dAng = 0
|
|
end
|
|
-- creo linea
|
|
local nId1 = EgtLine( nAddGrpId, ptP1, ptP3, GDB_RT.GLOB)
|
|
table.insert( nPath, nId1)
|
|
table.insert( nPathData, {nId1, dAng})
|
|
end
|
|
|
|
-- creo il percorso e poi lo offsetto del raggio utensile
|
|
local AuxId = EgtCurveCompo( nAddGrpId, nPath, true)
|
|
EgtOffsetCurve( AuxId, dMillDiam / 2, GDB_OT.EXTEND)
|
|
-- spezzo il percorso nelle entità componenti
|
|
local nId1st, nIdCount = EgtExplodeCurveCompo( AuxId)
|
|
-- se il numero entità è diverso da quelle iniziali esco con errore
|
|
if nIdCount ~= #vGeom then
|
|
local sErr = 'Error : cannot make offset path'
|
|
return 0, sErr
|
|
end
|
|
-- resetto la tabella
|
|
nPath = {}
|
|
AuxId = nil
|
|
-- in base al tipo di ripresa spigolo modifico il percorso
|
|
if nConeCut == 2 then
|
|
-- acquisisco la lunghezza utensile
|
|
sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner30')
|
|
if not sMilling then
|
|
local sErr = 'Error : CleanCorner 30 not found in library'
|
|
return 0, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dMillDiam = 20
|
|
local dMillLength = 0
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
|
|
dMillLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dMillLength
|
|
end
|
|
end
|
|
-- calcolo la lunghezza della linea da inserire in base all'angolo e alla lunghezza utensile
|
|
local dLenAdd = abs(( dMillLength * sin( 33)) - ( dMillDiam / 2))
|
|
-- per ogni entità compongo la nuova lista per creare percorso
|
|
for i = 1, nIdCount do
|
|
-- aggiungo linea precedente
|
|
table.insert( nPath, ( nId1st + i - 1))
|
|
-- se non è la linea finale e l'angolo tra le due facce è ammesso
|
|
if ( i < nIdCount or bClosed) and dThick <= ( WD.MAX_CLEAN_CRN30 + 20 * GEO.EPS_SMALL) and
|
|
nPathData[i][2] < 0 and nPathData[i][2] > -( 180 - dAngleSmall + 10 * GEO.EPS_SMALL) then
|
|
-- aggiungo una retta sulla bisettrice
|
|
local _, vtN2 = EgtSurfTmFacetCenter( vGeom[i][1], vGeom[i][2], GDB_ID.ROOT)
|
|
local _, vtN3 = EgtSurfTmFacetCenter( vGeom[i][1], vGeom[EgtIf( i == nIdCount, 1, i+1)][2], GDB_ID.ROOT)
|
|
local ptP1 = EgtEP( ( nId1st + i - 1), GDB_ID.ROOT)
|
|
-- sommo i tre versori per avere una direzione media
|
|
local vtExtrExit = vtN2 + vtN3
|
|
vtExtrExit:normalize()
|
|
-- linea intermedia (componente lunghezza utensile in direzione bisettrice)
|
|
local pEnd = ptP1 + ( dLenAdd * vtExtrExit)
|
|
nAuxId = EgtLine( nAddGrpId, ptP1, pEnd, GDB_RT.GLOB)
|
|
table.insert( nPath, nAuxId)
|
|
-- linea di ritorno
|
|
nAuxId = EgtLine( nAddGrpId, pEnd, ptP1, GDB_RT.GLOB)
|
|
table.insert( nPath, nAuxId)
|
|
end
|
|
end
|
|
-- ricreo il percorso
|
|
AuxId = EgtCurveCompo( nAddGrpId, nPath, true)
|
|
-- altrimenti sfondo spigolo
|
|
elseif nConeCut == 3 then
|
|
-- per ogni entità compongo la nuova lista per creare percorso
|
|
for i = 1, nIdCount do
|
|
-- aggiungo linea precedente
|
|
table.insert( nPath, ( nId1st + i - 1))
|
|
-- se non è la linea finale e l'angolo tra le due facce è ammesso
|
|
if ( i < nIdCount or bClosed) and nPathData[i][2] < 0 then
|
|
-- aggiungo una retta sulla bisettrice
|
|
local _, vtN2 = EgtSurfTmFacetCenter( vGeom[i][1], vGeom[i][2], GDB_ID.ROOT)
|
|
local _, vtN3 = EgtSurfTmFacetCenter( vGeom[i][1], vGeom[EgtIf( i == nIdCount, 1, i+1)][2], GDB_ID.ROOT)
|
|
local ptP1 = EgtEP( ( nId1st + i - 1), GDB_ID.ROOT)
|
|
-- sommo i tre versori per avere una direzione media
|
|
local vtExtrExit = vtN2 + vtN3
|
|
vtExtrExit:normalize()
|
|
vtExtrExit = -vtExtrExit
|
|
-- calcolo di quanto entrare
|
|
local dLenAdd = abs( (dMillDiam/2) / cos( nPathData[i][2]/2)) + dExtraCorner - (dMillDiam/2)
|
|
-- linea intermedia (componente lunghezza utensile in direzione bisettrice)
|
|
local pEnd = ptP1 + ( dLenAdd * vtExtrExit)
|
|
nAuxId = EgtLine( nAddGrpId, ptP1, pEnd, GDB_RT.GLOB)
|
|
table.insert( nPath, nAuxId)
|
|
-- linea di ritorno
|
|
nAuxId = EgtLine( nAddGrpId, pEnd, ptP1, GDB_RT.GLOB)
|
|
table.insert( nPath, nAuxId)
|
|
end
|
|
end
|
|
-- ricreo il percorso
|
|
AuxId = EgtCurveCompo( nAddGrpId, nPath, true)
|
|
end
|
|
if not AuxId then
|
|
local sErr = 'Error : Impossibe make custom machining path'
|
|
return 0, sErr
|
|
end
|
|
|
|
return AuxId
|
|
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[1][7], tFacAdj[1][8], tFacAdj[1][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
|
|
ReorderFacesFromTab( nNewProcLoc, vFace)
|
|
-- acquisisco il numero della faccia
|
|
nFacCnt = EgtSurfTmFacetCount( nNewProcLoc)
|
|
nFacInd = nFacCnt - 1
|
|
else
|
|
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][1], GDB_ID.ROOT)
|
|
local _, vtN3 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[1][2], GDB_ID.ROOT)
|
|
-- trovo il punto sulla superfice di riferimento
|
|
local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[1][1], GDB_ID.ROOT)
|
|
local _, ptLocP3, ptLocP4, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[1][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[1][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[1][4]) < GEO.EPS_SMALL) then
|
|
nIdEndPoint = 4
|
|
nIdIniPoint = 5
|
|
elseif ( dist( ptLocP1, tFacAdj[1][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[1][5]) < GEO.EPS_SMALL) then
|
|
nIdEndPoint = 5
|
|
nIdIniPoint = 4
|
|
end
|
|
end
|
|
-- versore direzione
|
|
local vtExtr = tFacAdj[1][nIdIniPoint] - tFacAdj[1][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[1][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[1][nIdIniPoint], tFacAdj[1][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[1][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then
|
|
ptApPoint = ptLocP2
|
|
else
|
|
ptApPoint = ptLocP1
|
|
end
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB)
|
|
local dLenTrimExt = dist( tFacAdj[1][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[1][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[1][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[1][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[1][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[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB)
|
|
local dLenTrimExt = dist( tFacAdj[1][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[1][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[1][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[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
end
|
|
-- ultima linea di distacco (5mm in direzione utensile)
|
|
local pEnd = tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach) + ( 5 * vtExtr)
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), pEnd, GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
else
|
|
-- linea di distacco (2mm in direzione utensile)
|
|
local pEnd = tFacAdj[1][nIdEndPoint] + ( 2 * vtExtr)
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[1][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[1][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_YM
|
|
if vtExtr:getY() > 100 * GEO.EPS_ZERO then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
end
|
|
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)
|
|
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill
|
|
local sUserNotes = 'VMRS=0;'
|
|
-- aggiungo alle note massima elevazione
|
|
sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( 0.0, 1) .. ';'
|
|
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
|
|
if 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
|
|
ReorderFacesFromTab( nNewProc, vFace)
|
|
-- acquisisco il numero della faccia
|
|
nFacCnt = EgtSurfTmFacetCount( nNewProc)
|
|
nFacInd = nFacCnt - 1
|
|
else
|
|
return true
|
|
--local sErr = 'Error : cannot create base surface'
|
|
--EgtOutLog( sErr)
|
|
--return false, sErr
|
|
end
|
|
else
|
|
bMakeLocSurf = true
|
|
end
|
|
-- verifico se ciclo chiuso
|
|
local bClosed = ( abs( vFace[1].PrevAng) > 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
|
|
local tFacAdj = {}
|
|
local nFace1 = vFace[i].Fac
|
|
local nFace2
|
|
-- ricavo i tre punti per eventuale superficie locale
|
|
local ptLoc1, ptLoc2, ptLoc3
|
|
-- punto precedente (punto precedente della faccia [i])
|
|
ptLoc3 = vFace[i].PPrev
|
|
-- aggiungo geometria
|
|
i = i + 1
|
|
local j = EgtIf( i <= #vFace, i, EgtIf( bClosed, 1, nil))
|
|
if not j then
|
|
return true
|
|
end
|
|
nFace2 = vFace[j].Fac
|
|
-- punto in comune tra le due facce (punto precedente della faccia [j])
|
|
ptLoc1 = vFace[j].PPrev
|
|
-- punto successivo ( precedente della faccia successiva)
|
|
j = j + 1
|
|
local k = EgtIf( j <= #vFace, j, 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-1].Cen:getX(), vFace[j-1].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
|
|
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)
|
|
table.insert( 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
|
|
else
|
|
i = i + 1
|
|
end
|
|
end
|
|
-- cancello la copia della superfice
|
|
if nNewProc then
|
|
EgtErase( nNewProc)
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen)
|
|
local CosA = abs( vtNz)
|
|
if CosA >= 0.05 then
|
|
local SinA = sqrt( 1 - CosA * CosA)
|
|
local dRad = dDiamTh / 2 + dMillDiam / 2 * EgtIf( vtNz > 0, -1, 1)
|
|
local dSlantFreeLen = dFreeLen - ( dRad * CosA / SinA)
|
|
return min( dMaxDepth, dSlantFreeLen)
|
|
else
|
|
return dMaxDepth
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
|
|
local function Is3EdgesApprox( Proc, nFacet, nAddGrpId)
|
|
local bResult = false
|
|
local nContourId = EgtExtractSurfTmFacetLoops( Proc.Id, nFacet, nAddGrpId)
|
|
EgtMergeCurvesInCurveCompo( nContourId)
|
|
-- recupero il numero effettivo di lati
|
|
local _, nEntityCount = EgtCurveDomain( nContourId)
|
|
local nEdges = nEntityCount
|
|
if nContourId then
|
|
if nEntityCount and nEntityCount == 3 then
|
|
bResult = true
|
|
-- rimuovo i lati molto corti dal conteggio totale
|
|
elseif nEntityCount then
|
|
for i = 1, nEntityCount do
|
|
local dLength = EgtCurveCompoLength( nContourId, i - 1)
|
|
if dLength < 15 then nEdges = nEdges - 1 end
|
|
end
|
|
end
|
|
if nEdges == 3 then bResult = true end
|
|
end
|
|
if bResult == true then
|
|
EgtOutLog( 'FreeContour : Face with ' .. tointeger( nEntityCount) .. ' edges skipped (approx 3 edges)')
|
|
end
|
|
return bResult
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAddGrpId)
|
|
-- flag per fresature non passanti
|
|
local bNotThrou
|
|
local dThick
|
|
local dOriDepth
|
|
-- recupero i dati dell'utensile
|
|
local dMillDiam = 20
|
|
local dMaxDepth = 0
|
|
local dFreeLen = 0
|
|
local dDiamTh = 0
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
|
|
dDiamTh = EgtTdbGetCurrToolThDiam()
|
|
dFreeLen = EgtTdbGetCurrToolMaxDepth()
|
|
dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), dFreeLen) or dMaxDepth
|
|
end
|
|
end
|
|
-- verifico se la facce hanno alcuni lati molto corti e possono quindi essere approssimate a 3 lati
|
|
for currentFace = 1, #vFace do
|
|
if Is3EdgesApprox( Proc, vFace[currentFace].Fac, nAddGrpId) then
|
|
vFace[currentFace].Is3EdgesApprox = true
|
|
end
|
|
end
|
|
-- verifico se ciclo chiuso
|
|
local bClosed = ( abs( vFace[1].PrevAng) > 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 and ( vFace[#vFace].Edges > 3 and not vFace[#vFace].Is3EdgesApprox)) or ( vFace[#vFace].Type & 2) ~= 0) then
|
|
while i <= #vFace and vFace[i].Type == 4 and ( vFace[i].Edges > 3 and not vFace[i].Is3EdgesApprox) and abs( vFace[i].SideAng) < 0.1 do
|
|
i = i + 1
|
|
end
|
|
end
|
|
-- se facce tutte da saltare, parto dall'inizio
|
|
local bAllType4 = ( i > #vFace)
|
|
if bAllType4 then i = 1 end
|
|
while i <= #vFace do
|
|
-- se inizio faccia senza taglio e non è successiva di senza taglio, inserisco una fresatura
|
|
local j = EgtIf( i > 1, i - 1, EgtIf( bClosed, #vFace, nil))
|
|
if ( vFace[i].Type & 1) ~= 0 and ( not j or vFace[j].Type == 0 or vFace[j].Type == 1 or abs( vFace[i].SideAng) > 0.1 or abs( vFace[j].SideAng) > 0.1) then
|
|
-- inserisco la lavorazione
|
|
local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId))
|
|
local nMchId = WM.AddMachining( Proc, sName, sMilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return 0, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', Proc.PartId)
|
|
-- calcolo l'affondamento
|
|
local dDepth = vFace[i].Width + WD.CUT_EXTRA
|
|
dThick = vFace[i].Width
|
|
local vtNz = vFace[i].Norm:getZ()
|
|
if WD.CHECK_MIN_Z_SAW then
|
|
if vtNz >= 0 then
|
|
dDepth = min( dDepth, vFace[i].Width - WD.MIN_Z_SAW)
|
|
else
|
|
dDepth = min( dDepth, dDepth - WD.MIN_Z_SAW + dMillDiam * vtNz / sqrt( 1 - vtNz * vtNz))
|
|
end
|
|
end
|
|
local dCurrMaxDepth = GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen)
|
|
-- se affondamento superiore ai limiti della fresa
|
|
if dDepth > dCurrMaxDepth then
|
|
dOriDepth = dDepth
|
|
-- lo limito e tolgo eventuali Tabs
|
|
dDepth = dCurrMaxDepth
|
|
EgtSetMachiningParam( MCH_MP.LEAVETAB, false)
|
|
bNotThrou = true
|
|
end
|
|
-- tolgo i Tabs se devo rimuovere lo sfrido
|
|
if nConeCut == 1 then EgtSetMachiningParam( MCH_MP.LEAVETAB, false) end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, vFace[i].Fac}})
|
|
local dSal = 0
|
|
if #vFace == 1 then dSal = -dMillDiam / 2 end
|
|
-- se angolo interno prima
|
|
if vFace[i].PrevAng < -30 then
|
|
local dSinA = -sin( vFace[i].PlPrevAng + 90)
|
|
local dTanA = -tan( vFace[i].PlPrevAng + 90)
|
|
dSal = -dMillDiam / 2 * ( 1 + ( 1 + dSinA) * dTanA) + min( 0, vFace[i].Width * vFace[i].Norm:getZ() * dTanA)
|
|
-- se faccia precedente inclinata verso il basso
|
|
if j and vFace[j].Norm:getZ() < -0.017 then
|
|
dSal = dSal + vFace[j].Width * vFace[j].Norm:getZ()
|
|
end
|
|
-- se angolo esterno prima
|
|
elseif vFace[i].PrevAng > 30 then
|
|
-- se faccia precedente inclinata verso il basso
|
|
if j and vFace[j].Norm:getZ() < -0.017 then
|
|
dSal = dSal - vFace[j].Width * vFace[j].Norm:getZ()
|
|
end
|
|
end
|
|
local dEal = vFace[i].Whisk - vFace[i].Len
|
|
-- se faccia precedente inclinata verso il basso prolungo il finale per adeguarmi all percorso della lama
|
|
if j and vFace[j].Norm:getZ() < -0.017 then
|
|
dEal = dEal - vFace[j].Width * vFace[j].Norm:getZ()
|
|
end
|
|
-- se angolo interno prima e faccia precedente inclinata verso l'alto oltre 16.1deg
|
|
if vFace[i].PrevAng < -30 and j and vFace[j].Norm:getZ() < 0.96078 and vFace[j].Norm:getZ() > 0 then
|
|
dEal = dEal + vFace[j].Width * vFace[j].Norm:getZ()
|
|
end
|
|
-- se angolo interno dopo e faccia successiva inclinata verso l'alto oltre 16.1deg
|
|
local k = EgtIf( i < #vFace, i + 1, EgtIf( bClosed, 1, nil))
|
|
if k and vFace[k].PrevAng < -30 and vFace[k].Norm:getZ() < 0.96078 and vFace[k].Norm:getZ() > 0 then
|
|
dEal = dEal + vFace[k].Width * vFace[k].Norm:getZ()
|
|
-- se l'inclinazione è inferiore a 46.1deg
|
|
if vFace[k].Norm:getZ() > 0.72055 then
|
|
dEal = dEal - vFace[k].Width
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
-- percorso da non invertire
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- assegno utilizzo faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
|
|
-- assegno affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- assegno lato di lavoro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
-- posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_ZP
|
|
if abs( vFace[i].Norm:getZ()) < GEO.EPS_SMALL then
|
|
nSCC = EgtIf( abs( vFace[i].Norm:getX()) > abs( vFace[i].Norm:getY()), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_YP)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return 0, sErr
|
|
end
|
|
end
|
|
-- se tutta la faccia o la sua fine senza taglio, inserisco una fresatura
|
|
if ( vFace[i].Type & 2) ~= 0 or ( vFace[i].Type == 4 and ( vFace[i].Edges > 3 and not vFace[i].Is3EdgesApprox)) then
|
|
-- inserisco la lavorazione
|
|
local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId))
|
|
local nMchId = WM.AddMachining( Proc, sName, sMilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return 0, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', Proc.PartId)
|
|
-- calcolo l'affondamento
|
|
local dDepth = vFace[i].Width + WD.CUT_EXTRA
|
|
dThick = vFace[i].Width
|
|
local vtNz = vFace[i].Norm:getZ()
|
|
if WD.CHECK_MIN_Z_SAW then
|
|
if vtNz >= 0 then
|
|
dDepth = min( dDepth, vFace[i].Width - WD.MIN_Z_SAW)
|
|
else
|
|
dDepth = min( dDepth, dDepth - WD.MIN_Z_SAW + dMillDiam * vtNz / sqrt( 1 - vtNz * vtNz))
|
|
end
|
|
end
|
|
local dCurrMaxDepth = GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen)
|
|
-- se affondamento superiore ai limiti della fresa
|
|
if dDepth > dCurrMaxDepth then
|
|
dOriDepth = dDepth
|
|
-- lo limito e tolgo eventuali Tabs
|
|
dDepth = dCurrMaxDepth
|
|
EgtSetMachiningParam( MCH_MP.LEAVETAB, false)
|
|
bNotThrou = true
|
|
end
|
|
-- tolgo i Tabs se devo rimuovere lo sfrido
|
|
if nConeCut == 1 then EgtSetMachiningParam( MCH_MP.LEAVETAB, false) end
|
|
-- aggiungo geometria
|
|
local vGeom = {{ Proc.Id, vFace[i].Fac}}
|
|
local dSal = EgtIf( ( vFace[i].Type & 2) ~= 0, vFace[i].Whisk - vFace[i].Len, 0)
|
|
local dEal = 0
|
|
local OrigI = i
|
|
local OrigH = j
|
|
local LastJ
|
|
i = i + 1
|
|
local j = EgtIf( i <= #vFace, i, EgtIf( bAllType4 or not bClosed, nil, 1))
|
|
while j and ( ( vFace[j].Type & 1) ~= 0 or ( vFace[j].Type == 4 and ( vFace[j].Edges > 3 and not vFace[j].Is3EdgesApprox))) and abs( vFace[j].SideAng) < 0.1 and abs( vFace[OrigI].SideAng) < 0.1 do
|
|
table.insert( vGeom, { Proc.Id, vFace[j].Fac})
|
|
LastJ = j
|
|
dEal = EgtIf( ( vFace[j].Type & 1) ~= 0, vFace[j].Whisk - vFace[j].Len, 0)
|
|
if ( vFace[j].Type & 1) ~= 0 then
|
|
break
|
|
end
|
|
i = i + 1
|
|
j = EgtIf( j + 1 <= #vFace, j + 1, EgtIf( bAllType4 or not bClosed, nil, 1))
|
|
end
|
|
-- se faccia singola è da fare tutta senza oltrepassare estremi
|
|
if #vFace == 1 and vFace[OrigI].Type == 4 and ( vFace[OrigI].Edges > 3 and not vFace[OrigI].Is3EdgesApprox) then
|
|
dSal = -dMillDiam / 2
|
|
dEal = -dMillDiam / 2
|
|
-- altrimenti va verificato
|
|
else
|
|
-- se lavorazione completa su faccia iniziale
|
|
if vFace[OrigI].Type == 4 and ( vFace[OrigI].Edges > 3 and not vFace[OrigI].Is3EdgesApprox) then
|
|
-- se angolo interno prima
|
|
if vFace[OrigI].PrevAng < -30 then
|
|
local dSinA = -sin( vFace[OrigI].PlPrevAng + 90)
|
|
local dTanA = -tan( vFace[OrigI].PlPrevAng + 90)
|
|
dSal = -dMillDiam / 2 * ( 1 + ( 1 + dSinA) * dTanA) + min( 0, vFace[OrigI].Width * vFace[OrigI].Norm:getZ() * dTanA)
|
|
-- se faccia precedente inclinata verso il basso
|
|
if OrigH and vFace[OrigH].Norm:getZ() < -0.017 then
|
|
dSal = dSal + vFace[OrigH].Width * vFace[OrigH].Norm:getZ()
|
|
end
|
|
-- se angolo esterno prima
|
|
elseif vFace[OrigI].PrevAng > 30 then
|
|
-- se faccia precedente inclinata verso il basso
|
|
if OrigH and vFace[OrigH].Norm:getZ() < -0.017 then
|
|
dSal = dSal - vFace[OrigH].Width * vFace[OrigH].Norm:getZ()
|
|
end
|
|
end
|
|
end
|
|
-- se lavorazione completa o finale su faccia finale
|
|
local LastFace = ( LastJ or OrigI)
|
|
local OrigK = EgtIf( LastFace < #vFace, LastFace + 1, EgtIf( bClosed, 1, nil))
|
|
if ( vFace[LastFace].Type == 4 and ( vFace[LastFace].Edges > 3 and not vFace[LastFace].Is3EdgesApprox)) or ( LastFace == OrigI and ( vFace[LastFace].Type & 2) ~= 0) then
|
|
-- se angolo interno dopo
|
|
if OrigK and vFace[OrigK].PrevAng < -30 then
|
|
local dSinA = -sin( vFace[OrigK].PlPrevAng + 90)
|
|
local dTanA = -sin( vFace[OrigK].PlPrevAng + 90)
|
|
dEal = -dMillDiam / 2 * ( 1 + ( 1 + dSinA) * dTanA) + min( 0, vFace[OrigI].Width * vFace[OrigI].Norm:getZ() * dTanA)
|
|
-- se faccia successiva inclinata verso il basso
|
|
if vFace[OrigK].Norm:getZ() < -0.017 then
|
|
dEal = dEal + vFace[OrigK].Width * vFace[OrigK].Norm:getZ()
|
|
end
|
|
-- se angolo esterno dopo
|
|
elseif OrigK and vFace[OrigK].PrevAng > 30 then
|
|
-- se faccia successiva inclinata verso il basso
|
|
if vFace[OrigK].Norm:getZ() < -0.017 then
|
|
dEal = dEal - vFace[OrigK].Width * vFace[OrigK].Norm:getZ()
|
|
end
|
|
end
|
|
end
|
|
-- per sola lavorazione finale
|
|
if LastFace == OrigI and ( vFace[LastFace].Type & 2) ~= 0 then
|
|
-- se angolo interno dopo e faccia successiva inclinata verso l'alto oltre 16.1 deg
|
|
if OrigK and vFace[OrigK].PrevAng < -30 and vFace[OrigK].Norm:getZ() < 0.96078 and vFace[OrigK].Norm:getZ() > 0 then
|
|
dSal = dSal + vFace[OrigK].Width * vFace[OrigK].Norm:getZ()
|
|
end
|
|
-- se angolo interno prima e faccia precedente inclinata verso l'alto oltre 16.1 deg
|
|
if vFace[OrigI].PrevAng < -30 and OrigH and vFace[OrigH].Norm:getZ() < 0.96078 and vFace[OrigH].Norm:getZ() > 0 then
|
|
dSal = dSal + vFace[OrigH].Width * vFace[OrigH].Norm:getZ()
|
|
-- se l'inclinazione è inferiore a 46.1deg
|
|
if vFace[OrigH].Norm:getZ() > 0.72055 then
|
|
dSal = dSal - vFace[OrigH].Width
|
|
end
|
|
end
|
|
end
|
|
-- se percorso chiuso e completo con fresa
|
|
if bClosed and bAllType4 then
|
|
dSal = 0
|
|
dEal = 0
|
|
end
|
|
-- se faccia singola non oltrepasso l'estremo finale
|
|
if #vFace == 1 then
|
|
dEal = -dMillDiam / 2
|
|
end
|
|
end
|
|
-- se non devo scaricare l'angolo o la faccia è inclinata
|
|
if nConeCut <= 1 or abs( vFace[OrigI].SideAng) > 0.1 then
|
|
EgtSetMachiningGeometry( vGeom)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
-- tolgo i Tabs se devo rimuovere lo sfrido
|
|
if nConeCut == 1 then EgtSetMachiningParam( MCH_MP.LEAVETAB, false) end
|
|
-- percorso da non invertire
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- assegno utilizzo faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
|
|
-- assegno affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- assegno lato di lavoro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
-- posizione braccio porta testa
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP)
|
|
-- posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_ZP
|
|
if abs( vFace[OrigI].Norm:getZ()) < GEO.EPS_SMALL then
|
|
nSCC = EgtIf( abs( vFace[OrigI].Norm:getX()) > abs( vFace[OrigI].Norm:getY()), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_YP)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- altrimenti se devo fare rientranza per inserimento utensile cono 30°
|
|
elseif nConeCut == 2 then
|
|
-- eseguo la costruzione del percorso
|
|
local nPathId, sErr = MakeCustomPath( vGeom, nConeCut, dMillDiam, nAddGrpId, dThick, bClosed and bAllType4)
|
|
if nPathId == 0 then return 0, sErr end
|
|
EgtSetMachiningGeometry({{ nPathId, -1}})
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
-- percorso da non invertire
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- assegno utilizzo faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
|
|
-- assegno affondamento
|
|
-- EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
if bNotThrou then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, ( dDepth - dOriDepth))
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, 0)
|
|
end
|
|
-- assegno lato di lavoro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER)
|
|
-- posizione braccio porta testa
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP)
|
|
-- altrimenti se devo scaricare l'angolo
|
|
elseif nConeCut == 3 then
|
|
-- eseguo la costruzione del percorso
|
|
local nPathId, sErr = MakeCustomPath( vGeom, nConeCut, dMillDiam, nAddGrpId, nil, bClosed and bAllType4)
|
|
if nPathId == 0 then return 0, sErr end
|
|
EgtSetMachiningGeometry({{ nPathId, -1}})
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
-- percorso da non invertire
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- assegno affondamento
|
|
if bNotThrou then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, ( dDepth - dOriDepth))
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, 0)
|
|
end
|
|
-- assegno lato di lavoro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER)
|
|
-- posizione braccio porta testa
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP)
|
|
end
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return 0, sErr
|
|
end
|
|
else
|
|
i = i + 1
|
|
end
|
|
end
|
|
-- aggiungo eventuali fresature a metà faccia
|
|
for i =1, #vFace do
|
|
if vFace[i].Split then
|
|
-- inserisco la lavorazione
|
|
local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) .. '_M'
|
|
local nMchId = WM.AddMachining( Proc, sName, sMilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return 0, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', Proc.PartId)
|
|
-- calcolo l'affondamento
|
|
local dDepth = vFace[i].Width + WD.CUT_EXTRA
|
|
dThick = vFace[i].Width
|
|
local vtNz = vFace[i].Norm:getZ()
|
|
if WD.CHECK_MIN_Z_SAW then
|
|
if vtNz >= 0 then
|
|
dDepth = min( dDepth, vFace[i].Width - WD.MIN_Z_SAW)
|
|
else
|
|
dDepth = min( dDepth, dDepth - WD.MIN_Z_SAW + dMillDiam * vtNz / sqrt( 1 - vtNz * vtNz))
|
|
end
|
|
end
|
|
local dCurrMaxDepth = GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen)
|
|
-- se affondamento superiore ai limiti della fresa
|
|
if dDepth > dCurrMaxDepth then
|
|
dOriDepth = dDepth
|
|
-- lo limito e tolgo eventuali Tabs
|
|
dDepth = dCurrMaxDepth
|
|
EgtSetMachiningParam( MCH_MP.LEAVETAB, false)
|
|
bNotThrou = true
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, vFace[i].Fac}})
|
|
local dSal = vFace[i].Whisk - vFace[i].Len / 2
|
|
local dEal = vFace[i].Whisk - vFace[i].Len / 2
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
-- percorso da non invertire
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- assegno utilizzo faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
|
|
-- assegno affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- assegno lato di lavoro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
-- posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_ZP
|
|
if abs( vFace[i].Norm:getZ()) < GEO.EPS_SMALL then
|
|
nSCC = EgtIf( abs( vFace[i].Norm:getX()) > abs( vFace[i].Norm:getY()), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_YP)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return 0, sErr
|
|
end
|
|
end
|
|
end
|
|
-- se fresature non sono passanti
|
|
if bNotThrou then
|
|
return 2, dMillDiam, dThick
|
|
end
|
|
|
|
return 1, dMillDiam, dThick
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AddSawings( sSawing, vFace, Proc, nRawId, b3Raw)
|
|
-- flag per tagli non passanti
|
|
local bNotThrou
|
|
local dThick
|
|
-- recupero i dati dell'utensile
|
|
local dSawDiam = 0
|
|
local dMaxDepth = 0
|
|
local dSawThick = 0
|
|
if EgtMdbSetCurrMachining( sSawing) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
|
|
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
end
|
|
-- Calcolo angolo 3° asse rot (da direz. utensile)
|
|
local sRot3Ang = 'A1=180'
|
|
if WD.GetChainSawBlockedAxis then
|
|
sRot3Ang = WD.GetChainSawBlockedAxis( 1)
|
|
end
|
|
-- ciclo di inserimento dei tagli con sega a catena
|
|
for i = 1, #vFace do
|
|
-- se inizio faccia non tagliato completamente, inserisco un ripasso con sega a catena
|
|
if ( vFace[i].Type & 1) ~= 0 then
|
|
-- inserisco la lavorazione
|
|
local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId))
|
|
local nMchId = WM.AddMachining( Proc, sName, sSawing)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing
|
|
EgtOutLog( sErr)
|
|
return 0, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', Proc.PartId)
|
|
-- calcolo l'affondamento
|
|
local dDepth = vFace[i].Width + min( WD.CUT_EXTRA, -WD.MIN_Z_SAW)
|
|
dThick = vFace[i].Width
|
|
-- se affondamento superiore ai limiti della sega a catena
|
|
if dDepth > dMaxDepth then
|
|
dDepth = dMaxDepth
|
|
bNotThrou = true
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, vFace[i].Fac}})
|
|
local dSal = - dSawDiam / 2
|
|
local dEal = vFace[i].Whisk - vFace[i].Len - dSawDiam / 2
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
-- assegno utilizzo faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
|
|
-- imposto angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, sRot3Ang)
|
|
-- assegno affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- assegno lato di lavoro e inversione direzione movimento
|
|
if vFace[i].Norm:getX() < 0.018 then
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
end
|
|
-- posizione braccio porta testa
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return 0, sErr
|
|
end
|
|
end
|
|
-- se fine faccia non tagliato completamente o faccia non tagliata completamente e abbastanza lunga, inserisco un ripasso con sega a catena
|
|
if ( vFace[i].Type & 2) ~= 0 or ( vFace[i].Type == 4 and ( vFace[i].Edges > 3 and not vFace[i].Is3EdgesApprox) and vFace[i].Len > dSawDiam + 1) then
|
|
-- inserisco la lavorazione
|
|
local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId))
|
|
local nMchId = WM.AddMachining( Proc, sName, sSawing)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing
|
|
EgtOutLog( sErr)
|
|
return 0, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', Proc.PartId)
|
|
-- calcolo l'affondamento
|
|
local dDepth = vFace[i].Width + min( WD.CUT_EXTRA, -WD.MIN_Z_SAW)
|
|
dThick = vFace[i].Width
|
|
-- se affondamento superiore ai limiti della sega a catena
|
|
if dDepth > dMaxDepth then
|
|
dDepth = dMaxDepth
|
|
bNotThrou = true
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, vFace[i].Fac}})
|
|
local dSal = - dSawDiam / 2
|
|
local dEal = - dSawDiam / 2
|
|
if ( vFace[i].Type & 2) ~= 0 then
|
|
dSal = vFace[i].Whisk - vFace[i].Len - dSawDiam / 2
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
-- assegno utilizzo faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
|
|
-- imposto angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, sRot3Ang)
|
|
-- assegno affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- assegno lato di lavoro e inversione direzione movimento
|
|
if vFace[i].Norm:getX() < 0.018 then
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
end
|
|
-- posizione braccio porta testa
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return 0, sErr
|
|
end
|
|
end
|
|
end
|
|
-- se fresature non sono passanti
|
|
if bNotThrou then
|
|
return 2, dSawThick, dThick
|
|
end
|
|
return 1, dSawThick, dThick
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AddCuts( sCutting, vFace, Proc, nRawId, b3Raw, dSawThick)
|
|
-- verifico se ciclo chiuso
|
|
local bClosed = ( abs( vFace[1].PrevAng) > 0.1)
|
|
-- ciclo di inserimento dei tagli sulle facce del contorno in esame
|
|
for i = 1, #vFace do
|
|
-- verifico se faccia da saltare, perchè macchina travi e faccia su bordo longitudinale esterno già finito
|
|
local bToSkip = ( WD.BEAM_MACHINE and IsPointOnRawLongEdges( vFace[i].Cen, b3Raw))
|
|
-- se non è faccia da saltare, inserisco il taglio di lama
|
|
if not bToSkip and vFace[i].Type ~= 4 then
|
|
-- indice del successivo
|
|
local j = EgtIf( i < #vFace, i + 1, 1)
|
|
-- indice del precedente
|
|
local h = EgtIf( i > 1, i - 1, EgtIf( bClosed, #vFace, nil))
|
|
-- inserisco la lavorazione
|
|
local sName = 'Cut_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) .. '_' .. 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)
|
|
local dSpeed = EgtGetMachiningParam( MCH_MP.SPEED)
|
|
local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD)
|
|
local bGearbox = EgtGetInfo( EgtGetHeadId( sHead) or GDB_ID.NULL, 'Gearbox', 'b')
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( { { Proc.Id, vFace[i].Fac}})
|
|
-- calcolo l'affondamento
|
|
local dDepth = vFace[i].Depth
|
|
local vtNz = vFace[i].Norm:getZ()
|
|
if WD.CHECK_MIN_Z_SAW then
|
|
if vtNz >= 0 then
|
|
dDepth = min( dDepth, -WD.MIN_Z_SAW)
|
|
else
|
|
dDepth = min( dDepth, -WD.MIN_Z_SAW + dSawThick * vtNz)
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- verifico se va invertita la direzione di lavorazione perchè faccia verso l'alto (angolo maggiore di 0.01 deg)
|
|
local bInvert = ( vFace[i].Norm:getZ() > 0.0001745)
|
|
-- imposto inversione
|
|
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
|
|
-- imposto lato di lavoro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bInvert, MCH_SAW_WS.LEFT, MCH_SAW_WS.RIGHT))
|
|
-- lato mandrino ( standard a sinistra se rotazione CCW, altrimenti a destra, oppure da funzione di macchina)
|
|
local nHeadSide = EgtIf( dSpeed < 0, MCH_SAW_HS.LEFT, MCH_SAW_HS.RIGHT)
|
|
if WD.GetSawHeadSide then nHeadSide = WD.GetSawHeadSide( dSpeed, sHead) end
|
|
EgtSetMachiningParam( MCH_MP.HEADSIDE, nHeadSide)
|
|
-- assegno i dati di attacco (sicurezza solo se angolo interno)
|
|
local nLeadIn = MCH_SAW_LI.CENT
|
|
if ( not bInvert and ( vFace[i].Type & 1) ~= 0) or ( bInvert and ( vFace[i].Type & 2) ~= 0) then
|
|
nLeadIn = MCH_SAW_LI.STRICT
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, nLeadIn)
|
|
local dSal = 0
|
|
if ( not bInvert and vFace[i].PrevAng < -0.1) or ( bInvert and vFace[j].PrevAng < -0.1) then
|
|
-- se faccia precedente inclinata verso il basso
|
|
if not bInvert and h and vFace[h].Norm:getZ() < -0.017 then
|
|
dSal = vFace[h].Width * vFace[h].Norm:getZ() - WHISK_SAFE
|
|
elseif bInvert and j and vFace[j].Norm:getZ() < -0.017 then
|
|
dSal = vFace[j].Width * vFace[j].Norm:getZ() - WHISK_SAFE
|
|
else
|
|
dSal = -WHISK_SAFE
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
-- assegno i dati di uscita (sicurezza solo se angolo interno)
|
|
local nLeadOut = MCH_SAW_LO.CENT
|
|
if ( not bInvert and ( vFace[i].Type & 2) ~= 0) or ( bInvert and ( vFace[i].Type & 1) ~= 0) then
|
|
nLeadOut = MCH_SAW_LO.STRICT
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, nLeadOut)
|
|
local dEal = 0
|
|
if ( not bInvert and vFace[j].PrevAng < -0.1) or ( bInvert and vFace[i].PrevAng < -0.1) then
|
|
-- se faccia precedente inclinata verso il basso
|
|
if not bInvert and j and vFace[j].Norm:getZ() < -0.017 then
|
|
dEal = vFace[j].Width * vFace[j].Norm:getZ() - WHISK_SAFE
|
|
elseif bInvert and h and vFace[h].Norm:getZ() < -0.017 then
|
|
dEal = vFace[h].Width * vFace[h].Norm:getZ() - WHISK_SAFE
|
|
else
|
|
dEal = -WHISK_SAFE
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
-- posizione braccio porta testa
|
|
if not bGearbox then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_NEAR)
|
|
end
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
-- provo a invertire direzione, lato di lavoro e attacco/uscita
|
|
EgtSetMachiningParam( MCH_MP.INVERT, not bInvert)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( not bInvert, MCH_SAW_WS.LEFT, MCH_SAW_WS.RIGHT))
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, EgtIf( nLeadOut == MCH_SAW_LO.STRICT, MCH_SAW_LI.STRICT, MCH_SAW_LI.CENT))
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, EgtIf( nLeadIn == MCH_SAW_LI.STRICT, MCH_SAW_LO.STRICT, MCH_SAW_LO.CENT))
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal)
|
|
-- ri-eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- se limite lunghezza di taglio e taglio lo supera
|
|
if WD.CUT_MAX_LENGTH and vFace[i].Len > WD.CUT_MAX_LENGTH then
|
|
-- sdoppio la lavorazione
|
|
local sSouName = EgtGetName( nMchId)
|
|
local nNewMchId = EgtCopyMachining( sSouName..'_B', sSouName)
|
|
--accorciamento iniziale della seconda
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, -vFace[i].Len/2)
|
|
--accorciamento finale della prima
|
|
EgtSetCurrMachining( nMchId)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -vFace[i].Len/2)
|
|
-- segnalo spezzatura lavorazione faccia
|
|
vFace[i].Split = true
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByCut( Proc, nRawId, b3Raw)
|
|
local sWarn = ''
|
|
-- ingombro del pezzo
|
|
local Ls = EgtGetFirstNameInGroup( Proc.PartId, 'Box')
|
|
local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
if not b3Solid then
|
|
local sErr = 'Error : part box not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero la curva associata
|
|
local bOpposite = false
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
|
|
if AuxId then
|
|
AuxId = AuxId + Proc.Id
|
|
local vtExtr= EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
if vtExtr then
|
|
bOpposite = ( Proc.Grp == 4 and vtExtr:getZ() < 0) or ( Proc.Grp == 3 and vtExtr:getZ() > 0)
|
|
if GetFacesExternalSide( Proc, vtExtr) ~= Proc.Grp then
|
|
bOpposite = not bOpposite
|
|
end
|
|
end
|
|
end
|
|
-- altezza massima delle facce
|
|
local dWidth = 0
|
|
for i = 1, Proc.Fct do
|
|
local _, _, dFctW = WL.GetFaceHvRefDim( Proc.Id, i - 1)
|
|
dWidth = max( dWidth, dFctW)
|
|
end
|
|
-- lettura parametri (probabile/i parametro/i Q)
|
|
local nConeCut = VerifyCornerType( Proc)
|
|
-- recupero la lavorazione di taglio con lama e i suoi parametri (dapprima cerco quella che possa tagliare completamente)
|
|
local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i')
|
|
local sCutting, dSawDiam, dSawThick, dSawMaxDepth = WM.FindCutting( 'Standard', dWidth, nTool_ID)
|
|
if not sCutting then
|
|
sCutting, dSawDiam, dSawThick, dSawMaxDepth = WM.FindCutting( 'Standard', nil, nTool_ID)
|
|
sWarn = 'Warning : elevation bigger than max sawcut depth'
|
|
end
|
|
if not sCutting then
|
|
local sErr = 'Error : cutting not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- gruppo ausiliario
|
|
local nAddGrpId = WL.GetAddGroup( Proc.PartId)
|
|
-- recupero i dati di tutte le facce
|
|
local vFace, dMaxWidth, nNewProc = GetFacesData( Proc, bOpposite, true, dSawDiam, dSawMaxDepth, dSawThick, nAddGrpId, b3Raw, nil)
|
|
-- inserimento dei tagli di lama
|
|
local bCtOk, sCtErr = AddCuts( sCutting, vFace, Proc, nRawId, b3Raw, dSawThick)
|
|
if not bCtOk then return bCtOk, sCtErr end
|
|
-- se richiesta solo lama, esco
|
|
local nCntType = EgtGetInfo( Proc.Id, 'CNT_TYPE', 'i') or 0
|
|
if nCntType == 1 and nTool_ID ~= 0 then return true, sWarn end
|
|
-- se ci sono facce inclinate, escludo la sega a catena
|
|
local bSlanting = false
|
|
for i = 1, #vFace do
|
|
if abs( vFace[i].Norm:getZ()) > 0.01 then
|
|
bSlanting = true
|
|
break
|
|
end
|
|
end
|
|
-- recupero la lavorazione con sega a catena
|
|
local sSawing = WM.FindSawing( 'Sawing')
|
|
-- recupero la lavorazione di fresatura
|
|
local sMilling, dMillMaxDepth = WM.FindMilling( 'FreeContour', dMaxWidth + WD.CUT_EXTRA, nil, nil, nil, nil, true)
|
|
local sMilling2 = WM.FindMilling( 'FreeContour', nil, nil, nil, nil, nil, true)
|
|
if not sMilling and ( not sSawing or bSlanting) then
|
|
-- se non trovo una fresa di lunghezza sufficiente, prendo la più lunga disponibile
|
|
local sMillingMaxLength = WM.FindMilling( 'FreeContour', 0.8 * ( dMaxWidth + WD.CUT_EXTRA), nil, nil, nil, nil, true) or
|
|
WM.FindMilling( 'FreeContour', 0.6 * ( dMaxWidth + WD.CUT_EXTRA), nil, nil, nil, nil, true) or
|
|
WM.FindMilling( 'FreeContour', 0.4 * ( dMaxWidth + WD.CUT_EXTRA), nil, nil, nil, nil, true) or
|
|
WM.FindMilling( 'FreeContour', 0.2 * ( dMaxWidth + WD.CUT_EXTRA), nil, nil, nil, nil, true) or
|
|
WM.FindMilling( 'FreeContour', nil, nil, nil, nil, nil, true)
|
|
sMilling = sMillingMaxLength
|
|
if not sMilling then
|
|
local sErr = 'Error : milling not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- se possibile, inserimento delle fresature
|
|
local bDone = false
|
|
if sMilling then
|
|
local nMlOk, sMlErr, dThick = AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAddGrpId)
|
|
if nMlOk == 0 then return false, sMlErr end
|
|
bDone = ( dThick ~= nil)
|
|
-- se ci sono almeno due facce e lavorato almeno un angolo
|
|
if Proc.Fct >= 2 and bDone then
|
|
-- se abilitata la lavorazione corner con stop macchina e lavorazione precedente passante e spessore sotto il limite
|
|
-- o con fresa cono piccola e spessore sotto il limite
|
|
if ( nConeCut == 1 and nMlOk == 1 and dThick <= ( WD.MAX_CLEAN_CRN60 + 20 * GEO.EPS_SMALL)) or
|
|
( nConeCut == 2 and dThick <= ( WD.MAX_CLEAN_CRN30 + 20 * GEO.EPS_SMALL)) then
|
|
local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw,
|
|
sMlErr, nAddGrpId, dThick, nNewProc, 0, true)
|
|
if not bMcok then return bMcok, sMcErr end
|
|
else
|
|
-- messaggi nel log
|
|
if nConeCut == 1 then
|
|
if nMlOk ~= 1 then
|
|
local sErr = 'Clean corner 60° not applid because Milling not thru the thickness'
|
|
EgtOutLog( sErr)
|
|
else
|
|
local sErr = 'Clean corner 60° not applid because thickness: ' .. EgtNumToString( dThick, 2) ..
|
|
' is bigger than parameter MAX_CLEAN_CRN60: ' .. EgtNumToString( WD.MAX_CLEAN_CRN60 , 2)
|
|
EgtOutLog( sErr)
|
|
end
|
|
elseif nConeCut == 2 then
|
|
local sErr = 'Clean corner 30° not applid because thickness: ' .. EgtNumToString( dThick, 2) ..
|
|
' is bigger than parameter MAX_CLEAN_CRN30: ' .. EgtNumToString( WD.MAX_CLEAN_CRN30 , 2)
|
|
EgtOutLog( sErr)
|
|
end
|
|
end
|
|
end
|
|
-- altrimenti provo con la sega a catena
|
|
elseif sSawing then
|
|
local nCsOk, sCsErr, dThick = AddSawings( sSawing, vFace, Proc, nRawId, b3Raw)
|
|
if nCsOk == 0 then return false, sCsErr end
|
|
bDone = ( dThick ~= nil)
|
|
-- se ci sono almeno due facce e lavorato almeno un angolo
|
|
if Proc.Fct >= 2 and bDone then
|
|
-- se abilitata la lavorazione corner con stop macchina e lavorazione precedente passante e spessore sotto il limite
|
|
if nConeCut == 1 and nCsOk == 1 and dThick <= ( WD.MAX_CLEAN_CRN60 + 20 * GEO.EPS_SMALL) then
|
|
local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw,
|
|
sCSErr, nAddGrpId, nil, nNewProc, 0, true)
|
|
if not bMcok then return bMcok, sMcErr end
|
|
else
|
|
if nConeCut == 1 then
|
|
if nCsOk ~= 1 then
|
|
local sErr = 'Clean corner 60° not applied because Chainsawing not thru the thickness'
|
|
EgtOutLog( sErr)
|
|
else
|
|
local sErr = 'Clean corner 60° not applid because thickness: ' .. EgtNumToString( dThick, 2) ..
|
|
' is bigger than parameter MAX_CLEAN_CRN60: ' .. EgtNumToString( WD.MAX_CLEAN_CRN60 , 2)
|
|
EgtOutLog( sErr)
|
|
end
|
|
elseif nConeCut == 2 then
|
|
local sErr = 'Not possible apply Clean corner 30° after use sawing'
|
|
EgtOutLog( sErr)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- altrimenti provo con fresa ad affondamento ridotto
|
|
if not bDone then
|
|
local nMlOk, sMlErr, dThick = AddMillings( sMilling2, vFace, Proc, nRawId, b3Raw, nConeCut, nAddGrpId)
|
|
if nMlOk == 0 then return false, sMlErr end
|
|
-- se ci sono almeno due facce e lavorato almeno un angolo
|
|
if Proc.Fct >= 2 and dThick then
|
|
-- se abilitata la lavorazione corner con stop macchina e lavorazione precedente passante e spessore sotto il limite
|
|
-- o con fresa cono piccola e spessore sotto il limite
|
|
if ( nConeCut == 1 and nMlOk == 1 and dThick <= ( WD.MAX_CLEAN_CRN60 + 20 * GEO.EPS_SMALL)) or
|
|
( nConeCut == 2 and dThick <= ( WD.MAX_CLEAN_CRN30 + 20 * GEO.EPS_SMALL)) then
|
|
local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw,
|
|
sMlErr, nAddGrpId, dThick, nNewProc, 0, true)
|
|
if not bMcok then return bMcok, sMcErr end
|
|
else
|
|
-- messaggi nel log
|
|
if nConeCut == 1 then
|
|
if nMlOk ~= 1 then
|
|
local sErr = 'Clean corner 60° not applid because Milling not thru the thickness'
|
|
EgtOutLog( sErr)
|
|
else
|
|
local sErr = 'Clean corner 60° not applid because thickness: ' .. EgtNumToString( dThick, 2) ..
|
|
' is bigger than parameter MAX_CLEAN_CRN60: ' .. EgtNumToString( WD.MAX_CLEAN_CRN60 , 2)
|
|
EgtOutLog( sErr)
|
|
end
|
|
elseif nConeCut == 2 then
|
|
local sErr = 'Clean corner 30° not applid because thickness: ' .. EgtNumToString( dThick, 2) ..
|
|
' is bigger than parameter MAX_CLEAN_CRN30: ' .. EgtNumToString( WD.MAX_CLEAN_CRN30 , 2)
|
|
EgtOutLog( sErr)
|
|
end
|
|
end
|
|
sWarn = 'Depth reduced to mill capabilities'
|
|
end
|
|
end
|
|
return true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByMill( Proc, nRawId, b3Raw)
|
|
-- ingombro del pezzo
|
|
local Ls = EgtGetFirstNameInGroup( Proc.PartId, 'Box')
|
|
local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
if not b3Solid then
|
|
local sErr = 'Error : part box not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero e verifico l'entità curva
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then
|
|
local sErr = 'Error : missing profile geometry'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati della curva e del profilo
|
|
local dDepth = abs( EgtCurveThickness( AuxId))
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local b3Aux = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD)
|
|
local bToolInv = ( vtExtr:getZ() < -0.1)
|
|
local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i')
|
|
-- lettura parametri (probabile/i parametro/i Q)
|
|
local nConeCut = VerifyCornerType( Proc)
|
|
-- recupero la lavorazione
|
|
local bTipFeed = EgtIf( nTool_ID, false, true)
|
|
local sMilling = WM.FindMilling( 'FreeContour', nil, nil, nTool_ID, nil, nil, bTipFeed)
|
|
if not sMilling then
|
|
local sErr = 'Error : milling not found in library'
|
|
if nTool_ID then sErr = sErr .. ' (Tool_ID=' .. tostring( nTool_ID) .. ')' end
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dMillDiam = 20
|
|
local dMaxDepth = 0
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local 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
|
|
end
|
|
end
|
|
-- verifiche per affondamento
|
|
if b3Aux:getDimZ() > b3Raw:getDimZ() - 1.0 then
|
|
dDepth = min( dDepth, b3Raw:getDimZ())
|
|
end
|
|
dDepth = dDepth + WD.CUT_EXTRA
|
|
local bReducedDepth = ( dDepth > dMaxDepth)
|
|
if bReducedDepth then
|
|
dDepth = dMaxDepth
|
|
end
|
|
-- inserisco la lavorazione
|
|
local sName = 'Free_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchId = WM.AddMachining( Proc, sName, sMilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', Proc.PartId)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ AuxId, -1}})
|
|
-- percorso da non invertire
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- se estrusione da sotto, inverto direzione fresa
|
|
if bToolInv then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
end
|
|
-- tolgo i Tabs se non passante o devo rimuovere lo sfrido
|
|
if bReducedDepth or nConeCut == 1 then EgtSetMachiningParam( MCH_MP.LEAVETAB, false) end
|
|
-- assegno affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- assegno lato di lavoro
|
|
if Proc.Grp == 0 then
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER)
|
|
elseif ( Proc.Grp == 3 and not bToolInv) or ( Proc.Grp == 4 and bToolInv) then
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
elseif ( Proc.Grp == 3 and bToolInv) or ( Proc.Grp == 4 and not bToolInv) then
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
end
|
|
|
|
-- se lamatura affondata speciale, setto attacco e stacco al centro
|
|
local bIsRecessedCounterBore = ( Proc.Box:getMax():getZ() < b3Raw:getMax():getZ() + 10 * GEO.EPS_SMALL) and
|
|
( nTool_ID == WD.RECESSED_COUNTERBORE_TOOLID or 0) and
|
|
( EgtCurveIsACircle( AuxId))
|
|
if bIsRecessedCounterBore then
|
|
local _, _, _, dContourRadius = EgtCurveIsACircle( AuxId)
|
|
-- setto attacco
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.TANGENT)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dContourRadius - 0.5 * dMillDiam)
|
|
EgtSetMachiningParam( MCH_MP.LIELEV, 0)
|
|
-- setto stacco
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, dContourRadius - 0.5 * dMillDiam)
|
|
EgtSetMachiningParam( MCH_MP.LOELEV, 0)
|
|
-- imposto step
|
|
local dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or 0
|
|
local dStep = EgtGetMachiningParam( MCH_MP.STEP)
|
|
if dStep < GEO.EPS_SMALL then dStep = 0.75 * dMaxMat end
|
|
local nStep = ceil( ( dDepth - dMaxMat) / dStep)
|
|
dStep = max( ( dDepth - dMaxMat) / max( nStep, 1), 0)
|
|
local dMaxElev = max( ( nStep + 1) * dStep - GEO.EPS_SMALL, 0)
|
|
EgtSetMachiningParam( MCH_MP.STEP, dStep)
|
|
-- imposto elevazione e forzo attacco dal lato aperto
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMaxElev, 1) .. ';OutRaw=3;')
|
|
end
|
|
|
|
-- posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_ZP
|
|
if AreSameOrOppositeVectorApprox( vtExtr, 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)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sErr
|
|
end
|
|
-- se abilitata la lavorazione corner con stop macchina, ci sono almeno due facce e fresata passante per consentire eliminazione sfrido
|
|
if nConeCut == 1 and Proc.Fct >= 2 and not bReducedDepth then
|
|
-- gruppo ausiliario
|
|
local nAddGrpId = WL.GetAddGroup( Proc.PartId)
|
|
-- recupero i dati di tutte le facce
|
|
local vFace, dMaxWidth, nNewProc = GetFacesData( Proc, bOpposite, false, dMillDiam, dMaxDepth, (dMillDiam/2), nAddGrpId, b3Raw)
|
|
-- se affondamento non superiore al limite
|
|
if dDepth <= ( WD.MAX_CLEAN_CRN60 + 20 * GEO.EPS_SMALL) then
|
|
local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw,
|
|
dMillDiam, nAddGrpId, nil, nNewProc, 0, true)
|
|
if not bMcok then return bMcok, sMcErr end
|
|
else
|
|
EgtErase( nNewProc)
|
|
if nConeCut == 1 then
|
|
local sErr = 'Clean corner 60° not applid because thickness: ' .. EgtNumToString( dThick, 2) ..
|
|
' is bigger than parameter MAX_CLEAN_CRN60: ' .. EgtNumToString( WD.MAX_CLEAN_CRN60 , 2)
|
|
EgtOutLog( sErr)
|
|
end
|
|
end
|
|
elseif nConeCut == 2 then
|
|
local sErr = 'Clean corner 30° is not applied on milling'
|
|
EgtOutLog( sErr)
|
|
elseif nConeCut == 3 then
|
|
local sErr = 'Clean corner with undercut is not applied on milling'
|
|
EgtOutLog( sErr)
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByMark( Proc, nRawId, b3Raw)
|
|
-- ingombro del pezzo
|
|
local Ls = EgtGetFirstNameInGroup( Proc.PartId, 'Box')
|
|
local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
if not b3Solid then
|
|
local sErr = 'Error : part box not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero e verifico l'entità curva
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then
|
|
local sErr = 'Error : missing profile geometry'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati della curva e del profilo
|
|
local dDepth = abs( EgtCurveThickness( AuxId))
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local b3Aux = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD)
|
|
local bToolInv = ( vtExtr:getZ() < -0.1)
|
|
local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i')
|
|
-- recupero la lavorazione
|
|
local sMilling = WM.FindMilling( 'Text', nil, nil, nTool_ID)
|
|
if not sMilling then
|
|
local sErr = 'Error : milling not found in library'
|
|
if nTool_ID then sErr = sErr .. ' (Tool_ID=' .. tostring( nTool_ID) .. ')' end
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- inserisco la lavorazione
|
|
local sName = 'FreeMark_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchId = WM.AddMachining( Proc, sName, sMilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', Proc.PartId)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ AuxId, -1}})
|
|
-- se estrusione da sotto, inverto direzione fresa
|
|
if bToolInv then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
end
|
|
-- posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_ZP
|
|
if AreSameOrOppositeVectorApprox( vtExtr, 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)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sErr
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByNail( Proc, nRawId, b3Raw)
|
|
-- ingombro del pezzo
|
|
local Ls = EgtGetFirstNameInGroup( Proc.PartId, 'Box')
|
|
local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
if not b3Solid then
|
|
local sErr = 'Error : part box not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero e verifico l'entità curva
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then
|
|
local sErr = 'Error : missing profile geometry'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati della curva e del profilo
|
|
local dDepth = abs( EgtCurveThickness( AuxId))
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local b3Aux = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD)
|
|
local bToolInv = ( vtExtr:getZ() < -0.1)
|
|
local nCntData = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i') or 0
|
|
if nCntData < 10 then
|
|
nCntData = nCntData + 10
|
|
end
|
|
local dCntPar = EgtGetInfo( Proc.Id, 'CNT_PAR', 'd') or 100
|
|
-- recupero la lavorazione
|
|
local sNailing = WM.FindNailing( nCntData)
|
|
if not sNailing then
|
|
local sErr = 'Error : nailing not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- inserisco la lavorazione
|
|
local sName = 'Nail_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchId = WM.AddMachining( Proc, sName, sNailing)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sNailing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', Proc.PartId)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ AuxId, -1}})
|
|
-- percorso da non invertire
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- se estrusione da sotto, inverto direzione fresa
|
|
if bToolInv then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
end
|
|
-- assegno affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, 10)
|
|
-- assegno lato di lavoro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER)
|
|
-- se in doppio lungo Y, devo dimezzare opportunamente la lavorazione
|
|
local dExtraDelta = 0
|
|
if Proc.Double == 2 then
|
|
dExtraDelta = 0.45 * dCntPar
|
|
if Proc.Delta > 0 then
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -Proc.DblAcc - dExtraDelta)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, -Proc.DblAcc - dExtraDelta)
|
|
end
|
|
end
|
|
-- assegno parametri a note utente
|
|
local sUserNotes = 'Par=' .. EgtNumToString( dCntPar, 0) .. ';'
|
|
if Proc.Double and Proc.Double > 0 then
|
|
sUserNotes = sUserNotes .. 'Dbl=' .. EgtNumToString( Proc.Double, 0) .. ';' ..
|
|
'Dlt=' .. EgtNumToString( abs( Proc.Delta) + dExtraDelta, 0) .. ';'
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sErr
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByPocket( Proc, nRawId, b3Raw)
|
|
-- recupero e verifico l'entità curva
|
|
local bOpposite = false
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
local vtExtr
|
|
if AuxId then
|
|
AuxId = AuxId + Proc.Id
|
|
vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
if vtExtr then
|
|
bOpposite = ( Proc.Grp == 4 and vtExtr:getZ() < 0) or ( Proc.Grp == 3 and vtExtr:getZ() > 0)
|
|
if GetFacesExternalSide( Proc, vtExtr) ~= Proc.Grp then
|
|
bOpposite = not bOpposite
|
|
end
|
|
end
|
|
end
|
|
if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then
|
|
local sErr = 'Error : missing profile geometry'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local bPocketBotface = false
|
|
-- se la curva è aperta non la svuoto
|
|
if not EgtCurveIsClosed( AuxId) then
|
|
bPocketBotface = true
|
|
end
|
|
-- cerco la faccia di fondo della superfice (deve avere direzione circa quella di estrusione della curva)
|
|
local nFacet
|
|
for i = 1, Proc.Fct do
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT)
|
|
if abs( vtN * vtExtr) > 0.99 then
|
|
nFacet = i - 1
|
|
break
|
|
end
|
|
end
|
|
if not nFacet then
|
|
return MakeByMill( Proc, nRawId, b3Raw)
|
|
end
|
|
-- se la faccia di fondo ha confini aperti, devo lavorarla direttamente
|
|
vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacet)[1] or {}
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] == - 1 then
|
|
bPocketBotface = true
|
|
break
|
|
end
|
|
end
|
|
-- recupero i dati della curva e del profilo
|
|
local dDepth = EgtIf( bPocketBotface, 0, abs( EgtCurveThickness( AuxId)))
|
|
local dOriDepth = dDepth
|
|
-- dati della faccia di fondo
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
local dDiam = min( dH, dV)
|
|
local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId)
|
|
-- gruppo ausiliario
|
|
local nAddGrpId = WL.GetAddGroup( Proc.PartId)
|
|
local nNewProc, nNumFacet = RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFacet)
|
|
-- se ho forma a L
|
|
local bIsL = ( nNumFacet == 2 or TestElleShape3( nNewProc, nNumFacet) or TestElleShape4( nNewProc, nNumFacet) == 2)
|
|
-- verifico se U
|
|
local bIsU = ( nNumFacet == 3 and not TestElleShape3( nNewProc, nNumFacet))
|
|
local dMiddleFacetLength = 0
|
|
if bIsU then
|
|
local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( nNewProc, 1, GDB_ID.ROOT)
|
|
-- prendo la linea di base
|
|
if abs( dElev - dH2) < 1 and abs( dElev - dV2) > 1 then
|
|
dMiddleFacetLength = dV2
|
|
elseif abs( dElev - dV2) < 1 and abs( dElev - dH2) > 1 then
|
|
dMiddleFacetLength = dH2
|
|
end
|
|
end
|
|
if Proc.Fct < 5 and (( bIsL and not bIsU) or ( bIsU and dMiddleFacetLength > dDiam * 2)) then dDiam = dDiam * 2 end
|
|
local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i')
|
|
-- recupero la lavorazione
|
|
local sPocketing = WM.FindPocketing( 'Pocket', dDiam, dDepth, nTool_ID)
|
|
if not sPocketing then
|
|
local sErr = 'Error : pocketing not found in library'
|
|
if nTool_ID then sErr = sErr .. ' (Tool_ID=' .. tostring( nTool_ID) .. ')' end
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dMillDiam = 20
|
|
local dMaxDepth = 0
|
|
local dThDiam = 100
|
|
if EgtMdbSetCurrMachining( sPocketing) then
|
|
local 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
|
|
-- 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)
|
|
-- aggiungo geometria
|
|
if bPocketBotface then
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacet}})
|
|
else
|
|
EgtSetMachiningGeometry( {{ AuxId, -1}})
|
|
end
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_ZP
|
|
if AreSameVectorApprox( vtExtr, 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)
|
|
local sWarn = ''
|
|
if bPocketBotface then
|
|
local dThElev = dThDiam / 2 * sqrt( vtExtr:getX() * vtExtr:getX() + vtExtr:getY() * vtExtr:getY())
|
|
if dElev + dThElev > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
dDepth = dMaxDepth - dElev - dThElev
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
else
|
|
-- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente
|
|
if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
dDepth = dMaxDepth
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- imposto elevazione
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( EgtIf( bPocketBotface, min( dElev, dMaxDepth), dMaxDepth), 1) .. ';')
|
|
-- eseguo
|
|
local bAppOk = EgtApplyMachining( true, false)
|
|
if not bAppOk and not bPocketBotface then
|
|
bPocketBotface = true
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacet}})
|
|
dDepth = 0
|
|
local dThElev = dThDiam / 2 * sqrt( vtExtr:getX() * vtExtr:getX() + vtExtr:getY() * vtExtr:getY())
|
|
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)
|
|
bAppOk = EgtApplyMachining( true, false)
|
|
end
|
|
if not bAppOk then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
-- lettura parametri (probabile/i parametro/i Q)
|
|
local nConeCut = VerifyCornerType( Proc)
|
|
-- recupero i dati di tutte le facce
|
|
local vFace, dMaxWidth
|
|
vFace, dMaxWidth, nNewProc = GetFacesData( Proc, bOpposite, false, dMillDiam, dMaxDepth, (dMillDiam/2), nAddGrpId, b3Raw, nNewProc)
|
|
-- se ci sono almeno due facce più quella di fondo
|
|
if Proc.Fct >= 3 then
|
|
-- se abilitata la lavorazione corner con stop macchina e affondamento non superiore al limite
|
|
local dDepthMach = EgtIf( bPocketBotface, dDepth, ( dDepth - dOriDepth))
|
|
if nConeCut == 1 and dDepthMach <= ( WD.MAX_CLEAN_CRN60 + 20 * GEO.EPS_SMALL) then
|
|
local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw,
|
|
dMillDiam, nAddGrpId, nil, nNewProc, dDepthMach)
|
|
if not bMcok then return bMcok, sMcErr end
|
|
else
|
|
EgtErase( nNewProc)
|
|
if nConeCut == 1 then
|
|
local sErr = 'Clean corner 60° not applid because thickness: ' .. EgtNumToString( dThick, 2) ..
|
|
' is bigger than parameter MAX_CLEAN_CRN60: ' .. EgtNumToString( WD.MAX_CLEAN_CRN60 , 2)
|
|
EgtOutLog( sErr)
|
|
elseif nConeCut == 2 then
|
|
local sErr = 'Clean corner 30° is not applied on pocketing'
|
|
EgtOutLog( sErr)
|
|
end
|
|
end
|
|
end
|
|
return true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione
|
|
function WPF.Make( Proc, nRawId, b3Raw)
|
|
-- recupero la tipologia (contorno o tasca)
|
|
local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1)
|
|
-- se svuotatura
|
|
if bPocket then
|
|
return MakeByPocket( Proc, nRawId, b3Raw)
|
|
-- altrimenti contorno
|
|
else
|
|
-- riordino le facce
|
|
ReorderFaces( Proc.Id, EgtSurfTmFacetCount( Proc.Id))
|
|
-- recupero il tipo di lavorazione
|
|
local nCntType = EgtGetInfo( Proc.Id, 'CNT_TYPE', 'i') or 0
|
|
-- se fresatura
|
|
if nCntType == 2 then
|
|
return MakeByMill( Proc, nRawId, b3Raw)
|
|
-- se marcatura
|
|
elseif nCntType == 10 then
|
|
return MakeByMark( Proc, nRawId, b3Raw)
|
|
-- se chiodatura
|
|
elseif nCntType == 20 then
|
|
return MakeByNail( Proc, nRawId, b3Raw)
|
|
-- area vietata
|
|
elseif nCntType == 200 then
|
|
return true, 'Lock-out area Ignored'
|
|
-- altrimenti, taglio con lama e pulizia angoli con fresa
|
|
else
|
|
return MakeByCut( Proc, nRawId, b3Raw)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return WPF
|