Skip to content

Commit

Permalink
Changed the defaults for where animations are written, and where imag…
Browse files Browse the repository at this point in the history
…es for ImageMobject and SVGMobject are sought after
  • Loading branch information
3b1b committed Jan 12, 2018
1 parent 0b595ed commit ffcd9b5
Show file tree
Hide file tree
Showing 19 changed files with 68 additions and 147 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def resize_space_shape(self, fixed_dimension = 0):

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
Expand Down
18 changes: 10 additions & 8 deletions constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,23 @@

# 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):
Expand All @@ -84,8 +88,6 @@
TEMPLATE_TEXT_FILE = os.path.join(THIS_DIR, "text_template.tex")


LOGO_PATH = os.path.join(IMAGE_DIR, "logo.png")

FFMPEG_BIN = "ffmpeg"


Expand Down
2 changes: 1 addition & 1 deletion extract_scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ def main():
)

config["output_directory"] = os.path.join(
MOVIE_DIR,
ANIMATIONS_DIR,
config["file"].replace(".py", "")
)

Expand Down
11 changes: 0 additions & 11 deletions files/images/Bubbles_speech.svg

This file was deleted.

18 changes: 0 additions & 18 deletions files/images/Bubbles_thought.svg

This file was deleted.

24 changes: 0 additions & 24 deletions files/images/PiCreature/PiCreatures_plain.svg

This file was deleted.

10 changes: 5 additions & 5 deletions helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion mobject/image_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion mobject/mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def show(self, camera = None):

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):
Expand Down
4 changes: 2 additions & 2 deletions mobject/svg_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ def ensure_valid_file(self):
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):
Expand Down
4 changes: 2 additions & 2 deletions nn/part1.py
Original file line number Diff line number Diff line change
Expand Up @@ -1532,7 +1532,7 @@ def setup_needed_patterns(self):
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
]
Expand Down Expand Up @@ -1921,7 +1921,7 @@ def setup_network_mob(self):
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 = [
Expand Down
6 changes: 3 additions & 3 deletions old_projects/counting_in_binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
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
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -164,7 +164,7 @@ def construct(self):
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)
Expand Down
18 changes: 9 additions & 9 deletions old_projects/playground_counting_in_binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -81,14 +81,14 @@ def args_to_string(filename, t1, t2):
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))
Expand Down Expand Up @@ -128,7 +128,7 @@ def args_to_string(scenename):
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)
Expand All @@ -146,7 +146,7 @@ def args_to_string(*args):
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()

Expand All @@ -163,11 +163,11 @@ def drag_pixels(self, num_frames_to_drag_over = 5):

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)
Expand All @@ -182,7 +182,7 @@ def args_to_string(filename):
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):
Expand All @@ -207,7 +207,7 @@ def args_to_string(filename):
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))
Expand Down
2 changes: 1 addition & 1 deletion scene/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
50 changes: 0 additions & 50 deletions stage_animations.py

This file was deleted.

10 changes: 5 additions & 5 deletions stage_scenes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
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):
Expand All @@ -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))
Expand Down
4 changes: 2 additions & 2 deletions topics/characters.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
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
Expand Down Expand Up @@ -51,7 +51,7 @@ def __init__(self, mode = "plain", **kwargs):
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)
Expand Down
Loading

0 comments on commit ffcd9b5

Please sign in to comment.