diff --git a/BatchProcessNew.lua b/BatchProcessNew.lua index 5bcbf0b..5a45f9b 100644 --- a/BatchProcessNew.lua +++ b/BatchProcessNew.lua @@ -58,11 +58,14 @@ _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 -- 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 +181,13 @@ local function WriteResultToJson( RESULT) end ------------------------------------------------------------------------------------------------------------- + +-- calcolo tempo esecuzione +TIMER:start() +EgtOutLog( ' Execution timer started') + +-- script principale + local sFlag = '' if BEAM.FLAG == 0 then sFlag = 'GENERATE' @@ -443,6 +453,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 @@ -614,6 +627,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 @@ -675,15 +689,11 @@ if bToProcess then -- TODO gestire errori e messaggi di ritorno in questo caso 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) local sOutput = '' @@ -785,6 +795,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 31d2d72..5c78146 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 = {} @@ -348,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) @@ -493,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) .. ')' @@ -1195,10 +1203,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 +1250,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 +1565,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/BeamLib.lua b/LuaLibs/BeamLib.lua index 5719ac6..5a1d4c4 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 @@ -424,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) @@ -500,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] @@ -593,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 @@ -618,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 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/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/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 0752e39..1111e81 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) @@ -269,7 +270,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 @@ -283,143 +284,63 @@ local function IsFaceZOutOfRange ( vtNFace, Tool) return false 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. - - -------------------------------------------------------------------------------------------------------------- --- 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) - - -- 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 - -- 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 in base a lavorazione di coda (spostare dopo separazione?) o 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' +-- TODO si dovrà decidere come tagliare anche se pezzo corto (il motore non deve ingombrare con il pinzaggio) +-- TODO da gestire riduzione percorso +function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachine, bIsDicing) - -- 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 + -- 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 - - -- 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) - if bCollisionCheckForDownUpOnly or not bCollisionFound then + + 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, bIsDicing) + end + + 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 + if not bCollisionFound then + local sBladeEngagement = 'Standard' + local bMoveAfterSplit = bMoveAfterSplitZ or bMoveAfterSplitC or bMoveAfterSplitAB 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 - -- 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 + local bCollisionFound + local bMoveAfterSplitZ, bMoveAfterSplitC, bMoveAfterSplitAB - if Tool.SetupInfo.HeadType.bTop and bIsToolBelowWorkpiece - or ( Tool.SetupInfo.HeadType.bBottom and bIsToolAboveWorkpiece) then + bCollisionFound, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionWithAxis( 'Z', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) - return false + if not bCollisionFound then + bCollisionFound, bMoveAfterSplitC = PreCollisionLib.CheckCollisionWithAxis( 'C', Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine) end - -- orientamento faccia / utensile compatibili con DownUp: lavorabile - local bCollisionFound, bMoveAfterSplit = Check2DBladeCollision( 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) + end - sBladeEngagement = 'DownUp' + -- 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 @@ -570,7 +491,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 @@ -595,7 +516,9 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters) if bIsToolCompatible then if FaceToMachine and EdgeToMachine and Part and dElevation then local bIsBladeOk = false - bIsBladeOk, sCurrentBladeEngagement, bCurrentMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bCollisionCheckForDownUpOnly) + TIMER:startElapsed( 'GetBladeEngagement') + bIsBladeOk, sCurrentBladeEngagement, bCurrentMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bIsDicing) + TIMER:stopElapsed( 'GetBladeEngagement') -- orientamento non raggiungibile if not bIsBladeOk then bIsToolCompatible = false @@ -1476,7 +1399,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..4f89a25 --- /dev/null +++ b/LuaLibs/PreCollisionLib.lua @@ -0,0 +1,256 @@ +-- PreCollisionLib.lua by Egalware s.r.l. 2025/11/24 +-- Libreria stima collisioni per travi + +-- Tabella per definizione modulo +local PreCollisionLib = {} + +-- Include +require( 'EgtBase') +local BeamLib = require( 'BeamLib') +local BeamData = require( 'BeamData') + +-- Carico i dati globali + + +EgtOutLog( ' PreCollisionLib started', 1) + + +------------------------------------------------------------------------------------------------------------- +-- 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 + 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) + + return idRestLengthBoxTm +end + +------------------------------------------------------------------------------------------------------------- +-- calcolo pivot in riferimento globale +local function GetGlobalPivot( ptRef, vtC, vtHead, vtMovePivot) + + -- frame solidale all'utensile (lo stesso in cui vtMovePivot è definito) + local frTool = Frame3d( ptRef, vtHead, vtC) + local vtMovePivotGlob = Vector3d( vtMovePivot) + vtMovePivotGlob:toGlob( frTool) + local ptPivot = ptRef + vtMovePivotGlob + + 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 not bIsEdgeParallelToMainDirection then + table.insert( MachiningPoints, ptStart) + end + table.insert( MachiningPoints, ptMid) + if not bIsEdgeParallelToMainDirection then + table.insert( MachiningPoints, ptEnd) + end + + return MachiningPoints +end + +------------------------------------------------------------------------------------------------------------- +-- 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 + error( 'CheckCollisionWithAxis : 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 = GetMachiningPoints( Edge, 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 + + -- 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) + local vtSCC = BeamLib.GetDirectionFromSCC( nSCC) + 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, vtC, vtHead) + + local bMoveAfterSplit = false + + -- 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 + + local ptPivot = GetGlobalPivot( ToolExitPoints[i], vtC, vtHead, PreCollisionData.vtMovePivot) + + -- 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 + + -- check collisione con pezzo + local bCollisionFoundPiece = false + 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 + if not bCollisionFoundPiece then + local idRestLengthSurfFr = GetRestlengthSurfTm( Part) + 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 + end + + -- se trovata collisione con pezzo si esce subito + if bCollisionFoundPiece then + return true + end + end + + -- se si arriva qui significa che non è stata trovata alcuna collisione con pezzo + return false, bMoveAfterSplit +end + +------------------------------------------------------------------------------------------------------------- +-- nel piano perpendicolare alla direzione di taglio, se c'è intersezione tra motore e trave c'è collisione +-- 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 + 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 + 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 + bCollisionFoundRestLength = not EgtSurfFrTestExternal( idRestlengthSurfFr, idHeadSurfFr) + end + + return bCollisionFoundPiece, bCollisionFoundRestLength +end + + + + + + + + + + + + + + + + + +return PreCollisionLib \ No newline at end of file diff --git a/LuaLibs/TimeLib.lua b/LuaLibs/TimeLib.lua new file mode 100644 index 0000000..b4ea056 --- /dev/null +++ b/LuaLibs/TimeLib.lua @@ -0,0 +1,122 @@ +-- 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 TimeLibInstance = setmetatable({}, TimeLib) + TimeLibInstance.dStartTime = os.clock() + TimeLibInstance.Measurements = {} + return TimeLibInstance +end + +-- reset entire timer +function TimeLib:start() + self.dStartTime = os.clock() + self.Measurements = {} +end + +-- start elapsed measurement for a specific name +function TimeLib:startElapsed(sName) + local sMeasurementName = sName or "Default" + local dNow = os.clock() + + 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 + +-- 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 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 + +-- reset elapsed for a specific measurement +function TimeLib:resetElapsed(sName) + local sMeasurementName = sName or "Default" + self.Measurements[sMeasurementName] = nil +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/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..0bf3bb8 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') @@ -46,11 +46,14 @@ _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 -- 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. @@ -300,8 +303,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) @@ -348,6 +349,7 @@ local function MyProcessFeatures() end -- cancello gruppo temporaneo + local idTempGroup = BeamLib.GetTempGroup() EgtErase( idTempGroup) if #sOutput > 0 then EgtOutLog( sOutput) end @@ -365,11 +367,21 @@ end ------------------------------------------------------------------------------------------------------------- -- *** Esecuzione *** ------------------------------------------------------------------------------------------------------------- + +-- calcolo tempo esecuzione +TIMER:start() +EgtOutLog( ' Execution timer started') + +-- script principale + 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 @@ -378,3 +390,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/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 = {} 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/STR0006/STR0006.lua b/Strategies/Standard/STR0006/STR0006.lua index 1be5fe3..31c4c1d 100644 --- a/Strategies/Standard/STR0006/STR0006.lua +++ b/Strategies/Standard/STR0006/STR0006.lua @@ -74,6 +74,7 @@ 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 (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 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 8226c12..55885c7 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,7 +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:startElapsed( 'GetBladeEngagement') local bIsApplicableOpposite = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[ToolInfo.nToolIndex], dDepthToMachine) + TIMER:stopElapsed( 'GetBladeEngagement') if not bIsApplicableOpposite then return CuttingParametersList, EdgeToMachine end @@ -896,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) @@ -1045,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 0d3b71c..3cc51fa 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 @@ -260,10 +260,11 @@ 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 + -- TODO questa deve essere ptEnd - ptStart Cutting.vtEdgeDirection = EdgeToMachine.vtN ^ FaceToMachine.vtN Cutting.vtToolDirection = EdgeToMachine.vtN Cutting.ptEdge1, Cutting.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd @@ -273,7 +274,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if nToolIndex then Cutting.nToolIndex = nToolIndex - Cutting.bIsApplicable, Cutting.sBladeEngagement, Cutting.bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) + TIMER:startElapsed( 'GetBladeEngagement') + 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 else @@ -354,7 +357,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 - local bIsApplicableOpposite, sBladeEngagementOpposite, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bCollisionCheckForDownUpOnly) + TIMER:startElapsed( 'GetBladeEngagement') + local bIsApplicableOpposite, sBladeEngagementOpposite, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineOpposite, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine, bIsDicing) + TIMER:stopElapsed( 'GetBladeEngagement') -- taglio opposto non fattibile if not bIsApplicableOpposite then @@ -449,7 +454,9 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar if OppositeToolDirectionMode == 'Enabled' then EdgeToMachineForEngagement = EdgeToMachineOpposite end + TIMER:startElapsed( 'GetBladeEngagement') local bIsApplicable, sBladeEngagement, bMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachineForEngagement, Part, TOOLS[Cutting.nToolIndex], dDepthToMachine) + 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 @@ -501,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()))