示例#1
0
# radius of the cylindrical links or the rope
radii = 0.1

ball_mass = 10
# radius of the wrecking ball
ball_radius = 0.5
ball_color = np.array([[1, 0, 0]])

joint_friction = 0.0005

###############################################################################
# Creating the base plane actor.

# Base
base_actor = actor.box(centers=np.array([[0, 0, 0]]),
                       directions=[0, 0, 0],
                       scales=(5, 5, 0.2),
                       colors=(1, 1, 1))
base_coll = p.createCollisionShape(p.GEOM_BOX, halfExtents=[2.5, 2.5, 0.1])
base = p.createMultiBody(baseCollisionShapeIndex=base_coll,
                         basePosition=[0, 0, -0.1],
                         baseOrientation=[0, 0, 0, 1])
p.changeDynamics(base, -1, lateralFriction=0.3, restitution=0.5)

###############################################################################
# The following definitions are made to render a NxNxN brick wall.

# Generate bricks.
nb_bricks = wall_length * wall_breadth * wall_height
brick_centers = np.zeros((nb_bricks, 3))

brick_directions = np.zeros((nb_bricks, 3))
示例#2
0

# BALL
ball_actor = actor.sphere(centers=np.array([[0, 0, 0]]),
                          colors=np.array([1, 0, 0]),
                          radii=0.3)
ball_coll = p.createCollisionShape(p.GEOM_SPHERE, radius=0.3)
ball = p.createMultiBody(baseMass=3,
                         baseCollisionShapeIndex=ball_coll,
                         basePosition=[2, 0, 1.5],
                         baseOrientation=[0, 0, 0, 1])
p.changeDynamics(ball, -1, lateralFriction=0.3, restitution=0.5)

# BASE Plane
base_actor = actor.box(centers=np.array([[0, 0, 0]]),
                       directions=[0, 0, 0],
                       size=(5, 5, 0.2),
                       colors=(1, 1, 1))
base_coll = p.createCollisionShape(p.GEOM_BOX,
                                   halfExtents=[2.5, 2.5, 0.1
                                                ])  # half of the actual size.
base = p.createMultiBody(baseCollisionShapeIndex=base_coll,
                         basePosition=[0, 0, -0.1],
                         baseOrientation=[0, 0, 0, 1])
p.changeDynamics(base, -1, lateralFriction=0.3, restitution=0.5)

height = 10
base_length = 10

brick_Ids = []
brick_actors = []
示例#3
0
文件: viz_chain.py 项目: zoq/fury
                                   force=friction_vec)

###############################################################################
# Next, we define a constraint base that will help us in the oscillation of the
# chain.

root_robe_c = p.createConstraint(rope, -1, -1, -1, p.JOINT_FIXED, [0, 0, 0],
                                 [0, 0, 0], [0, 0, 2])

# some traj to inject motion
amplitude_x = 0.3
amplitude_y = 0.0
freq = 0.6

base_actor = actor.box(centers=np.array([[0, 0, 0]]),
                       directions=np.array([[0, 0, 0]]),
                       scales=(0.02, 0.02, 0.02),
                       colors=np.array([[1, 0, 0]]))

###############################################################################
# We add the necessary actors to the scene.

scene = window.Scene()
scene.background((1, 1, 1))
scene.set_camera((2.2, -3.0, 3.0), (-0.3, 0.6, 0.7), (-0.2, 0.2, 1.0))
scene.add(actor.axes(scale=(0.1, 0.1, 0.1)))
scene.add(rope_actor)
scene.add(base_actor)

