diff --git a/README.md b/README.md
index 13b42b54..5be335f4 100644
--- a/README.md
+++ b/README.md
@@ -36,7 +36,7 @@ python extract_scene.py -p example_scenes.py SquareToCircle
`-p` gives a preview of an animation, `-w` will write it to a file, and `-s` will show/save the final image in the animation.
-You will probably want to change the MOVIE_DIR constant to be whatever direction you want video files to output to.
+You will probably want to change the ANIMATIONS_DIR constant to be whatever direction you want video files to output to.
Look through the old_projects folder to see the code for previous 3b1b videos.
diff --git a/camera.py b/camera.py
index 4b30258d..19b299f2 100644
--- a/camera.py
+++ b/camera.py
@@ -49,7 +49,7 @@ class Camera(object):
def init_background(self):
if self.background_image is not None:
- path = get_full_image_path(self.background_image)
+ path = get_full_raster_image_path(self.background_image)
image = Image.open(path).convert(self.image_mode)
height, width = self.pixel_shape
#TODO, how to gracefully handle backgrounds
diff --git a/constants.py b/constants.py
index 257cd97d..31673f08 100644
--- a/constants.py
+++ b/constants.py
@@ -61,19 +61,23 @@ RIGHT_SIDE = SPACE_WIDTH*RIGHT
# Change this to point to where you want
# animation files to output
-MOVIE_DIR = os.path.join(os.path.expanduser('~'), "Dropbox (3Blue1Brown)/3Blue1Brown Team Folder/animations")
-STAGED_SCENES_DIR = os.path.join(MOVIE_DIR, "staged_scenes")
+MEDIA_DIR = os.path.join(os.path.expanduser('~'), "Dropbox (3Blue1Brown)/3Blue1Brown Team Folder")
+
+ANIMATIONS_DIR = os.path.join(MEDIA_DIR, "animations")
+RASTER_IMAGE_DIR = os.path.join(MEDIA_DIR, "designs", "raster_images")
+SVG_IMAGE_DIR = os.path.join(MEDIA_DIR, "designs", "svg_images")
+#TODO, staged scenes should really go into a subdirectory of a given scenes directory
+STAGED_SCENES_DIR = os.path.join(ANIMATIONS_DIR, "staged_scenes")
###
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
FILE_DIR = os.path.join(THIS_DIR, "files")
-IMAGE_DIR = os.path.join(FILE_DIR, "images")
-GIF_DIR = os.path.join(FILE_DIR, "gifs")
TEX_DIR = os.path.join(FILE_DIR, "Tex")
-TEX_IMAGE_DIR = os.path.join(IMAGE_DIR, "Tex")
+TEX_IMAGE_DIR = TEX_DIR #TODO, What is this doing?
+#These two may be depricated now.
MOBJECT_DIR = os.path.join(FILE_DIR, "mobjects")
IMAGE_MOBJECT_DIR = os.path.join(MOBJECT_DIR, "image")
-for folder in [FILE_DIR, IMAGE_DIR, GIF_DIR, MOVIE_DIR, TEX_DIR,
+for folder in [FILE_DIR, RASTER_IMAGE_DIR, SVG_IMAGE_DIR, ANIMATIONS_DIR, TEX_DIR,
TEX_IMAGE_DIR, MOBJECT_DIR, IMAGE_MOBJECT_DIR,
STAGED_SCENES_DIR]:
if not os.path.exists(folder):
@@ -84,8 +88,6 @@ TEMPLATE_TEX_FILE = os.path.join(THIS_DIR, "template.tex")
TEMPLATE_TEXT_FILE = os.path.join(THIS_DIR, "text_template.tex")
-LOGO_PATH = os.path.join(IMAGE_DIR, "logo.png")
-
FFMPEG_BIN = "ffmpeg"
diff --git a/extract_scene.py b/extract_scene.py
index 75945e85..537884f7 100644
--- a/extract_scene.py
+++ b/extract_scene.py
@@ -190,7 +190,7 @@ def main():
)
config["output_directory"] = os.path.join(
- MOVIE_DIR,
+ ANIMATIONS_DIR,
config["file"].replace(".py", "")
)
diff --git a/files/images/Bubbles_speech.svg b/files/images/Bubbles_speech.svg
deleted file mode 100644
index 173ebf35..00000000
--- a/files/images/Bubbles_speech.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
diff --git a/files/images/Bubbles_thought.svg b/files/images/Bubbles_thought.svg
deleted file mode 100644
index c77ebca4..00000000
--- a/files/images/Bubbles_thought.svg
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
diff --git a/files/images/PiCreature/PiCreatures_plain.svg b/files/images/PiCreature/PiCreatures_plain.svg
deleted file mode 100644
index 552043d6..00000000
--- a/files/images/PiCreature/PiCreatures_plain.svg
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
diff --git a/helpers.py b/helpers.py
index 2dd96c8c..2683bd6c 100644
--- a/helpers.py
+++ b/helpers.py
@@ -410,13 +410,13 @@ def cammel_case_initials(name):
################################################
-def get_full_image_path(image_file_name):
+def get_full_raster_image_path(image_file_name):
possible_paths = [
image_file_name,
- os.path.join(IMAGE_DIR, image_file_name),
- os.path.join(IMAGE_DIR, image_file_name + ".jpg"),
- os.path.join(IMAGE_DIR, image_file_name + ".png"),
- os.path.join(IMAGE_DIR, image_file_name + ".gif"),
+ os.path.join(RASTER_IMAGE_DIR, image_file_name),
+ os.path.join(RASTER_IMAGE_DIR, image_file_name + ".jpg"),
+ os.path.join(RASTER_IMAGE_DIR, image_file_name + ".png"),
+ os.path.join(RASTER_IMAGE_DIR, image_file_name + ".gif"),
]
for path in possible_paths:
if os.path.exists(path):
diff --git a/mobject/image_mobject.py b/mobject/image_mobject.py
index 0a602c0b..e4a74382 100644
--- a/mobject/image_mobject.py
+++ b/mobject/image_mobject.py
@@ -23,7 +23,7 @@ class ImageMobject(Mobject):
def __init__(self, filename_or_array, **kwargs):
digest_config(self, kwargs)
if isinstance(filename_or_array, str):
- path = get_full_image_path(filename_or_array)
+ path = get_full_raster_image_path(filename_or_array)
image = Image.open(path).convert(self.image_mode)
self.pixel_array = np.array(image)
else:
diff --git a/mobject/mobject.py b/mobject/mobject.py
index ec1ff7c3..d79c5482 100644
--- a/mobject/mobject.py
+++ b/mobject/mobject.py
@@ -96,7 +96,7 @@ class Mobject(object):
def save_image(self, name = None):
self.get_image().save(
- os.path.join(MOVIE_DIR, (name or str(self)) + ".png")
+ os.path.join(ANIMATIONS_DIR, (name or str(self)) + ".png")
)
def copy(self):
diff --git a/mobject/svg_mobject.py b/mobject/svg_mobject.py
index ede49a77..0c90ffef 100644
--- a/mobject/svg_mobject.py
+++ b/mobject/svg_mobject.py
@@ -37,8 +37,8 @@ class SVGMobject(VMobject):
raise Exception("Must specify file for SVGMobject")
possible_paths = [
self.file_name,
- os.path.join(IMAGE_DIR, self.file_name),
- os.path.join(IMAGE_DIR, self.file_name + ".svg"),
+ os.path.join(SVG_IMAGE_DIR, self.file_name),
+ os.path.join(SVG_IMAGE_DIR, self.file_name + ".svg"),
]
for path in possible_paths:
if os.path.exists(path):
diff --git a/nn/part1.py b/nn/part1.py
index 12540128..2efa5d80 100644
--- a/nn/part1.py
+++ b/nn/part1.py
@@ -1532,7 +1532,7 @@ class BreakUpMacroPatterns(IntroduceEachLayer):
prefixes = self.prefixes
vects = [
np.array(Image.open(
- get_full_image_path("handwritten_" + p),
+ get_full_raster_image_path("handwritten_" + p),
))[:,:,0].flatten()/255.0
for p in prefixes
]
@@ -1921,7 +1921,7 @@ class SecondLayerIsLittleEdgeLayer(IntroduceEachLayer):
def setup_activations_and_nines(self):
layers = self.network_mob.layers
nine_im, loop_im, line_im = images = [
- Image.open(get_full_image_path("handwritten_%s"%s))
+ Image.open(get_full_raster_image_path("handwritten_%s"%s))
for s in "nine", "upper_loop", "right_line"
]
nine_array, loop_array, line_array = [
diff --git a/old_projects/counting_in_binary.py b/old_projects/counting_in_binary.py
index 7428e146..1a6acfb7 100644
--- a/old_projects/counting_in_binary.py
+++ b/old_projects/counting_in_binary.py
@@ -14,7 +14,7 @@ from scene import Scene, SceneFromVideo
from script_wrapper import command_line_create_scene
MOVIE_PREFIX = "counting_in_binary/"
-BASE_HAND_FILE = os.path.join(MOVIE_DIR, MOVIE_PREFIX, "Base.mp4")
+BASE_HAND_FILE = os.path.join(ANIMATIONS_DIR, MOVIE_PREFIX, "Base.mp4")
FORCED_FRAME_DURATION = 0.02
TIME_RANGE = (0, 42)
INITIAL_PADDING = 27
@@ -88,7 +88,7 @@ class Hand(ImageMobject):
def __init__(self, num, small = False, **kwargs):
Mobject2D.__init__(self, **kwargs)
path = os.path.join(
- MOVIE_DIR, MOVIE_PREFIX, "images", "Hand%d.png"%num
+ ANIMATIONS_DIR, MOVIE_PREFIX, "images", "Hand%d.png"%num
)
invert = False
if not self.read_in_cached_attrs(path, invert):
@@ -164,7 +164,7 @@ class SaveEachNumber(OverHand):
OverHand.construct(self)
for count in COUNT_TO_FRAME_NUM:
path = os.path.join(
- MOVIE_DIR, MOVIE_PREFIX, "images",
+ ANIMATIONS_DIR, MOVIE_PREFIX, "images",
"Hand%d.png"%count
)
Image.fromarray(self.frames[COUNT_TO_FRAME_NUM[count]]).save(path)
diff --git a/old_projects/playground_counting_in_binary.py b/old_projects/playground_counting_in_binary.py
index 2ba8f831..ed7cd705 100644
--- a/old_projects/playground_counting_in_binary.py
+++ b/old_projects/playground_counting_in_binary.py
@@ -55,7 +55,7 @@ class Hand(ImageMobject):
def __init__(self, num, **kwargs):
Mobject2D.__init__(self, **kwargs)
path = os.path.join(
- MOVIE_DIR, MOVIE_PREFIX, "images", "Hand%d.png"%num
+ ANIMATIONS_DIR, MOVIE_PREFIX, "images", "Hand%d.png"%num
)
invert = False
if self.read_in_cached_attrs(path, invert):
@@ -81,14 +81,14 @@ class EdgeDetection(SceneFromVideo):
return "-".join([filename.split(".")[0], str(t1), str(t2)])
def construct(self, filename, t1, t2):
- path = os.path.join(MOVIE_DIR, filename)
+ path = os.path.join(ANIMATIONS_DIR, filename)
SceneFromVideo.construct(self, path)
self.apply_gaussian_blur()
self.apply_edge_detection(t1, t2)
class BufferedCounting(SceneFromVideo):
def construct(self):
- path = os.path.join(MOVIE_DIR, "CountingInBinary.m4v")
+ path = os.path.join(ANIMATIONS_DIR, "CountingInBinary.m4v")
time_range = (3, 42)
SceneFromVideo.construct(self, path, time_range = time_range)
self.buffer_pixels(spreads = (3, 2))
@@ -128,7 +128,7 @@ class ClearLeftSide(SceneFromVideo):
return scenename
def construct(self, scenename):
- path = os.path.join(MOVIE_DIR, MOVIE_PREFIX, scenename + ".mp4")
+ path = os.path.join(ANIMATIONS_DIR, MOVIE_PREFIX, scenename + ".mp4")
SceneFromVideo.construct(self, path)
self.highlight_region_over_time_range(
Region(lambda x, y : x < -1, shape = self.shape)
@@ -146,7 +146,7 @@ class DraggedPixels(SceneFromVideo):
return args[0]
def construct(self, video):
- path = os.path.join(MOVIE_DIR, MOVIE_PREFIX, video+".mp4")
+ path = os.path.join(ANIMATIONS_DIR, MOVIE_PREFIX, video+".mp4")
SceneFromVideo.construct(self, path)
self.drag_pixels()
@@ -163,11 +163,11 @@ class DraggedPixels(SceneFromVideo):
class SaveEachNumber(SceneFromVideo):
def construct(self):
- path = os.path.join(MOVIE_DIR, MOVIE_PREFIX, "ClearLeftSideBufferedCounting.mp4")
+ path = os.path.join(ANIMATIONS_DIR, MOVIE_PREFIX, "ClearLeftSideBufferedCounting.mp4")
SceneFromVideo.construct(self, path)
for count in COUNT_TO_FRAME_NUM:
path = os.path.join(
- MOVIE_DIR, MOVIE_PREFIX, "images",
+ ANIMATIONS_DIR, MOVIE_PREFIX, "images",
"Hand%d.png"%count
)
Image.fromarray(self.frames[COUNT_TO_FRAME_NUM[count]]).save(path)
@@ -182,7 +182,7 @@ class ShowCounting(SceneFromVideo):
return filename
def construct(self, filename):
- path = os.path.join(MOVIE_DIR, MOVIE_PREFIX, filename + ".mp4")
+ path = os.path.join(ANIMATIONS_DIR, MOVIE_PREFIX, filename + ".mp4")
SceneFromVideo.construct(self, path)
total_time = len(self.frames)*self.frame_duration
for count in range(32):
@@ -207,7 +207,7 @@ class ShowFrameNum(SceneFromVideo):
return filename
def construct(self, filename):
- path = os.path.join(MOVIE_DIR, MOVIE_PREFIX, filename+".mp4")
+ path = os.path.join(ANIMATIONS_DIR, MOVIE_PREFIX, filename+".mp4")
SceneFromVideo.construct(self, path)
for frame, count in zip(self.frames, it.count()):
print(count + "of" + len(self.frames))
diff --git a/scene/scene.py b/scene/scene.py
index 621328f2..d1500e11 100644
--- a/scene/scene.py
+++ b/scene/scene.py
@@ -32,7 +32,7 @@ class Scene(object):
"save_frames" : False,
"save_pngs" : False,
"pngs_mode" : "RGBA",
- "output_directory" : MOVIE_DIR,
+ "output_directory" : ANIMATIONS_DIR,
"name" : None,
"always_continually_update" : False,
"random_seed" : 0,
diff --git a/stage_animations.py b/stage_animations.py
deleted file mode 100644
index 6f129239..00000000
--- a/stage_animations.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import sys
-import inspect
-import os
-import shutil
-import itertools as it
-from extract_scene import is_scene, get_module
-from constants import MOVIE_DIR, STAGED_SCENES_DIR
-
-
-def get_sorted_scene_names(module_name):
- module = get_module(module_name)
- line_to_scene = {}
- for name, scene_class in inspect.getmembers(module, is_scene):
- lines, line_no = inspect.getsourcelines(scene_class)
- line_to_scene[line_no] = name
- return [
- line_to_scene[line_no]
- for line_no in sorted(line_to_scene.keys())
- ]
-
-
-
-def stage_animaions(module_name):
- scene_names = get_sorted_scene_names(module_name)
- movie_dir = os.path.join(
- MOVIE_DIR, module_name.replace(".py", "")
- )
- files = os.listdir(movie_dir)
- sorted_files = []
- for scene in scene_names:
- for clip in filter(lambda f : f.startswith(scene), files):
- sorted_files.append(
- os.path.join(movie_dir, clip)
- )
- for f in os.listdir(STAGED_SCENES_DIR):
- os.remove(os.path.join(STAGED_SCENES_DIR, f))
- for f, count in zip(sorted_files, it.count()):
- symlink_name = os.path.join(
- STAGED_SCENES_DIR,
- "Scene_%03d"%count + f.split(os.sep)[-1]
- )
- os.symlink(f, symlink_name)
-
-
-
-if __name__ == "__main__":
- if len(sys.argv) < 2:
- raise Exception("No module given.")
- module_name = sys.argv[1]
- stage_animaions(module_name)
\ No newline at end of file
diff --git a/stage_scenes.py b/stage_scenes.py
index 6f129239..e79d341c 100644
--- a/stage_scenes.py
+++ b/stage_scenes.py
@@ -4,7 +4,7 @@ import os
import shutil
import itertools as it
from extract_scene import is_scene, get_module
-from constants import MOVIE_DIR, STAGED_SCENES_DIR
+from constants import ANIMATIONS_DIR, STAGED_SCENES_DIR
def get_sorted_scene_names(module_name):
@@ -22,15 +22,15 @@ def get_sorted_scene_names(module_name):
def stage_animaions(module_name):
scene_names = get_sorted_scene_names(module_name)
- movie_dir = os.path.join(
- MOVIE_DIR, module_name.replace(".py", "")
+ animation_dir = os.path.join(
+ ANIMATIONS_DIR, module_name.replace(".py", "")
)
- files = os.listdir(movie_dir)
+ files = os.listdir(animation_dir)
sorted_files = []
for scene in scene_names:
for clip in filter(lambda f : f.startswith(scene), files):
sorted_files.append(
- os.path.join(movie_dir, clip)
+ os.path.join(animation_dir, clip)
)
for f in os.listdir(STAGED_SCENES_DIR):
os.remove(os.path.join(STAGED_SCENES_DIR, f))
diff --git a/topics/characters.py b/topics/characters.py
index 432c30e5..fef18cb8 100644
--- a/topics/characters.py
+++ b/topics/characters.py
@@ -13,7 +13,7 @@ from animation.simple_animations import Write, ShowCreation, AnimationGroup
from scene import Scene
-PI_CREATURE_DIR = os.path.join(IMAGE_DIR, "PiCreature")
+PI_CREATURE_DIR = os.path.join(MEDIA_DIR, "designs", "PiCreature")
PI_CREATURE_SCALE_FACTOR = 0.5
LEFT_EYE_INDEX = 0
@@ -51,7 +51,7 @@ class PiCreature(SVGMobject):
except:
warnings.warn("No PiCreature design with mode %s"%mode)
svg_file = os.path.join(
- PI_CREATURE_DIR,
+ FILE_DIR,
"PiCreatures_plain.svg"
)
SVGMobject.__init__(self, file_name = svg_file, **kwargs)
diff --git a/topics/objects.py b/topics/objects.py
index b445d861..769ea8ff 100644
--- a/topics/objects.py
+++ b/topics/objects.py
@@ -388,7 +388,11 @@ class Bubble(SVGMobject):
digest_config(self, kwargs, locals())
if self.file_name is None:
raise Exception("Must invoke Bubble subclass")
- SVGMobject.__init__(self, **kwargs)
+ try:
+ SVGMobject.__init__(self, **kwargs)
+ except IOError as err:
+ self.file_name = os.path.join(FILE_DIR, self.file_name)
+ SVGMobject.__init__(self, **kwargs)
self.center()
self.stretch_to_fit_height(self.height)
self.stretch_to_fit_width(self.width)
@@ -515,4 +519,22 @@ class Broadcast(LaggedStart):
self, ApplyMethod, circles,
lambda c : (c.restore,),
**kwargs
- )
\ No newline at end of file
+
+ )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+