Skip to content

Commit

Permalink
enhance and restructure FEM mesh handling and visualization
Browse files Browse the repository at this point in the history
Added new functions attach_mesh_with_springs,
attach_3d_points_to_meca_with_barycentric_mapping, and
add_finger_mesh_force_field_Object to modularize and simplify FEM mesh
handling and visualization.
Introduced show_mecha_visual for toggling visibility of mechanical
objects and indices.
Replaced addFEMObject with add_finger_mesh_force_field_Object for
improved clarity and functionality.
Updated tuto_5.py to utilize new FEM mesh functions, enabling better
integration and enhanced visualization.
Removed redundant code and refactored solver and geometry attachment
logic for better maintainability.
  • Loading branch information
adagolodjo committed Nov 15, 2024
1 parent 8f54ed3 commit 04ec1c8
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 27 deletions.
48 changes: 25 additions & 23 deletions examples/python3/useful/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
import os
from useful.params import ContactParameters as DefaultContactParams


def show_mecha_visual(node, show=True):
node.showObject = show
node.showIndices = show
def addHeader(parent_node, multithreading=False, inverse=False, is_constrained=False, is_contact=False,
contact_params=None):
"""
Expand Down Expand Up @@ -152,44 +154,44 @@ def addSolverNode(parent_node, name='solverNode', template='CompressedRowSparseM

return solver_node

def attach_mesh_with_springs(mesh_node, _box='-18 -15 -8 2 -3 8'):
mesh_node.addObject('BoxROI', name='ROI1', box=_box, drawBoxes='true')
mesh_node.addObject('RestShapeSpringsForceField',
points='@ROI1.indices', stiffness='1e12')

def attach_3d_points_to_meca_with_barycentric_mapping(parent_node, name='node_name',
list_of_points=[" 0.0 0 0 15 0 0 30 0 0 45 0 0 60 0 0 66 0 0 81 0.0 0.0"]):
points_node = parent_node.addChild(name)
points_node.addObject('MechanicalObject', name=name+"_mo", position=list_of_points)
points_node.addObject('BarycentricMapping')
return points_node

def addFEMObject(parent_node, path, name='FEMFinger'):
finger_solver = addSolverNode(parent_node, name=name)
def add_finger_mesh_force_field_Object(parent_node, path):
parent_node.addObject('VisualStyle', displayFlags='showForceFields')
#finger_solver = addSolverNode(parent_node, name=name)

# Load a VTK tetrahedral mesh and expose the resulting topology in the scene .
loader = finger_solver.addObject('MeshVTKLoader', name='loader', filename=f'{path}finger.vtk',
loader = parent_node.addObject('MeshVTKLoader', name='loader', filename=f'{path}finger.vtk',
translation="-17.5 -12.5 7.5",
rotation="0 180 0")
finger_solver.addObject('TetrahedronSetTopologyContainer', position=loader.position.getLinkPath(),
parent_node.addObject('TetrahedronSetTopologyContainer', position=loader.position.getLinkPath(),
tetras=loader.tetras.getLinkPath(), name='container')
# Create a MechanicalObject component to stores the DoFs of the model
finger_solver.addObject('MechanicalObject', template='Vec3', name='dofs')
parent_node.addObject('MechanicalObject', template='Vec3', name='dofs')

# Gives a mass to the model
finger_solver.addObject('UniformMass', totalMass='0.075')
parent_node.addObject('UniformMass', totalMass='1.75')
# Add a TetrahedronFEMForceField component which implement an elastic material model
# solved using the Finite Element Method on
# tetrahedrons.
finger_solver.addObject('TetrahedronFEMForceField', template='Vec3d', name='forceField', method='large',
parent_node.addObject('TetrahedronFEMForceField', template='Vec3d', name='forceField', method='large',
poissonRatio='0.45', youngModulus='500')
attach_mesh_with_springs(parent_node)

finger_solver.addObject('BoxROI', name='ROI1', box='-18 -15 -8 2 -3 8', drawBoxes='true')
finger_solver.addObject('RestShapeSpringsForceField',
points='@ROI1.indices', stiffness='1e12')
##########################################
# Cable points #
##########################################
# Mapped points inside the finger volume, these points attached to the FE model
# are constrained to slide on the cable.

FEMpos = [" 0.0 0 0 15 0 0 30 0 0 45 0 0 60 0 0 66 0 0 81 0.0 0.0"]
fem_points = finger_solver.addChild('femPoints')
fem_points.addObject('MechanicalObject', name="pointsInFEM", position=FEMpos, showObject="1",
showIndices="1")
fem_points.addObject('BarycentricMapping')

return finger_solver, fem_points

points_node = attach_3d_points_to_meca_with_barycentric_mapping(parent_node)
return points_node

def addMappedPoints(parent_node, name="pointsInFEM", position=None, showObject="1",
showIndices="1", femPos="0.0 0 0 15 0 0 30 0 0 45 0 0 60 0 0 66 0 0 81 0.0 0.0"):
Expand Down
18 changes: 14 additions & 4 deletions tutorial/tuto_scenes/tuto_5.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
__copyright__ = "(c) 2021,Inria"
__date__ = "October, 26 2021"

from useful.header import addHeader, addSolverNode, addFEMObject
from useful.header import addHeader, addSolverNode, add_finger_mesh_force_field_Object, show_mecha_visual
from useful.params import BeamPhysicsParametersNoInertia, BeamGeometryParameters, SimulationParameters
from useful.params import Parameters
from cosserat.CosseratBase import CosseratBase
Expand All @@ -19,6 +19,7 @@
import os
from math import pi
from controller import FingerController
from geo_cosserat_cable_driven_cosserat_beam import show_mecha_visual

_beam_radius = 0.5
_beam_length = 81.
Expand Down Expand Up @@ -100,22 +101,31 @@ def onKeypressedEvent(self, event):


def createScene(root_node):
addHeader(root_node, is_constrained=True)
addHeader(root_node, is_constrained=False)
root_node.gravity = [0, -9.81, 0.]

# Add FEM finger node
finger_node = addSolverNode(root_node, name="finger_node")
# this function attach the geometry and force field to predefine solver node
# It also fixe finger regarding predefine box
attached_3d_points_fem_node = add_finger_mesh_force_field_Object(finger_node, path=path)
show_mecha_visual(attached_3d_points_fem_node, show=True)

return root_node

solver_node = addSolverNode(root_node, name="cable_node", isConstrained=is_constrained)

# create cosserat Beam
cosserat_beam = solver_node.addChild(CosseratBase(parent=solver_node, params=Params))
cosserat_frames_node = cosserat_beam.cosseratFrame

# Finger node
femFingerNode = root_node.addChild('femFingerNode')
#femFingerNode = root_node.addChild('femFingerNode')
""" Add FEM finger to the scene"""
# finger_node, fem_points_node = Finger(femFingerNode, name="Finger", rotation=array([0.0, 180.0, 0.0]),
# translation=array([-17.5, -12.5, 7.5]), path=path)

finger_node, fem_points_node = addFEMObject(root_node, path=path, name="Finger")


return root_node

Expand Down

0 comments on commit 04ec1c8

Please sign in to comment.