Exemple #1
0
def test_digest_file(tmp_path):
    """Test that a config file can be digested programatically."""
    with tempconfig({}):
        tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False)
        tmp_cfg.write("""
            [CLI]
            media_dir = this_is_my_favorite_path
            video_dir = {media_dir}/videos
            """)
        tmp_cfg.close()
        config.digest_file(tmp_cfg.name)

        assert config.get_dir("media_dir") == Path("this_is_my_favorite_path")
        assert config.get_dir("video_dir") == Path(
            "this_is_my_favorite_path/videos")
Exemple #2
0
def main():
    console.print(f"Manim Community [green]v{__version__}[/green]")
    args = parse_args(sys.argv)

    if hasattr(args, "cmd"):
        if args.cmd == "cfg":
            if args.subcmd:
                from manim._config import cfg_subcmds

                if args.subcmd == "write":
                    cfg_subcmds.write(args.level, args.open)
                elif args.subcmd == "show":
                    cfg_subcmds.show()
                elif args.subcmd == "export":
                    cfg_subcmds.export(args.dir)
            else:
                logger.error("No subcommand provided; Exiting...")

        elif args.cmd == "plugins":
            from manim.plugins import plugins_flags

            if args.list:
                plugins_flags.list_plugins()
            elif not args.list:
                logger.error("No flag provided; Exiting...")

        # elif args.cmd == "some_other_cmd":
        #     something_else_here()

    else:
        config.digest_args(args)
        input_file = config.get_dir("input_file")
        if config["use_webgl_renderer"]:
            try:
                from manim.grpc.impl import frame_server_impl

                server = frame_server_impl.get(input_file)
                server.start()
                server.wait_for_termination()
            except ModuleNotFoundError as e:
                print("\n\n")
                print("Dependencies for the WebGL render are missing. Run "
                      "pip install manim[webgl_renderer] to install them.")
                print(e)
                print("\n\n")
        else:
            for SceneClass in scene_classes_from_file(input_file):
                try:
                    scene = SceneClass()
                    scene.render()
                    open_file_if_needed(scene.renderer.file_writer)
                except Exception:
                    print("\n\n")
                    traceback.print_exc()
                    print("\n\n")
Exemple #3
0
def main():
    args = parse_args(sys.argv)

    if hasattr(args, "cmd"):
        if args.cmd == "cfg":
            if args.subcmd:
                from manim._config import cfg_subcmds

                if args.subcmd == "write":
                    cfg_subcmds.write(args.level, args.open)
                elif args.subcmd == "show":
                    cfg_subcmds.show()
                elif args.subcmd == "export":
                    cfg_subcmds.export(args.dir)
            else:
                logger.error("No subcommand provided; Exiting...")

        elif args.cmd == "plugins":
            from manim.plugins import plugins_flags

            if args.list:
                plugins_flags.list_plugins()
            elif not args.list:
                logger.error("No flag provided; Exiting...")

        # elif args.cmd == "some_other_cmd":
        #     something_else_here()

    else:
        config.digest_args(args)
        input_file = config.get_dir("input_file")
        if config["use_js_renderer"]:
            try:
                if frame_server_impl is None:
                    raise ImportError(
                        "Dependencies for JS renderer is not installed.")
                server = frame_server_impl.get(input_file)
                server.start()
                server.wait_for_termination()
            except Exception:
                print("\n\n")
                traceback.print_exc()
                print("\n\n")
        else:
            for SceneClass in scene_classes_from_file(input_file):
                try:
                    scene = SceneClass()
                    scene.render()
                    open_file_if_needed(scene.renderer.file_writer)
                except Exception:
                    print("\n\n")
                    traceback.print_exc()
                    print("\n\n")
Exemple #4
0
def test_digest_file(tmp_path):
    """Test that a config file can be digested programmatically."""
    with tempconfig({}):
        tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False)
        tmp_cfg.write(
            """
            [CLI]
            media_dir = this_is_my_favorite_path
            video_dir = {media_dir}/videos
            sections_dir = {media_dir}/{scene_name}/prepare_for_unforeseen_consequences
            frame_height = 10
            """, )
        tmp_cfg.close()
        config.digest_file(tmp_cfg.name)

        assert config.get_dir("media_dir") == Path("this_is_my_favorite_path")
        assert config.get_dir("video_dir") == Path(
            "this_is_my_favorite_path/videos")
        assert config.get_dir("sections_dir", scene_name="test") == Path(
            "this_is_my_favorite_path/test/prepare_for_unforeseen_consequences"
        )