# Create show manager.
showm = window.ShowManager(scene,
                           size=(900, 768),
示例#4
0
#BALL
ball = actor.sphere(centers=np.array([[2, 3, 3]]),
                    colors=np.array([1, 1, 1]),
                    radii=0.6)
ball_coll = p.createCollisionShape(p.GEOM_SPHERE, radius=0.3)
ball_vis = p.createVisualShape(p.GEOM_SPHERE, radius=0.3)
ball_ = p.createMultiBody(baseMass=3,
                          baseCollisionShapeIndex=ball_coll,
                          baseVisualShapeIndex=ball_vis,
                          basePosition=[2, 3, 3],
                          baseOrientation=[0, 0, 0, 1])
p.changeDynamics(ball_, -1, lateralFriction=0.3, restitution=0.5)

#BASE
base = actor.box(centers=np.array([[-4, 3, -0.1]]),
                 directions=[1.57, 0, 0],
                 size=(20, 15, 0.2),
                 colors=(0, 1, 0))
base_coll = p.createCollisionShape(p.GEOM_BOX, halfExtents=[10, 7.5, 0.1])
base_vis = p.createVisualShape(p.GEOM_BOX, halfExtents=[10, 7.5, 0.1])
base_ = p.createMultiBody(baseVisualShapeIndex=base_vis,
                          baseCollisionShapeIndex=base_coll,
                          basePosition=[-4, 3, -0.1],
                          baseOrientation=[0, 0, 0, 1])
p.changeDynamics(base_, -1, lateralFriction=0.3, restitution=0.5)

height = 20
base_length = 20

brick_Ids = []
brick_actors = []
示例#5
0
ball_coll = p.createCollisionShape(p.GEOM_SPHERE, radius=ball_radius)

# Creating a multi-body which will be tracked by pybullet.
ball = p.createMultiBody(baseMass=3,
                         baseCollisionShapeIndex=ball_coll,
                         basePosition=ball_position,
                         baseOrientation=ball_orientation)

# Change the dynamics of the ball by adding friction and restitution.
p.changeDynamics(ball, -1, lateralFriction=0.3, restitution=0.5)

###############################################################################
# Render a base plane to support the bricks.

base_actor = actor.box(centers=np.array([[0, 0, 0]]),
                       directions=[0, 0, 0],
                       scales=base_size,
                       colors=base_color)

base_coll = p.createCollisionShape(p.GEOM_BOX, halfExtents=base_size / 2)
# half of the actual size.

base = p.createMultiBody(baseCollisionShapeIndex=base_coll,
                         basePosition=base_position,
                         baseOrientation=base_orientation)

p.changeDynamics(base, -1, lateralFriction=0.3, restitution=0.5)

###############################################################################
# Now we render the bricks. All the bricks are rendered by a single actor for
# better performance.
示例#6
0
xyz = np.array([box_lx, box_ly, box_lz
                ]) * (np.random.rand(num_particles, 3) - 0.5) * 0.6
vel = 4 * (np.random.rand(num_particles, 3) - 0.5)
colors = np.random.rand(num_particles, 3)
radii = np.random.rand(num_particles) + 0.01

##############################################################################
# With box, streamtube and sphere actors, we can create the box, the
# edges of the box and the spheres respectively.

scene = window.Scene()
box_centers = np.array([[0, 0, 0]])
box_directions = np.array([[0, 1, 0]])
box_colors = np.array([[1, 1, 1, 0.2]])
box_actor = actor.box(box_centers,
                      box_directions,
                      box_colors,
                      scales=(box_lx, box_ly, box_lz))
scene.add(box_actor)

lines = box_edges(box_lx, box_ly, box_lz)
line_actor = actor.streamtube(lines, colors=(1, 0.5, 0), linewidth=0.1)
scene.add(line_actor)

sphere_actor = actor.sphere(centers=xyz, colors=colors, radii=radii)
scene.add(sphere_actor)

showm = window.ShowManager(scene,
                           size=(900, 768),
                           reset_camera=True,
                           order_transparent=True)
showm.initialize()
示例#7
0
p.setCollisionFilterPair(obj, wall, -1, -1, enableCol)
p.setCollisionFilterPair(obj, wall_1, -1, -1, enableCol)
# p.setRealTimeSimulation(1)

xyz = np.array([[0, 0, 0]])
colors = np.array([[0.7, 0.5, 0.5, 1]])
radii = 0.5

scene = window.Scene()

sphere_actor = actor.sphere(centers=xyz, colors=colors, radii=radii)

cuboid_actor = actor.box(centers=xyz,
                         directions=np.array(
                             p.getEulerFromQuaternion([
                                 -0.4044981, -0.8089962, -0.4044981, 0.1352322
                             ])),
                         size=(0.2, 0.2, 1),
                         colors=(0, 1, 1))

wall_actor_1 = actor.box(centers=np.array([[-4, 0, 4]]),
                         directions=np.array([[1.57, 0, 0]]),
                         size=(0.2, 10, 10),
                         colors=(1, 1, 1))

wall_actor_2 = actor.box(centers=np.array([[0, 0, 0]]),
                         directions=np.array([[-1.57, 0, 0]]),
                         size=(10, 10, 0.2),
                         colors=(1, 1, 1))

scene.add(wall_actor_1)
示例#8
0
ring_slider = ui.RingSlider2D(initial_value=0, text_template="{angle:5.1f}°")

line_slider_x = ui.LineSlider2D(initial_value=0,
                                min_value=-10,
                                max_value=10,
                                orientation="horizontal",
                                text_alignment="Top")

line_slider_y = ui.LineSlider2D(initial_value=0,
                                min_value=-10,
                                max_value=10,
                                orientation="vertical",
                                text_alignment="Right")

cube = actor.box(centers=np.array([[10, 0, 0]]),
                 directions=np.array([[0, 1, 0]]),
                 colors=np.array([[0, 0, 1]]),
                 scales=np.array([[1, 1, 1]]))
cube_x = 0
cube_y = 0


def rotate_cube(slider):
    angle = slider.value
    previous_angle = slider.previous_value
    rotation_angle = angle - previous_angle
    cube.RotateX(rotation_angle)


def translate_cube_x(slider):
    global cube_x, cube_y
    cube_x = slider.value
示例#9
0
# Apply gravity to the scene.
p.setGravity(0, 0, -10, physicsClientId=client)

###############################################################################
# Set the Number of Dominoes for Simulation.
number_of_dominoes = 10

# Base Plane Parameters
base_size = np.array([number_of_dominoes * 2, number_of_dominoes * 2, 0.2])
base_color = np.array([1, 1, 1])
base_position = np.array([0, 0, -0.1])
base_orientation = np.array([0, 0, 0, 1])

# Render a BASE plane to support the Dominoes.
base_actor = actor.box(centers=np.array([[0, 0, 0]]),
                       directions=[0, 0, 0],
                       scales=base_size,
                       colors=base_color)

# half of the actual size.
base_coll = p.createCollisionShape(p.GEOM_BOX, halfExtents=base_size / 2)

base = p.createMultiBody(baseCollisionShapeIndex=base_coll,
                         basePosition=base_position,
                         baseOrientation=base_orientation)

p.changeDynamics(base, -1, lateralFriction=1, restitution=0.5)

###############################################################################
# We define some global parameters of the Dominoes so that its easier for
# us to tweak the simulation.
示例#10
0
def test_manifest_standard():
    # Test non-supported property
    test_actor = actor.text_3d('Test')
    npt.assert_warns(UserWarning, material.manifest_standard, test_actor)

    center = np.array([[0, 0, 0]])

    # Test non-supported interpolation method
    test_actor = actor.square(center, directions=(1, 1, 1), colors=(0, 0, 1))
    npt.assert_warns(UserWarning, material.manifest_standard, test_actor,
                     interpolation='test')

    scene = window.Scene()  # Setup scene

    test_actor = actor.box(center, directions=(1, 1, 1), colors=(0, 0, 1),
                           scales=1)
    scene.add(test_actor)

    # scene.reset_camera()
    # window.show(scene)
    ss = window.snapshot(scene, size=(200, 200))
    actual = ss[75, 100, :] / 1000
    desired = np.array([0, 0, 170]) / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 125, :] / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 75, :] / 1000
    desired = np.array([0, 0, 85]) / 1000
    # TODO: check if camera affects this assert
    # npt.assert_array_almost_equal(actual, desired, decimal=2)

    # Test ambient level
    material.manifest_standard(test_actor, ambient_level=1)
    ss = window.snapshot(scene, size=(200, 200))
    actual = ss[75, 100, :] / 1000
    desired = np.array([0, 0, 255]) / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 125, :] / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 75, :] / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)

    # Test ambient color
    material.manifest_standard(test_actor, ambient_level=.5,
                               ambient_color=(1, 0, 0))
    ss = window.snapshot(scene, size=(200, 200))
    actual = ss[75, 100, :] / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 125, :] / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 75, :] / 1000
    desired = np.array([0, 0, 212]) / 1000
    # TODO: check what affects this
    # npt.assert_array_almost_equal(actual, desired, decimal=2)

    # Test diffuse level
    material.manifest_standard(test_actor, diffuse_level=.75)
    ss = window.snapshot(scene, size=(200, 200))
    actual = ss[75, 100, :] / 1000
    desired = np.array([0, 0, 127]) / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 125, :] / 1000
    desired = np.array([0, 0, 128]) / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 75, :] / 1000
    desired = np.array([0, 0, 64]) / 1000
    # TODO: check what affects this
    # npt.assert_array_almost_equal(actual, desired, decimal=2)

    # Test diffuse color
    material.manifest_standard(test_actor, diffuse_level=.5,
                               diffuse_color=(1, 0, 0))
    ss = window.snapshot(scene, size=(200, 200))
    actual = ss[75, 100, :] / 1000
    desired = np.array([0, 0, 85]) / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 125, :] / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 75, :] / 1000
    desired = np.array([0, 0, 42]) / 1000
    # TODO: check what affects the line below
    # npt.assert_array_almost_equal(actual, desired, decimal=2)

    # Test specular level
    material.manifest_standard(test_actor, specular_level=1)
    ss = window.snapshot(scene, size=(200, 200))
    actual = ss[75, 100, :] / 1000
    desired = np.array([170, 170, 255]) / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 125, :] / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 75, :] / 1000
    desired = np.array([85, 85, 170]) / 1000
    # TODO: check what affects the line below
    # npt.assert_array_almost_equal(actual, desired, decimal=2)

    # Test specular power
    material.manifest_standard(test_actor, specular_level=1,
                               specular_power=5)
    ss = window.snapshot(scene, size=(200, 200))
    actual = ss[75, 100, :] / 1000
    desired = np.array([34, 34, 204]) / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 125, :] / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 75, :] / 1000
    desired = np.array([1, 1, 86]) / 1000
    # TODO: check what affects the line below
    # npt.assert_array_almost_equal(actual, desired, decimal=2)

    # Test specular color
    material.manifest_standard(test_actor, specular_level=1,
                               specular_color=(1, 0, 0), specular_power=5)
    ss = window.snapshot(scene, size=(200, 200))
    actual = ss[75, 100, :] / 1000
    desired = np.array([34, 0, 170]) / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 125, :] / 1000
    npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[125, 75, :] / 1000
    desired = np.array([1, 0, 85]) / 1000
    # TODO: check what affects the line below
    # npt.assert_array_almost_equal(actual, desired, decimal=2)

    scene.clear()  # Reset scene

    # Special case: Contour from roi
    data = np.zeros((50, 50, 50))
    data[20:30, 25, 25] = 1.
    data[25, 20:30, 25] = 1.
    test_actor = actor.contour_from_roi(data, color=np.array([1, 0, 1]))
    scene.add(test_actor)

    ss = window.snapshot(scene, size=(200, 200))
    actual = ss[90, 110, :] / 1000
    desired = np.array([253, 0, 253]) / 1000
    # TODO: check what affects the line below
    # npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[90, 60, :] / 1000
    desired = np.array([180, 0, 180]) / 1000
    # TODO: check what affects the line below
    # npt.assert_array_almost_equal(actual, desired, decimal=2)

    material.manifest_standard(test_actor)
    ss = window.snapshot(scene, size=(200, 200))
    actual = ss[90, 110, :] / 1000
    desired = np.array([253, 253, 253]) / 1000
    # TODO: check what affects the line below
    # npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[90, 60, :] / 1000
    desired = np.array([180, 180, 180]) / 1000
    # TODO: check what affects the line below
    # npt.assert_array_almost_equal(actual, desired, decimal=2)

    material.manifest_standard(test_actor, diffuse_color=(1, 0, 1))
    ss = window.snapshot(scene, size=(200, 200))
    actual = ss[90, 110, :] / 1000
    desired = np.array([253, 0, 253]) / 1000
    # TODO: check what affects the line below
    # npt.assert_array_almost_equal(actual, desired, decimal=2)
    actual = ss[90, 60, :] / 1000
    desired = np.array([180, 0, 180]) / 1000
