37. Granular Coloring

Note

Feature requires a Momentum Granular license

../_images/ColorGranularShapesRibbon.png

The Color Granular Shapes tool controls how non-spherical shapes emitted during a simulation are colored. It can color bodies from built-in values, such as velocity and maximum impact energy, or from colors assigned by a Python script.

37.1. Usage

  1. Select Color Granular Shapes from the ribbon menu.

  2. Select the Coloring Mode.

  3. For Velocity and Max Impact Energy, set the Min value and Max value that define the color range.

  4. For Custom, assign colors from a Python script during the simulation.

37.2. Coloring Modes

It is currently possible to color emitted bodies by Velocity, Max Impact Energy, and Custom.

37.2.1. Velocity

In Velocity mode, the color of each emitted body depends on its current velocity. The Min value and Max value fields define the scalar interval used by the color map.

37.2.2. Max Impact Energy

In Max Impact Energy mode, the color of each emitted body depends on the maximum impact energy that the body has registered. The maximum impact energy is the largest amount of energy dissipated in any contact that the body has been a part of. The dissipated energy for a contact is computed as:

(37.1)\[\begin{equation} W = \lambda \frac{( v_t + v_{t + 1})}{2} \end{equation}\]

Where \(\lambda\) is the impact lambda, \(v_t\) is the pre impact speed and \(v_{t+1}\) is the post impact speed.

37.2.3. Custom

In Custom mode, coloring is controlled from Python scripting. This mode can be used when the color should depend on a user-defined value, a state in the script, or any other information available during the simulation.

Use setColor on a body to assign a color directly:

from Momentum import v1

sim = v1.getSimulation()

def OnStep(time):
  for body in sim.getEmittedBodies():
    if body.getVelocity().length() > 1.0:
      body.setColor(v1.Vec4(255, 0, 0, 255))
    else:
      body.setColor(v1.Vec4(0, 100, 255, 255))

The color components are red, green, blue and alpha values in the range 0 to 255. A value of v1.Vec4() restores the body to its default color. For a rigid body with multiple solids, the first solid in the rigid body defines the default color, and all solids in that rigid body will be colored according to that solid.

For scalar based custom coloring, use setColorAsScalar. The scalar value is converted to a color using the current scalar color map, including the Min and Max scalar values set on the map:

from Momentum import v1

sim = v1.getSimulation()

def OnStart(time):
  color_map = sim.getScalarColorMap()
  color_map.setMinScalar(0.0)
  color_map.setMaxScalar(2.0)

def OnStep(time):
  for body in sim.getEmittedBodies():
    custom_scalar = body.getVelocity().length()
    body.setColorAsScalar(custom_scalar)

The scalar color map can also be used manually if the script needs to inspect or reuse the resulting color:

from Momentum import v1

sim = v1.getSimulation()

def OnStep(time):
  color_map = sim.getScalarColorMap()

  for body in sim.getEmittedBodies():
    custom_scalar = body.getVelocity().length()
    color = color_map.getColor(custom_scalar)
    body.setColor(color)

When Custom mode is active, the Min and Max fields in the coloring panel are not editable. Set the scalar range in the script with sim.getScalarColorMap().setMinScalar(value) and sim.getScalarColorMap().setMaxScalar(value) if the script uses the scalar color map.

The scalar color map can be changed to different predefined color ranges. Pass one of the Python preset values to the scalar color map function that selects the color range:

Preset

Python value

Rainbow

v1.ScalarColorMap.RAINBOW

Cool warm

v1.ScalarColorMap.COOLWARM

Viridis

v1.ScalarColorMap.VIRIDIS

Inferno

v1.ScalarColorMap.INFERNO

Plasma

v1.ScalarColorMap.PLASMA

Grayscale

v1.ScalarColorMap.GRAYSCALE

Blue white red

v1.ScalarColorMap.BLUE_WHITE_RED

Cividis

v1.ScalarColorMap.CIVIDIS

Bone

v1.ScalarColorMap.BONE

Copper

v1.ScalarColorMap.COPPER

Afmhot

v1.ScalarColorMap.AFMHOT