jupyter-widgets / pythreejs

A Jupyter - Three.js bridge
https://pythreejs.readthedocs.io
Other
951 stars 188 forks source link

VertexColors on Mesh Geometries #34

Closed j-herrera closed 7 years ago

j-herrera commented 8 years ago

pythreejs doesn't seem to render vertexColors on Mesh geometries. A minimal example of what I was trying to do is:

geom = PlainGeometry(vertices=[[0,0,0],[1,0,0],[0,1,0],[0,0,1]],
                          faces=[[1,2,3],[0,1,2]],
                          colors = ['red',  'green', 'white', 'orange'])
mesh = Mesh(geometry=geom, material=BasicMaterial(vertexColors='VertexColors'))
scene = Scene(children=[mesh, DirectionalLight(color=0xccaabb, position=[0,10,0]),AmbientLight(color=0xcccccc)])
c = PerspectiveCamera(position=[0,2,2])
renderer = Renderer(camera=c, scene = scene, controls=[OrbitControls(controlling=c)])
display(renderer)

The expected result is two triangles with interpolated colors on faces from vertex values. Instead, two white triangles are rendered. If Mesh is substituted by Line, the lines are interpolated.

Am I doing something wrong? Is this feature not implemented? I'm trying to do scientific visualization of 3D mesh data on ipython using pythreejs and this feature would be really useful.

jasongrout commented 8 years ago

Looking into this. Here's a three.js example doing what you want: http://threejs.org/examples/#webgl_geometry_colors

DavidPowell commented 8 years ago

I am having the same problem, except I am defining colours per face, rather than per vertex, so I use the material setting vertexColors='FaceColors'.

I note in the MeshBasicMaterial documentation, that this setting only works with the webgl renderer, and not the canvas renderer. However, I checked the javascript console, and it seems that I am using the webgl renderer, so this doesn't seem to be the cause.

DavidPowell commented 8 years ago

I forgot to mention, the problem may be related to the use of PlainGeometry. Regardless of whether or not I try adding colours, I get the javascript error:

jupyter-threejs.js: 109 Uncaught TypeError: Cannot read property 'obj' of undefined

This error does not appear if I instead use a FaceGeometry, but then I have no option for colouring faces.

misolietavec commented 7 years ago

Based on jasongrout example in new Examples.ipynb, this is the solution:

geom = PlainGeometry(vertices=[[0,0,0],[1,0,0],[0,1,0],[0,0,1]],
                     faces=[[1,2,3],[0,1,2]],
                     colors = ['red',  'green', 'white', 'orange'])

# this is the crucial change
geom.faceColors = [[vertexcolors[i] for i in f] for f in faces] 

mesh = Mesh(geometry=geom, material=LambertMaterial(vertexColors='VertexColors'))
scene = Scene(children=[mesh, DirectionalLight(color="#ccaabb", position=[0,10,0]),
                        AmbientLight(color="#cccccc")])
c = PerspectiveCamera(position=[0,2,2])
renderer = Renderer(camera=c, scene = scene, controls=[OrbitControls(controlling=c)])
display(renderer)

Works with pythreejs version 0.3.1.

jasongrout commented 7 years ago

Thanks for the answer, @misolietavec!