Skip to content
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

Error in OpenGL SurfaceExample: 'Sphere' object has no attribute 'uv_func' #3705

Open
phinate opened this issue Apr 16, 2024 · 4 comments
Open

Comments

@phinate
Copy link

phinate commented Apr 16, 2024

Hi! I'm running this scene (SurfaceExample) in the OpenGL examples, and I'm unable to create the OpenGLTexturedSurface because the Sphere object is not of type OpenGLSurface and has no uv_func as far as I can see.

This is on manim==0.18.0, Python 3.12, Apple M1. I've tried downgrading manim (and Python) to <0.18, <0.17, since this was shown to be working in this video, but then started running into other issues when the latter installed 0.15.0, so I've abandoned that for now.

Any help would be much appreciated — happy to PR any changes back to the examples!

@phinate
Copy link
Author

phinate commented Apr 16, 2024

More info: I'm running manim -qm --renderer=opengl -p manim.py SurfaceExample, where manim.py contains just the code from that example (trimmed down a little to just make the sphere). I'm using these textures: https://github.com/ManimCommunity/manim/tree/04bfa221075166a00eaa11fc9e9f0757f56625d2/example_scenes/assets. Here's my code:

from pathlib import Path

import manim.utils.opengl as opengl
from manim import *
from manim.opengl import *  # type: ignore

class SurfaceExample(Scene):
    def construct(self):

        sphere = Sphere(radius=3, resolution=Torus(major_radius=1, minor_radius=1).resolution)
        # You can texture a surface with up to two images, which will
        # be interpreted as the side towards the light, and away from
        # the light.  These can be either urls, or paths to a local file
        # in whatever you've set as the image directory in
        # the custom_config.yml file

        script_location = Path(__file__).resolve().parent
        day_texture = (
            script_location / "assets" / "1280px-Whole_world_-_land_and_oceans.jpg"
        )
        night_texture = script_location / "assets" / "1280px-The_earth_at_night.jpg"

         # <-- fails here
        textured_earth = OpenGLTexturedSurface(sphere, day_texture, night_texture) 


        textured_earth.shift(IN)
        textured_earth.mesh = OpenGLSurfaceMesh(textured_earth)
        textured_earth.mesh.set_stroke(BLUE, 1, opacity=0.5)

        # Set perspective
        frame = self.renderer.camera
        frame.set_euler_angles(
            theta=-30 * DEGREES,
            phi=70 * DEGREES,
        )

        

        self.play(
            FadeIn(textured_earth),
            Create(textured_earth.mesh, lag_ratio=0.01, run_time=3),
        )
        textured_earth.add(textured_earth.mesh)
        textured_earth.save_state()
        self.play(Rotate(textured_earth, PI / 2), run_time=2)

        # self.play(Transform(surface, surfaces[1]), run_time=3)

        # self.play(
        #     Transform(surface, surfaces[2]),
        #     # Move camera frame during the transition
        #     frame.animate.increment_phi(-10 * DEGREES),
        #     frame.animate.increment_theta(-20 * DEGREES),
        #     run_time=3,
        # )
        # Add ambient rotation
        frame.add_updater(lambda m, dt: m.increment_theta(-0.1 * dt))

        # Play around with where the light is
        # light_text = Text("You can move around the light source")
        # light_text.move_to(surface_text)
        # light_text.fix_in_frame()

        # self.play(FadeTransform(surface_text, light_text))
        light = self.camera.light_source
        self.add(light)
        light.save_state()
        self.play(light.animate.move_to(3 * IN), run_time=5)
        self.play(light.animate.shift(10 * OUT), run_time=5)

@uwezi
Copy link
Contributor

uwezi commented Apr 16, 2024

try to rename your file to something else than "manim.py" and make sure to remove any file called "manim.py"

@phinate
Copy link
Author

phinate commented Apr 16, 2024

try to rename your file to something else than "manim.py" and make sure to remove any file called "manim.py"

Right, that was an accidental top-level library name pollution, but it didn't impact running this particular example, which I can replicate regardless of filename in a blank directory, and also in a Jupyter notebook.

@uwezi
Copy link
Contributor

uwezi commented Apr 16, 2024

as a help to debug the cause of the new problem in 0.18.0.post0: the following code works, i.e. explicitly defining an OpenGLSurface while the internal overloading of a Surface or Sphere does not work and gives an error because uv_func is not defined....

from manim import *
from manim.opengl import *  # type: ignore

class SurfaceExample(Scene):
    def construct(self):

        sphere = OpenGLSurface(
            lambda u,v: [3*np.sin(u)*np.cos(v), 3*np.sin(u)*np.sin(v), 3*np.cos(u)],
            u_range=[0,PI],
            v_range=[-PI,PI]
        )

        # You can texture a surface with up to two images, which will
        # be interpreted as the side towards the light, and away from
        # the light.  These can be either urls, or paths to a local file
        # in whatever you've set as the image directory in
        # the custom_config.yml file

        day_texture = "bilder/1280px-Whole_world_-_land_and_oceans.jpg"

        night_texture = "bilder/1280px-The_earth_at_night.jpg"

         # <-- fails here
        textured_earth = OpenGLTexturedSurface(sphere, day_texture, night_texture)


        textured_earth.shift(IN)
        textured_earth.mesh = OpenGLSurfaceMesh(textured_earth)
        textured_earth.mesh.set_stroke(BLUE, 1, opacity=0.5)

        # Set perspective
        frame = self.renderer.camera
        frame.set_euler_angles(
            theta=-30 * DEGREES,
            phi=70 * DEGREES,
        )



        self.play(
            FadeIn(textured_earth),
            Create(textured_earth.mesh, lag_ratio=0.01, run_time=3),
        )
        textured_earth.add(textured_earth.mesh)
        textured_earth.save_state()
        self.play(Rotate(textured_earth, PI / 2), run_time=2)

        # self.play(Transform(surface, surfaces[1]), run_time=3)

        # self.play(
        #     Transform(surface, surfaces[2]),
        #     # Move camera frame during the transition
        #     frame.animate.increment_phi(-10 * DEGREES),
        #     frame.animate.increment_theta(-20 * DEGREES),
        #     run_time=3,
        # )
        # Add ambient rotation
        frame.add_updater(lambda m, dt: m.increment_theta(-0.1 * dt))

        # Play around with where the light is
        # light_text = Text("You can move around the light source")
        # light_text.move_to(surface_text)
        # light_text.fix_in_frame()

        # self.play(FadeTransform(surface_text, light_text))
        light = self.camera.light_source
        self.add(light)
        light.save_state()
        self.play(light.animate.move_to(3 * IN), run_time=5)
        self.play(light.animate.shift(10 * OUT), run_time=5)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 🆕 New
Development

No branches or pull requests

2 participants