734 lines
30 KiB
Lua
734 lines
30 KiB
Lua
-- WProcessDrill.lua by Egaltech s.r.l. 2022/03/08
|
|
-- Gestione calcolo forature per Pareti
|
|
-- 2021/08/29 DS Se foratura di fianco setto flag per farla dopo i tagli.
|
|
-- 2021/12/04 DS Modifiche per forature speciali lungo Y.
|
|
-- 2022/01/12 DS Se con fresatura richiedo che l'utensile possa lavorare di testa.
|
|
-- 2022/01/19 DS Forature orizzontali lunghe con nome LhDrill_.
|
|
-- 2022/01/20 DS Aggiunta gestione Q01 (flag forzatura solo contornatura).
|
|
-- 2022/01/29 DS Corretta gestione ingombro portautensili per fori inclinati da sopra.
|
|
-- 2022/02/22 ES Aggiunta gestione prefori.
|
|
-- 2022/03/08 DS Vanno accettati fori orizzontali sul bordo anche senza foratori orizzontali speciali.
|
|
-- 2023/05/25 Funzioni EgtAddMachining sostituite da WM.AddMachining in modo da trascrivere le priorità da btl alle lavorazioni.
|
|
-- 2023/11/14 Aggiunta gestione forature in doppio.
|
|
|
|
-- Tabella per definizione modulo
|
|
local WPD = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local WL = require( 'WallLib')
|
|
|
|
EgtOutLog( ' WProcessDrill started', 1)
|
|
|
|
-- Dati
|
|
local WD = require( 'WallData')
|
|
local WM = require( 'WMachiningLib')
|
|
|
|
-- Parametri Q
|
|
local sContourOnly = 'Q01' -- 0=no, 1=si
|
|
|
|
-- Per forature MultiDrill, lista lavorazioni già provate
|
|
local TriedDrillings = {}
|
|
|
|
|
|
---------------------------------------------------------------------
|
|
-- Riconoscimento della feature
|
|
function WPD.Identify( Proc)
|
|
return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 40)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Recupero dati foro e adattamento se speciale
|
|
function WPD.GetData( Proc)
|
|
-- verifico se foro da adattare
|
|
if EgtExistsInfo( Proc.Id, 'DiamUser') then
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if AuxId and EgtGetType( AuxId) == GDB_TY.CRV_ARC and WD.USER_HOLE_DIAM and WD.USER_HOLE_DIAM > 1 then
|
|
EgtModifyArcRadius( AuxId, WD.USER_HOLE_DIAM / 2)
|
|
EgtSetInfo( Proc.Id, 'P12', WD.USER_HOLE_DIAM)
|
|
end
|
|
end
|
|
-- recupero diametro
|
|
local dDiam = EgtGetInfo( Proc.Id, 'P12', 'd') or 0
|
|
-- recupero faccia di entrata e uscita
|
|
local nFcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0
|
|
local nFce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0
|
|
return dDiam, nFcs, nFce
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione della feature
|
|
function WPD.Classify( Proc, b3Raw, bUseMultiDrill)
|
|
|
|
-- recupero e verifico l'entità foro
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then
|
|
return false
|
|
end
|
|
-- recupero i dati del foro
|
|
local dDiam = 2 * EgtArcRadius( AuxId)
|
|
local dLen = abs( EgtCurveThickness( AuxId))
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local ptCen = EgtCP( AuxId, GDB_RT.GLOB)
|
|
local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0)
|
|
-- se inizia o finisce sulla faccia sopra
|
|
if ptCen:getZ() > b3Raw:getMax():getZ() - dDiam / 2 or ( bOpen and ptCen:getZ() - vtExtr:getZ() * dLen > b3Raw:getMax():getZ() - dDiam / 2) then
|
|
-- è lavorabile se non troppo inclinato
|
|
return ( abs( vtExtr:getZ()) >= WD.DRILL_VZ_MIN)
|
|
end
|
|
-- multiforatore (cabinet)
|
|
if bUseMultiDrill then
|
|
return true
|
|
end
|
|
-- se con direzione asse Y e macchina con foratore orizzontale del giusto diametro
|
|
if WD.HOR_DRILL_DIAM and abs( dDiam - WD.HOR_DRILL_DIAM) < WD.DRILL_TOL and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then
|
|
return true
|
|
end
|
|
-- se foro orizzontale, verifico sia sul bordo del grezzo
|
|
local b3RedRaw = BBox3d( b3Raw)
|
|
b3RedRaw:expand( -20)
|
|
if ( WD.HOR_DRILL_5AX or WD.HOR_DRILL_5AX == nil) and vtExtr:getZ() > -0.05 and not EnclosesPointXY( b3RedRaw, ptCen) then
|
|
return true
|
|
end
|
|
-- altrimenti non lavorabile
|
|
return false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione del flip della feature per nesting
|
|
-- return nFlip0, nFlip1
|
|
function WPD.FlipClassify( Proc, b3Part)
|
|
-- recupero e verifico l'entità foro
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then
|
|
return false
|
|
end
|
|
-- recupero i dati del foro
|
|
local dDiam = 2 * EgtArcRadius( AuxId)
|
|
local dLen = abs( EgtCurveThickness( AuxId))
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local ptCen = EgtCP( AuxId, GDB_RT.GLOB)
|
|
-- se foro cieco
|
|
if Proc.Fcs == 0 or Proc.Fce == 0 then
|
|
-- se normale positiva
|
|
local dVtExtrZ = vtExtr:getZ()
|
|
-- verifico se è lavorabile da sopra
|
|
local nFlip0 = EgtIf( dVtExtrZ >= WD.DRILL_VZ_MIN, 100, 0)
|
|
-- verifico se e' lavorabile da flipped: cambio segno al versore
|
|
local nFlip1 = EgtIf( -dVtExtrZ >= WD.DRILL_VZ_MIN, 100, 0)
|
|
return nFlip0, nFlip1
|
|
end
|
|
-- altrimenti
|
|
return 0, 0
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione della rotazione della feature per nesting
|
|
-- return nRot0, nRot90, nRot180, nRot270
|
|
function WPD.RotateClassify( Proc)
|
|
|
|
local nRot0 = -1
|
|
local nRot90 = -1
|
|
local nRot180 = -1
|
|
local nRot270 = -1
|
|
-- recupero e verifico l'entità foro
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then
|
|
return false
|
|
end
|
|
-- recupero i dati del foro
|
|
local dDiam = 2 * EgtArcRadius( AuxId)
|
|
local dLen = abs( EgtCurveThickness( AuxId))
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local ptCen = EgtCP( AuxId, GDB_RT.GLOB)
|
|
-- se foro orizzontale con punta lunga
|
|
if dDiam <= ( WD.HOR_DRILL_DIAM or 35) + WD.DRILL_TOL and dDiam >= ( WD.HOR_DRILL_DIAM or 35) - WD.DRILL_TOL and vtExtr:getZ() > -0.1 and vtExtr:getZ() < 0.1 then
|
|
-- se orientato perpendicolare ad X
|
|
if AreSameOrOppositeVectorApprox( vtExtr, X_AX()) then
|
|
nRot0 = 0
|
|
nRot90 = 100
|
|
nRot180 = 0
|
|
nRot270 = 100
|
|
return nRot0, nRot90, nRot180, nRot270
|
|
elseif AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then
|
|
nRot0 = 100
|
|
nRot90 = 0
|
|
nRot180 = 100
|
|
nRot270 = 0
|
|
return nRot0, nRot90, nRot180, nRot270
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function IsToolDoubleOk( sToolMasterName, sToolDoubleName)
|
|
local bIsToolDoubleOk = false
|
|
-- dimensioni utensile master
|
|
EgtTdbSetCurrTool( sToolMasterName)
|
|
local dTMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT)
|
|
local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
|
|
-- dimensioni utensile double
|
|
EgtTdbSetCurrTool( sToolDoubleName)
|
|
local dTMaxMatDouble = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT)
|
|
local dTDiamDouble = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
|
|
-- controllo che siano uguali
|
|
bIsToolDoubleOk = ( dTMaxMatDouble > dTMaxMat - 100 * GEO.EPS_SMALL) and
|
|
( abs( dTDiam - dTDiamDouble) < 100 * GEO.EPS_SMALL) and
|
|
EgtFindToolInCurrSetup( sToolDoubleName)
|
|
return bIsToolDoubleOk
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function IsMachiningOkForDouble( sMachining)
|
|
local bDoubleOk = false
|
|
if sMachining and EgtMdbSetCurrMachining( sMachining) then
|
|
-- recupero l'utensile della lavorazione
|
|
local sToolMasterName = EgtMdbGetCurrMachiningParam( MCH_MP.TOOL)
|
|
if EgtTdbSetCurrTool( sToolMasterName or '') then
|
|
-- cerco eventuale utensile in doppio
|
|
local sToolDoubleName = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'DOUBLE', 's')
|
|
if sToolDoubleName and EgtTdbSetCurrTool( sToolDoubleName) then
|
|
bDoubleOk = IsToolDoubleOk( sToolMasterName, sToolDoubleName)
|
|
end
|
|
end
|
|
end
|
|
return bDoubleOk
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function IsHorizLongDrill( Proc)
|
|
-- recupero e verifico l'entità foro
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then
|
|
return false
|
|
end
|
|
-- recupero i dati del foro
|
|
local dDiam = 2 * EgtArcRadius( AuxId)
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
return WD.HOR_DRILL_DIAM and dDiam <= WD.HOR_DRILL_DIAM + WD.DRILL_TOL and dDiam >= WD.HOR_DRILL_DIAM - WD.DRILL_TOL and vtExtr:getZ() > -0.1 and vtExtr:getZ() < 0.1
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function WPD.UseMinYForLongDrill( Proc)
|
|
if IsHorizLongDrill( Proc) then
|
|
-- recupero e verifico l'entità foro
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then
|
|
return false
|
|
end
|
|
-- recupero i dati del foro
|
|
local dDiam = 2 * EgtArcRadius( AuxId)
|
|
local dLen = abs( EgtCurveThickness( AuxId))
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local ptCen = EgtCP( AuxId, GDB_RT.GLOB)
|
|
local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0)
|
|
-- se foro lungo orizzontale e piu' lungo della punta o orientato in Y-
|
|
if dDiam <= WD.HOR_DRILL_DIAM + WD.DRILL_TOL and dDiam >= WD.HOR_DRILL_DIAM - WD.DRILL_TOL and vtExtr:getZ() > -0.1 and vtExtr:getZ() < 0.1 and
|
|
( (bOpen and dLen > WD.HOR_DRILL_LEN) or ( not bOpen and vtExtr:getY() < 0)) then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Verifica se da lavorare in due metà
|
|
function WPD.Split( Proc, b3Raw)
|
|
-- recupero e verifico l'entità foro
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then
|
|
return false
|
|
end
|
|
-- recupero i dati del foro
|
|
local dDiam = 2 * EgtArcRadius( AuxId)
|
|
local dLen = abs( EgtCurveThickness( AuxId))
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0)
|
|
-- verifico se foro orizzontale in Y da lavorare in due metà
|
|
if WD.HOR_DRILL_Y_SPLIT and bOpen and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) and
|
|
Proc.Box:getMin():getY() < WD.HOR_DRILL_Y_SPLIT - 10 and Proc.Box:getMax():getY() > WD.HOR_DRILL_Y_SPLIT + 10 then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione
|
|
function WPD.Make( Proc, nRawId, b3Raw, bUseMultiDrill, DrillingsToAvoid)
|
|
-- recupero e verifico l'entità foro
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then
|
|
local sErr = 'Error : missing drill geometry'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati del foro
|
|
local dDiam = 2 * EgtArcRadius( AuxId)
|
|
local dLen = abs( EgtCurveThickness( AuxId))
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
local ptCen = EgtCP( AuxId, GDB_RT.GLOB)
|
|
local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0)
|
|
-- verifico che il foro non sia fattibile solo da sotto
|
|
local bToInvert = ( vtExtr:getZ() < -0.1)
|
|
if bToInvert and ( not bOpen or Proc.Flg > 1) then
|
|
local sErr = 'Error : drilling from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- se foro da fare dall'altra parte forzo inversione
|
|
if Proc.Flg == -2 then bToInvert = true end
|
|
-- se foro chiuso sulla partenza forzo inversione
|
|
if Proc.Fcs == 0 then bToInvert = true end
|
|
-- se richiesta inversione, inverto versore di riferimento
|
|
if bToInvert then vtExtr = - vtExtr end
|
|
-- recupero la lavorazione (foratura/svuotatura)
|
|
local sHead
|
|
if WD.HOR_DRILL_Y_SPLIT and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then
|
|
local dExtrY = vtExtr:getY()
|
|
if not bOpen or abs( Proc.Flg) == 2 then
|
|
sHead = EgtIf( dExtrY > 0, 'H5', 'H6')
|
|
else
|
|
if Proc.Box:getMax():getY() > WD.HOR_DRILL_Y_SPLIT + 10 then
|
|
sHead = 'H5'
|
|
if vtExtr:getY() < 0 then bToInvert = true end
|
|
else
|
|
sHead = 'H6'
|
|
if vtExtr:getY() > 0 then bToInvert = true end
|
|
end
|
|
end
|
|
end
|
|
local sDrilling, nType
|
|
if bUseMultiDrill then
|
|
sDrilling, nType = WM.FindDrilling( nil, nil, nil, nil, true, TriedDrillings)
|
|
if not sDrilling then
|
|
return false
|
|
end
|
|
else
|
|
local bUseDLenToFindDrilling = true
|
|
sDrilling, nType = WM.FindDrilling( dDiam, dLen, sHead)
|
|
if not sDrilling then
|
|
bUseDLenToFindDrilling = false
|
|
sDrilling, nType = WM.FindDrilling( dDiam, nil, sHead)
|
|
end
|
|
-- se Proc è settata per essere specchiata cerco la lavorazione adatta e verifico possa essere effettivamente specchiata
|
|
if Proc.Double and Proc.Double == 2 then
|
|
local sDrillingBackup = sDrilling
|
|
sDrilling = WM.FindDrilling( dDiam, EgtIf( bUseDLenToFindDrilling, dLen, nil), 'H1')
|
|
if not IsMachiningOkForDouble( sDrilling) then
|
|
Proc.Double = 0
|
|
sDrilling = sDrillingBackup
|
|
end
|
|
end
|
|
if sHead and not sDrilling then
|
|
sDrilling, nType = WM.FindDrilling( dDiam, dLen)
|
|
if not sDrilling then
|
|
sDrilling, nType = WM.FindDrilling( dDiam)
|
|
end
|
|
if sDrilling then sHead = '' end
|
|
end
|
|
end
|
|
local bAngledContourDrill = false
|
|
local nAngledContourDrillId = GDB_ID.NULL
|
|
local dReduceDepth = 0
|
|
local bUseTabs = false
|
|
-- se trovata svuotatura, verifico se richiesta invece contornatura
|
|
if nType == 'Pocket' then
|
|
-- recupero eventuale flag per fare sola contornatura
|
|
local nContourOnly = ( EgtGetInfo( Proc.Id, sContourOnly, 'i') or 0)
|
|
if nContourOnly == 1 then
|
|
-- se passante
|
|
if Proc.Fcs > 0 and Proc.Fce > 0 then
|
|
-- se inclinato
|
|
if abs( vtExtr:getZ()) >= WD.DRILL_VZ_MIN and abs( vtExtr:getZ()) < 0.999 then
|
|
-- gruppo ausiliario per preforo
|
|
local nAddGrpId = WL.GetAddGroup( Proc.PartId)
|
|
-- ricavo contorno inferiore della superficie
|
|
local nAngledCircleId, nAngledCircleCnt = EgtExtractSurfTmLoops( Proc.Id, nAddGrpId)
|
|
local dMinZ = 10000
|
|
local nMinCircleId = GDB_ID.NULL
|
|
for Circleindex = 1, nAngledCircleCnt do
|
|
local b3Circle = EgtGetBBoxGlob( nAngledCircleId + Circleindex -1, GDB_BB.EXACT)
|
|
if b3Circle:getMin():getZ() < dMinZ then
|
|
nMinCircleId = nAngledCircleId + Circleindex -1
|
|
end
|
|
end
|
|
-- estrudo
|
|
EgtModifyCurveExtrusion( nMinCircleId, vtExtr, GDB_RT.GLOB)
|
|
EgtModifyCurveThickness( nMinCircleId, dLen)
|
|
bAngledContourDrill = true
|
|
nAngledContourDrillId = nMinCircleId
|
|
-- se non inclinato e abbastanza grande uso i tab
|
|
-- TODO se si risolve il problema dei tabs non funzionanti sotto ai 200 mm rimuovere il check sul diametro
|
|
elseif dDiam > 100 - 10 * GEO.EPS_SMALL then
|
|
bUseTabs = true
|
|
-- se non inclinato e piccolo non arrivo sul fondo
|
|
else
|
|
dReduceDepth = 5
|
|
end
|
|
end
|
|
sDrilling = WM.FindMilling( 'FreeContour', dLen, nil, nil, nil, nil, true)
|
|
if sDrilling then
|
|
nType = 'Mill'
|
|
sHead = ''
|
|
end
|
|
end
|
|
end
|
|
if not sDrilling then
|
|
local sErr = 'Error : drilling not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- controllo posizione Y inizio foro con testa H6
|
|
if WD.HOR_DRILL_YNEG_MAXMIN and sHead == 'H6' then
|
|
if b3Raw:getMin():getY() > WD.HOR_DRILL_YNEG_MAXMIN then
|
|
local sErr = 'Error : horizontal hole with Drilling2 starting too far'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dMaxDepth = 20
|
|
local dFreeLen = 20
|
|
local dDiamTh = 35
|
|
local dDiamT = 35
|
|
if EgtMdbSetCurrMachining( sDrilling) then
|
|
local bIsDrilling = ( EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) == MCH_MY.DRILLING)
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
if bIsDrilling then
|
|
dFreeLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) - EgtTdbGetCurrToolThLength() - EgtMdbGetGeneralParam( MCH_GP.MAXDEPTHSAFE)
|
|
dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth
|
|
else
|
|
dFreeLen = EgtTdbGetCurrToolMaxDepth() or dFreeLen
|
|
dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth, dFreeLen)
|
|
end
|
|
dDiamTh = EgtTdbGetCurrToolThDiam()
|
|
dDiamT = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dDiamT
|
|
end
|
|
end
|
|
-- calcolo riduzione lunghezza aggiuntiva per inclinazione utensile
|
|
if bAngledContourDrill then
|
|
local dToolAngleReduce = ( dDiamT / 2) * sqrt( 1 - vtExtr:getZ() * vtExtr:getZ()) / vtExtr:getZ()
|
|
dReduceDepth = ( dToolAngleReduce) + ( 5 / vtExtr:getZ())
|
|
end
|
|
-- aggiusto massimo affondamento per fori lungo Y con teste speciali
|
|
if sHead == 'H5' then
|
|
local dMaxY = WD.HOR_DRILL_Y_SPLIT + WD.HOR_DRILL_Y_TABLE / 2
|
|
local dDeltaY = dMaxY - Proc.Box:getMax():getY()
|
|
if dDeltaY > 0 then
|
|
dMaxDepth = dMaxDepth - dDeltaY
|
|
end
|
|
elseif sHead == 'H6' then
|
|
local dMinY = WD.HOR_DRILL_Y_SPLIT - WD.HOR_DRILL_Y_TABLE / 2
|
|
local dDeltaY = Proc.Box:getMin():getY() - dMinY
|
|
if dDeltaY > 0 then
|
|
dMaxDepth = dMaxDepth - dDeltaY
|
|
end
|
|
end
|
|
-- se foro faccia sopra, limito il massimo affondamento secondo inclinazione
|
|
if ptCen:getZ() > b3Raw:getMax():getZ() - dDiam / 2 then
|
|
local SinA = abs( vtExtr:getZ())
|
|
if SinA >= WD.DRILL_VZ_MIN then
|
|
local CosA = sqrt( 1 - SinA * SinA)
|
|
local dSlantFreeLen = dFreeLen - ( dDiamTh / 2 * CosA / SinA)
|
|
dMaxDepth = min( dMaxDepth, dSlantFreeLen)
|
|
else
|
|
dMaxDepth = 0
|
|
end
|
|
end
|
|
-- inserisco la lavorazione
|
|
local sName = EgtIf( sHead == 'H5' or sHead == 'H6', 'LhDrill_', 'Drill_') .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchId = WM.AddMachining( Proc, sName, sDrilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sDrilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', Proc.PartId)
|
|
-- se foratura di fianco setto la nota per spostarla dopo i tagli di lama
|
|
if vtExtr:getZ() < WD.NZ_MINA and not sHead then
|
|
EgtSetInfo( nMchId, 'MOVE_AFTER', 1)
|
|
end
|
|
-- aggiungo geometria
|
|
if bAngledContourDrill then
|
|
EgtSetMachiningGeometry( nAngledContourDrillId)
|
|
elseif bUseMultiDrill then
|
|
if Proc.SkippedGeometries and #Proc.SkippedGeometries > 0 then
|
|
EgtSetMachiningGeometry( Proc.SkippedGeometries)
|
|
else
|
|
local HolesGeometries = {}
|
|
-- aggiungo foro principale
|
|
table.insert( HolesGeometries, { AuxId, -1})
|
|
-- aggiungo eventuali altre geometrie connesse
|
|
if Proc.OtherGeometries and #Proc.OtherGeometries > 0 then
|
|
for i = 1, #Proc.OtherGeometries do
|
|
-- recupero geometria da lavorare
|
|
local OtherAuxId = Proc.OtherGeometries[i].Id + EgtGetInfo( Proc.OtherGeometries[i].Id, 'AUXID', 'i')
|
|
local Geometry = { OtherAuxId, -1}
|
|
table.insert( HolesGeometries, Geometry)
|
|
end
|
|
end
|
|
EgtSetMachiningGeometry( HolesGeometries)
|
|
end
|
|
else
|
|
EgtSetMachiningGeometry( {{ AuxId, -1}})
|
|
end
|
|
-- eventuale inversione
|
|
if nType == 'Drill' or nType == 'MultiDrill' then
|
|
EgtSetMachiningParam( MCH_MP.INVERT, bToInvert)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, bToInvert)
|
|
end
|
|
-- se fresatura gestisco il lato di lavoro
|
|
if bAngledContourDrill then
|
|
local nWorkSide = EgtGetMachiningParam( MCH_MP.WORKSIDE)
|
|
if nWorkSide == MCH_MILL_WS.CENTER then
|
|
nWorkSide = MCH_MILL_WS.RIGHT
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.INVERT, nWorkSide == MCH_MILL_WS.LEFT)
|
|
elseif nType == 'Mill' then
|
|
local frRef = EgtGetGlobFrame( AuxId)
|
|
local vtNa, _, dArea = EgtCurveArea( AuxId)
|
|
vtNa:toGlob( frRef)
|
|
if vtNa:getZ() * dArea > 0 then
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
end
|
|
-- per fori lungo Y con teste speciali aggiusto eventuale parte prima del foro ma nel grezzo
|
|
if sHead == 'H5' then
|
|
local dSafeStart = b3Raw:getMax():getY() - Proc.Box:getMax():getY() + 10
|
|
if dSafeStart > 20 then
|
|
EgtSetMachiningParam( MCH_MP.STARTPOS, dSafeStart)
|
|
end
|
|
elseif sHead == 'H6' then
|
|
local dSafeStart = Proc.Box:getMin():getY() - b3Raw:getMin():getY() + 10
|
|
if dSafeStart > 20 then
|
|
EgtSetMachiningParam( MCH_MP.STARTPOS, dSafeStart)
|
|
end
|
|
end
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_ZP
|
|
if bUseMultiDrill then
|
|
nSCC = MCH_SCC.ADIR_NEAR
|
|
elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- aggiusto l'affondamento
|
|
local sMyWarn
|
|
local dDepth = dLen - dReduceDepth
|
|
if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
dDepth = dMaxDepth
|
|
if abs( Proc.Flg) ~= 2 then
|
|
sMyWarn = 'Warning in drill : depth (' .. EgtNumToString( dLen, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')'
|
|
EgtOutLog( sMyWarn .. ' (process ' .. tostring( Proc.Id) .. ')')
|
|
end
|
|
end
|
|
if bUseMultiDrill then
|
|
local sDepth = 'TH'
|
|
EgtSetMachiningParam( MCH_MP.DEPTH_STR, sDepth)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
end
|
|
-- leggo eventuali note esistenti della lavorazione
|
|
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
|
|
-- se foratura o svuotatura, dichiarazione nessuna generazione sfridi per Vmill
|
|
if nType == 'Drill' or nType == 'Pocket' then
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'VMRS', 0)
|
|
end
|
|
-- se foratura
|
|
if nType == 'Drill' then
|
|
-- aggiungo alle note massima elevazione (coincide con affondamento)
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( dDepth, 1))
|
|
-- se foro passante, aggiungo questa qualifica alle note
|
|
if bOpen then
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'Open', 1)
|
|
end
|
|
end
|
|
-- se lavorazione in doppio aggiungo le rispettive note
|
|
if Proc.Double and Proc.Double == 2 then
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'DOUBLE', Proc.Double)
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MirrorAx', Proc.MirrorAx)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
if bUseTabs then
|
|
local dStep = EgtGetMachiningParam( MCH_MP.STEP)
|
|
EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.ONEWAY)
|
|
EgtSetMachiningParam( MCH_MP.LEAVETAB, true)
|
|
EgtSetMachiningParam( MCH_MP.TABHEIGHT, EgtClamp( dStep, 0.15 * dDepth, 0.25 * dDepth ))
|
|
EgtSetMachiningParam( MCH_MP.TABLEN, EgtClamp( 2 * dDiamT, 0.1 * dDiam, 0.2 * dDiam ))
|
|
EgtSetMachiningParam( MCH_MP.TABANGLE, 45)
|
|
EgtSetMachiningParam( MCH_MP.TABDIST, 100)
|
|
EgtSetMachiningParam( MCH_MP.TABMIN, 3)
|
|
EgtSetMachiningParam( MCH_MP.TABMAX, 3)
|
|
end
|
|
-- eseguo
|
|
local bOk = EgtApplyMachining( true, false)
|
|
|
|
-- in caso di fori raggruppati vengono restituiti gli eventuali fori saltati
|
|
local SkippedGeometries = {}
|
|
SkippedGeometries = EgtGetMachiningSkippedGeometry()
|
|
local sMsgMaster
|
|
if bUseMultiDrill and SkippedGeometries and #SkippedGeometries > 0 then
|
|
if ( Proc.SkippedGeometries and ( #SkippedGeometries == #Proc.SkippedGeometries))
|
|
or ( Proc.OtherGeometries and ( #SkippedGeometries == #Proc.OtherGeometries + 1))
|
|
or ( not Proc.OtherGeometries and #SkippedGeometries == 1) then
|
|
EgtRemoveOperation( nMchId)
|
|
end
|
|
Proc.SkippedGeometries = SkippedGeometries
|
|
table.insert( TriedDrillings, sDrilling)
|
|
-- per provare tutte le MultiDrill disponibili si passano quelle già fatte come lavorazioni da ignorare
|
|
bOk = WPD.Make( Proc, nRawId, b3Raw, true, TriedDrillings)
|
|
-- non trovata lavorazione, si prova con le lavorazioni singole
|
|
if not bOk then
|
|
local bOkMaster = true
|
|
for i = #Proc.SkippedGeometries, 1, -1 do
|
|
local sErr
|
|
if Proc.OtherGeometries then
|
|
for j = 1, #Proc.OtherGeometries do
|
|
local AuxIdOtherGeometry = EgtGetInfo( Proc.OtherGeometries[j].Id, 'AUXID', 'i') or 0
|
|
if AuxIdOtherGeometry then AuxIdOtherGeometry = AuxIdOtherGeometry + Proc.OtherGeometries[j].Id end
|
|
if Proc.SkippedGeometries[i][1] == AuxIdOtherGeometry then
|
|
bOk, sErr = WPD.Make( Proc.OtherGeometries[j], nRawId, b3Raw, false)
|
|
if bOk then
|
|
Proc.OtherGeometries[j].bOk = true
|
|
else
|
|
Proc.OtherGeometries[j].bOk = false
|
|
end
|
|
Proc.OtherGeometries[j].sMsg = sErr
|
|
break
|
|
end
|
|
end
|
|
-- se nelle altre geometrie non è stato trovato, potrebbe essere la principale
|
|
local AuxIdProc = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0
|
|
if AuxIdProc then AuxIdProc = AuxIdProc + Proc.Id end
|
|
if Proc.SkippedGeometries[i][1] == AuxIdProc then
|
|
bOk, sErr = WPD.Make( Proc, nRawId, b3Raw, false)
|
|
if not bOk then
|
|
bOkMaster = false
|
|
end
|
|
sMsgMaster = sErr
|
|
end
|
|
-- se non ci sono altre geometrie quella da fare è sicuramente la Proc principale
|
|
else
|
|
bOk, sErr = WPD.Make( Proc, nRawId, b3Raw, false)
|
|
if not bOk then
|
|
bOkMaster = false
|
|
end
|
|
sMsgMaster = sErr
|
|
end
|
|
if bOk then
|
|
table.remove( Proc.SkippedGeometries, i)
|
|
end
|
|
end
|
|
bOk = bOkMaster
|
|
end
|
|
end
|
|
-- se presenti geometrie aggiuntive, aggiunta informazioni per output statistiche
|
|
if Proc.OtherGeometries and #Proc.OtherGeometries > 0 then
|
|
for i = 1, #Proc.OtherGeometries do
|
|
if Proc.OtherGeometries[i].bOk == nil then
|
|
Proc.OtherGeometries[i].bOk = true
|
|
Proc.OtherGeometries[i].sMsg = ''
|
|
end
|
|
end
|
|
end
|
|
|
|
if not bUseMultiDrill then
|
|
if not bOk then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sErr
|
|
else
|
|
local _, sWarn = EgtGetMachMgrWarning( 0)
|
|
if EgtIsMachiningEmpty() then
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sWarn
|
|
else
|
|
sMyWarn = (sMyWarn or sWarn)
|
|
end
|
|
end
|
|
else
|
|
return bOk, sMsgMaster
|
|
end
|
|
|
|
-- se preforo inclinato impostato, inclinazione oltre limite impostato e foro non orizzontale
|
|
if WD.PREDRILL_DIAM and WD.PREDRILL_DIAM > 0 and vtExtr:getZ() < ( WD.PREDRILL_MINANGLE or 0.707) and vtExtr:getZ() > 0.1 then
|
|
-- gruppo ausiliario per preforo
|
|
local nAddGrpId = WL.GetAddGroup( Proc.PartId)
|
|
-- calcolo profondita' foro
|
|
local dLen = ( WD.PREDRILL_DIAM / 2) * sqrt( 1 - vtExtr:getZ() * vtExtr:getZ()) / vtExtr:getZ()
|
|
-- copio foro originale
|
|
local nPreHoleId = EgtCopyGlob( AuxId, nAddGrpId)
|
|
EgtModifyArcRadius( nPreHoleId, WD.PREDRILL_DIAM / 2)
|
|
EgtModifyCurveThickness( nPreHoleId, -dLen) --dLen = 10
|
|
|
|
-- se da invertire
|
|
if bToInvert then
|
|
-- lo sposto della lunghezza d'estrusione e ne inverto il versore
|
|
local dThickness = EgtCurveThickness( AuxId)
|
|
EgtMove( nPreHoleId, abs( dThickness) * vtExtr, GDB_RT.GLOB)
|
|
EgtModifyCurveExtrusion( nPreHoleId, vtExtr, GDB_RT.GLOB)
|
|
end
|
|
-- recupero lavorazione di pocket
|
|
local sDrilling = WM.FindDrilling( WD.PREDRILL_DIAM, dLen, nil, true) --dLen = 10
|
|
|
|
if not sDrilling then
|
|
local sErr = 'Error : prehole pocket not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
-- inserisco la lavorazione
|
|
local sName = 'PreDrill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchId = WM.AddMachining( Proc, sName, sDrilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sDrilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtSetInfo( nMchId, 'Part', Proc.PartId)
|
|
-- setto la nota per spostarla prima della foratura
|
|
EgtSetInfo( nMchId, 'MOVE_BEFORE', 1)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ nPreHoleId, -1}})
|
|
|
|
-- note utente, dichiarazione nessuna generazione sfridi per Vmill
|
|
local sUserNotes = 'VMRS=0;'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- eseguo
|
|
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
|
|
else
|
|
sMyWarn = (sMyWarn or sWarn)
|
|
end
|
|
end
|
|
end
|
|
|
|
return true, sMyWarn
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return WPD
|