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