Merge branch 'CuttingImprovements' into develop

This commit is contained in:
luca.mazzoleni
2025-12-02 17:07:06 +01:00
17 changed files with 546 additions and 208 deletions
+19 -4
View File
@@ -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 >>>')
+9 -30
View File
@@ -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
+52 -23
View File
@@ -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
+1 -1
View File
@@ -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
-12
View File
@@ -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
+1 -1
View File
@@ -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')
+43 -120
View File
@@ -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
+256
View File
@@ -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
+122
View File
@@ -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
-2
View File
@@ -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 = {}
+21 -3
View File
@@ -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
+3 -2
View File
@@ -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 = {}
+1 -1
View File
@@ -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
+1
View File
@@ -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
+1 -1
View File
@@ -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)
+4 -3
View File
@@ -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)
+12 -5
View File
@@ -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()))