From 1bc725aba82a61fa8046574f0638c53827ad7b27 Mon Sep 17 00:00:00 2001 From: Manish Reddy Rakasi Date: Mon, 27 Jan 2025 23:34:32 -0500 Subject: [PATCH 01/11] NF: Adding actor for Tetrahedron, TEST: Adding uni tests for Tetrahedron --- fury/actor.py | 64 ++++++++++++++++++++++++++++++++++++++++ fury/tests/test_actor.py | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/fury/actor.py b/fury/actor.py index 613d0f295..60265ebba 100644 --- a/fury/actor.py +++ b/fury/actor.py @@ -441,3 +441,67 @@ def frustum( material=material, enable_picking=enable_picking, ) + + +def tetrahedron( + centers, + *, + directions=(0, 0, 0), + colors=(1, 1, 1), + scales=(1, 1, 1), + opacity=None, + material="phong", + enable_picking=True, +): + """Visualize one or many tetrahedrons with different features. + + Parameters + ---------- + centers : ndarray, shape (N, 3) + tetrahedron positions. + directions : ndarray, shape (N, 3), optional + The orientation vector of the tetrahedron. + colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional + RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. + scales : int or ndarray (N,3) or tuple (3,), optional + The size of the tetrahedron in each dimension. If a single value is provided, + the same size will be used for all tetrahedron. + opacity : float, optional + Takes values from 0 (fully transparent) to 1 (opaque). + If both `opacity` and RGBA are provided, the final alpha will be: + final_alpha = alpha_in_RGBA * opacity + material : str, optional + The material type for the tetrahedrons. Options are 'phong' and 'basic'. + enable_picking : bool, optional + Whether the tetrahedrons should be pickable in a 3D scene. + + Returns + ------- + mesh_actor : Actor + A mesh actor containing the generated tetrahedrons, with the specified + material and properties. + + Examples + -------- + >>> from fury import window, actor + >>> import numpy as np + >>> scene = window.Scene() + >>> centers = np.random.rand(5, 3) * 10 + >>> colors = np.random.rand(5, 3) + >>> tetrahedron_actor = actor.tetrahedron(centers=centers, colors=colors) + >>> scene.add(tetrahedron_actor) + >>> show_manager = window.ShowManager(scene=scene, size=(600, 600)) + >>> show_manager.start() + """ + vertices, faces = fp.prim_tetrahedron() + return actor_from_primitive( + vertices, + faces, + centers=centers, + colors=colors, + scales=scales, + directions=directions, + opacity=opacity, + material=material, + enable_picking=enable_picking, + ) diff --git a/fury/tests/test_actor.py b/fury/tests/test_actor.py index de5c0c77a..71b439fb2 100644 --- a/fury/tests/test_actor.py +++ b/fury/tests/test_actor.py @@ -229,3 +229,60 @@ def test_frustum(): assert g == 0 and b == 0 assert r == 255 scene.remove(frustum_actor_2) + + +def test_tetrahedron(): + scene = window.Scene() + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + + tetrahedron_actor = actor.tetrahedron(centers=centers, colors=colors) + scene.add(tetrahedron_actor) + + npt.assert_array_equal(tetrahedron_actor.local.position, centers[0]) + + mean_vertex = np.mean(tetrahedron_actor.geometry.positions.view, axis=0) + npt.assert_array_almost_equal(mean_vertex, centers[0]) + + assert tetrahedron_actor.prim_count == 1 + + window.snapshot(scene=scene, fname="tetrahedron_test_1.png") + + img = Image.open("tetrahedron_test_1.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == b + scene.remove(tetrahedron_actor) + + tetrahedron_actor_2 = actor.tetrahedron( + centers=centers, colors=colors, material="basic" + ) + scene.add(tetrahedron_actor_2) + window.snapshot(scene=scene, fname="tetrahedron_test_2.png") + + img = Image.open("tetrahedron_test_2.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + assert 0 < mean_r < 255 + assert mean_g == 0 and mean_b == 0 + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == 0 and b == 0 + assert r == 255 + scene.remove(tetrahedron_actor_2) From 27200f296dbbc777e501c0ada9f1036cb09e3eba Mon Sep 17 00:00:00 2001 From: Manish Reddy Rakasi Date: Tue, 28 Jan 2025 13:09:59 -0500 Subject: [PATCH 02/11] NF:Added actor for icosahedron, TEST: Added uni tests for icosahedron --- fury/actor.py | 64 ++++++++++++++++++++++++++++++++++++++++ fury/tests/test_actor.py | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/fury/actor.py b/fury/actor.py index 60265ebba..d488904af 100644 --- a/fury/actor.py +++ b/fury/actor.py @@ -505,3 +505,67 @@ def tetrahedron( material=material, enable_picking=enable_picking, ) + + +def icosahedron( + centers, + *, + directions=(0, 0, 0), + colors=(1, 1, 1), + scales=(1, 1, 1), + opacity=None, + material="phong", + enable_picking=True, +): + """Visualize one or many icosahedrons with different features. + + Parameters + ---------- + centers : ndarray, shape (N, 3) + icosahedron positions. + directions : ndarray, shape (N, 3), optional + The orientation vector of the icosahedron. + colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional + RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. + scales : int or ndarray (N,3) or tuple (3,), optional + The size of the icosahedron in each dimension. If a single value is provided, + the same size will be used for all icosahedron. + opacity : float, optional + Takes values from 0 (fully transparent) to 1 (opaque). + If both `opacity` and RGBA are provided, the final alpha will be: + final_alpha = alpha_in_RGBA * opacity + material : str, optional + The material type for the icosahedrons. Options are 'phong' and 'basic'. + enable_picking : bool, optional + Whether the icosahedrons should be pickable in a 3D scene. + + Returns + ------- + mesh_actor : Actor + A mesh actor containing the generated icosahedrons, with the specified + material and properties. + + Examples + -------- + >>> from fury import window, actor + >>> import numpy as np + >>> scene = window.Scene() + >>> centers = np.random.rand(5, 3) * 10 + >>> colors = np.random.rand(5, 3) + >>> icosahedron_actor = actor.icosahedron(centers=centers, colors=colors) + >>> scene.add(icosahedron_actor) + >>> show_manager = window.ShowManager(scene=scene, size=(600, 600)) + >>> show_manager.start() + """ + vertices, faces = fp.prim_icosahedron() + return actor_from_primitive( + vertices, + faces, + centers=centers, + colors=colors, + scales=scales, + directions=directions, + opacity=opacity, + material=material, + enable_picking=enable_picking, + ) diff --git a/fury/tests/test_actor.py b/fury/tests/test_actor.py index 71b439fb2..68886f24b 100644 --- a/fury/tests/test_actor.py +++ b/fury/tests/test_actor.py @@ -286,3 +286,60 @@ def test_tetrahedron(): assert g == 0 and b == 0 assert r == 255 scene.remove(tetrahedron_actor_2) + + +def test_icosahedron(): + scene = window.Scene() + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + + icosahedron_actor = actor.icosahedron(centers=centers, colors=colors) + scene.add(icosahedron_actor) + + npt.assert_array_equal(icosahedron_actor.local.position, centers[0]) + + mean_vertex = np.mean(icosahedron_actor.geometry.positions.view, axis=0) + npt.assert_array_almost_equal(mean_vertex, centers[0]) + + assert icosahedron_actor.prim_count == 1 + + window.snapshot(scene=scene, fname="icosahedron_test_1.png") + + img = Image.open("icosahedron_test_1.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == b + scene.remove(icosahedron_actor) + + icosahedron_actor_2 = actor.icosahedron( + centers=centers, colors=colors, material="basic" + ) + scene.add(icosahedron_actor_2) + window.snapshot(scene=scene, fname="icosahedron_test_2.png") + + img = Image.open("icosahedron_test_2.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + assert 0 < mean_r < 255 + assert mean_g == 0 and mean_b == 0 + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == 0 and b == 0 + assert r == 255 + scene.remove(icosahedron_actor_2) From 9ff2329799652e8455f868763bb2036bdf6dac91 Mon Sep 17 00:00:00 2001 From: Manish Reddy Rakasi Date: Tue, 28 Jan 2025 16:47:02 -0500 Subject: [PATCH 03/11] NF: Added actor for rhombicuboctahedron, TEST: Added uni tests for rhombicuboctahedron. --- fury/actor.py | 66 ++++++++++++++++++++++++++++++++++++++++ fury/tests/test_actor.py | 59 +++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/fury/actor.py b/fury/actor.py index d488904af..b7b8ca51e 100644 --- a/fury/actor.py +++ b/fury/actor.py @@ -569,3 +569,69 @@ def icosahedron( material=material, enable_picking=enable_picking, ) + + +def rhombicuboctahedron( + centers, + *, + directions=(0, 0, 0), + colors=(1, 1, 1), + scales=(1, 1, 1), + opacity=None, + material="phong", + enable_picking=True, +): + """Visualize one or many rhombicuboctahedrons with different features. + + Parameters + ---------- + centers : ndarray, shape (N, 3) + rhombicuboctahedron positions. + directions : ndarray, shape (N, 3), optional + The orientation vector of the rhombicuboctahedron. + colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional + RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. + scales : int or ndarray (N,3) or tuple (3,), optional + The size of the rhombicuboctahedro in each dimension. If a single value is + provided, the same size will be used for all rhombicuboctahedron. + opacity : float, optional + Takes values from 0 (fully transparent) to 1 (opaque). + If both `opacity` and RGBA are provided, the final alpha will be: + final_alpha = alpha_in_RGBA * opacity + material : str, optional + The material type for the rhombicuboctahedrons. Options are 'phong' and 'basic'. + enable_picking : bool, optional + Whether the rhombicuboctahedrons should be pickable in a 3D scene. + + Returns + ------- + mesh_actor : Actor + A mesh actor containing the generated rhombicuboctahedrons, with the specified + material and properties. + + Examples + -------- + >>> from fury import window, actor + >>> import numpy as np + >>> scene = window.Scene() + >>> centers = np.random.rand(5, 3) * 10 + >>> colors = np.random.rand(5, 3) + >>> rhombicuboctahedron_actor = actor.rhombicuboctahedron( + centers=centers, colors=colors + ) + >>> scene.add(rhombicuboctahedron_actor) + >>> show_manager = window.ShowManager(scene=scene, size=(600, 600)) + >>> show_manager.start() + """ + vertices, faces = fp.prim_rhombicuboctahedron() + return actor_from_primitive( + vertices, + faces, + centers=centers, + colors=colors, + scales=scales, + directions=directions, + opacity=opacity, + material=material, + enable_picking=enable_picking, + ) diff --git a/fury/tests/test_actor.py b/fury/tests/test_actor.py index 68886f24b..ff4a84d54 100644 --- a/fury/tests/test_actor.py +++ b/fury/tests/test_actor.py @@ -343,3 +343,62 @@ def test_icosahedron(): assert g == 0 and b == 0 assert r == 255 scene.remove(icosahedron_actor_2) + + +def test_rhombicuboctahedron(): + scene = window.Scene() + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + + rhombicuboctahedron_actor = actor.rhombicuboctahedron( + centers=centers, colors=colors + ) + scene.add(rhombicuboctahedron_actor) + + npt.assert_array_equal(rhombicuboctahedron_actor.local.position, centers[0]) + + mean_vertex = np.mean(rhombicuboctahedron_actor.geometry.positions.view, axis=0) + npt.assert_array_almost_equal(mean_vertex, centers[0]) + + assert rhombicuboctahedron_actor.prim_count == 1 + + window.snapshot(scene=scene, fname="rhombicuboctahedron_test_1.png") + + img = Image.open("rhombicuboctahedron_test_1.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == b + scene.remove(rhombicuboctahedron_actor) + + rhombicuboctahedron_actor_2 = actor.rhombicuboctahedron( + centers=centers, colors=colors, material="basic" + ) + scene.add(rhombicuboctahedron_actor_2) + window.snapshot(scene=scene, fname="rhombicuboctahedron_test_2.png") + + img = Image.open("rhombicuboctahedron_test_2.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + assert 0 < mean_r < 255 + assert mean_g == 0 and mean_b == 0 + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == 0 and b == 0 + assert r == 255 + scene.remove(rhombicuboctahedron_actor_2) From e4245bca95bb76b46a1614620ca5c36ce1323b75 Mon Sep 17 00:00:00 2001 From: Manish Reddy Rakasi Date: Tue, 28 Jan 2025 17:04:07 -0500 Subject: [PATCH 04/11] NF: Adding actor for triangularprism, TEST: Adding uni tests for triangularprism. --- fury/actor.py | 65 ++++++++++++++++++++++++++++++++++++++++ fury/tests/test_actor.py | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/fury/actor.py b/fury/actor.py index b7b8ca51e..fffa92974 100644 --- a/fury/actor.py +++ b/fury/actor.py @@ -635,3 +635,68 @@ def rhombicuboctahedron( material=material, enable_picking=enable_picking, ) + + +def triangularprism( + centers, + *, + directions=(0, 0, 0), + colors=(1, 1, 1), + scales=(1, 1, 1), + opacity=None, + material="phong", + enable_picking=True, +): + """Visualize one or many triangularprism with different features. + + Parameters + ---------- + centers : ndarray, shape (N, 3) + triangularprism positions. + directions : ndarray, shape (N, 3), optional + The orientation vector of the triangularprism. + colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional + RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. + scales : int or ndarray (N,3) or tuple (3,), optional + The size of the triangularprism in each dimension. If a single value is + provided, the same size will be used for all triangularprism. + opacity : float, optional + Takes values from 0 (fully transparent) to 1 (opaque). + If both `opacity` and RGBA are provided, the final alpha will be: + final_alpha = alpha_in_RGBA * opacity + material : str, optional + The material type for the triangularprisms. Options are 'phong' and 'basic'. + enable_picking : bool, optional + Whether the triangularprisms should be pickable in a 3D scene. + + Returns + ------- + mesh_actor : Actor + A mesh actor containing the generated triangularprisms, with the specified + material and properties. + + Examples + -------- + >>> from fury import window, actor + >>> import numpy as np + >>> scene = window.Scene() + >>> centers = np.random.rand(5, 3) * 10 + >>> colors = np.random.rand(5, 3) + >>> triangularprism_actor = actor.triangularprism( + centers=centers, colors=colors) + >>> scene.add(triangularprism_actor) + >>> show_manager = window.ShowManager(scene=scene, size=(600, 600)) + >>> show_manager.start() + """ + vertices, faces = fp.prim_triangularprism() + return actor_from_primitive( + vertices, + faces, + centers=centers, + colors=colors, + scales=scales, + directions=directions, + opacity=opacity, + material=material, + enable_picking=enable_picking, + ) diff --git a/fury/tests/test_actor.py b/fury/tests/test_actor.py index ff4a84d54..115b4cb1c 100644 --- a/fury/tests/test_actor.py +++ b/fury/tests/test_actor.py @@ -402,3 +402,60 @@ def test_rhombicuboctahedron(): assert g == 0 and b == 0 assert r == 255 scene.remove(rhombicuboctahedron_actor_2) + + +def test_triangularprism(): + scene = window.Scene() + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + + triangularprism_actor = actor.triangularprism(centers=centers, colors=colors) + scene.add(triangularprism_actor) + + npt.assert_array_equal(triangularprism_actor.local.position, centers[0]) + + mean_vertex = np.mean(triangularprism_actor.geometry.positions.view, axis=0) + npt.assert_array_almost_equal(mean_vertex, centers[0]) + + assert triangularprism_actor.prim_count == 1 + + window.snapshot(scene=scene, fname="triangularprism_test_1.png") + + img = Image.open("triangularprism_test_1.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == b + scene.remove(triangularprism_actor) + + triangularprism_actor_2 = actor.triangularprism( + centers=centers, colors=colors, material="basic" + ) + scene.add(triangularprism_actor_2) + window.snapshot(scene=scene, fname="triangularprism_test_2.png") + + img = Image.open("triangularprism_test_2.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + assert 0 < mean_r < 255 + assert mean_g == 0 and mean_b == 0 + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == 0 and b == 0 + assert r == 255 + scene.remove(triangularprism_actor_2) From b1bf94274c313896bf987136207279fb45805428 Mon Sep 17 00:00:00 2001 From: Manish Reddy Rakasi Date: Tue, 28 Jan 2025 17:44:58 -0500 Subject: [PATCH 05/11] NF: Added actor for pentagonalprism, TEST: Added uni tests for pentagonalprism. --- fury/actor.py | 65 ++++++++++++++++++++++++++++++++++++++++ fury/tests/test_actor.py | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/fury/actor.py b/fury/actor.py index fffa92974..2a42e05dd 100644 --- a/fury/actor.py +++ b/fury/actor.py @@ -700,3 +700,68 @@ def triangularprism( material=material, enable_picking=enable_picking, ) + + +def pentagonalprism( + centers, + *, + directions=(0, 0, 0), + colors=(1, 1, 1), + scales=(1, 1, 1), + opacity=None, + material="phong", + enable_picking=True, +): + """Visualize one or many pentagonalprism with different features. + + Parameters + ---------- + centers : ndarray, shape (N, 3) + pentagonalprism positions. + directions : ndarray, shape (N, 3), optional + The orientation vector of the pentagonalprism. + colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional + RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. + scales : int or ndarray (N,3) or tuple (3,), optional + The size of the pentagonalprism in each dimension. If a single value is + provided, the same size will be used for all pentagonalprism. + opacity : float, optional + Takes values from 0 (fully transparent) to 1 (opaque). + If both `opacity` and RGBA are provided, the final alpha will be: + final_alpha = alpha_in_RGBA * opacity + material : str, optional + The material type for the pentagonalprisms. Options are 'phong' and 'basic'. + enable_picking : bool, optional + Whether the pentagonalprisms should be pickable in a 3D scene. + + Returns + ------- + mesh_actor : Actor + A mesh actor containing the generated pentagonalprism, with the specified + material and properties. + + Examples + -------- + >>> from fury import window, actor + >>> import numpy as np + >>> scene = window.Scene() + >>> centers = np.random.rand(5, 3) * 10 + >>> colors = np.random.rand(5, 3) + >>> pentagonalprism_actor = actor.pentagonalprism( + centers=centers, colors=colors) + >>> scene.add(pentagonalprism_actor) + >>> show_manager = window.ShowManager(scene=scene, size=(600, 600)) + >>> show_manager.start() + """ + vertices, faces = fp.prim_pentagonalprism() + return actor_from_primitive( + vertices, + faces, + centers=centers, + colors=colors, + scales=scales, + directions=directions, + opacity=opacity, + material=material, + enable_picking=enable_picking, + ) diff --git a/fury/tests/test_actor.py b/fury/tests/test_actor.py index 115b4cb1c..5fe99d78b 100644 --- a/fury/tests/test_actor.py +++ b/fury/tests/test_actor.py @@ -459,3 +459,60 @@ def test_triangularprism(): assert g == 0 and b == 0 assert r == 255 scene.remove(triangularprism_actor_2) + + +def test_pentagonalprism(): + scene = window.Scene() + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + + pentagonalprism_actor = actor.pentagonalprism(centers=centers, colors=colors) + scene.add(pentagonalprism_actor) + + npt.assert_array_equal(pentagonalprism_actor.local.position, centers[0]) + + mean_vertex = np.mean(pentagonalprism_actor.geometry.positions.view, axis=0) + npt.assert_array_almost_equal(mean_vertex, centers[0]) + + assert pentagonalprism_actor.prim_count == 1 + + window.snapshot(scene=scene, fname="pentagonalprism_test_1.png") + + img = Image.open("pentagonalprism_test_1.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == b + scene.remove(pentagonalprism_actor) + + pentagonalprism_actor_2 = actor.pentagonalprism( + centers=centers, colors=colors, material="basic" + ) + scene.add(pentagonalprism_actor_2) + window.snapshot(scene=scene, fname="pentagonalprism_test_2.png") + + img = Image.open("pentagonalprism_test_2.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + assert 0 < mean_r < 255 + assert mean_g == 0 and mean_b == 0 + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == 0 and b == 0 + assert r == 255 + scene.remove(pentagonalprism_actor_2) From 90c6b3ae9678686f82d1bb04dfd85a4a465a4e94 Mon Sep 17 00:00:00 2001 From: Manish Reddy Rakasi Date: Tue, 28 Jan 2025 19:18:38 -0500 Subject: [PATCH 06/11] NF: Adding actor for octogonal prism, TEST: Adding uni tests for octogonal prism. --- fury/actor.py | 97 +++++++++++++++++++++++++++++++++------- fury/tests/test_actor.py | 57 +++++++++++++++++++++++ 2 files changed, 138 insertions(+), 16 deletions(-) diff --git a/fury/actor.py b/fury/actor.py index 2a42e05dd..751aad935 100644 --- a/fury/actor.py +++ b/fury/actor.py @@ -647,32 +647,32 @@ def triangularprism( material="phong", enable_picking=True, ): - """Visualize one or many triangularprism with different features. + """Visualize one or many triangular prism with different features. Parameters ---------- centers : ndarray, shape (N, 3) - triangularprism positions. + triangular prism positions. directions : ndarray, shape (N, 3), optional - The orientation vector of the triangularprism. + The orientation vector of the triangular prism. colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. scales : int or ndarray (N,3) or tuple (3,), optional - The size of the triangularprism in each dimension. If a single value is - provided, the same size will be used for all triangularprism. + The size of the triangular prism in each dimension. If a single value is + provided, the same size will be used for all triangular prism. opacity : float, optional Takes values from 0 (fully transparent) to 1 (opaque). If both `opacity` and RGBA are provided, the final alpha will be: final_alpha = alpha_in_RGBA * opacity material : str, optional - The material type for the triangularprisms. Options are 'phong' and 'basic'. + The material type for the triangular prisms. Options are 'phong' and 'basic'. enable_picking : bool, optional - Whether the triangularprisms should be pickable in a 3D scene. + Whether the triangular prisms should be pickable in a 3D scene. Returns ------- mesh_actor : Actor - A mesh actor containing the generated triangularprisms, with the specified + A mesh actor containing the generated triangular prisms, with the specified material and properties. Examples @@ -712,32 +712,32 @@ def pentagonalprism( material="phong", enable_picking=True, ): - """Visualize one or many pentagonalprism with different features. + """Visualize one or many pentagonal prism with different features. Parameters ---------- centers : ndarray, shape (N, 3) - pentagonalprism positions. + pentagonal prism positions. directions : ndarray, shape (N, 3), optional - The orientation vector of the pentagonalprism. + The orientation vector of the pentagonal prism. colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. scales : int or ndarray (N,3) or tuple (3,), optional - The size of the pentagonalprism in each dimension. If a single value is - provided, the same size will be used for all pentagonalprism. + The size of the pentagonal prism in each dimension. If a single value is + provided, the same size will be used for all pentagonal prism. opacity : float, optional Takes values from 0 (fully transparent) to 1 (opaque). If both `opacity` and RGBA are provided, the final alpha will be: final_alpha = alpha_in_RGBA * opacity material : str, optional - The material type for the pentagonalprisms. Options are 'phong' and 'basic'. + The material type for the pentagonal prisms. Options are 'phong' and 'basic'. enable_picking : bool, optional - Whether the pentagonalprisms should be pickable in a 3D scene. + Whether the pentagonal prisms should be pickable in a 3D scene. Returns ------- mesh_actor : Actor - A mesh actor containing the generated pentagonalprism, with the specified + A mesh actor containing the generated pentagonal prism, with the specified material and properties. Examples @@ -765,3 +765,68 @@ def pentagonalprism( material=material, enable_picking=enable_picking, ) + + +def octagonalprism( + centers, + *, + directions=(0, 0, 0), + colors=(1, 1, 1), + scales=(1, 1, 1), + opacity=None, + material="phong", + enable_picking=True, +): + """Visualize one or many octagonal prism with different features. + + Parameters + ---------- + centers : ndarray, shape (N, 3) + octagonal prism positions. + directions : ndarray, shape (N, 3), optional + The orientation vector of the octagonal prism. + colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional + RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. + scales : int or ndarray (N,3) or tuple (3,), optional + The size of the octagonal prism in each dimension. If a single value is + provided, the same size will be used for all octagonal prism. + opacity : float, optional + Takes values from 0 (fully transparent) to 1 (opaque). + If both `opacity` and RGBA are provided, the final alpha will be: + final_alpha = alpha_in_RGBA * opacity + material : str, optional + The material type for the octagonal prisms. Options are 'phong' and 'basic'. + enable_picking : bool, optional + Whether the octagonal prisms should be pickable in a 3D scene. + + Returns + ------- + mesh_actor : Actor + A mesh actor containing the generated octagonal prisms, with the specified + material and properties. + + Examples + -------- + >>> from fury import window, actor + >>> import numpy as np + >>> scene = window.Scene() + >>> centers = np.random.rand(5, 3) * 10 + >>> colors = np.random.rand(5, 3) + >>> octagonalprism_actor = actor.octagonalprism( + centers=centers, colors=colors) + >>> scene.add(octagonalprism_actor) + >>> show_manager = window.ShowManager(scene=scene, size=(600, 600)) + >>> show_manager.start() + """ + vertices, faces = fp.prim_octagonalprism() + return actor_from_primitive( + vertices, + faces, + centers=centers, + colors=colors, + scales=scales, + directions=directions, + opacity=opacity, + material=material, + enable_picking=enable_picking, + ) diff --git a/fury/tests/test_actor.py b/fury/tests/test_actor.py index 5fe99d78b..16384f5c4 100644 --- a/fury/tests/test_actor.py +++ b/fury/tests/test_actor.py @@ -516,3 +516,60 @@ def test_pentagonalprism(): assert g == 0 and b == 0 assert r == 255 scene.remove(pentagonalprism_actor_2) + + +def test_octagonalprism(): + scene = window.Scene() + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + + octagonalprism_actor = actor.octagonalprism(centers=centers, colors=colors) + scene.add(octagonalprism_actor) + + npt.assert_array_equal(octagonalprism_actor.local.position, centers[0]) + + mean_vertex = np.mean(octagonalprism_actor.geometry.positions.view, axis=0) + npt.assert_array_almost_equal(mean_vertex, centers[0]) + + assert octagonalprism_actor.prim_count == 1 + + window.snapshot(scene=scene, fname="octagonalprism_test_1.png") + + img = Image.open("octagonalprism_test_1.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == b + scene.remove(octagonalprism_actor) + + octagonalprism_actor_2 = actor.octagonalprism( + centers=centers, colors=colors, material="basic" + ) + scene.add(octagonalprism_actor_2) + window.snapshot(scene=scene, fname="octagonalprism_test_2.png") + + img = Image.open("octagonalprism_test_2.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + assert 0 < mean_r < 255 + assert mean_g == 0 and mean_b == 0 + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == 0 and b == 0 + assert r == 255 + scene.remove(octagonalprism_actor_2) From 9e3d602cc5a851cb596bfa8fc013c349fb12e5df Mon Sep 17 00:00:00 2001 From: Manish Reddy Rakasi Date: Tue, 28 Jan 2025 22:47:49 -0500 Subject: [PATCH 07/11] NF: Adding actor for arrow, TEST: Adding uni tests for arrow actor. --- fury/actor.py | 87 ++++++++++++++++++++++++++++++++++++++++ fury/tests/test_actor.py | 52 ++++++++++++++++++++++++ 2 files changed, 139 insertions(+) diff --git a/fury/actor.py b/fury/actor.py index 751aad935..a024c378b 100644 --- a/fury/actor.py +++ b/fury/actor.py @@ -830,3 +830,90 @@ def octagonalprism( material=material, enable_picking=enable_picking, ) + + +def arrow( + centers, + *, + directions=(0, 0, 0), + colors=(1, 1, 1), + height=1.0, + resolution=10, + tip_length=0.35, + tip_radius=0.1, + shaft_radius=0.03, + scales=(1, 1, 1), + opacity=None, + material="phong", + enable_picking=True, +): + """Visualize one or many arrows with different features. + + Parameters + ---------- + centers : ndarray, shape (N, 3) + arrow positions. + directions : ndarray, shape (N, 3), optional + The orientation vector of the arrow. + colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional + RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. + height : float, optional + The total height of the arrow, including the shaft and tip. Default is 1.0. + resolution : int, optional + The number of divisions along the arrow's circular cross-sections. + Higher values produce smoother arrows. Default is 10. + tip_length : float, optional + The length of the arrowhead tip relative to the total height. Default is 0.35. + tip_radius : float, optional + The radius of the arrowhead tip. Default is 0.1. + shaft_radius : float, optional + The radius of the arrow shaft. Default is 0.03. + scales : int or ndarray (N,3) or tuple (3,), optional + The size of the arrow in each dimension. If a single value is + provided, the same size will be used for all arrow. + opacity : float, optional + Takes values from 0 (fully transparent) to 1 (opaque). + If both `opacity` and RGBA are provided, the final alpha will be: + final_alpha = alpha_in_RGBA * opacity + material : str, optional + The material type for the arrows. Options are 'phong' and 'basic'. + enable_picking : bool, optional + Whether the arrows should be pickable in a 3D scene. + + Returns + ------- + mesh_actor : Actor + A mesh actor containing the generated arrows, with the specified + material and properties. + + Examples + -------- + >>> from fury import window, actor + >>> import numpy as np + >>> scene = window.Scene() + >>> centers = np.random.rand(5, 3) * 10 + >>> colors = np.random.rand(5, 3) + >>> arrow_actor = actor.arrow(centers=centers, colors=colors) + >>> scene.add(arrow_actor) + >>> show_manager = window.ShowManager(scene=scene, size=(600, 600)) + >>> show_manager.start() + """ + + vertices, faces = fp.prim_arrow( + height=height, + resolution=resolution, + tip_length=tip_length, + tip_radius=tip_radius, + shaft_radius=shaft_radius, + ) + return actor_from_primitive( + vertices, + faces, + centers=centers, + colors=colors, + scales=scales, + directions=directions, + opacity=opacity, + material=material, + enable_picking=enable_picking, + ) diff --git a/fury/tests/test_actor.py b/fury/tests/test_actor.py index 16384f5c4..04404d0d4 100644 --- a/fury/tests/test_actor.py +++ b/fury/tests/test_actor.py @@ -573,3 +573,55 @@ def test_octagonalprism(): assert g == 0 and b == 0 assert r == 255 scene.remove(octagonalprism_actor_2) + + +def test_arrow(): + scene = window.Scene() + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + + arrow_actor = actor.arrow(centers=centers, colors=colors) + scene.add(arrow_actor) + + npt.assert_array_equal(arrow_actor.local.position, centers[0]) + + assert arrow_actor.prim_count == 1 + + window.snapshot(scene=scene, fname="arrow_test_1.png") + + img = Image.open("arrow_test_1.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == b + scene.remove(arrow_actor) + + arrow_actor_2 = actor.arrow(centers=centers, colors=colors, material="basic") + scene.add(arrow_actor_2) + window.snapshot(scene=scene, fname="arrow_test_2.png") + + img = Image.open("arrow_test_2.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + assert 0 < mean_r < 255 + assert mean_g == 0 and mean_b == 0 + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == 0 and b == 0 + assert r == 255 + scene.remove(arrow_actor_2) From 53561ae93114de7074622b2e206b7afdf749f45d Mon Sep 17 00:00:00 2001 From: Manish Reddy Rakasi Date: Tue, 28 Jan 2025 23:26:58 -0500 Subject: [PATCH 08/11] NF:Adding actor for superquadric, TEST: Adding uni tests for superquadric. --- fury/actor.py | 68 ++++++++++++++++++++++++++++++++++++++++ fury/tests/test_actor.py | 57 +++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/fury/actor.py b/fury/actor.py index a024c378b..b44ce7a12 100644 --- a/fury/actor.py +++ b/fury/actor.py @@ -917,3 +917,71 @@ def arrow( material=material, enable_picking=enable_picking, ) + + +def superquadric( + centers, + *, + roundness=(1, 1), + directions=(0, 0, 0), + colors=(1, 1, 1), + scales=(1, 1, 1), + opacity=None, + material="phong", + enable_picking=True, +): + """Visualize one or many superquadric with different features. + + Parameters + ---------- + centers : ndarray, shape (N, 3) + superquadric positions. + directions : ndarray, shape (N, 3), optional + The orientation vector of the superquadric. + roundness : tuple, optional + parameters (Phi and Theta) that control the shape of the superquadric. + Default is (1,1). + colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional + RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. + scales : int or ndarray (N,3) or tuple (3,), optional + The size of the superquadric in each dimension. If a single value is + provided, the same size will be used for all superquadric. + opacity : float, optional + Takes values from 0 (fully transparent) to 1 (opaque). + If both `opacity` and RGBA are provided, the final alpha will be: + final_alpha = alpha_in_RGBA * opacity + material : str, optional + The material type for the superquadrics. Options are 'phong' and 'basic'. + enable_picking : bool, optional + Whether the superquadrics should be pickable in a 3D scene. + + Returns + ------- + mesh_actor : Actor + A mesh actor containing the generated superquadrics, with the specified + material and properties. + + Examples + -------- + >>> from fury import window, actor + >>> import numpy as np + >>> scene = window.Scene() + >>> centers = np.random.rand(5, 3) * 10 + >>> colors = np.random.rand(5, 3) + >>> superquadric_actor = actor.superquadric(centers=centers, colors=colors) + >>> scene.add(superquadric_actor) + >>> show_manager = window.ShowManager(scene=scene, size=(600, 600)) + >>> show_manager.start() + """ + vertices, faces = fp.prim_superquadric(roundness=roundness) + return actor_from_primitive( + vertices, + faces, + centers=centers, + colors=colors, + scales=scales, + directions=directions, + opacity=opacity, + material=material, + enable_picking=enable_picking, + ) diff --git a/fury/tests/test_actor.py b/fury/tests/test_actor.py index 04404d0d4..5807e2a61 100644 --- a/fury/tests/test_actor.py +++ b/fury/tests/test_actor.py @@ -625,3 +625,60 @@ def test_arrow(): assert g == 0 and b == 0 assert r == 255 scene.remove(arrow_actor_2) + + +def test_superquadric(): + scene = window.Scene() + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + + superquadric_actor = actor.superquadric(centers=centers, colors=colors) + scene.add(superquadric_actor) + + npt.assert_array_equal(superquadric_actor.local.position, centers[0]) + + mean_vertex = np.mean(superquadric_actor.geometry.positions.view, axis=0) + npt.assert_array_almost_equal(mean_vertex, centers[0]) + + assert superquadric_actor.prim_count == 1 + + window.snapshot(scene=scene, fname="superquadric_test_1.png") + + img = Image.open("superquadric_test_1.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == b + scene.remove(superquadric_actor) + + superquadric_actor_2 = actor.superquadric( + centers=centers, colors=colors, material="basic" + ) + scene.add(superquadric_actor_2) + window.snapshot(scene=scene, fname="superquadric_test_2.png") + + img = Image.open("superquadric_test_2.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + assert 0 < mean_r < 255 + assert mean_g == 0 and mean_b == 0 + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == 0 and b == 0 + assert r == 255 + scene.remove(superquadric_actor_2) From 60bd223faba7eec36fefe5107039176303189b66 Mon Sep 17 00:00:00 2001 From: Manish Reddy Rakasi Date: Thu, 30 Jan 2025 22:32:12 -0500 Subject: [PATCH 09/11] NF: Adding actor for cone, TEST: Adding uni tests for cone. --- fury/actor.py | 76 ++++++++++++++++++++++++++++++++++++++++ fury/tests/test_actor.py | 52 +++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/fury/actor.py b/fury/actor.py index b44ce7a12..01244a914 100644 --- a/fury/actor.py +++ b/fury/actor.py @@ -985,3 +985,79 @@ def superquadric( material=material, enable_picking=enable_picking, ) + + +def cone( + centers, + *, + colors=(1, 1, 1), + height=1, + sectors=10, + radii=0.5, + scales=(1, 1, 1), + directions=(0, 1, 0), + opacity=None, + material="phong", + enable_picking=True, +): + """Visualize one or many cones with different features. + + Parameters + ---------- + centers : ndarray, shape (N, 3) + cone positions. + colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional + RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. + height: float, optional + The height of the cone. Default is 1. + sectors: int, optional + The number of divisions around the cones's circumference . + Higher values produce smoother cones. Default is 10. + radii : float or ndarray (N,) or tuple, optional + The radius of the base of the cones, single value applies to all cones, + while an array specifies a radius for each cone individually. Default:0.5. + scales : int or ndarray (N, 3) or tuple (3,), optional + Scaling factors for the cones in the (x, y, z) dimensions. + Default is uniform scaling (1, 1, 1). + directions : ndarray, shape (N, 3), optional + The orientation vector of the cone. + opacity : float, optional + Takes values from 0 (fully transparent) to 1 (opaque). + If both `opacity` and RGBA are provided, the final alpha will be: + final_alpha = alpha_in_RGBA * opacity + material : str, optional + The material type for the cones. Options are 'phong' and 'basic'. + enable_picking : bool, optional + Whether the cones should be pickable in a 3D scene. + + Returns + ------- + mesh_actor : Actor + A mesh actor containing the generated cones, with the specified + material and properties. + + Examples + -------- + >>> from fury import window, actor + >>> import numpy as np + >>> scene = window.Scene() + >>> centers = np.random.rand(5, 3) * 10 + >>> colors = np.random.rand(5, 3) + >>> cone_actor = actor.cone(centers=centers, colors=colors) + >>> scene.add(cone_actor) + >>> show_manager = window.ShowManager(scene=scene, size=(600, 600)) + >>> show_manager.start() + """ + + vertices, faces = fp.prim_cone(radius=radii, height=height, sectors=sectors) + return actor_from_primitive( + vertices, + faces, + centers=centers, + colors=colors, + scales=scales, + directions=directions, + opacity=opacity, + material=material, + enable_picking=enable_picking, + ) diff --git a/fury/tests/test_actor.py b/fury/tests/test_actor.py index 5807e2a61..e6e04bd37 100644 --- a/fury/tests/test_actor.py +++ b/fury/tests/test_actor.py @@ -682,3 +682,55 @@ def test_superquadric(): assert g == 0 and b == 0 assert r == 255 scene.remove(superquadric_actor_2) + + +def test_cone(): + scene = window.Scene() + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + + cone_actor = actor.cone(centers=centers, colors=colors) + scene.add(cone_actor) + + npt.assert_array_equal(cone_actor.local.position, centers[0]) + + assert cone_actor.prim_count == 1 + + window.snapshot(scene=scene, fname="cone_test_1.png") + + img = Image.open("cone_test_1.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == b + scene.remove(cone_actor) + + cone_actor_2 = actor.cone(centers=centers, colors=colors, material="basic") + scene.add(cone_actor_2) + window.snapshot(scene=scene, fname="cone_test_2.png") + + img = Image.open("cone_test_2.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + assert 0 < mean_r < 255 + assert mean_g == 0 and mean_b == 0 + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == 0 and b == 0 + assert r == 255 + scene.remove(cone_actor_2) From de6c512f11c93641479d9a97a06b5d083253cd6d Mon Sep 17 00:00:00 2001 From: Manish Reddy Rakasi Date: Thu, 30 Jan 2025 22:48:33 -0500 Subject: [PATCH 10/11] NF:Adding actor for star, TEST:Adding unitests for star. --- fury/actor.py | 67 ++++++++++++++++++++++++++++++++++++++++ fury/tests/test_actor.py | 52 +++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/fury/actor.py b/fury/actor.py index 01244a914..4c8176996 100644 --- a/fury/actor.py +++ b/fury/actor.py @@ -1061,3 +1061,70 @@ def cone( material=material, enable_picking=enable_picking, ) + + +def star( + centers, + *, + dim=2, + directions=(0, 0, 0), + colors=(1, 1, 1), + scales=(1, 1, 1), + opacity=None, + material="phong", + enable_picking=True, +): + """Visualize one or many star with different features. + + Parameters + ---------- + centers : ndarray, shape (N, 3) + star positions. + dim : int, optional. + The dimensionality of the star (2D or 3D). Default is 2. + directions : ndarray, shape (N, 3), optional + The orientation vector of the star. + colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional + RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. + scales : int or ndarray (N,3) or tuple (3,), optional + The size of the star in each dimension. If a single value is + provided, the same size will be used for all star. + opacity : float, optional + Takes values from 0 (fully transparent) to 1 (opaque). + If both `opacity` and RGBA are provided, the final alpha will be: + final_alpha = alpha_in_RGBA * opacity + material : str, optional + The material type for the stars. Options are 'phong' and 'basic'. + enable_picking : bool, optional + Whether the stars should be pickable in a 3D scene. + + Returns + ------- + mesh_actor : Actor + A mesh actor containing the generated stars, with the specified + material and properties. + + Examples + -------- + >>> from fury import window, actor + >>> import numpy as np + >>> scene = window.Scene() + >>> centers = np.random.rand(5, 3) * 10 + >>> colors = np.random.rand(5, 3) + >>> star_actor = actor.star(centers=centers, colors=colors) + >>> scene.add(star_actor) + >>> show_manager = window.ShowManager(scene=scene, size=(600, 600)) + >>> show_manager.start() + """ + vertices, faces = fp.prim_star(dim=dim) + return actor_from_primitive( + vertices, + faces, + centers=centers, + colors=colors, + scales=scales, + directions=directions, + opacity=opacity, + material=material, + enable_picking=enable_picking, + ) diff --git a/fury/tests/test_actor.py b/fury/tests/test_actor.py index e6e04bd37..fdfe9e87f 100644 --- a/fury/tests/test_actor.py +++ b/fury/tests/test_actor.py @@ -734,3 +734,55 @@ def test_cone(): assert g == 0 and b == 0 assert r == 255 scene.remove(cone_actor_2) + + +def test_star(): + scene = window.Scene() + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + + star_actor = actor.star(centers=centers, colors=colors) + scene.add(star_actor) + + npt.assert_array_equal(star_actor.local.position, centers[0]) + + assert star_actor.prim_count == 1 + + window.snapshot(scene=scene, fname="star_test_1.png") + + img = Image.open("star_test_1.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == b + scene.remove(star_actor) + + star_actor_2 = actor.star(centers=centers, colors=colors, material="basic") + scene.add(star_actor_2) + window.snapshot(scene=scene, fname="star_test_2.png") + + img = Image.open("star_test_2.png") + img_array = np.array(img) + + mean_r, mean_g, mean_b, mean_a = np.mean( + img_array.reshape(-1, img_array.shape[2]), axis=0 + ) + + assert mean_r > mean_b and mean_r > mean_g + assert 0 < mean_r < 255 + assert mean_g == 0 and mean_b == 0 + + middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] + r, g, b, a = middle_pixel + assert r > g and r > b + assert g == 0 and b == 0 + assert r == 255 + scene.remove(star_actor_2) From 3a4e77b5fa6f64ccb63918b3e18987f01f12f63f Mon Sep 17 00:00:00 2001 From: Manish Reddy Rakasi Date: Fri, 31 Jan 2025 22:43:22 -0500 Subject: [PATCH 11/11] RF: Tried refactoring tests. --- fury/actor.py | 59 ++-- fury/tests/test_actor.py | 727 +++------------------------------------ 2 files changed, 73 insertions(+), 713 deletions(-) diff --git a/fury/actor.py b/fury/actor.py index 4c8176996..fb5678429 100644 --- a/fury/actor.py +++ b/fury/actor.py @@ -257,20 +257,20 @@ def cylinder( colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. height: float, optional - The height of the cylinder. Default is 1. + The height of the cylinder. sectors: int, optional The number of divisions around the cylinder's circumference . - Higher values produce smoother cylinders. Default is 36. + Higher values produce smoother cylinders. radii : float or ndarray (N,) or tuple, optional The radius of the base of the cylinders, single value applies to all cylinders, - while an array specifies a radius for each cylinder individually. Default:0.5. - scales : int or ndarray (N, 3) or tuple (3,), optional - Scaling factors for the cylinders in the (x, y, z) dimensions. - Default is uniform scaling (1, 1, 1). + while an array specifies a radius for each cylinder individually. + scales : int or ndarray (N,3) or tuple (3,), optional + The size of the square in each dimension. If a single value is provided, + the same size will be used for all cylinders. directions : ndarray, shape (N, 3), optional The orientation vector of the cylinder. capped : bool, optional - Whether to add caps (circular ends) to the cylinders. Default is True. + Whether to add caps (circular ends) to the cylinders. opacity : float, optional Takes values from 0 (fully transparent) to 1 (opaque). If both `opacity` and RGBA are provided, the final alpha will be: @@ -465,7 +465,7 @@ def tetrahedron( RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. scales : int or ndarray (N,3) or tuple (3,), optional The size of the tetrahedron in each dimension. If a single value is provided, - the same size will be used for all tetrahedron. + the same size will be used for all tetrahedrons. opacity : float, optional Takes values from 0 (fully transparent) to 1 (opaque). If both `opacity` and RGBA are provided, the final alpha will be: @@ -529,7 +529,7 @@ def icosahedron( RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. scales : int or ndarray (N,3) or tuple (3,), optional The size of the icosahedron in each dimension. If a single value is provided, - the same size will be used for all icosahedron. + the same size will be used for all icosahedrons. opacity : float, optional Takes values from 0 (fully transparent) to 1 (opaque). If both `opacity` and RGBA are provided, the final alpha will be: @@ -593,7 +593,7 @@ def rhombicuboctahedron( RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. scales : int or ndarray (N,3) or tuple (3,), optional The size of the rhombicuboctahedro in each dimension. If a single value is - provided, the same size will be used for all rhombicuboctahedron. + provided, the same size will be used for all rhombicuboctahedrons. opacity : float, optional Takes values from 0 (fully transparent) to 1 (opaque). If both `opacity` and RGBA are provided, the final alpha will be: @@ -659,7 +659,7 @@ def triangularprism( RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. scales : int or ndarray (N,3) or tuple (3,), optional The size of the triangular prism in each dimension. If a single value is - provided, the same size will be used for all triangular prism. + provided, the same size will be used for all triangular prisms. opacity : float, optional Takes values from 0 (fully transparent) to 1 (opaque). If both `opacity` and RGBA are provided, the final alpha will be: @@ -724,7 +724,7 @@ def pentagonalprism( RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. scales : int or ndarray (N,3) or tuple (3,), optional The size of the pentagonal prism in each dimension. If a single value is - provided, the same size will be used for all pentagonal prism. + provided, the same size will be used for all pentagonal prisms. opacity : float, optional Takes values from 0 (fully transparent) to 1 (opaque). If both `opacity` and RGBA are provided, the final alpha will be: @@ -789,7 +789,7 @@ def octagonalprism( RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. scales : int or ndarray (N,3) or tuple (3,), optional The size of the octagonal prism in each dimension. If a single value is - provided, the same size will be used for all octagonal prism. + provided, the same size will be used for all octagonal prisms. opacity : float, optional Takes values from 0 (fully transparent) to 1 (opaque). If both `opacity` and RGBA are provided, the final alpha will be: @@ -858,19 +858,19 @@ def arrow( colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. height : float, optional - The total height of the arrow, including the shaft and tip. Default is 1.0. + The total height of the arrow, including the shaft and tip. resolution : int, optional The number of divisions along the arrow's circular cross-sections. - Higher values produce smoother arrows. Default is 10. + Higher values produce smoother arrows. tip_length : float, optional - The length of the arrowhead tip relative to the total height. Default is 0.35. + The length of the arrowhead tip relative to the total height. tip_radius : float, optional - The radius of the arrowhead tip. Default is 0.1. + The radius of the arrowhead tip. shaft_radius : float, optional - The radius of the arrow shaft. Default is 0.03. + The radius of the arrow shaft. scales : int or ndarray (N,3) or tuple (3,), optional The size of the arrow in each dimension. If a single value is - provided, the same size will be used for all arrow. + provided, the same size will be used for all arrows. opacity : float, optional Takes values from 0 (fully transparent) to 1 (opaque). If both `opacity` and RGBA are provided, the final alpha will be: @@ -922,8 +922,8 @@ def arrow( def superquadric( centers, *, - roundness=(1, 1), directions=(0, 0, 0), + roundness=(1, 1), colors=(1, 1, 1), scales=(1, 1, 1), opacity=None, @@ -940,12 +940,11 @@ def superquadric( The orientation vector of the superquadric. roundness : tuple, optional parameters (Phi and Theta) that control the shape of the superquadric. - Default is (1,1). colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. scales : int or ndarray (N,3) or tuple (3,), optional The size of the superquadric in each dimension. If a single value is - provided, the same size will be used for all superquadric. + provided, the same size will be used for all superquadrics. opacity : float, optional Takes values from 0 (fully transparent) to 1 (opaque). If both `opacity` and RGBA are provided, the final alpha will be: @@ -1009,16 +1008,16 @@ def cone( colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. height: float, optional - The height of the cone. Default is 1. + The height of the cone. sectors: int, optional The number of divisions around the cones's circumference . - Higher values produce smoother cones. Default is 10. + Higher values produce smoother cones. radii : float or ndarray (N,) or tuple, optional The radius of the base of the cones, single value applies to all cones, - while an array specifies a radius for each cone individually. Default:0.5. - scales : int or ndarray (N, 3) or tuple (3,), optional - Scaling factors for the cones in the (x, y, z) dimensions. - Default is uniform scaling (1, 1, 1). + while an array specifies a radius for each cone individually. + scales : int or ndarray (N,3) or tuple (3,), optional + The size of the square in each dimension. If a single value is provided, + the same size will be used for all cones. directions : ndarray, shape (N, 3), optional The orientation vector of the cone. opacity : float, optional @@ -1081,14 +1080,14 @@ def star( centers : ndarray, shape (N, 3) star positions. dim : int, optional. - The dimensionality of the star (2D or 3D). Default is 2. + The dimensionality of the star (2D or 3D). directions : ndarray, shape (N, 3), optional The orientation vector of the star. colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]. scales : int or ndarray (N,3) or tuple (3,), optional The size of the star in each dimension. If a single value is - provided, the same size will be used for all star. + provided, the same size will be used for all stars. opacity : float, optional Takes values from 0 (fully transparent) to 1 (opaque). If both `opacity` and RGBA are provided, the final alpha will be: diff --git a/fury/tests/test_actor.py b/fury/tests/test_actor.py index fdfe9e87f..ed8057d76 100644 --- a/fury/tests/test_actor.py +++ b/fury/tests/test_actor.py @@ -5,116 +5,22 @@ from fury import actor, window -def test_sphere(): - scene = window.Scene() - centers = np.array([[0, 0, 0]]) - colors = np.array([[1, 0, 0]]) - radii = np.array([1]) - - sphere_actor = actor.sphere(centers=centers, colors=colors, radii=radii) - scene.add(sphere_actor) - - window.snapshot(scene=scene, fname="sphere_test_1.png") - - img = Image.open("sphere_test_1.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, _ = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 <= mean_r <= 255 and 0 <= mean_g <= 255 and 0 <= mean_b <= 255 - - npt.assert_array_equal(sphere_actor.local.position, centers[0]) - - assert sphere_actor.prim_count == 1 - - # center_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - # npt.assert_array_equal(center_pixel[0], colors[0][0] * 255) - - phi, theta = 100, 100 - sphere_actor_2 = actor.sphere( - centers=centers, - colors=colors, - radii=radii, - opacity=1, - material="basic", - phi=phi, - theta=theta, - ) - scene.remove(sphere_actor) - scene.add(sphere_actor_2) - - window.snapshot(scene=scene, fname="sphere_test_2.png") - - img = Image.open("sphere_test_2.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 <= mean_r <= 255 and 0 <= mean_g <= 255 and 0 <= mean_b <= 255 - assert mean_a == 255.0 - assert mean_b == 0.0 - assert mean_g == 0.0 - - vertices = sphere_actor_2.geometry.positions.view - faces = sphere_actor_2.geometry.indices.view - colors = sphere_actor_2.geometry.colors.view - - vertices_mean = np.mean(vertices, axis=0) - - npt.assert_array_almost_equal(vertices_mean, centers[0]) - - assert len(vertices) == len(colors) - - npt.assert_array_almost_equal(len(faces), (2 * phi * (theta - 2))) - - -def test_box(): +def validate_actors(centers, colors, actor_type="actor_name"): scene = window.Scene() - centers = np.array([[0, 0, 0]]) - colors = np.array([[1, 0, 0]]) - scales = np.array([[1, 1, 7]]) - - box_actor = actor.box(centers=centers, colors=colors, scales=scales) - scene.add(box_actor) + typ_actor = getattr(actor, actor_type) + get_actor = typ_actor(centers=centers, colors=colors) + scene.add(get_actor) - npt.assert_array_equal(box_actor.local.position, centers[0]) + npt.assert_array_equal(get_actor.local.position, centers[0]) - mean_vertex = np.mean(box_actor.geometry.positions.view, axis=0) + mean_vertex = np.round(np.mean(get_actor.geometry.positions.view, axis=0)) npt.assert_array_almost_equal(mean_vertex, centers[0]) - assert box_actor.prim_count == 1 - - scene.remove(box_actor) - - -def test_cylinder(): - scene = window.Scene() - centers = np.array([[0, 0, 0]]) - colors = np.array([[1, 0, 0]]) - sectors = 36 - capped = True - - cylinder_actor = actor.cylinder( - centers=centers, colors=colors, sectors=sectors, capped=capped - ) - scene.add(cylinder_actor) - - npt.assert_array_equal(cylinder_actor.local.position, centers[0]) - - mean_vertex = np.mean(cylinder_actor.geometry.positions.view, axis=0) - npt.assert_array_almost_equal(mean_vertex, centers[0], decimal=2) + assert get_actor.prim_count == 1 + fname = f"{actor_type}_test.png" + window.snapshot(scene=scene, fname=fname) - assert cylinder_actor.prim_count == 1 - - window.snapshot(scene=scene, fname="cylinder_test_1.png") - - img = Image.open("cylinder_test_1.png") + img = Image.open(fname) img_array = np.array(img) mean_r, mean_g, mean_b, mean_a = np.mean( @@ -122,23 +28,19 @@ def test_cylinder(): ) assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 and 0 < mean_g < 255 and 0 <= mean_b < 255 middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] r, g, b, a = middle_pixel assert r > g and r > b assert g == b - assert r > 0 and g > 0 and b > 0 + scene.remove(get_actor) - scene.remove(cylinder_actor) - - cylinder_actor_2 = actor.cylinder( - centers=centers, colors=colors, sectors=sectors, capped=capped, material="basic" - ) - scene.add(cylinder_actor_2) - window.snapshot(scene=scene, fname="cylinder_test_2.png") - - img = Image.open("cylinder_test_2.png") + typ_actor_1 = getattr(actor, actor_type) + get_actor_1 = typ_actor_1(centers=centers, colors=colors, material="basic") + scene.add(get_actor_1) + fname_1 = f"{actor_type}_test_1.png" + window.snapshot(scene=scene, fname=fname_1) + img = Image.open(fname_1) img_array = np.array(img) mean_r, mean_g, mean_b, mean_a = np.mean( @@ -154,635 +56,94 @@ def test_cylinder(): assert r > g and r > b assert g == 0 and b == 0 assert r == 255 - scene.remove(cylinder_actor_2) + scene.remove(get_actor_1) -def test_square(): - scene = window.Scene() +def test_sphere(): centers = np.array([[0, 0, 0]]) colors = np.array([[1, 0, 0]]) + validate_actors(centers=centers, colors=colors, actor_type="sphere") - square_actor = actor.square(centers=centers, colors=colors) - scene.add(square_actor) - - npt.assert_array_equal(square_actor.local.position, centers[0]) - - mean_vertex = np.mean(square_actor.geometry.positions.view, axis=0) - npt.assert_array_almost_equal(mean_vertex, centers[0]) - assert square_actor.prim_count == 1 - scene.remove(square_actor) - - -def test_frustum(): - scene = window.Scene() +def test_box(): centers = np.array([[0, 0, 0]]) colors = np.array([[1, 0, 0]]) + validate_actors(centers=centers, colors=colors, actor_type="box") - frustum_actor = actor.frustum(centers=centers, colors=colors) - scene.add(frustum_actor) - - npt.assert_array_equal(frustum_actor.local.position, centers[0]) - - mean_vertex = np.mean(frustum_actor.geometry.positions.view, axis=0) - npt.assert_array_almost_equal(mean_vertex, centers[0]) - - assert frustum_actor.prim_count == 1 - - window.snapshot(scene=scene, fname="frustum_test_1.png") - - img = Image.open("frustum_test_1.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 and 0 < mean_g < 255 and 0 <= mean_b < 255 - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == b - assert r > 0 and g > 0 and b > 0 - scene.remove(frustum_actor) - frustum_actor_2 = actor.frustum(centers=centers, colors=colors, material="basic") - scene.add(frustum_actor_2) - window.snapshot(scene=scene, fname="frustum_test_2.png") +def test_cylinder(): + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + validate_actors(centers=centers, colors=colors, actor_type="cylinder") - img = Image.open("frustum_test_2.png") - img_array = np.array(img) - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) +def test_square(): + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + validate_actors(centers=centers, colors=colors, actor_type="square") - assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 - assert mean_g == 0 and mean_b == 0 - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == 0 and b == 0 - assert r == 255 - scene.remove(frustum_actor_2) +def test_frustum(): + centers = np.array([[0, 0, 0]]) + colors = np.array([[1, 0, 0]]) + validate_actors(centers=centers, colors=colors, actor_type="frustum") def test_tetrahedron(): - scene = window.Scene() centers = np.array([[0, 0, 0]]) colors = np.array([[1, 0, 0]]) - - tetrahedron_actor = actor.tetrahedron(centers=centers, colors=colors) - scene.add(tetrahedron_actor) - - npt.assert_array_equal(tetrahedron_actor.local.position, centers[0]) - - mean_vertex = np.mean(tetrahedron_actor.geometry.positions.view, axis=0) - npt.assert_array_almost_equal(mean_vertex, centers[0]) - - assert tetrahedron_actor.prim_count == 1 - - window.snapshot(scene=scene, fname="tetrahedron_test_1.png") - - img = Image.open("tetrahedron_test_1.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == b - scene.remove(tetrahedron_actor) - - tetrahedron_actor_2 = actor.tetrahedron( - centers=centers, colors=colors, material="basic" - ) - scene.add(tetrahedron_actor_2) - window.snapshot(scene=scene, fname="tetrahedron_test_2.png") - - img = Image.open("tetrahedron_test_2.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 - assert mean_g == 0 and mean_b == 0 - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == 0 and b == 0 - assert r == 255 - scene.remove(tetrahedron_actor_2) + validate_actors(centers=centers, colors=colors, actor_type="tetrahedron") def test_icosahedron(): - scene = window.Scene() centers = np.array([[0, 0, 0]]) colors = np.array([[1, 0, 0]]) - - icosahedron_actor = actor.icosahedron(centers=centers, colors=colors) - scene.add(icosahedron_actor) - - npt.assert_array_equal(icosahedron_actor.local.position, centers[0]) - - mean_vertex = np.mean(icosahedron_actor.geometry.positions.view, axis=0) - npt.assert_array_almost_equal(mean_vertex, centers[0]) - - assert icosahedron_actor.prim_count == 1 - - window.snapshot(scene=scene, fname="icosahedron_test_1.png") - - img = Image.open("icosahedron_test_1.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == b - scene.remove(icosahedron_actor) - - icosahedron_actor_2 = actor.icosahedron( - centers=centers, colors=colors, material="basic" - ) - scene.add(icosahedron_actor_2) - window.snapshot(scene=scene, fname="icosahedron_test_2.png") - - img = Image.open("icosahedron_test_2.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 - assert mean_g == 0 and mean_b == 0 - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == 0 and b == 0 - assert r == 255 - scene.remove(icosahedron_actor_2) + validate_actors(centers=centers, colors=colors, actor_type="icosahedron") def test_rhombicuboctahedron(): - scene = window.Scene() centers = np.array([[0, 0, 0]]) colors = np.array([[1, 0, 0]]) - - rhombicuboctahedron_actor = actor.rhombicuboctahedron( - centers=centers, colors=colors - ) - scene.add(rhombicuboctahedron_actor) - - npt.assert_array_equal(rhombicuboctahedron_actor.local.position, centers[0]) - - mean_vertex = np.mean(rhombicuboctahedron_actor.geometry.positions.view, axis=0) - npt.assert_array_almost_equal(mean_vertex, centers[0]) - - assert rhombicuboctahedron_actor.prim_count == 1 - - window.snapshot(scene=scene, fname="rhombicuboctahedron_test_1.png") - - img = Image.open("rhombicuboctahedron_test_1.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == b - scene.remove(rhombicuboctahedron_actor) - - rhombicuboctahedron_actor_2 = actor.rhombicuboctahedron( - centers=centers, colors=colors, material="basic" - ) - scene.add(rhombicuboctahedron_actor_2) - window.snapshot(scene=scene, fname="rhombicuboctahedron_test_2.png") - - img = Image.open("rhombicuboctahedron_test_2.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 - assert mean_g == 0 and mean_b == 0 - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == 0 and b == 0 - assert r == 255 - scene.remove(rhombicuboctahedron_actor_2) + validate_actors(centers=centers, colors=colors, actor_type="rhombicuboctahedron") def test_triangularprism(): - scene = window.Scene() centers = np.array([[0, 0, 0]]) colors = np.array([[1, 0, 0]]) - - triangularprism_actor = actor.triangularprism(centers=centers, colors=colors) - scene.add(triangularprism_actor) - - npt.assert_array_equal(triangularprism_actor.local.position, centers[0]) - - mean_vertex = np.mean(triangularprism_actor.geometry.positions.view, axis=0) - npt.assert_array_almost_equal(mean_vertex, centers[0]) - - assert triangularprism_actor.prim_count == 1 - - window.snapshot(scene=scene, fname="triangularprism_test_1.png") - - img = Image.open("triangularprism_test_1.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == b - scene.remove(triangularprism_actor) - - triangularprism_actor_2 = actor.triangularprism( - centers=centers, colors=colors, material="basic" - ) - scene.add(triangularprism_actor_2) - window.snapshot(scene=scene, fname="triangularprism_test_2.png") - - img = Image.open("triangularprism_test_2.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 - assert mean_g == 0 and mean_b == 0 - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == 0 and b == 0 - assert r == 255 - scene.remove(triangularprism_actor_2) + validate_actors(centers=centers, colors=colors, actor_type="triangularprism") def test_pentagonalprism(): - scene = window.Scene() centers = np.array([[0, 0, 0]]) colors = np.array([[1, 0, 0]]) - - pentagonalprism_actor = actor.pentagonalprism(centers=centers, colors=colors) - scene.add(pentagonalprism_actor) - - npt.assert_array_equal(pentagonalprism_actor.local.position, centers[0]) - - mean_vertex = np.mean(pentagonalprism_actor.geometry.positions.view, axis=0) - npt.assert_array_almost_equal(mean_vertex, centers[0]) - - assert pentagonalprism_actor.prim_count == 1 - - window.snapshot(scene=scene, fname="pentagonalprism_test_1.png") - - img = Image.open("pentagonalprism_test_1.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == b - scene.remove(pentagonalprism_actor) - - pentagonalprism_actor_2 = actor.pentagonalprism( - centers=centers, colors=colors, material="basic" - ) - scene.add(pentagonalprism_actor_2) - window.snapshot(scene=scene, fname="pentagonalprism_test_2.png") - - img = Image.open("pentagonalprism_test_2.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 - assert mean_g == 0 and mean_b == 0 - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == 0 and b == 0 - assert r == 255 - scene.remove(pentagonalprism_actor_2) + validate_actors(centers=centers, colors=colors, actor_type="pentagonalprism") def test_octagonalprism(): - scene = window.Scene() centers = np.array([[0, 0, 0]]) colors = np.array([[1, 0, 0]]) - - octagonalprism_actor = actor.octagonalprism(centers=centers, colors=colors) - scene.add(octagonalprism_actor) - - npt.assert_array_equal(octagonalprism_actor.local.position, centers[0]) - - mean_vertex = np.mean(octagonalprism_actor.geometry.positions.view, axis=0) - npt.assert_array_almost_equal(mean_vertex, centers[0]) - - assert octagonalprism_actor.prim_count == 1 - - window.snapshot(scene=scene, fname="octagonalprism_test_1.png") - - img = Image.open("octagonalprism_test_1.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == b - scene.remove(octagonalprism_actor) - - octagonalprism_actor_2 = actor.octagonalprism( - centers=centers, colors=colors, material="basic" - ) - scene.add(octagonalprism_actor_2) - window.snapshot(scene=scene, fname="octagonalprism_test_2.png") - - img = Image.open("octagonalprism_test_2.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 - assert mean_g == 0 and mean_b == 0 - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == 0 and b == 0 - assert r == 255 - scene.remove(octagonalprism_actor_2) + validate_actors(centers=centers, colors=colors, actor_type="octagonalprism") def test_arrow(): - scene = window.Scene() centers = np.array([[0, 0, 0]]) colors = np.array([[1, 0, 0]]) - - arrow_actor = actor.arrow(centers=centers, colors=colors) - scene.add(arrow_actor) - - npt.assert_array_equal(arrow_actor.local.position, centers[0]) - - assert arrow_actor.prim_count == 1 - - window.snapshot(scene=scene, fname="arrow_test_1.png") - - img = Image.open("arrow_test_1.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == b - scene.remove(arrow_actor) - - arrow_actor_2 = actor.arrow(centers=centers, colors=colors, material="basic") - scene.add(arrow_actor_2) - window.snapshot(scene=scene, fname="arrow_test_2.png") - - img = Image.open("arrow_test_2.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 - assert mean_g == 0 and mean_b == 0 - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == 0 and b == 0 - assert r == 255 - scene.remove(arrow_actor_2) + validate_actors(centers=centers, colors=colors, actor_type="arrow") def test_superquadric(): - scene = window.Scene() centers = np.array([[0, 0, 0]]) colors = np.array([[1, 0, 0]]) - - superquadric_actor = actor.superquadric(centers=centers, colors=colors) - scene.add(superquadric_actor) - - npt.assert_array_equal(superquadric_actor.local.position, centers[0]) - - mean_vertex = np.mean(superquadric_actor.geometry.positions.view, axis=0) - npt.assert_array_almost_equal(mean_vertex, centers[0]) - - assert superquadric_actor.prim_count == 1 - - window.snapshot(scene=scene, fname="superquadric_test_1.png") - - img = Image.open("superquadric_test_1.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == b - scene.remove(superquadric_actor) - - superquadric_actor_2 = actor.superquadric( - centers=centers, colors=colors, material="basic" - ) - scene.add(superquadric_actor_2) - window.snapshot(scene=scene, fname="superquadric_test_2.png") - - img = Image.open("superquadric_test_2.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 - assert mean_g == 0 and mean_b == 0 - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == 0 and b == 0 - assert r == 255 - scene.remove(superquadric_actor_2) + validate_actors(centers=centers, colors=colors, actor_type="superquadric") def test_cone(): - scene = window.Scene() centers = np.array([[0, 0, 0]]) colors = np.array([[1, 0, 0]]) - - cone_actor = actor.cone(centers=centers, colors=colors) - scene.add(cone_actor) - - npt.assert_array_equal(cone_actor.local.position, centers[0]) - - assert cone_actor.prim_count == 1 - - window.snapshot(scene=scene, fname="cone_test_1.png") - - img = Image.open("cone_test_1.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == b - scene.remove(cone_actor) - - cone_actor_2 = actor.cone(centers=centers, colors=colors, material="basic") - scene.add(cone_actor_2) - window.snapshot(scene=scene, fname="cone_test_2.png") - - img = Image.open("cone_test_2.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 - assert mean_g == 0 and mean_b == 0 - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == 0 and b == 0 - assert r == 255 - scene.remove(cone_actor_2) + validate_actors(centers=centers, colors=colors, actor_type="cone") def test_star(): - scene = window.Scene() centers = np.array([[0, 0, 0]]) colors = np.array([[1, 0, 0]]) - - star_actor = actor.star(centers=centers, colors=colors) - scene.add(star_actor) - - npt.assert_array_equal(star_actor.local.position, centers[0]) - - assert star_actor.prim_count == 1 - - window.snapshot(scene=scene, fname="star_test_1.png") - - img = Image.open("star_test_1.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == b - scene.remove(star_actor) - - star_actor_2 = actor.star(centers=centers, colors=colors, material="basic") - scene.add(star_actor_2) - window.snapshot(scene=scene, fname="star_test_2.png") - - img = Image.open("star_test_2.png") - img_array = np.array(img) - - mean_r, mean_g, mean_b, mean_a = np.mean( - img_array.reshape(-1, img_array.shape[2]), axis=0 - ) - - assert mean_r > mean_b and mean_r > mean_g - assert 0 < mean_r < 255 - assert mean_g == 0 and mean_b == 0 - - middle_pixel = img_array[img_array.shape[0] // 2, img_array.shape[1] // 2] - r, g, b, a = middle_pixel - assert r > g and r > b - assert g == 0 and b == 0 - assert r == 255 - scene.remove(star_actor_2) + validate_actors(centers=centers, colors=colors, actor_type="star")