Skip to content

Python API

This section is mostly for TDs and Tech Animators.

This is not exactly and API, but there are ways to run BroDynamics simulations from your own scripts, if and when you need to automate the process.

Running simulation from Python

Here's an example:

1
2
3
simulator = BroTools.BroDynamics.modules.chain.SimulatorModule()
simulationParameters = {"parameter_name":value}
simulator.run(objects, **simulationParameters)

simulationParameters should be a dict that contains:

  • objects - a list \ array of objects so simulate (for example you can pass cmds.ls(sl=True) there to simulate on selection)

  • preserveAnimation - boolean - preserfe animation or not

  • simulationProperties - a dict of simulation properties. These are directly fed into either nParticle of nHair object, so you can use any. For a list of existing properties refer to json files in BroTools\BroDynamics\config folder (chain_properties.json and point_properties.json)
  • shiftDistance - float - distance to shift additional locator for
  • collisionMode - boolean - collision mode on or off
  • dontRefresh - boolean - refresh or not
  • colliders - list of objects to turn into colliders
  • skipControls - int - number of controls to skip
  • skipFrames - int - number of frames to skip
  • aimRotation - boolean - match rotations or not
  • matchPositions - boolean - match translations or not
  • debugMode - boolean - use debug mode or not
  • deleteNucleus - boolean - delete nucleus after simulation or leave it
  • up - list showing which axis is up ([x,y,z])
  • axis - list showing which axis is front ([x,y,z])

To see what properties your current UI has you can enable Info logging under BroTools - Preferences and set Debug Level to 1. Then run your test simulation from UI.

You should see a line that goes like:

1
2
3
4
5
6
7
8
9
// BroTools | INFO ||  chain.run:82 | Run Simulator for module: Chain (nHair). 

    Args:
 ([u'nurbsCircle1', u'nurbsCircle2', u'nurbsCircle3'],)

  Kwargs:
{'preserveAnimation': True, 'collisionMode': False, 'forces': [], 'shiftDistance': 1.0, 'dontRefresh': False, 'followBaseTwist': True, 'preserveInertia': True, 'preAlign': False, 'autoShiftDistance': True, 'cycleIterations': 0, 'aimRotation': True, 'multiPassSimulation': False, 'simulationProperties': {'attractionScale[1].attractionScale_Position': 1, u'stiffnessScale[1].stiffnessScale_FloatValue': 1.0, 'stiffnessScale[0].stiffnessScale_Position': 0, u'damp': 0.0, u'compressionResistance': 10.0, u'gravity': 0.0, u'collideWidthOffset': 0.0, u'drag': 0.05, u'attractionScale[1].attractionScale_FloatValue': 1.0, u'stiffnessScale[0].stiffnessScale_FloatValue': 1.0, 'attractionScale[0].attractionScale_Position': 0, u'bendResistance': 1.0, u'stretchResistance': 10.0, 'stiffnessScale[1].stiffnessScale_Position': 1, u'attractionDamp': 0.15, u'mass': 1.0, u'attractionScale[0].attractionScale_FloatValue': 1.0, u'startCurveAttract': 0.01}, 'skipControls': 1, 'eulerFilter': True, 'matchPositions': False, 'colliders': [], 'deleteNucleus': True}

 //

Here's the code that prints that message

1
log.debug("Run", MODULE_NAME, objects, args, kwargs)

So the part in {} brackets is your simulationParameters dict which you should be able to just copy and paste into your code and adjust as needed.

Here's a complete and working example for Chain simulation:

1
2
3
4
5
6
7
8
9
import BroTools
import BroTools.BroDynamics.modules.chain
from maya import cmds

objects = cmds.ls(sl=True)

simulator = BroTools.BroDynamics.modules.chain.SimulatorModule()
simulationParameters = {'preserveAnimation': True, 'collisionMode': False, 'forces': [], 'shiftDistance': 1.0, 'dontRefresh': False, 'followBaseTwist': True, 'preserveInertia': True, 'preAlign': False, 'autoShiftDistance': True, 'cycleIterations': 0, 'aimRotation': True, 'multiPassSimulation': False, 'simulationProperties': {'attractionScale[1].attractionScale_Position': 1, u'stiffnessScale[1].stiffnessScale_FloatValue': 1.0, 'stiffnessScale[0].stiffnessScale_Position': 0, u'damp': 0.0, u'compressionResistance': 10.0, u'gravity': 0.0, u'collideWidthOffset': 0.0, u'drag': 0.05, u'attractionScale[1].attractionScale_FloatValue': 1.0, u'stiffnessScale[0].stiffnessScale_FloatValue': 1.0, 'attractionScale[0].attractionScale_Position': 0, u'bendResistance': 1.0, u'stretchResistance': 10.0, 'stiffnessScale[1].stiffnessScale_Position': 1, u'attractionDamp': 0.15, u'mass': 1.0, u'attractionScale[0].attractionScale_FloatValue': 1.0, u'startCurveAttract': 0.01}, 'skipControls': 1, 'eulerFilter': True, 'matchPositions': False, 'colliders': [], 'deleteNucleus': True}
simulator.run(objects, **simulationParameters)  

I am open to any suggestions on improving Python API and documentation.

Running Batch simulation from Python

Here's how you can run Batch simulation from Python.

1
2
3
4
5
import BroTools
BroTools.BroDynamics.BroDynamicsUI.initUI()
BroTools.BroDynamics.BroDynamicsUI.BroDynamicsWindow.BroBatchWindow.show()
BroTools.BroDynamics.BroDynamicsUI.BroDynamicsWindow.BroBatchWindow.refreshDropdowns()
BroTools.BroDynamics.BroDynamicsUI.BroDynamicsWindow.BroBatchWindow.startBatchSimulation()

This will load the first broDynamics_Data node in your scene and run a batch simulation for all objects which are setup in that node.

You can also change the node, by manually switching the id of the dropdown control, here's how you can access it:

1
BroTools.BroDynamics.BroDynamicsUI.BroDynamicsWindow.BroBatchWindow.node_dropdown