示例#11
0
l_particle = [
    particle(colors=np.random.rand(1, 3),
             origin=origin,
             num_total_steps=num_total_steps,
             total_time=total_time,
             path_thickness=path_thickness) for _ in range(num_particles)
]

scene.add(*l_particle)

###############################################################################
# Creating a container (cube actor) inside which the particle(s) move around

container_actor = actor.box(centers=np.array([[0, 0, 0]]),
                            colors=(0.5, 0.9, 0.7, 0.4),
                            scales=6)
scene.add(container_actor)

###############################################################################
# Initializing text box to display the name of the animation

tb = ui.TextBlock2D(bold=True, position=(235, 40), color=(0, 0, 0))
tb.message = "Brownian Motion"
scene.add(tb)

###############################################################################
# The path of the particles exhibiting Brownian motion is plotted here


def timer_callback(_obj, _event):
示例#12
0
def test_manifest_standard():
    # Test non-supported property
    test_actor = actor.text_3d('Test')
    npt.assert_warns(UserWarning, material.manifest_standard, test_actor)

    center = np.array([[0, 0, 0]])

    # Test non-supported interpolation method
    test_actor = actor.square(center, directions=(1, 1, 1), colors=(0, 0, 1))
    npt.assert_warns(UserWarning,
                     material.manifest_standard,
                     test_actor,
                     interpolation='test')

    # Create tmp dir to save and query images
    with TemporaryDirectory() as out_dir:
        tmp_fname = os.path.join(out_dir, 'tmp_img.png')  # Tmp image to test

        scene = window.Scene()  # Setup scene

        test_actor = actor.box(center,
                               directions=(1, 1, 1),
                               colors=(0, 0, 1),
                               scales=1)
        scene.add(test_actor)

        # Test basic actor
        window.record(scene,
                      out_path=tmp_fname,
                      size=(200, 200),
                      reset_camera=True)
        npt.assert_equal(os.path.exists(tmp_fname), True)
        ss = load_image(tmp_fname)
        actual = ss[75, 100, :] / 1000
        desired = np.array([0, 0, 170]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 125, :] / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 75, :] / 1000
        desired = np.array([0, 0, 85]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)

        # Test ambient level
        material.manifest_standard(test_actor, ambient_level=1)
        window.record(scene,
                      out_path=tmp_fname,
                      size=(200, 200),
                      reset_camera=True)
        npt.assert_equal(os.path.exists(tmp_fname), True)
        ss = load_image(tmp_fname)
        actual = ss[75, 100, :] / 1000
        desired = np.array([0, 0, 255]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 125, :] / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 75, :] / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)

        # Test ambient color
        material.manifest_standard(test_actor,
                                   ambient_level=.5,
                                   ambient_color=(1, 0, 0))
        window.record(scene,
                      out_path=tmp_fname,
                      size=(200, 200),
                      reset_camera=True)
        npt.assert_equal(os.path.exists(tmp_fname), True)
        ss = load_image(tmp_fname)
        actual = ss[75, 100, :] / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 125, :] / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 75, :] / 1000
        desired = np.array([0, 0, 212]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)

        # Test diffuse level
        material.manifest_standard(test_actor, diffuse_level=.75)
        window.record(scene,
                      out_path=tmp_fname,
                      size=(200, 200),
                      reset_camera=True)
        npt.assert_equal(os.path.exists(tmp_fname), True)
        ss = load_image(tmp_fname)
        actual = ss[75, 100, :] / 1000
        desired = np.array([0, 0, 127]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 125, :] / 1000
        desired = np.array([0, 0, 128]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 75, :] / 1000
        desired = np.array([0, 0, 64]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)

        # Test diffuse color
        material.manifest_standard(test_actor,
                                   diffuse_level=.5,
                                   diffuse_color=(1, 0, 0))
        window.record(scene,
                      out_path=tmp_fname,
                      size=(200, 200),
                      reset_camera=True)
        npt.assert_equal(os.path.exists(tmp_fname), True)
        ss = load_image(tmp_fname)
        actual = ss[75, 100, :] / 1000
        desired = np.array([0, 0, 85]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 125, :] / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 75, :] / 1000
        desired = np.array([0, 0, 42]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)

        # Test specular level
        material.manifest_standard(test_actor, specular_level=1)
        window.record(scene,
                      out_path=tmp_fname,
                      size=(200, 200),
                      reset_camera=True)
        npt.assert_equal(os.path.exists(tmp_fname), True)
        ss = load_image(tmp_fname)
        actual = ss[75, 100, :] / 1000
        desired = np.array([170, 170, 255]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 125, :] / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 75, :] / 1000
        desired = np.array([85, 85, 170]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)

        # Test specular power
        material.manifest_standard(test_actor,
                                   specular_level=1,
                                   specular_power=5)
        window.record(scene,
                      out_path=tmp_fname,
                      size=(200, 200),
                      reset_camera=True)
        npt.assert_equal(os.path.exists(tmp_fname), True)
        ss = load_image(tmp_fname)
        actual = ss[75, 100, :] / 1000
        desired = np.array([34, 34, 204]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 125, :] / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 75, :] / 1000
        desired = np.array([1, 1, 86]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)

        # Test specular color
        material.manifest_standard(test_actor,
                                   specular_level=1,
                                   specular_color=(1, 0, 0),
                                   specular_power=5)
        window.record(scene,
                      out_path=tmp_fname,
                      size=(200, 200),
                      reset_camera=True)
        npt.assert_equal(os.path.exists(tmp_fname), True)
        ss = load_image(tmp_fname)
        actual = ss[75, 100, :] / 1000
        desired = np.array([34, 0, 170]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 125, :] / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[125, 75, :] / 1000
        desired = np.array([1, 0, 85]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)

        scene.clear()  # Reset scene

        # Special case: Contour from roi
        data = np.zeros((50, 50, 50))
        data[20:30, 25, 25] = 1.
        data[25, 20:30, 25] = 1.
        test_actor = actor.contour_from_roi(data, color=np.array([1, 0, 1]))
        scene.add(test_actor)

        window.record(scene,
                      out_path=tmp_fname,
                      size=(200, 200),
                      reset_camera=True)
        npt.assert_equal(os.path.exists(tmp_fname), True)
        ss = load_image(tmp_fname)
        actual = ss[90, 110, :] / 1000
        desired = np.array([253, 0, 253]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[90, 60, :] / 1000
        desired = np.array([180, 0, 180]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)

        material.manifest_standard(test_actor)
        window.record(scene,
                      out_path=tmp_fname,
                      size=(200, 200),
                      reset_camera=True)
        npt.assert_equal(os.path.exists(tmp_fname), True)
        ss = load_image(tmp_fname)
        actual = ss[90, 110, :] / 1000
        desired = np.array([253, 253, 253]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[90, 60, :] / 1000
        desired = np.array([180, 180, 180]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)

        material.manifest_standard(test_actor, diffuse_color=(1, 0, 1))
        window.record(scene,
                      out_path=tmp_fname,
                      size=(200, 200),
                      reset_camera=True)
        npt.assert_equal(os.path.exists(tmp_fname), True)
        ss = load_image(tmp_fname)
        actual = ss[90, 110, :] / 1000
        desired = np.array([253, 0, 253]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)
        actual = ss[90, 60, :] / 1000
        desired = np.array([180, 0, 180]) / 1000
        npt.assert_array_almost_equal(actual, desired, decimal=2)