pythoncolorsmeshcubevispy

How can I modify the face colors of a mesh object with vispy when they're already set?


I've got a problem trying to modify the colors of the faces of my Mesh cube with vispy. I an using the set_face_colors() method but it's not working. I think I just don't know how to use it properly...

Here's my code. The goal really is just dispalying 2 cubes with the same color when pressing 'a'.

from vispy import app, scene, geometry
import numpy as np

class MonCanvas(scene.SceneCanvas):
    def on_key_press(self,event):
        global cube1, cube2, c1data, c2data
        print("You pressed '{}'".format(event.text))
        if '{}'.format(event.text) == 'a':
            print(c2data.get_face_colors())
            print(c1data)
            cube1 = cube1.mesh_data.set_face_colors([[0,0,1,1],[0,0,1,1],[0,1,0,1],[0,1,0,1],[1,1,1,1],[1,1,1,1],[1,1,0,1],[1,1,0,1],[1,0,0,1],[1,0,0,1],[1,0.5,0,1],[1,0.5,0,1]])
            print(c1data)

fenetre = MonCanvas(title="FenĂȘtre principale", size=(2000,1000), keys="interactive")

view = fenetre.central_widget.add_view()
view.camera = 'turntable'
view.camera.distance = 10

c1data = geometry.MeshData(vertices = np.array([[0.5,0.5,-0.5],[0.5,-0.5,-0.5],[-0.5,0.5,-0.5],[-0.5,-0.5,-0.5],[0.5,0.5,0.5],[0.5,-0.5,0.5],[-0.5,0.5,0.5],[-0.5,-0.5,0.5]]), edges = np.array([[0,1],[0,2],[0,4],[3,1],[3,2],[3,7],[5,1],[5,4],[5,7],[6,2],[6,4],[6,7]]), faces = np.array([[1,2,3],[0,1,2],[5,6,7],[4,5,6],[0,1,5],[0,5,4],[2,3,7],[2,7,6],[1,3,7],[1,7,5],[0,2,6],[0,6,4]]))
c1data.set_face_colors([[0,0,1,1],[0,0,1,1],[0,0,1,1],[0,0,1,1],[0,0,1,1],[0,0,1,1],[0,0,1,1],[0,0,1,1],[0,0,1,1],[0,0,1,1],[0,0,1,1],[0,0,1,1]])
cube1 = scene.visuals.Mesh(meshdata = c1data)
view.add(cube1)

c2data = geometry.MeshData(vertices = np.array([[0.5,0.5,0.5],[0.5,-0.5,0.5],[-0.5,0.5,0.5],[-0.5,-0.5,0.5],[0.5,0.5,1.5],[0.5,-0.5,1.5],[-0.5,0.5,1.5],[-0.5,-0.5,1.5]]), edges = np.array([[0,1],[0,2],[0,4],[3,1],[3,2],[3,7],[5,1],[5,4],[5,7],[6,2],[6,4],[6,7]]), faces = np.array([[1,2,3],[0,1,2],[5,6,7],[4,5,6],[0,1,5],[0,5,4],[2,3,7],[2,7,6],[1,3,7],[1,7,5],[0,2,6],[0,6,4]]))
c2data.set_face_colors([[0,0,1,1],[0,0,1,1],[0,1,0,1],[0,1,0,1],[1,1,1,1],[1,1,1,1],[1,1,0,1],[1,1,0,1],[1,0,0,1],[1,0,0,1],[1,0.5,0,1],[1,0.5,0,1]])
cube2 = scene.visuals.Mesh(meshdata = c2data)
view.add(cube2)

fenetre.show()
app.run()

Thank you all for your help !


Solution

  • So there are two things that need changing in your code. First, you reassign cube1 in your key press handler when you set the face colors. set_face_colors doesn't return anything so you're setting cube1 to None. Not necessarily a problem since vispy will hold on to references, but definitely not something you intended to do I'm guessing.

    Next, you've updated the MeshData object underneath the MeshVisual, but haven't told the MeshVisual. As an optimization, MeshVisual will only update the GPU-side data when it is told that it has changed. This is done automatically when you use methods like mesh.set_data. In cases like yours when you're updating the lower-level MeshData object (a perfectly fine thing to do I think), you can tell the mesh to update by doing cube1.mesh_data_changed() right after the set_face_colors call.