diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index facd6ad..85a0666 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -30,6 +30,8 @@ -- 2022/06/10 Per sezioni alte e larghe modificata la gestione del sovramateriale per considerare la presenza di feature preesistenti ed -- eventuale parametro Q05, che determinano la presenza o meno della finitura. -- Create le funzioni AnalyzeHeadFeatures e AnalyzeTailFeatures. Spostate più in alto le funzioni CollectFeatures, isHeadFeature e isTailFeature. +-- 2022/07/01 Aggiunta la gestione delle forature migliorate in presenza di feature testa/coda ad 1 faccia che tagliano tutta la sezione, +-- controllata tramite il parametro IMPROVE_HEAD_TAIL_DRILLINGS da BeamData. Attivata di default. -- Tabella per definizione modulo local BeamExec = {} @@ -123,7 +125,6 @@ local FreeContour = require( 'ProcessFreeContour') local Decor = require( 'ProcessDecor') EgtOutLog( ' BeamExec started', 1) - EgtMdbSetGeneralParam( MCH_GP.MAXDEPTHSAFE, BD.COLL_SIC) EgtMdbSave() @@ -226,13 +227,23 @@ local function IsTailFeature( Proc, b3Raw, dCurrOvmH, dCurrOvmT) return false end +------------------------------------------------------------------------------------------------------------- +-- restituisce vero se la feature con box b3Proc taglia l'intera sezione della barra, rappresentata dalle sue dimensioni W e H +local function IsFeatureCuttingEntireSection( b3Proc, dRawW, dRawH) + return ((abs(b3Proc:getDimY() - dRawW) < 10 * GEO.EPS_SMALL or b3Proc:getDimY() > dRawW) and (abs(b3Proc:getDimZ() - dRawH) < 10 * GEO.EPS_SMALL or b3Proc:getDimZ() > dRawH)) +end + ------------------------------------------------------------------------------------------------------------- local function CollectFeatures( PartId, b3Raw, dCurrOvmH, dCurrOvmT) + local dRawW = b3Raw:getDimY() + local dRawH = b3Raw:getDimZ() -- recupero le feature local vProc = {} local LayerId = {} LayerId[1] = BL.GetAddGroup( PartId) LayerId[2] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Processings') + local nMachineBeforeIntersectingDrillingsIdHead, dMachineBeforeIntersectingDrillingsXHead, nMachineBeforeIntersectingDrillingsIdTail, dMachineBeforeIntersectingDrillingsXTail = nil, GEO.INFINITO, nil, -GEO.INFINITO + local b3MachineBeforeIntersectingDrillingsBoxHead, b3MachineBeforeIntersectingDrillingsBoxTail = nil, nil for nInd = 1, 2 do local ProcId = EgtGetFirstInGroup( LayerId[nInd] or GDB_ID.NULL) while ProcId do @@ -260,6 +271,17 @@ local function CollectFeatures( PartId, b3Raw, dCurrOvmH, dCurrOvmT) if Proc.Box and not Proc.Box:isEmpty() then Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH) Proc.Tail, Proc.AdvTail = IsTailFeature( Proc, b3Raw, dCurrOvmH, dCurrOvmT) + if Proc.Fct == 1 and IsFeatureCuttingEntireSection( Proc.Box , dRawW, dRawH) and ( Proc.Head or Proc.Tail) and Proc.Prc ~= 340 and Proc.Prc ~= 350 then + if Proc.Head and Proc.Box:getCenter():getX() < dMachineBeforeIntersectingDrillingsXHead then + dMachineBeforeIntersectingDrillingsXHead = Proc.Box:getCenter():getX() + nMachineBeforeIntersectingDrillingsIdHead = Proc.Id + b3MachineBeforeIntersectingDrillingsBoxHead = Proc.Box + elseif Proc.Tail and Proc.Box:getCenter():getX() > dMachineBeforeIntersectingDrillingsXTail then + dMachineBeforeIntersectingDrillingsXTail = Proc.Box:getCenter():getX() + nMachineBeforeIntersectingDrillingsIdTail = Proc.Id + b3MachineBeforeIntersectingDrillingsBoxTail = Proc.Box + end + end table.insert( vProc, Proc) -- se foro if Drill.Identify( Proc) then @@ -310,7 +332,11 @@ local function CollectFeatures( PartId, b3Raw, dCurrOvmH, dCurrOvmT) ProcId = EgtGetNext( ProcId) end end - return vProc + local vMachineBeforeIntersectingDrillings = { + Head = { Id = nMachineBeforeIntersectingDrillingsIdHead, Box = b3MachineBeforeIntersectingDrillingsBoxHead}, + Tail = { Id = nMachineBeforeIntersectingDrillingsIdTail, Box = b3MachineBeforeIntersectingDrillingsBoxTail} + } + return vProc, vMachineBeforeIntersectingDrillings end ------------------------------------------------------------------------------------------------------------- @@ -330,8 +356,7 @@ local function AnalyzeHeadFeatures( b3Solid, vProc, dRawW, dRawH) end if Proc.Head and Proc.Id ~= nReplacedFeatureId and Proc.Prc ~= 340 then -- controllo se la feature taglia l'intera sezione; in caso positivo la finitura non è necessaria - bHeadFinishingNeeded = not (( abs( Proc.Box:getDimY() - dRawW) < 10 * GEO.EPS_SMALL or Proc.Box:getDimY() > dRawW) and - ( abs( Proc.Box:getDimZ() - dRawH) < 10 * GEO.EPS_SMALL or Proc.Box:getDimZ() > dRawH)) + bHeadFinishingNeeded = not IsFeatureCuttingEntireSection( Proc.Box, dRawW, dRawH) end end return bHeadFinishingNeeded, nReplacedFeatureId @@ -354,8 +379,7 @@ local function AnalyzeTailFeatures( b3Solid, vProc, dRawW, dRawH) end if Proc.Tail and Proc.Id ~= nReplacedFeatureId and Proc.Prc ~= 350 then -- controllo se la feature taglia l'intera sezione; in caso positivo la finitura non è necessaria - bTailFinishingNeeded = not (( abs( Proc.Box:getDimY() - dRawW) < 10 * GEO.EPS_SMALL or Proc.Box:getDimY() > dRawW) and - ( abs( Proc.Box:getDimZ() - dRawH) < 10 * GEO.EPS_SMALL or Proc.Box:getDimZ() > dRawH)) + bTailFinishingNeeded = not IsFeatureCuttingEntireSection( Proc.Box, dRawW, dRawH) end end return bTailFinishingNeeded, nReplacedFeatureId @@ -861,12 +885,18 @@ local function ClassifyFeatures( vProc, b3Raw, Stats) local bSplitRot = false local nHeading local nSplitting + local vMachineBeforeIntersectingDrillingsId = {} for i = 1, #vProc do local Proc = vProc[i] local bOk = true local bDown = false local bSide = false local bDownSideOnHeadOk = false + + if Proc.MachineBeforeIntersectingDrillings then + table.Insert ( vMachineBeforeIntersectingDrillingsId, Proc.Id) + end + -- se senza geometria (già disabilitato if Proc.Flg == 0 then bOk = false @@ -1283,8 +1313,68 @@ local function MoveDrillsOnTenon( vProc) end end +------------------------------------------------------------------------------------------------------------- +-- verifica se ci sono forature da lavorare dopo tagli di testa o coda e nel caso le classifica come Head o Tail e gli assegna l'Id della rispettiva feature di taglio +local function SetDrillingsToMachineAfterHeadOrTailCut( vProc, vMachineBeforeIntersectingDrillings) + for i = 1, #vProc do + if Drill.Identify( vProc[i]) then + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( vProc[i].Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + vProc[i].Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + return false + end + -- recupero il vettore estrusione + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local bOpen = ( vProc[i].Fcs ~= 0 and vProc[i].Fce ~= 0) + local ptCen = EgtCP( AuxId, GDB_RT.GLOB) + local vDistHead, vDistTail + -- check intersezione con feature di testa + if vMachineBeforeIntersectingDrillings.Head.Id then + -- verifico che ci sia intersezione tra la feature foro e la feature taglio di testa + local bIntersectionWithHead = + vMachineBeforeIntersectingDrillings.Head.Box and vProc[i].Box:getMin():getX() < vMachineBeforeIntersectingDrillings.Head.Box:getMax():getX() + 100 * GEO.EPS_SMALL and + vMachineBeforeIntersectingDrillings.Head.Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL + -- verifico che ci sia intersezione tra la direzione di estrusione e la faccia della feature taglio di testa + if bIntersectionWithHead then + _, _, vDistHead = EgtLineSurfTmInters( ptCen, -vtExtr, vMachineBeforeIntersectingDrillings.Head.Id, GDB_RT.GLOB) + end + end + -- check intersezione con feature di coda + if vMachineBeforeIntersectingDrillings.Tail.Id then + -- verifico che ci sia intersezione tra la feature foro e la feature taglio di coda + local bIntersectionWithTail = + vMachineBeforeIntersectingDrillings.Tail.Box and vProc[i].Box:getMin():getX() < vMachineBeforeIntersectingDrillings.Tail.Box:getMax():getX() + 100 * GEO.EPS_SMALL and + vMachineBeforeIntersectingDrillings.Tail.Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL + -- verifico che ci sia intersezione tra la direzione di estrusione e la faccia della feature taglio di coda + if bIntersectionWithTail then + _, _, vDistTail = EgtLineSurfTmInters( ptCen, -vtExtr, vMachineBeforeIntersectingDrillings.Tail.Id, GDB_RT.GLOB) + end + end + -- se esiste intersezione tra il foro e la feature di testa + if vDistHead and #vDistHead > 0 then + -- verifico che il foro sia di testa + if ( bOpen or ( not bOpen and vtExtr:getX() > 0 and vProc[i].Fcs ~= 0) or ( not bOpen and vtExtr:getX() < 0 and vProc[i].Fce ~= 0)) then + vProc[i].MachineAfterHeadCutId = vMachineBeforeIntersectingDrillings.Head.Id + vProc[i].Head = true + end + -- se esiste intersezione tra il foro e la feature di coda + elseif vDistTail and #vDistTail > 0 then + -- verifico che il foro sia di coda + if ( bOpen or ( not bOpen and vtExtr:getX() < 0 and vProc[i].Fcs ~= 0) or ( not bOpen and vtExtr:getX() > 0 and vProc[i].Fce ~= 0)) then + vProc[i].MachineAfterTailCutId = vMachineBeforeIntersectingDrillings.Tail.Id + vProc[i].Tail = true + end + end + end + end +end + ------------------------------------------------------------------------------------------------------------- function BeamExec.ProcessFeatures() + if BD.IMPROVE_HEAD_TAIL_DRILLINGS == nil then + BD.IMPROVE_HEAD_TAIL_DRILLINGS = true + end -- verifica se possibile rotazione di 90 gradi BD.ROT90 = BD.ROT90 and Verify90DegRotation( EgtGetFirstRawPart()) -- ciclo sui pezzi @@ -1312,7 +1402,11 @@ function BeamExec.ProcessFeatures() local dCurrOvmH = EgtGetInfo( nRawId, 'HOVM', 'd') or 0 local dCurrOvmT = EgtGetInfo( nRawId, 'TOVM', 'd') or 0 -- recupero le feature di lavorazione della trave - local vProc = CollectFeatures( nPartId, b3Raw, dCurrOvmH, dCurrOvmT) + local vProc, vMachineBeforeIntersectingDrillings = CollectFeatures( nPartId, b3Raw, dCurrOvmH, dCurrOvmT) + -- verifica presenza forature influenzate da lavorazioni di testa o coda + if BD.IMPROVE_HEAD_TAIL_DRILLINGS then + SetDrillingsToMachineAfterHeadOrTailCut( vProc, vMachineBeforeIntersectingDrillings) + end -- le ordino lungo X OrderFeatures( vProc, b3Raw) -- le classifico diff --git a/LuaLibs/ProcessDrill.lua b/LuaLibs/ProcessDrill.lua index e3921dc..e268770 100644 --- a/LuaLibs/ProcessDrill.lua +++ b/LuaLibs/ProcessDrill.lua @@ -8,6 +8,8 @@ -- 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. -- Tabella per definizione modulo local ProcessDrill = {} @@ -310,6 +312,8 @@ function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId) EgtOutLog( sErr) return false, sErr end + -- conservo il valore originale di MaxDepth per poter eventualmente bypassare i check successivi + local dMaxDepthOri = dMaxDepth -- verifico il massimo affondamento local dSubL1 = 0 local dSubL2 = 0 @@ -391,18 +395,62 @@ function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId) nSCC = MCH_SCC.NONE end EgtSetMachiningParam( MCH_MP.SCC, nSCC) - -- aggiusto l'affondamento + -- aggiusto affondamento e MaxElev + local dMaxElev = dDepth local sMyWarn if 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 - EgtOutLog( sMyWarn) + -- se c'è un taglio precedente di testa o coda posso impostare MaxElev per allungare il percorso + -- considero solo i fori "entranti" in testa o coda + if (( Proc.MachineAfterHeadCutId and vtExtr:getX() > 0) or ( Proc.MachineAfterTailCutId and vtExtr:getX() < 0)) then + local ptCen = EgtCP( AuxId, GDB_RT.GLOB) + local bIntersectionOk, _, vDistance = EgtLineSurfTmInters( ptCen, -vtExtr, Proc.MachineAfterHeadCutId or Proc.MachineAfterTailCutId, GDB_RT.GLOB) + dHoleToCutDistance = vDistance[1] + -- setto MaxElev + -- il segno della distanza data dalla funzione di intersezione mi indica dove sia la geometria del foro + if bIntersectionOk then + -- se MaxDepth era stato settato a 0 per disattivare la lavorazione gli riassegno il valore originale + if dMaxDepth == 0 then + dMaxDepth = dMaxDepthOri + end + if dHoleToCutDistance > 0 then + dMaxElev = dLen - dHoleToCutDistance + elseif dHoleToCutDistance < 0 then + dMaxElev = -dHoleToCutDistance + end + 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 + -- se per qualche motivo fallisce l'intersezione torno al caso standard + else + sMyWarn = 'Warning in drill : depth (' .. EgtNumToString( dDepth, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + dDepth = dMaxDepth + dMaxElev = dMaxDepth + end + -- caso standard + else + sMyWarn = 'Warning in drill : depth (' .. EgtNumToString( dDepth, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + dDepth = dMaxDepth + dMaxElev = dMaxDepth + end + if sMyWarn then + EgtOutLog( sMyWarn) + end end EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) -- Note utente con dichiarazione nessuna generazione sfridi per Vmill local sUserNotes = 'VMRS=0;' -- aggiungo alle note massima elevazione (coincide con affondamento) - sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dDepth, 1) .. ';' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dMaxElev, 1) .. ';' -- se foro passante, aggiungo questa qualifica alle note if ( sType == 'Drill' or sType == 'Drill_H2') and bOpen then sUserNotes = sUserNotes .. 'Open=1;'