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

face_colors doesn't color faces properly, but instead interpolates the colors #1997

Open
coderforlife opened this issue Aug 7, 2023 · 7 comments

Comments

@coderforlife
Copy link

If I draw a box with each triangle a solid color like so:

import trimesh
import numpy as np
mesh = trimesh.primitives.Box(extents=(5, 5, 5))
mesh.visual.face_colors = np.array([
    [255, 0, 0, 255],
    [255, 128, 0, 255],
    [255, 255, 0, 255],
    [128, 255, 0, 255],
    [0, 255, 0, 255],
    [0, 255, 128, 255],
    [0, 255, 255, 255],
    [0, 128, 255, 255],
    [0, 0, 255, 255],
    [128, 0, 255, 255],
    [255, 0, 255, 255],
    [255, 0, 128, 255],
])
mesh.show()

There are no solid colors anywhere on the cube, everything is a gradient. When doing a face-visual (instead of a vertex-visual) you need to be using flat colors for each triangle. This may require a geometry shader to do properly so that each triangle can emit the same color to each of its vertices (and each vertex is emitted by one triangle instead of shared between triangles).

It is even more severe than just making gradients as entire faces can miss the designated color. For example, in the box, there is no spot that is red (to make it really obvious, keep the first color red and set all other colors to black - the entire cube is black with no hint of red anywhere).

I was using the trimesh library to highlight particular faces with particular computed properties, but several faces weren't showing up because of this issue.

@mikedh
Copy link
Owner

mikedh commented Aug 8, 2023

Hey, I think you might want mesh.show(smooth=False) which should probably be the default if mesh.visual.kind == 'face', which produces this:
image

@coderforlife
Copy link
Author

Exactly! Sorry I didn't find that option. Still a bit odd that with smoothing some face colors get completely dropped...

@coderforlife
Copy link
Author

Reopening... smooth=False doesn't work in Jupyter notebook...

@coderforlife coderforlife reopened this Aug 8, 2023
@paireks
Copy link

paireks commented Nov 1, 2023

Yes, I have the same issue. Tried smooth=False and mesh.visual.kind == 'face', but it still keeps smoothing.
2023-11-01_17h21_10

@gtangg11
Copy link

gtangg11 commented Aug 1, 2024

Has this been resolved. It seems preventing interpolation in trimesh is just not possible.

ie this code still interpolates

mesh = Trimesh(mesh.vertices, mesh.faces, smooth=False, process=False)
mesh.visual.vertex_colors = None
mesh.visual.face_colors = np.random.randint(0, 255, (len(mesh.faces), 3))
mesh.visual.kind == 'face'
return mesh

@gtangg11
Copy link

gtangg11 commented Aug 1, 2024

Ok, it seems the reason why face interpolation is happening is because openGL stores the data in vertex form as opposed to face form. Just run your mesh through this function, which preserves the number and index of faces but makes the vertices unique (and changes faces' vertex indexing)

def duplicate_verts(mesh: Trimesh):
    """
    """
    verts = mesh.vertices[mesh.faces.reshape(-1), :]
    faces = np.arange(0, verts.shape[0])
    faces = faces.reshape(-1, 3)
    return Trimesh(vertices=verts, faces=faces, process=False)

Wish this would have been made clear before, which would have saved a lot of time for everyone (only occurred to me reading the src code of mesh.show() as well as getting misled by Trimesh arguments such as process and smooth).

Before:
Screenshot 2024-08-01 at 7 40 18 AM

After:
Screenshot 2024-08-01 at 7 41 15 AM

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

No branches or pull requests

4 participants