Fix: Issue with OpenGL rendering for Transform of SVGMobjects #4182
This is a fix for issue https://github.com/ManimCommunity/manim/issues/4182
Overview: What does this pull request change?
In some cases the stroke_width parameter is not saved as a np.ndarray but a float or int instead.
In that case the len(...) call will fail in the align_data method in opengl_mobject.py.
In the PR the for loop in align_data is also skipped for data with the key stroke_width or if the self.data[key] is of type int in the interpolate method.
Reviewer Checklist
- [ ] The PR title is descriptive enough for the changelog, and the PR is labeled correctly
- [ ] If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
- [ ] If applicable: newly added functions and classes are tested
Wouldn't it be better to make sure the stroke_width is actually stored as a numpy array? (I don't have a strong opinion on this though, I'd also be willing to merge this as-is.)
Thanks for your effort!
Wouldn't it be better to make sure the stroke_width is actually stored as a numpy array? I think it would be a cleaner solution to make it a numpy array.
In this branch https://github.com/henrikmidtiby/manim/commits/Issue4182MakeArray/ I have tried to make stroke_width an np.array in all locations in opengl_vectorized_mobject.py.
In that case it works fine with all the unit tests, but the example given in issue https://github.com/ManimCommunity/manim/issues/4182#issuecomment-3151032237 would now fail with the error shown below.
│ /home/hemi/localbuild/manim/manim/renderer/opengl_renderer.py:340 in render_mobject │
│ │
│ 337 │ │ │ if config["use_projection_stroke_shaders"]: │
│ 338 │ │ │ │ render_opengl_vectorized_mobject_stroke(self, mobject) │
│ 339 │ │ │
│ ❱ 340 │ │ shader_wrapper_list = mobject.get_shader_wrapper_list() │
│ 341 │ │ │
│ 342 │ │ # Convert ShaderWrappers to Meshes. │
│ 343 │ │ for shader_wrapper in shader_wrapper_list: │
│ │
│ /home/hemi/localbuild/manim/manim/mobject/opengl/opengl_vectorized_mobject.py:1548 in │
│ get_shader_wrapper_list │
│ │
│ 1545 │ │ for submob in self.family_members_with_points(): │
│ 1546 │ │ │ if submob.has_fill() and not config["use_projection_fill_shaders"]: │
│ 1547 │ │ │ │ fill_shader_wrappers.append(submob.get_fill_shader_wrapper()) │
│ ❱ 1548 │ │ │ if submob.has_stroke() and not config["use_projection_stroke_shaders"]: │
│ 1549 │ │ │ │ ssw = submob.get_stroke_shader_wrapper() │
│ 1550 │ │ │ │ if submob.draw_stroke_behind_fill: │
│ 1551 │ │ │ │ │ back_stroke_shader_wrappers.append(ssw) │
│ │
│ /home/hemi/localbuild/manim/manim/mobject/opengl/opengl_vectorized_mobject.py:455 in has_stroke │
│ │
│ 452 │ │ return ( │
│ 453 │ │ │ stroke_widths is not None │
│ 454 │ │ │ and stroke_opacities is not None │
│ ❱ 455 │ │ │ and any(stroke_widths) │
│ 456 │ │ │ and any(stroke_opacities) │
│ 457 │ │ ) │
│ 458 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
TypeError: iteration over a 0-d array
This seems to be caused by the SVGMobject, which sets the stroke_width property to a float an I cannot locate where.