Files
DataWall/LuaLibs/WProcessDrill.lua
T
DarioS 99bc0e9e8b DataWall :
- per lavorazioni di FreeContour e di Drill si accettano solo frese che possano lavorare di testa
- aggiunto controllo massimo affondamento per pulitura spigoli con fresa conica 60deg.
2022-01-13 12:58:43 +01:00

438 lines
17 KiB
Lua

-- WProcessDrill.lua by Egaltech s.r.l. 2022/01/12
-- 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.
-- Tabella per definizione modulo
local WPD = {}
-- Include
require( 'EgtBase')
EgtOutLog( ' WProcessDrill started', 1)
-- Dati
local WD = require( 'WallData')
local WM = require( 'WMachiningLib')
---------------------------------------------------------------------
-- 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)
-- 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)
-- verifico se troppo inclinato e quindi non lavorabile
if not ( Proc.Fcs == 5 or Proc.Fcs == 6 or Proc.Fce == 5 or Proc.Fce == 6) and abs( vtExtr:getX()) > WD.DRILL_VX_MAX then
return false
end
local bOpen = ( Proc.Fce ~= 0)
local bFaceDown = ( ptCen:getZ() < b3Raw:getMin():getZ() + 2)
-- verifico se il foro è sotto e quindi va spostato o sopra o sul fianco
if (( vtExtr:getZ() < WD.DRILL_VZ_MIN or bFaceDown) and not AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) and not bOpen) then
return false
else
return true
end
end
---------------------------------------------------------------------
-- Classificazione del flip della feature per nesting
-- return nFlip0, nFlip1
function WPD.FlipClassify( Proc, b3Part)
local nFlip0 = 0
local nFlip1 = 0
-- 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)
-- identifico su quali facce si trova il foro
local ptPrcMin = Proc.Box:getMin()
local ptPrcMax = Proc.Box:getMax()
local ptPartMin = b3Part:getMin()
local ptPartMax = b3Part:getMax()
if not ( abs( ptPrcMin:getX() - ptPartMin:getX()) < GEO.EPS_SMALL or abs( ptPrcMax:getX() - ptPartMax:getX()) < GEO.EPS_SMALL) then -- corrispondente delle facce 5/6 nel caso ruotato
if abs( vtExtr:getX()) > WD.DRILL_VX_MAX then return 0, 0 end
end
-- se foro cieco
if Proc.Fcs == 0 or Proc.Fce == 0 then
-- se normale positiva
local dVtExtrZ = vtExtr:getZ()
-- verifico se è lavorabile da sopra
nFlip0 = EgtIf( dVtExtrZ >= WD.DRILL_VZ_MIN, 100, 0)
-- verifico se e' lavorabile da fliped: cambio segno al versore
nFlip1 = EgtIf( -dVtExtrZ >= WD.DRILL_VZ_MIN, 100, 0)
return nFlip0, nFlip1
-- -- altrimenti foro passante
-- else
-- -- verifico orientamento della normale rispetto ad angolo massimo
-- if abs( vtExtr:getX()) <= WD.DRILL_VX_MAX then
-- nFlip0 = 100
-- nFlip1 = 100
-- else
-- nFlip0 = 0
-- nFlip1 = 0
-- end
end
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 + WD.DRILL_TOL and dDiam >= WD.HOR_DRILL_DIAM - 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
-- local b3Drill = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD)
-- -- se ci sono fori sul profilo (box attaccato al profilo e / calcolo intersezione tra foro e box, se box del profilo foro ha Z, e' sul profilo)
end
function WPD.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 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 WPD.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)
-- 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 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
local sDrilling, nType
local sHead
if dDiam < 200 then
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
sDrilling, nType = WM.FindDrilling( dDiam, dLen, sHead)
if not sDrilling then
sDrilling, nType = WM.FindDrilling( dDiam, nil, sHead)
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
else
sDrilling = WM.FindMilling( 'FreeContour', dLen, nil, nil, nil, nil, true)
nType = 'Mill'
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 dDiamTh = 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
dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth
else
dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) or dMaxDepth
end
dDiamTh = EgtTdbGetCurrToolThDiam()
end
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 intermedio e inclinato, limito il massimo affondamento
if not ( ( Proc.Fcs == 5 or Proc.Fcs == 6) or ( bToInvert and ( Proc.Fce == 5 or Proc.Fce == 6))) then
local CosB = abs( vtExtr:getX())
if CosB < WD.DRILL_VX_MAX then
local TgA = CosB / sqrt( 1 - CosB * CosB)
dMaxDepth = dMaxDepth - dDiamTh / 2 * TgA
else
dMaxDepth = 0
end
end
-- inserisco la lavorazione
local sName = 'Drill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
local nMchId = EgtAddMachining( sName, sDrilling)
if not nMchId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sDrilling
EgtOutLog( sErr)
return false, sErr
end
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
EgtSetMachiningGeometry( {{ AuxId, -1}})
-- eventuale inversione
if nType == 'Drill' then
EgtSetMachiningParam( MCH_MP.INVERT, bToInvert)
else
EgtSetMachiningParam( MCH_MP.TOOLINVERT, bToInvert)
end
-- se fresatura gestisco il lato di lavoro
if 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 AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then
nSCC = MCH_SCC.ADIR_YP
end
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- aggiusto l'affondamento
local sMyWarn
local dDepth = dLen
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
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
-- Note utente
local sUserNotes = ''
-- se foratura o svuotatura, dichiarazione nessuna generazione sfridi per Vmill
if nType == 'Drill' or nType == 'Pocket' then
sUserNotes = 'VMRS=0;'
end
-- se foratura
if nType == 'Drill' then
-- aggiungo alle note massima elevazione (coincide con affondamento)
sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dDepth, 1) .. ';'
-- se foro passante, aggiungo questa qualifica alle note
if bOpen then
sUserNotes = sUserNotes .. 'Open=1;'
end
end
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
return true, ( sMyWarn or sWarn)
end
end
return true, sMyWarn
end
---------------------------------------------------------------------
return WPD