-- 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