- funzioni di precollisione lama spostate in libreria apposita PreCollisionLib

- calcolo tempo esecuzione migliorato (TimeLib e riferimenti)
- idTempGroup ora è scritto nel Part per evitare di ricercarlo ogni volta
This commit is contained in:
luca.mazzoleni
2025-11-25 15:19:09 +01:00
parent 06a73a069f
commit 74a12a4a42
12 changed files with 368 additions and 287 deletions
+10 -218
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)
@@ -283,218 +284,6 @@ local function IsFaceZOutOfRange( vtNFace, Tool)
return false
end
-------------------------------------------------------------------------------------------------------------
--
local function CheckCollisionAxisC( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine)
end
-------------------------------------------------------------------------------------------------------------
-- si controlla la collisione con il carro Z nei 3 piani globali X, Y e Z. Se c'è collisione in tutti i piani, il carro sarà in collisione.
local function CheckCollisionAxisZ( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine)
-- se faccia non parallela a direzione testa c'è qualcosa che non va
if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then
error( 'CheckCollisionAxisZ : invalid directions')
end
-- TODO rimettere
-- se direzione utensile parallela ad uno degli assi principali non serve alcuna verifica
-- if AreSameOrOppositeVectorApprox( Edge.vtN, X_AX())
-- or AreSameOrOppositeVectorApprox( Edge.vtN, Y_AX())
-- or AreSameOrOppositeVectorApprox( Edge.vtN, Z_AX()) then
-- return false
-- end
local idTempGroup = BeamLib.GetTempGroup()
-- punti notevoli della lavorazione in cui fare il check
-- TODO aggiungere anche ptMid?
local MachiningPoints = {
Point3d( Edge.ptStart) + Edge.vtN * ( Edge.dElevation - dDepthToMachine),
Point3d( Edge.ptEnd) + Edge.vtN * ( Edge.dElevation - dDepthToMachine)
}
-- punti in centro lama su naso mandrino o aggregato. In base a direzione e punto
local bIsDownUp = AreOppositeVectorApprox( vtNFace, vtHead)
local ToolExitPoints = {}
for i = 1, #MachiningPoints do
ToolExitPoints[i] = Point3d( MachiningPoints[i] + Edge.vtN * Tool.dDiameter / 2) + vtHead * EgtIf( bIsDownUp, ( Tool.dLength - Tool.dThickness), Tool.dLength)
end
-- direzioni in cui fare il check
-- TODO queste cambieranno in base all'asse da controllare
local CheckDirections = {
{ vtDirectionX = X_AX(), vtDirectionY = Z_AX(), vtDirectionZ = -Y_AX(), sDirectionName = 'X'},
{ vtDirectionX = Y_AX(), vtDirectionY = Z_AX(), vtDirectionZ = X_AX(), sDirectionName = 'Y'},
{ vtDirectionX = X_AX(), vtDirectionY = Y_AX(), vtDirectionZ = Z_AX(), sDirectionName = 'Z'}
}
-- TEST
local Color = Color3d( math.random(0, 255), math.random(0, 255), math.random(0, 255))
-- TEST
for i = 1, #CheckDirections do
local vtDirectionX = CheckDirections[i].vtDirectionX
local vtDirectionZ = CheckDirections[i].vtDirectionZ
local sDirectionName = CheckDirections[i].sDirectionName
-- costruzione flat region del pezzo nel piano scelto
-- si estrae prima la silhouette nel piano
local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( Part.idBoxTm, vtDirectionZ, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB)
-- se più curve c'è qualcosa che non va: errore
if nCurveCount > 1 then
error( 'CheckCollisionAxisZ : error in part box')
end
-- creazione flat region dalla silhouette
local idPartSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve)
-- costruzione flat region del grezzo restante nel piano scelto (con leggera sovrapposizione)
-- si costruisce il box in globale
local ptRestLengthMax = Point3d( Part.b3Part:getMin()) + X_AX() * 500 * GEO.EPS_SMALL
local ptRestLengthMin = Point3d( Part.b3Part:getMin():getX() - 2000, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
local b3RestLength = BBox3d( ptRestLengthMin, ptRestLengthMax)
-- si crea la trimesh dal box
local idRestLengthBoxTm = EgtSurfTmBBox( idTempGroup, b3RestLength , false, GDB_RT.GLOB)
-- si estrae la silhouette nel piano
idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( idRestLengthBoxTm, vtDirectionZ, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB)
-- se più curve c'è qualcosa che non va: errore
if nCurveCount > 1 then
error( 'CheckCollisionAxisZ : error in part box')
end
-- creazione flat region dalla silhouette
local idRestLengthSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve)
-- costruzione flat region del carro Z nel piano scelto, tra punto iniziale e finale lavorazione
-- recupero punti da macchina per costruire flat region
local ZAxisPoints = Tool.SetupInfo.GetAxisZPoints( sDirectionName)
-- per ogni punto in cui controllare si crea una flat region (al momento solo 2, altrimenti la ruled)
local CollisionCurves = {}
for j = 1, #ToolExitPoints do
-- curva di collisione in riferimento locale
local idCollisionCurve = EgtCurveCompoFromPoints( idTempGroup, ZAxisPoints)
table.insert( CollisionCurves, idCollisionCurve)
-- TEST
EgtSetColor( idCollisionCurve, Color)
-- TEST
-- calcolo pivot in riferimento globale
local ptRef = ToolExitPoints[j]
local frTool = Frame3d( ptRef, vtHead, Edge.vtN)
-- TODO vtPivotGlob dovrà arrivare da funzione perchè può cambiare con SCC (es: aggregato)
local vtPivotGlob = Vector3d( Tool.SetupInfo.vtPivot)
vtPivotGlob:toGlob( frTool)
local ptPivot = ptRef + vtPivotGlob
EgtPoint( idTempGroup, ptPivot, 0)
-- curva in riferimento globale
local frReference = Frame3d( ptPivot, vtDirectionZ, vtDirectionX)
EgtTransform( idCollisionCurve, frReference, GDB_RT.GLOB )
end
-- TODO serve fare la ruled o basta controllare nei punti estremi?
--EgtSurfTmRuled( idTempGroup, CollisionCurves[1], CollisionCurves[2])
end
end
-------------------------------------------------------------------------------------------------------------
-- nel piano perpendicolare alla direzione di taglio, se c'è intersezione tra motore e trave c'è collisione
-- TODO da integrare in funzione sopra
local function CheckCollisionAxisAB( Edge, vtNFace, vtHead, Part, Tool, dDepthToMachine)
-- se direzione utensile parallela ad uno degli assi principali non serve alcuna verifica
if AreSameOrOppositeVectorApprox( Edge.vtN, X_AX())
or AreSameOrOppositeVectorApprox( Edge.vtN, Y_AX())
or AreSameOrOppositeVectorApprox( Edge.vtN, Z_AX()) then
return false
end
local idTempGroup = BeamLib.GetTempGroup()
-- riferimento perpendicolare al taglio, X nel verso della normale al lato e Y verso il motore
local ptMachining = Point3d( ( Edge.ptStart + Edge.ptEnd) / 2) + Edge.vtN * ( Edge.dElevation - dDepthToMachine)
local vtEdge = Edge.ptEnd - Edge.ptStart
vtEdge:normalize()
-- costruzione flat region del pezzo nel piano perpendicolare al taglio
-- si estrae prima la silhouette nel piano
local idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( Part.idBoxTm, vtEdge, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB)
-- se più curve c'è qualcosa che non va: errore
if nCurveCount > 1 then
error( 'Check2DBladeCollision : error in part box')
end
-- creazione flat region dalla silhouette
local idPartSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve)
-- costruzione flat region del grezzo restante nel piano perpendicolare al taglio (con leggera sovrapposizione)
-- si costruisce il box in globale
local ptRestLengthMax = Point3d( Part.b3Part:getMin() + X_AX() * 500 * GEO.EPS_SMALL)
local ptRestLengthMin = Point3d( Part.b3Part:getMin():getX() - 2000, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
local b3RestLength = BBox3d( ptRestLengthMin, ptRestLengthMax)
-- si crea la trimesh dal box
local idRestLengthBoxTm = EgtSurfTmBBox( idTempGroup, b3RestLength , false, GDB_RT.GLOB)
-- si estrae la silhouette nel piano
idFirstCurve, nCurveCount = EgtGetSurfTmSilhouette( idRestLengthBoxTm, vtEdge, 10 * GEO.EPS_SMALL, idTempGroup, GDB_RT.GLOB)
-- se più curve c'è qualcosa che non va: errore
if nCurveCount > 1 then
error( 'Check2DBladeCollision : error in part box')
end
-- creazione flat region dalla silhouette
local idRestLengthSurfFr = EgtSurfFlatRegion( idTempGroup, idFirstCurve)
-- costruzione flat region approssimata del motore nel piano perpendicolare al taglio
-- punto di congiunzione tra motore e lama
local ptMaxElev = ptMachining + Edge.vtN * Tool.dMaxMaterial
-- se taglio standard (no DownUp) il punto va spostato dello spessore lama
if AreSameVectorApprox( vtNFace, vtHead) then
ptMaxElev = ptMaxElev + vtNFace * Tool.dThickness
end
-- TODO qui sostituire con il valore reale letto dal SetupInfo
-- per Fast si dovrà aggiungere la lunghezza del massimo utensile utilizzabile con lama
local dHeadDepth = 480
local dHeadWidth = 480
local ptOpposite = ptMaxElev + Edge.vtN * dHeadWidth
local ptCross = ptOpposite + vtHead * dHeadDepth
local idHeadRectangle = EgtRectangle3P( idTempGroup, ptMaxElev, ptCross, ptOpposite, GDB_RT.GLOB)
-- flat region dal rettangolo
local idHeadSurfFr = EgtSurfFlatRegion( idTempGroup, idHeadRectangle)
-- intersezione tra pezzo e motore (se fallisce si inverte la flat region del motore, probabile normale opposta)
local bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr)
if not bIntersectSuccess then
EgtInvertSurf( idHeadSurfFr)
bIntersectSuccess = EgtSurfFrIntersect( idPartSurfFr, idHeadSurfFr)
end
if not bIntersectSuccess then
error( 'Check2DBladeCollision : intersect fail')
end
local bCollisionFoundPiece = EgtExistsObj( idPartSurfFr)
-- intersezione tra grezzo restante e motore, se con il pezzo non c'è collisione
local bCollisionFoundRestLength
if not bCollisionFoundPiece then
bIntersectSuccess = EgtSurfFrIntersect( idRestLengthSurfFr, idHeadSurfFr)
if not bIntersectSuccess then
EgtInvertSurf( idHeadSurfFr)
bIntersectSuccess = EgtSurfFrIntersect( idRestLengthSurfFr, idHeadSurfFr)
end
if not bIntersectSuccess then
error( 'Check2DBladeCollision : intersect fail')
end
bCollisionFoundRestLength = EgtExistsObj( idRestLengthSurfFr)
end
return bCollisionFoundPiece, bCollisionFoundRestLength
end
-------------------------------------------------------------------------------------------------------------
-- ritorna se la faccia e il lato sono lavorabili e, se sì, il modo di lavorare (standard/DownUp)
-- TODO si dovrà decidere come tagliare anche se pezzo corto (il motore non deve ingombrare con il pinzaggio)
@@ -507,9 +296,12 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin
-- TODO La riduzione percorso cambia questo test?
-- TODO da completare questo test
local bCollisionFoundZ, bMoveAfterSplitZ = CheckCollisionAxisZ( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine)
-- TODO rimuovere timer qua
TIMER:startElapsed( 'CollisionZ')
local bCollisionFoundZ, bMoveAfterSplitZ = PreCollisionLib.CheckCollisionAxisZ( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine)
TIMER:stopElapsed( 'CollisionZ')
local bCollisionFound, bMoveAfterSplit = CheckCollisionAxisAB( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine)
local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionAxisAB( Edge, Face.vtN, Face.vtN, Part, Tool, dDepthToMachine)
if bCollisionCheckForDownUpOnly or not bCollisionFound then
return true, sBladeEngagement, bMoveAfterSplit
@@ -535,7 +327,7 @@ function MachiningLib.GetBladeEngagement( Face, Edge, Part, Tool, dDepthToMachin
end
-- orientamento faccia / utensile compatibili con DownUp: lavorabile
local bCollisionFound, bMoveAfterSplit = CheckCollisionAxisAB( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine)
local bCollisionFound, bMoveAfterSplit = PreCollisionLib.CheckCollisionAxisAB( Edge, Face.vtN, -Face.vtN, Part, Tool, dDepthToMachine)
if not bCollisionFound then
sBladeEngagement = 'DownUp'
@@ -714,9 +506,9 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
if bIsToolCompatible then
if FaceToMachine and EdgeToMachine and Part and dElevation then
local bIsBladeOk = false
TIMER:setCheckpoint( 'GetBladeEngagement')
TIMER:startElapsed( 'GetBladeEngagement')
bIsBladeOk, sCurrentBladeEngagement, bCurrentMoveAfterSplit = MachiningLib.GetBladeEngagement( FaceToMachine, EdgeToMachine, Part, TOOLS[i], dElevation, bCollisionCheckForDownUpOnly)
TIMER:logElapsed( 'GetBladeEngagement')
TIMER:stopElapsed( 'GetBladeEngagement')
-- orientamento non raggiungibile
if not bIsBladeOk then
bIsToolCompatible = false
@@ -1597,7 +1389,7 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
local ProcTm = FeatureLib.GetProcFromTrimesh( Machining.Geometry[1][1], Part)
local dDepthToMachine = min( ProcTm.Faces[Machining.Geometry[1][2] + 1].dElevation, ( Machining.dMaxElev or ProcTm.Faces[Machining.Geometry[1][2] + 1].dElevation)) - ( max( 0, Machining.dResidualDepth or 0))
local nSteps = max( ceil( ( dDepthToMachine - 50 * GEO.EPS_SMALL) / TOOLS[Machining.nToolIndex].dStep), 1)
local idTempGroup = BeamLib.GetTempGroup()
local idTempGroup = Part.idTempGroup
-- TODO in futuro creare flatregion (se ci fossero isole il calcolo del percorso non sarebbe corretto)
local idFaceContour = EgtExtractSurfTmFacetLoops( ProcTm.id, Machining.Geometry[1][2], idTempGroup)
-- si settano i lati aperti della curva derivata dalla superficie