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

First Stage of the KDE Rendering API #826

Open
wants to merge 43 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
35bbb98
Post processing functions file
JoaoDell Jul 19, 2023
ef06af3
docs?
JoaoDell Jul 19, 2023
110ad6b
feat: Introduces EffectManager Class
JoaoDell Jul 20, 2023
a09e262
feat: Opacity inclusion
JoaoDell Jul 20, 2023
bec5f0e
fix: Fixed sigma scale and spelling issues
JoaoDell Jul 21, 2023
b572b4b
fix: Usage of native colormap function and cleanups
JoaoDell Jul 21, 2023
269c4de
feat: Added remove_effect feature
JoaoDell Jul 21, 2023
fae89e1
feat: Added gaussian and laplacian filters
JoaoDell Jul 22, 2023
39f43b4
feat: Added grayscale effect and changed laplacian and gaussian calcu…
JoaoDell Jul 24, 2023
13687be
fix: Fixed gaussian blur issues
JoaoDell Jul 24, 2023
6be3ddc
fix!: Experimenting with multiple effects on the same render and some…
JoaoDell Jul 25, 2023
6dedaec
fix: Fixed textured_billboard positioning issues
JoaoDell Jul 25, 2023
bf1503c
fix: Fixed bugs and cleaned EffectManager class
JoaoDell Jul 27, 2023
fb024d8
refactor!: Refactored and cleaned the whole PR
JoaoDell Jul 27, 2023
edd06e8
Merge branch 'fury-gl:master' into feat/api-kde
JoaoDell Jul 27, 2023
7ecefeb
feat: Added 5 more kernels for the KDE rendering
JoaoDell Jul 27, 2023
68e520e
fix: Added sigma restraining condition
JoaoDell Jul 27, 2023
f0a3d6d
feat: Testing renormalization approaches to KDE
JoaoDell Jul 29, 2023
f35626e
fix!: Stabilizing approaches to renormalization
JoaoDell Jul 30, 2023
9ad1501
fix: Minor refactoring on effect manager
JoaoDell Jul 31, 2023
0ffaf28
feat!: Experimenting with intensity slider (unstable)
JoaoDell Aug 1, 2023
03299b1
Merge branch 'fury-gl:master' into feat/api-kde
JoaoDell Aug 1, 2023
2c1685a
fix: Deleted effects testing file
JoaoDell Aug 1, 2023
73dfc3f
fix: Deleted experimental files
JoaoDell Aug 1, 2023
bacae2e
fix: Improved ui and cleaned the code (deleted other effects)
JoaoDell Aug 1, 2023
80acf71
fix: Added ui tracking inside class
JoaoDell Aug 1, 2023
4490950
fix: Fixed formatting issues and removed UI
JoaoDell Aug 2, 2023
51ae7a6
feat: Initial draft of testing script
JoaoDell Aug 3, 2023
e153297
test: Completed testing scripts
JoaoDell Aug 3, 2023
10bcb90
refactor: Written and relocated file to examples
JoaoDell Aug 3, 2023
e4612b5
style: Formatted some codes to pep8 and improved example text
JoaoDell Aug 4, 2023
0e475f6
fix: Fixing view up vector
JoaoDell Aug 7, 2023
70d911b
fix: Adressing style issues
JoaoDell Aug 10, 2023
734e8e7
fix: Fixed major scaling issue, sigmas bug, and adressed style issues
JoaoDell Aug 14, 2023
1722b2e
doc: minor doc fix
JoaoDell Aug 15, 2023
c54c97f
refactor: use callable approach
devmessias Aug 15, 2023
3f7d335
refactor: effects module
devmessias Aug 15, 2023
f996852
refactor: Cleaning refactored API
JoaoDell Aug 16, 2023
daa810b
test: Added tests for effects module and tweaked multiple effects han…
JoaoDell Aug 17, 2023
f0d855c
test: Implemented the features from last commit
JoaoDell Aug 17, 2023
700e010
fix: Fixed KDE description and set interactive to False
JoaoDell Aug 20, 2023
f03bd6a
style: Fixing upper case in shaders.base
JoaoDell Aug 21, 2023
ac2ce0d
style: Added Union of float and np.ndarray in bandwidth
JoaoDell Aug 21, 2023
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
39 changes: 20 additions & 19 deletions docs/examples/viz_kde_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
======================================================================
Fury Kernel Density Estimation rendering Actor
======================================================================
This example shows how to use the KDE actor. This is a special actor in Fury that works
with post-processing effects to render kernel density estimations of a given set of points
in real-time to the screen. For better understanding on KDEs, check this
`Wikipedia page <https://en.wikipedia.org/wiki/Kernel_density_estimation>`_ about it.
This example shows how to use the KDE effect. This is a feature in Fury
that uses a post-processing stage to render kernel density estimations of a
given set of points in real-time to the screen. For better understanding
on KDEs, check this `Wikipedia page <https://en.wikipedia.org/wiki/Kernel_density_estimation>`_
about it.

