Skip to content

Commit a75d551

Browse files
committed
Add Scene.embed()
1 parent 2c30068 commit a75d551

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

example_scenes/opengl.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,57 @@
33
import os
44
from pathlib import Path
55

6+
67
# Copied from https://3b1b.github.io/manim/getting_started/example_scenes.html#surfaceexample.
78
# Lines that do not yet work with the Community Version are commented.
9+
10+
11+
class InteractiveDevelopment(Scene):
12+
def construct(self):
13+
circle = OpenGLCircle()
14+
circle.set_fill(BLUE, opacity=0.5)
15+
circle.set_stroke(BLUE_E, width=4)
16+
square = OpenGLSquare()
17+
18+
self.play(ShowCreation(square))
19+
self.wait()
20+
21+
# This opens an iPython termnial where you can keep writing
22+
# lines as if they were part of this construct method.
23+
# In particular, 'square', 'circle' and 'self' will all be
24+
# part of the local namespace in that terminal.
25+
self.embed()
26+
27+
# Try copying and pasting some of the lines below into
28+
# the interactive shell
29+
self.play(ReplacementTransform(square, circle))
30+
self.wait()
31+
self.play(circle.animate.stretch(4, 0))
32+
self.play(Rotate(circle, 90 * DEGREES))
33+
self.play(circle.animate.shift(2 * RIGHT).scale(0.25))
34+
35+
# text = Text("""
36+
# In general, using the interactive shell
37+
# is very helpful when developing new scenes
38+
# """)
39+
# self.play(Write(text))
40+
41+
# # In the interactive shell, you can just type
42+
# # play, add, remove, clear, wait, save_state and restore,
43+
# # instead of self.play, self.add, self.remove, etc.
44+
45+
# # To interact with the window, type touch(). You can then
46+
# # scroll in the window, or zoom by holding down 'z' while scrolling,
47+
# # and change camera perspective by holding down 'd' while moving
48+
# # the mouse. Press 'r' to reset to the standard camera position.
49+
# # Press 'q' to stop interacting with the window and go back to
50+
# # typing new commands into the shell.
51+
52+
# # In principle you can customize a scene to be responsive to
53+
# # mouse and keyboard interactions
54+
# always(circle.move_to, self.mouse_point)
55+
56+
857
class SurfaceExample(Scene):
958
def construct(self):
1059
# surface_text = Text("For 3d scenes, try using surfaces")

manim/scene/scene.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,46 @@ def play_internal(self, skip_rendering=False):
873873
self.update_mobjects(0)
874874
self.renderer.static_image = None
875875

876+
def embed(self):
877+
if not config["preview"]:
878+
logger.warning("Called embed() while no preview window is available.")
879+
return
880+
if config["write_to_movie"]:
881+
logger.warning("embed() is skipped while writing to a file.")
882+
return
883+
884+
self.renderer.render(self, -1, self.moving_mobjects)
885+
886+
# Configure IPython shell.
887+
from IPython.terminal.embed import InteractiveShellEmbed
888+
889+
shell = InteractiveShellEmbed()
890+
891+
# Have the frame update after each command
892+
shell.events.register(
893+
"post_run_cell",
894+
lambda *a, **kw: self.renderer.render(self, -1, self.moving_mobjects),
895+
)
896+
897+
# Use the locals of the caller as the local namespace
898+
# once embeded, and add a few custom shortcuts.
899+
local_ns = inspect.currentframe().f_back.f_locals
900+
# local_ns["touch"] = self.interact
901+
for method in (
902+
"play",
903+
"wait",
904+
"add",
905+
"remove",
906+
# "clear",
907+
# "save_state",
908+
# "restore",
909+
):
910+
local_ns[method] = getattr(self, method)
911+
shell(local_ns=local_ns, stack_depth=2)
912+
913+
# End scene when exiting an embed.
914+
raise Exception("Exiting scene.")
915+
876916
def update_to_time(self, t):
877917
dt = t - self.last_t
878918
self.last_t = t

0 commit comments

Comments
 (0)