Exemple #5
0
def main():
    args = parse_args(sys.argv)

    if hasattr(args, "cmd"):
        if args.cmd == "cfg":
            if args.subcmd:
                from manim.config import cfg_subcmds

                if args.subcmd == "write":
                    cfg_subcmds.write(args.level, args.open)
                elif args.subcmd == "show":
                    cfg_subcmds.show()
                elif args.subcmd == "export":
                    cfg_subcmds.export(args.dir)
            else:
                logger.error("No subcommand provided; Exiting...")

        # elif args.cmd == "some_other_cmd":
        #     something_else_here()

    else:
        config.digest_args(args)

        module = get_module(config.get_dir("input_file"))
        all_scene_classes = get_scene_classes_from_module(module)
        scene_classes_to_render = get_scenes_to_render(all_scene_classes)
        for SceneClass in scene_classes_to_render:
            try:
                if config["use_js_renderer"]:
                    if frame_server_impl is None:
                        raise ImportError(
                            "Dependencies for JS renderer is not installed.")
                    frame_server_impl.get(SceneClass).start()
                else:
                    scene = SceneClass()
                    scene.render()
                    open_file_if_needed(scene.renderer.file_writer)
            except Exception:
                print("\n\n")
                traceback.print_exc()
                print("\n\n")
