From 06a73a069f1d4f3d6e83ee00159ba34e913cb438 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Mon, 24 Nov 2025 17:30:57 +0100 Subject: [PATCH 01/17] =?UTF-8?q?-=20aggiunta=20nuova=20modalit=C3=A0=20di?= =?UTF-8?q?=20pre=20calcolo=20collisioni,=20al=20momento=20lama=20e=20solo?= =?UTF-8?q?=20asse=20Z=20-=20aggiunta=20libreria=20TimeLib=20per=20calcola?= =?UTF-8?q?re=20i=20tempi=20di=20esecuzione=20(sostituite=20chiamate=20a?= =?UTF-8?q?=20EgtStartCounter=20e=20Stop)=20-=20rimosse=20chiamate=20a=20E?= =?UTF-8?q?gtOutLog=20deprecate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BatchProcessNew.lua | 13 ++- LuaLibs/BeamExec.lua | 35 +----- LuaLibs/FaceData.lua | 12 --- LuaLibs/MachiningLib.lua | 137 ++++++++++++++++++++++-- LuaLibs/TimeLib.lua | 70 ++++++++++++ NestProcess.lua | 2 - Process.lua | 13 ++- Strategies/Standard/STR0006/STR0006.lua | 3 +- StrategyLibs/BLADETOWASTE.lua | 2 + StrategyLibs/FACEBYBLADE.lua | 6 ++ 10 files changed, 238 insertions(+), 55 deletions(-) create mode 100644 LuaLibs/TimeLib.lua diff --git a/BatchProcessNew.lua b/BatchProcessNew.lua index 916d580..fc6df01 100644 --- a/BatchProcessNew.lua +++ b/BatchProcessNew.lua @@ -63,6 +63,8 @@ _G.package.loaded['HEADCUT\\HEADCUT'] = nil _G.package.loaded['TAILCUT\\TAILCUT'] = nil -- libreria macchina _G.package.loaded.BeamData = nil +-- libreria calcolo tempo esecuzione +_G.package.loaded.TimeLib = nil -- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente -- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento. @@ -178,6 +180,15 @@ local function WriteResultToJson( RESULT) end ------------------------------------------------------------------------------------------------------------- + +-- calcolo tempo esecuzione +if EgtGetDebugLevel() >= 3 then + TIMER:start() + EgtOutLog( ' Execution timer started') +end + +-- script principale + local sFlag = '' if BEAM.FLAG == 0 then sFlag = 'GENERATE' @@ -650,7 +661,7 @@ if bToProcess then -- si cancella gruppo temporaneo contenente entità da cancellare local idTempGroup = BeamLib.GetTempGroup() - EgtErase( idTempGroup) + --EgtErase( idTempGroup) local sOutput = '' diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index bd24d0a..a78a556 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -19,6 +19,7 @@ local FeatureLib = require( 'FeatureLib') local FaceData = require( 'FaceData') local MachiningLib = require( 'MachiningLib') local Logs = require( 'Logs') +local TimeLib = require( 'TimeLib') EgtOutLog( ' BeamExec started', 1) @@ -28,6 +29,7 @@ EgtMdbSave() ------------------------------------------------------------------------------------------------------------- -- *** variabili globali *** ------------------------------------------------------------------------------------------------------------- +-- TODO spostare in file separato TOOLS = {} -- tabella contenente tutti gli utensili STRATEGIES = {} -- tabella contenente le strategie disponibili per ogni feature STRATEGIES_CONFIG = {} -- tabella contenente i parametri di default delle strategie disponibili @@ -37,6 +39,7 @@ PROCESSINGS = {} -- tabella contenente tutte le informazioni di ogni feat RESULT = {} -- tabella contenente il risultato, feature per feature, dell'applicazione della strategia scelta e il resoconto dell'analisi fatta GENERAL_PARAMETERS = {} -- tabella contenente i parametri generali già letti e importati GENERAL_PARAMETERS_JSON = {} -- tabella contenente i parametri generali di default +TIMER = TimeLib.new() -- tabella contenente l'oggetto timer che tiene traccia del tempo di esecuzione ------------------------------------------------------------------------------------------------------------- -- *** COSTANTI *** TODO -> DA SPOSTARE IN BEAMDATA??? @@ -115,6 +118,7 @@ function BeamExec.GetToolsFromDB() Tool.dMaxMaterial = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) Tool.dDiameter = EgtTdbGetCurrToolParam( MCH_TP.DIAM) Tool.dLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) + Tool.dTotalLength = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) Tool.dSpeed = EgtTdbGetCurrToolParam( MCH_TP.SPEED) Tool.bIsCCW = Tool.dSpeed < 0 Tool.Feeds = {} @@ -1195,10 +1199,6 @@ end ------------------------------------------------------------------------------------------------------------- function BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition) -- recupero tutti i processing di tutti i pezzi in tutte le rotazioni - -- TODO calcolo tempi da rimuovere o lasciare solo per debug - -- if EgtGetDebugLevel() >= 3 then - -- EgtStartCounter() - -- end -- si aprono i limiti tavola per permettere rotazioni di pezzi più larghi della tavola EgtSetTableAreaOffset( 2000, 2000, 2000, 2000) @@ -1246,13 +1246,7 @@ function BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition) -- recupero le feature di lavorazione della trave table.insert( PROCESSINGS, Part) end - -- TODO calcolo tempi da rimuovere o lasciare solo per debug - -- if EgtGetDebugLevel() >= 3 then - -- local timeGetProcessings = EgtStopCounter() - -- timeGetProcessings = timeGetProcessings + 0 - -- EgtOutBox( timeGetProcessings, 'GetProcessings calculation time') - -- EgtStartCounter() - -- end + return PROCESSINGS end @@ -1567,25 +1561,6 @@ function BeamExec.ProcessMachinings( PARTS) local Stats = {} local nOrd = 1 --- TODO da rimuovere o lasciare solo per debug ---if EgtGetDebugLevel() >= 3 then --- EgtStartCounter() ---end --- TODO da rimuovere o lasciare solo per debug ---if EgtGetDebugLevel() >= 3 then --- local timeCollect = EgtStopCounter() --- timeCollect = timeCollect + 0 --- EgtOutBox( timeCollect, 'Collect calculation time') --- EgtStartCounter() ---end --- TODO da rimuovere o lasciare solo per debug ---if EgtGetDebugLevel() >= 3 then --- local timeMachining = EgtStopCounter() --- timeMachining = timeMachining + 0 --- EgtOutBox( timeMachining, 'Machining calculation time') ---end - - -- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni for nPart = 1, #PARTS do diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index 3013d82..18bf947 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -149,7 +149,6 @@ end ------------------------------------------------------------------------------------------------------------- function FaceData.GetFacesInfo( Proc, Part, FacesToGet) - EgtOutLog( '---Faces START---') local Faces = {} local function FaceIsToGet( nIndex) @@ -194,26 +193,18 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet) Faces[i].bIsOkForMachining = nFaceType < 1 Faces[i].Edges = Edges - -- TODO valutare se fare un output unico alla fine o gestire log in altro modo - EgtOutLog( 'Facet ' .. Faces[i].id .. ' of ' .. Proc.nFct - 1) - EgtOutLog( ' vtN: ' .. tostring( Faces[i].vtN)) - -- adiacenze della faccia -- TODO chiamarle in modo che si capisca che sono solo gli id e non l'intero oggetto faccia Faces[i].Adjacencies = {} for j = 1, Proc.nFct do if vAdj[i][j] and vAdj[i][j] ~= 0 and ( i ~= j) then table.insert( Faces[i].Adjacencies, j - 1) - if EgtGetDebugLevel() >= 3 then - EgtOutLog( ' Adjacent to facet: ' .. j - 1) - end end end end end - EgtOutLog( '---Faces END---') return Faces end @@ -656,7 +647,6 @@ end -- TODO test iniziale replicato in GetTunnelFaces function FaceData.GetMainFaces( Proc, Part) - EgtOutLog( '---MainFaces START---') local MainFaces = {} -- CASO 1 : Feature tipo LapJoint @@ -676,10 +666,8 @@ function FaceData.GetMainFaces( Proc, Part) else MainFaces = nil - EgtOutLog( '---MainFaces NOT NEEDED---') end - EgtOutLog( '---MainFaces END---') return MainFaces end diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 0752e39..afdbd35 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -269,7 +269,7 @@ end ------------------------------------------------------------------------------------------------------------- -- in base a tipo testa e angolo soglia, verifica se la faccia è troppo inclinata per la lavorazione scelta (per DownUp passare vtNFace opposta) -local function IsFaceZOutOfRange ( vtNFace, Tool) +local function IsFaceZOutOfRange( vtNFace, Tool) -- lama sopra: angolo negativo troppo basso if Tool.SetupInfo.HeadType.bTop and vtNFace:getZ() < Tool.SetupInfo.GetMinNz( vtNFace, Tool) - GEO.EPS_ZERO then @@ -284,12 +284,128 @@ local function IsFaceZOutOfRange ( vtNFace, Tool) end ------------------------------------------------------------------------------------------------------------- --- si controlla la collisione con il carro Z nei 2 piani globali X e Y (si considera infinitamente alto in Z). Se c'è collisione in entrambi i piani, il carro sarà in collisione. +-- +local function CheckCollisionAxisC( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) +end + +------------------------------------------------------------------------------------------------------------- +-- si controlla la collisione con il carro Z nei 3 piani globali X, Y e Z. Se c'è collisione in tutti i piani, il carro sarà in collisione. +local function CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) + + -- se faccia non parallela a direzione testa c'è qualcosa che non va + if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then + error( 'CheckCollisionAxisZ : invalid directions') + end + + -- TODO rimettere + -- se direzione utensile parallela ad uno degli assi principali non serve alcuna verifica + -- if AreSameOrOppositeVectorApprox( Edge.vtN, X_AX()) + -- or AreSameOrOppositeVectorApprox( Edge.vtN, Y_AX()) + -- or AreSameOrOppositeVectorApprox( Edge.vtN, Z_AX()) then + + -- return false + -- end + + local idTempGroup = BeamLib.GetTempGroup() + + -- punti notevoli della lavorazione in cui fare il check + -- TODO aggiungere anche ptMid? + local MachiningPoints = { + Point3d( Edge.ptStart) + Edge.vtN * ( Edge.dElevation - dDepthToMachine), + Point3d( Edge.ptEnd) + Edge.vtN * ( Edge.dElevation - dDepthToMachine) + } + + -- punti in centro lama su naso mandrino o aggregato. In base a direzione e punto + local bIsDownUp = AreOppositeVectorApprox( vtNFace, vtHead) + local ToolExitPoints = {} + for i = 1, #MachiningPoints do + ToolExitPoints[i] = Point3d( MachiningPoints[i] + Edge.vtN * Tool.dDiameter / 2) + vtHead * EgtIf( bIsDownUp, ( Tool.dLength - Tool.dThickness), Tool.dLength) + end + + -- direzioni in cui fare il check + -- TODO queste cambieranno in base all'asse da controllare + local CheckDirections = { + { vtDirectionX = X_AX(), vtDirectionY = Z_AX(), vtDirectionZ = -Y_AX(), sDirectionName = 'X'}, + { vtDirectionX = Y_AX(), vtDirectionY = Z_AX(), vtDirectionZ = X_AX(), sDirectionName = 'Y'}, + { vtDirectionX = X_AX(), vtDirectionY = Y_AX(), vtDirectionZ = Z_AX(), sDirectionName = 'Z'} + } + + -- TEST + local Color = Color3d( math.random(0, 255), math.random(0, 255), math.random(0, 255)) + -- TEST + + for i = 1, #CheckDirections do + + local vtDirectionX = CheckDirections[i].vtDirectionX + local vtDirectionZ = CheckDirections[i].vtDirectionZ + local sDirectionName = CheckDirections[i].sDirectionName + + -- costruzione flat region del pezzo nel piano scelto + -- si estrae prima la silhouette nel piano + local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( Part.idBoxTm, vtDirectionZ, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB) + -- se più curve c'è qualcosa che non va: errore + if nCurveCount > 1 then + error( 'CheckCollisionAxisZ : error in part box') + end + -- creazione flat region dalla silhouette + local idPartSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve) + + -- costruzione flat region del grezzo restante nel piano scelto (con leggera sovrapposizione) + -- si costruisce il box in globale + local ptRestLengthMax = Point3d( Part.b3Part:getMin()) + X_AX() * 500 * GEO.EPS_SMALL + local ptRestLengthMin = Point3d( Part.b3Part:getMin():getX() - 2000, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) + local b3RestLength = BBox3d( ptRestLengthMin, ptRestLengthMax) + -- si crea la trimesh dal box + local idRestLengthBoxTm = EgtSurfTmBBox( idTempGroup, b3RestLength , false, GDB_RT.GLOB) + -- si estrae la silhouette nel piano + idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( idRestLengthBoxTm, vtDirectionZ, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB) + -- se più curve c'è qualcosa che non va: errore + if nCurveCount > 1 then + error( 'CheckCollisionAxisZ : error in part box') + end + -- creazione flat region dalla silhouette + local idRestLengthSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve) + + -- costruzione flat region del carro Z nel piano scelto, tra punto iniziale e finale lavorazione + -- recupero punti da macchina per costruire flat region + local ZAxisPoints = Tool.SetupInfo.GetAxisZPoints( sDirectionName) + -- per ogni punto in cui controllare si crea una flat region (al momento solo 2, altrimenti la ruled) + local CollisionCurves = {} + for j = 1, #ToolExitPoints do + -- curva di collisione in riferimento locale + local idCollisionCurve = EgtCurveCompoFromPoints( idTempGroup, ZAxisPoints) + table.insert( CollisionCurves, idCollisionCurve) + + -- TEST + EgtSetColor( idCollisionCurve, Color) + -- TEST + + -- calcolo pivot in riferimento globale + local ptRef = ToolExitPoints[j] + local frTool = Frame3d( ptRef, vtHead, Edge.vtN) + -- TODO vtPivotGlob dovrà arrivare da funzione perchè può cambiare con SCC (es: aggregato) + local vtPivotGlob = Vector3d( Tool.SetupInfo.vtPivot) + vtPivotGlob:toGlob( frTool) + local ptPivot = ptRef + vtPivotGlob + EgtPoint( idTempGroup, ptPivot, 0) + + -- curva in riferimento globale + local frReference = Frame3d( ptPivot, vtDirectionZ, vtDirectionX) + EgtTransform( idCollisionCurve, frReference, GDB_RT.GLOB ) + end + -- TODO serve fare la ruled o basta controllare nei punti estremi? + --EgtSurfTmRuled( idTempGroup, CollisionCurves[1], CollisionCurves[2]) + end + + +end + ------------------------------------------------------------------------------------------------------------- -- nel piano perpendicolare alla direzione di taglio, se c'è intersezione tra motore e trave c'è collisione -local function Check2DBladeCollision( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) +-- TODO da integrare in funzione sopra +local function CheckCollisionAxisAB( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) -- se direzione utensile parallela ad uno degli assi principali non serve alcuna verifica if AreSameOrOppositeVectorApprox( Edge.vtN, X_AX()) @@ -316,7 +432,7 @@ local function Check2DBladeCollision( Edge, vtNFace, vtHead, Part, Tool, dDepthT -- creazione flat region dalla silhouette local idPartSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve) - -- costruzione flat region del grezzo restante nel piano perpendicolare al taglio + -- costruzione flat region del grezzo restante nel piano perpendicolare al taglio (con leggera sovrapposizione) -- si costruisce il box in globale local ptRestLengthMax = Point3d( Part.b3Part:getMin() + X_AX() * 500 * GEO.EPS_SMALL) local ptRestLengthMin = Point3d( Part.b3Part:getMin():getX() - 2000, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) @@ -381,7 +497,7 @@ end ------------------------------------------------------------------------------------------------------------- -- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) --- TODO si dovrà decidere come tagliare anche in base a lavorazione di coda (spostare dopo separazione?) o pezzo corto (il motore non deve ingombrare con il pinzaggio) +-- TODO si dovrà decidere come tagliare anche se pezzo corto (il motore non deve ingombrare con il pinzaggio) -- valutare se restituire, se disponibili, entrambe le soluzioni e demandare la decisione alla FaceByBlade function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachine, bCollisionCheckForDownUpOnly) local sBladeEngagement = 'Standard' @@ -389,8 +505,11 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin -- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci altre condizioni che fanno fallire il taglio if not IsFaceZOutOfRange( Face.vtN, Tool) then - -- TODO verifica collisione carro Z, collisione traversa PF, collisione 'C' Fast... La riduzione percorso cambia questo test? - local bCollisionFound, bMoveAfterSplit = Check2DBladeCollision( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + -- TODO La riduzione percorso cambia questo test? + -- TODO da completare questo test + local bCollisionFoundZ, bMoveAfterSplitZ = CheckCollisionAxisZ( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + + local bCollisionFound, bMoveAfterSplit = CheckCollisionAxisAB( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) if bCollisionCheckForDownUpOnly or not bCollisionFound then return true, sBladeEngagement, bMoveAfterSplit @@ -416,7 +535,7 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin end -- orientamento faccia / utensile compatibili con DownUp: lavorabile - local bCollisionFound, bMoveAfterSplit = Check2DBladeCollision( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) + local bCollisionFound, bMoveAfterSplit = CheckCollisionAxisAB( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) if not bCollisionFound then sBladeEngagement = 'DownUp' @@ -595,7 +714,9 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) if bIsToolCompatible then if FaceToMachine and EdgeToMachine and Part and dElevation then local bIsBladeOk = false + TIMER:setCheckpoint( 'GetBladeEngagement') bIsBladeOk, sCurrentBladeEngagement, bCurrentMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bCollisionCheckForDownUpOnly) + TIMER:logElapsed( 'GetBladeEngagement') -- orientamento non raggiungibile if not bIsBladeOk then bIsToolCompatible = false diff --git a/LuaLibs/TimeLib.lua b/LuaLibs/TimeLib.lua new file mode 100644 index 0000000..96f8f62 --- /dev/null +++ b/LuaLibs/TimeLib.lua @@ -0,0 +1,70 @@ +-- BeamLib.lua by Egalware s.r.l. 2025/11/24 +-- Libreria calcolo tempo automatismo + + +-- Tabella per definizione modulo +local TimeLib = {} + + +EgtOutLog( ' TimeLib started', 1) + + +TimeLib.__index = TimeLib + +function TimeLib.new() + local self = setmetatable({}, TimeLib) + self.dStartTime = os.clock() + self.Checkpoints = {} -- each checkpoint stores first and last timestamps + return self +end + +-- reset timer +function TimeLib:start() + self.dStartTime = os.clock() + self.Checkpoints = {} +end + +-- setta un checkpoint con nome (default se non specificato) +function TimeLib:setCheckpoint( sName) + local sCpName = sName or "default" + local dNow = os.clock() + + if not self.Checkpoints[sCpName] then + self.Checkpoints[sCpName] = { dFirst = dNow, dLast = dNow } + else + self.Checkpoints[sCpName].dLast = dNow + end +end + +-- ritorna il tempo trascorso +-- se settato un checkpoint, ritorna anche il tempo di quel checkpoint, cumulativo (dal primo checkpoint settato con quel nome) e recente (dall'ultimo checkpoint settato) +function TimeLib:elapsed( sCheckpointName) + local dTotal = os.clock() - self.dStartTime + local sCpName = sCheckpointName or "default" + local Checkpoint = self.Checkpoints[sCpName] + + if Checkpoint then + local dCumulative = os.clock() - Checkpoint.dFirst + local dRecent = os.clock() - Checkpoint.dLast + return dTotal, dCumulative, dRecent + else + return dTotal, nil, nil + end +end + +-- log del tempo trascorso, come sopra +function TimeLib:logElapsed( sCheckpointName) + local dTotal, dCumulative, dRecent = self:elapsed( sCheckpointName) + local sCpName = sCheckpointName or "default" + + if dCumulative then + EgtOutLog( string.format( + "%s time: recent %.3f, cumulative %.3f, total %.3f", + sCpName, dRecent, dCumulative, dTotal)) + else + EgtOutLog( string.format("Total %.3f (no checkpoint '%s' set)", + dTotal, sCpName)) + end +end + +return TimeLib diff --git a/NestProcess.lua b/NestProcess.lua index d3fd807..aaace66 100644 --- a/NestProcess.lua +++ b/NestProcess.lua @@ -91,9 +91,7 @@ local function ExecMaximumFilling( Raw, Parts) EgtMaxFillerAddPart( i, Parts[i].Len, Parts[i].DispLen or Parts[i].Len, Parts[i].Cnt or 1) end -- Eseguo l'ottimizzazione - --EgtStartCounter() EgtMaxFillerCompute( Raw.LenToFill, Raw.StartGap, Raw.MidGap, Raw.EndGap, Raw.SortType) - --local dTime = EgtStopCounter() -- Recupero i risultati local nFilledParts, nDiffParts, dTotFillRatio = EgtMaxFillerGetResults() local OneRes = {} diff --git a/Process.lua b/Process.lua index f89550b..961be4f 100644 --- a/Process.lua +++ b/Process.lua @@ -7,7 +7,7 @@ -- Intestazioni require( 'EgtBase') _ENV = EgtProtectGlobal() -EgtEnableDebug( true) +EgtEnableDebug( false) -- Imposto direttorio libreria specializzata per Travi EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua') @@ -51,6 +51,8 @@ _G.package.loaded['HEADCUT\\HEADCUT'] = nil _G.package.loaded['TAILCUT\\TAILCUT'] = nil -- libreria macchina _G.package.loaded.BeamData = nil +-- libreria calcolo tempo esecuzione +_G.package.loaded.TimeLib = nil -- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente -- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento. @@ -365,6 +367,15 @@ end ------------------------------------------------------------------------------------------------------------- -- *** Esecuzione *** ------------------------------------------------------------------------------------------------------------- + +-- calcolo tempo esecuzione +if EgtGetDebugLevel() >= 3 then + TIMER:start() + EgtOutLog( ' Execution timer started') +end + +-- script principale + if not MyProcessInputData() then return end -- recupero parametri generali da progetto diff --git a/Strategies/Standard/STR0006/STR0006.lua b/Strategies/Standard/STR0006/STR0006.lua index 1be5fe3..08648d7 100644 --- a/Strategies/Standard/STR0006/STR0006.lua +++ b/Strategies/Standard/STR0006/STR0006.lua @@ -74,7 +74,8 @@ local function GetTenonStrategy( Proc, Part) local bMachIsOk = true if ( Proc.FeatureInfo.vtTenonN:getZ() < 0 and TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.HeadType.bTop) or ( Proc.FeatureInfo.vtTenonN:getZ() > 0 and TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.HeadType.bBottom) then - local dTotalLen = TOOLS[Machining.Milling.ToolInfo.nToolIndex].dLength + TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.dPivot + -- TODO questo test va sostituito con check collisione asse Z + local dTotalLen = TOOLS[Machining.Milling.ToolInfo.nToolIndex].dLength + TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.vtPivot:len() local dHorizSpace = dTotalLen * sqrt( 1 - ( Proc.FeatureInfo.vtTenonN:getZ() * Proc.FeatureInfo.vtTenonN:getZ())) if dHorizSpace - ( TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.dCAxisSideEncumbrance / 2) < Proc.b3Box:getDimX() then bMachIsOk = false diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 8226c12..00f5e15 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -561,7 +561,9 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) -- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN) + TIMER:setCheckpoint( 'GetBladeEngagement') local bIsApplicableOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[ToolInfo.nToolIndex], dDepthToMachine) + TIMER:logElapsed( 'GetBladeEngagement') if not bIsApplicableOpposite then return CuttingParametersList, EdgeToMachine end diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 0d3b71c..3a51f6f 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -273,7 +273,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if nToolIndex then Cutting.nToolIndex = nToolIndex + TIMER:setCheckpoint( 'GetBladeEngagement') Cutting.bIsApplicable, Cutting.sBladeEngagement, Cutting.bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) + TIMER:logElapsed( 'GetBladeEngagement') -- utensile da cercare: si prende la lama migliore che può effettuare questo taglio, senza particolari analisi else @@ -354,7 +356,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if OppositeToolDirectionMode ~= 'Disabled' then -- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto + TIMER:setCheckpoint( 'GetBladeEngagement') local bIsApplicableOpposite, sBladeEngagementOpposite, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) + TIMER:logElapsed( 'GetBladeEngagement') -- taglio opposto non fattibile if not bIsApplicableOpposite then @@ -449,7 +453,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if OppositeToolDirectionMode == 'Enabled' then EdgeToMachineForEngagement = EdgeToMachineOpposite end + TIMER:setCheckpoint( 'GetBladeEngagement') local bIsApplicable, sBladeEngagement, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineForEngagement, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine) + TIMER:logElapsed( 'GetBladeEngagement') -- se non fattibile o cambiano le condizioni BladeEngagement, non si riduce if not ( bIsApplicable and ( sBladeEngagement == Cutting.sBladeEngagement) and ( bMoveAfterSplit == Cutting.bMoveAfterSplit)) then From 74a12a4a42f8531a85da907033eb7c0a4a158d5c Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Tue, 25 Nov 2025 15:19:09 +0100 Subject: [PATCH 02/17] =?UTF-8?q?-=20funzioni=20di=20precollisione=20lama?= =?UTF-8?q?=20spostate=20in=20libreria=20apposita=20PreCollisionLib=20-=20?= =?UTF-8?q?calcolo=20tempo=20esecuzione=20migliorato=20(TimeLib=20e=20rife?= =?UTF-8?q?rimenti)=20-=20idTempGroup=20ora=20=C3=A8=20scritto=20nel=20Par?= =?UTF-8?q?t=20per=20evitare=20di=20ricercarlo=20ogni=20volta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BatchProcessNew.lua | 21 ++- LuaLibs/BeamExec.lua | 4 + LuaLibs/DiceCut.lua | 2 +- LuaLibs/FeatureLib.lua | 2 +- LuaLibs/MachiningLib.lua | 228 ++---------------------- LuaLibs/PreCollisionLib.lua | 225 +++++++++++++++++++++++ LuaLibs/TimeLib.lua | 132 +++++++++----- Process.lua | 18 +- Strategies/Standard/STR0002/STR0002.lua | 2 +- Strategies/Standard/STR0015/STR0015.lua | 2 +- StrategyLibs/BLADETOWASTE.lua | 7 +- StrategyLibs/FACEBYBLADE.lua | 12 +- 12 files changed, 368 insertions(+), 287 deletions(-) create mode 100644 LuaLibs/PreCollisionLib.lua diff --git a/BatchProcessNew.lua b/BatchProcessNew.lua index fc6df01..dce4acf 100644 --- a/BatchProcessNew.lua +++ b/BatchProcessNew.lua @@ -182,10 +182,8 @@ end ------------------------------------------------------------------------------------------------------------- -- calcolo tempo esecuzione -if EgtGetDebugLevel() >= 3 then - TIMER:start() - EgtOutLog( ' Execution timer started') -end +TIMER:start() +EgtOutLog( ' Execution timer started') -- script principale @@ -436,6 +434,9 @@ if bToProcess then -- recupero parametri generali da progetto BeamExec.GetGeneralParameters() + -- creo un gruppo temporaneo dove finiranno tutte le entità che non bisogna salvare, alla fine lo si cancella + local idTempGroup = BeamLib.CreateTempGroup() + -- Se devo creare la barra if bCreateBar then if #PARTS == 0 then @@ -595,6 +596,7 @@ if bToProcess then PARTS[i].SplittingPoints = BeamLib.GetPartSplittingPoints( PARTS[i]) PARTS[i].NotClampableLength = { STD = { dHead = 0, dTail = 0}, SIDE = { dHead = 0, dTail = 0}, DOWN = { dHead = 0, dTail = 0}} PARTS[i].sBTLInfo = EgtGetInfo( PARTS[i].id, 'PROJ', 's') or nil + PARTS[i].idTempGroup = idTempGroup PARTS[i].sAISetupConfig = EgtGetInfo( PARTS[i].id, 'AISETUP', 's') or ( GENERAL_PARAMETERS.BTL[PARTS[i].sBTLInfo] and GENERAL_PARAMETERS.BTL[PARTS[i].sBTLInfo].sAISetupConfig) or -- i parametri BTL potrebbero non esistere @@ -652,16 +654,12 @@ if bToProcess then -- Lavoro le features if not GetDataConfig() then return end - -- creo un gruppo temporaneo dove finiranno tutte le entità che non bisogna salvare, alla fine lo si cancella - BeamLib.CreateTempGroup() - BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition) BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition) BeamExec.ProcessMachinings( PARTS) -- si cancella gruppo temporaneo contenente entità da cancellare - local idTempGroup = BeamLib.GetTempGroup() - --EgtErase( idTempGroup) + EgtErase( idTempGroup) local sOutput = '' @@ -764,6 +762,11 @@ else end end +-- log tempi di esecuzione +if EgtGetDebugLevel() >= 3 then + TIMER:logAllElapsed() +end + -- *** Eseguo simulazione con verifica collisione in cieco *** if ( BEAM.FLAG == 0 and ( bToProcess or bToRecalc)) or BEAM.FLAG == 3 or BEAM.FLAG == 4 then EgtOutLog( ' +++ Simulating with collision check >>>') diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index a78a556..bbce2dd 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -352,6 +352,9 @@ end -- *** funzioni posizionamento pezzi all'interno della barra *** ------------------------------------------------------------------------------------------------------------- function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, bCreateMachGroup, bCalcBestPieceUnloadPosition) + -- gruppo per geometrie temporanee + local idTempGroup = BeamLib.GetTempGroup() + -- default per nuove costanti qualora non definite BeamData.OVM_BLADE_HBEAM = ( BeamData.OVM_BLADE_HBEAM or 11) BeamData.OVM_CHAIN_HBEAM = ( BeamData.OVM_CHAIN_HBEAM or 8) @@ -497,6 +500,7 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, b BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig) PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON) PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], bCalcBestPieceUnloadPosition) + PARTS[i].idTempGroup = idTempGroup else local sOut = 'Error: part L(' .. EgtNumToString( dPartLen, 1) .. ') too big for raw part L(' .. EgtNumToString( dLen - 0.1, 1) .. ')' diff --git a/LuaLibs/DiceCut.lua b/LuaLibs/DiceCut.lua index 00e9457..14db6ce 100644 --- a/LuaLibs/DiceCut.lua +++ b/LuaLibs/DiceCut.lua @@ -398,7 +398,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters) if OptionalParameters.bSaveAddedGeometries then idAddGroup = BeamLib.GetAddGroup( Part.id) else - idAddGroup = BeamLib.GetTempGroup() + idAddGroup = Part.idTempGroup end -- faccia primaria diff --git a/LuaLibs/FeatureLib.lua b/LuaLibs/FeatureLib.lua index 2c6886c..f86d831 100644 --- a/LuaLibs/FeatureLib.lua +++ b/LuaLibs/FeatureLib.lua @@ -54,7 +54,7 @@ end -- restituisce vero se tutti i lati della faccia passata si trovano sul grezzo local function AreAllFaceEdgesOnRaw( Part, Proc, idFace) local bEdgeOnRaw = true - local idTempGroup = BeamLib.GetTempGroup() + local idTempGroup = Part.idTempGroup local nLoopId, nLoopCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, idTempGroup) if nLoopCnt > 1 then error( 'AreAllFaceEdgesOnRaw : too many loops') diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index afdbd35..fe5e21a 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -13,6 +13,7 @@ local BeamData = require( 'BeamData') local BeamLib = require( 'BeamLib') local FeatureLib = require( 'FeatureLib') local BCS = require( 'BasicCustomerStrategies') +local PreCollisionLib = require( 'PreCollisionLib') local FaceData = require ( 'FaceData') EgtOutLog( ' MachiningLib started', 1) @@ -283,218 +284,6 @@ local function IsFaceZOutOfRange( vtNFace, Tool) return false end -------------------------------------------------------------------------------------------------------------- --- -local function CheckCollisionAxisC( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) - - -end - -------------------------------------------------------------------------------------------------------------- --- si controlla la collisione con il carro Z nei 3 piani globali X, Y e Z. Se c'è collisione in tutti i piani, il carro sarà in collisione. -local function CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) - - -- se faccia non parallela a direzione testa c'è qualcosa che non va - if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then - error( 'CheckCollisionAxisZ : invalid directions') - end - - -- TODO rimettere - -- se direzione utensile parallela ad uno degli assi principali non serve alcuna verifica - -- if AreSameOrOppositeVectorApprox( Edge.vtN, X_AX()) - -- or AreSameOrOppositeVectorApprox( Edge.vtN, Y_AX()) - -- or AreSameOrOppositeVectorApprox( Edge.vtN, Z_AX()) then - - -- return false - -- end - - local idTempGroup = BeamLib.GetTempGroup() - - -- punti notevoli della lavorazione in cui fare il check - -- TODO aggiungere anche ptMid? - local MachiningPoints = { - Point3d( Edge.ptStart) + Edge.vtN * ( Edge.dElevation - dDepthToMachine), - Point3d( Edge.ptEnd) + Edge.vtN * ( Edge.dElevation - dDepthToMachine) - } - - -- punti in centro lama su naso mandrino o aggregato. In base a direzione e punto - local bIsDownUp = AreOppositeVectorApprox( vtNFace, vtHead) - local ToolExitPoints = {} - for i = 1, #MachiningPoints do - ToolExitPoints[i] = Point3d( MachiningPoints[i] + Edge.vtN * Tool.dDiameter / 2) + vtHead * EgtIf( bIsDownUp, ( Tool.dLength - Tool.dThickness), Tool.dLength) - end - - -- direzioni in cui fare il check - -- TODO queste cambieranno in base all'asse da controllare - local CheckDirections = { - { vtDirectionX = X_AX(), vtDirectionY = Z_AX(), vtDirectionZ = -Y_AX(), sDirectionName = 'X'}, - { vtDirectionX = Y_AX(), vtDirectionY = Z_AX(), vtDirectionZ = X_AX(), sDirectionName = 'Y'}, - { vtDirectionX = X_AX(), vtDirectionY = Y_AX(), vtDirectionZ = Z_AX(), sDirectionName = 'Z'} - } - - -- TEST - local Color = Color3d( math.random(0, 255), math.random(0, 255), math.random(0, 255)) - -- TEST - - for i = 1, #CheckDirections do - - local vtDirectionX = CheckDirections[i].vtDirectionX - local vtDirectionZ = CheckDirections[i].vtDirectionZ - local sDirectionName = CheckDirections[i].sDirectionName - - -- costruzione flat region del pezzo nel piano scelto - -- si estrae prima la silhouette nel piano - local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( Part.idBoxTm, vtDirectionZ, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB) - -- se più curve c'è qualcosa che non va: errore - if nCurveCount > 1 then - error( 'CheckCollisionAxisZ : error in part box') - end - -- creazione flat region dalla silhouette - local idPartSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve) - - -- costruzione flat region del grezzo restante nel piano scelto (con leggera sovrapposizione) - -- si costruisce il box in globale - local ptRestLengthMax = Point3d( Part.b3Part:getMin()) + X_AX() * 500 * GEO.EPS_SMALL - local ptRestLengthMin = Point3d( Part.b3Part:getMin():getX() - 2000, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) - local b3RestLength = BBox3d( ptRestLengthMin, ptRestLengthMax) - -- si crea la trimesh dal box - local idRestLengthBoxTm = EgtSurfTmBBox( idTempGroup, b3RestLength , false, GDB_RT.GLOB) - -- si estrae la silhouette nel piano - idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( idRestLengthBoxTm, vtDirectionZ, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB) - -- se più curve c'è qualcosa che non va: errore - if nCurveCount > 1 then - error( 'CheckCollisionAxisZ : error in part box') - end - -- creazione flat region dalla silhouette - local idRestLengthSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve) - - -- costruzione flat region del carro Z nel piano scelto, tra punto iniziale e finale lavorazione - -- recupero punti da macchina per costruire flat region - local ZAxisPoints = Tool.SetupInfo.GetAxisZPoints( sDirectionName) - -- per ogni punto in cui controllare si crea una flat region (al momento solo 2, altrimenti la ruled) - local CollisionCurves = {} - for j = 1, #ToolExitPoints do - -- curva di collisione in riferimento locale - local idCollisionCurve = EgtCurveCompoFromPoints( idTempGroup, ZAxisPoints) - table.insert( CollisionCurves, idCollisionCurve) - - -- TEST - EgtSetColor( idCollisionCurve, Color) - -- TEST - - -- calcolo pivot in riferimento globale - local ptRef = ToolExitPoints[j] - local frTool = Frame3d( ptRef, vtHead, Edge.vtN) - -- TODO vtPivotGlob dovrà arrivare da funzione perchè può cambiare con SCC (es: aggregato) - local vtPivotGlob = Vector3d( Tool.SetupInfo.vtPivot) - vtPivotGlob:toGlob( frTool) - local ptPivot = ptRef + vtPivotGlob - EgtPoint( idTempGroup, ptPivot, 0) - - -- curva in riferimento globale - local frReference = Frame3d( ptPivot, vtDirectionZ, vtDirectionX) - EgtTransform( idCollisionCurve, frReference, GDB_RT.GLOB ) - end - -- TODO serve fare la ruled o basta controllare nei punti estremi? - --EgtSurfTmRuled( idTempGroup, CollisionCurves[1], CollisionCurves[2]) - end - - -end - -------------------------------------------------------------------------------------------------------------- --- nel piano perpendicolare alla direzione di taglio, se c'è intersezione tra motore e trave c'è collisione --- TODO da integrare in funzione sopra -local function CheckCollisionAxisAB( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) - - -- se direzione utensile parallela ad uno degli assi principali non serve alcuna verifica - if AreSameOrOppositeVectorApprox( Edge.vtN, X_AX()) - or AreSameOrOppositeVectorApprox( Edge.vtN, Y_AX()) - or AreSameOrOppositeVectorApprox( Edge.vtN, Z_AX()) then - - return false - end - - local idTempGroup = BeamLib.GetTempGroup() - - -- riferimento perpendicolare al taglio, X nel verso della normale al lato e Y verso il motore - local ptMachining = Point3d( ( Edge.ptStart + Edge.ptEnd) / 2) + Edge.vtN * ( Edge.dElevation - dDepthToMachine) - local vtEdge = Edge.ptEnd - Edge.ptStart - vtEdge:normalize() - - -- costruzione flat region del pezzo nel piano perpendicolare al taglio - -- si estrae prima la silhouette nel piano - local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( Part.idBoxTm, vtEdge, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB) - -- se più curve c'è qualcosa che non va: errore - if nCurveCount > 1 then - error( 'Check2DBladeCollision : error in part box') - end - -- creazione flat region dalla silhouette - local idPartSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve) - - -- costruzione flat region del grezzo restante nel piano perpendicolare al taglio (con leggera sovrapposizione) - -- si costruisce il box in globale - local ptRestLengthMax = Point3d( Part.b3Part:getMin() + X_AX() * 500 * GEO.EPS_SMALL) - local ptRestLengthMin = Point3d( Part.b3Part:getMin():getX() - 2000, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) - local b3RestLength = BBox3d( ptRestLengthMin, ptRestLengthMax) - -- si crea la trimesh dal box - local idRestLengthBoxTm = EgtSurfTmBBox( idTempGroup, b3RestLength , false, GDB_RT.GLOB) - -- si estrae la silhouette nel piano - idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( idRestLengthBoxTm, vtEdge, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB) - -- se più curve c'è qualcosa che non va: errore - if nCurveCount > 1 then - error( 'Check2DBladeCollision : error in part box') - end - -- creazione flat region dalla silhouette - local idRestLengthSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve) - - -- costruzione flat region approssimata del motore nel piano perpendicolare al taglio - -- punto di congiunzione tra motore e lama - local ptMaxElev = ptMachining + Edge.vtN * Tool.dMaxMaterial - -- se taglio standard (no DownUp) il punto va spostato dello spessore lama - if AreSameVectorApprox( vtNFace, vtHead) then - ptMaxElev = ptMaxElev + vtNFace * Tool.dThickness - end - -- TODO qui sostituire con il valore reale letto dal SetupInfo - -- per Fast si dovrà aggiungere la lunghezza del massimo utensile utilizzabile con lama - local dHeadDepth = 480 - local dHeadWidth = 480 - local ptOpposite = ptMaxElev + Edge.vtN * dHeadWidth - local ptCross = ptOpposite + vtHead * dHeadDepth - local idHeadRectangle = EgtRectangle3P( idTempGroup, ptMaxElev, ptCross, ptOpposite, GDB_RT.GLOB) - -- flat region dal rettangolo - local idHeadSurfFr = EgtSurfFlatRegion( idTempGroup, idHeadRectangle) - - -- intersezione tra pezzo e motore (se fallisce si inverte la flat region del motore, probabile normale opposta) - local bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr) - if not bIntersectSuccess then - EgtInvertSurf( idHeadSurfFr) - bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr) - end - if not bIntersectSuccess then - error( 'Check2DBladeCollision : intersect fail') - end - - local bCollisionFoundPiece = EgtExistsObj( idPartSurfFr) - - -- intersezione tra grezzo restante e motore, se con il pezzo non c'è collisione - local bCollisionFoundRestLength - if not bCollisionFoundPiece then - bIntersectSuccess = EgtSurfFrIntersect( idRestLengthSurfFr, idHeadSurfFr) - if not bIntersectSuccess then - EgtInvertSurf( idHeadSurfFr) - bIntersectSuccess = EgtSurfFrIntersect( idRestLengthSurfFr, idHeadSurfFr) - end - if not bIntersectSuccess then - error( 'Check2DBladeCollision : intersect fail') - end - - bCollisionFoundRestLength = EgtExistsObj( idRestLengthSurfFr) - end - - return bCollisionFoundPiece, bCollisionFoundRestLength -end - ------------------------------------------------------------------------------------------------------------- -- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) -- TODO si dovrà decidere come tagliare anche se pezzo corto (il motore non deve ingombrare con il pinzaggio) @@ -507,9 +296,12 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin -- TODO La riduzione percorso cambia questo test? -- TODO da completare questo test - local bCollisionFoundZ, bMoveAfterSplitZ = CheckCollisionAxisZ( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + -- TODO rimuovere timer qua + TIMER:startElapsed( 'CollisionZ') + local bCollisionFoundZ, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionAxisZ( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + TIMER:stopElapsed( 'CollisionZ') - local bCollisionFound, bMoveAfterSplit = CheckCollisionAxisAB( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionAxisAB( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) if bCollisionCheckForDownUpOnly or not bCollisionFound then return true, sBladeEngagement, bMoveAfterSplit @@ -535,7 +327,7 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin end -- orientamento faccia / utensile compatibili con DownUp: lavorabile - local bCollisionFound, bMoveAfterSplit = CheckCollisionAxisAB( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) + local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionAxisAB( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) if not bCollisionFound then sBladeEngagement = 'DownUp' @@ -714,9 +506,9 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) if bIsToolCompatible then if FaceToMachine and EdgeToMachine and Part and dElevation then local bIsBladeOk = false - TIMER:setCheckpoint( 'GetBladeEngagement') + TIMER:startElapsed( 'GetBladeEngagement') bIsBladeOk, sCurrentBladeEngagement, bCurrentMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bCollisionCheckForDownUpOnly) - TIMER:logElapsed( 'GetBladeEngagement') + TIMER:stopElapsed( 'GetBladeEngagement') -- orientamento non raggiungibile if not bIsBladeOk then bIsToolCompatible = false @@ -1597,7 +1389,7 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part) local ProcTm = FeatureLib.GetProcFromTrimesh( Machining.Geometry[1][1], Part) local dDepthToMachine = min( ProcTm.Faces[Machining.Geometry[1][2] + 1].dElevation, ( Machining.dMaxElev or ProcTm.Faces[Machining.Geometry[1][2] + 1].dElevation)) - ( max( 0, Machining.dResidualDepth or 0)) local nSteps = max( ceil( ( dDepthToMachine - 50 * GEO.EPS_SMALL) / TOOLS[Machining.nToolIndex].dStep), 1) - local idTempGroup = BeamLib.GetTempGroup() + local idTempGroup = Part.idTempGroup -- TODO in futuro creare flatregion (se ci fossero isole il calcolo del percorso non sarebbe corretto) local idFaceContour = EgtExtractSurfTmFacetLoops( ProcTm.id, Machining.Geometry[1][2], idTempGroup) -- si settano i lati aperti della curva derivata dalla superficie diff --git a/LuaLibs/PreCollisionLib.lua b/LuaLibs/PreCollisionLib.lua new file mode 100644 index 0000000..f653856 --- /dev/null +++ b/LuaLibs/PreCollisionLib.lua @@ -0,0 +1,225 @@ +-- PreCollisionLib.lua by Egalware s.r.l. 2025/11/24 +-- Libreria stima collisioni per travi + +-- Tabella per definizione modulo +local PreCollisionLib = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali + + +EgtOutLog( ' PreCollisionLib started', 1) + + +------------------------------------------------------------------------------------------------------------- +-- costruzione flat region del pezzo nel piano scelto +local function GetPartSurfFrInPlane( Part, vtDirection) + + -- si estrae prima la silhouette nel piano + local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( Part.idBoxTm, vtDirection, 10 * GEO.EPS_SMALL, Part.idTempGroup, GDB_RT.GLOB) + -- se più curve c'è qualcosa che non va: errore + if nCurveCount > 1 then + error( 'GetPartSurfFrInPlane : error in part box') + end + -- creazione flat region dalla silhouette + local idPartSurfFr = EgtSurfFlatRegion( Part.idTempGroup, idFirstCurve) + + return idPartSurfFr +end + +------------------------------------------------------------------------------------------------------------- +-- costruzione flat region del grezzo restante nel piano scelto (con leggera sovrapposizione) +local function GetRestlengthSurfFrInPlane( Part, vtDirection) + + -- si costruisce il box in globale + local ptRestLengthMax = Point3d( Part.b3Part:getMin()) + X_AX() * 500 * GEO.EPS_SMALL + local ptRestLengthMin = Point3d( Part.b3Part:getMin():getX() - 2000, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ()) + local b3RestLength = BBox3d( ptRestLengthMin, ptRestLengthMax) + -- si crea la trimesh dal box + local idRestLengthBoxTm = EgtSurfTmBBox( Part.idTempGroup, b3RestLength , false, GDB_RT.GLOB) + -- si estrae la silhouette nel piano + local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( idRestLengthBoxTm, vtDirection, 10 * GEO.EPS_SMALL, Part.idTempGroup, GDB_RT.GLOB) + -- se più curve c'è qualcosa che non va: errore + if nCurveCount > 1 then + error( 'CheckCollisionAxisZ : error in part box') + end + -- creazione flat region dalla silhouette + local idRestlengthSurfFr = EgtSurfFlatRegion( Part.idTempGroup, idFirstCurve) + + return idRestlengthSurfFr +end + +------------------------------------------------------------------------------------------------------------- +-- si controlla la collisione con il carro Z nei 3 piani globali X, Y e Z. Se c'è collisione in tutti i piani, il carro sarà in collisione. +function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) + + -- se faccia non parallela a direzione testa c'è qualcosa che non va + if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then + error( 'CheckCollisionAxisZ : invalid directions') + end + + -- TODO modificare e rimettere (Hmax pezzo) + -- se direzione utensile parallela ad uno degli assi principali non serve alcuna verifica + -- if AreSameOrOppositeVectorApprox( Edge.vtN, X_AX()) + -- or AreSameOrOppositeVectorApprox( Edge.vtN, Y_AX()) + -- or AreSameOrOppositeVectorApprox( Edge.vtN, Z_AX()) then + + -- return false + -- end + + -- punti notevoli della lavorazione in cui fare il check + local MachiningPoints = { + Edge.ptStart + Edge.vtN * ( Edge.dElevation - dDepthToMachine), + Point3d( ( Edge.ptStart + Edge.ptEnd) / 2) + Edge.vtN * ( Edge.dElevation - dDepthToMachine), + Edge.ptEnd + Edge.vtN * ( Edge.dElevation - dDepthToMachine) + } + + -- punti in centro lama su naso mandrino o aggregato. In base a direzione e punto + local bIsDownUp = AreOppositeVectorApprox( vtNFace, vtHead) + local ToolExitPoints = {} + for i = 1, #MachiningPoints do + ToolExitPoints[i] = Point3d( MachiningPoints[i] + Edge.vtN * Tool.dDiameter / 2) + vtHead * EgtIf( bIsDownUp, ( Tool.dLength - Tool.dThickness), Tool.dLength) + end + + -- direzioni in cui fare il check + -- TODO queste cambieranno in base all'asse da controllare + local CheckDirections = { + { vtDirectionX = X_AX(), vtDirectionY = Z_AX(), vtDirectionZ = -Y_AX(), sDirectionName = 'X'}, + { vtDirectionX = Y_AX(), vtDirectionY = Z_AX(), vtDirectionZ = X_AX(), sDirectionName = 'Y'}, + { vtDirectionX = X_AX(), vtDirectionY = Y_AX(), vtDirectionZ = Z_AX(), sDirectionName = 'Z'} + } + + -- TEST + local Color = Color3d( math.random(0, 255), math.random(0, 255), math.random(0, 255)) + -- TEST + + -- per ogni punto in cui controllare si crea una flat region + local CollisionCurves = {} + + for j = 1, #ToolExitPoints do + + -- calcolo pivot in riferimento globale + local ptRef = ToolExitPoints[j] + local frTool = Frame3d( ptRef, vtHead, Edge.vtN) + -- TODO vtPivotGlob dovrà arrivare da funzione perchè può cambiare con SCC (es: aggregato) + local vtPivotGlob = Vector3d( Tool.SetupInfo.vtPivot) + vtPivotGlob:toGlob( frTool) + local ptPivot = ptRef + vtPivotGlob + + for i = 1, #CheckDirections do + + local vtDirectionX = CheckDirections[i].vtDirectionX + local vtDirectionZ = CheckDirections[i].vtDirectionZ + local sDirectionName = CheckDirections[i].sDirectionName + + -- costruzione flat region del pezzo e del grezzo restante nel piano perpendicolare al taglio + local idPartSurfFr = GetPartSurfFrInPlane( Part, vtDirectionZ) + local idRestLengthSurfFr = GetRestlengthSurfFrInPlane( Part, vtDirectionZ) + + -- costruzione flat region della curva di collisione nel piano scelto, per tutti i punti notevoli scelti + -- recupero punti da macchina per costruire flat region + local ZAxisPoints = Tool.SetupInfo.GetAxisZPoints( sDirectionName) + + -- curva di collisione in riferimento locale + local idCollisionCurve = EgtCurveCompoFromPoints( Part.idTempGroup, ZAxisPoints) + table.insert( CollisionCurves, idCollisionCurve) + + -- TEST + EgtSetColor( idCollisionCurve, Color) + -- TEST + + -- curva in riferimento globale + local frReference = Frame3d( ptPivot, vtDirectionZ, vtDirectionX) + EgtTransform( idCollisionCurve, frReference, GDB_RT.GLOB ) + end + end +end + +------------------------------------------------------------------------------------------------------------- +-- nel piano perpendicolare alla direzione di taglio, se c'è intersezione tra motore e trave c'è collisione +-- TODO da integrare in funzione sopra +function PreCollisionLib.CheckCollisionAxisAB( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) + + -- se direzione utensile parallela ad uno degli assi principali non serve alcuna verifica + if AreSameOrOppositeVectorApprox( Edge.vtN, X_AX()) + or AreSameOrOppositeVectorApprox( Edge.vtN, Y_AX()) + or AreSameOrOppositeVectorApprox( Edge.vtN, Z_AX()) then + + return false + end + + -- riferimento perpendicolare al taglio, X nel verso della normale al lato e Y verso il motore + local ptMachining = Point3d( ( Edge.ptStart + Edge.ptEnd) / 2) + Edge.vtN * ( Edge.dElevation - dDepthToMachine) + local vtEdge = Edge.ptEnd - Edge.ptStart + vtEdge:normalize() + + -- costruzione flat region del pezzo e del grezzo restante nel piano perpendicolare al taglio + local idPartSurfFr = GetPartSurfFrInPlane( Part, vtEdge) + local idRestlengthSurfFr = GetRestlengthSurfFrInPlane( Part, vtEdge) + + -- costruzione flat region approssimata del motore nel piano perpendicolare al taglio + -- punto di congiunzione tra motore e lama + local ptMaxElev = ptMachining + Edge.vtN * Tool.dMaxMaterial + -- se taglio standard (no DownUp) il punto va spostato dello spessore lama + if AreSameVectorApprox( vtNFace, vtHead) then + ptMaxElev = ptMaxElev + vtNFace * Tool.dThickness + end + -- TODO qui sostituire con il valore reale letto dal SetupInfo + -- per Fast si dovrà aggiungere la lunghezza del massimo utensile utilizzabile con lama + local dHeadDepth = 480 + local dHeadWidth = 480 + local ptOpposite = ptMaxElev + Edge.vtN * dHeadWidth + local ptCross = ptOpposite + vtHead * dHeadDepth + local idHeadRectangle = EgtRectangle3P( Part.idTempGroup, ptMaxElev, ptCross, ptOpposite, GDB_RT.GLOB) + -- flat region dal rettangolo + local idHeadSurfFr = EgtSurfFlatRegion( Part.idTempGroup, idHeadRectangle) + + -- intersezione tra pezzo e motore (se fallisce si inverte la flat region del motore, probabile normale opposta) + local bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr) + if not bIntersectSuccess then + EgtInvertSurf( idHeadSurfFr) + bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr) + end + if not bIntersectSuccess then + error( 'Check2DBladeCollision : intersect fail') + end + + local bCollisionFoundPiece = EgtExistsObj( idPartSurfFr) + + -- intersezione tra grezzo restante e motore, se con il pezzo non c'è collisione + local bCollisionFoundRestLength + if not bCollisionFoundPiece then + bIntersectSuccess = EgtSurfFrIntersect( idRestlengthSurfFr, idHeadSurfFr) + if not bIntersectSuccess then + EgtInvertSurf( idHeadSurfFr) + bIntersectSuccess = EgtSurfFrIntersect( idRestlengthSurfFr, idHeadSurfFr) + end + if not bIntersectSuccess then + error( 'Check2DBladeCollision : intersect fail') + end + + bCollisionFoundRestLength = EgtExistsObj( idRestlengthSurfFr) + end + + return bCollisionFoundPiece, bCollisionFoundRestLength +end + + + + + + + + + + + + + + + + + +return PreCollisionLib \ No newline at end of file diff --git a/LuaLibs/TimeLib.lua b/LuaLibs/TimeLib.lua index 96f8f62..b4ea056 100644 --- a/LuaLibs/TimeLib.lua +++ b/LuaLibs/TimeLib.lua @@ -12,59 +12,111 @@ EgtOutLog( ' TimeLib started', 1) TimeLib.__index = TimeLib function TimeLib.new() - local self = setmetatable({}, TimeLib) - self.dStartTime = os.clock() - self.Checkpoints = {} -- each checkpoint stores first and last timestamps - return self + local TimeLibInstance = setmetatable({}, TimeLib) + TimeLibInstance.dStartTime = os.clock() + TimeLibInstance.Measurements = {} + return TimeLibInstance end --- reset timer +-- reset entire timer function TimeLib:start() self.dStartTime = os.clock() - self.Checkpoints = {} + self.Measurements = {} end --- setta un checkpoint con nome (default se non specificato) -function TimeLib:setCheckpoint( sName) - local sCpName = sName or "default" - local dNow = os.clock() +-- start elapsed measurement for a specific name +function TimeLib:startElapsed(sName) + local sMeasurementName = sName or "Default" + local dNow = os.clock() - if not self.Checkpoints[sCpName] then - self.Checkpoints[sCpName] = { dFirst = dNow, dLast = dNow } - else - self.Checkpoints[sCpName].dLast = dNow - end + if not self.Measurements[sMeasurementName] then + self.Measurements[sMeasurementName] = { + dStart = dNow, + dLast = 0, + dCumulative = 0, + dRecent = 0, + nCount = 0 + } + else + self.Measurements[sMeasurementName].dStart = dNow + end end --- ritorna il tempo trascorso --- se settato un checkpoint, ritorna anche il tempo di quel checkpoint, cumulativo (dal primo checkpoint settato con quel nome) e recente (dall'ultimo checkpoint settato) -function TimeLib:elapsed( sCheckpointName) - local dTotal = os.clock() - self.dStartTime - local sCpName = sCheckpointName or "default" - local Checkpoint = self.Checkpoints[sCpName] +-- stop elapsed measurement (increments count and updates cumulative) +function TimeLib:stopElapsed(sName) + local sMeasurementName = sName or "Default" + local dNow = os.clock() + local Measurement = self.Measurements[sMeasurementName] - if Checkpoint then - local dCumulative = os.clock() - Checkpoint.dFirst - local dRecent = os.clock() - Checkpoint.dLast - return dTotal, dCumulative, dRecent - else - return dTotal, nil, nil - end + if Measurement and Measurement.dStart then + local dDuration = dNow - Measurement.dStart + Measurement.dRecent = dDuration + Measurement.dCumulative = Measurement.dCumulative + dDuration + Measurement.dLast = dNow + Measurement.nCount = Measurement.nCount + 1 + Measurement.dStart = nil + else + -- if stop called without start, initialize with zero + self.Measurements[sMeasurementName] = { + dStart = nil, + dLast = dNow, + dCumulative = 0, + dRecent = 0, + nCount = 0 + } + end end --- log del tempo trascorso, come sopra -function TimeLib:logElapsed( sCheckpointName) - local dTotal, dCumulative, dRecent = self:elapsed( sCheckpointName) - local sCpName = sCheckpointName or "default" +-- reset elapsed for a specific measurement +function TimeLib:resetElapsed(sName) + local sMeasurementName = sName or "Default" + self.Measurements[sMeasurementName] = nil +end - if dCumulative then - EgtOutLog( string.format( - "%s time: recent %.3f, cumulative %.3f, total %.3f", - sCpName, dRecent, dCumulative, dTotal)) - else - EgtOutLog( string.format("Total %.3f (no checkpoint '%s' set)", - dTotal, sCpName)) - end +-- return elapsed times: total, cumulative, recent, count +function TimeLib:getElapsed(sName) + local dTotal = os.clock() - self.dStartTime + local sMeasurementName = sName or "Default" + local Measurement = self.Measurements[sMeasurementName] + + if Measurement then + return dTotal, Measurement.dCumulative, Measurement.dRecent, Measurement.nCount + else + return dTotal, nil, nil, 0 + end +end + +-- log elapsed times for one measurement +function TimeLib:logElapsed(sName) + local dTotal, dCumulative, dRecent, nCount = self:getElapsed(sName) + local sMeasurementName = sName or "Default" + + if dCumulative then + EgtOutLog(string.format( + "%s(#%d): recent %.3f, cumulative %.3f, total %.3f", + sMeasurementName, nCount, dRecent, dCumulative, dTotal)) + else + EgtOutLog(string.format("Total %.3f (no '%s' measurement started)", + dTotal, sMeasurementName)) + end +end + +-- log elapsed times for all measurements +function TimeLib:logAllElapsed() + local dTotal = os.clock() - self.dStartTime + if next(self.Measurements) == nil then + EgtOutLog(string.format("Total %.3f (no measurements started)", dTotal)) + return + end + + for sMeasurementName, Measurement in pairs(self.Measurements) do + local dCumulative = Measurement.dCumulative + local dRecent = Measurement.dRecent + local nCount = Measurement.nCount + EgtOutLog(string.format( + "%s(#%d): recent %.3f, cumulative %.3f, total %.3f", + sMeasurementName, nCount, dRecent, dCumulative, dTotal)) + end end return TimeLib diff --git a/Process.lua b/Process.lua index 961be4f..ce5a431 100644 --- a/Process.lua +++ b/Process.lua @@ -302,8 +302,6 @@ end -- *** Inserimento delle lavorazioni nelle travi *** ------------------------------------------------------------------------------------------------------------- local function MyProcessFeatures() - -- creo un gruppo temporaneo dove finiranno tutte le entità che non bisogna salvare, alla fine lo si cancella - local idTempGroup = BeamLib.CreateTempGroup() BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition) BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition) @@ -350,6 +348,7 @@ local function MyProcessFeatures() end -- cancello gruppo temporaneo + local idTempGroup = BeamLib.GetTempGroup() EgtErase( idTempGroup) if #sOutput > 0 then EgtOutLog( sOutput) end @@ -369,10 +368,8 @@ end ------------------------------------------------------------------------------------------------------------- -- calcolo tempo esecuzione -if EgtGetDebugLevel() >= 3 then - TIMER:start() - EgtOutLog( ' Execution timer started') -end +TIMER:start() +EgtOutLog( ' Execution timer started') -- script principale @@ -381,6 +378,9 @@ if not MyProcessInputData() then return end -- recupero parametri generali da progetto BeamExec.GetGeneralParameters() +-- creo un gruppo temporaneo dove finiranno tutte le entità che non bisogna salvare, alla fine lo si cancella +BeamLib.CreateTempGroup() + if not MyProcessBeams() then return end if not GetDataConfig() then return end @@ -389,3 +389,9 @@ if not GetDataConfig() then return end EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') if not MyProcessFeatures() then return end + +-- log tempi di esecuzione +if EgtGetDebugLevel() >= 3 then + TIMER:logAllElapsed() +end + diff --git a/Strategies/Standard/STR0002/STR0002.lua b/Strategies/Standard/STR0002/STR0002.lua index eda5f52..bbc2542 100644 --- a/Strategies/Standard/STR0002/STR0002.lua +++ b/Strategies/Standard/STR0002/STR0002.lua @@ -432,7 +432,7 @@ local function GetSplitSurfaces( Proc, Part, bAddMachining) if bAddMachining then idAddGroup = BeamLib.GetAddGroup( Part.id) else - idAddGroup = BeamLib.GetTempGroup() + idAddGroup = Part.idTempGroup end local nOriginalTmIdTunnel = GDB_ID.NULL if Proc.MainFaces.TunnelAddedFaces then diff --git a/Strategies/Standard/STR0015/STR0015.lua b/Strategies/Standard/STR0015/STR0015.lua index 1be1101..448d5b6 100644 --- a/Strategies/Standard/STR0015/STR0015.lua +++ b/Strategies/Standard/STR0015/STR0015.lua @@ -112,7 +112,7 @@ local function GetRoughStrategy( Proc, Part, bSaveAddedGeometries) if bSaveAddedGeometries then idAddGroup = BeamLib.GetAddGroup( Part.id) else - idAddGroup = BeamLib.GetTempGroup() + idAddGroup = Part.idTempGroup end -- aggiungo piano di sgrossatura e lo lavoro local ptStart, vtNP = GetSawCutData( Proc, Proc.idAddAuxGeom, vtNF, vtN) diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 00f5e15..4327116 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -17,7 +17,6 @@ local DiceCut = require( 'DiceCut') -- strategie di base local FaceByBlade = require('FACEBYBLADE') --- tabella per definizione modulo local FeatureInfo = {} ------------------------------------------------------------------------------------------------------------- @@ -561,9 +560,9 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters) -- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN) - TIMER:setCheckpoint( 'GetBladeEngagement') + TIMER:startElapsed( 'GetBladeEngagement') local bIsApplicableOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[ToolInfo.nToolIndex], dDepthToMachine) - TIMER:logElapsed( 'GetBladeEngagement') + TIMER:stopElapsed( 'GetBladeEngagement') if not bIsApplicableOpposite then return CuttingParametersList, EdgeToMachine end @@ -1047,7 +1046,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) if bSaveAddedGeometries then idAddGroup = BeamLib.GetAddGroup( Part.id) else - idAddGroup = BeamLib.GetTempGroup() + idAddGroup = Part.idTempGroup end local idFace1 = EgtSurfTmPlaneInBBox( idAddGroup, Proc.Faces[1].ptCenter, Proc.Faces[1].vtN, Part.b3Part, GDB_ID.ROOT) local idFace2 = EgtSurfTmPlaneInBBox( idAddGroup, Proc.Faces[2].ptCenter, Proc.Faces[2].vtN, Part.b3Part, GDB_ID.ROOT) diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 3a51f6f..8772d7c 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -273,9 +273,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if nToolIndex then Cutting.nToolIndex = nToolIndex - TIMER:setCheckpoint( 'GetBladeEngagement') + TIMER:startElapsed( 'GetBladeEngagement') Cutting.bIsApplicable, Cutting.sBladeEngagement, Cutting.bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) - TIMER:logElapsed( 'GetBladeEngagement') + TIMER:stopElapsed( 'GetBladeEngagement') -- utensile da cercare: si prende la lama migliore che può effettuare questo taglio, senza particolari analisi else @@ -356,9 +356,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if OppositeToolDirectionMode ~= 'Disabled' then -- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto - TIMER:setCheckpoint( 'GetBladeEngagement') + TIMER:startElapsed( 'GetBladeEngagement') local bIsApplicableOpposite, sBladeEngagementOpposite, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) - TIMER:logElapsed( 'GetBladeEngagement') + TIMER:stopElapsed( 'GetBladeEngagement') -- taglio opposto non fattibile if not bIsApplicableOpposite then @@ -453,9 +453,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if OppositeToolDirectionMode == 'Enabled' then EdgeToMachineForEngagement = EdgeToMachineOpposite end - TIMER:setCheckpoint( 'GetBladeEngagement') + TIMER:startElapsed( 'GetBladeEngagement') local bIsApplicable, sBladeEngagement, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineForEngagement, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine) - TIMER:logElapsed( 'GetBladeEngagement') + TIMER:stopElapsed( 'GetBladeEngagement') -- se non fattibile o cambiano le condizioni BladeEngagement, non si riduce if not ( bIsApplicable and ( sBladeEngagement == Cutting.sBladeEngagement) and ( bMoveAfterSplit == Cutting.bMoveAfterSplit)) then From 86adb74131eab9ccc7bbf8cc1af93fa1391a14df Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Wed, 26 Nov 2025 12:26:37 +0100 Subject: [PATCH 03/17] - in PreCollisionLib refactoring e ottimizzazioni tempo esecuzione - in Process e simili aggiunto azzeramento PreCollisionLib --- BatchProcessNew.lua | 1 + LuaLibs/PreCollisionLib.lua | 150 ++++++++++++++++++++++++++++-------- Process.lua | 1 + 3 files changed, 120 insertions(+), 32 deletions(-) diff --git a/BatchProcessNew.lua b/BatchProcessNew.lua index dce4acf..6b9d0b2 100644 --- a/BatchProcessNew.lua +++ b/BatchProcessNew.lua @@ -58,6 +58,7 @@ _G.package.loaded.FeatureLib = nil _G.package.loaded.Identity = nil _G.package.loaded.Logs = nil _G.package.loaded.MachiningLib = nil +_G.package.loaded.PreCollisionLib = nil -- strategie di base sempre presenti _G.package.loaded['HEADCUT\\HEADCUT'] = nil _G.package.loaded['TAILCUT\\TAILCUT'] = nil diff --git a/LuaLibs/PreCollisionLib.lua b/LuaLibs/PreCollisionLib.lua index f653856..63bf790 100644 --- a/LuaLibs/PreCollisionLib.lua +++ b/LuaLibs/PreCollisionLib.lua @@ -51,13 +51,59 @@ local function GetRestlengthSurfFrInPlane( Part, vtDirection) return idRestlengthSurfFr end +------------------------------------------------------------------------------------------------------------- +-- calcolo pivot in riferimento globale +local function GetGlobalPivot( ptRef, vtHead, vtNEdge, Tool) + + -- frame solidale all'utensile (lo stesso in cui vtPivot è definito) + local frTool = Frame3d( ptRef, vtHead, vtNEdge) + -- TODO vtPivotGlob dovrà arrivare da funzione perchè può cambiare con SCC (es: aggregato) + local vtPivotGlob = Vector3d( Tool.SetupInfo.vtPivot) + vtPivotGlob:toGlob( frTool) + local ptPivot = ptRef + vtPivotGlob + + return ptPivot +end + +------------------------------------------------------------------------------------------------------------- +-- restituisce i punti notevoli della lavorazioni in cui fare il controllo +local function GetMachiningPoints( Edge, dDepthToMachine) + + local MachiningPoints = {} + + -- punti notevoli + local ptStart = Edge.ptStart + Edge.vtN * ( Edge.dElevation - dDepthToMachine) + local ptEnd = Edge.ptEnd + Edge.vtN * ( Edge.dElevation - dDepthToMachine) + local ptMid = Point3d( ( ptStart + ptEnd) / 2) + + -- caso ottimizzato: lato parallelo ad una direzione principale + local vtEdge = Edge.ptEnd - Edge.ptStart + vtEdge:normalize() + local bIsEdgeParallelToMainDirection = + AreSameOrOppositeVectorApprox( vtEdge, X_AX()) + or AreSameOrOppositeVectorApprox( vtEdge, Y_AX()) + or AreSameOrOppositeVectorApprox( vtEdge, Z_AX()) + + -- aggiunta punti + -- inizio e fine solo se lato obliquo + if bIsEdgeParallelToMainDirection then + table.insert( MachiningPoints, ptStart) + end + table.insert( MachiningPoints, ptMid) + if bIsEdgeParallelToMainDirection then + table.insert( MachiningPoints, ptEnd) + end + + return MachiningPoints +end + ------------------------------------------------------------------------------------------------------------- -- si controlla la collisione con il carro Z nei 3 piani globali X, Y e Z. Se c'è collisione in tutti i piani, il carro sarà in collisione. function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) -- se faccia non parallela a direzione testa c'è qualcosa che non va if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then - error( 'CheckCollisionAxisZ : invalid directions') + error( 'CheckCollision : invalid directions') end -- TODO modificare e rimettere (Hmax pezzo) @@ -70,11 +116,7 @@ function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, -- end -- punti notevoli della lavorazione in cui fare il check - local MachiningPoints = { - Edge.ptStart + Edge.vtN * ( Edge.dElevation - dDepthToMachine), - Point3d( ( Edge.ptStart + Edge.ptEnd) / 2) + Edge.vtN * ( Edge.dElevation - dDepthToMachine), - Edge.ptEnd + Edge.vtN * ( Edge.dElevation - dDepthToMachine) - } + local MachiningPoints = GetMachiningPoints( Edge, dDepthToMachine) -- punti in centro lama su naso mandrino o aggregato. In base a direzione e punto local bIsDownUp = AreOppositeVectorApprox( vtNFace, vtHead) @@ -95,46 +137,90 @@ function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, local Color = Color3d( math.random(0, 255), math.random(0, 255), math.random(0, 255)) -- TEST - -- per ogni punto in cui controllare si crea una flat region - local CollisionCurves = {} + local bMoveAfterSplit = false - for j = 1, #ToolExitPoints do + -- nel singolo punto notevole si ha collisione se si trova intersezione in tutte le direzioni + -- se almeno in un punto c'è collisione con il pezzo si ritorna collisione + -- se non si trova collisione si ritorna se è necessario separare prima di effettuare la lavorazione (ossia non c'è collisione con il pezzo ma c'è con il grezzo restante) + for i = 1, #ToolExitPoints do - -- calcolo pivot in riferimento globale - local ptRef = ToolExitPoints[j] - local frTool = Frame3d( ptRef, vtHead, Edge.vtN) - -- TODO vtPivotGlob dovrà arrivare da funzione perchè può cambiare con SCC (es: aggregato) - local vtPivotGlob = Vector3d( Tool.SetupInfo.vtPivot) - vtPivotGlob:toGlob( frTool) - local ptPivot = ptRef + vtPivotGlob + -- pivot in globale + local ptRef = ToolExitPoints[i] + local ptPivot = GetGlobalPivot( ptRef, vtHead, Edge.vtN, Tool) - for i = 1, #CheckDirections do + local nCollisionCountPiece = 0 + local nCollisionCountRestlength = 0 - local vtDirectionX = CheckDirections[i].vtDirectionX - local vtDirectionZ = CheckDirections[i].vtDirectionZ - local sDirectionName = CheckDirections[i].sDirectionName + for j = 1, #CheckDirections do - -- costruzione flat region del pezzo e del grezzo restante nel piano perpendicolare al taglio - local idPartSurfFr = GetPartSurfFrInPlane( Part, vtDirectionZ) - local idRestLengthSurfFr = GetRestlengthSurfFrInPlane( Part, vtDirectionZ) - - -- costruzione flat region della curva di collisione nel piano scelto, per tutti i punti notevoli scelti - -- recupero punti da macchina per costruire flat region - local ZAxisPoints = Tool.SetupInfo.GetAxisZPoints( sDirectionName) - - -- curva di collisione in riferimento locale - local idCollisionCurve = EgtCurveCompoFromPoints( Part.idTempGroup, ZAxisPoints) - table.insert( CollisionCurves, idCollisionCurve) + local vtDirectionX = CheckDirections[j].vtDirectionX + local vtDirectionZ = CheckDirections[j].vtDirectionZ + local sDirectionName = CheckDirections[j].sDirectionName + -- costruzione flat region della curva di collisione nel piano scelto + -- recupero punti da macchina per costruire flat region + local CollisionCurvePoints = Tool.SetupInfo.GetAxisPoints( 'Z', sDirectionName) + -- curva di collisione in riferimento locale + local idCollisionCurve = EgtCurveCompoFromPoints( Part.idTempGroup, CollisionCurvePoints) -- TEST EgtSetColor( idCollisionCurve, Color) -- TEST - -- curva in riferimento globale local frReference = Frame3d( ptPivot, vtDirectionZ, vtDirectionX) EgtTransform( idCollisionCurve, frReference, GDB_RT.GLOB ) + -- flat region di collisione + local idCollisionSurfFr = EgtSurfFlatRegion( Part.idTempGroup, idCollisionCurve) + + -- check collisione con pezzo (per la collisione deve esserci intersezione su tutti e 3 i piani) + -- si controlla solo se nelle direzioni precedenti è stata trovata collisione col pezzo, + -- altrimenti significa che non si è usciti dal ciclo solamente la collisione con grezzo per restituire bMoveAfterSplit + local bCollisionFoundPiece = false + if nCollisionCountPiece == j - 1 then + local idPartSurfFr = GetPartSurfFrInPlane( Part, vtDirectionZ) + local bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idCollisionSurfFr) + if not bIntersectSuccess then + error( 'CheckCollision : intersect fail') + end + + bCollisionFoundPiece = EgtExistsObj( idPartSurfFr) + end + + -- check collisione con grezzo restante, se con il pezzo non c'è collisione + local bCollisionFoundRestLength = false + if not bCollisionFoundPiece then + local idRestLengthSurfFr = GetRestlengthSurfFrInPlane( Part, vtDirectionZ) + local bIntersectSuccess = EgtSurfFrIntersect( idRestLengthSurfFr, idCollisionSurfFr) + if not bIntersectSuccess then + error( 'CheckCollision : intersect fail') + end + + bCollisionFoundRestLength = EgtExistsObj( idRestLengthSurfFr) + end + + -- se non trovata collisione si passa al punto successivo + if not ( bCollisionFoundPiece or bCollisionFoundRestLength) then + nCollisionCountPiece = 0 + nCollisionCountRestlength = 0 + break + -- altrimenti si aggiorna il numero di collisioni con pezzo e con grezzo restante + elseif bCollisionFoundPiece then + nCollisionCountPiece = nCollisionCountPiece + 1 + elseif bCollisionFoundRestLength then + nCollisionCountRestlength = nCollisionCountRestlength + 1 + end + end + + -- collisione trovata + if nCollisionCountPiece == #CheckDirections then + return true, nil + -- nessuna collisione trovata con pezzo ma serve separazione + elseif nCollisionCountRestlength == #CheckDirections then + bMoveAfterSplit = true end end + + -- se si arriva qui significa che non è stata trovata alcuna collisione con pezzo + return false, bMoveAfterSplit end ------------------------------------------------------------------------------------------------------------- diff --git a/Process.lua b/Process.lua index ce5a431..0bf3bb8 100644 --- a/Process.lua +++ b/Process.lua @@ -46,6 +46,7 @@ _G.package.loaded.FeatureLib = nil _G.package.loaded.Identity = nil _G.package.loaded.Logs = nil _G.package.loaded.MachiningLib = nil +_G.package.loaded.PreCollisionLib = nil -- strategie di base sempre presenti _G.package.loaded['HEADCUT\\HEADCUT'] = nil _G.package.loaded['TAILCUT\\TAILCUT'] = nil From 155fd09ee52761d1585023553438e137d705ff04 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Wed, 26 Nov 2025 15:00:12 +0100 Subject: [PATCH 04/17] - in PreCollisionLib ottimizzazioni tempi di esecuzione - in TempGroup le geometrie sono settate azzurre con alpha 5 --- LuaLibs/BeamLib.lua | 1 + LuaLibs/PreCollisionLib.lua | 47 ++++++------------------------------- 2 files changed, 8 insertions(+), 40 deletions(-) diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index 5719ac6..37db86a 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -299,6 +299,7 @@ function BeamLib.CreateTempGroup() if not idTempGroup then idTempGroup = EgtGroup( GDB_ID.ROOT) EgtSetName( idTempGroup, "#TEMP_GROUP#") + EgtSetColor( idTempGroup, Color3d( 80, 160, 160, 1)) EgtSetLevel( idTempGroup, GDB_LV.TEMP) end return idTempGroup diff --git a/LuaLibs/PreCollisionLib.lua b/LuaLibs/PreCollisionLib.lua index 63bf790..381fc78 100644 --- a/LuaLibs/PreCollisionLib.lua +++ b/LuaLibs/PreCollisionLib.lua @@ -86,11 +86,11 @@ local function GetMachiningPoints( Edge, dDepthToMachine) -- aggiunta punti -- inizio e fine solo se lato obliquo - if bIsEdgeParallelToMainDirection then + if not bIsEdgeParallelToMainDirection then table.insert( MachiningPoints, ptStart) end table.insert( MachiningPoints, ptMid) - if bIsEdgeParallelToMainDirection then + if not bIsEdgeParallelToMainDirection then table.insert( MachiningPoints, ptEnd) end @@ -133,10 +133,6 @@ function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, { vtDirectionX = X_AX(), vtDirectionY = Y_AX(), vtDirectionZ = Z_AX(), sDirectionName = 'Z'} } - -- TEST - local Color = Color3d( math.random(0, 255), math.random(0, 255), math.random(0, 255)) - -- TEST - local bMoveAfterSplit = false -- nel singolo punto notevole si ha collisione se si trova intersezione in tutte le direzioni @@ -162,9 +158,6 @@ function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, local CollisionCurvePoints = Tool.SetupInfo.GetAxisPoints( 'Z', sDirectionName) -- curva di collisione in riferimento locale local idCollisionCurve = EgtCurveCompoFromPoints( Part.idTempGroup, CollisionCurvePoints) - -- TEST - EgtSetColor( idCollisionCurve, Color) - -- TEST -- curva in riferimento globale local frReference = Frame3d( ptPivot, vtDirectionZ, vtDirectionX) EgtTransform( idCollisionCurve, frReference, GDB_RT.GLOB ) @@ -177,24 +170,16 @@ function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, local bCollisionFoundPiece = false if nCollisionCountPiece == j - 1 then local idPartSurfFr = GetPartSurfFrInPlane( Part, vtDirectionZ) - local bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idCollisionSurfFr) - if not bIntersectSuccess then - error( 'CheckCollision : intersect fail') - end - bCollisionFoundPiece = EgtExistsObj( idPartSurfFr) + bCollisionFoundPiece = not EgtSurfFrTestExternal( idPartSurfFr, idCollisionSurfFr) end -- check collisione con grezzo restante, se con il pezzo non c'è collisione local bCollisionFoundRestLength = false if not bCollisionFoundPiece then local idRestLengthSurfFr = GetRestlengthSurfFrInPlane( Part, vtDirectionZ) - local bIntersectSuccess = EgtSurfFrIntersect( idRestLengthSurfFr, idCollisionSurfFr) - if not bIntersectSuccess then - error( 'CheckCollision : intersect fail') - end - bCollisionFoundRestLength = EgtExistsObj( idRestLengthSurfFr) + bCollisionFoundRestLength = not EgtSurfFrTestExternal( idRestLengthSurfFr, idCollisionSurfFr) end -- se non trovata collisione si passa al punto successivo @@ -262,31 +247,13 @@ function PreCollisionLib.CheckCollisionAxisAB( Edge, vtNFace, vtHead, Part, Tool -- flat region dal rettangolo local idHeadSurfFr = EgtSurfFlatRegion( Part.idTempGroup, idHeadRectangle) - -- intersezione tra pezzo e motore (se fallisce si inverte la flat region del motore, probabile normale opposta) - local bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr) - if not bIntersectSuccess then - EgtInvertSurf( idHeadSurfFr) - bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr) - end - if not bIntersectSuccess then - error( 'Check2DBladeCollision : intersect fail') - end - - local bCollisionFoundPiece = EgtExistsObj( idPartSurfFr) + -- intersezione tra pezzo e motore + local bCollisionFoundPiece = not EgtSurfFrTestExternal( idPartSurfFr, idHeadSurfFr) -- intersezione tra grezzo restante e motore, se con il pezzo non c'è collisione local bCollisionFoundRestLength if not bCollisionFoundPiece then - bIntersectSuccess = EgtSurfFrIntersect( idRestlengthSurfFr, idHeadSurfFr) - if not bIntersectSuccess then - EgtInvertSurf( idHeadSurfFr) - bIntersectSuccess = EgtSurfFrIntersect( idRestlengthSurfFr, idHeadSurfFr) - end - if not bIntersectSuccess then - error( 'Check2DBladeCollision : intersect fail') - end - - bCollisionFoundRestLength = EgtExistsObj( idRestlengthSurfFr) + bCollisionFoundRestLength = not EgtSurfFrTestExternal( idRestlengthSurfFr, idHeadSurfFr) end return bCollisionFoundPiece, bCollisionFoundRestLength From 9ed315ab9bac7dcdeafb9a5f0be512190a602c45 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 28 Nov 2025 12:54:06 +0100 Subject: [PATCH 05/17] - in PreCollision varie modifiche e migliorie per rendere CheckCollisionWithAxis unica per ogni asse da testare - in STR0006 si ritorna a usare dPivot da SetupInfo per check collisione asse Z, in attesa di implementare CheckCollisionWithAxis anche per fresa --- LuaLibs/MachiningLib.lua | 2 +- LuaLibs/PreCollisionLib.lua | 59 ++++++++++++++----------- Strategies/Standard/STR0006/STR0006.lua | 4 +- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index fe5e21a..43fe21c 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -298,7 +298,7 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin -- TODO da completare questo test -- TODO rimuovere timer qua TIMER:startElapsed( 'CollisionZ') - local bCollisionFoundZ, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionAxisZ( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + local bCollisionFoundZ, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) TIMER:stopElapsed( 'CollisionZ') local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionAxisAB( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) diff --git a/LuaLibs/PreCollisionLib.lua b/LuaLibs/PreCollisionLib.lua index 381fc78..5cfb7a6 100644 --- a/LuaLibs/PreCollisionLib.lua +++ b/LuaLibs/PreCollisionLib.lua @@ -43,7 +43,7 @@ local function GetRestlengthSurfFrInPlane( Part, vtDirection) local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( idRestLengthBoxTm, vtDirection, 10 * GEO.EPS_SMALL, Part.idTempGroup, GDB_RT.GLOB) -- se più curve c'è qualcosa che non va: errore if nCurveCount > 1 then - error( 'CheckCollisionAxisZ : error in part box') + error( 'Error in part box') end -- creazione flat region dalla silhouette local idRestlengthSurfFr = EgtSurfFlatRegion( Part.idTempGroup, idFirstCurve) @@ -53,12 +53,12 @@ end ------------------------------------------------------------------------------------------------------------- -- calcolo pivot in riferimento globale -local function GetGlobalPivot( ptRef, vtHead, vtNEdge, Tool) +local function GetGlobalPivot( ptRef, vtSCC, vtHead, vtMovePivot) -- frame solidale all'utensile (lo stesso in cui vtPivot è definito) - local frTool = Frame3d( ptRef, vtHead, vtNEdge) + local frTool = Frame3d( ptRef, vtHead, vtSCC) -- TODO vtPivotGlob dovrà arrivare da funzione perchè può cambiare con SCC (es: aggregato) - local vtPivotGlob = Vector3d( Tool.SetupInfo.vtPivot) + local vtPivotGlob = Vector3d( vtMovePivot) vtPivotGlob:toGlob( frTool) local ptPivot = ptRef + vtPivotGlob @@ -98,12 +98,12 @@ local function GetMachiningPoints( Edge, dDepthToMachine) end ------------------------------------------------------------------------------------------------------------- --- si controlla la collisione con il carro Z nei 3 piani globali X, Y e Z. Se c'è collisione in tutti i piani, il carro sarà in collisione. -function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) +-- si controlla la collisione con il carro Z nei 3 piani principali dell'asse sAxis. Se c'è collisione in tutti i piani, l'asse sarà in collisione. +function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) - -- se faccia non parallela a direzione testa c'è qualcosa che non va + -- se normale faccia non parallela a direzione testa c'è qualcosa che non va if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then - error( 'CheckCollision : invalid directions') + error( 'CheckCollisionWithAxis : invalid directions') end -- TODO modificare e rimettere (Hmax pezzo) @@ -125,14 +125,12 @@ function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, ToolExitPoints[i] = Point3d( MachiningPoints[i] + Edge.vtN * Tool.dDiameter / 2) + vtHead * EgtIf( bIsDownUp, ( Tool.dLength - Tool.dThickness), Tool.dLength) end + -- TODO questo va girato di verso in base a SCC + local vtSCC = Edge.vtN + -- direzioni in cui fare il check - -- TODO queste cambieranno in base all'asse da controllare - local CheckDirections = { - { vtDirectionX = X_AX(), vtDirectionY = Z_AX(), vtDirectionZ = -Y_AX(), sDirectionName = 'X'}, - { vtDirectionX = Y_AX(), vtDirectionY = Z_AX(), vtDirectionZ = X_AX(), sDirectionName = 'Y'}, - { vtDirectionX = X_AX(), vtDirectionY = Y_AX(), vtDirectionZ = Z_AX(), sDirectionName = 'Z'} - } - + local PreCollisionData = Tool.SetupInfo.GetPreCollisionData( sAxis, vtSCC, vtHead) + local bMoveAfterSplit = false -- nel singolo punto notevole si ha collisione se si trova intersezione in tutte le direzioni @@ -140,22 +138,21 @@ function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, -- se non si trova collisione si ritorna se è necessario separare prima di effettuare la lavorazione (ossia non c'è collisione con il pezzo ma c'è con il grezzo restante) for i = 1, #ToolExitPoints do - -- pivot in globale - local ptRef = ToolExitPoints[i] - local ptPivot = GetGlobalPivot( ptRef, vtHead, Edge.vtN, Tool) - local nCollisionCountPiece = 0 local nCollisionCountRestlength = 0 - for j = 1, #CheckDirections do + for j = 1, #PreCollisionData do - local vtDirectionX = CheckDirections[j].vtDirectionX - local vtDirectionZ = CheckDirections[j].vtDirectionZ - local sDirectionName = CheckDirections[j].sDirectionName + -- pivot in globale + local ptPivot = GetGlobalPivot( ToolExitPoints[i], vtSCC, vtHead, PreCollisionData[j].vtMovePivot) + + -- orientamento del riferimento locale + local vtDirectionX = PreCollisionData[j].Directions.vtDirectionX + local vtDirectionZ = PreCollisionData[j].Directions.vtDirectionZ -- costruzione flat region della curva di collisione nel piano scelto -- recupero punti da macchina per costruire flat region - local CollisionCurvePoints = Tool.SetupInfo.GetAxisPoints( 'Z', sDirectionName) + local CollisionCurvePoints = PreCollisionData[j].Points -- curva di collisione in riferimento locale local idCollisionCurve = EgtCurveCompoFromPoints( Part.idTempGroup, CollisionCurvePoints) -- curva in riferimento globale @@ -166,12 +163,16 @@ function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, -- check collisione con pezzo (per la collisione deve esserci intersezione su tutti e 3 i piani) -- si controlla solo se nelle direzioni precedenti è stata trovata collisione col pezzo, - -- altrimenti significa che non si è usciti dal ciclo solamente la collisione con grezzo per restituire bMoveAfterSplit + -- altrimenti significa che non si è usciti dal ciclo solamente per la collisione con grezzo per restituire bMoveAfterSplit local bCollisionFoundPiece = false if nCollisionCountPiece == j - 1 then local idPartSurfFr = GetPartSurfFrInPlane( Part, vtDirectionZ) bCollisionFoundPiece = not EgtSurfFrTestExternal( idPartSurfFr, idCollisionSurfFr) + + if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then + EgtSetColor( { idCollisionSurfFr, idCollisionSurfFr}, RED()) + end end -- check collisione con grezzo restante, se con il pezzo non c'è collisione @@ -180,6 +181,10 @@ function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, local idRestLengthSurfFr = GetRestlengthSurfFrInPlane( Part, vtDirectionZ) bCollisionFoundRestLength = not EgtSurfFrTestExternal( idRestLengthSurfFr, idCollisionSurfFr) + + if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then + EgtSetColor( { idRestLengthSurfFr, idCollisionSurfFr}, ORANGE()) + end end -- se non trovata collisione si passa al punto successivo @@ -196,10 +201,10 @@ function PreCollisionLib.CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, end -- collisione trovata - if nCollisionCountPiece == #CheckDirections then + if nCollisionCountPiece == #PreCollisionData then return true, nil -- nessuna collisione trovata con pezzo ma serve separazione - elseif nCollisionCountRestlength == #CheckDirections then + elseif nCollisionCountRestlength == #PreCollisionData then bMoveAfterSplit = true end end diff --git a/Strategies/Standard/STR0006/STR0006.lua b/Strategies/Standard/STR0006/STR0006.lua index 08648d7..31c4c1d 100644 --- a/Strategies/Standard/STR0006/STR0006.lua +++ b/Strategies/Standard/STR0006/STR0006.lua @@ -74,8 +74,8 @@ local function GetTenonStrategy( Proc, Part) local bMachIsOk = true if ( Proc.FeatureInfo.vtTenonN:getZ() < 0 and TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.HeadType.bTop) or ( Proc.FeatureInfo.vtTenonN:getZ() > 0 and TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.HeadType.bBottom) then - -- TODO questo test va sostituito con check collisione asse Z - local dTotalLen = TOOLS[Machining.Milling.ToolInfo.nToolIndex].dLength + TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.vtPivot:len() + -- TODO questo test va sostituito con check collisione asse Z (PreCollision) + local dTotalLen = TOOLS[Machining.Milling.ToolInfo.nToolIndex].dLength + TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.dPivot local dHorizSpace = dTotalLen * sqrt( 1 - ( Proc.FeatureInfo.vtTenonN:getZ() * Proc.FeatureInfo.vtTenonN:getZ())) if dHorizSpace - ( TOOLS[Machining.Milling.ToolInfo.nToolIndex].SetupInfo.dCAxisSideEncumbrance / 2) < Proc.b3Box:getDimX() then bMachIsOk = false From 1ad5a74a8bfc1d51dca2182d100b504463e63b8f Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 28 Nov 2025 13:15:16 +0100 Subject: [PATCH 06/17] - in MachiningLib CheckCollisionAxisAB sostituito con CheckCollisionWithAxis --- LuaLibs/MachiningLib.lua | 6 ++++-- LuaLibs/PreCollisionLib.lua | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 43fe21c..4cf0178 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -301,7 +301,8 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin local bCollisionFoundZ, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) TIMER:stopElapsed( 'CollisionZ') - local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionAxisAB( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + --local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionAxisAB( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) if bCollisionCheckForDownUpOnly or not bCollisionFound then return true, sBladeEngagement, bMoveAfterSplit @@ -327,7 +328,8 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin end -- orientamento faccia / utensile compatibili con DownUp: lavorabile - local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionAxisAB( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) + --local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionAxisAB( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) + local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) if not bCollisionFound then sBladeEngagement = 'DownUp' diff --git a/LuaLibs/PreCollisionLib.lua b/LuaLibs/PreCollisionLib.lua index 5cfb7a6..65a078b 100644 --- a/LuaLibs/PreCollisionLib.lua +++ b/LuaLibs/PreCollisionLib.lua @@ -171,7 +171,7 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P bCollisionFoundPiece = not EgtSurfFrTestExternal( idPartSurfFr, idCollisionSurfFr) if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then - EgtSetColor( { idCollisionSurfFr, idCollisionSurfFr}, RED()) + EgtSetColor( idCollisionSurfFr, RED()) end end @@ -183,7 +183,7 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P bCollisionFoundRestLength = not EgtSurfFrTestExternal( idRestLengthSurfFr, idCollisionSurfFr) if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then - EgtSetColor( { idRestLengthSurfFr, idCollisionSurfFr}, ORANGE()) + EgtSetColor( idCollisionSurfFr, ORANGE()) end end From 198fa3a5460e8bab79cb6fe4c96a06cddec7aa7c Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 28 Nov 2025 14:56:31 +0100 Subject: [PATCH 07/17] - piccole correzioni riguardanti PreCollision --- LuaLibs/MachiningLib.lua | 11 ----------- LuaLibs/PreCollisionLib.lua | 9 ++++----- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 4cf0178..e8c2016 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -316,17 +316,6 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin return false end - -- rischio collisione carro Z: non lavorabile in Downup - -- TODO questo test è da spostare sulla macchina, non è universale - local bIsToolBelowWorkpiece = Edge.vtN:getZ() < - 0.5 - local bIsToolAboveWorkpiece = Edge.vtN:getZ() > 0.5 - - if Tool.SetupInfo.HeadType.bTop and bIsToolBelowWorkpiece - or ( Tool.SetupInfo.HeadType.bBottom and bIsToolAboveWorkpiece) then - - return false - end - -- orientamento faccia / utensile compatibili con DownUp: lavorabile --local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionAxisAB( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) diff --git a/LuaLibs/PreCollisionLib.lua b/LuaLibs/PreCollisionLib.lua index 65a078b..ca7530b 100644 --- a/LuaLibs/PreCollisionLib.lua +++ b/LuaLibs/PreCollisionLib.lua @@ -55,12 +55,11 @@ end -- calcolo pivot in riferimento globale local function GetGlobalPivot( ptRef, vtSCC, vtHead, vtMovePivot) - -- frame solidale all'utensile (lo stesso in cui vtPivot è definito) + -- frame solidale all'utensile (lo stesso in cui vtMovePivot è definito) local frTool = Frame3d( ptRef, vtHead, vtSCC) - -- TODO vtPivotGlob dovrà arrivare da funzione perchè può cambiare con SCC (es: aggregato) - local vtPivotGlob = Vector3d( vtMovePivot) - vtPivotGlob:toGlob( frTool) - local ptPivot = ptRef + vtPivotGlob + local vtMovePivotGlob = Vector3d( vtMovePivot) + vtMovePivotGlob:toGlob( frTool) + local ptPivot = ptRef + vtMovePivotGlob return ptPivot end From a2ed6f57894c5e201dc1f970df0b49eb978e65b1 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 28 Nov 2025 15:58:14 +0100 Subject: [PATCH 08/17] - in PreCollisionLib si gestisce correttamente la direzione SCC - in FACEBYBLADE SCC preso da funzione macchina - in BeamLib aggiunta funzione per convertire il valore SCC in direzione --- LuaLibs/BeamLib.lua | 22 ++++++++++++++++++++++ LuaLibs/PreCollisionLib.lua | 20 ++++++++++++++------ StrategyLibs/FACEBYBLADE.lua | 5 +++-- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index 37db86a..33899e0 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -425,6 +425,28 @@ function BeamLib.GetNearestParalOpposite( vtRef, vtNorm) return nil end +------------------------------------------------------------------------------------------------------------- +-- TODO gestire anche altri valori +function BeamLib.GetDirectionFromSCC( nSCC) + local vtSCC + + if nSCC == MCH_SCC.ADIR_XP then + vtSCC = X_AX() + elseif nSCC == MCH_SCC.ADIR_XM then + vtSCC = -X_AX() + elseif nSCC == MCH_SCC.ADIR_YP then + vtSCC = Y_AX() + elseif nSCC == MCH_SCC.ADIR_YM then + vtSCC = -Y_AX() + elseif nSCC == MCH_SCC.ADIR_ZP then + vtSCC = Z_AX() + elseif nSCC == MCH_SCC.ADIR_ZM then + vtSCC = -Z_AX() + end + + return vtSCC +end + ------------------------------------------------------------------------------------------------------------- -- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce function BeamLib.Is3EdgesApprox( Proc, idFace, nAddGrpId) diff --git a/LuaLibs/PreCollisionLib.lua b/LuaLibs/PreCollisionLib.lua index ca7530b..b6f2667 100644 --- a/LuaLibs/PreCollisionLib.lua +++ b/LuaLibs/PreCollisionLib.lua @@ -6,6 +6,7 @@ local PreCollisionLib = {} -- Include require( 'EgtBase') +local BeamLib = require( 'BeamLib') -- Carico i dati globali @@ -53,10 +54,10 @@ end ------------------------------------------------------------------------------------------------------------- -- calcolo pivot in riferimento globale -local function GetGlobalPivot( ptRef, vtSCC, vtHead, vtMovePivot) +local function GetGlobalPivot( ptRef, vtToolSCC, vtHead, vtMovePivot) -- frame solidale all'utensile (lo stesso in cui vtMovePivot è definito) - local frTool = Frame3d( ptRef, vtHead, vtSCC) + local frTool = Frame3d( ptRef, vtHead, vtToolSCC) local vtMovePivotGlob = Vector3d( vtMovePivot) vtMovePivotGlob:toGlob( frTool) local ptPivot = ptRef + vtMovePivotGlob @@ -124,11 +125,18 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P ToolExitPoints[i] = Point3d( MachiningPoints[i] + Edge.vtN * Tool.dDiameter / 2) + vtHead * EgtIf( bIsDownUp, ( Tool.dLength - Tool.dThickness), Tool.dLength) end - -- TODO questo va girato di verso in base a SCC - local vtSCC = Edge.vtN + -- vtToolSCC è la direzione vtTool con verso dato dalla direzione SCC (punta verso il lato in cui c'è l'asse C/aggregato) + local nSCC = Tool.SetupInfo.GetSCC( Edge.vtN, Edge.ptEnd - Edge.ptStart, vtNFace) + local vtSCC = BeamLib.GetDirectionFromSCC( nSCC) + local vtToolSCC + if Edge.vtN * vtSCC > GEO.EPS_SMALL then + vtToolSCC = Vector3d( Edge.vtN) + else + vtToolSCC = Vector3d( -Edge.vtN) + end -- direzioni in cui fare il check - local PreCollisionData = Tool.SetupInfo.GetPreCollisionData( sAxis, vtSCC, vtHead) + local PreCollisionData = Tool.SetupInfo.GetPreCollisionData( sAxis, vtToolSCC, vtHead) local bMoveAfterSplit = false @@ -143,7 +151,7 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P for j = 1, #PreCollisionData do -- pivot in globale - local ptPivot = GetGlobalPivot( ToolExitPoints[i], vtSCC, vtHead, PreCollisionData[j].vtMovePivot) + local ptPivot = GetGlobalPivot( ToolExitPoints[i], vtToolSCC, vtHead, PreCollisionData[j].vtMovePivot) -- orientamento del riferimento locale local vtDirectionX = PreCollisionData[j].Directions.vtDirectionX diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 8772d7c..4c7924d 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -164,7 +164,7 @@ end -- TODO implementare SCC in funzione macchina -local function GetSCC( vtMachiningDirection, vtEdgeDirection, vtNFace) +function FACEBYBLADE.GetSCC( vtMachiningDirection, vtEdgeDirection, vtNFace) local nSCC = MCH_SCC.NONE if abs( vtMachiningDirection:getX()) > abs( vtMachiningDirection:getY()) - GEO.EPS_SMALL then @@ -264,6 +264,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato Cutting.dEdgeLength = EdgeToMachine.dLength + -- TODO questa deve essere ptEnd - ptStart Cutting.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN Cutting.vtToolDirection = EdgeToMachine.vtN Cutting.ptEdge1, Cutting.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd @@ -507,7 +508,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end -- SCC - Cutting.nSCC = GetSCC( Cutting.vtToolDirection, Cutting.vtEdgeDirection, FaceToMachine.vtN) + Cutting.nSCC = TOOLS[Cutting.nToolIndex].SetupInfo.GetSCC( Cutting.vtToolDirection, Cutting.vtEdgeDirection, FaceToMachine.vtN) -- asse bloccato Cutting.sBlockedAxis = BeamLib.GetBlockedAxis( Cutting.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN, EgtIf( FaceToMachine.vtN:getX() > 0, X_AX(), -X_AX())) From dc8c5e8ba2ee5d5e5cdf2352c33d0e7305d67275 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 28 Nov 2025 16:03:00 +0100 Subject: [PATCH 09/17] - in PreCollisionLib piccola correzione --- LuaLibs/PreCollisionLib.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/LuaLibs/PreCollisionLib.lua b/LuaLibs/PreCollisionLib.lua index b6f2667..fb290ff 100644 --- a/LuaLibs/PreCollisionLib.lua +++ b/LuaLibs/PreCollisionLib.lua @@ -126,7 +126,9 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P end -- vtToolSCC è la direzione vtTool con verso dato dalla direzione SCC (punta verso il lato in cui c'è l'asse C/aggregato) - local nSCC = Tool.SetupInfo.GetSCC( Edge.vtN, Edge.ptEnd - Edge.ptStart, vtNFace) + local vtEdge = Edge.ptEnd - Edge.ptStart + vtEdge:normalize() + local nSCC = Tool.SetupInfo.GetSCC( Edge.vtN, vtEdge, vtNFace) local vtSCC = BeamLib.GetDirectionFromSCC( nSCC) local vtToolSCC if Edge.vtN * vtSCC > GEO.EPS_SMALL then From 530dce3d0de500e8930a6c806c2a60653ce8287e Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 28 Nov 2025 18:16:00 +0100 Subject: [PATCH 10/17] - PreCollisionLib: ultima versione con controllo 3d fatto nelle 3 viste principali --- LuaLibs/MachiningLib.lua | 2 +- LuaLibs/PreCollisionLib.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index e8c2016..80378af 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -308,7 +308,7 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin return true, sBladeEngagement, bMoveAfterSplit end end - + -- faccia non lavorabile in modo standard: si verifica se il DownUp è fattibile -- la normale della faccia non permette il DownUp: non lavorabile in DownUp (se taglio DownUp la faccia è lavorata al contrario, vtN opposta) if IsFaceZOutOfRange( -Face.vtN, Tool) then diff --git a/LuaLibs/PreCollisionLib.lua b/LuaLibs/PreCollisionLib.lua index fb290ff..3801ae5 100644 --- a/LuaLibs/PreCollisionLib.lua +++ b/LuaLibs/PreCollisionLib.lua @@ -137,7 +137,7 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P vtToolSCC = Vector3d( -Edge.vtN) end - -- direzioni in cui fare il check + -- punti curva collisione e direzioni check da macchina local PreCollisionData = Tool.SetupInfo.GetPreCollisionData( sAxis, vtToolSCC, vtHead) local bMoveAfterSplit = false From d5b4edea14c2da5f74a50a7c604ae0ee63577db7 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Mon, 1 Dec 2025 12:44:23 +0100 Subject: [PATCH 11/17] - PreCollisionLib rivista per testare costruire trimesh da punti e usare funzione EgtTestSurfaceSurface per verificare collisione --- LuaLibs/PreCollisionLib.lua | 133 ++++++++++++++---------------------- 1 file changed, 51 insertions(+), 82 deletions(-) diff --git a/LuaLibs/PreCollisionLib.lua b/LuaLibs/PreCollisionLib.lua index 3801ae5..ea17ac8 100644 --- a/LuaLibs/PreCollisionLib.lua +++ b/LuaLibs/PreCollisionLib.lua @@ -7,6 +7,7 @@ local PreCollisionLib = {} -- Include require( 'EgtBase') local BeamLib = require( 'BeamLib') +local BeamData = require( 'BeamData') -- Carico i dati globali @@ -15,24 +16,8 @@ EgtOutLog( ' PreCollisionLib started', 1) ------------------------------------------------------------------------------------------------------------- --- costruzione flat region del pezzo nel piano scelto -local function GetPartSurfFrInPlane( Part, vtDirection) - - -- si estrae prima la silhouette nel piano - local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( Part.idBoxTm, vtDirection, 10 * GEO.EPS_SMALL, Part.idTempGroup, GDB_RT.GLOB) - -- se più curve c'è qualcosa che non va: errore - if nCurveCount > 1 then - error( 'GetPartSurfFrInPlane : error in part box') - end - -- creazione flat region dalla silhouette - local idPartSurfFr = EgtSurfFlatRegion( Part.idTempGroup, idFirstCurve) - - return idPartSurfFr -end - -------------------------------------------------------------------------------------------------------------- --- costruzione flat region del grezzo restante nel piano scelto (con leggera sovrapposizione) -local function GetRestlengthSurfFrInPlane( Part, vtDirection) +-- costruzione trimesh del grezzo restante (con leggera sovrapposizione) +local function GetRestlengthSurfTm( Part) -- si costruisce il box in globale local ptRestLengthMax = Point3d( Part.b3Part:getMin()) + X_AX() * 500 * GEO.EPS_SMALL @@ -40,16 +25,8 @@ local function GetRestlengthSurfFrInPlane( Part, vtDirection) local b3RestLength = BBox3d( ptRestLengthMin, ptRestLengthMax) -- si crea la trimesh dal box local idRestLengthBoxTm = EgtSurfTmBBox( Part.idTempGroup, b3RestLength , false, GDB_RT.GLOB) - -- si estrae la silhouette nel piano - local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( idRestLengthBoxTm, vtDirection, 10 * GEO.EPS_SMALL, Part.idTempGroup, GDB_RT.GLOB) - -- se più curve c'è qualcosa che non va: errore - if nCurveCount > 1 then - error( 'Error in part box') - end - -- creazione flat region dalla silhouette - local idRestlengthSurfFr = EgtSurfFlatRegion( Part.idTempGroup, idFirstCurve) - return idRestlengthSurfFr + return idRestLengthBoxTm end ------------------------------------------------------------------------------------------------------------- @@ -147,74 +124,66 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P -- se non si trova collisione si ritorna se è necessario separare prima di effettuare la lavorazione (ossia non c'è collisione con il pezzo ma c'è con il grezzo restante) for i = 1, #ToolExitPoints do - local nCollisionCountPiece = 0 - local nCollisionCountRestlength = 0 + local ptPivot = GetGlobalPivot( ToolExitPoints[i], vtToolSCC, vtHead, PreCollisionData.vtMovePivot) - for j = 1, #PreCollisionData do + -- orientamento del riferimento locale + local vtDirectionX = PreCollisionData.Directions.vtDirectionX + local vtDirectionY = PreCollisionData.Directions.vtDirectionY + local vtDirectionZ = PreCollisionData.Directions.vtDirectionZ + + -- costruzione trimesh a partire dalla curva di collisione + -- recupero punti da macchina per costruire trimesh + local CollisionCurvePoints = PreCollisionData.Points + -- curva di collisione in riferimento locale + local idCollisionCurve = EgtCurveCompoFromPoints( Part.idTempGroup, CollisionCurvePoints) + -- curva in riferimento globale + local frReference = Frame3d( ptPivot, vtDirectionZ, vtDirectionX) + EgtTransform( idCollisionCurve, frReference, GDB_RT.GLOB) + -- trimesh di collisione + local idCollisionSurfTm + if PreCollisionData.bSurfTmByRevolve then + idCollisionSurfTm = EgtSurfTmByRevolve( Part.idTempGroup, idCollisionCurve, ptPivot, vtDirectionY, true, 0.05, GDB_RT.GLOB) + else + local vtPreMove = -vtDirectionZ * ( PreCollisionData.dExtrusionDepth / 2) + EgtMove( idCollisionCurve, vtPreMove, GDB_RT.GLOB) + local vtExtrusion = vtDirectionZ * PreCollisionData.dExtrusionDepth + idCollisionSurfTm = EgtSurfTmByRegionExtrusion( Part.idTempGroup, idCollisionCurve, vtExtrusion, 0.05, GDB_RT.GLOB) + end - -- pivot in globale - local ptPivot = GetGlobalPivot( ToolExitPoints[i], vtToolSCC, vtHead, PreCollisionData[j].vtMovePivot) + -- check collisione con pezzo + local bCollisionFoundPiece = false - -- orientamento del riferimento locale - local vtDirectionX = PreCollisionData[j].Directions.vtDirectionX - local vtDirectionZ = PreCollisionData[j].Directions.vtDirectionZ - - -- costruzione flat region della curva di collisione nel piano scelto - -- recupero punti da macchina per costruire flat region - local CollisionCurvePoints = PreCollisionData[j].Points - -- curva di collisione in riferimento locale - local idCollisionCurve = EgtCurveCompoFromPoints( Part.idTempGroup, CollisionCurvePoints) - -- curva in riferimento globale - local frReference = Frame3d( ptPivot, vtDirectionZ, vtDirectionX) - EgtTransform( idCollisionCurve, frReference, GDB_RT.GLOB ) - -- flat region di collisione - local idCollisionSurfFr = EgtSurfFlatRegion( Part.idTempGroup, idCollisionCurve) + bCollisionFoundPiece = EgtTestSurfaceSurface( Part.idBoxTm, idCollisionSurfTm, BeamData.COLL_SIC) + if not type( bCollisionFoundPiece) == "boolean" then + error( 'EgtTestSurfaceSurface fail') + end - -- check collisione con pezzo (per la collisione deve esserci intersezione su tutti e 3 i piani) - -- si controlla solo se nelle direzioni precedenti è stata trovata collisione col pezzo, - -- altrimenti significa che non si è usciti dal ciclo solamente per la collisione con grezzo per restituire bMoveAfterSplit - local bCollisionFoundPiece = false - if nCollisionCountPiece == j - 1 then - local idPartSurfFr = GetPartSurfFrInPlane( Part, vtDirectionZ) + if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then + EgtSetColor( idCollisionSurfTm, RED()) + end - bCollisionFoundPiece = not EgtSurfFrTestExternal( idPartSurfFr, idCollisionSurfFr) + -- check collisione con grezzo restante, se con il pezzo non c'è collisione + local bCollisionFoundRestLength = false + if not bCollisionFoundPiece then + local idRestLengthSurfFr = GetRestlengthSurfTm( Part, vtDirectionZ) - if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then - EgtSetColor( idCollisionSurfFr, RED()) - end + bCollisionFoundRestLength = EgtTestSurfaceSurface( idRestLengthSurfFr, idCollisionSurfTm, BeamData.COLL_SIC) + if not type( bCollisionFoundRestLength) == "boolean" then + error( 'EgtTestSurfaceSurface fail') end - -- check collisione con grezzo restante, se con il pezzo non c'è collisione - local bCollisionFoundRestLength = false - if not bCollisionFoundPiece then - local idRestLengthSurfFr = GetRestlengthSurfFrInPlane( Part, vtDirectionZ) - - bCollisionFoundRestLength = not EgtSurfFrTestExternal( idRestLengthSurfFr, idCollisionSurfFr) - - if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then - EgtSetColor( idCollisionSurfFr, ORANGE()) - end + if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then + EgtSetColor( idCollisionSurfTm, ORANGE()) end - -- se non trovata collisione si passa al punto successivo - if not ( bCollisionFoundPiece or bCollisionFoundRestLength) then - nCollisionCountPiece = 0 - nCollisionCountRestlength = 0 - break - -- altrimenti si aggiorna il numero di collisioni con pezzo e con grezzo restante - elseif bCollisionFoundPiece then - nCollisionCountPiece = nCollisionCountPiece + 1 - elseif bCollisionFoundRestLength then - nCollisionCountRestlength = nCollisionCountRestlength + 1 + if bCollisionFoundRestLength then + bMoveAfterSplit = true end end - -- collisione trovata - if nCollisionCountPiece == #PreCollisionData then - return true, nil - -- nessuna collisione trovata con pezzo ma serve separazione - elseif nCollisionCountRestlength == #PreCollisionData then - bMoveAfterSplit = true + -- se trovata collisione con pezzo si esce subito + if bCollisionFoundPiece then + return true end end From 1e327819c6125e3fa98ba775300a6f975f0c5a58 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Mon, 1 Dec 2025 17:21:48 +0100 Subject: [PATCH 12/17] - in PreCollisionLib corretta gestione SCC --- LuaLibs/PreCollisionLib.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/LuaLibs/PreCollisionLib.lua b/LuaLibs/PreCollisionLib.lua index ea17ac8..5101283 100644 --- a/LuaLibs/PreCollisionLib.lua +++ b/LuaLibs/PreCollisionLib.lua @@ -31,10 +31,10 @@ end ------------------------------------------------------------------------------------------------------------- -- calcolo pivot in riferimento globale -local function GetGlobalPivot( ptRef, vtToolSCC, vtHead, vtMovePivot) +local function GetGlobalPivot( ptRef, vtC, vtHead, vtMovePivot) -- frame solidale all'utensile (lo stesso in cui vtMovePivot è definito) - local frTool = Frame3d( ptRef, vtHead, vtToolSCC) + local frTool = Frame3d( ptRef, vtHead, vtC) local vtMovePivotGlob = Vector3d( vtMovePivot) vtMovePivotGlob:toGlob( frTool) local ptPivot = ptRef + vtMovePivotGlob @@ -102,20 +102,20 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P ToolExitPoints[i] = Point3d( MachiningPoints[i] + Edge.vtN * Tool.dDiameter / 2) + vtHead * EgtIf( bIsDownUp, ( Tool.dLength - Tool.dThickness), Tool.dLength) end - -- vtToolSCC è la direzione vtTool con verso dato dalla direzione SCC (punta verso il lato in cui c'è l'asse C/aggregato) + -- vtC punta sempre verso il corpo dell'asse C local vtEdge = Edge.ptEnd - Edge.ptStart vtEdge:normalize() local nSCC = Tool.SetupInfo.GetSCC( Edge.vtN, vtEdge, vtNFace) local vtSCC = BeamLib.GetDirectionFromSCC( nSCC) - local vtToolSCC - if Edge.vtN * vtSCC > GEO.EPS_SMALL then - vtToolSCC = Vector3d( Edge.vtN) - else - vtToolSCC = Vector3d( -Edge.vtN) + local vtC = vtHead ^ Tool.SetupInfo.vtRotationAxisC + if vtC:isZero() then + vtC = vtSCC + elseif vtC * vtSCC < GEO.EPS_SMALL then + vtC = -vtC end -- punti curva collisione e direzioni check da macchina - local PreCollisionData = Tool.SetupInfo.GetPreCollisionData( sAxis, vtToolSCC, vtHead) + local PreCollisionData = Tool.SetupInfo.GetPreCollisionData( sAxis, vtC, vtHead) local bMoveAfterSplit = false @@ -124,7 +124,7 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P -- se non si trova collisione si ritorna se è necessario separare prima di effettuare la lavorazione (ossia non c'è collisione con il pezzo ma c'è con il grezzo restante) for i = 1, #ToolExitPoints do - local ptPivot = GetGlobalPivot( ToolExitPoints[i], vtToolSCC, vtHead, PreCollisionData.vtMovePivot) + local ptPivot = GetGlobalPivot( ToolExitPoints[i], vtC, vtHead, PreCollisionData.vtMovePivot) -- orientamento del riferimento locale local vtDirectionX = PreCollisionData.Directions.vtDirectionX @@ -165,7 +165,7 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P -- check collisione con grezzo restante, se con il pezzo non c'è collisione local bCollisionFoundRestLength = false if not bCollisionFoundPiece then - local idRestLengthSurfFr = GetRestlengthSurfTm( Part, vtDirectionZ) + local idRestLengthSurfFr = GetRestlengthSurfTm( Part) bCollisionFoundRestLength = EgtTestSurfaceSurface( idRestLengthSurfFr, idCollisionSurfTm, BeamData.COLL_SIC) if not type( bCollisionFoundRestLength) == "boolean" then From cb60773216f8667bc8b70650b4e740733983d230 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Mon, 1 Dec 2025 18:54:03 +0100 Subject: [PATCH 13/17] =?UTF-8?q?-=20in=20MachiningLib=20si=20GetBladeEnga?= =?UTF-8?q?gement=20si=20controlla=20la=20collisione=20con=20tutti=20gli?= =?UTF-8?q?=20assi=20in=20modalit=C3=A0=20standard=20o=20DownUp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LuaLibs/MachiningLib.lua | 66 +++++++++++++++++++++++------------ StrategyLibs/BLADETOWASTE.lua | 2 +- StrategyLibs/FACEBYBLADE.lua | 6 ++-- 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 80378af..c689c8e 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -288,45 +288,65 @@ end -- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) -- TODO si dovrà decidere come tagliare anche se pezzo corto (il motore non deve ingombrare con il pinzaggio) -- valutare se restituire, se disponibili, entrambe le soluzioni e demandare la decisione alla FaceByBlade -function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachine, bCollisionCheckForDownUpOnly) +function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachine, bIsDicing) local sBladeEngagement = 'Standard' - -- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci altre condizioni che fanno fallire il taglio + -- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci collisioni che fanno fallire il taglio if not IsFaceZOutOfRange( Face.vtN, Tool) then - - -- TODO La riduzione percorso cambia questo test? - -- TODO da completare questo test - -- TODO rimuovere timer qua - TIMER:startElapsed( 'CollisionZ') - local bCollisionFoundZ, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) - TIMER:stopElapsed( 'CollisionZ') - --local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionAxisAB( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) - local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) - if bCollisionCheckForDownUpOnly or not bCollisionFound then + -- se cubetti si controlla solo asse Z (ci sarebbe collisione con il materiale già rimosso) + if bIsDicing then + local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + + return not bCollisionFound, sBladeEngagement, bMoveAfterSplit + end + + local bMoveAfterSplit = false + + local bCollisionFoundZ, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + + local bCollisionFoundC, bMoveAfterSplitC = PreCollisionLib.CheckCollisionWithAxis( 'C', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + + local bCollisionFoundAB, bMoveAfterSplitAB = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + + -- se nessuna collisione trovata si ritorna lavorazione fattibile, altrimenti si proseguirà al DownUp + if not ( bCollisionFoundZ or bCollisionFoundC or bCollisionFoundAB) then + if bMoveAfterSplitZ or bMoveAfterSplitC or bMoveAfterSplitAB then + bMoveAfterSplit = true + end return true, sBladeEngagement, bMoveAfterSplit end end -- faccia non lavorabile in modo standard: si verifica se il DownUp è fattibile + -- la normale della faccia non permette il DownUp: non lavorabile in DownUp (se taglio DownUp la faccia è lavorata al contrario, vtN opposta) if IsFaceZOutOfRange( -Face.vtN, Tool) then return false end - -- orientamento faccia / utensile compatibili con DownUp: lavorabile - --local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionAxisAB( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) - local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) - if not bCollisionFound then - - sBladeEngagement = 'DownUp' - - return true, sBladeEngagement, bMoveAfterSplit + local bCollisionFoundZ, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) + if bCollisionFoundZ then + return false end - return false + local bCollisionFoundC, bMoveAfterSplitC = PreCollisionLib.CheckCollisionWithAxis( 'C', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) + if bCollisionFoundC then + return false + end + + local bCollisionFoundAB, bMoveAfterSplitAB = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) + if bCollisionFoundAB then + return false + end + + -- se si è arrivati qui il DownUp è fattibile + sBladeEngagement = 'DownUp' + local bMoveAfterSplit = bMoveAfterSplitZ or bMoveAfterSplitC or bMoveAfterSplitAB + + return true, sBladeEngagement, bMoveAfterSplit end ------------------------------------------------------------------------------------------------------------- @@ -472,7 +492,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) local bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false local EdgeToMachine = ToolSearchParameters.EdgeToMachine local Part = ToolSearchParameters.Part - local bCollisionCheckForDownUpOnly = ToolSearchParameters.bCollisionCheckForDownUpOnly or false + local bIsDicing = ToolSearchParameters.bIsDicing or false local nBestToolIndex local dBestToolResidualDepth = 0 @@ -498,7 +518,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) if FaceToMachine and EdgeToMachine and Part and dElevation then local bIsBladeOk = false TIMER:startElapsed( 'GetBladeEngagement') - bIsBladeOk, sCurrentBladeEngagement, bCurrentMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bCollisionCheckForDownUpOnly) + bIsBladeOk, sCurrentBladeEngagement, bCurrentMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bIsDicing) TIMER:stopElapsed( 'GetBladeEngagement') -- orientamento non raggiungibile if not bIsBladeOk then diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 4327116..55885c7 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -897,7 +897,7 @@ local function CutWithDicing( Proc, Part, OptionalParameters) nToolIndex = nToolIndex, dRadialStepSpan = 0, dExtendAfterTail = dExtendAfterTail, - bCollisionCheckForDownUpOnly = true + bIsDicing = true } Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade) Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0) diff --git a/StrategyLibs/FACEBYBLADE.lua b/StrategyLibs/FACEBYBLADE.lua index 4c7924d..3cc51fa 100644 --- a/StrategyLibs/FACEBYBLADE.lua +++ b/StrategyLibs/FACEBYBLADE.lua @@ -260,7 +260,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar end local dRadialStepSpan = OptionalParameters.dRadialStepSpan local sUserNotes = OptionalParameters.sUserNotes or '' - local bCollisionCheckForDownUpOnly = OptionalParameters.bCollisionCheckForDownUpOnly or false + local bIsDicing = OptionalParameters.bIsDicing or false -- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato Cutting.dEdgeLength = EdgeToMachine.dLength @@ -275,7 +275,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar Cutting.nToolIndex = nToolIndex TIMER:startElapsed( 'GetBladeEngagement') - Cutting.bIsApplicable, Cutting.sBladeEngagement, Cutting.bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) + Cutting.bIsApplicable, Cutting.sBladeEngagement, Cutting.bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bIsDicing) TIMER:stopElapsed( 'GetBladeEngagement') -- utensile da cercare: si prende la lama migliore che può effettuare questo taglio, senza particolari analisi @@ -358,7 +358,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar -- lavorando dalla direzione opposta si verifica come se si lavorasse il lato opposto TIMER:startElapsed( 'GetBladeEngagement') - local bIsApplicableOpposite, sBladeEngagementOpposite, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) + local bIsApplicableOpposite, sBladeEngagementOpposite, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bIsDicing) TIMER:stopElapsed( 'GetBladeEngagement') -- taglio opposto non fattibile From 4bbadb8581ecfde56697bd01fe499b405a43b3ad Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Tue, 2 Dec 2025 10:27:59 +0100 Subject: [PATCH 14/17] - in MachiningLib miglioramenti a GetBladeEngagement --- LuaLibs/MachiningLib.lua | 61 ++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index c689c8e..dcf909b 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -287,33 +287,30 @@ end ------------------------------------------------------------------------------------------------------------- -- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp) -- TODO si dovrà decidere come tagliare anche se pezzo corto (il motore non deve ingombrare con il pinzaggio) --- valutare se restituire, se disponibili, entrambe le soluzioni e demandare la decisione alla FaceByBlade +-- TODO da gestire riduzione percorso function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachine, bIsDicing) - local sBladeEngagement = 'Standard' -- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci collisioni che fanno fallire il taglio + -- se cubetti si controlla solo asse Z e si passa subito al DownUp (ci sarebbe collisione con il materiale già rimosso) if not IsFaceZOutOfRange( Face.vtN, Tool) then - -- se cubetti si controlla solo asse Z (ci sarebbe collisione con il materiale già rimosso) - if bIsDicing then - local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + local bCollisionFound + local bMoveAfterSplitZ, bMoveAfterSplitC, bMoveAfterSplitAB - return not bCollisionFound, sBladeEngagement, bMoveAfterSplit + bCollisionFound, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + + if not ( bIsDicing or bCollisionFound) then + bCollisionFound, bMoveAfterSplitC = PreCollisionLib.CheckCollisionWithAxis( 'C', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) end - local bMoveAfterSplit = false - - local bCollisionFoundZ, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) - - local bCollisionFoundC, bMoveAfterSplitC = PreCollisionLib.CheckCollisionWithAxis( 'C', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) - - local bCollisionFoundAB, bMoveAfterSplitAB = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + if not ( bIsDicing or bCollisionFound) then + bCollisionFound, bMoveAfterSplitAB = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + end -- se nessuna collisione trovata si ritorna lavorazione fattibile, altrimenti si proseguirà al DownUp - if not ( bCollisionFoundZ or bCollisionFoundC or bCollisionFoundAB) then - if bMoveAfterSplitZ or bMoveAfterSplitC or bMoveAfterSplitAB then - bMoveAfterSplit = true - end + if not bCollisionFound then + local sBladeEngagement = 'Standard' + local bMoveAfterSplit = bMoveAfterSplitZ or bMoveAfterSplitC or bMoveAfterSplitAB return true, sBladeEngagement, bMoveAfterSplit end @@ -327,26 +324,28 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin return false end - local bCollisionFoundZ, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) - if bCollisionFoundZ then - return false + local bCollisionFound + local bMoveAfterSplitZ, bMoveAfterSplitC, bMoveAfterSplitAB + + bCollisionFound, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) + + if not bCollisionFound then + bCollisionFound, bMoveAfterSplitC = PreCollisionLib.CheckCollisionWithAxis( 'C', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) end - local bCollisionFoundC, bMoveAfterSplitC = PreCollisionLib.CheckCollisionWithAxis( 'C', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) - if bCollisionFoundC then - return false + if not bCollisionFound then + bCollisionFound, bMoveAfterSplitAB = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) end - local bCollisionFoundAB, bMoveAfterSplitAB = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) - if bCollisionFoundAB then - return false + -- se si è arrivati qui senza collisioni il DownUp è fattibile + if not bCollisionFound then + local sBladeEngagement = 'DownUp' + local bMoveAfterSplit = bMoveAfterSplitZ or bMoveAfterSplitC or bMoveAfterSplitAB + + return true, sBladeEngagement, bMoveAfterSplit end - -- se si è arrivati qui il DownUp è fattibile - sBladeEngagement = 'DownUp' - local bMoveAfterSplit = bMoveAfterSplitZ or bMoveAfterSplitC or bMoveAfterSplitAB - - return true, sBladeEngagement, bMoveAfterSplit + return false end ------------------------------------------------------------------------------------------------------------- From d6900a2c596f41e46feee392c8df6676023b9b10 Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Tue, 2 Dec 2025 15:59:53 +0100 Subject: [PATCH 15/17] =?UTF-8?q?Modifica=20a=20lettura=20parametri=20gene?= =?UTF-8?q?rali.=20Se=20il=20parametro=20non=20=C3=A8=20salvato=20in=20NGE?= =?UTF-8?q?=20si=20salta=20subito,=20altrimenti=20se=20fosse=20stato=20un?= =?UTF-8?q?=20boolean=20veniva=20messo=20a=20false.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LuaLibs/BeamLib.lua | 52 +++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index 33899e0..5a1d4c4 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -523,7 +523,7 @@ function BeamLib.GetPieceGeneralParameters( Part, DefaultGeneralParamList) GeneralParameters[DefaultGeneralParamList[i].sName] = xParameterValue end else - if GENERAL_PARAMETERS.BTL and GENERAL_PARAMETERS.BTL[Part.sBTLInfo] and GENERAL_PARAMETERS.BTL[Part.sBTLInfo][DefaultGeneralParamList[i].sName] ~= nil then + if GENERAL_PARAMETERS.BTL and GENERAL_PARAMETERS.BTL[Part.sBTLInfo] and GENERAL_PARAMETERS.BTL[Part.sBTLInfo][DefaultGeneralParamList[i].sName] then GeneralParameters[DefaultGeneralParamList[i].sName] = GENERAL_PARAMETERS.BTL[Part.sBTLInfo][DefaultGeneralParamList[i].sName] elseif GENERAL_PARAMETERS.PROJECT[DefaultGeneralParamList[i].sName] then GeneralParameters[DefaultGeneralParamList[i].sName] = GENERAL_PARAMETERS.PROJECT[DefaultGeneralParamList[i].sName] @@ -616,18 +616,21 @@ function BeamLib.LoadGeneralParametersInList( DefaultGeneralParamList) for i = 1, #DefaultGeneralParamList do local sParamNameNGE = DefaultGeneralParamList[i].sNameNge local xParameterValue = EgtGetInfo( idProjectInfo, sParamNameNGE, 's') or DefaultGeneralParamList[i].sValue - -- salvataggio dato su lista con accesso diretto - if DefaultGeneralParamList[i].sType == 'b' then - UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = xParameterValue == 'true' or xParameterValue == '1' or xParameterValue == true - elseif DefaultGeneralParamList[i].sType == 'd' then - if #DefaultGeneralParamList[i].sValue > 0 then - UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = tonumber( xParameterValue) - -- stringa vuota equivale a non passare alcun valore (deciderà la strategia) - else - UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = nil + -- se parametro non trovato si salta tutto. N.B. = I parametri progetto non dovrebbero mai essere nil + if xParameterValue then + -- salvataggio dato su lista con accesso diretto + if DefaultGeneralParamList[i].sType == 'b' then + UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = xParameterValue == 'true' or xParameterValue == '1' or xParameterValue == true + elseif DefaultGeneralParamList[i].sType == 'd' then + if #DefaultGeneralParamList[i].sValue > 0 then + UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = tonumber( xParameterValue) + -- stringa vuota equivale a non passare alcun valore (deciderà la strategia) + else + UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = nil + end + else --DefaultGeneralParamList[i].sType == 's' or DefaultGeneralParamList[i].sType == 'combo' + UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = xParameterValue end - else --DefaultGeneralParamList[i].sType == 's' or DefaultGeneralParamList[i].sType == 'combo' - UpdatedParameters.PROJECT[DefaultGeneralParamList[i].sName] = xParameterValue end end @@ -641,18 +644,21 @@ function BeamLib.LoadGeneralParametersInList( DefaultGeneralParamList) for i = 1, #DefaultGeneralParamList do local sParamNameNGE = DefaultGeneralParamList[i].sNameNge local xParameterValue = EgtGetInfo( BTLInfo[j], sParamNameNGE, 's') - -- salvataggio dato su lista con accesso diretto - if DefaultGeneralParamList[i].sType == 'b' then - UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = xParameterValue == 'true' or xParameterValue == '1' or xParameterValue == true - elseif DefaultGeneralParamList[i].sType == 'd' then - if #DefaultGeneralParamList[i].sValue > 0 then - UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = tonumber( xParameterValue) - -- stringa vuota equivale a non passare alcun valore (deciderà la strategia) - else - UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = nil + -- se parametro non trovato si salta tutto + if xParameterValue then + -- salvataggio dato su lista con accesso diretto + if DefaultGeneralParamList[i].sType == 'b' then + UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = xParameterValue == 'true' or xParameterValue == '1' or xParameterValue == true + elseif DefaultGeneralParamList[i].sType == 'd' then + if #DefaultGeneralParamList[i].sValue > 0 then + UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = tonumber( xParameterValue) + -- stringa vuota equivale a non passare alcun valore (deciderà la strategia) + else + UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = nil + end + else --DefaultGeneralParamList[i].sType == 's' or DefaultGeneralParamList[i].sType == 'combo' + UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = xParameterValue end - else --DefaultGeneralParamList[i].sType == 's' or DefaultGeneralParamList[i].sType == 'combo' - UpdatedParameters.BTL[BTLName][DefaultGeneralParamList[i].sName] = xParameterValue end end end From 68da716da1228e726b717867d4e8ed5ee85a5182 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Tue, 2 Dec 2025 16:44:51 +0100 Subject: [PATCH 16/17] - in MachiningLib e PreCollision correzioni per controllare collisione con grezzo nei cubetti --- LuaLibs/MachiningLib.lua | 10 +++++----- LuaLibs/PreCollisionLib.lua | 31 +++++++++++++------------------ 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index dcf909b..1111e81 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -291,7 +291,7 @@ end function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachine, bIsDicing) -- la normale della faccia permette di lavorare in modo standard, ma potrebbero esserci collisioni che fanno fallire il taglio - -- se cubetti si controlla solo asse Z e si passa subito al DownUp (ci sarebbe collisione con il materiale già rimosso) + -- se cubetti si controlla con pezzo solo asse Z e grezzo con tutti (ci sarebbe collisione con il materiale già rimosso controllando AB e C con pezzo) if not IsFaceZOutOfRange( Face.vtN, Tool) then local bCollisionFound @@ -299,12 +299,12 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin bCollisionFound, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) - if not ( bIsDicing or bCollisionFound) then - bCollisionFound, bMoveAfterSplitC = PreCollisionLib.CheckCollisionWithAxis( 'C', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + if not bCollisionFound then + bCollisionFound, bMoveAfterSplitC = PreCollisionLib.CheckCollisionWithAxis( 'C', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine, bIsDicing) end - if not ( bIsDicing or bCollisionFound) then - bCollisionFound, bMoveAfterSplitAB = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine) + if not bCollisionFound then + bCollisionFound, bMoveAfterSplitAB = PreCollisionLib.CheckCollisionWithAxis( 'AB', Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine, bIsDicing) end -- se nessuna collisione trovata si ritorna lavorazione fattibile, altrimenti si proseguirà al DownUp diff --git a/LuaLibs/PreCollisionLib.lua b/LuaLibs/PreCollisionLib.lua index 5101283..4f89a25 100644 --- a/LuaLibs/PreCollisionLib.lua +++ b/LuaLibs/PreCollisionLib.lua @@ -75,8 +75,8 @@ local function GetMachiningPoints( Edge, dDepthToMachine) end ------------------------------------------------------------------------------------------------------------- --- si controlla la collisione con il carro Z nei 3 piani principali dell'asse sAxis. Se c'è collisione in tutti i piani, l'asse sarà in collisione. -function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) +-- controllo collisione con verifica intersezione trimesh e geometrie da macchina +function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine, bCheckOnlyRestlength) -- se normale faccia non parallela a direzione testa c'è qualcosa che non va if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then @@ -102,7 +102,7 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P ToolExitPoints[i] = Point3d( MachiningPoints[i] + Edge.vtN * Tool.dDiameter / 2) + vtHead * EgtIf( bIsDownUp, ( Tool.dLength - Tool.dThickness), Tool.dLength) end - -- vtC punta sempre verso il corpo dell'asse C + -- vtC punta sempre verso il corpo dell'asse C o verso l'aggregato local vtEdge = Edge.ptEnd - Edge.ptStart vtEdge:normalize() local nSCC = Tool.SetupInfo.GetSCC( Edge.vtN, vtEdge, vtNFace) @@ -119,7 +119,6 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P local bMoveAfterSplit = false - -- nel singolo punto notevole si ha collisione se si trova intersezione in tutte le direzioni -- se almeno in un punto c'è collisione con il pezzo si ritorna collisione -- se non si trova collisione si ritorna se è necessario separare prima di effettuare la lavorazione (ossia non c'è collisione con il pezzo ma c'è con il grezzo restante) for i = 1, #ToolExitPoints do @@ -152,30 +151,26 @@ function PreCollisionLib.CheckCollisionWithAxis( sAxis, Edge, vtNFace, vtHead, P -- check collisione con pezzo local bCollisionFoundPiece = false - - bCollisionFoundPiece = EgtTestSurfaceSurface( Part.idBoxTm, idCollisionSurfTm, BeamData.COLL_SIC) - if not type( bCollisionFoundPiece) == "boolean" then - error( 'EgtTestSurfaceSurface fail') - end - - if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then - EgtSetColor( idCollisionSurfTm, RED()) + if not bCheckOnlyRestlength then + bCollisionFoundPiece = EgtTestSurfaceSurface( Part.idBoxTm, idCollisionSurfTm, BeamData.COLL_SIC) + if not type( bCollisionFoundPiece) == "boolean" then + error( 'EgtTestSurfaceSurface fail') + end + if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then + EgtSetColor( idCollisionSurfTm, RED()) + end end -- check collisione con grezzo restante, se con il pezzo non c'è collisione - local bCollisionFoundRestLength = false if not bCollisionFoundPiece then local idRestLengthSurfFr = GetRestlengthSurfTm( Part) - - bCollisionFoundRestLength = EgtTestSurfaceSurface( idRestLengthSurfFr, idCollisionSurfTm, BeamData.COLL_SIC) + local bCollisionFoundRestLength = EgtTestSurfaceSurface( idRestLengthSurfFr, idCollisionSurfTm, BeamData.COLL_SIC) if not type( bCollisionFoundRestLength) == "boolean" then error( 'EgtTestSurfaceSurface fail') end - if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then EgtSetColor( idCollisionSurfTm, ORANGE()) end - if bCollisionFoundRestLength then bMoveAfterSplit = true end @@ -193,7 +188,7 @@ end ------------------------------------------------------------------------------------------------------------- -- nel piano perpendicolare alla direzione di taglio, se c'è intersezione tra motore e trave c'è collisione --- TODO da integrare in funzione sopra +-- ATTENZIONE NON PIU' USATA, verificare ed eliminare function PreCollisionLib.CheckCollisionAxisAB( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine) -- se direzione utensile parallela ad uno degli assi principali non serve alcuna verifica From fa1a12b41cd0e803eaca8852bbb5701be914c35a Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Tue, 2 Dec 2025 17:06:55 +0100 Subject: [PATCH 17/17] - in HEADCUT correzione --- Strategies/Standard/HEADCUT/HEADCUT.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Strategies/Standard/HEADCUT/HEADCUT.lua b/Strategies/Standard/HEADCUT/HEADCUT.lua index 30d9383..183ce4e 100644 --- a/Strategies/Standard/HEADCUT/HEADCUT.lua +++ b/Strategies/Standard/HEADCUT/HEADCUT.lua @@ -66,10 +66,11 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters) end local MachiningsToAdd = {} - local bExecutePrecutOnly = Part.dHeadOverMaterial < 20 + local bExecutePrecutOnly = false -- se abilitato, faccio tagli di PRECUT a zero (come SPLIT) if Strategy.Parameters.bExecutePreCut then - + bExecutePrecutOnly = Part.dHeadOverMaterial < 20 + if Strategy.SplitStrategy and #Strategy.SplitStrategy > 0 then for i = 1, #Strategy.SplitStrategy do local TempList = {}