Skip to content

Commit

Permalink
Merge pull request #551 from Sassafrass6/glyph_orientation
Browse files Browse the repository at this point in the history
Fixed #550 : Added necessary allignment between glyph creation and ac…
  • Loading branch information
skoudoro authored Apr 4, 2022
2 parents 588b938 + c0c2874 commit 8335555
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 19 deletions.
82 changes: 77 additions & 5 deletions fury/actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
PolyDataNormals, Assembly, LODActor, VTK_UNSIGNED_CHAR,
PolyDataMapper2D, ScalarBarActor, PolyVertex, CellArray,
UnstructuredGrid, DataSetMapper, ConeSource, ArrowSource,
SphereSource, CylinderSource, TexturedSphereSource,
SphereSource, CylinderSource, DiskSource, TexturedSphereSource,
Texture, FloatArray, VTK_TEXT_LEFT, VTK_TEXT_RIGHT,
VTK_TEXT_BOTTOM, VTK_TEXT_TOP, VTK_TEXT_CENTERED,
TexturedActor2D, TextureMapToPlane, TextActor3D,
Expand Down Expand Up @@ -1609,21 +1609,93 @@ def cylinder(centers, directions, colors, radius=0.05, heights=1,
>>> # window.show(scene)
"""
src = CylinderSource() if faces is None else None

if src is not None:
if faces is None:
src = CylinderSource()
src.SetCapping(capped)
src.SetResolution(resolution)
src.SetRadius(radius)
rotate = np.array([[0, 1, 0, 0],
[-1, 0, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]])
else:
src = None
rotate = None

cylinder_actor = repeat_sources(centers=centers, colors=colors,
directions=directions,
active_scalars=heights, source=src,
vertices=vertices, faces=faces)
vertices=vertices, faces=faces,
orientation=rotate)

return cylinder_actor


def disk(centers, directions, colors, rinner=0.3,
router=0.7, cresolution=6, rresolution=2, vertices=None, faces=None):
"""Visualize one or many disks with different features.
Parameters
----------
centers : ndarray, shape (N, 3)
Disk positions
directions : ndarray, shape (N, 3)
The orientation vector of the disk.
colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,)
RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1]
rinner : float
disk inner radius, default: 0.3
router : float
disk outer radius, default: 0.5
cresolution: int, optional
Number of facets used to define perimeter of disk, default: 6
rresolution: int, optional
Number of facets used radially, default: 2
vertices : ndarray, shape (N, 3)
The point cloud defining the disk.
faces : ndarray, shape (M, 3)
If faces is None then a disk is created based on theta and phi angles
If not then a disk is created with the provided vertices and faces.
Returns
-------
disk_actor: Actor
Examples
--------
>>> from fury import window, actor
>>> import numpy as np
>>> scene = window.Scene()
>>> centers = np.random.rand(5, 3)
>>> dirs = np.random.rand(5, 3)
>>> colors = np.random.rand(5, 4)
>>> actor = actor.disk(centers, dirs, colors,
>>> rinner=.1, router=.8, cresolution=30)
>>> scene.add(actor)
>>> window.show(scene)
"""
if faces is None:
src = DiskSource()
src.SetCircumferentialResolution(cresolution)
src.SetRadialResolution(rresolution)
src.SetInnerRadius(rinner)
src.SetOuterRadius(router)
rotate = np.array([[0, 0, -1, 0],
[0, 1, 0, 0],
[1, 0, 0, 0],
[0, 0, 0, 1]])
else:
src = None
rotate = None

disk_actor = repeat_sources(centers=centers, colors=colors,
directions=directions, source=src,
vertices=vertices, faces=faces,
orientation=rotate)

return disk_actor


def square(centers, directions=(1, 0, 0), colors=(1, 0, 0), scales=1):
"""Visualize one or many squares with different features.
Expand Down
1 change: 1 addition & 0 deletions fury/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
##############################################################
# vtkFiltersGeneral Module
SplineFilter = fgvtk.vtkSplineFilter
TransformPolyDataFilter = fgvtk.vtkTransformPolyDataFilter

