547 lines
24 KiB
Lua
547 lines
24 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')
|
|
|
|
EgtOutLog( ' PreSimulationLib started', 1)
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function GetMachineAxes()
|
|
|
|
local LinearAxes = {}
|
|
local RotativeAxes = {}
|
|
|
|
-- si recuperano tutti gli assi, lineari e rotativi
|
|
local AxesNames = EgtGetAllCurrAxesNames()
|
|
for i = 1, #AxesNames do
|
|
-- EgtGetAxisType restituisce vero se asse lineare, false se asse rotativo
|
|
if EgtGetAxisType( AxesNames[i]) then
|
|
LinearAxes[#LinearAxes + 1] = {}
|
|
LinearAxes[#LinearAxes].sName = AxesNames[i]
|
|
else
|
|
RotativeAxes[#RotativeAxes + 1] = {}
|
|
RotativeAxes[#RotativeAxes].sName = AxesNames[i]
|
|
end
|
|
end
|
|
|
|
return LinearAxes, RotativeAxes
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function LogOutstroke( sToolName, ptOnToolTipCenter, vtHead, OptionalParameters)
|
|
|
|
-- parametri opzionali
|
|
OptionalParameters = OptionalParameters or {}
|
|
local LinearAxesValues = OptionalParameters.LinearAxesValues
|
|
local RotativeAxesValues = OptionalParameters.RotativeAxesValues
|
|
|
|
-- gruppo per geometrie temporanee
|
|
local idTempGroup = BeamLib.GetTempGroup()
|
|
|
|
-- si disegnano punto e vettore
|
|
local idPoint = EgtPoint( idTempGroup, ptOnToolTipCenter, GDB_RT.GLOB)
|
|
local idVector = EgtVector( idTempGroup, vtHead, ptOnToolTipCenter, GDB_RT.GLOB)
|
|
EgtSetColor( idPoint, RED())
|
|
EgtSetColor( idVector, RED())
|
|
|
|
-- nome utensile
|
|
EgtOutLog( 'Tool ' .. sToolName)
|
|
|
|
-- si loggano valori di punto e vettore
|
|
EgtOutLog( ' Presimulation : OutStroke, Tip Point = ' .. tostring( ptOnToolTipCenter) .. ', id = ' .. idPoint .. ', vtHead = ' .. tostring( vtHead) .. ', id = ' .. idVector)
|
|
|
|
-- se disponibili, si loggano anche i valori calcolati degli assi
|
|
if LinearAxesValues then
|
|
EgtOutLog( ' ' .. 'Lin1' .. ' = ' .. tostring( LinearAxesValues[1]) .. ', ' .. 'Lin2' .. ' = ' .. tostring( LinearAxesValues[2]) .. ', ' .. 'Lin3' .. ' = ' .. tostring( LinearAxesValues[3]))
|
|
end
|
|
if RotativeAxesValues then
|
|
EgtOutLog( ' ' .. 'Rot1' .. ' = ' .. tostring( RotativeAxesValues[1]) .. ', ' .. 'Rot2' .. ' = ' .. tostring( RotativeAxesValues[2]) .. ', ' .. 'Rot3' .. ' = ' .. tostring( RotativeAxesValues[3]))
|
|
end
|
|
|
|
return
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- costruzione trimesh del grezzo restante in testa o in coda
|
|
local function GetRestlengthSurfTm( Part, sSide)
|
|
|
|
-- si costruisce il box in globale
|
|
local b3RestLength
|
|
if sSide == 'Head' then
|
|
local b3PartWithOvermaterial = BeamLib.GetPartBoxWithHeadTail( Part, sSide)
|
|
local ptStartRestLength = Point3d( Part.b3Part:getMax():getX(), Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
|
|
local ptEndRestLength = Point3d( b3PartWithOvermaterial:getMax():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
|
|
b3RestLength = BBox3d( ptStartRestLength, ptEndRestLength)
|
|
elseif sSide == 'Tail' then
|
|
local b3PartWithOvermaterial = BeamLib.GetPartBoxWithHeadTail( Part, sSide)
|
|
local dXMin = b3PartWithOvermaterial:getMin():getX()
|
|
-- si evita sempre di lavorare col motore dietro la coda della barra (potrebbe succedere con barra restante molto corta): in quel caso si deve sempre separare prima
|
|
dXMin = min( dXMin, Part.b3Part:getMin():getX() - 2000)
|
|
local ptStartRestLength = Point3d( Part.b3Part:getMin():getX(), Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
|
|
local ptEndRestLength = Point3d( dXMin, Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
|
|
b3RestLength = BBox3d( ptStartRestLength, ptEndRestLength)
|
|
-- caso non testato, non dovrebbe mai finire qui (il default che arriva da fuori è Tail)
|
|
else
|
|
return nil
|
|
end
|
|
|
|
-- si crea la trimesh dal box
|
|
local idRestLengthBoxTm = EgtSurfTmBBox( Part.idTempGroup, b3RestLength , false, GDB_RT.GLOB)
|
|
|
|
return idRestLengthBoxTm
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function PreSimulationLib.GetPointOnToolTipCenter( ptPointAtDepth, vtHead, vtNFace, vtToolOffset, Tool)
|
|
|
|
return ptPointAtDepth + vtToolOffset * Tool.dDiameter / 2 + vtNFace * EgtIf( AreSameVectorApprox( vtHead, vtNFace), 0, Tool.dThickness)
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- calcolo punto sull'uscita testa a partire dal punto di lavorazione o di attacco sul diametro utensile
|
|
local function GetToolExitPoint( ptMachining, vtNEdge, vtHead, Tool, bIsDownUp)
|
|
|
|
local ptToolExitPoint = Point3d( ptMachining + vtNEdge * Tool.dDiameter / 2) + vtHead * EgtIf( bIsDownUp, ( Tool.dLength - Tool.dThickness), Tool.dLength)
|
|
|
|
return ptToolExitPoint
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- calcolo pivot in riferimento globale, dati punto sull'uscita utensile e direzioni
|
|
local function GetGlobalPivot( ptToolExit, vtC, vtHead, vtMovePivot)
|
|
|
|
-- frame solidale all'utensile (lo stesso in cui vtMovePivot è definito)
|
|
local frTool = Frame3d( ptToolExit, vtHead, vtC)
|
|
local vtMovePivotGlob = Vector3d( vtMovePivot)
|
|
vtMovePivotGlob:toGlob( frTool)
|
|
local ptPivot = ptToolExit + vtMovePivotGlob
|
|
|
|
return ptPivot
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- restituisce i punti notevoli della lavorazioni in cui fare il controllo
|
|
local function GetCollisionPointsToCheck( Edge, dDepthToMachine)
|
|
|
|
local PointsToCheck = {}
|
|
|
|
-- 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 bIsEdgeParallelToMainDirection =
|
|
AreSameOrOppositeVectorApprox( Edge.vtEdge, X_AX())
|
|
or AreSameOrOppositeVectorApprox( Edge.vtEdge, Y_AX())
|
|
or AreSameOrOppositeVectorApprox( Edge.vtEdge, Z_AX())
|
|
|
|
-- aggiunta punti
|
|
table.insert( PointsToCheck, ptStart)
|
|
if not bIsEdgeParallelToMainDirection then
|
|
table.insert( PointsToCheck, ptMid)
|
|
end
|
|
table.insert( PointsToCheck, ptEnd)
|
|
|
|
return PointsToCheck
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function CheckOutOfStrokePoint( ptOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
|
|
|
-- impostazione utensile
|
|
local bOkTool = EgtSetCalcTool( Tool.sName, Tool.sHead, Tool.nExit)
|
|
if not bOkTool then
|
|
error( 'CheckOutOfStrokePoint : cannot set calc tool')
|
|
end
|
|
|
|
-- settaggio SCC per discriminare soluzioni multiple
|
|
EgtSetCalcSolCh( nSCC)
|
|
|
|
-- se presente, settaggio asse bloccato
|
|
if sBlockedAxis and type( sBlockedAxis) == "string" then
|
|
local BlockedAxis = EgtSplitString( sBlockedAxis, '=')
|
|
EgtSetRotAxisBlock( BlockedAxis[1], tonumber( BlockedAxis[2]))
|
|
end
|
|
|
|
-- calcolo assi rotativi
|
|
local bOkAngles, nSolutionsAngles, RotativeAxesValues = EgtGetCalcAnglesEx( vtHead, vtAux)
|
|
local dRotative1 = RotativeAxesValues[1]
|
|
local dRotative2 = RotativeAxesValues[2]
|
|
local dRotative3 = RotativeAxesValues[3]
|
|
|
|
if not bOkAngles then
|
|
error( ' CheckOutOfStrokePoint : error')
|
|
end
|
|
|
|
-- se nessuna soluzione dagli assi rotativi, è in extracorsa
|
|
if nSolutionsAngles == 0 then
|
|
|
|
if EgtGetDebugLevel() >= 3 then
|
|
LogOutstroke( Tool.sName, ptOnToolTipCenter, vtHead, { RotativeAxesValues = { dRotative1, dRotative2, dRotative3}})
|
|
end
|
|
return true
|
|
end
|
|
|
|
-- calcolo assi lineari
|
|
local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, dRotative1, dRotative2, dRotative3)
|
|
|
|
if not bOkPositions then
|
|
|
|
error( ' CheckOutOfStrokePoint : error')
|
|
end
|
|
|
|
-- verifica finecorsa per assi lineari (assi rotativi già verificati)
|
|
local bAllAxesInStroke = EgtVerifyOutstroke( dLinear1, dLinear2, dLinear3)
|
|
|
|
-- extracorsa
|
|
if not bAllAxesInStroke then
|
|
|
|
if EgtGetDebugLevel() >= 3 then
|
|
LogOutstroke( Tool.sName, ptOnToolTipCenter, vtHead, { LinearAxesValues = { dLinear1, dLinear2, dLinear3}, RotativeAxesValues = { dRotative1, dRotative2, dRotative3}})
|
|
end
|
|
return true
|
|
end
|
|
|
|
-- EgtSetAxisPos( 'T', dT)
|
|
-- EgtSetAxisPos( 'Y', dY)
|
|
-- EgtSetAxisPos( 'Z', dZ)
|
|
-- EgtSetAxisPos( 'C', dC1)
|
|
-- EgtSetAxisPos( 'A', dA1)
|
|
|
|
-- se si arriva qui, il punto non è in finecorsa
|
|
return false
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- check extracorsa da punti sul tip dell'utensile
|
|
function PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
|
|
|
for i = 1, #PointsOnToolTipCenter do
|
|
|
|
local bOutOfStroke = CheckOutOfStrokePoint( PointsOnToolTipCenter[i], vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
|
|
|
-- se trovato extracorsa inutile procedere con gli altri punti
|
|
if bOutOfStroke then
|
|
return true
|
|
end
|
|
end
|
|
|
|
-- se arrivati qui, nessun extracorsa
|
|
return false
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- check extracorsa da geometria
|
|
-- TODO da considerare anche gli attacchi
|
|
function PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeometry, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
|
|
|
local b3GeomMaxOffset = EgtGetBBoxGlob( idGeometry, GDB_BB.STANDARD)
|
|
local ptBoxCenter = b3GeomMaxOffset:getCenter()
|
|
local dBoxDimX = b3GeomMaxOffset:getDimX()
|
|
local dBoxDimY = b3GeomMaxOffset:getDimY()
|
|
local dBoxDimZ = b3GeomMaxOffset:getDimZ()
|
|
|
|
-- si controlla il finecorsa nei punti al centro delle 6 facce del box
|
|
local PointsOnToolTipCenter = {}
|
|
-- X+
|
|
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter + dBoxDimX / 2 * X_AX()))
|
|
-- X-
|
|
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter - dBoxDimX / 2 * X_AX()))
|
|
-- Y+
|
|
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter + dBoxDimY / 2 * Y_AX()))
|
|
-- Y-
|
|
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter - dBoxDimY / 2 * Y_AX()))
|
|
-- Z+
|
|
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter + dBoxDimZ / 2 * Z_AX()))
|
|
-- Z-
|
|
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter - dBoxDimZ / 2 * Z_AX()))
|
|
|
|
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
|
|
|
|
return bOutOfStroke
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function MoveMachineAxesToPosition( ptOnToolTipCenter, vtHead, vtAux)
|
|
|
|
-- calcolo assi rotativi
|
|
local bOkAngles, nSolutionsAngles, RotativeAxesValues = EgtGetCalcAnglesEx( vtHead, vtAux)
|
|
local dRotative1 = RotativeAxesValues[1]
|
|
local dRotative2 = RotativeAxesValues[2]
|
|
local dRotative3 = RotativeAxesValues[3]
|
|
|
|
if not bOkAngles then
|
|
error( ' MoveMachineAxesToPosition : error')
|
|
end
|
|
|
|
-- calcolo assi lineari
|
|
local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, dRotative1, dRotative2, dRotative3)
|
|
|
|
if not bOkPositions then
|
|
|
|
error( ' MoveMachineAxesToPosition : error')
|
|
end
|
|
|
|
local AxesNames = EgtGetAllCurrAxesNames()
|
|
local dTHome = EgtGetAxisHomePos( AxesNames[1])
|
|
|
|
-- spostamento assi in posizione (la T non si sposta perchè si sposta il pezzo)
|
|
EgtSetAxisPos( AxesNames[2], dLinear2)
|
|
EgtSetAxisPos( AxesNames[3], dLinear3)
|
|
EgtSetAxisPos( AxesNames[4], dRotative1)
|
|
EgtSetAxisPos( AxesNames[5], dRotative2)
|
|
if dRotative3 then
|
|
EgtSetAxisPos( AxesNames[6], dRotative3)
|
|
end
|
|
|
|
return dLinear1 - dTHome
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
local function CheckCollisionPoint( sAxis, ptOnToolTipCenter, vtHead, vtAux, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, bCheckOnlyRestlength)
|
|
|
|
-- spostamento assi macchina in posizione
|
|
local dDeltaXHeadOffset = MoveMachineAxesToPosition( ptOnToolTipCenter, vtHead, vtAux)
|
|
|
|
-- si recuperano gli id delle geometrie dell'asse con cui controllare la collisione
|
|
local idCollisionGroup = EgtGetFirstNameInGroup( EgtGetAxisId( sAxis), 'COLLISION')
|
|
local idCollisionGroupOther = EgtGetFirstNameInGroup( EgtGetAxisId( sAxis), 'OTHER_COLLISION') or GDB_ID.NULL
|
|
local CollisionGroupEntitiesId = EgtGetAllInGroup( idCollisionGroup)
|
|
local CollisionGroupOtherEntitiesId = EgtGetAllInGroup( idCollisionGroupOther)
|
|
-- si tengono solo gli elementi trimesh
|
|
local CollisionSurfTmId = {}
|
|
for i = 1, #CollisionGroupEntitiesId do
|
|
if EgtGetType( CollisionGroupEntitiesId[i]) == GDB_TY.SRF_MESH then
|
|
local idCollisionSurfTmCopy = EgtCopyGlob( CollisionGroupEntitiesId[i], Part.idTempGroup)
|
|
EgtMove( idCollisionSurfTmCopy, Vector3d( dDeltaXHeadOffset, 0, 0), GDB_RT.GLOB)
|
|
table.insert( CollisionSurfTmId, idCollisionSurfTmCopy)
|
|
end
|
|
end
|
|
-- se presenti geometrie nel gruppo other si aggiungono anche quelle
|
|
if CollisionGroupOtherEntitiesId and #CollisionGroupOtherEntitiesId > 0 then
|
|
for i = 1, #CollisionGroupOtherEntitiesId do
|
|
if EgtGetType( CollisionGroupOtherEntitiesId[i]) == GDB_TY.SRF_MESH then
|
|
local idCollisionOtherSurfTmCopy = EgtCopyGlob( CollisionGroupOtherEntitiesId[i], Part.idTempGroup)
|
|
EgtMove( idCollisionOtherSurfTmCopy, Vector3d( dDeltaXHeadOffset, 0, 0), GDB_RT.GLOB)
|
|
table.insert( CollisionSurfTmId, idCollisionOtherSurfTmCopy)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- check collisione con pezzo
|
|
local bCollisionFoundPiece = false
|
|
if not bCheckOnlyRestlength then
|
|
local idCheckCollisionTm = Part.idBoxTm
|
|
-- se testa o coda attaccate, si considerano nella superficie di collisione
|
|
if bCannotSplitRestLength then
|
|
local b3CheckCollision = BeamLib.GetPartBoxWithHeadTail( Part, sRestLengthSideForPreSimulation)
|
|
idCheckCollisionTm = EgtSurfTmBBox( Part.idTempGroup, b3CheckCollision, false, GDB_RT.GLOB)
|
|
end
|
|
for i = 1, #CollisionSurfTmId do
|
|
bCollisionFoundPiece = EgtCDeSolidSolid( idCheckCollisionTm, CollisionSurfTmId[i], BeamData.COLL_SIC)
|
|
if not type( bCollisionFoundPiece) == "boolean" then
|
|
error( 'Presimulation fail')
|
|
end
|
|
if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then
|
|
EgtSetColor( CollisionSurfTmId[i], RED())
|
|
end
|
|
if bCollisionFoundPiece then
|
|
break
|
|
end
|
|
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 e non è un taglio di testa o coda
|
|
local bCollisionFoundRestLength = false
|
|
if not ( bCollisionFoundPiece or bCannotSplitRestLength) then
|
|
local idRestLengthSurfFr = GetRestlengthSurfTm( Part, sRestLengthSideForPreSimulation)
|
|
if idRestLengthSurfFr then
|
|
for i = 1, #CollisionSurfTmId do
|
|
bCollisionFoundRestLength = EgtCDeSolidSolid( idRestLengthSurfFr, CollisionSurfTmId[i], BeamData.COLL_SIC)
|
|
if not type( bCollisionFoundRestLength) == "boolean" then
|
|
error( 'Presimulation fail')
|
|
end
|
|
if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then
|
|
EgtSetColor( CollisionSurfTmId[i], ORANGE())
|
|
end
|
|
if bCollisionFoundRestLength then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return false, bCollisionFoundRestLength
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
-- controllo collisione con verifica intersezione trimesh e geometrie da macchina
|
|
local function 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
|
|
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
|
|
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
|
|
local vtAux = OptionalParameters.vtAux
|
|
|
|
-- se normale faccia non parallela a direzione testa c'è qualcosa che non va
|
|
if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then
|
|
error( 'CheckCollisionWithAxis : invalid directions')
|
|
end
|
|
|
|
-- punti notevoli della lavorazione in cui fare il check
|
|
local PointsToCheck = OptionalParameters.PointsToCheck or GetCollisionPointsToCheck( Edge, dDepthToMachine)
|
|
|
|
-- punti sul tip dell'utensile, in centro
|
|
local PointsOnToolTipCenter = {}
|
|
for i = 1, #PointsToCheck do
|
|
PointsOnToolTipCenter[i] = PreSimulationLib.GetPointOnToolTipCenter( PointsToCheck[i], vtHead, vtNFace, Edge.vtN, Tool)
|
|
end
|
|
|
|
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, #PointsOnToolTipCenter do
|
|
|
|
local bCollisionFoundPiece, bCollisionFoundRestLength = CheckCollisionPoint( sAxis, PointsOnToolTipCenter[i], vtHead, vtAux, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, 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
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, OptionalParameters)
|
|
|
|
local bCollisionFound
|
|
local bMoveAfterSplitL3, bMoveAfterSplitR3, bMoveAfterSplitR2, bMoveAfterSplitR1
|
|
|
|
-- parametri obbligatori
|
|
local Edge = Parameters.Edge
|
|
local vtNFace = Parameters.vtNFace
|
|
local Tool = Parameters.Tool
|
|
|
|
-- parametri opzionali, in parte da far transitare
|
|
OptionalParameters = OptionalParameters or {}
|
|
|
|
local OptionalParametersCheckCollisionWithAxis = {}
|
|
OptionalParametersCheckCollisionWithAxis.bCheckOnlyRestlength = false
|
|
OptionalParametersCheckCollisionWithAxis.PointsToCheck = OptionalParameters.PointsToCheck or nil
|
|
OptionalParametersCheckCollisionWithAxis.sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
|
|
OptionalParametersCheckCollisionWithAxis.bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
|
|
OptionalParametersCheckCollisionWithAxis.sBlockedAxis = OptionalParameters.sBlockedAxis
|
|
OptionalParametersCheckCollisionWithAxis.vtAux = OptionalParameters.vtAux
|
|
|
|
local sBlockedAxis = OptionalParameters.sBlockedAxis
|
|
local bIsDicing = OptionalParameters.bIsDicing or false
|
|
local bDisableRealElevationCheck = OptionalParameters.bDisableRealElevationCheck or false
|
|
local bCheckOnlyRestlengthForAxisABC = false
|
|
|
|
-- se cubetti in modalità standard (no DownUp) gli assi AB e C si controllano solo con grezzo (ci sarebbe collisione con il materiale già rimosso controllando AB e C con pezzo)
|
|
if bIsDicing and ( sBladeEngagement == 'Standard') then
|
|
bCheckOnlyRestlengthForAxisABC = true
|
|
-- se l'elevazione reale (rispetto al pezzo + eventuale materiale in testa/coda) è maggiore del massimo materiale è sempre collisione
|
|
-- TODO rifare con funzione
|
|
elseif not bDisableRealElevationCheck then
|
|
local Edge = Parameters.Edge
|
|
local vtNFace = Parameters.vtNFace
|
|
local dDepthToMachine = Parameters.dDepthToMachine
|
|
local b3BoxForElevationCheck = BBox3d( Parameters.Part.b3Part)
|
|
-- se è un taglio di testa o coda va aggiunto il sovramateriale
|
|
if OptionalParametersCheckCollisionWithAxis.bCannotSplitRestLength then
|
|
b3BoxForElevationCheck = BeamLib.GetPartBoxWithHeadTail( Parameters.Part, OptionalParametersCheckCollisionWithAxis.sRestLengthSideForPreSimulation)
|
|
end
|
|
-- trimesh rettangolare con un lato corrispondente al lato da lavorare e larghezza come spessore utensile
|
|
local idTrimesh = EgtSurfTmRectangle( Parameters.Part.idTempGroup, Edge.ptStart, Edge.ptEnd, Edge.ptEnd + vtNFace * Parameters.Tool.dThickness, GDB_RT.GLOB)
|
|
local vtNTrimesh = EgtSurfTmFacetNormVersor( idTrimesh, 0, GDB_ID.ROOT)
|
|
-- se trimesh con normale opposta a quella del lato, si inverte (non si sa a priori che verso avrà)
|
|
if not AreSameVectorApprox( Edge.vtN, vtNTrimesh) then
|
|
EgtInvertSurf( idTrimesh)
|
|
end
|
|
local dRealElevation = EgtSurfTmFacetElevationInBBox( idTrimesh, 0, b3BoxForElevationCheck, true, GDB_ID.ROOT)
|
|
local dRealDepthToMachine = ( dRealElevation - Parameters.Edge.dElevation + dDepthToMachine)
|
|
if dRealDepthToMachine > Parameters.Tool.dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
return true
|
|
end
|
|
end
|
|
|
|
-- SCC
|
|
local nSCC = Tool.SetupInfo.GetSCC( Edge.vtN, Edge.vtEdge, vtNFace)
|
|
|
|
-- si settano utensile, SCC e asse bloccato per il controllo collisione
|
|
local bOkTool = EgtSetCalcTool( Tool.sName, Tool.sHead, Tool.nExit)
|
|
if not bOkTool then
|
|
error( 'CheckCollisionWithAxis : cannot set calc tool')
|
|
end
|
|
EgtSetCalcSolCh( nSCC)
|
|
if sBlockedAxis and type( sBlockedAxis) == "string" then
|
|
local BlockedAxis = EgtSplitString( sBlockedAxis, '=')
|
|
EgtSetRotAxisBlock( BlockedAxis[1], tonumber( BlockedAxis[2]))
|
|
end
|
|
|
|
-- nomi degli assi con cui controllare la collisione
|
|
local AxesNames = EgtGetAllCurrAxesNames()
|
|
local sL3 = AxesNames[3]
|
|
local sR3 = AxesNames[6]
|
|
local sR2 = AxesNames[5]
|
|
local sR1 = AxesNames[4]
|
|
|
|
-- ultimo asse lineare prima dei rotativi (solitamente Z) si controlla sempre
|
|
bCollisionFound, bMoveAfterSplitL3 = CheckCollisionWithAxis( sL3, Parameters, OptionalParametersCheckCollisionWithAxis)
|
|
|
|
-- assi rotativi: se richiesto si controlla la collisione solo col grezzo
|
|
OptionalParametersCheckCollisionWithAxis.bCheckOnlyRestlength = bCheckOnlyRestlengthForAxisABC
|
|
|
|
if sR3 and not bCollisionFound then
|
|
bCollisionFound, bMoveAfterSplitR3 = CheckCollisionWithAxis( sR3, Parameters, OptionalParametersCheckCollisionWithAxis)
|
|
end
|
|
|
|
if not bCollisionFound then
|
|
bCollisionFound, bMoveAfterSplitR2 = CheckCollisionWithAxis( sR2, Parameters, OptionalParametersCheckCollisionWithAxis)
|
|
end
|
|
|
|
if not bCollisionFound then
|
|
bCollisionFound, bMoveAfterSplitR1 = CheckCollisionWithAxis( sR1, Parameters, OptionalParametersCheckCollisionWithAxis)
|
|
end
|
|
|
|
local bMoveAfterSplit = bMoveAfterSplitL3 or bMoveAfterSplitR3 or bMoveAfterSplitR2 or bMoveAfterSplitR1
|
|
|
|
return bCollisionFound, bMoveAfterSplit
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------------
|
|
return PreSimulationLib |