mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Add caching functionality, and have Tex and Text both use it for saved svg strings
This commit is contained in:
parent
88370d4d5d
commit
129e512b0c
7 changed files with 64 additions and 46 deletions
|
@ -61,6 +61,7 @@ from manimlib.scene.interactive_scene import *
|
|||
from manimlib.scene.scene import *
|
||||
|
||||
from manimlib.utils.bezier import *
|
||||
from manimlib.utils.cache import *
|
||||
from manimlib.utils.color import *
|
||||
from manimlib.utils.dict_ops import *
|
||||
from manimlib.utils.customization import *
|
||||
|
|
|
@ -7,7 +7,7 @@ import re
|
|||
from manimlib.constants import BLACK, WHITE
|
||||
from manimlib.mobject.svg.svg_mobject import SVGMobject
|
||||
from manimlib.mobject.types.vectorized_mobject import VGroup
|
||||
from manimlib.utils.tex_file_writing import tex_content_to_svg_file
|
||||
from manimlib.utils.tex_file_writing import tex_to_svg
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
|
@ -76,12 +76,12 @@ class SingleStringTex(SVGMobject):
|
|||
self.additional_preamble
|
||||
)
|
||||
|
||||
def get_file_path(self) -> str:
|
||||
content = self.get_tex_file_body(self.tex_string)
|
||||
file_path = tex_content_to_svg_file(
|
||||
content, self.template, self.additional_preamble, self.tex_string
|
||||
def get_svg_string_by_content(self, content: str) -> str:
|
||||
return get_cached_value(
|
||||
key=hash_string(str((content, self.template, self.additional_preamble))),
|
||||
value_func=lambda: tex_to_svg(content, self.template, self.additional_preamble),
|
||||
message=f"Writing {self.tex_string}..."
|
||||
)
|
||||
return file_path
|
||||
|
||||
def get_tex_file_body(self, tex_string: str) -> str:
|
||||
new_tex = self.get_modified_expression(tex_string)
|
||||
|
|
|
@ -20,7 +20,6 @@ from manimlib.mobject.types.vectorized_mobject import VMobject
|
|||
from manimlib.utils.directories import get_mobject_data_dir
|
||||
from manimlib.utils.images import get_full_vector_image_path
|
||||
from manimlib.utils.iterables import hash_obj
|
||||
from manimlib.utils.simple_functions import hash_string
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
if TYPE_CHECKING:
|
||||
|
|
|
@ -6,10 +6,12 @@ from pathlib import Path
|
|||
from manimlib.mobject.svg.string_mobject import StringMobject
|
||||
from manimlib.mobject.types.vectorized_mobject import VGroup
|
||||
from manimlib.mobject.types.vectorized_mobject import VMobject
|
||||
from manimlib.utils.cache import get_cached_value
|
||||
from manimlib.utils.color import color_to_hex
|
||||
from manimlib.utils.color import hex_to_int
|
||||
from manimlib.utils.tex_file_writing import tex_content_to_svg_file
|
||||
from manimlib.utils.tex_file_writing import tex_to_svg
|
||||
from manimlib.utils.tex import num_tex_symbols
|
||||
from manimlib.utils.simple_functions import hash_string
|
||||
from manimlib.logger import log
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
@ -84,11 +86,11 @@ class Tex(StringMobject):
|
|||
)
|
||||
|
||||
def get_svg_string_by_content(self, content: str) -> str:
|
||||
# TODO, implement this without writing to a file
|
||||
file_path = tex_content_to_svg_file(
|
||||
content, self.template, self.additional_preamble, self.tex_string
|
||||
return get_cached_value(
|
||||
key=hash_string(str((content, self.template, self.additional_preamble))),
|
||||
value_func=lambda: tex_to_svg(content, self.template, self.additional_preamble),
|
||||
message=f"Writing {self.tex_string}..."
|
||||
)
|
||||
return Path(file_path).read_text()
|
||||
|
||||
def _handle_scale_side_effects(self, scale_factor: float) -> Self:
|
||||
self.font_size *= scale_factor
|
||||
|
|
|
@ -16,9 +16,10 @@ from manimlib.constants import DEFAULT_PIXEL_WIDTH, FRAME_WIDTH
|
|||
from manimlib.constants import NORMAL
|
||||
from manimlib.logger import log
|
||||
from manimlib.mobject.svg.string_mobject import StringMobject
|
||||
from manimlib.utils.customization import get_customization
|
||||
from manimlib.utils.cache import get_cached_value
|
||||
from manimlib.utils.color import color_to_hex
|
||||
from manimlib.utils.color import int_to_hex
|
||||
from manimlib.utils.customization import get_customization
|
||||
from manimlib.utils.directories import get_downloads_dir
|
||||
from manimlib.utils.directories import get_text_dir
|
||||
from manimlib.utils.simple_functions import hash_string
|
||||
|
@ -172,17 +173,14 @@ class MarkupText(StringMobject):
|
|||
)
|
||||
|
||||
def get_svg_string_by_content(self, content: str) -> str:
|
||||
# TODO, check the cache
|
||||
hash_content = str((
|
||||
key = hash_string(str((
|
||||
content,
|
||||
self.justify,
|
||||
self.indent,
|
||||
self.alignment,
|
||||
self.line_width
|
||||
))
|
||||
# hash_string(hash_content)
|
||||
key = hashlib.sha256(hash_content.encode()).hexdigest()
|
||||
return self.markup_to_svg_string(content)
|
||||
)))
|
||||
return get_cached_value(key, lambda: self.markup_to_svg_string(content))
|
||||
|
||||
def markup_to_svg_string(self, markup_str: str) -> str:
|
||||
self.validate_markup_string(markup_str)
|
||||
|
|
33
manimlib/utils/cache.py
Normal file
33
manimlib/utils/cache.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
import appdirs
|
||||
import os
|
||||
from diskcache import Cache
|
||||
from contextlib import contextmanager
|
||||
|
||||
|
||||
CACHE_SIZE = 1e9 # 1 Gig
|
||||
|
||||
|
||||
def get_cached_value(key, value_func, message=""):
|
||||
cache_dir = appdirs.user_cache_dir("manim")
|
||||
cache = Cache(cache_dir, size_limit=CACHE_SIZE)
|
||||
|
||||
value = cache.get(key)
|
||||
if value is None:
|
||||
with display_during_execution(message):
|
||||
value = value_func()
|
||||
cache.set(key, value)
|
||||
return value
|
||||
|
||||
|
||||
@contextmanager
|
||||
def display_during_execution(message: str):
|
||||
# Merge into a single line
|
||||
to_print = message.replace("\n", " ")
|
||||
max_characters = os.get_terminal_size().columns - 1
|
||||
if len(to_print) > max_characters:
|
||||
to_print = to_print[:max_characters - 3] + "..."
|
||||
try:
|
||||
print(to_print, end="\r")
|
||||
yield
|
||||
finally:
|
||||
print(" " * len(to_print), end="\r")
|
|
@ -1,10 +1,12 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from contextlib import contextmanager
|
||||
import os
|
||||
import re
|
||||
import yaml
|
||||
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
|
||||
from manimlib.config import get_custom_config
|
||||
from manimlib.config import get_manim_dir
|
||||
from manimlib.logger import log
|
||||
|
@ -51,9 +53,10 @@ def get_tex_config() -> dict[str, str]:
|
|||
return SAVED_TEX_CONFIG
|
||||
|
||||
|
||||
def tex_content_to_svg_file(
|
||||
content: str, template: str, additional_preamble: str,
|
||||
short_tex: str
|
||||
def tex_to_svg(
|
||||
content: str,
|
||||
template: str,
|
||||
additional_preamble: str,
|
||||
) -> str:
|
||||
tex_config = get_tex_config()
|
||||
if not template or template == tex_config["template"]:
|
||||
|
@ -74,14 +77,11 @@ def tex_content_to_svg_file(
|
|||
"\\end{document}"
|
||||
)) + "\n"
|
||||
|
||||
svg_file = os.path.join(
|
||||
get_tex_dir(), hash_string(full_tex) + ".svg"
|
||||
)
|
||||
if not os.path.exists(svg_file):
|
||||
# If svg doesn't exist, create it
|
||||
with display_during_execution("Writing " + short_tex):
|
||||
create_tex_svg(full_tex, svg_file, compiler)
|
||||
return svg_file
|
||||
with tempfile.NamedTemporaryFile(suffix='.svg', mode='r+') as tmp:
|
||||
create_tex_svg(full_tex, tmp.name, compiler)
|
||||
# Read the contents
|
||||
tmp.seek(0)
|
||||
return tmp.read()
|
||||
|
||||
|
||||
def create_tex_svg(full_tex: str, svg_file: str, compiler: str) -> None:
|
||||
|
@ -145,20 +145,5 @@ def create_tex_svg(full_tex: str, svg_file: str, compiler: str) -> None:
|
|||
pass
|
||||
|
||||
|
||||
# TODO, perhaps this should live elsewhere
|
||||
@contextmanager
|
||||
def display_during_execution(message: str):
|
||||
# Merge into a single line
|
||||
to_print = message.replace("\n", " ")
|
||||
max_characters = os.get_terminal_size().columns - 1
|
||||
if len(to_print) > max_characters:
|
||||
to_print = to_print[:max_characters - 3] + "..."
|
||||
try:
|
||||
print(to_print, end="\r")
|
||||
yield
|
||||
finally:
|
||||
print(" " * len(to_print), end="\r")
|
||||
|
||||
|
||||
class LatexError(Exception):
|
||||
pass
|
||||
|
|
Loading…
Add table
Reference in a new issue