diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..19b2fa691c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,135 @@ +jobs: + include: + # Linux Jobs + - os: linux + language: python + python: 3.6 + install: + - pip3 install --upgrade pip + - pip3 install -r ./.travis/travis-requirements.txt + - pip3 install pycairo pytest + - pip3 install . + script: + - pytest + + - os: linux + language: python + python: 3.7 + install: + - pip3 install --upgrade pip + - pip3 install -r ./.travis/travis-requirements.txt + - pip3 install pycairo pytest + - pip3 install . + script: + - pytest + + - os: linux + language: python + python: 3.8 + install: + - pip3 install --upgrade pip + - pip3 install -r ./.travis/travis-requirements.txt + - pip3 install pycairo pytest + - pip3 install . + script: + - pytest + + # MacOS (OSX) Jobs + - os: osx + language: sh + python: 3.6 + env: PYVER="3.6.10" + install: + - pip3 install --upgrade pip + - pip3 install -r ./.travis/travis-requirements.txt + - pip3 install pycairo pytest + - pip3 install . + script: + - pytest + + - os: osx + language: sh + python: 3.7 + env: PYVER="3.7.7" + install: + - pip3 install --upgrade pip + - pip3 install -r ./.travis/travis-requirements.txt + - pip3 install pycairo pytest + - pip3 install . + script: + - pytest + + - os: osx + language: sh + python: 3.8 + env: PYVER="3.8.0" # Using Python 3.8.0 due to error with rich + install: + - pip3 install --upgrade pip + - pip3 install -r ./.travis/travis-requirements.txt + - pip3 install pycairo pytest + - pip3 install . + script: + - pytest + + # Windows Jobs + - os: windows + language: sh + python: 3.6 + # the latest version available on chocolatey is 3.6.8 + env: PYVER="3.6.8" PYDIR="Python36" + install: + - choco install python --version=$PYVER + - export PATH="/c/$PYDIR:/c/$PYDIR/Scripts:$PATH" + - choco install ffmpeg + - cmd.exe //c "RefreshEnv.cmd" + - python -m pip install --upgrade pip + - python -m pip install --user -r ./.travis/travis-requirements.txt + - python ./.travis/cairo-windows.py + - cmd.exe //c "RefreshEnv.cmd" + - python -m pip install --user . + script: + - python -m pytest + + - os: windows + language: sh + python: 3.7 + env: PYVER="3.7.7" PYDIR="Python37" + install: + - choco install python --version=$PYVER + - export PATH="/c/$PYDIR:/c/$PYDIR/Scripts:$PATH" + - choco install ffmpeg + - cmd.exe //c "RefreshEnv.cmd" + - python -m pip install --upgrade pip + - python -m pip install --user -r ./.travis/travis-requirements.txt + - python ./.travis/cairo-windows.py + - cmd.exe //c "RefreshEnv.cmd" + - python -m pip install --user . + script: + - python -m pytest + + - os: windows + language: sh + python: 3.8 + env: PYVER="3.8.0" PYDIR="Python38" # Using Python 3.8.0 due to error with rich + install: + - choco install python --version=$PYVER + - export PATH="/c/$PYDIR:/c/$PYDIR/Scripts:$PATH" + - choco install ffmpeg + - cmd.exe //c "RefreshEnv.cmd" + - python -m pip install --upgrade pip + - python -m pip install --user -r ./.travis/travis-requirements.txt + - python ./.travis/cairo-windows.py + - cmd.exe //c "RefreshEnv.cmd" + - python -m pip install --user . + script: + - python -m pytest + +before_install: + - if [ "$TRAVIS_OS_NAME" == "osx" ]; then chmod +x ./.travis/osx.sh; sh ./.travis/osx.sh; fi + +branches: + only: + - master + +notifications: + email: false diff --git a/.travis/cairo-windows.py b/.travis/cairo-windows.py new file mode 100644 index 0000000000..9cde2b37cd --- /dev/null +++ b/.travis/cairo-windows.py @@ -0,0 +1,51 @@ +import platform +import os +import sys +import urllib.request + +if 'Windows' in platform.system(): + #In case the python version is 3.6 and the system is 32-bit, try pycairo‑1.19.1‑cp37‑cp37m‑win32.whl version of cairo + if sys.version[:3]=='3.6' and platform.machine()=='x86': + urllib.request.urlretrieve("https://download.lfd.uci.edu/pythonlibs/s2jqpv5t/pycairo-1.19.1-cp36-cp36m-win32.whl", "pycairo-1.19.1-cp36-cp36m-win32.whl") + os.system("pip install pycairo-1.19.1-cp36-cp36m-win32.whl") + os.remove("pycairo-1.19.1-cp37-cp37m-win32.whl") + + #In case the python version is 3.6 and the system is 64-bit, try pycairo‑1.19.1‑cp37‑cp37m‑win32.whl version of cairo + elif sys.version[:3]=='3.6' and platform.machine()=='AMD64': + urllib.request.urlretrieve("https://download.lfd.uci.edu/pythonlibs/s2jqpv5t/pycairo-1.19.1-cp36-cp36m-win_amd64.whl", "pycairo-1.19.1-cp36-cp36m-win_amd64.whl") + print("Sucessfully downloaded Cairo for your system") + print("Installing Cairo") + os.system("pip install pycairo-1.19.1-cp36-cp36m-win_amd64.whl") + os.remove("pycairo-1.19.1-cp36-cp36m-win_amd64.whl") + + #In case the python version is 3.7 and the system is 32-bit, try pycairo‑1.19.1‑cp37‑cp37m‑win32.whl version of cairo + if sys.version[:3]=='3.7' and platform.machine()=='x86': + urllib.request.urlretrieve("https://download.lfd.uci.edu/pythonlibs/s2jqpv5t/pycairo-1.19.1-cp37-cp37m-win32.whl", "pycairo-1.19.1-cp37-cp37m-win32.whl") + print("Sucessfully downloaded Cairo for your system") + print("Installing Cairo") + os.system("pip install pycairo-1.19.1-cp37-cp37m-win32.whl") + os.remove("pycairo-1.19.1-cp37-cp37m-win32.whl") + + #In case the python version is 3.7 and the system is AMD64, try pycairo-1.19.1-cp37-cp37m-win_amd64.whl version of cairo + elif sys.version[:3]=='3.7' and platform.machine()=='AMD64': + urllib.request.urlretrieve("https://download.lfd.uci.edu/pythonlibs/s2jqpv5t/pycairo-1.19.1-cp37-cp37m-win_amd64.whl", "pycairo-1.19.1-cp37-cp37m-win_amd64.whl") + print("Sucessfully downloaded Cairo for your system") + print("Installing Cairo") + os.system("pip install pycairo-1.19.1-cp37-cp37m-win_amd64.whl") + os.remove("pycairo-1.19.1-cp37-cp37m-win_amd64.whl") + + #In case the python version is 3.8 and the system is 32-bit, try pycairo-1.19.1-cp38-cp38-win32.whl version of cairo + elif sys.version[:3]=='3.8' and platform.machine()=='x86': + urllib.request.urlretrieve("https://download.lfd.uci.edu/pythonlibs/s2jqpv5t/pycairo-1.19.1-cp38-cp38-win32.whl", "pycairo-1.19.1-cp38-cp38-win32.whl") + print("Sucessfully downloaded Cairo for your system") + print("Installing Cairo") + os.system("pip install pycairo-1.19.1-cp38-cp38-win32.whl") + os.remove("pycairo-1.19.1-cp38-cp38-win32.whl") + + #In case the python version is 3.8 and the system is AMD64, try pycairo-1.19.1-cp38-cp38-win_amd64.whl version of cairo + elif sys.version[:3]=='3.8' and platform.machine()=='AMD64': + urllib.request.urlretrieve("https://download.lfd.uci.edu/pythonlibs/s2jqpv5t/pycairo-1.19.1-cp38-cp38-win_amd64.whl", "pycairo-1.19.1-cp38-cp38-win_amd64.whl") + print("Sucessfully downloaded Cairo for your system") + print("Installing Cairo") + os.system("pip install pycairo-1.19.1-cp38-cp38-win_amd64.whl") + os.remove("pycairo-1.19.1-cp38-cp38-win_amd64.whl") \ No newline at end of file diff --git a/.travis/osx.sh b/.travis/osx.sh new file mode 100644 index 0000000000..1d3ec02b0f --- /dev/null +++ b/.travis/osx.sh @@ -0,0 +1,12 @@ +##### THIS IS FOR TRAVIS BUILDS, DO NOT RUN THIS ON YOUR COMPUTER! ##### + +brew update +brew install openssl readline +brew outdated pyenv || brew upgrade pyenv +brew install pyenv-virtualenv +pyenv install $PYVER +export PYENV_VERSION=$PYVER +export PATH="/Users/travis/.pyenv/shims:${PATH}" +pyenv virtualenv venv +source ~/.pyenv/versions/venv/bin/activate +python --version \ No newline at end of file diff --git a/.travis/travis-requirements.txt b/.travis/travis-requirements.txt new file mode 100644 index 0000000000..e51d737699 --- /dev/null +++ b/.travis/travis-requirements.txt @@ -0,0 +1,14 @@ +argparse +colour +numpy +Pillow +progressbar +scipy +tqdm +# opencv-python +# pycairo +pydub +pygments +pyreadline; sys_platform == 'win32' +rich +pytest \ No newline at end of file diff --git a/README.md b/README.md index e0f4f8fa68..dfa75f45bc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![logo](logo/cropped.png) -[![Build Status](https://travis-ci.org/3b1b/manim.svg?branch=master)](https://travis-ci.org/3b1b/manim) +[![Build Status](https://travis-ci.com/ManimCommunity/manim.svg?branch=master)](https://travis-ci.com/ManimCommunity/manim) [![Documentation](https://img.shields.io/badge/docs-EulerTour-blue.svg)](https://www.eulertour.com/docs) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://choosealicense.com/licenses/mit/) [![Manim Subreddit](https://img.shields.io/reddit/subreddit-subscribers/manim.svg?color=ff4301&label=reddit)](https://www.reddit.com/r/manim/) diff --git a/logo/logo.py b/logo/logo.py index 41bb7e3930..a4b485fc47 100644 --- a/logo/logo.py +++ b/logo/logo.py @@ -1,4 +1,4 @@ -from manim.imports import * +from manim import * NEW_BLUE = "#68a8e1" diff --git a/manim/scene/scene_from_video.py b/manim/scene/scene_from_video.py index 170c6f0162..1e21251407 100644 --- a/manim/scene/scene_from_video.py +++ b/manim/scene/scene_from_video.py @@ -1,54 +1,54 @@ -from tqdm import tqdm as show_progress -import cv2 +# from tqdm import tqdm as show_progress +# import cv2 -from ..scene.scene import Scene -from ..logger import logger +# from ..scene.scene import Scene +# from ..logger import logger -# TODO, is this depricated? -class SceneFromVideo(Scene): - def construct(self, file_name, - freeze_last_frame=True, - time_range=None): - cap = cv2.VideoCapture(file_name) - self.shape = ( - int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)), - int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)) - ) - fps = cap.get(cv2.cv.CV_CAP_PROP_FPS) - self.camera.frame_rate = fps - frame_count = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT)) - if time_range is None: - start_frame = 0 - end_frame = frame_count - else: - start_frame, end_frame = [fps * t for t in time_range] +# # TODO, is this depricated? +# class SceneFromVideo(Scene): +# def construct(self, file_name, +# freeze_last_frame=True, +# time_range=None): +# cap = cv2.VideoCapture(file_name) +# self.shape = ( +# int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)), +# int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)) +# ) +# fps = cap.get(cv2.cv.CV_CAP_PROP_FPS) +# self.camera.frame_rate = fps +# frame_count = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT)) +# if time_range is None: +# start_frame = 0 +# end_frame = frame_count +# else: +# start_frame, end_frame = [fps * t for t in time_range] - frame_count = end_frame - start_frame - logger.info("Reading in " + file_name + "...") - for count in show_progress(list(range(start_frame, end_frame + 1))): - returned, frame = cap.read() - if not returned: - break - # b, g, r = cv2.split(frame) - # self.frames.append(cv2.merge([r, g, b])) - self.frames.append(frame) - cap.release() +# frame_count = end_frame - start_frame +# logger.info("Reading in " + file_name + "...") +# for count in show_progress(list(range(start_frame, end_frame + 1))): +# returned, frame = cap.read() +# if not returned: +# break +# # b, g, r = cv2.split(frame) +# # self.frames.append(cv2.merge([r, g, b])) +# self.frames.append(frame) +# cap.release() - if freeze_last_frame and len(self.frames) > 0: - self.original_background = self.background = self.frames[-1] +# if freeze_last_frame and len(self.frames) > 0: +# self.original_background = self.background = self.frames[-1] - def apply_gaussian_blur(self, ksize=(5, 5), sigmaX=5): - self.frames = [ - cv2.GaussianBlur(frame, ksize, sigmaX) - for frame in self.frames - ] +# def apply_gaussian_blur(self, ksize=(5, 5), sigmaX=5): +# self.frames = [ +# cv2.GaussianBlur(frame, ksize, sigmaX) +# for frame in self.frames +# ] - def apply_edge_detection(self, threshold1=50, threshold2=100): - edged_frames = [ - cv2.Canny(frame, threshold1, threshold2) - for frame in self.frames - ] - for index in range(len(self.frames)): - for i in range(3): - self.frames[index][:, :, i] = edged_frames[index] \ No newline at end of file +# def apply_edge_detection(self, threshold1=50, threshold2=100): +# edged_frames = [ +# cv2.Canny(frame, threshold1, threshold2) +# for frame in self.frames +# ] +# for index in range(len(self.frames)): +# for i in range(3): +# self.frames[index][:, :, i] = edged_frames[index] \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index f9fb3b9025..4221c80dc5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,9 +5,10 @@ Pillow progressbar scipy tqdm -opencv-python +# opencv-python pycairo pydub pygments pyreadline; sys_platform == 'win32' rich +# pytest (for development only) diff --git a/setup.py b/setup.py index 2cb6b855f4..15a0c90a3a 100755 --- a/setup.py +++ b/setup.py @@ -26,6 +26,6 @@ "pydub", "pygments", "pyreadline; sys_platform == 'win32'", - "rich" + "rich", ], ) diff --git a/tests/test_imports.py b/tests/test_imports.py new file mode 100644 index 0000000000..55ed89a48a --- /dev/null +++ b/tests/test_imports.py @@ -0,0 +1,2 @@ +def test_import(): + import manim diff --git a/tests/tests_sample_scenes.py b/tests/test_sample_scenes.py similarity index 83% rename from tests/tests_sample_scenes.py rename to tests/test_sample_scenes.py index 438568822a..af2c318a91 100644 --- a/tests/tests_sample_scenes.py +++ b/tests/test_sample_scenes.py @@ -1,13 +1,14 @@ -from manim.imports import * +from manim import * -# This file is intended to test any new feature added. -# Feel free to add a test or to modify one when adding a new/changing a feature. -class Test(Scene): - def construct(self): +# This file is intended to test any new feature added. +# Feel free to add a test or to modify one when adding a new/changing a feature. +class BasicScene(Scene): + def construct(self): square = Square() self.play(ShowCreation(square)) - -class Test_geometry(Scene): + + +class GeometryScene(Scene): def construct(self): circle = Circle() square = Square() @@ -39,7 +40,8 @@ def construct(self): ) self.wait() -class Test_plotting(GraphScene): + +class PlottingScene(GraphScene): CONFIG = { "x_min" : -10, "x_max" : 10.3, @@ -49,8 +51,12 @@ class Test_plotting(GraphScene): "function_color" : RED , "axes_color" : GREEN, "x_labeled_nums" :range(-10,12,2), - } - def construct(self): + } + def construct(self): self.setup_axes(animate=False) func_graph = self.get_graph(lambda x : x**2, self.function_color) self.play(ShowCreation(func_graph)) + + +def test_scenes(): + BasicScene()