mikedh / trimesh

Python library for loading and using triangular meshes.
https://trimesh.org
MIT License
2.94k stars 574 forks source link

Wrong colors in notebook viewer #1336

Open jravaglia opened 3 years ago

jravaglia commented 3 years ago

Hello,

first of all thanks to all developers for this library !

I want to use the trimesh viewer to visualize colored meshes (coloring vertices) in notebooks, but the notebook viewer seems to have trouble displaying the corresponding colors. However, if I use a pyglet viewer, colors are displayed as expected; and if I save the mesh, export it and open it in an external software, colors are also as expected.

So I guess there is a problem with the notebook viewer only but I am no expert. Do you have any clue about what causes this behavior ?

Here is a small code that creates a small mesh and colors the vertices according to their x coordinate together with the visualization within the notebooks viewer and the pyglet viewer :

notebook viewer

import trimesh

mesh   = trimesh.creation.icosphere()
colors = trimesh.visual.interpolate(values=mesh.vertices[:,0], color_map='viridis')

mesh.visual.vertex_colors = colors
assert(mesh.visual.kind == 'vertex')
mesh.show(viewer='notebook')

notebook_viewer

pyglet viewer

import trimesh

mesh   = trimesh.creation.icosphere()
colors = trimesh.visual.interpolate(values=mesh.vertices[:,0], color_map='viridis')

mesh.visual.vertex_colors = colors
assert(mesh.visual.kind == 'vertex')
mesh.show(viewer='gl')

pyglet_viewer

anna-charlotte commented 1 year ago

I oberved similar behaviour to the one described here. When calling .show() on a Trimesh instance, in the notebook the object seems to appear much darker than in pyglet viewer. For example, the featuretype.STL object (as used in your documentation), looks like this in pyglet viewer:

image

And like this in notevook viewer:

image
spanag commented 1 week ago

Note that other ColorVisuals are not dimmed like meshes are! The Path3D visual gets the requested color just fine. See for example, https://trimesh.org/shortest.html in the user guide.

In the above code, I set the color of both to (1,0,0) to make it more obvious vs. the background (using Jupyter):

mesh.visual.face_colors = [255, 0, 0, 255]
...
path_visual.colors = [(255, 0, 0, 255) for x in path_visual.entities]

inconsistent-mesh-path-color

How can we get the same bright red that the path has, on our meshes?

spanag commented 1 week ago

The core issue seems to be that when exporting to HTML, lights are not included in the glTF format which is used to reload the scene from in JS. (They could be exported separately and reloaded to three.js though with a patch.) Hence the lighting is different (and dim enough to be comfortable with bare solids, which by default are painted #FFFFFF.) By comparison, non-mesh annotations like paths are simply not shaded. Whereas when visualising with pyglet, the actual lights on the scene are converted and used.

Hence, a fix is to export a viewer.html that includes a modified load_base64.js, with this section substituted with the three.js equivalents of the trimesh scene lights. (By default, they are on scene.bounds with #3C3C3C color and intensity of 1)