From 7d65813c323352fff8306dc8e5a2af83d0fcf84f Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Tue, 2 Jan 2024 16:07:40 +0100 Subject: [PATCH] =?UTF-8?q?DataBeam=202.5l4=20:=20-=20modifiche=20per=20ce?= =?UTF-8?q?ntrare=20i=20pezzi=20in=20Y=20sulla=20tavola=20(da=20flag=20Bea?= =?UTF-8?q?mData.CENTER=5FBEAM)=20-=20modifiche=20per=20rendere=20pi=C3=B9?= =?UTF-8?q?=20veloci=20i=20calcoli=20di=20FeatureTopology=20-=20scorporata?= =?UTF-8?q?=20CalcHeadTailMachBeforeIntersDrillings=20da=20CollectFeatures?= =?UTF-8?q?=20-=20migliorato=20calcolo=20attacco/uscite=20lame=20in=20Face?= =?UTF-8?q?sBySaw.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LuaLibs/BeamExec.lua | 96 +++++++++--- LuaLibs/FacesBySaw.lua | 279 ++++++++++----------------------- LuaLibs/FeatureTopology.lua | 110 +++++++------ LuaLibs/ProcessFreeContour.lua | 1 + LuaLibs/ProcessLapJoint.lua | 4 +- Version.lua | 6 +- 6 files changed, 222 insertions(+), 274 deletions(-) diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index f8702f1..ee06769 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -1,4 +1,4 @@ --- BeamExec.lua by Egaltech s.r.l. 2023/11/08 +-- BeamExec.lua by Egaltech s.r.l. 2023/12/26 -- Libreria esecuzione lavorazioni per Travi -- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3. -- 2019/09/04 Corretto controllo feature di testa e coda con sovramateriale di testa elevato. @@ -52,6 +52,7 @@ -- 2023/10/24 Aggiunta scrittura parametro BARLEN nelle info del mach group -- 2023/11/08 Aggiunta gestione processi Variant. -- 2023/11/30 Migliorato il calcolo elevazione con l'utilizzo della nuova funzione EgtSurfTmFacetElevationInBBox. +-- 2023/12/26 Modifiche per centrare i pezzi in Y sulla tavola. -- Tabella per definizione modulo local BeamExec = {} @@ -256,6 +257,40 @@ local function IsTailFeature( Proc, b3Raw, dCurrOvmH, dCurrOvmT) return false end +------------------------------------------------------------------------------------------------------------- +local function NeedTopologyFeature( Proc) + -- richiedono calcolo topologia + if Cut.Identify( Proc) then + return true + end + if DoubleCut.Identify( Proc) then + return true + end + if LongCut.Identify( Proc) then + return true + end + if Long2Cut.Identify( Proc) then + return true + end + if SawCut.Identify( Proc) then + return true + end + if RidgeLap.Identify( Proc) then + return true + end + if LapJoint.Identify( Proc) then + return true + end + if FrenchRidgeLap.Identify( Proc) then + return true + end + if Chamfer.Identify( Proc) then + return true + end + -- tutte le altre non richiedono calcolo topologia + return false +end + ------------------------------------------------------------------------------------------------------------- local function CollectFeatures( PartId, b3Raw, dCurrOvmH, dCurrOvmT) local dRawW = b3Raw:getDimY() @@ -265,8 +300,6 @@ local function CollectFeatures( PartId, b3Raw, dCurrOvmH, dCurrOvmT) 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 @@ -317,19 +350,9 @@ local function CollectFeatures( PartId, b3Raw, dCurrOvmH, dCurrOvmT) end end if Proc.Box and not Proc.Box:isEmpty() then + Proc.NeedTopology = NeedTopologyFeature( Proc) Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH) Proc.Tail, Proc.AdvTail = IsTailFeature( Proc, b3Raw, dCurrOvmH, dCurrOvmT) - if Proc.Fct == 1 and BL.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 @@ -383,11 +406,38 @@ local function CollectFeatures( PartId, b3Raw, dCurrOvmH, dCurrOvmT) ProcId = EgtGetNext( ProcId) end end - local vMachineBeforeIntersectingDrillings = { - Head = { Id = nMachineBeforeIntersectingDrillingsIdHead, Box = b3MachineBeforeIntersectingDrillingsBoxHead}, - Tail = { Id = nMachineBeforeIntersectingDrillingsIdTail, Box = b3MachineBeforeIntersectingDrillingsBoxTail} + return vProc +end + +------------------------------------------------------------------------------------------------------------- +local function CalcHeadTailMachBeforeIntersDrillings( vProc, b3Raw) + local nHeadId + local dHeadX = GEO.INFINITO + local nTailId + local dTailX = -GEO.INFINITO + local b3HeadBox + local b3TailBox + for i = 1, #vProc do + local Proc = vProc[i] + if Proc.Box and not Proc.Box:isEmpty() then + if Proc.Fct == 1 and BL.IsFeatureCuttingEntireSection( Proc.Box, b3Raw:getDimY(), b3Raw:getDimZ()) and ( Proc.Head or Proc.Tail) and Proc.Prc ~= 340 and Proc.Prc ~= 350 then + if Proc.Head and Proc.Box:getCenter():getX() < dHeadX then + dHeadX = Proc.Box:getCenter():getX() + nHeadId = Proc.Id + b3HeadBox = Proc.Box + elseif Proc.Tail and Proc.Box:getCenter():getX() > dTailX then + dTailX = Proc.Box:getCenter():getX() + nTailId = Proc.Id + b3TailBox = Proc.Box + end + end + end + end + local vMachBeforeIntersDrillings = { + Head = { Id = nHeadId, Box = b3HeadBox}, + Tail = { Id = nTailId, Box = b3TailBox} } - return vProc, vMachineBeforeIntersectingDrillings + return vMachBeforeIntersDrillings end ------------------------------------------------------------------------------------------------------------- @@ -501,7 +551,8 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam, bMachGroup -- Area tavola local b3Tab = EgtGetTableArea() -- Calcolo posizione estremo TR/BR della tavola rispetto a sua origine in BL - BD.OriXR = Point3d( b3Tab:getDimX(), EgtIf( BD.RIGHT_LOAD, 0, b3Tab:getDimY()), 0) + local dPosY = EgtIf( BD.CENTER_BEAM, ( b3Tab:getDimY() + dRawW * EgtIf( BD.RIGHT_LOAD, -1, 1)) / 2, EgtIf( BD.RIGHT_LOAD, 0, b3Tab:getDimY())) + BD.OriXR = Point3d( b3Tab:getDimX(), dPosY, 0) BD.PosXR = EgtIf( BD.RIGHT_LOAD, MCH_CR.BR, MCH_CR.TR) -- Impostazione dell'attrezzaggio di default @@ -1179,7 +1230,7 @@ local function ClassifyTopology( vProc, nRawId) nRecognized = nRecognized + 1 end end - + return nRecognized end @@ -1857,10 +1908,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, vMachineBeforeIntersectingDrillings = CollectFeatures( nPartId, b3Raw, dCurrOvmH, dCurrOvmT) + local vProc = 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) + vMachBeforeIntersDrillings = CalcHeadTailMachBeforeIntersDrillings( vProc, b3Raw) + SetDrillingsToMachineAfterHeadOrTailCut( vProc, vMachBeforeIntersDrillings) end -- verifica presenza di feature specchiate per eventuali lavorazioni simultanee if BD.TWO_EQUAL_HEADS or BD.DOWN_HEAD then diff --git a/LuaLibs/FacesBySaw.lua b/LuaLibs/FacesBySaw.lua index 5894bf8..10f0e26 100644 --- a/LuaLibs/FacesBySaw.lua +++ b/LuaLibs/FacesBySaw.lua @@ -1,4 +1,4 @@ --- FacesBySaw.lua by Egaltech s.r.l. 2023/11/28 +-- FacesBySaw.lua by Egaltech s.r.l. 2023/12/30 -- Gestione taglio con lama di feature con una o due facce -- 2021/01/06 Cambiato limite per attacco Tg con lama e CalcLeadInOutGeom rinominata in CalcLeadInOutPerpGeom. -- 2021/02/03 In taglio lama si accettano anche due lati con deviazione minore di 20deg. @@ -22,6 +22,7 @@ -- 2023/11/14 In MakeOne migliorato calcolo scelta soluzione per macchina TURN -- 2023/11/28 In MakeTwo raffinamento calcolo vtRef per casi dubbi. -- 2023/12/06 In CalcLeadInOutPerpGeom gestito caso in cui la geometria della feature esce dal grezzo. +-- 2023/12/30 Modifiche in CalcLeadInOutPerpGeom e CalcLeadInOutTangGeom con uso di EgtCAvToolPosBox. -- Tabella per definizione modulo local FacesBySaw = {} @@ -39,6 +40,7 @@ local ML = require( 'MachiningLib') --------------------------------------------------------------------- function MakeParallelOne( nSurfId, nFacet, sCutting, dSawDiam, nFaceUse, dVzLimDwnUp, dCutExtra, dCutSic, dCutOffset, dAccStart, dAccEnd, sNotes, b3Raw, bForceInvert) + EgtOutLog( 'FacesBySaw.MakeParallelOne', 3) -- dati della faccia local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) -- accetto solo facce perpendicolari all'asse X della trave @@ -181,6 +183,7 @@ function FacesBySaw.MakeOne( nSurfId, nFacet, sCutting, dSawDiam, Par5, dVzLimDw return MakeParallelOne( nSurfId, nFacet, sCutting, dSawDiam, Par5, dVzLimDwnUp, dCutExtra, dCutSic, dCutOffset, dAccStart, dAccEnd, sNotes, b3Raw, bForceInvert) end -- la lama ha asse perpendicolare alla faccia + EgtOutLog( 'FacesBySaw.MakeOne', 3) -- dati della faccia local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) -- risolvo parametro ambiguo @@ -193,7 +196,7 @@ function FacesBySaw.MakeOne( nSurfId, nFacet, sCutting, dSawDiam, Par5, dVzLimDw nOrthoOpposite = Par5 vtOrthO = BL.GetVersRef( Par5) end - EgtOutLog( 'VtOrthO='..tostring( vtOrthO)..' FaceUse='..tostring( nOrthoOpposite), 1) + EgtOutLog( 'VtOrthO='..tostring( vtOrthO)..' FaceUse='..tostring( nOrthoOpposite), 3) -- verifico se testa da sotto oppure se lavorazione sotto con testa da sopra if not dVzLimDwnUp then dVzLimDwnUp = BL.GetNzLimDownUp( b3Raw, vtN, vtOrthO) end local bDownHead = ( dVzLimDwnUp and dVzLimDwnUp < - 1.5) @@ -233,7 +236,7 @@ function FacesBySaw.MakeOne( nSurfId, nFacet, sCutting, dSawDiam, Par5, dVzLimDw local dAllStart = 0 local dAllEnd = 0 local bIsBiLinea = false - local bCosAngleL1L2 = 0 + local dCosAngleL1L2 = 0 local dDist1 = dist( ptP1, ptPm) local dDist2 = dist( ptP2, ptPm) -- verifico se la bilinea si trova sul bordo del solido, quindi è una geometria aperta @@ -252,10 +255,8 @@ function FacesBySaw.MakeOne( nSurfId, nFacet, sCutting, dSawDiam, Par5, dVzLimDw local dCosMax = 0.951 -- cos( 18°) local dLenMin = 30 local dLenMax = max( 0.5 * dSawDiam * 0.17365 + 1, 2 * dLenMin) - --if vtTg1 * vtTg2 < dCosMax or ( dDist1 < dLenMax and dDist1 > dLenMin) or ( dDist2 < dLenMax and dDist2 > dLenMin) then - - bCosAngleL1L2 = vtTg1 * vtTg2 - if bCosAngleL1L2 < dCosMax then + dCosAngleL1L2 = vtTg1 * vtTg2 + if dCosAngleL1L2 < dCosMax then local dOrtho1 = abs( vtTg1 * vtOrthO) local dOrtho2 = abs( vtTg2 * vtOrthO) if dOrtho1 < dOrtho2 or ( abs( dOrtho1 - dOrtho2) < 0.1 and dDist1 > 4 * dDist2) then @@ -302,43 +303,46 @@ function FacesBySaw.MakeOne( nSurfId, nFacet, sCutting, dSawDiam, Par5, dVzLimDw -- parametri di attacco/uscita local b3Box = BBox3d( b3Raw) b3Box:expand( dCutSic) + local ptPa1 = ptP1 + dAccStart * vtTg + local ptPa2 = ptP2 + dAccEnd * vtTg -- attacco perpendicolare - local dLiTang, dLiPerp, dLoTang, dLoPerp, vtLio = FacesBySaw.CalcLeadInOutPerpGeom( ptP1, ptP2, vtV1, vtV2, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) + local dLiTang, dLiPerp, dLoTang, dLoPerp, vtLio = FacesBySaw.CalcLeadInOutPerpGeom( ptPa1, ptPa2, vtV1, vtV2, vtN, dSawDiam / 2, vtRef, dCutExtra, b3Box) local dLenLi = sqrt( dLiTang * dLiTang + dLiPerp * dLiPerp) local dLenLo = sqrt( dLoTang * dLoTang + dLoPerp * dLoPerp) -- attacco tangente - local dLi2Tang, dLi2Perp, dLo2Tang, dLo2Perp = FacesBySaw.CalcLeadInOutTangGeom( ptP1, ptP2, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) + local dLi2Tang, dLi2Perp, dLo2Tang, dLo2Perp = FacesBySaw.CalcLeadInOutTangGeom( ptPa1, ptPa2, vtN, dSawDiam / 2, vtRef, dCutExtra, b3Box) local dLenLi2 = abs( dLi2Tang) local dLenLo2 = abs( dLo2Tang) -- se il lato non lavorato della bilinea è aperto, setto entrata/uscita con la stessa direzione if bIsBiLinea then -- angolo tra le due linee - local dAlpha = acos( abs( bCosAngleL1L2)) + local dCosAlpha = dCosAngleL1L2 + local dSinAlpha = sqrt( max( 1 - dCosAlpha * dCosAlpha, 0)) -- se ho accorciato ingresso, setto componente tangente e perpendicolare sul percorso di entrata if abs( dAllStart) > 100 * GEO.EPS_SMALL and bIsL1OnFace then -- controllo prima che il secondo lato non sia già incluso nella lavorazione del primo - local dDistPtTang = cos( dAlpha) * dDist1 - local dDistPtPerp = abs( sin( dAlpha) * dDist1) + local dDistPtTang = dCosAlpha * dDist1 + local dDistPtPerp = dSinAlpha * dDist1 local dDistToCenter = 0.5 * dSawDiam - dDistPtPerp local dDistPointToCenter = sqrt( dDistPtTang * dDistPtTang + dDistToCenter * dDistToCenter) -- se distanza al punto è maggiore del raggio lama, significa che non ho già lavorato, quindi calcolo entrata opportunamente if dDistPointToCenter > 0.5 * dSawDiam then - dLiTang = -dAllStart * cos( dAlpha) - dLiPerp = sin( dAlpha) * dDist1 + dLiTang = -dAllStart * dCosAlpha + dLiPerp = dDist1 * dSinAlpha end end -- se ho accorciato uscita, setto componente tangente e perpendicolare sul percorso di uscita if abs( dAllEnd) > 100 * GEO.EPS_SMALL and bIsL2OnFace then -- controllo prima che il secondo lato non sia già incluso nella lavorazione del primo - local dDistPtTang = cos( dAlpha) * dDist2 - local dDistPtPerp = abs( sin( dAlpha) * dDist2) + local dDistPtTang = dCosAlpha * dDist2 + local dDistPtPerp = dSinAlpha * dDist2 local dDistToCenter = 0.5 * dSawDiam - dDistPtPerp local dDistPointToCenter = sqrt( dDistPtTang * dDistPtTang + dDistToCenter * dDistToCenter) -- se distanza al punto è maggiore del raggio lama, significa che non ho già lavorato, quindi calcolo uscita opportunamente if dDistPointToCenter > 0.5 * dSawDiam then - dLoTang = -dAllEnd * cos( dAlpha) - dLoPerp = sin( dAlpha) * dDist2 + dLoTang = -dAllEnd * dCosAlpha + dLoPerp = dDist2 * dSinAlpha end end end @@ -357,7 +361,7 @@ function FacesBySaw.MakeOne( nSurfId, nFacet, sCutting, dSawDiam, Par5, dVzLimDw dLiTang, dLiPerp, dLoTang, dLoPerp = dLi2Tang, dLi2Perp, dLo2Tang, dLo2Perp if BD.TURN then local dMove = dist( ptP1, ptP2) - dLoTang = -( dLiTang + dAllStart - dAccStart + dAllEnd - dAccEnd + dMove) + dLoTang = -( dLiTang - dAccStart - dAccEnd + dMove) dLoPerp = BD.COLL_SIC end end @@ -441,6 +445,7 @@ end --------------------------------------------------------------------- function FacesBySaw.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, sCutType, bUpdateIng, bDownHead) + EgtOutLog( 'FacesBySaw.MakeTwo', 3) -- bUpdateIng : parametro opzionale con default true if bUpdateIng == nil then bUpdateIng = true end -- recupero l'ingombro del grezzo di appartenenza @@ -552,7 +557,6 @@ function FacesBySaw.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, sCutType, local vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[nUpInd], vtN[nUpInd], false, ptC[nOtInd], vtN[nOtInd]) --DC.PrintOrderCut( vCuts) if #vCuts > 0 then - EgtOutLog( 'FacesBySaw.MakeTwo', 4) -- sistemo posizione nel DB, nome e info for i = 1, #vCuts do for j = 1, #vCuts[i] do @@ -694,131 +698,49 @@ function FacesBySaw.CalcLeadInOutPerpGeom( ptP1, ptP2, vtV1, vtV2, vtN, dRad, vt -- Sistema di riferimento intrinseco al taglio local vtX = vtTg ^ vtN local frFace = Frame3d( ptP1, vtX, vtTg, vtN) - EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) + local bRight = ( vtX * vtRef > 0) + EgtOutLog( 'LioPerp --> Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) + -- Versore di attacco e uscita local dCos1 = vtV1 * vtRef local dCos2 = vtV2 * vtRef local vtLio if abs( dCos1 - dCos2) < 0.001 then - if abs( vtV1:getZ()) < abs( vtV2:getZ()) then - vtLio = vtV1 - else - vtLio = vtV2 - end + vtLio = EgtIf( abs( vtV1:getZ()) < abs( vtV2:getZ()), vtV1, vtV2) elseif dCos1 > dCos2 then vtLio = vtV1 else vtLio = vtV2 end - local bRight = ( vtX * vtLio > 0) -- Versore di attacco e uscita nel riferimento intrinseco al taglio local vtLioL = Vector3d( vtLio) ; vtLioL:toLoc( frFace) - -- Spostamento punti per effetto dell'extra o della deficienza di taglio - ptP1 = ptP1 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) - ptP2 = ptP2 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) - -- Spostamento punti se fuori dal pezzo: si riportano sul bordo del grezzo - local dDeltaMovePt1, dDeltaMovePt2 = 0, 0 - local dPt1X, dPt1Y, dPt1Z = ptP1:getX(), ptP1:getY(), ptP1:getZ() - local dPt2X, dPt2Y, dPt2Z = ptP2:getX(), ptP2:getY(), ptP2:getZ() - local dBoxMinX, dBoxMinY, dBoxMinZ = b3Box:getMin():getX(), b3Box:getMin():getY(), b3Box:getMin():getZ() - local dBoxMaxX, dBoxMaxY, dBoxMaxZ = b3Box:getMax():getX(), b3Box:getMax():getY(), b3Box:getMax():getZ() - if dPt1X < dBoxMinX then - dDeltaMovePt1 = dBoxMinX - dPt1X - elseif dPt1X > dBoxMaxX then - dDeltaMovePt1 = dBoxMaxX - dPt1X - elseif dPt1Y < dBoxMinY then - dDeltaMovePt1 = dBoxMinY - dPt1Y - elseif dPt1Y > dBoxMaxY then - dDeltaMovePt1 = dBoxMaxY - dPt1Y - elseif dPt1Z < dBoxMinZ then - dDeltaMovePt1 = dBoxMinZ - dPt1Z - elseif dPt1Z > dBoxMaxZ then - dDeltaMovePt1 = dBoxMaxZ - dPt1Z - end - if dPt2X < dBoxMinX then - dDeltaMovePt2 = dPt2X - dBoxMinX - elseif dPt2X > dBoxMaxX then - dDeltaMovePt2 = dPt2X - dBoxMaxX - elseif dPt2Y < dBoxMinY then - dDeltaMovePt2 = dPt2Y - dBoxMinY - elseif dPt2Y > dBoxMaxY then - dDeltaMovePt2 = dPt2Y - dBoxMaxY - elseif dPt2Z < dBoxMinZ then - dDeltaMovePt2 = dPt2Z - dBoxMinZ - elseif dPt2Z > dBoxMaxZ then - dDeltaMovePt2 = dPt2Z - dBoxMaxZ - end - ptP1 = ptP1 + vtTg * dDeltaMovePt1 - ptP2 = ptP2 + vtTg * dDeltaMovePt2 - -- Non va considerata l'uscita dalla faccia sotto, pertanto va abbassata - -- 2021/02/26 Abilito anche uscita sotto - local b3MyBox = BBox3d( b3Box) ; --b3MyBox:Add( b3MyBox:getMin() - 1000 * Z_AX()) - -- Attacco - local dLiTang = 10000 - local dLiPerp = 10000 - local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtLio, b3MyBox) - if bLiOk and #vLiPar > 0 then - -- con la prima faccia di uscita - local dLen = vLiPar[#vLiPar] - local ptInt = ptP1 + vtLio * dLen - local vtFN = BL.GetBoxFaceNorm( b3MyBox, ptInt, vtLio) - EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) - local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLio * vtFN) - local dLiLen = dLen + dAddLen - EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) - dLiTang = - dLiLen * vtLioL:getY() - dLiPerp = EgtIf( bRight, dLiLen, - dLiLen) * vtLioL:getX() - -- verifico se miglioro calcolando con faccia successiva - local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) - local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtLio, b3Mod) - if bLiOk2 and #vLiPar2 > 0 then - local dLen2 = vLiPar2[#vLiPar2] - local vtFN2 = BL.GetBoxFaceNorm( b3Mod, ptP1 + vtLio * dLen2, vtLio) - EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) - local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLio * vtFN2) - local dLiLen2 = dLen2 + dAddLen2 - EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) - local dLiTang2 = - dLiLen2 * vtLioL:getY() - local dLiPerp2 = EgtIf( bRight, dLiLen2, - dLiLen2) * vtLioL:getX() - if dLiLen2 < dLiLen then - dLiTang = dLiTang2 - dLiPerp = dLiPerp2 - end - end - end - -- Lunghezza di uscita - local dLoTang = 10000 - local dLoPerp = 10000 - local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtLio, b3MyBox) - if bLoOk and #vLoPar > 0 then - -- con la prima faccia di uscita - local dLen = vLoPar[#vLoPar] - local ptInt = ptP2 + vtLio * dLen - local vtFN = BL.GetBoxFaceNorm( b3MyBox, ptInt, vtLio) - EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) - local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLio * vtFN) - local dLoLen = dLen + dAddLen - EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) - dLoTang = dLoLen * vtLioL:getY() - dLoPerp = EgtIf( bRight, dLoLen, - dLoLen) * vtLioL:getX() - -- verifico se miglioro calcolando con faccia successiva - local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) - local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtLio, b3Mod) - if bLoOk2 and #vLoPar2 > 0 then - local dLen2 = vLoPar2[#vLoPar2] - local vtFN2 = BL.GetBoxFaceNorm( b3Mod, ptP2 + vtLio * dLen2, vtLio) - EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) - local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLio * vtFN2) - local dLoLen2 = dLen2 + dAddLen2 - EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) - local dLoTang2 = dLoLen2 * vtLioL:getY() - local dLoPerp2 = EgtIf( bRight, dLoLen2, - dLoLen2) * vtLioL:getX() - if dLoLen2 < dLoLen then - dLoTang = dLoTang2 - dLoPerp = dLoPerp2 - end - end - end + + -- Centro lama a inizio fine percorso + local dOffs = ( -dCutExtra + dRad) * EgtIf( bRight, 1, -1) + local ptCen1 = ptP1 + dOffs * vtX + local ptCen2 = ptP2 + dOffs * vtX + + -- Box del pezzo espansi ortogonalmente alle tre direzioni canoniche X, Y e Z + local b3BoxX = BBox3d( b3Box) ; b3BoxX:expand( 0, 1000, 1000) + local b3BoxY = BBox3d( b3Box) ; b3BoxY:expand( 1000, 0, 1000) + local b3BoxZ = BBox3d( b3Box) ; b3BoxZ:expand( 1000, 1000, 0) + + -- Calcolo elevazione dei due centri + local dSawThick = 6 + EgtCAvSetSawTool( dSawThick, 2 * dRad, dSawThick, 0, 0) + local dElev1 = min( EgtCAvToolPosBox( ptCen1 + dSawThick * vtN, vtN, b3BoxX, vtLio), + EgtCAvToolPosBox( ptCen1 + dSawThick * vtN, vtN, b3BoxY, vtLio), + EgtCAvToolPosBox( ptCen1 + dSawThick * vtN, vtN, b3BoxZ, vtLio)) + EgtOutLog( 'Elev1=' .. EgtNumToString( dElev1), 3) + local dLiTang = -dElev1 * vtLioL:getY() + local dLiPerp = EgtIf( bRight, dElev1, -dElev1) * vtLioL:getX() + local dElev2 = min( EgtCAvToolPosBox( ptCen2 + dSawThick * vtN, vtN, b3BoxX, vtLio), + EgtCAvToolPosBox( ptCen2 + dSawThick * vtN, vtN, b3BoxY, vtLio), + EgtCAvToolPosBox( ptCen2 + dSawThick * vtN, vtN, b3BoxZ, vtLio)) + EgtOutLog( 'Elev2=' .. EgtNumToString( dElev2), 3) + local dLoTang = dElev2 * vtLioL:getY() + local dLoPerp = EgtIf( bRight, dElev2, -dElev2) * vtLioL:getX() + return dLiTang, dLiPerp, dLoTang, dLoPerp, vtLio end @@ -830,72 +752,35 @@ function FacesBySaw.CalcLeadInOutTangGeom( ptP1, ptP2, vtN, dRad, vtRef, dCutExt -- Sistema di riferimento intrinseco al taglio local vtX = vtTg ^ vtN local frFace = Frame3d( ptP1, vtX, vtTg, vtN) - if ( vtX * vtRef < 0) then - vtX = - vtX - end - EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) - -- Spostamento punti per effetto dell'extra o della deficienza di taglio - ptP1 = ptP1 - vtX * dCutExtra - ptP2 = ptP2 - vtX * dCutExtra - -- Non va considerata l'uscita dalla faccia sotto, pertanto va abbassata - -- 2021/02/26 Abilito anche uscita sotto - local b3MyBox = BBox3d( b3Box) ; --b3MyBox:Add( b3MyBox:getMin() - 1000 * Z_AX()) - -- Attacco - local dLiTang = 10000 + local bRight = ( vtX * vtRef > 0) + EgtOutLog( 'LioTang --> Vref=' .. tostring( vtRef), 3) + + -- Centro lama a inizio fine percorso + local dOffs = ( -dCutExtra + dRad) * EgtIf( bRight, 1, -1) + local ptCen1 = ptP1 + dOffs * vtX + local ptCen2 = ptP2 + dOffs * vtX + + -- Box del pezzo espansi ortogonalmente alle tre direzioni canoniche X, Y e Z + local b3BoxX = BBox3d( b3Box) ; b3BoxX:expand( 0, 1000, 1000) + local b3BoxY = BBox3d( b3Box) ; b3BoxY:expand( 1000, 0, 1000) + local b3BoxZ = BBox3d( b3Box) ; b3BoxZ:expand( 1000, 1000, 0) + + -- Calcolo elevazione dei due centri + local dSawThick = 6 + EgtCAvSetSawTool( dSawThick, 2 * dRad, dSawThick, 0, 0) + local dElev1 = min( EgtCAvToolPosBox( ptCen1 + dSawThick * vtN, vtN, b3BoxX, -vtTg), + EgtCAvToolPosBox( ptCen1 + dSawThick * vtN, vtN, b3BoxY, -vtTg), + EgtCAvToolPosBox( ptCen1 + dSawThick * vtN, vtN, b3BoxZ, -vtTg)) + EgtOutLog( 'Elev1=' .. EgtNumToString( dElev1), 3) + local dLiTang = dElev1 local dLiPerp = 0 - local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtTg, b3MyBox) - if bLiOk and #vLiPar > 0 then - local dLen = vLiPar[1] - local ptInt = ptP1 + vtTg * dLen - local vtFN = BL.GetBoxFaceNorm( b3MyBox, ptInt, -vtTg) - EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) - local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN) - local dLiLen = dLen + dAddLen - EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) - dLiTang = - dLiLen - -- verifico se miglioro calcolando con faccia successiva - local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) - local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtTg, b3Mod) - if bLiOk2 and #vLiPar2 > 0 then - local dLen2 = vLiPar2[1] - local vtFN2 = BL.GetBoxFaceNorm( b3Mod, ptP1 + vtTg * dLen2, -vtTg) - EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) - local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2) - local dLiLen2 = dLen2 + dAddLen2 - EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) - if -dLiLen2 < -dLiLen then - dLiTang = - dLiLen2 - end - end - end - -- Lunghezza di uscita - local dLoTang = 10000 + local dElev2 = min( EgtCAvToolPosBox( ptCen2 + dSawThick * vtN, vtN, b3BoxX, vtTg), + EgtCAvToolPosBox( ptCen2 + dSawThick * vtN, vtN, b3BoxY, vtTg), + EgtCAvToolPosBox( ptCen2 + dSawThick * vtN, vtN, b3BoxZ, vtTg)) + EgtOutLog( 'Elev2=' .. EgtNumToString( dElev2), 3) + local dLoTang = dElev2 local dLoPerp = 0 - local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtTg, b3MyBox) - if bLoOk and #vLoPar > 0 then - local dLen = vLoPar[#vLoPar] - local ptInt = ptP2 + vtTg * dLen - local vtFN = BL.GetBoxFaceNorm( b3MyBox, ptInt, vtTg) - EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) - local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN) - local dLoLen = dLen + dAddLen - EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) - dLoTang = dLoLen - -- verifico se miglioro calcolando con faccia successiva - local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) - local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtTg, b3Mod) - if bLoOk2 and #vLoPar2 > 0 then - local dLen2 = vLoPar2[#vLoPar2] - local vtFN2 = BL.GetBoxFaceNorm( b3Mod, ptP2 + vtTg * dLen2, vtTg) - EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) - local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2) - local dLoLen2 = dLen2 + dAddLen2 - EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) - if dLoLen2 < dLoLen then - dLoTang = dLoLen2 - end - end - end + return dLiTang, dLiPerp, dLoTang, dLoPerp end diff --git a/LuaLibs/FeatureTopology.lua b/LuaLibs/FeatureTopology.lua index dbb464b..da56d5c 100644 --- a/LuaLibs/FeatureTopology.lua +++ b/LuaLibs/FeatureTopology.lua @@ -21,30 +21,33 @@ EgtOutLog( ' FeatureTopology started', 1) -- restituisce la matrice delle adiacenze di Proc dove i e j sono le facce e a(ij) è l'angolo tra di esse; 0 se nessuna adiacenza local function GetAdjacencyMatrix( Proc) local vAdj = {} + -- essendo la matrice simmetrica a diagonale nulla, ne calcolo solo la metà superiore for i = 1, Proc.Fct do vAdj[i] = {} - for j = 1, Proc.Fct do - if i == j then - vAdj[i][j] = 0 - else - _, _, _, vAdj[i][j] = EgtSurfTmFacetsContact( Proc.Id, i - 1, j - 1, GDB_ID.ROOT) - if not vAdj[i][j] then vAdj[i][j] = 0 end - end - j = j + 1 + for j = i + 1, Proc.Fct do + _, _, _, vAdj[i][j] = EgtSurfTmFacetsContact( Proc.Id, i - 1, j - 1, GDB_ID.ROOT) + if not vAdj[i][j] then vAdj[i][j] = 0 end + end + end + -- riempio di conseguenza il resto della matrice + for i = 1, Proc.Fct do + vAdj[i][i] = 0 + for j = i + 1, Proc.Fct do + vAdj[j][i] = vAdj[i][j] end - i = i + 1 end return vAdj end --------------------------------------------------------------------- -- restituisce gli id delle facce di Proc che hanno il numero di adiacenze nAdj -function FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, nAdj) - local vAdj = GetAdjacencyMatrix( Proc) +function FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, vAdj, nAdj) + if not vAdj then vAdj = GetAdjacencyMatrix( Proc) end + local nFct = #( vAdj or {}) local vFacesWithGivenAdj = {} - for i = 1, Proc.Fct do + for i = 1, nFct do local nAdjCount = 0 - for j = 1, Proc.Fct do + for j = 1, nFct do if vAdj[i][j] and vAdj[i][j] ~= 0 then nAdjCount = nAdjCount + 1 end @@ -58,11 +61,11 @@ end --------------------------------------------------------------------- -- restituisce true se Proc ha tutti gli angoli concavi (bAllConcave) e, nei casi in cui ha senso, se questi sono esattamente 90 deg (bAllRight) -local function AreAllAnglesConcaveOrRight( Proc) - local vAdj = GetAdjacencyMatrix( Proc) +local function AreAllAnglesConcaveOrRight( vAdj) local bAllConcave, bAllRight = true, true - for i = 1, Proc.Fct do - for j = 1, Proc.Fct do + local nFct = #( vAdj or {}) + for i = 1, nFct do + for j = 1, nFct do -- se trovo un angolo convesso restituisco falso e esco subito if vAdj[i][j] and vAdj[i][j] > 0 then bAllConcave = false @@ -74,7 +77,7 @@ local function AreAllAnglesConcaveOrRight( Proc) end end -- se 1 faccia oppure 2 facce con angolo convesso non ha senso ritornare valori per bAllRight - if Proc.Fct < 2 or ( Proc.Fct == 2 and vAdj[1][2] > 0) then + if nFct < 2 or ( nFct == 2 and vAdj[1][2] > 0) then return bAllConcave else return bAllConcave, bAllRight @@ -165,36 +168,42 @@ end -- riconosce se Proc è una delle topologie standard e, in caso positivo, ne scrive le caratteristiche in campi specifici della Proc stessa restituendo true function FeatureTopology.Classify( Proc, b3Raw) - if not Proc.AffectedFaces then Proc.AffectedFaces = BL.GetProcessAffectedFaces( Proc) end + -- la feature deve avere geometria if not Proc.Box or Proc.Box:isEmpty() then return false end - local bRecognized = false - local sFamily - local bIsThrough - local bAllRightAngles - local bIsParallel - local sLongName = '' + -- se non richiesto (default true, quindi nil vale true), esco + if Proc.NeedTopology == false then + Proc.Topology = 'SPECIAL' + Proc.TopologyLongName = Proc.Topology + return true + end - -- SE NON HA TUTTE LE FACCE PIANE RITORNARE NIL!! + -- se già calcolato, esco + if Proc.Topology then + return true + end - local bAllAnglesConcave - bAllAnglesConcave, bAllRightAngles = AreAllAnglesConcaveOrRight( Proc) + -- calcoli + if not Proc.AffectedFaces then Proc.AffectedFaces = BL.GetProcessAffectedFaces( Proc) end + + local vAdj = GetAdjacencyMatrix( Proc) + local bAllAnglesConcave, bAllRightAngles = AreAllAnglesConcaveOrRight( vAdj) local vTriangularFaces = GetTriangularFaces( Proc) local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc) - local vFacesWithOneAdj = FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, 1) - local vFacesWithTwoAdj = FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, 2) - local vFacesWithThreeAdj = FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, 3) - local vFacesWithFourAdj = FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, 4) - local dRawW, dRawH = b3Raw:getDimY(), b3Raw:getDimZ() + local vFacesWithOneAdj = FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, vAdj, 1) + local vFacesWithTwoAdj = FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, vAdj, 2) + local vFacesWithThreeAdj = FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, vAdj, 3) + local vFacesWithFourAdj = FeatureTopology.GetFacesWithGivenAdjacencyNumber( Proc, vAdj, 4) + local dRawW = b3Raw:getDimY() + local dRawH = b3Raw:getDimZ() local bIsFeatureCuttingEntireSection = BL.IsFeatureCuttingEntireSection( Proc.Box, dRawW, dRawH) - if Proc.IsOutline then - sFamily = 'OUTLINE' - elseif Proc.Prc == 40 then - sFamily = 'DRILLING' - elseif Proc.Fct == 1 and bIsAnyDimensionLongAsPart and bIsFeatureCuttingEntireSection then + -- assegnazione tipologia + local sFamily + local bIsThrough + if Proc.Fct == 1 and bIsAnyDimensionLongAsPart and bIsFeatureCuttingEntireSection then sFamily = 'Cut' elseif Proc.Fct == 1 and bIsAnyDimensionLongAsPart then sFamily = 'Bevel' @@ -233,23 +242,24 @@ function FeatureTopology.Classify( Proc, b3Raw) sFamily = 'Pocket' bIsThrough = false end - local vFacesParallelToPart = GetFacesParallelToPart( Proc, sFamily, bIsThrough) - bIsParallel = ( #vFacesParallelToPart == Proc.Fct) - if sFamily == 'OUTLINE' or sFamily == 'DRILLING' then + -- verifico se facce parallele a quelle della trave + local vFacesParallelToPart = GetFacesParallelToPart( Proc, sFamily, bIsThrough) + local bIsParallel = ( #vFacesParallelToPart == Proc.Fct) + + -- assegnazioni + if sFamily then Proc.Topology = sFamily - Proc.TopologyLongName = sFamily - bRecognized = true - elseif sFamily then - sLongName = GetTopologyLongName( sFamily, bIsThrough, bAllRightAngles, bIsParallel, Proc.Fct) - Proc.Topology, Proc.IsThrough, Proc.AllRightAngles, Proc.IsParallel, Proc.TopologyLongName = sFamily, bIsThrough, bAllRightAngles, bIsParallel, sLongName - bRecognized = true + Proc.TopologyLongName = GetTopologyLongName( sFamily, bIsThrough, bAllRightAngles, bIsParallel, Proc.Fct) + Proc.IsThrough = bIsThrough + Proc.AllRightAngles = bAllRightAngles + Proc.IsParallel = bIsParallel + return true else Proc.Topology = 'OTHER' - Proc.TopologyLongName = 'OTHER' + Proc.TopologyLongName = Proc.Topology + return false end - - return bRecognized end ------------------------------------------------------------------------------------------------------------- diff --git a/LuaLibs/ProcessFreeContour.lua b/LuaLibs/ProcessFreeContour.lua index aa65038..ba41e6d 100644 --- a/LuaLibs/ProcessFreeContour.lua +++ b/LuaLibs/ProcessFreeContour.lua @@ -35,6 +35,7 @@ local Q_RADIAL_OFFSET = 'Q06' -- d, valido solo per pocket function ProcessFreeContour.Identify( Proc) return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 250) end + --------------------------------------------------------------------- -- Verifica se feature di testa function ProcessFreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) diff --git a/LuaLibs/ProcessLapJoint.lua b/LuaLibs/ProcessLapJoint.lua index 19411d9..c5563b7 100644 --- a/LuaLibs/ProcessLapJoint.lua +++ b/LuaLibs/ProcessLapJoint.lua @@ -775,7 +775,7 @@ function ProcessLapJoint.Classify( Proc, b3Raw) end -- se scanalatura chiusa lavoro la faccia di fondo if Proc.Topology == 'Pocket' and ( Proc.IsParallel or Proc.AllRightAngles) and not bClosedOrthoFaces then - nFacInd = Topology.GetFacesWithGivenAdjacencyNumber( Proc, 4)[1] + nFacInd = Topology.GetFacesWithGivenAdjacencyNumber( Proc, nil, 4)[1] nFacInd2 = nil dElev = Proc.Face[ nFacInd + 1].Elevation end @@ -4507,7 +4507,7 @@ local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, bSinglePa end -- se scanalatura chiusa lavoro la faccia di fondo if Proc.Topology == 'Pocket' and ( Proc.IsParallel or Proc.AllRightAngles) and not bClosedOrthoFaces then - nFacInd = Topology.GetFacesWithGivenAdjacencyNumber( Proc, 4)[1] + nFacInd = Topology.GetFacesWithGivenAdjacencyNumber( Proc, nil, 4)[1] nFacInd2 = nil dFacElev = Proc.Face[ nFacInd + 1].Elevation end diff --git a/Version.lua b/Version.lua index d6d4230..41ff71c 100644 --- a/Version.lua +++ b/Version.lua @@ -1,6 +1,6 @@ --- Version.lua by Egaltech s.r.l. 2023/12/15 +-- Version.lua by Egaltech s.r.l. 2023/12/30 -- Gestione della versione di Beam NAME = 'Beam' -VERSION = '2.5l2' -MIN_EXE = '2.5l1' +VERSION = '2.5l4' +MIN_EXE = '2.5l3'