Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sofa Cloth simulation
import Sofa
class KeyboardControl(Sofa.PythonScriptController):
# called once graph is created, to init some stuff...
def initGraph(self,node):
print 'initGraph called (python side)'
self.MechanicalState = node.getObject('DOFs')
gravity = node.findData('gravity').value
print gravity
self.rootNode = node.getRoot()
self.clothMesh = self.rootNode.getChild('SquareGravity')
self.ballMesh = self.rootNode.getChild('ball')
print self.ballMesh.getObject('ballState').position
return 0
# key and mouse events; use this to add some user interaction to your scripts
def onKeyPressed(self,k):
# free_position is a scalar array : [tx,ty,tz,rx,ry,rz,rw]
free_position=self.MechanicalState.free_position
# translation speed
speed = 1
# UP key : front
if ord(k)==19:
free_position[0][2]-=speed
self.MechanicalState.free_position=free_position
# DOWN key : rear
if ord(k)==21:
free_position[0][2]+=speed
self.MechanicalState.free_position=free_position
if ord(k)==23:
free_position[0][1]-=speed
self.MechanicalState.free_position=free_position
# RIGHT key : right
if ord(k)==22:
free_position[0][1]+=speed
self.MechanicalState.free_position=free_position
# PAGEUP key : up
if ord(k)==18:
free_position[0][0]-=speed
self.MechanicalState.free_position=free_position
# PAGEDN key : down
if ord(k)==20:
free_position[0][0]+=speed
self.MechanicalState.free_position=free_position
print self.ballMesh.getObject('ballState').position
return 0
# def reset(self):
# print 'reset'
# return 0
# def cleanup(self):
# print 'cleanup called (python side)'
# return 0
<?xml version="1.0" ?>
<!-- Mechanical MassSpring Group Basic Example -->
<Node name="root" dt="0.05" showBoundingTree="0">
<VisualStyle displayFlags="hideBehaviorModels hideCollisionModels hideMappings hideForceFields" />
<RequiredPlugin name="SofaPython" pluginName="SofaPython" />
<Gravity name="G" gravity="0 -10 0" />
<CollisionPipeline name="pipeline" depth="6" verbose="0"/>
<BruteForceDetection name="detection" />
<CollisionResponse name="response"/>
<LocalMinDistance name="proximity" alarmDistance="0.5" contactDistance="0.05" />
<!-- <MinProximityIntersection name="Proximity" alarmDistance="0.8" contactDistance="0.8" /> -->
<FreeMotionAnimationLoop/>
<LCPConstraintSolver tolerance="0.001" maxIt="1000"/>
<!-- <DefaultContactManager response="distanceLMConstraint" /> -->
<!-- <CollisionGroup /> -->
<Node name="SquareGravity">
<!-- <CGImplicit iterations="50" tolerance="1e-6" threshold="1e-10" /> -->
<EulerImplicit name="cg_odesolver" printLog="false" />
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-100" />
<MeshGmshLoader name="loader" filename="mesh/square3.msh" createSubelements="true" />
<OglModel name="Visual" color="red" />
<MechanicalObject name='cloth' src="@loader" translation="50 5 50" rotation="0 90 90" scale="100"/>
<PrecomputedConstraintCorrection recompute="true"/>
<include href="Objects/TriangleSetTopology.xml" src="@loader" template="Vec3d"/>
<DiagonalMass massDensity="0.005" />
<!-- <FixedConstraint indices="0 1 2" /> -->
<StiffSpringForceField name="FF" />
<TriangularFEMForceField name="FEM" youngModulus="100" poissonRatio="0.01" method="large" />
<TriangularBendingSprings name="FEM-Bend" stiffness="300" damping="1.0" />
<TriangleSet />
<IdentityMapping input="@." output="@Visual" />
<Node name="Edge Mesh">
<EdgeSetTopologyContainer name="Container" />
<EdgeSetTopologyModifier name="Modifier" />
<EdgeSetTopologyAlgorithms template="Vec3d" name="TopoAlgo" />
<EdgeSetGeometryAlgorithms template="Vec3d" name="GeomAlgo" drawEdges="1" />
<Triangle2EdgeTopologicalMapping name="Mapping" input="@../Container" output="@Container" />
</Node>
<TTriangleModel name="ClothTriangle" selfCollision="0" contactStiffness="1" contactFriction="100" group="1" />
<Triangle name="ClothTriangle" selfCollision="1" contactStiffness="100" contactFriction="100"/>
<LineModel name="ClothLine" selfCollision="1" contactStiffness="5" contactFriction="100" group="1"/>
<PointModel name="ClothPoint" selfCollision="1" contactStiffness="30" contactFriction="100" group="1"/>
<!-- <LinearSolverConstraintCorrection/> -->
<PlaneForceField stiffness="1" damping="1" normal="0 1 0" d="-5" />
</Node>
<Node name="Input">
<PythonScriptController filename="keyboardControl.py" classname="KeyboardControl"/>
<MechanicalObject template="Rigid" name="DOFs" position="0 0 0 0 0 0 1.0"/>
<Node name="VisuAvatar" activated="false" >
<OglModel name="Visual" fileMesh="mesh/sphere.obj" color="red" scale="1"/>
<RigidMapping input="@.." output="@Visual" index="0"/>
</Node>
<Node name="RefModel">
<MeshObjLoader filename="mesh/sphere.obj" name="loader"/>
<Mesh src="@loader" />
<MechanicalObject src="@loader" name="instrumentCollisionState" ry="-15" rz="-90" dz="3.5" dx="-0.3" />
<RigidMapping />
</Node>
</Node>
<Node name="ball" >
<EulerImplicitSolver name="ODE solver" rayleighStiffness="0.05" rayleighMass="1.0" />
<CGLinearSolver name="linear solver" iterations="25" tolerance="1e-10" threshold="10e-100" />
<MechanicalObject name="ballState" template="Rigid"/>
<UniformMass name="mass" totalmass="0.5" />
<LCPForceFeedback activate="true" forceCoef="0.001"/>
<UncoupledConstraintCorrection/>
<Node name="VisualModel" >
<OglModel name="ballVisualModel" fileMesh="mesh/sphere.obj" color="1.0 0.2 0.2 1.0" dz="3.5" dx="-0.3" dy="20.3" scale="5" />
<RigidMapping name="MM->VM mapping" input="@ballState" output="@ballVisualModel" />
</Node>
<Node name="CollisionModel" >
<MeshObjLoader filename="mesh/sphere.obj" name="loader"/>
<Mesh src="@loader" name="ballCollisionModel" />
<MechanicalObject src="@loader" name="ballCollisionState" dz="3.5" dx="-0.3" dy="20.3" scale="5" />
<Line name="ball" />
<Point name="ball"/>
<RigidMapping name="MM->CM mapping" input="@ballState" output="@ballCollisionState" />
</Node>
<VectorSpringForceField object1="@Input/RefModel/instrumentCollisionState" object2="@ball/CollisionModel/ballCollisionState" stiffness="10000" viscosity="0" />
</Node>
<!-- <Node name="Floor">
<MeshTopology name="Topology Floor" filename="mesh/floor.obj" />
<MechanicalObject name="Floor Particles" />
<OglModel name="Visual" color="brown" />
<Triangle name="Floor Triangle For Collision" moving="0" simulated="0" />
<TriangleModel group="2"/>
<LineModel group="2"/>
<PointModel group="2"/>
</Node> -->
<Node name="Floor">
<MeshObjLoader name="loader" filename="mesh/floorFlat.obj" />
<Mesh src="@loader" />
<MechanicalObject src="@loader" name="DOFs" scale="10" translation="10 -10 -10" />
<TriangleModel name="FloorTriangle" simulated="0" moving="0" contactFriction="100" group="2"/>
<LineModel name="FloorLine" simulated="0" moving="0" contactFriction="100" group="2"/>
<PointModel name="FloorPoint" simulated="0" moving="0" contactFriction="100" group="2"/>
<OglModel name="FloorV" />
<IdentityMapping input="@." output="@FloorV" />
</Node>
<!-- <Node name="Floor" >
<Node name="BaseGround-Friction0.5" >
<MeshObjLoader name="loader" filename="mesh/cube.obj" />
<MeshTopology src="@loader" />
<MechanicalObject src="@loader" translation="10 -10 -10" scale3d="120 10 120" />
<TTriangleModel moving="0" simulated="0" contactFriction="0.5" />
<LineModel moving="0" simulated="0" contactFriction="@[-1].contactFriction" />
<PointModel moving="0" simulated="0" contactFriction="@[-1].contactFriction" />
</Node>
</Node> -->
<!-- <Node name="Floor">
<MeshObjLoader name="loader" filename="mesh/floor.obj" />
<MeshTopology src="@loader" />
<MechanicalObject name="Floor Particles" translation="10 -10 -10" scale3d="2 1 2" />
<TTriangleModel moving="0" simulated="0" contactFriction="1" group="2" />
<LineModel moving="0" simulated="0" contactFriction="@[-1].contactFriction" group="2" />
<PointModel moving="0" simulated="0" contactFriction="@[-1].contactFriction" group="2"/>
</Node> -->
</Node>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.