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