Exemple #6
0
    def run(self):
        # Render is skipped if the tag skip-manim is present
        should_skip = (
            "skip-manim"
            in self.state.document.settings.env.app.builder.tags.tags)
        # Or if we are making the pot-files
        should_skip = (should_skip
                       or self.state.document.settings.env.app.builder.name
                       == "gettext")
        if should_skip:
            node = skip_manim_node()
            self.state.nested_parse(
                StringList(self.content[0]),
                self.content_offset,
                node,
            )
            return [node]

        from manim import config, tempconfig

        global classnamedict

        clsname = self.arguments[0]
        if clsname not in classnamedict:
            classnamedict[clsname] = 1
        else:
            classnamedict[clsname] += 1

        hide_source = "hide_source" in self.options
        save_as_gif = "save_as_gif" in self.options
        save_last_frame = "save_last_frame" in self.options
        assert not (save_as_gif and save_last_frame)

        ref_content = (self.options.get("ref_modules", []) +
                       self.options.get("ref_classes", []) +
                       self.options.get("ref_functions", []) +
                       self.options.get("ref_methods", []))
        if ref_content:
            ref_block = "References: " + " ".join(ref_content)

        else:
            ref_block = ""

        if "quality" in self.options:
            quality = f'{self.options["quality"]}_quality'
        else:
            quality = "example_quality"
        frame_rate = QUALITIES[quality]["frame_rate"]
        pixel_height = QUALITIES[quality]["pixel_height"]
        pixel_width = QUALITIES[quality]["pixel_width"]

        state_machine = self.state_machine
        document = state_machine.document

        source_file_name = Path(document.attributes["source"])
        source_rel_name = source_file_name.relative_to(setup.confdir)
        source_rel_dir = source_rel_name.parents[0]
        dest_dir = Path(setup.app.builder.outdir, source_rel_dir).absolute()
        if not dest_dir.exists():
            dest_dir.mkdir(parents=True, exist_ok=True)

        source_block = [
            ".. code-block:: python",
            "",
            "    from manim import *\n",
            *("    " + line for line in self.content),
        ]
        source_block = "\n".join(source_block)

        config.media_dir = (Path(setup.confdir) / "media").absolute()
        config.images_dir = "{media_dir}/images"
        config.video_dir = "{media_dir}/videos/{quality}"
        output_file = f"{clsname}-{classnamedict[clsname]}"
        config.assets_dir = Path("_static")
        config.progress_bar = "none"
        config.verbosity = "WARNING"

        example_config = {
            "frame_rate": frame_rate,
            "pixel_height": pixel_height,
            "pixel_width": pixel_width,
            "save_last_frame": save_last_frame,
            "write_to_movie": not save_last_frame,
            "output_file": output_file,
        }
        if save_last_frame:
            example_config["format"] = None
        if save_as_gif:
            example_config["format"] = "gif"

        user_code = self.content
        if user_code[0].startswith(
                ">>> "):  # check whether block comes from doctest
            user_code = [
                line[4:] for line in user_code
                if line.startswith((">>> ", "... "))
            ]

        code = [
            "from manim import *",
            *user_code,
            f"{clsname}().render()",
        ]

        with tempconfig(example_config):
            run_time = timeit(lambda: exec("\n".join(code), globals()),
                              number=1)
            video_dir = config.get_dir("video_dir")
            images_dir = config.get_dir("images_dir")

        _write_rendering_stats(
            clsname,
            run_time,
            self.state.document.settings.env.docname,
        )

        # copy video file to output directory
        if not (save_as_gif or save_last_frame):
            filename = f"{output_file}.mp4"
            filesrc = video_dir / filename
            destfile = Path(dest_dir, filename)
            shutil.copyfile(filesrc, destfile)
        elif save_as_gif:
            filename = f"{output_file}.gif"
            filesrc = video_dir / filename
        elif save_last_frame:
            filename = f"{output_file}.png"
            filesrc = images_dir / filename
        else:
            raise ValueError("Invalid combination of render flags received.")
        rendered_template = jinja2.Template(TEMPLATE).render(
            clsname=clsname,
            clsname_lowercase=clsname.lower(),
            hide_source=hide_source,
            filesrc_rel=Path(filesrc).relative_to(setup.confdir).as_posix(),
            output_file=output_file,
            save_last_frame=save_last_frame,
            save_as_gif=save_as_gif,
            source_block=source_block,
            ref_block=ref_block,
        )
        state_machine.insert_input(
            rendered_template.split("\n"),
            source=document.attributes["source"],
        )

        return []
    def run(self):
        if "skip-manim" in self.state.document.settings.env.app.builder.tags.tags:
            node = skip_manim_node()
            self.state.nested_parse(StringList(self.content[0]),
                                    self.content_offset, node)
            return [node]

        from manim import config

        global classnamedict

        clsname = self.arguments[0]
        if clsname not in classnamedict:
            classnamedict[clsname] = 1
        else:
            classnamedict[clsname] += 1

        hide_source = "hide_source" in self.options
        save_as_gif = "save_as_gif" in self.options
        save_last_frame = "save_last_frame" in self.options
        assert not (save_as_gif and save_last_frame)

        ref_content = (self.options.get("ref_modules", []) +
                       self.options.get("ref_classes", []) +
                       self.options.get("ref_functions", []) +
                       self.options.get("ref_methods", []))
        if ref_content:
            ref_block = "References: " + " ".join(ref_content)

        else:
            ref_block = ""

        if "quality" in self.options:
            quality = f'{self.options["quality"]}_quality'
        else:
            quality = "example_quality"
        frame_rate = QUALITIES[quality]["frame_rate"]
        pixel_height = QUALITIES[quality]["pixel_height"]
        pixel_width = QUALITIES[quality]["pixel_width"]
        qualitydir = f"{pixel_height}p{frame_rate}"

        state_machine = self.state_machine
        document = state_machine.document

        source_file_name = document.attributes["source"]
        source_rel_name = relpath(source_file_name, setup.confdir)
        source_rel_dir = os.path.dirname(source_rel_name)
        while source_rel_dir.startswith(os.path.sep):
            source_rel_dir = source_rel_dir[1:]

        dest_dir = os.path.abspath(
            os.path.join(setup.app.builder.outdir, source_rel_dir))
        if not os.path.exists(dest_dir):
            os.makedirs(dest_dir)

        source_block = [
            ".. code-block:: python",
            "",
            "    from manim import *\n",
            *["    " + line for line in self.content],
        ]
        source_block = "\n".join(source_block)

        config.media_dir = Path(setup.confdir) / "media"
        config.images_dir = "{media_dir}/images"
        config.video_dir = "{media_dir}/videos/{quality}"
        output_file = f"{clsname}-{classnamedict[clsname]}"
        config.assets_dir = Path("_static")

        config_code = [
            f'config["frame_rate"] = {frame_rate}',
            f'config["pixel_height"] = {pixel_height}',
            f'config["pixel_width"] = {pixel_width}',
            f'config["save_last_frame"] = {save_last_frame}',
            f'config["save_as_gif"] = {save_as_gif}',
            f'config["write_to_movie"] = {not save_last_frame}',
            f'config["output_file"] = r"{output_file}"',
        ]

        user_code = self.content
        if user_code[0].startswith(
                ">>> "):  # check whether block comes from doctest
            user_code = [
                line[4:] for line in user_code
                if line.startswith((">>> ", "... "))
            ]

        code = [
            "from manim import *",
            *config_code,
            *user_code,
            f"{clsname}().render()",
        ]
        exec("\n".join(code), globals())

        # copy video file to output directory
        if not (save_as_gif or save_last_frame):
            filename = f"{output_file}.mp4"
            filesrc = config.get_dir("video_dir") / filename
        elif save_as_gif:
            filename = f"{output_file}.gif"
            filesrc = config.get_dir("video_dir") / filename
        elif save_last_frame:
            filename = f"{output_file}.png"
            filesrc = config.get_dir("images_dir") / filename
        else:
            raise ValueError("Invalid combination of render flags received.")

        rendered_template = jinja2.Template(TEMPLATE).render(
            clsname=clsname,
            clsname_lowercase=clsname.lower(),
            hide_source=hide_source,
            filename=filename,
            filesrc_rel=os.path.relpath(filesrc, setup.confdir),
            output_file=output_file,
            save_last_frame=save_last_frame,
            save_as_gif=save_as_gif,
            source_block=source_block,
            ref_block=ref_block,
        )
        state_machine.insert_input(rendered_template.split("\n"),
                                   source=document.attributes["source"])

        return []
