286 lines
11 KiB
Lua
286 lines
11 KiB
Lua
-- PreSimulationLib.lua by Egalware s.r.l. 2025/11/24
|
|
-- Libreria stima collisioni per travi
|
|
|
|
-- Tabella per definizione modulo
|
|
local PreSimulationLib = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local BeamLib = require( 'BeamLib')
|
|
local BeamData = require( 'BeamDataNew')
|
|
|
|
-- Carico i dati globali
|
|
|
|
|
|
EgtOutLog( ' PreSimulationLib 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
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function CheckCollisionPoint( ptPointToCheck, vtC, vtHead, PreCollisionData, Part, bCheckOnlyRestlength)
|
|
|
|
local ptPivot = GetGlobalPivot( ptPointToCheck, 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
|
|
|
|
-- se trovata collisione con pezzo è inutile procedere con il grezzo
|
|
if bCollisionFoundPiece then
|
|
return true
|
|
end
|
|
end
|
|
|
|
-- check collisione con grezzo restante, se con il pezzo non c'è collisione
|
|
local bCollisionFoundRestLength = false
|
|
if not bCollisionFoundPiece then
|
|
local idRestLengthSurfFr = GetRestlengthSurfTm( Part)
|
|
bCollisionFoundRestLength = EgtTestSurfaceSurface( idRestLengthSurfFr, idCollisionSurfTm, BeamData.COLL_SIC)
|
|
if not type( bCollisionFoundRestLength) == "boolean" then
|
|
error( 'EgtTestSurfaceSurface fail')
|
|
end
|
|
if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then
|
|
EgtSetColor( idCollisionSurfTm, ORANGE())
|
|
end
|
|
end
|
|
|
|
return false, bCollisionFoundRestLength
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- controllo collisione con verifica intersezione trimesh e geometrie da macchina
|
|
function PreSimulationLib.CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParameters)
|
|
|
|
-- parametri obbligatori
|
|
local Edge = MachiningParameters.Edge
|
|
local vtNFace = MachiningParameters.vtNFace
|
|
local vtHead = MachiningParameters.vtHead
|
|
local Part = MachiningParameters.Part
|
|
local Tool = MachiningParameters.Tool
|
|
local dDepthToMachine = MachiningParameters.dDepthToMachine
|
|
|
|
-- parametri opzionali
|
|
OptionalParameters = OptionalParameters or {}
|
|
local bCheckOnlyRestlength = OptionalParameters.bCheckOnlyRestlength or false
|
|
|
|
-- 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 = OptionalParameters.MachiningPoints or 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
|
|
vtC:normalize()
|
|
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 bCollisionFoundPiece, bCollisionFoundRestLength = CheckCollisionPoint( ToolExitPoints[i], vtC, vtHead, PreCollisionData, Part, bCheckOnlyRestlength)
|
|
|
|
-- se trovata collisione con pezzo è inutile controllare gli altri punti
|
|
if bCollisionFoundPiece then
|
|
|
|
return true
|
|
|
|
-- se trovata collisione con grezzo si setta che la lavorazione è da fare dopo separazione e si prosegue con gli altri punti
|
|
elseif bCollisionFoundRestLength then
|
|
|
|
bMoveAfterSplit = 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 PreSimulationLib.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 PreSimulationLib |