For this example, you will only need the modules below:
"""
Expand Down Expand Up @@ -56,10 +57,8 @@ def normalize(array : np.array, min : float = 0.0, max : float = 1.0, axis : int
manager = ShowManager(
scene,
"KDE Render",
(size[0],
size[1]))
size)

manager.initialize()

####################################################################
# ``numpy.random.rand`` will be used to generate random points, which
Expand All @@ -80,7 +79,6 @@ def normalize(array : np.array, min : float = 0.0, max : float = 1.0, axis : int

bandwidths = normalize(np.random.rand(n_points, 1), 0.05, 0.2)


###################################################################
# Now, for the KDE render, a special class is needed, the
# ``EffectManager``. This class is needed to manage the post-processing
Expand All @@ -90,19 +88,22 @@ def normalize(array : np.array, min : float = 0.0, max : float = 1.0, axis : int
# worry, none of this will need to be setup by you! Just call the
# ``EffectManager`` like below, passing the manager to it:

effects = EffectManager(manager)
effects_m = EffectManager(manager)

###################################################################
# After having the ``effects`` setup, just call the kde actor method
# from it, passing the points, bandwidth, and other optional options
# if wished, like the kernel to be used or the colormap desired.
# The colormaps are by default taken from *matplotlib*, but a
# custom one can be passed. After calling it, just pass the actor
# to the scene, and start it as usual.

#kde_actor = effects.kde(points, bandwidths, kernel="gaussian", colormap="inferno")
kde_effect = KDE(points, bandwidths, kernel="gaussian", colormap="inferno")
effects.add(kde_effect)
# After having the ``effects_m`` setup, we can add effects to it.
# Here, we will use the ``KDE`` effect, that comes from ``fury.effects.effects``
# module. When we call it, we pass the points, bandwidth, and other optional options
# if wished, like the kernel to be used or the colormap desired. The available kernels
# can be found inside KDE's description. The colormaps are by default taken from *matplotlib*,
# but a custom one can be passed. After calling it, it returns the KDE class, that will
# then need to be added to the ``EffectManager`` with the ``add()`` method.

kde_effect = KDE(points, bandwidths, kernel="exponential", colormap="inferno")
effects_m.add(kde_effect)

####################################################################
# Having that setup, just start the rendering process to see the results, and we are done here!

interactive = True
JoaoDell marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
42 changes: 22 additions & 20 deletions fury/effects/effect_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class EffectManager():
Target manager that will render post processed actors."""

def __init__(self, manager : ShowManager):
manager.initialize()
self.scene = Scene()
cam_params = manager.scene.get_camera()
self.scene.set_camera(*cam_params)
Expand All @@ -22,43 +23,44 @@ def __init__(self, manager : ShowManager):
self._n_active_effects = 0
self._active_effects = {}

def add(self, effect):
def add(self, effect : callable):
"""Add an effect to the EffectManager. The effect must have a callable property,
that will act as the callback for the interactor. Check the KDE effect for reference.

Parameters
----------
effect : callable
Effect to be added to the `EffectManager`.
"""
callback = partial(
effect,
off_manager=self.off_manager,
on_manager=self.on_manager
)
if hasattr(effect, "apply"):
effect.apply(
off_manager = self.off_manager,
n_active_effects = self._n_active_effects
)
effect.apply(self)

callback()
callback_id = self.on_manager.add_iren_callback(callback, "RenderEvent")


self._active_effects[effect.textured_billboard] = (callback_id, effect.bill)
self._active_effects[effect] = (callback_id, effect._offscreen_actor)
self._n_active_effects += 1
self.on_manager.scene.add(effect.textured_billboard)

return effect.textured_billboard
self.on_manager.scene.add(effect._onscreen_actor)

def remove_effect(self, effect_actor):
"""Remove an existing effect from the effects manager.
Beware that the effect and the actor will be removed from the rendering pipeline
and shall not work after this action.
def remove_effect(self, effect):
"""
Remove an existing effect from the effect manager.

Parameters
----------
effect_actor : actor.Actor
Actor of effect to be removed.
effect_actor : callable
Effect to be removed.
"""
if self._n_active_effects > 0:
self.on_manager.iren.RemoveObserver(self._active_effects[effect_actor][0])
self.off_manager.scene.RemoveActor(self._active_effects[effect_actor][1])
self.on_manager.scene.RemoveActor(effect_actor)
self._active_effects.pop(effect_actor)
self.on_manager.iren.RemoveObserver(self._active_effects[effect][0])
self.off_manager.scene.RemoveActor(self._active_effects[effect][1])
self.on_manager.scene.RemoveActor(effect._onscreen_actor)
self._active_effects.pop(effect)
self._n_active_effects -= 1
else:
raise IndexError("Manager has no active effects.")
Loading