Files
DataBeam/LuaLibs/ProcessMortise.lua
T
luca.mazzoleni f8c40739da - in attacchi tangenziali solo da un lato alcune correzioni
- aggiunta la raccolta delle Affected Faces a tutti i casi in cui si crea una feature a posteriori (non presente nel btl)
2024-08-19 17:37:16 +02:00

704 lines
31 KiB
Lua

-- ProcessMortise.lua by Egaltech s.r.l. 2023/08/10
-- Gestione calcolo mortase per Travi
-- 2021/07/20 Aggiunta gestione rinvio angolare su FAST.
-- 2021/12/01 Se frontale aggiungo taglio con Grp e Proc di vero taglio (per aggiornare ingombro di testa /coda).
-- 2022/07/26 Aggiunta gestione del parametro P04=1 per la pulizia degli angoli con mortasatrice (sega a catena) specifica
-- 2022/07/29 Nella pulitura angoli aggiunto il check dimensioni tasca vs utensile. Corretta direzione utensile per mortasa frontale.
-- 2022/09/27 Migliorata la scelta utensile. Se c'è almeno una lavorazione 'mortise' si cerca di usare quelle, riducendo l'elevazione se necessario.
-- Se non c'è nemmeno una lavorazione 'mortise' si passa alle pocket.
-- 2022/12/12 Migliorato controllo necessità CleanCorners.
-- 2023/01/31 Aggiunta gestione lavorazione in doppio.
-- 2023/01/31 Creata la funzione ConvertToClosedCurve (parte della ProcessMortise.Make) e spostata in BeamLib.
-- 2023/05/11 Se lavorazione in doppio e precedente no oppure di tipo diverso, forzo risalita a Zmax.
-- 2023/06/27 Esclusa la ricerca lati aperti per le mortase passanti, per le quali il contorno finisce sulla faccia e il riconoscimento sbaglia.
-- 2023/07/21 Correzioni per mortise passanti con curva Aux che guarda in basso.
-- 2023/08/10 Modificata scelta SCC per tasche in Y+/- in coda o quasi.
-- 2024/01/18 Implementata GetBlockedAxis che gestisce gli assi bloccati per tutti i tipi di utensile.
-- 2024/02/28 Forzata SPIRAL_IN se c'è anche un solo lato aperto
-- 2024/03/05 Aggiunta possibilità di inserire lavorazione di smusso
-- Tabella per definizione modulo
local ProcessMortise = {}
-- Include
require( 'EgtBase')
local BL = require( 'BeamLib')
local Cut = require( 'ProcessCut')
EgtOutLog( ' ProcessMortise started', 1)
-- Dati
local BD = require( 'BeamData')
local ML = require( 'MachiningLib')
-- variabili assegnazione parametri Q
local Q_DEPTH_CHAMFER = 'Q02' -- d
---------------------------------------------------------------------
-- Riconoscimento della feature
function ProcessMortise.Identify( Proc)
return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 50) or
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 51) or
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 53))
end
---------------------------------------------------------------------
-- Riconoscimento della sola feature frontale
function ProcessMortise.FrontIdentify( Proc)
return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 51)
end
---------------------------------------------------------------------
-- Riconoscimento delle sole feature laterali
function ProcessMortise.SideIdentify( Proc)
return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 50) or
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 53))
end
---------------------------------------------------------------------
-- Classificazione della feature: decide se la feature è in una posizione che per lavorala
-- deve essere ribaltata o no
function ProcessMortise.Classify( Proc)
-- recupero e verifico il percorso supplementare
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
if AuxId then AuxId = AuxId + Proc.Id end
-- recupero versore estrusione della curva supplementare e non più della superficie
-- perché quest'ultima potrebbe non avere il fondo e dare quindi un risultato non corretto
local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT)
-- recupero i dati della faccia di fondo
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
-- verifico sia una superficie
if not vtExtr then
return false
end
if not vtN then
return false
end
local bDown
-- Confronto le direzioni Z dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante
if abs( vtExtr:getZ() - vtN:getZ()) > GEO.EPS_SMALL then
bDown = false
-- altrimenti è chiusa
else
-- verifico se la mortasa è lavorabile solo da sotto
bDown = ( vtN:getZ() < - 0.1)
end
-- se da sotto e presente rinvio angolare verifico se c'è opportuna lavorazione
if bDown and BD.ANG_TRASM then
if ML.FindPocketing( 'Mortise_AT') then
bDown = false
end
end
return true, bDown
end
---------------------------------------------------------------------
-- Piano di taglio della feature
function ProcessMortise.GetCutPlane( Proc)
if ProcessMortise.FrontIdentify( Proc) then
return EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
else
return nil, nil
end
end
---------------------------------------------------------------------
-- Aggiunge la lavorazione di pulizia angoli
local function AddCleanCornersMachining( nProcId, sMortising, nWorkFaceInd, vtN, dDepth)
-- aggiungo la lavorazione
local sName = 'Mort_' .. ( EgtGetName( nProcId) or tostring( nProcId)) .. '_CleanCorners1'
local nMchFId = EgtAddMachining( sName, sMortising)
if not nMchFId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sMortising
EgtOutLog( sErr)
return false, sErr
end
-- imposto geometria
EgtSetMachiningGeometry( {{ nProcId, nWorkFaceInd}})
-- imposto lato di lavoro e inversione
local vtFaceN = EgtSurfTmFacetNormVersor( nProcId, nWorkFaceInd, GDB_ID.ROOT)
local bInvert = ( vtFaceN:getZ() < -GEO.EPS_SMALL or vtFaceN:getY() > GEO.EPS_SMALL)
EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bInvert, MCH_MORTISE_WS.LEFT, MCH_MORTISE_WS.RIGHT))
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
-- se richiesto, imposto affondamento
if dDepth then
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
end
-- imposto uso del lato faccia
local nFaceUse = BL.GetNearestParalOpposite( vtN)
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
-- applico il parametro plunge, che setta la lavorazione per affondare solamente, senza lavorare tutto il contorno; 1: solo lato iniziale, 2: solo lato finale, 3: entrambi
local sNotes = 'Plunge=3;'
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
-- imposto angolo 3° asse rot
local vtOrtho = BL.GetVersRef( nFaceUse)
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, BL.GetBlockedAxis( sMortising, 'perpendicular'))
EgtSetMachiningParam( MCH_MP.INITANGS, BL.GetChainSawInitAngs( vtN, vtOrtho, 1))
-- calcolo la lavorazione
if not ML.ApplyMachining( true, false) then
if EgtGetOutstrokeInfo() then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
-- impostazione alternativa angolo 3° asse rot
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, BL.GetBlockedAxis( sMortising, 'parallel'))
EgtSetMachiningParam( MCH_MP.INITANGS, BL.GetChainSawInitAngs( vtN, vtOrtho, 2))
if not ML.ApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
end
if EgtIsMachiningEmpty() then
_, sWarn = EgtGetMachMgrWarning( 0)
EgtSetOperationMode( nMchFId, false)
return false, sWarn
end
return true, sWarn
end
---------------------------------------------------------------------
-- Pulizia angoli nel caso sia settato il parametro P04=1
local function CleanCorners( Proc, dMorH, vtN, bDoubleDir, AuxId)
-- verifico se l'orientamento della feature è adeguato
local bCleanCorners = ( AreSameOrOppositeVectorApprox( vtN, X_AX()) or
AreSameOrOppositeVectorApprox( vtN, Y_AX()) or
AreSameOrOppositeVectorApprox( vtN, Z_AX()))
if not bCleanCorners then
local sWarn = 'Warning: mortising not aligned with XYZ axes, corner cleaning skipped'
EgtOutLog( sWarn)
return true, sWarn
end
-- cerco la lavorazione adatta
local sMortisingCleanCorners = ML.FindSawing( 'Mortising')
if not sMortisingCleanCorners then
local sWarn = 'Warning: mortising tool not found, corner cleaning skipped'
EgtOutLog( sWarn)
return true, sWarn
end
-- recupero i dati dell'utensile
local dSawWidth = 50
local dSawThick = 12
local dMaxDepth = 200
if EgtMdbSetCurrMachining( sMortisingCleanCorners) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
end
end
-- se l'utensile non arriva in fondo, riduco l'affondamento
local sWarn
local dDepth
local bUseDoubleDir
if bDoubleDir then
if ( 2 * dMorH + dSawWidth / 2) > dMaxDepth + 10 * GEO.EPS_SMALL then
bUseDoubleDir = true
if ( dMorH + dSawWidth / 2) > dMaxDepth + 10 * GEO.EPS_SMALL then
dDepth = dMaxDepth
sWarn = 'Warning in corner cleaning with mortise: elevation (' .. EgtNumToString( dMorH + dSawWidth / 2, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')'
EgtOutLog( sWarn)
else
dDepth = dMorH + dSawWidth / 2
end
else
dDepth = 2 * dMorH + dSawWidth / 2
end
else
if dMorH > dMaxDepth + 10 * GEO.EPS_SMALL then
dDepth = dMaxDepth
sWarn = 'Warning in corner cleaning with mortise: elevation (' .. EgtNumToString( dMorH, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')'
EgtOutLog( sWarn)
end
end
-- verifico se la tasca ha dimensioni sufficienti per l'utensile
local nFlat = EgtSurfTmByFlatContour( EgtGetParent( AuxId), AuxId, 0.05)
local frMor, dMortiseWidth, dMortiseThick = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT)
if abs( frMor:getVersX() * X_AX()) < abs( frMor:getVersY() * X_AX()) then
dMortiseWidth, dMortiseThick = dMortiseThick, dMortiseWidth
end
EgtErase( nFlat)
if dSawWidth >= dMortiseWidth + 10 * GEO.EPS_SMALL or dSawThick >= dMortiseThick + 10 * GEO.EPS_SMALL then
sWarn = 'warning in corner cleaning with mortise: pocket too small'
EgtOutLog( sWarn)
return true, sWarn
end
-- cerco le due facce migliori da lavorare
local nWorkFaceInd, nWorkFaceInd2
if AreSameOrOppositeVectorApprox( vtN, X_AX()) then
nWorkFaceInd, _, _ = BL.FindFaceBestOrientedAsAxis( Proc, vtN ^ Y_AX())
nWorkFaceInd2, _, _ = BL.FindFaceBestOrientedAsAxis( Proc, vtN ^ Y_AX(), nWorkFaceInd)
else
nWorkFaceInd, _, _ = BL.FindFaceBestOrientedAsAxis( Proc, vtN ^ X_AX())
nWorkFaceInd2, _, _ = BL.FindFaceBestOrientedAsAxis( Proc, vtN ^ X_AX(), nWorkFaceInd)
end
-- lavoro la prima faccia
local bOk1, sErr = AddCleanCornersMachining( Proc.Id, sMortisingCleanCorners, nWorkFaceInd, vtN, dDepth)
-- lavoro la seconda faccia
local bOk2, sErr2 = AddCleanCornersMachining( Proc.Id, sMortisingCleanCorners, nWorkFaceInd2, vtN, dDepth)
if sErr2 then sErr = ( sErr or '') .. EgtIf( sErr, '\n', '') .. sErr2 end
-- se richiesto di lavorare dall'altra parte
if bUseDoubleDir then
local bOk3, sErr3 = AddCleanCornersMachining( Proc.Id, sMortisingCleanCorners, nWorkFaceInd, -vtN, dDepth)
if sErr3 then sErr = ( sErr or '') .. EgtIf( sErr, '\n', '') .. sErr3 end
local bOk4, sErr4 = AddCleanCornersMachining( Proc.Id, sMortisingCleanCorners, nWorkFaceInd2, -vtN, dDepth)
if sErr4 then sErr = ( sErr or '') .. EgtIf( sErr, '\n', '') .. sErr4 end
end
if not bOk1 or not bOk2 or not bOk3 or not bOk4 then
return false, sErr
end
return true, sWarn
end
---------------------------------------------------------------------
function ProcessMortise.VerifyMortiseOrPocket( Proc, dDiam, dDepth, dMaxTotLen, sType, bPocketDown, bExcludeH2)
-- ricerca della svuotatura
local sPocketing
if dDepth then
sPocketing = ML.FindPocketing( sType, dDiam, dDepth, dMaxTotLen, not bPocketDown, bPocketDown, bExcludeH2) or
ML.FindPocketing( sType, dDiam, 0.8 * dDepth, dMaxTotLen, not bPocketDown, bPocketDown, bExcludeH2) or
ML.FindPocketing( sType, dDiam, 0.6 * dDepth, dMaxTotLen, not bPocketDown, bPocketDown, bExcludeH2) or
ML.FindPocketing( sType, dDiam, 0.4 * dDepth, dMaxTotLen, not bPocketDown, bPocketDown, bExcludeH2) or
ML.FindPocketing( sType, dDiam, 0, dMaxTotLen, bExcludeH2)
else
sPocketing = ML.FindPocketing( sType, dDiam, 0, dMaxTotLen, bExcludeH2)
end
if not sPocketing then
return nil
end
-- recupero i dati dell'utensile
local dMaxDepth = 0
local dToolDiam = 0
if EgtMdbSetCurrMachining( sPocketing) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
end
end
return sPocketing, dMaxDepth, dToolDiam
end
---------------------------------------------------------------------
local function VerifyChamfer( Proc, AuxId, nRawId, bMakeVertCham, bDownHead)
local nChamfer = 0
-- ingombro del grezzo
local b3Raw = EgtGetRawPartBBox( nRawId)
-- verifico che lo smusso sia richiesto
local dDepth = EgtGetInfo( Proc.Id, Q_DEPTH_CHAMFER, 'd') or 0
if dDepth > 0 then
nChamfer = 1
end
-- recupero la lavorazione
local sMilling
if nChamfer > 0 then
if bDownHead then
sMilling = ML.FindMilling( 'Mark_H2', nil, nil, nil, nil, false, true)
else
sMilling = ML.FindMilling( 'Mark')
end
if not sMilling then
local sErr = 'Error : Mark not found in library'
EgtOutLog( sErr)
return -1, 0, sErr
end
end
return nChamfer, dDepth, sMilling
end
---------------------------------------------------------------------
-- Applicazione della lavorazione
function ProcessMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH)
-- ingombro del pezzo
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
if not b3Solid then
local sErr = 'Error : part box not found'
EgtOutLog( sErr)
return false, sErr
end
-- recupero e verifico l'entità curva
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
local bForceOneSide
local bRevertSide
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
-- verifico se frontale
local bFront = ( Proc.Prc == 51)
-- recupero i dati della faccia di fondo
local frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT)
local ptC = ORIG()
local vtN = V_NULL()
if frMor then
ptC = frMor:getOrigin()
vtN = frMor:getVersZ()
end
-- recupero versore estrusione della curva supplementare
local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT)
-- Confronto le direzioni dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante
local bOpenBtm = not AreSameVectorApprox( vtExtr, vtN)
-- se curva di contorno aperta la rendo chiusa
local _, bModif = BL.ConvertToClosedCurve( Proc, AuxId)
-- se la mortasa passante il contorno è sulla faccia della trave e il riconoscimento lati aperti non è corretto
if not bModif and not bOpenBtm then
BL.SetOpenSide( AuxId, b3Solid)
end
if bOpenBtm then
-- creo superficie chiusa
local nFlat = EgtSurfTmByFlatContour( EgtGetParent( AuxId), AuxId, 0.05)
if nFlat then
frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT)
ptC = frMor:getOrigin()
vtN = frMor:getVersZ()
-- verifico se copiare la geometria lungo l'asse Z
local b3Aux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frMor)
local bxMax = b3Aux:getMax()
local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor)
local bxMin = b3Mor:getMin()
local dMove = bxMin:getZ()-bxMax:getZ()
-- se il percorso ausiliario è esterno al grezzo, lo riavvicino
if abs( dMove) > GEO.EPS_SMALL then
AuxId = EgtCopyGlob( AuxId, BL.GetAddGroup( nPartId))
local vtMove = Vector3d(0,0,dMove)
vtMove:toGlob(frMor)
EgtMove( AuxId, vtMove, GDB_RT.GLOB)
EgtMove( nFlat, vtMove, GDB_RT.GLOB)
frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT)
ptC = frMor:getOrigin()
vtN = frMor:getVersZ()
end
-- cancello le prove del misfatto (superficie piana)
EgtErase( nFlat)
end
end
-- scrivo info nel log
EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3)
-- Se mortasa chiusa
if not bOpenBtm then
-- verifico che la mortasa non sia orientata verso il basso (limite -5 deg) o che ci sia una testa da sotto o un rinvio angolare o macchina Turn
if vtN:getZ() < -0.1 and not BD.DOWN_HEAD and not BD.ANG_TRASM and not BD.TURN then
local sErr = 'Error : Mortise from bottom impossible'
EgtOutLog( sErr)
return false, sErr
end
-- altrimenti passante
else
-- determino se la mortasa da lavorare sul lato opposto sia di angolo inferiore a quello consentito
if abs( vtN:getZ()) > 0.1 then
bForceOneSide = true
end
-- determino se è meglio lavorare la mortasa nel lato opposto
if vtN:getZ() < -GEO.EPS_SMALL then
bRevertSide = true
end
end
-- se mortasa di fronte, eseguo il taglio della faccia
if bFront then
-- verifico esista la faccia di taglio
local ptCutC, vtCutN = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
if ptCutC and vtCutN and AreSameVectorApprox( vtExtr, vtCutN) then
-- recupero gruppo per geometria addizionale
local nAddGrpId = BL.GetAddGroup( nPartId)
if not nAddGrpId then
local sErr = 'Error : missing AddGroup'
EgtOutLog( sErr)
return false, sErr
end
local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptCutC, vtCutN, b3Solid, GDB_RT.GLOB)
local b3Cut = EgtGetBBoxGlob( AddId or GDB_ID.NULL, GDB_BB.STANDARD)
local CutProc = { Id = AddId, Grp = Proc.Grp - 2, Prc = 10, Box = b3Cut, Fct = 1, Flg = Proc.Flg,
Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId, PartId = Proc.PartId}
CutProc.AffectedFaces = BL.GetProcessAffectedFaces( CutProc)
local bFromBottom = ( b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getZ() > 0.25)
local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH, bFromBottom)
if not bOk then return bOk, sErr end
end
end
-- determino altezza della mortasa
local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor)
local dMorH = b3Mor:getDimZ()
-- elevazione del punto centro
if not bFront then
local _, dCenElev = BL.GetPointDirDepth( nPartId, ptC, vtN)
dMorH = max( dMorH, dCenElev or 0)
end
-- determino larghezza della mortasa
if dL < dW then dL, dW = dW, dL end
-- abilitazione lavorazione da sotto
local bPockUp = ( BD.DOWN_HEAD and vtExtr:getZ() > -0.259)
local bPockDown = ( BD.DOWN_HEAD and vtExtr:getZ() < 0.174)
local bPockAngTrasm = ( BD.ANG_TRASM and vtExtr:getZ() < -0.1)
-- recupero i dati della curva e del profilo
local dDepth = dMorH
local bDownHead = ( BD.DOWN_HEAD and vtExtr:getZ() < 0.1)
local bToolInv = ( not bDownHead and vtExtr:getZ() < -0.1 and Proc.Box:getDimZ() > b3Solid:getDimZ() - 5)
local dExtra = 2
-- verifico se servono gli smussi. Se lavorazione principale di svuotatura significa che è solo da un lato
-- generalmente sono lavorazioni non molto lunghe, quindi non si gestistono gli step
-- verifico i parametri Q per profondità smusso e per eseguirlo in esclusiva
local nChamfer, dDepthCham, sChamfer = VerifyChamfer( Proc, AuxId, nRawId, true)
-- se devo inserire il chamfer
if nChamfer > 0 and Proc.Grp ~= 0 and dDepth > dDepthCham then
-- inserisco la lavorazione
local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
local nMchId = EgtAddMachining( sNameCh, sChamfer)
if not nMchId then
local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer
EgtOutLog( sErr)
return false, sErr
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ AuxId, -1}})
if not bToolInv then
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
EgtSetMachiningParam( MCH_MP.INVERT, true)
else
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
EgtSetMachiningParam( MCH_MP.INVERT, true)
end
-- assegno affondamento e offset radiale
EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra - dMorH)
EgtSetMachiningParam( MCH_MP.OFFSR, dExtra)
-- posizione braccio porta testa
local nSCC = MCH_SCC.NONE
if not BD.C_SIMM then
if Proc.Head then
nSCC = MCH_SCC.ADIR_XP
elseif Proc.Tail then
nSCC = MCH_SCC.ADIR_XM
elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then
nSCC = MCH_SCC.ADIR_YP
elseif vtExtr:getY() > -0.01 then
nSCC = MCH_SCC.ADIR_YP
else
nSCC = MCH_SCC.ADIR_YM
end
end
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- eseguo
if not ML.ApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchId, false)
return false, sErr
end
end
-- recupero la lavorazione
local sPockType = 'Mortise'
local sMchExt = ''
if bPockDown then
sMchExt = '_H2'
elseif bPockAngTrasm then
sMchExt = '_AT'
end
local bExcludeH2 = false
if Proc.Double and Proc.Double > 0 then
bPockUp = false
bPockDown = false
bExcludeH2 = true
sMchExt = ''
end
local sPocketing
if Proc.Prc ~= 53 then
sPocketing = ProcessMortise.VerifyMortiseOrPocket( Proc, dW, dMorH, nil, sPockType..sMchExt, bPockDown, bExcludeH2)
if not sPocketing and bPockUp then
sPocketing = ProcessMortise.VerifyMortiseOrPocket( Proc, dW, dMorH, nil, sPockType..sMchExt, _, bExcludeH2)
end
end
if not sPocketing then
sPockType = 'Pocket'
sPocketing = ProcessMortise.VerifyMortiseOrPocket( Proc, dW, dMorH, nil, sPockType..sMchExt, bPockDown, bExcludeH2)
if not sPocketing and bPockUp then
sPocketing = ProcessMortise.VerifyMortiseOrPocket( Proc, dW, dMorH, nil, sPockType..sMchExt, _, bExcludeH2)
end
end
if not sPocketing then
local sErr = 'Error : Mortise or Pocket not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile
local dMillDiam = 20
local dMaxDepth = 0
local bCW = true
if EgtMdbSetCurrMachining( sPocketing) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth)
local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0
bCW = ( dSpeed >= 0)
end
end
-- inserisco la lavorazione di svuotatura
local sName = 'Mort_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
local nMchFId = EgtAddMachining( sName, sPocketing)
if not nMchFId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
EgtOutLog( sErr)
return false, sErr
end
-- verifico se invertire direzione utensile
if bRevertSide then
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
end
-- se ho anche solo un lato aperto, forzo SPIRAL-IN
local vOpen = EgtGetInfo( AuxId, 'OPEN', 'vi')
if vOpen and #vOpen > 0 then
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ AuxId, -1}})
-- sistemo la direzione di lavoro
EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false))
-- imposto posizione braccio porta testa
local nSCC = MCH_SCC.NONE
if bPockAngTrasm then
nSCC = MCH_SCC.ADIR_NEAR
elseif not BD.C_SIMM and not BD.TURN then
if AreSameOrOppositeVectorApprox( vtN, Z_AX()) then
nSCC = MCH_SCC.ADIR_YM
elseif abs( vtN:getX()) < 0.1 then
local bNearTail = ( Proc.Box:getMax():getX() < b3Solid:getCenter():getX() and
Proc.Box:getMax():getX() - b3Solid:getMin():getX() < 1000)
local bVeryShortPart = ( BD.LEN_VERY_SHORT_PART and b3Solid:getDimX() < BD.LEN_VERY_SHORT_PART)
nSCC = EgtIf( BL.IsPartFinalPhase( EgtGetCurrPhase()) or ( bNearTail and not bVeryShortPart), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
elseif vtN:getY() < GEO.EPS_SMALL then
nSCC = EgtIf( bRevertSide, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
else
nSCC = EgtIf( bRevertSide, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)
end
end
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
local sWarn
local nDepthMin
-- se la mortasa è passante e non è forzata a un solo lato, riduco l'affondamento a metà profondità
if bOpenBtm and not bForceOneSide then
dMorH = dMorH * 0.5
end
-- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente
if dMorH > dMaxDepth + 10 * GEO.EPS_SMALL then
sWarn = 'Warning in mortise : elevation (' .. EgtNumToString( dMorH,1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth,1) .. ')'
-- se non ho invertito la direzione di estrusione
if not bRevertSide then
nDepthMin = dMaxDepth - EgtIf( bOpenBtm and not bForceOneSide, dMorH * 2, dMorH)
else
nDepthMin = dMaxDepth
end
EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin)
dMorH = dMaxDepth
EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')')
else
-- se passante e lavorabile da due lati
if bOpenBtm and not bForceOneSide then
-- imposto metà profondità
nDepthMin = -dMorH
EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin)
-- se altrimenti passante ma lavorabile solo da un lato
elseif bOpenBtm and bForceOneSide then
if bRevertSide then
EgtSetMachiningParam( MCH_MP.DEPTH, min( dMorH + BD.CUT_EXTRA, dMaxDepth))
else
EgtSetMachiningParam( MCH_MP.DEPTH, min( BD.CUT_EXTRA, dMaxDepth - dMorH))
end
end
end
-- imposto elevazione
local sUserNotes = 'MaxElev=' .. EgtNumToString( dMorH, 1) .. ';'
-- se lavorazione in doppio
if Proc.Double and Proc.Double > 0 then
sUserNotes = EgtSetValInNotes( sUserNotes, 'DOUBLE', Proc.Double)
if Proc.Double ~= Proc.PrevDouble then
sUserNotes = EgtSetValInNotes( sUserNotes, 'StartZmax', 2)
end
end
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
-- eseguo
if not ML.ApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
-- Se non c'è il fondo e la lavorazione non ha lavorato tutta la superficie per limite altezza utensile
-- inserisco una ulteriore lavorazione contraria
if bOpenBtm and not bForceOneSide and nDepthMin and abs(nDepthMin) > 0 then
-- inserisco la lavorazione di svuotatura opposta
sName = 'Mort_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_Oppo'
nMchFId = EgtAddMachining( sName, sPocketing)
if not nMchFId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
EgtOutLog( sErr)
return false, sErr
end
-- faccio la copia e la metto nel layer dedicato alle geometrie aggiunte
local AuxId_oppo = EgtCopyGlob( AuxId, BL.GetAddGroup(nPartId))
-- inverto la direzione estrusione di questa
EgtModifyCurveExtrusion( AuxId_oppo, - vtExtr, GDB_ID.ROOT)
-- aggiungo geometria
EgtSetMachiningGeometry( {{ AuxId_oppo, -1}})
-- sistemo la direzione di lavoro
EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false))
-- imposto posizione braccio porta testa
local nSCC = MCH_SCC.NONE
if not BD.C_SIMM and not BD.TURN then
if AreSameOrOppositeVectorApprox( vtN, Z_AX()) then
nSCC = MCH_SCC.ADIR_YM
elseif abs( vtN:getX()) < 0.1 then
local bNearTail = ( Proc.Box:getMax():getX() < b3Solid:getCenter():getX() and
Proc.Box:getMax():getX() - b3Solid:getMin():getX() < 1000)
local bVeryShortPart = ( BD.LEN_VERY_SHORT_PART and b3Solid:getDimX() < BD.LEN_VERY_SHORT_PART)
nSCC = EgtIf( BL.IsPartFinalPhase( EgtGetCurrPhase()) or ( bNearTail and not bVeryShortPart), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
elseif vtN:getY() < GEO.EPS_SMALL then
nSCC = MCH_SCC.ADIR_YP
else
nSCC = MCH_SCC.ADIR_YM
end
end
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- se altezza mortasa differente da altezza massima lavorabile
if abs( dMorH - dMaxDepth) > GEO.EPS_SMALL then
nDepthMin = -dMorH
else -- se sono uguali setto
nDepthMin = -( dMorH - BD.CUT_EXTRA)
end
-- setto profondità
EgtSetMachiningParam( MCH_MP.DEPTH, -nDepthMin+BD.CUT_EXTRA)
-- imposto elevazione
EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( (-nDepthMin+BD.CUT_EXTRA), 1) .. ';')
-- eseguo
if not ML.ApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
end
-- verifico se necessaria la pulizia degli angoli ( tenone ad angoli non raggiati) e applico nel caso
if ( EgtGetInfo( Proc.Id, 'P04', 'i') == 1) then
local _, sWarn2 = CleanCorners( Proc, dMorH, vtN, bOpenBtm and not bForceOneSide, AuxId)
if sWarn2 then
if not sWarn then sWarn = '' end
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
end
end
return true, sWarn
end
---------------------------------------------------------------------
return ProcessMortise