Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardize actors colors #773

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions fury/actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
set_polydata_triangles,
set_polydata_vertices,
shallow_copy,
normalize_color,
)


Expand Down Expand Up @@ -383,6 +384,7 @@ def surface(vertices, faces=None, colors=None, smooth=None, subdivision=3):
triangle_poly_data.SetPoints(points)

if colors is not None:
colors = normalize_color(colors)
triangle_poly_data.GetPointData().SetScalars(numpy_to_vtk_colors(255 * colors))

if faces is None:
Expand Down Expand Up @@ -528,6 +530,9 @@ def contour_from_roi(data, affine=None, color=np.array([1, 0, 0]), opacity=1):
skin_actor = Actor()

skin_actor.SetMapper(skin_mapper)

color = normalize_color(color)

skin_actor.GetProperty().SetColor(color[0], color[1], color[2])
skin_actor.GetProperty().SetOpacity(opacity)

Expand Down Expand Up @@ -570,6 +575,8 @@ def contour_from_label(data, affine=None, color=None):
elif color.shape != (nb_surfaces, 3) and color.shape != (nb_surfaces, 4):
raise ValueError('Incorrect color array shape')

color = normalize_color(color)

if color.shape == (nb_surfaces, 4):
opacity = color[:, -1]
color = color[:, :-1]
Expand Down Expand Up @@ -680,6 +687,7 @@ def streamtube(

"""
# Poly data with lines and colors
colors = normalize_color(colors)
poly_data, color_is_scalar = lines_to_vtk_polydata(lines, colors)
next_input = poly_data

Expand Down Expand Up @@ -750,8 +758,6 @@ def streamtube(
actor.GetProperty().BackfaceCullingOn()
actor.GetProperty().SetOpacity(opacity)



return actor


Expand Down Expand Up @@ -833,6 +839,7 @@ def line(

"""
# Poly data with lines and colors
colors = normalize_color(colors)
poly_data, color_is_scalar = lines_to_vtk_polydata(lines, colors)
next_input = poly_data

Expand Down Expand Up @@ -950,6 +957,8 @@ def axes(
dirs = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
colors = np.array([colorx + (opacity,), colory + (opacity,), colorz + (opacity,)])

colors = normalize_color(colors)

scales = np.asarray(scale)
arrow_actor = arrow(centers, dirs, colors, scales, repeat_primitive=False)
return arrow_actor
Expand Down Expand Up @@ -1692,6 +1701,7 @@ def dot(points, colors=None, opacity=None, dot_size=5):
vtk_faces.InsertNextCell(1)
vtk_faces.InsertCellPoint(idd)

colors = normalize_color(colors)
color_tuple = color_check(len(points), colors)
color_array, global_opacity = color_tuple

Expand Down Expand Up @@ -1759,6 +1769,9 @@ def point(points, colors, point_radius=0.1, phi=8, theta=8, opacity=1.0):
>>> # window.show(scene)

"""

colors = normalize_color(colors)

return sphere(
centers=points,
colors=colors,
Expand Down Expand Up @@ -1820,6 +1833,7 @@ def sphere(
>>> # window.show(scene)

"""
colors = normalize_color(colors)
if not use_primitive:
src = SphereSource() if faces is None else None

Expand Down Expand Up @@ -1913,6 +1927,7 @@ def cylinder(
>>> # window.show(scene)

"""
colors = normalize_color(colors)
if faces is None:
src = CylinderSource()
src.SetCapping(capped)
Expand Down Expand Up @@ -2001,6 +2016,8 @@ def disk(
src = None
rotate = None

colors = normalize_color(colors)

disk_actor = repeat_sources(
centers=centers,
colors=colors,
Expand Down Expand Up @@ -2043,6 +2060,7 @@ def square(centers, directions=(1, 0, 0), colors=(1, 0, 0), scales=1):
>>> # window.show(scene)

"""
colors = normalize_color(colors)
verts, faces = fp.prim_square()
res = fp.repeat_primitive(
verts,
Expand Down Expand Up @@ -2095,6 +2113,7 @@ def rectangle(centers, directions=(1, 0, 0), colors=(1, 0, 0), scales=(1, 2, 0))
>>> # window.show(scene)

"""
colors = normalize_color(colors)
return square(centers=centers, directions=directions, colors=colors, scales=scales)


Expand Down Expand Up @@ -2128,6 +2147,7 @@ def box(centers, directions=(1, 0, 0), colors=(1, 0, 0), scales=(1, 2, 3)):
>>> # window.show(scene)

"""
colors = normalize_color(colors)
verts, faces = fp.prim_box()
res = fp.repeat_primitive(
verts,
Expand Down Expand Up @@ -2176,6 +2196,7 @@ def cube(centers, directions=(1, 0, 0), colors=(1, 0, 0), scales=1):
>>> # window.show(scene)

"""
colors = normalize_color(colors)
return box(centers=centers, directions=directions, colors=colors, scales=scales)


Expand Down Expand Up @@ -2236,6 +2257,7 @@ def arrow(
>>> # window.show(scene)

"""
colors = normalize_color(colors)
if repeat_primitive:
vertices, faces = fp.prim_arrow()
res = fp.repeat_primitive(
Expand Down Expand Up @@ -2323,6 +2345,7 @@ def cone(
>>> # window.show(scene)

"""
colors = normalize_color(colors)
if not use_primitive:
src = ConeSource() if faces is None else None

Expand Down Expand Up @@ -2387,6 +2410,7 @@ def triangularprism(centers, directions=(1, 0, 0), colors=(1, 0, 0), scales=1):
>>> # window.show(scene)

"""
colors = normalize_color(colors)
verts, faces = fp.prim_triangularprism()
res = fp.repeat_primitive(
verts,
Expand Down Expand Up @@ -2435,6 +2459,7 @@ def rhombicuboctahedron(centers, directions=(1, 0, 0), colors=(1, 0, 0), scales=
>>> # window.show(scene)

"""
colors = normalize_color(colors)
verts, faces = fp.prim_rhombicuboctahedron()
res = fp.repeat_primitive(
verts,
Expand Down Expand Up @@ -2484,6 +2509,7 @@ def pentagonalprism(centers, directions=(1, 0, 0), colors=(1, 0, 0), scales=1):
>>> # window.show(scene)

"""
colors = normalize_color(colors)
verts, faces = fp.prim_pentagonalprism()
res = fp.repeat_primitive(
verts,
Expand Down Expand Up @@ -2533,6 +2559,7 @@ def octagonalprism(centers, directions=(1, 0, 0), colors=(1, 0, 0), scales=1):
>>> # window.show(scene)

"""
colors = normalize_color(colors)
verts, faces = fp.prim_octagonalprism()
res = fp.repeat_primitive(
verts,
Expand Down Expand Up @@ -2582,6 +2609,7 @@ def frustum(centers, directions=(1, 0, 0), colors=(0, 1, 0), scales=1):
>>> # window.show(scene)

"""
colors = normalize_color(colors)
verts, faces = fp.prim_frustum()
res = fp.repeat_primitive(
verts,
Expand Down Expand Up @@ -2653,6 +2681,8 @@ def have_2_dimensions(arr):
else:
roundness = np.array(roundness)

colors = normalize_color(colors)

res = fp.repeat_primitive_function(
func=fp.prim_superquadric,
centers=centers,
Expand Down Expand Up @@ -2715,6 +2745,7 @@ def billboard(
-------
billboard_actor: Actor
"""
colors = normalize_color(colors)
verts, faces = fp.prim_square()
res = fp.repeat_primitive(
verts, faces, centers=centers, colors=colors, scales=scales
Expand Down Expand Up @@ -2925,6 +2956,7 @@ def add_to_scene(scene):

texta.SetMapper(textm)

color = normalize_color(color)
texta.GetProperty().SetColor(color)

# Set ser rotation origin to the center of the text is following the camera
Expand Down Expand Up @@ -3047,6 +3079,8 @@ def get_position(self):
text_actor.set_position(position)
text_actor.font_family(font_family)
text_actor.font_style(bold, italic, shadow)

color = normalize_color(color)
text_actor.color(color)
text_actor.justification(justification)
text_actor.vertical_justification(vertical_justification)
Expand All @@ -3071,6 +3105,7 @@ class Container:
Default: (0, 0, 0, 0, 0, 0).

"""

def __init__(self, layout=layout.Layout()):
"""

Expand Down Expand Up @@ -3347,7 +3382,7 @@ def texture(rgb, interp=True):
act: Actor

"""
arr = rgb
arr = normalize_color(rgb)
grid = rgb_to_vtk(np.ascontiguousarray(arr))

Y, X = arr.shape[:2]
Expand Down Expand Up @@ -3528,6 +3563,7 @@ def sdf(centers, directions=(1, 0, 0), colors=(1, 0, 0), primitives='torus', sca
"""
prims = {'sphere': 1, 'torus': 2, 'ellipsoid': 3, 'capsule': 4}

colors = normalize_color(colors)
verts, faces = fp.prim_box()
repeated = fp.repeat_primitive(
verts,
Expand Down Expand Up @@ -3640,6 +3676,7 @@ def markers(
>>> # window.show(scene, size=(600, 600))

"""
colors = normalize_color(colors)
n_markers = centers.shape[0]
verts, faces = fp.prim_square()
res = fp.repeat_primitive(
Expand Down
44 changes: 41 additions & 3 deletions fury/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ def test_color_check():
npt.assert_equal(global_opacity, 1)

points = np.array([[0, 0, 0], [0, 1, 0], [1, 0, 0]])
colors = (1, 1, 1, 0.5)
colors = np.array([1, 1, 1, 0.5])

color_tuple = color_check(len(points), colors)
color_array, global_opacity = color_tuple
Expand All @@ -848,7 +848,7 @@ def test_color_check():
npt.assert_equal(global_opacity, 0.5)

points = np.array([[0, 0, 0], [0, 1, 0], [1, 0, 0]])
colors = (1, 0, 0)
colors = np.array([1, 0, 0])

color_tuple = color_check(len(points), colors)
color_array, global_opacity = color_tuple
Expand All @@ -865,6 +865,44 @@ def test_color_check():
npt.assert_equal(global_opacity, 1)


def test_normalize_color():
# Test input None in color
none_color = None
assert utils.normalize_color(none_color) == None

# Test 2d input data
valid_color_array = np.array([[0.1, 0.2, 0.3, 0.4], [0.4, 0.5, 0.6, 0.7]])
outbound_color_array = [[0.1, 0.2, 1.0, 0.3], [255, 255, 255, 0.7]]
outbound_color_array_expected = np.array(
[[0.1, 0.2, 1.0, 0.3], [1.0, 1.0, 1.0, 0.7]])

# Test for valid 2d input
npt.assert_array_equal(utils.normalize_color(
valid_color_array), valid_color_array)

# Test for invalid 2d input
npt.assert_array_equal(utils.normalize_color(
outbound_color_array), outbound_color_array_expected)

# Test for input of type tuple
color_tuple = (0.1, 0.2, 0.3)
color_tuple_expected = np.array([0.1, 0.2, 0.3])
npt.assert_array_equal(utils.normalize_color(color_tuple), color_tuple_expected)

# Test for input of type list
color_list = [100, 150, 200, 0.4]
Clarkszw marked this conversation as resolved.
Show resolved Hide resolved
color_list_expected = np.array(color_list)
color_list_expected[:3] = color_list_expected[:3]/255.0
npt.assert_array_equal(
utils.normalize_color(color_list), color_list_expected)

# Test for input of type 1d np.array
color_1d = np.array([0.1, 0.5, 0.9, 0.3])
color_1d_expected = np.array([0.1, 0.5, 0.9, 0.3])
npt.assert_array_equal(
utils.normalize_color(color_1d), color_1d_expected)


def test_is_ui():
panel = Panel2D(position=(0, 0), size=(100, 100))
valid_ui = DummyUI(act=[])
Expand All @@ -885,7 +923,7 @@ def test_empty_array_to_polydata():
npt.assert_raises(ValueError, utils.lines_to_vtk_polydata, lines)


@pytest.mark.skipif(not have_dipy, reason='Requires DIPY')
@ pytest.mark.skipif(not have_dipy, reason='Requires DIPY')
def test_empty_array_sequence_to_polydata():
from dipy.tracking.streamline import Streamlines

Expand Down
Loading