##############################################################
# vtkFiltersHybrid Module
Expand Down
23 changes: 12 additions & 11 deletions fury/tests/test_actors.py
Original file line number Diff line number Diff line change
Expand Up @@ -919,20 +919,22 @@ def test_basic_geometry_actor(interactive=False):

def test_advanced_geometry_actor(interactive=False):
xyz = np.array([[0, 0, 0], [50, 0, 0], [100, 0, 0]])
dirs = np.array([[0, 1, 0], [1, 0, 0], [0, 0.5, 0.5]])
dirs = np.array([[0.5, 0.5, 0.5], [0.5, 0, 0.5], [0, 0.5, 0.5]])

actor_list = [[actor.cone, {'directions': dirs, 'resolution': 8}],
[actor.arrow, {'directions': dirs, 'resolution': 9}],
[actor.cylinder, {'directions': dirs}]]
heights = np.array([5, 7, 10])

actor_list = [[actor.cone, {'heights': heights, 'resolution': 8}],
[actor.arrow, {'heights': heights, 'resolution': 9}],
[actor.cylinder, {'heights': heights, 'resolution': 10}],
[actor.disk, {'rinner': 4, 'router': 8, 'rresolution': 2,
'cresolution': 2}]]

scene = window.Scene()

for act_func, extra_args in actor_list:
colors = np.array([[1, 0, 0, 0.3], [0, 1, 0, 0.4], [1, 1, 0, 1]])
heights = np.array([5, 7, 10])

geom_actor = act_func(centers=xyz, heights=heights, colors=colors[:],
**extra_args)
geom_actor = act_func(xyz, dirs, colors, **extra_args)
scene.add(geom_actor)

if interactive:
Expand All @@ -941,12 +943,11 @@ def test_advanced_geometry_actor(interactive=False):
report = window.analyze_snapshot(arr, colors=colors)
npt.assert_equal(report.objects, 3)

scene.clear()

colors = np.array([1.0, 1.0, 1.0, 1.0])
heights = 10

scene.clear()
geom_actor = act_func(centers=xyz[:, :3], heights=10, colors=colors[:],
**extra_args)
geom_actor = act_func(xyz, dirs, colors, **extra_args)
scene.add(geom_actor)

if interactive:
Expand Down
12 changes: 9 additions & 3 deletions fury/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
CellArray, PolyDataNormals, Actor, PolyDataMapper,
Matrix4x4, Matrix3x3, Glyph3D, VTK_DOUBLE, VTK_FLOAT,
Transform, AlgorithmOutput, VTK_INT, VTK_UNSIGNED_CHAR,
IdTypeArray)
TransformPolyDataFilter, IdTypeArray)


def remove_observer_from_actor(actor, id):
Expand Down Expand Up @@ -706,7 +706,7 @@ def get_actor_from_primitive(vertices, triangles, colors=None,


def repeat_sources(centers, colors, active_scalars=1., directions=None,
source=None, vertices=None, faces=None):
source=None, vertices=None, faces=None, orientation=None):
"""Transform a vtksource to glyph."""
if source is None and faces is None:
raise IOError("A source or faces should be defined")
Expand Down Expand Up @@ -749,10 +749,16 @@ def repeat_sources(centers, colors, active_scalars=1., directions=None,

glyph = Glyph3D()
if faces is None:
if orientation is not None:
transform = Transform()
transform.SetMatrix(numpy_to_vtk_matrix(orientation))
rtrans = TransformPolyDataFilter()
rtrans.SetInputConnection(source.GetOutputPort())
rtrans.SetTransform(transform)
source = rtrans
glyph.SetSourceConnection(source.GetOutputPort())
else:
glyph.SetSourceData(polydata_geom)

glyph.SetInputData(polydata_centers)
glyph.SetOrient(True)
glyph.SetScaleModeToScaleByScalar()
Expand Down

0 comments on commit 8335555

Please sign in to comment.