-- ProcessDrill.lua by Egaltech s.r.l. 2023/11/06 -- Gestione calcolo forature per Travi -- 2021/04/14 DS Corretta gestione Invert con testa da sotto. Migliorato calcolo ingombro portautensile. -- 2021/05/03 DS Su macchina con testa da sotto aggiunta possibilità di fare fori verticali metà sopra e l'altra sotto. -- 2021/09/19 DS Si premia il più possibile ricerca punta con adeguato affondamento. -- 2021/10/29 DS MaxElev anche su fori con svuotatura. -- 2022/03/26 DS Correzioni per fori testa-fianco nel piano. -- 2022/03/29 DS Corretta assegnazione fori molto inclinati fianco/coda a coda. -- 2022/04/21 DS Corretto riconoscimento fori di coda. -- 2022/06/22 Nel riconoscimento fori di coda si utilizza ora il reale sovramateriale di coda (dOvmTail) invece di BD.OVM_MID. -- 2022/07/01 Aggiunta gestione allungamento percorsi fori in caso di materiale già rimosso da lavorazioni precedenti -- 2022/07/07 Aggiunta la gestione delle forature migliorate in presenza di feature testa/coda che tagliano tutta la sezione; gli Id delle feature sono nelle proprietà MachineAfterHeadCutId e MachineAfterTailCutId. -- 2022/07/12 Aggiunto un valore minimo (10) per la distanza di sicurezza. -- 2022/07/27 Aggiunta la gestione del tipo di foratura "AngleDrill" per fori molto inclinati -- 2022/08/18 Aggiunta gestione macchine con testa da sotto e punta disabilitata. -- 2022/10/25 Nella funzione Split aggiunto il controllo che le facce di ingresso e uscita siano differenti (potrebbe succedere per fori molto corti). Modifica importatore in futuro. -- 2022/11/23 Aggiunta la gestione dei fori con angolo < 30 gradi, per i quali si usa la testa della macchina per accorciare l'utile di lavoro. -- 2022/12/28 Implementata gestione forature in doppio -- 2023/05/11 Se lavorazione in doppio e precedente no oppure di tipo diverso, forzo risalita a Zmax. -- 2023/07/28 Aggiunta gestione rinvio 90deg solo per forature da sotto esattamente verticali. -- 2023/09/26 Se errore in applicazione lavorazione si inverte e riprova solo se foratura singola su foro aperto. -- 2023/11/06 Migliorata gestione dei fori con AngularTransmission. -- 2024/03/13 Aggiunta gestione Predrill -- 2024/03/18 Per Predrill corretta direzione estrusione per fori con direzione verso il basso -- 2024/09/04 Gestione dipendenza foro-tasca in caso di fase con pezzo ribaltato -- 2024/09/10 In GetData corretta gestione modifica diametro foro -- Tabella per definizione modulo local ProcessDrill = {} -- Include require( 'EgtBase') local BL = require( 'BeamLib') EgtOutLog( ' ProcessDrill started', 1) -- Dati local BD = require( 'BeamData') local ML = require( 'MachiningLib') local FreeContour = require( 'ProcessFreeContour') --------------------------------------------------------------------- -- Riconoscimento della feature function ProcessDrill.Identify( Proc) return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 40) end --------------------------------------------------------------------- -- Classificazione della feature function ProcessDrill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) -- verifico se è in testa if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then return false end -- recupero e verifico l'entità foro local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') if AuxId then AuxId = AuxId + Proc.Id end if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then return false end local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) -- se entrata principale if Proc.Flg > 0 then local nFcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 return ( ( nFcs == 5 or nFcs == 6) and vtExtr:getX() > 0.5) -- altrimenti entrata opposta else local nFce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 return ( ( nFce == 5 or nFce == 6) and vtExtr:getX() < -0.5) end end --------------------------------------------------------------------- -- Verifica se feature di coda function ProcessDrill.IsTailFeature( Proc, b3Raw, dOvmTail) -- sovramateriale di coda dOvmTail = dOvmTail or BD.OVM_MID -- verifico se è in coda if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + dOvmTail + BD.MAX_DIST_HTFEA then return false end -- recupero e verifico l'entità foro local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') if AuxId then AuxId = AuxId + Proc.Id end if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then return false end local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) -- se entrata principale local nFcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 if ( Proc.Flg == 2 or ( Proc.Flg == 1 and vtExtr:getZ() >= BD.DRILL_VZ_MIN)) and ( nFcs == 5 or nFcs == 6 or abs( vtExtr:getX()) < BD.DRILL_VX_MAX) then return ( ( nFcs == 5 or nFcs == 6) and vtExtr:getX() < -0.5) -- altrimenti entrata opposta else local nFce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 return ( ( nFce == 5 or nFce == 6) and vtExtr:getX() > 0.5) end end --------------------------------------------------------------------- -- Recupero dati foro e adattamento se speciale function ProcessDrill.GetData( Proc, b3Raw) local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') -- verifico se foro da adattare if EgtExistsInfo( Proc.Id, 'DiamUser') then local nNewAuxId if AuxId then nNewAuxId = AuxId + Proc.Id end if AuxId and EgtGetType( nNewAuxId) == GDB_TY.CRV_ARC and BD.USER_HOLE_DIAM and BD.USER_HOLE_DIAM > 1 then EgtModifyArcRadius( nNewAuxId, BD.USER_HOLE_DIAM / 2) end end -- recupero diametro e lunghezza local dDiam = EgtGetInfo( Proc.Id, 'P12', 'd') or 0 local dLen = abs( EgtCurveThickness( Proc.Id + AuxId)) 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, dLen, nFcs, nFce end --------------------------------------------------------------------- -- Verifica se da lavorare in due metà function ProcessDrill.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.Fce ~= 0) and ( Proc.Fce ~= Proc.Fcs) -- recupero flag abilitazione split (0=auto,1=no) local bTrySplit = ( EgtGetInfo( Proc.Id, 'Q02', 'i') ~= 1) local bOnlyContour = ( EgtGetInfo( Proc.Id, 'Q04', 'i') == 1) if ( not bTrySplit) or bOnlyContour then return false end -- restituisco se va fatto in doppio (solo fori orizzontali) local bHoriz = ( abs( vtExtr:getZ()) < abs( BD.DRILL_VZ_MIN) and ( abs( vtExtr:getY()) * b3Raw:getDimZ() > abs( vtExtr:getZ()) * b3Raw:getDimY() or Proc.Fce == 5 or Proc.Fce == 6)) local bAngTransm = ( BD.ANG_TRASM and ML.FindDrilling( dDiam, nil, nil, nil, nil, true) and AreSameOrOppositeVectorApprox( vtExtr, Z_AX())) local bSlant = ( abs( vtExtr:getX()) > BD.DRILL_VX_MAX) return ( bOpen and ( bHoriz or BD.ROT90 or BD.DOWN_HEAD or BD.TURN or bAngTransm) and not bSlant) end --------------------------------------------------------------------- -- Verifica se bisogna aggiungere un preforo function ProcessDrill.IsPredrillNeeded( Proc) local dDepthPredrill = EgtGetInfo( Proc.Id, 'Q03', 'i') -- se non c'è la Q oppure se zero, allora non è da fare if not dDepthPredrill or dDepthPredrill <= 0 then return false -- altrimenti Predrill da fare else return true end end --------------------------------------------------------------------- -- Aggiunge il preforo alla feature passata function ProcessDrill.AddPredrillFromDrillProc( Proc) local dDepthPredrill = EgtGetInfo( Proc.Id, 'Q03', 'i') -- foro più corto del preforo, allora è il foro che diventa il preforo stesso if Proc.Len <= dDepthPredrill then Proc.IsPredrill = true Proc.IsPredrillOf = Proc.Id return false -- altrimenti creo un nuovo process else -- recupero gruppo per geometria aggiuntiva local nAddGrpId = BL.GetAddGroup( Proc.PartId) -- recupero e verifico l'entità foro local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 local ptCen = EgtCP( Proc.Id + AuxId, GDB_RT.GLOB) local vtExtr = EgtCurveExtrusion( Proc.Id + AuxId, GDB_RT.GLOB) -- copio foro originale local nPreHoleId = EgtCopyGlob( Proc.Id, nAddGrpId) local nPreHoleAux = EgtCopyGlob( Proc.Id + AuxId, nAddGrpId) -- se foro invertito sposto geometria dall'altro lato del foro e inverto direzione estrusione if Proc.Flg == -2 then local vsExtr = -vtExtr * Proc.Len EgtMove( nPreHoleAux, vsExtr, GDB_RT.GLOB) EgtModifyCurveExtrusion( nPreHoleAux, -vtExtr, GDB_RT.GLOB) end EgtModifyCurveThickness( nPreHoleAux, -dDepthPredrill) local PredrillProc = {} -- definisco dati seconda parte PredrillProc.PartId = Proc.PartId PredrillProc.Id = nPreHoleId PredrillProc.Grp = Proc.Grp PredrillProc.Prc = Proc.Prc PredrillProc.Flg = 1 PredrillProc.Box = Proc.Box PredrillProc.Fct = Proc.Fct PredrillProc.Diam = Proc.Diam PredrillProc.Len = dDepthPredrill PredrillProc.Head = Proc.Head PredrillProc.Tail = Proc.Tail PredrillProc.Fcs = Proc.Fcs PredrillProc.Fce = 0 -- il preforo è sempre chiuso, non ha faccia di uscita PredrillProc.CutId = Proc.CutId PredrillProc.TaskId = Proc.TaskId PredrillProc.AdjId = Proc.AdjId PredrillProc.MainId = Proc.MainId PredrillProc.IsPredrill = true PredrillProc.IsPredrillOf = Proc.Id -- recupero l'elenco delle facce della parte interessate dalla feature PredrillProc.AffectedFaces = BL.GetProcessAffectedFaces( PredrillProc) return true, PredrillProc end end --------------------------------------------------------------------- -- Classificazione della feature function ProcessDrill.Classify( Proc, b3Raw, sDownOrSideOrStd) -- 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 lavorato in doppio, devo considerare il lato più sfavorevole if Proc.Flg == -2 or (( BD.ROT90 or BD.DOWN_HEAD) and Proc.Flg == 2) then if vtExtr:getZ() > 0 then vtExtr = - vtExtr ptCen = ptCen + vtExtr * dLen end end -- verifico se foro annegato nel pezzo e quindi non lavorabile if Proc.Fcs == 0 and Proc.Fce == 0 then return false, false, false end -- 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()) > BD.DRILL_VX_MAX then return false, false, false end local bOpen = ( Proc.Fce ~= 0) local bFaceDown = ( ptCen:getZ() < b3Raw:getMin():getZ() + 2 and (( not Proc.Head and not Proc.Tail) or (( BD.ROT90 or BD.DOWN_HEAD or BD.TURN) and abs( Proc.Flg) == 2))) local bAngTransm = ( BD.ANG_TRASM and ML.FindDrilling( dDiam, nil, nil, nil, nil, true) and AreSameOrOppositeVectorApprox( vtExtr, Z_AX())) -- se ci sono delle dipendenze da altre feature da rispettare if sDownOrSideOrStd then if sDownOrSideOrStd == 'DOWN' then -- se foro fatto in doppio entrambe le forature (valore assoluto) devono essere sopra al valore limite, se foro singolo deve essere sopra al valore limite se ribaltato if ( abs( Proc.Flg) == 2 and ( abs( vtExtr:getZ()) < - BD.DRILL_VZ_MIN) or ( abs( Proc.Flg) ~= 2 and vtExtr:getZ() < - BD.DRILL_VZ_MIN)) then -- in doppio non cambio di fase al foro perchè devo garantire il lato master su H1 if not( Proc.Double) or Proc.Double == 0 then Proc.Down = true Proc.Side = false end return true end end return false end -- verifico se il foro è sotto e quindi va spostato o sopra o sul fianco if (( vtExtr:getZ() < BD.DRILL_VZ_MIN or bFaceDown) and ( not bOpen or Proc.Flg ~= 1)) then if not bOpen then -- se da sotto e presente rinvio angolare verifico se c'è opportuna lavorazione if bAngTransm then return true, false, false else return true, true, false end else return true, not ( BD.ROT90 or BD.DOWN_HEAD or BD.TURN or bAngTransm), ( BD.ROT90 or BD.DOWN_HEAD or BD.TURN) end else return true, false, false end end --------------------------------------------------------------------- -- Funzione per riconoscimento faccia inizio foro e dati correlati -- Indice faccia :1=Front, 2=Bottom, 3=Back, 4=Top, 5=Left, 6=Right local function GetHoleStartData( ptCen, vtExtr, b3Solid) -- Facce della trave local vFaces = { { Dist = -b3Solid:getMin():getY(), Norm = -Y_AX()}, { Dist = -b3Solid:getMin():getZ(), Norm = -Z_AX()}, { Dist = b3Solid:getMax():getY(), Norm = Y_AX()}, { Dist = b3Solid:getMax():getZ(), Norm = Z_AX()}, { Dist = -b3Solid:getMin():getX(), Norm = -X_AX()}, { Dist = b3Solid:getMax():getX(), Norm = X_AX()}} -- Ricerca della faccia di inizio local nFac = 0 local dCosMin = 0.0871 for i = 1, 6 do if ( ptCen - ORIG()) * vFaces[i].Norm - vFaces[i].Dist > -2 then local dCos = vtExtr * vFaces[i].Norm if dCos > dCosMin then nFac = i dCosMin = dCos if dCos > 0.7072 then break end end end end -- Coseno angolo dalla faccia local CosB = 0 if nFac ~= 0 then CosB = sqrt( 1 - sqr( vtExtr * vFaces[nFac].Norm)) end return nFac, CosB, vFaces end --------------------------------------------------------------------- local function GetSCC( Proc, vtExtr, b3Solid, bDrillAngTrasm, nPhase) local nSCC = MCH_SCC.NONE if bDrillAngTrasm then nSCC = MCH_SCC.ADIR_NEAR elseif BD.TURN == 2 then nSCC = MCH_SCC.ADIR_ZP elseif not BD.C_SIMM and not BD.TURN then nSCC = MCH_SCC.ADIR_YM if AreSameVectorApprox( vtExtr, Z_AX()) then nSCC = MCH_SCC.ADIR_YM elseif abs( vtExtr:getX()) < 0.1 then local bNearTail = ( Proc.Box:getCenter():getX() < b3Solid:getCenter():getX() and Proc.Box:getCenter():getX() - b3Solid:getMin():getX() < 1000) local bVeryShortPart = ( BD.LEN_VERY_SHORT_PART and b3Solid:getDimX() < BD.LEN_VERY_SHORT_PART) nSCC = EgtIf( BL.IsPartFinalPhase( nPhase) or ( bNearTail and not bVeryShortPart), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) elseif vtExtr:getY() > 0.1 then nSCC = MCH_SCC.ADIR_YP end else nSCC = MCH_SCC.NONE end return nSCC end --------------------------------------------------------------------- -- Applicazione della lavorazione function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- Se forzato contorno foro forzo richiamo a FreeContour e uscita dalla funzione if EgtGetInfo( Proc.Id, 'Q04', 'i') == 1 then return FreeContour.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) end -- default per costanti BD.DRILL_VX_MAX_ANGLEDRILL = ( BD.DRILL_VX_MAX_ANGLEDRILL or 0.928) -- 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à 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 ptCen = EgtCP( AuxId, GDB_RT.GLOB) local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) if Proc.Flg == -2 then ptCen = ptCen - vtExtr * dLen vtExtr = - vtExtr end local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) -- verifico possibilità di foratura da sotto local bDownDrill = ( BD.TURN or ( BD.DOWN_HEAD and ML.FindDrilling( dDiam, nil, false, true))) -- se presente rinvio angolare local bDrillAngTrasm = ( BD.ANG_TRASM and ML.FindDrilling( dDiam, nil, nil, nil, nil, true) and AreOppositeVectorApprox( vtExtr, Z_AX())) -- verifico che il foro non sia fattibile solo da sotto local bToInvert = ( vtExtr:getZ() < BD.DRILL_VZ_MIN and not bDownDrill and not bDrillAngTrasm) if bToInvert and ( not bOpen or Proc.Flg ~= 1) then local sErr = 'Error : drilling from bottom impossible' EgtOutLog( sErr) return false, sErr end local nFac, CosB -- se non già richiesta inversione e invertibile if not bToInvert and Proc.Flg == 1 and -vtExtr:getZ() >= BD.DRILL_VZ_MIN then -- se il foro è cieco o dalla faccia sotto o troppo inclinato all'inizio, lo inverto nFac, CosB, _ = GetHoleStartData( ptCen, vtExtr, b3Solid) if Proc.Fcs == 0 or (( nFac == 2 or CosB > BD.DRILL_VX_MAX) and bOpen) then bToInvert = true end end if bToInvert then ptCen = ptCen - vtExtr * dLen vtExtr = - vtExtr end -- se foro è splittato ed è la parte opposta, inverto if Proc.Flg == -2 then bToInvert = true end -- profondità geometrica del foro local dDepth = dLen local dDepth2 = dLen if Proc.Flg == 2 or Proc.Flg == -2 then dDepth = dLen / 2 + BD.DRILL_OVERLAP end local dCheckDepth = dDepth local dCheckDepth2 = dDepth2 local nErrorCode = 0 -- abilitazione foratura da sotto local bDrillDown = ( bDownDrill and ( Proc.Down or vtExtr:getZ() < -0.1 or vtExtr:getZ() < 0.259)) local bDrillUp = ( bDownDrill and vtExtr:getZ() > -0.421) local bExcludeH2 = false if Proc.Double and Proc.Double > 0 then -- bMillUp = true bDrillDown = false bExcludeH2 = true end -- primo gruppo di controlli con lunghezza utensile pari a metà foro se passante -- recupero la lavorazione local sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, dCheckDepth, bDrillUp, bDrillDown, bExcludeH2, bDrillAngTrasm, Proc.IsPredrill) local dMaxDepthOri local vFaces if sDrilling then -- Determino la faccia di inizio del foro e dati correlati nFac, CosB, vFaces = GetHoleStartData( ptCen, vtExtr, b3Solid) -- Calcolo acciorciamento affondamento utile per evitare collisione portautensile con faccia local TgA = CosB / sqrt( 1 - CosB * CosB) local dSubL = ( dDiamTh / 2 + ( Proc.Diam - dToolDiam) / 2 + 4) * TgA -- Per fori molto inclinati ( < 30 gradi) si usa la testa della macchina per l'accorciamento. Fast esclusa if BD.C_SIMM and CosB > 0.866 then dSubL = ( 190 / 2 + ( Proc.Diam - dToolDiam) / 2 + 4) * TgA - 116 end dMaxDepthOri = dMaxDepth dMaxDepth = min( dMaxDepth, max( dToolFreeLen - dSubL, 0)) -- se utensile scelto non arriva in fondo, cerco il più lungo if dMaxDepth < GEO.EPS_SMALL * 10 then sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, dCheckDepth, bDrillUp, bDrillDown, bExcludeH2, bDrillAngTrasm, Proc.IsPredrill, nil, 'Longest') end end if not sDrilling and dCheckDepth then sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, 0, bDrillUp, bDrillDown, bExcludeH2, bDrillAngTrasm, Proc.IsPredrill) if sDrilling then dCheckDepth = nil end end if not sDrilling then nErrorCode = 1 end -- se trovata la lavorazione e la lunghezza massima utensile supera il valore limite del BeamData e inclinato più di 10 gradi da Z -- allora ricerco un utensile senza imporre minima capacità di taglio if nErrorCode == 0 and dMaxToolLength > ( BD.MAX_TOOL_LEN_FOR_HOR_MACH or 300) and abs( vtExtr:getZ()) < ( BD.DRILL_VZ_MIN_LONG_TOOL or cos(10)) then -- se non ho passato altezza di taglio utensile allora la lunghezza utensile non è idonea per il taglio if not dCheckDepth then nErrorCode = 2 -- rifaccio ricerca lavorazione senza specificare la profondità (dovrebbe trovare l'utensile più corto) else sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, 0, bDrillUp, bDrillDown) if not sDrilling then nErrorCode = 1 elseif dMaxToolLength > ( BD.MAX_TOOL_LEN_FOR_HOR_MACH or 300) and abs( vtExtr:getZ()) < ( BD.DRILL_VZ_MIN_LONG_TOOL or cos(10)) then nErrorCode = 2 end end end -- secondo gruppo di controlli con lunghezza richiesta pari all'intero foro -- recupero la lavorazione local sDrilling2, sType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 if dDepth2 > dDepth + BD.DRILL_OVERLAP then sDrilling2, sType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 = ML.FindDrilling( dDiam, dCheckDepth2, bDrillUp, bDrillDown) if not sDrilling2 and dCheckDepth2 then sDrilling2, sType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 = ML.FindDrilling( dDiam, 0, bDrillUp, bDrillDown) if sDrilling2 then dCheckDepth2 = nil end end if not sDrilling2 then nErrorCode = 1 end -- se trovata la lavorazione e la lunghezza massima utensile supera il valore limite del BeamData e inclinato più di 10 gradi da Z -- allora ricerco un utensile senza imporre minima capacità di taglio if nErrorCode == 0 and dMaxToolLength2 > ( BD.MAX_TOOL_LEN_FOR_HOR_MACH or 300) and abs( vtExtr:getZ()) < ( BD.DRILL_VZ_MIN_LONG_TOOL or cos(10)) then -- se non ho passato altezza di taglio utensile allora la lunghezza utensile non è idonea per il taglio if not dCheckDepth2 then nErrorCode = 2 -- rifaccio ricerca lavorazione senza specificare la profondità (dovrebbe trovare l'utensile più corto) else sDrilling2, sType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 = ML.FindDrilling( dDiam, 0, bDrillUp, bDrillDown) if not sDrilling2 then nErrorCode = 1 elseif dMaxToolLength2 > ( BD.MAX_TOOL_LEN_FOR_HOR_MACH or 300) and abs( vtExtr:getZ()) < ( BD.DRILL_VZ_MIN_LONG_TOOL or cos(10)) then nErrorCode = 2 end end end end -- se esiste il parametro massima lunghezza per fori da dietro e il foro è passante e non è ancora stato invertito -- ed è orizzontale ed è orientato principalmente verso Y+ e non è la parte splittata e l'utensile supera una certa lunghezza -- lo inverto per premiare l'entrata davanti local bCommonCompare = BD.MAX_TOOL_LEN_BACK_HOR_MACH and bOpen and abs(vtExtr:getX()) < 0.5 and abs(vtExtr:getZ()) < 0.5 if nErrorCode == 0 and not bToInvert and bCommonCompare and vtExtr:getY() > 0.866 and Proc.Flg == 1 and dMaxToolLength > BD.MAX_TOOL_LEN_BACK_HOR_MACH then bToInvert = true ptCen = ptCen - vtExtr * dLen vtExtr = - vtExtr --------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------- -- 14/12/2020 richiesta di Fabio Squaratti: con foro orizzontale passante e parametro Q02 = 0 (settato per fare in due parti), -- se punta più lunga del parametro BD.MAX_TOOL_LEN_BACK_HOR_MACH alloro ignoro la doppia foratura contrapposta e faccio foratura solo dal davanti -- Questo implica che il valore del parametro Q02 = 0 non è vincolante perchè basta che l'utensile supera il parametro allora la foratura si comporta -- come se il parametro Q02 sia = 1 --------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------- elseif nErrorCode == 0 and not bToInvert and bCommonCompare and abs(vtExtr:getY()) > 0.866 and Proc.Flg == 2 and dMaxToolLength2 > BD.MAX_TOOL_LEN_BACK_HOR_MACH then sDrilling = sDrilling2 sType = sType2 dMaxDepth = dMaxDepth2 dToolDiam = dToolDiam2 dDiamTh = dDiamTh2 dToolFreeLen = dToolFreeLen2 dDepth = dDepth2 if vtExtr:getY() > 0 then bToInvert = true ptCen = ptCen - vtExtr * dLen vtExtr = - vtExtr end -- se sono al secondo mezzo foro con utensile che supera la lunghezza di riferimento non lo eseguo elseif nErrorCode == 0 and bCommonCompare and abs(vtExtr:getY()) > 0.866 and Proc.Flg == -2 and dMaxToolLength2 > BD.MAX_TOOL_LEN_BACK_HOR_MACH then return true, '' end if nErrorCode == 1 then local sErr = 'Error : drilling not found in library' EgtOutLog( sErr) return false, sErr elseif nErrorCode == 2 then local sErr = 'Error : tool too long to machine with big angle from vertical' EgtOutLog( sErr) return false, sErr end -- eventuale inversione foro in base al lato di lavoro e al lato testa dell'utensile scelto -- se non già richiesta inversione e foro quasi orizzontale (15deg) passante if not bToInvert and Proc.Flg == 1 and bOpen and abs( vtExtr:getZ()) < 0.259 and abs( vtExtr:getY()) > 0.966 then local Tool = BL.GetToolFromMachining( sDrilling) -- lato testa e lato di lavoro devono corrispondere if Tool.PreferredSide then if ( ( Tool.PreferredSide.bFront == true) and vtExtr:getY() > 10 * GEO.EPS_SMALL) or ( ( Tool.PreferredSide.bBack == true) and vtExtr:getY() < - 10 * GEO.EPS_SMALL) then ptCen = ptCen - vtExtr * dLen vtExtr = - vtExtr bToInvert = true end end end -- Determino la faccia di inizio del foro e dati correlati nFac, CosB, vFaces = GetHoleStartData( ptCen, vtExtr, b3Solid) -- Calcolo acciorciamento affondamento utile per evitare collisione portautensile con faccia TgA = CosB / sqrt( 1 - CosB * CosB) dSubL = ( dDiamTh / 2 + ( Proc.Diam - dToolDiam) / 2 + 4) * TgA -- Per fori molto inclinati ( < 30 gradi) si usa la testa della macchina per l'accorciamento. Fast esclusa if BD.C_SIMM and CosB > 0.866 then dSubL = ( 190 / 2 + ( Proc.Diam - dToolDiam) / 2 + 4) * TgA - 116 end dMaxDepthOri = dMaxDepth dMaxDepth = min( dMaxDepth, max( dToolFreeLen - dSubL, 0)) -- Verifico inclinazione foro nei limiti local bTryDrill = EgtIf( dMaxDepth > 0, ( CosB < BD.DRILL_VX_MAX), false) -- se il foro deve essere eseguito dopo un taglio, potrebbe essere perchè il taglio crea una superficie perpendicolare if Proc.Dependency and Proc.Dependency.ExecAfter then local ptCut, vtCutN = EgtSurfTmFacetCenter( Proc.Dependency.ExecAfter.Id, 0, GDB_ID.ROOT) local dMaxAngleDrillOnCut = BD.MAX_ANGLE_DRILL_CUT or 10 local dAngle = GetAngle( vtExtr, vtCutN) CosB = cos( dAngle) if dAngle < dMaxAngleDrillOnCut then -- controllo di essere nei limiti bTryDrill = true end end if ( CosB > 0.8 * BD.DRILL_VX_MAX and CosB < BD.DRILL_VX_MAX_ANGLEDRILL) then -- cerco le forature speciali AngleDrill local sDrilling3, sType3, dMaxDepth3 = ML.FindAngleDrilling( dDiam, dCheckDepth, bDrillUp, bDrillDown) if sDrilling3 then sDrilling = sDrilling3 sType = sType3 dMaxDepth = dMaxDepth3 bTryDrill = true end end -- aggiusto affondamento e MaxElev local dMaxElev local sMyWarn -- se c'è un taglio precedente di testa o coda in cui il foro "entra" devo ricalcolare i dati della foratura if ( not Proc.Double or Proc.Double == 0) and(( Proc.MachineAfterHeadCutId and vtExtr:getX() > 0) or ( Proc.MachineAfterTailCutId and vtExtr:getX() < 0)) then local bIntersectionOk, _, vDistance = EgtLineSurfTmInters( ptCen, -vtExtr, Proc.MachineAfterHeadCutId or Proc.MachineAfterTailCutId, GDB_RT.GLOB) if bIntersectionOk then local dHoleToCutDistance = vDistance[1] -- se il taglio accorcia realmente il foro if ( dHoleToCutDistance > 10 * GEO.EPS_SMALL or Proc.AffectedFaces.Right) and dHoleToCutDistance < dLen then dMaxDepth = dMaxDepthOri dMaxElev = dLen - dHoleToCutDistance bTryDrill = true local dToolAddLength = dLen - dMaxElev -- se l'utensile è comunque troppo corto lavoro il massimo possibile if dDepth - dToolAddLength > dMaxDepth + 10 * GEO.EPS_SMALL then sMyWarn = 'Warning in drill : depth (' .. EgtNumToString( dDepth - dToolAddLength, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' dDepth = dLen else -- se è un foro splittato cerco comunque di arrivare alla massima profondità possibile, evitando di sfondare dall'altro lato. if Proc.Flg == 2 or Proc.Flg == -2 then dDepth = dLen - 10 end -- se non lavoro la massima lunghezza disponibile devo correggere MaxElev dMaxElev = dMaxElev - dLen + dDepth end end end end local dDepthOri = dDepth -- se foro da saltare per eccessiva inclinazione if not bTryDrill then sMyWarn = 'Warning in drill : too slant hole' dDepth = 0 return true, sMyWarn -- se non ridotto e affondamento richiesto supera il consentito elseif not dMaxElev and dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then sMyWarn = 'Warning in drill : depth (' .. EgtNumToString( dDepth, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' dDepth = dMaxDepth dMaxElev = dMaxDepth end -- inserisco la lavorazione local sName = EgtIf( EgtStartsWith( sType, 'Predrill'), 'Predrill_', '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 -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- eventuali note utente local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) or '' -- eventuale inversione if sType == 'Drill' or sType == 'Drill_H2' or sType == 'Drill_AT' or sType == 'AngleDrill' or sType == 'Predrill' then EgtSetMachiningParam( MCH_MP.INVERT, bToInvert) else EgtSetMachiningParam( MCH_MP.TOOLINVERT, bToInvert) end -- imposto posizione braccio porta testa local nSCC = GetSCC( Proc, vtExtr, b3Solid, bDrillAngTrasm, nPhase) EgtSetMachiningParam( MCH_MP.SCC, nSCC) -- imposto affondamento local dLastStepDepth if Proc.Double and Proc.Double > 0 then if ( sType == 'Pocket_AT' or sType == 'Pocket') then if bOpen then local dReduceDepth = MIRROR_POCKETS_MIN_DISTANCE / 2 + 10 dLastStepDepth = dDepth + dReduceDepth dDepth = dDepth - dReduceDepth if ( dLastStepDepth > dMaxDepth + 10 * GEO.EPS_SMALL) and ( dMaxDepth <= ( dLen / 2) - dReduceDepth) and ( dDepthOri ~= dDepth) then dDepth = dMaxDepth end end else sUserNotes = EgtSetValInNotes( sUserNotes, 'LastStep', MIRROR_DRILLINGS_MIN_DISTANCE / 2 + 15) end if dDepth > Proc.MachDepthDouble + 10 * GEO.EPS_SMALL then sMyWarn = 'Warning in double head drilling : depth (' .. EgtNumToString( dDepth, 1) .. ') reduced to (' .. EgtNumToString( Proc.MachDepthDouble, 1) .. ') to match H2 max tool depth' dDepth = Proc.MachDepthDouble dMaxElev = Proc.MachDepthDouble end end EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) -- imposto il valore della distanza di sicurezza per l'attacco. Se il valore del db utensili è troppo basso lo alzo a 10. local dToolDbStartPos = EgtGetMachiningParam( MCH_MP.STARTPOS) local dMinStartPos = 10 local dStartPos = max( dMinStartPos, dToolDbStartPos) EgtSetMachiningParam( MCH_MP.STARTPOS, dStartPos) -- dichiarazione nessuna generazione sfridi per Vmill sUserNotes = EgtSetValInNotes( sUserNotes, 'VMRS', 0) -- aggiungo alle note massima elevazione (coincide con affondamento) local dCustomMaxElev if Proc.dCustomMaxElev and type( Proc.dCustomMaxElev) == "number" and Proc.dCustomMaxElev > 10 * GEO.EPS_SMALL then dCustomMaxElev = Proc.dCustomMaxElev end if dMaxElev or dCustomMaxElev then if dCustomMaxElev then sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( dCustomMaxElev, 1)) else sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( dMaxElev, 1)) end end -- se foro passante, aggiungo questa qualifica alle note if ( sType == 'Drill' or sType == 'Drill_H2' or sType == 'AngleDrill') and bOpen then sUserNotes = EgtSetValInNotes( sUserNotes, 'Open', 1) end -- 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 local bOk = ML.ApplyMachining( true, false) if not bOk and bDownDrill and bOpen and abs( Proc.Flg) == 1 then if sType == 'Drill' or sType == 'Drill_H2' or sType == 'AngleDrill' then EgtSetMachiningParam( MCH_MP.INVERT, true) else EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) end bOk = ML.ApplyMachining( true, false) end 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 -- se DrillPocket passante in doppio si fa lavorazione aggiuntiva dell'ultimo step if Proc.Double and Proc.Double > 0 and ( sType == 'Pocket_AT' or sType == 'Pocket') and bOpen then if dLastStepDepth > dMaxDepth + 10 * GEO.EPS_SMALL then sMyWarn = 'Warning in drill pocket last step: depth (' .. EgtNumToString( dLastStepDepth, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' return false, sMyWarn end local idMachiningLastStep = EgtCopyMachining( EgtIf( EgtStartsWith( sType, 'Predrill'), 'Predrill_', 'Drill_') .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)), sName) EgtSetCurrMachining( idMachiningLastStep) local dMaxElevLastStep = dLastStepDepth - dDepth sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( dMaxElevLastStep, 1)) EgtSetMachiningParam( MCH_MP.DEPTH, dLastStepDepth) sUserNotes = EgtSetValInNotes( sUserNotes, 'DOUBLE', '') sUserNotes = EgtSetValInNotes( sUserNotes, 'StartZmax', '') EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) local bOkLastStep = ML.ApplyMachining( true, false) if not bOkLastStep and bDownDrill and bOpen and abs( Proc.Flg) == 1 then if sType == 'Drill' or sType == 'Drill_H2' or sType == 'AngleDrill' then EgtSetMachiningParam( MCH_MP.INVERT, true) else EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) end bOkLastStep = ML.ApplyMachining( true, false) end if not bOkLastStep then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, false) return false, sErr else local _, sWarnLastStep = EgtGetMachMgrWarning( 0) if not bOkLastStep then sWarnLastStep = 'Drillpocket double : incomplete, last step missing' end local sPreviousWarn = sMyWarn or sWarn if sWarnLastStep then if not sPreviousWarn then sPreviousWarn = '' end sMyWarn = EgtIf( #sPreviousWarn > 0, sPreviousWarn .. '\n' .. sWarnLastStep, sWarnLastStep) end end end return true, ( sMyWarn or sWarn) end end return true, sMyWarn end --------------------------------------------------------------------- return ProcessDrill