Skip to content

Commit

Permalink
Added an example to dynamically alter the scene in each frame (#376)
Browse files Browse the repository at this point in the history
  • Loading branch information
IgorTatarnikov authored Aug 20, 2024
1 parent 242dad8 commit 11d0d76
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 5 deletions.
29 changes: 24 additions & 5 deletions brainrender/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,42 @@ def compress(self, temp_name):

@not_on_jupyter
def make_video(
self, *args, duration=10, fps=30, render_kwargs={}, **kwargs
self,
*args,
duration=10,
fps=30,
fix_camera=False,
render_kwargs={},
**kwargs,
):
"""
Creates a video using user defined parameters
:param *args: any extra argument to be bassed to `make_frame_func`
:param duration: float, duratino of the video in seconds
:param *args: any extra argument to be passed to `make_frame_func`
:param duration: float, duration of the video in seconds
:param fps: int, frame rate
:param **kwargs: any extra keyword argument to be bassed to `make_frame_func`
:param fix_camera: bool, if True the focal point of the camera is set based on the first frame
:param render_kwargs: dict, any extra keyword argument to be passed to `scene.render`
:param **kwargs: any extra keyword argument to be passed to `make_frame_func`
"""
logger.debug(f"Saving a video {duration}s long ({fps} fps)")
_off = br.settings.OFFSCREEN
br.settings.OFFSCREEN = True # render offscreen

self.scene.render(interactive=False, **render_kwargs)

if fix_camera:
first_frame = self.keyframes.get(0)
if not first_frame:
logger.error("No keyframes found, can't fix camera")

# Sets the focal point of the first frame to the centre of mass of the
# full root mesh, since this focal point is set subsequent frames will
# have the same focal point unless a new camera is defined
self.keyframes[0]["camera"][
"focal_point"
] = self.scene.root._mesh.center_of_mass()

# cd to folder where the video will be saved
curdir = os.getcwd()
os.chdir(self.save_fld)
Expand Down Expand Up @@ -317,7 +337,6 @@ def get_frame_params(self, frame_number):
elif frame_number > self.last_keyframe:
# check if current frame is past the last keyframe
params = self.keyframes[self.last_keyframe]
params["callback"] = None

else:
# interpolate between two key frames
Expand Down
39 changes: 39 additions & 0 deletions examples/animation_callback.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from brainrender import Animation, Scene, settings
from pathlib import Path

settings.SHOW_AXES = False

scene = Scene(atlas_name="allen_mouse_25um")

regions = (
"CTX",
"HPF",
"STR",
"CB",
"MB",
"TH",
"HY",
)
scene.add_brain_region(*regions, silhouette=True)


def slc(scene, framen, totframes):
# Get new slicing plane
fact = framen / totframes
shape_um = scene.atlas.shape_um
# Multiply by fact to move the plane, add buffer to go past the brain
point = [(shape_um[0] + 500) * fact, shape_um[1] // 2, shape_um[2] // 2]
plane = scene.atlas.get_plane(pos=point, norm=(1, 0, 0))

scene.slice(plane)


anim = Animation(
scene, Path.cwd(), "brainrender_animation_callback", size=None
)

# Specify camera pos and zoom at some key frames`
anim.add_keyframe(0, camera="frontal", zoom=1, callback=slc)

# Make videos
anim.make_video(duration=5, fps=10, fix_camera=True)

0 comments on commit 11d0d76

Please sign in to comment.