Exemple #8
0
    def run(self):
        from manim import config

        global classnamedict

        clsname = self.arguments[0]
        if clsname not in classnamedict:
            classnamedict[clsname] = 1
        else:
            classnamedict[clsname] += 1

        hide_source = "hide_source" in self.options
        save_as_gif = "save_as_gif" in self.options
        save_last_frame = "save_last_frame" in self.options
        assert not (save_as_gif and save_last_frame)
        if "ref_classes" in self.options or "ref_functions" in self.options:
            ref_classes = self.options.get("ref_classes", [])
            ref_functions = self.options.get("ref_functions", [])
            ref_content = ref_classes + ref_functions
            ref_block = f"""
.. admonition:: Example References
    :class: example-reference

    {' '.join(ref_content)}"""
        else:
            ref_block = ""

        frame_rate = 30
        pixel_height = 480
        pixel_width = 854

        if "quality" in self.options:
            quality = self.options["quality"]
            if quality == "low":
                pixel_height = 480
                pixel_width = 854
                frame_rate = 15
            elif quality == "medium":
                pixel_height = 720
                pixel_width = 1280
                frame_rate = 30
            elif quality == "high":
                pixel_height = 1440
                pixel_width = 2560
                frame_rate = 60
            elif quality == "fourk":
                pixel_height = 2160
                pixel_width = 3840
                frame_rate = 60

        qualitydir = f"{pixel_height}p{frame_rate}"

        state_machine = self.state_machine
        document = state_machine.document

        source_file_name = document.attributes["source"]
        source_rel_name = relpath(source_file_name, setup.confdir)
        source_rel_dir = os.path.dirname(source_rel_name)
        while source_rel_dir.startswith(os.path.sep):
            source_rel_dir = source_rel_dir[1:]

        dest_dir = os.path.abspath(
            os.path.join(setup.app.builder.outdir, source_rel_dir))
        if not os.path.exists(dest_dir):
            os.makedirs(dest_dir)

        source_block = [
            ".. code-block:: python",
            "",
            *["    " + line for line in self.content],
        ]
        source_block = "\n".join(source_block)

        config.media_dir = Path(setup.confdir) / "media"
        config.images_dir = "{media_dir}/images"
        config.video_dir = "{media_dir}/videos/{quality}"
        output_file = f"{clsname}-{classnamedict[clsname]}"
        config.assets_dir = Path("_static")

        config_code = [
            f'config["frame_rate"] = {frame_rate}',
            f'config["pixel_height"] = {pixel_height}',
            f'config["pixel_width"] = {pixel_width}',
            f'config["save_last_frame"] = {save_last_frame}',
            f'config["save_as_gif"] = {save_as_gif}',
            f'config["output_file"] = r"{output_file}"',
        ]

        user_code = self.content
        if user_code[0].startswith(
                ">>> "):  # check whether block comes from doctest
            user_code = [
                line[4:] for line in user_code
                if line.startswith((">>> ", "... "))
            ]

        code = [
            "from manim import *",
            *config_code,
            *user_code,
            f"{clsname}().render()",
        ]
        exec("\n".join(code), globals())

        # copy video file to output directory
        if not (save_as_gif or save_last_frame):
            filename = f"{output_file}.mp4"
            filesrc = config.get_dir("video_dir") / filename
            destfile = os.path.join(dest_dir, filename)
            shutil.copyfile(filesrc, destfile)
        elif save_as_gif:
            filename = f"{output_file}.gif"
            filesrc = config.get_dir("video_dir") / filename
        elif save_last_frame:
            filename = f"{output_file}.png"
            filesrc = config.get_dir("images_dir") / filename
        else:
            raise ValueError("Invalid combination of render flags received.")

        rendered_template = jinja2.Template(TEMPLATE).render(
            clsname=clsname,
            clsname_lowercase=clsname.lower(),
            hide_source=hide_source,
            filesrc_rel=os.path.relpath(filesrc, setup.confdir),
            output_file=output_file,
            save_last_frame=save_last_frame,
            save_as_gif=save_as_gif,
            source_block=source_block,
            ref_block=ref_block,
        )
        state_machine.insert_input(rendered_template.split("\n"),
                                   source=document.attributes["source"])

        return []