-
Couldn't load subscription status.
- Fork 2.5k
Add text and SVG mobjects to OpenGL #1200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks neat thanks. Tried it locally and it works. While I wonder something isn't working out
class WriteStuff(Scene):
def construct(self):
example_text = OpenGLTex("This is a some text", tex_to_color_map={"text": YELLOW})
example_tex = OpenGLMathTex(
"\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}",
)
group = OpenGLVGroup(example_text, example_tex)
group.arrange(DOWN)
group.width = config["frame_width"] - 2 * LARGE_BUFF
self.play(Write(example_text))
self.play(Write(example_tex))
self.wait()same as in basic.py. This creates a video like
WriteStuff.mp4
while when using Cairo renderer from basic.py it gives
WriteStuff.mp4
Is this difference indented?
for more information, see https://pre-commit.ci
|
The extra argument to |
|
Traceback➜ manim render .\opengl_test.py -pqm --renderer=opengl
Manim Community v0.5.0
1: ChanimTest
2: WriteStuff
Choose number corresponding to desired scene/arguments.
(Use comma separated list for multiple entries)
Choice(s): 1
Traceback (most recent call last):
╭──────────────────────────────────────────────────────────────────────────────────────╮
│ File "C:\CodeProjects\Python\Manim\manim\manim\cli\render\commands.py", line 115, in │
│render │
│ 112 try: │
│ 113 renderer = OpenGLRenderer() │
│ 114 scene = SceneClass(renderer) │
│ ❱ 115 scene.render() │
│ 116 except Exception: │
│ 117 console.print_exception() │
│ 118 elif config.renderer == "webgl": │
│ File "C:\CodeProjects\Python\Manim\manim\manim\scene\scene.py", line 179, in render │
│ 176 """ │
│ 177 self.setup() │
│ 178 try: │
│ ❱ 179 self.construct() │
│ 180 except EndSceneEarlyException: │
│ 181 pass │
│ 182 self.tear_down() │
│ File "opengl_test.py", line 21, in construct │
│ 18 │
│ 19 class ChanimTest(Scene): │
│ 20 def construct(self): │
│ ❱ 21 c = OpenGLChemObject(Benzene_Diazonium_Chloride) │
│ 22 │
│ 23 self.play(Write(c)) │
│ 24 self.wait() │
│ File "c:\codeprojects\python\manim\chanim\chanim\chem_objects.py", line 143, in │
│__init__ │
│ 140 node_style=node_style, │
│ 141 bond_style=bond_style, │
│ 142 ) │
│ ❱ 143 super().__init__( │
│ 144 "\\chemfig{%s}" % chem_code, │
│ 145 stroke_width=stroke_width, │
│ 146 tex_template=self.template, │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\svg\opengl_tex_mobject.py", │
│line 400, in __init__ │
│ 397 self.tex_environment = tex_environment │
│ 398 tex_strings = self.break_up_tex_strings(tex_strings) │
│ 399 self.tex_strings = tex_strings │
│ ❱ 400 OpenGLSingleStringMathTex.__init__( │
│ 401 self, │
│ 402 self.arg_separator.join(tex_strings), │
│ 403 tex_environment=self.tex_environment, │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\svg\opengl_tex_mobject.py", │
│line 237, in __init__ │
│ 234 environment=self.tex_environment, │
│ 235 tex_template=self.tex_template, │
│ 236 ) │
│ ❱ 237 OpenGLSVGMobject.__init__( │
│ 238 self, │
│ 239 file_name=file_name, │
│ 240 should_center=should_center, │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\svg\opengl_svg_mobject.py", │
│line 31, in __init__ │
│ 28 "should_subdivide_sharp_curves": should_subdivide_sharp_curves, │
│ 29 "should_remove_null_curves": should_remove_null_curves, │
│ 30 } │
│ ❱ 31 OpenGLVMobject.__init__( │
│ 32 self, stroke_width=stroke_width, fill_opacity=fill_opacity, **kwarg│
│ 33 ) │
│ 34 self.move_into_position(width, height) │
│ File │
│"C:\CodeProjects\Python\Manim\manim\manim\mobject\types\opengl_vectorized_mobject.py",│
│line 118, in __init__ │
│ 115 │
│ 116 self.needs_new_triangulation = True │
│ 117 self.triangulation = np.zeros(0, dtype="i4") │
│ ❱ 118 super().__init__(**kwargs) │
│ 119 self.refresh_unit_normal() │
│ 120 │
│ 121 def get_group_class(self): │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\opengl_mobject.py", line 91, │
│in __init__ │
│ 88 self.init_uniforms() │
│ 89 self.init_updaters() │
│ 90 # self.init_event_listners() │
│ ❱ 91 self.init_points() │
│ 92 self.init_colors() │
│ 93 │
│ 94 self.shader_indices = None │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\svg\opengl_svg_mobject.py", │
│line 37, in init_points │
│ 34 self.move_into_position(width, height) │
│ 35 │
│ 36 def init_points(self): │
│ ❱ 37 self.generate_points() │
│ 38 │
│ 39 def path_string_to_mobject(self, path_string: str, style: dict): │
│ 40 return OpenGLSVGPathMobject( │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\svg\svg_mobject.py", line 128,│
│in generate_points │
│ 125 """ │
│ 126 doc = minidom_parse(self.file_path) │
│ 127 for svg in doc.getElementsByTagName("svg"): │
│ ❱ 128 mobjects = self.get_mobjects_from(svg, {}) │
│ 129 if self.unpack_groups: │
│ 130 self.add(*mobjects) │
│ 131 else: │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\svg\svg_mobject.py", line 174,│
│in get_mobjects_from │
│ 171 pass # TODO, handle style │
│ 172 elif element.tagName in ["g", "svg", "symbol", "defs"]: │
│ 173 result += it.chain( │
│ ❱ 174 *[ │
│ 175 self.get_mobjects_from( │
│ 176 child, style, within_defs=within_defs or is_defs │
│ 177 ) │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\svg\svg_mobject.py", line 175,│
│in <listcomp> │
│ 172 elif element.tagName in ["g", "svg", "symbol", "defs"]: │
│ 173 result += it.chain( │
│ 174 *[ │
│ ❱ 175 self.get_mobjects_from( │
│ 176 child, style, within_defs=within_defs or is_defs │
│ 177 ) │
│ 178 for child in element.childNodes │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\svg\svg_mobject.py", line 174,│
│in get_mobjects_from │
│ 171 pass # TODO, handle style │
│ 172 elif element.tagName in ["g", "svg", "symbol", "defs"]: │
│ 173 result += it.chain( │
│ ❱ 174 *[ │
│ 175 self.get_mobjects_from( │
│ 176 child, style, within_defs=within_defs or is_defs │
│ 177 ) │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\svg\svg_mobject.py", line 175,│
│in <listcomp> │
│ 172 elif element.tagName in ["g", "svg", "symbol", "defs"]: │
│ 173 result += it.chain( │
│ 174 *[ │
│ ❱ 175 self.get_mobjects_from( │
│ 176 child, style, within_defs=within_defs or is_defs │
│ 177 ) │
│ 178 for child in element.childNodes │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\svg\svg_mobject.py", line 203,│
│in get_mobjects_from │
│ 200 │
│ 201 result = [m for m in result if m is not None] │
│ 202 if config["renderer"] == "opengl": │
│ ❱ 203 self.handle_transforms(element, OpenGLVGroup(*result)) │
│ 204 else: │
│ 205 self.handle_transforms(element, VGroup(*result)) │
│ 206 if len(result) > 1 and not self.unpack_groups: │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\svg\svg_mobject.py", line 513,│
│in handle_transforms │
│ 510 matrix[:, 1] *= -1 │
│ 511 │
│ 512 for mob in mobject.family_members_with_points(): │
│ ❱ 513 mob.points = np.dot(mob.points, matrix) │
│ 514 mobject.shift(x * RIGHT + y * UP) │
│ 515 │
│ 516 elif op_name == "scale": │
│ File "C:\CodeProjects\Python\Manim\manim\manim\mobject\mobject.py", line 526, in │
│__getattr__ │
│ 523 return types.MethodType(setter, self) │
│ 524 │
│ 525 # Unhandled attribute, therefore error │
│ ❱ 526 raise AttributeError(f"{type(self).__name__} object has no attribute │
│ 527 │
│ 528 @property │
│ 529 def width(self): │
╰──────────────────────────────────────────────────────────────────────────────────────╯
AttributeError: OpenGLTexSymbol object has no attribute 'points'Code usedclass ChanimTest(Scene):
def construct(self):
Benzene_Diazonium_Chloride = "*6(-=-=(-\\chemabove{N_2}{\quad\scriptstyle+}\\chemabove{Cl}{\quad\scriptstyle-})-=-)"
c = OpenGLChemObject(Benzene_Diazonium_Chloride)
self.play(Write(c))
self.wait()while for another, the output is pretty jagged: Code 2class ChanimTest(Scene):
def construct(self):
Benzene = "*6(-=-=-=)"
c = OpenGLChemObject(Benzene)
self.play(Write(c))
self.wait()Output rendered with `-pqk`ChanimTest.mp4I tested it out on some other input strings as well and got the same error. From what it seems, it breaks whenever it encounters an SVG with notmal text apparently. Is there a way around this? |
|
I added a missing check for the crash. The other problem might be solvable if you upload an SVG to compare against with cairo. |
|
Great! The fix works. Here are two videos comparing output from both renderers both rendered with ChanimTest.mp4Cairo: ChanimTest2.mp4and here's the SVG being used: |
|
I don't get the jagged video, what animation are you using? I generated this with Create. Test.mp4 |
|
I used |
|
I get this with Write Test.mp4 |
|
Weird... I can't get output like that from either |
|
It works correctly for me too: |
|
@kilacoda Are you able to render the rest of the OpenGL example scenes correctly? Also, it seems that the Cairo renderer renders the SVG with a black stroke color while the OpenGL renderer renders it white, is this intended? |
I tried them out just now, and apparently What code are you guys using exactly to render the SVG btw? I can try using that as is. |
For Cairo I uncommented the background color line, since for some reason the colors are opposite on both renderers. |
|
It's pretty clear that the problem being discussed now isn't related to this PR, so can this be approved and the debugging moved into #1240? |
|
There weren't any tests for this PR, is @ManimCommunity/tests okay with that? |
|
Also, this seems to not have been squashed and merged... |
Changelog / Overview
Added OpenGL-compatible text and SVG mobjects
Motivation
Add text and svg mobjects that work with the OpenGL renderer
Explanation for Changes
Created
opengl_text_mobject.pyandopengl_svg_path.pythat are mostly copied from the Cairo versions.opengl_svg_path.pyandopengl_svg_mobject.pyhave just enough information to allow reuse of our existing SVG / Text logic.Testing Status
None, but I'm willing to add some if I can figure out how to generate test data for OpenGL scenes.
Further Comments
Regarding the amount of duplicated code that this and the earlier OpenGL changes introduced, I don't know if it'll ever make sense to combine our Cairo and OpenGL logic. If so, it will have to be done very carefully.
Checklist
Reviewer Checklist