2

There is no example in OpenMesh documentation for coloring faces. Which function should I use to color fh0 to green? (I tried mesh.set_color but could not succeed. You can see my attempt on second part of code)

import openmesh as om
import numpy as np

mesh = om.TriMesh()

# add a a couple of vertices to the mesh
vh0 = mesh.add_vertex([0, 1, 0])
vh1 = mesh.add_vertex([1, 0, 0])
vh2 = mesh.add_vertex([2, 1, 0])
vh3 = mesh.add_vertex([0,-1, 0])
vh4 = mesh.add_vertex([2,-1, 0])

# add a couple of faces to the mesh
fh0 = mesh.add_face(vh0, vh1, vh2)
fh1 = mesh.add_face(vh1, vh3, vh4)
fh2 = mesh.add_face(vh0, vh3, vh1)

# add another face to the mesh, this time using a list
vh_list = [vh2, vh1, vh4]
fh3 = mesh.add_face(vh_list)

#  0 ==== 2
#  |\  0 /|
#  | \  / |
#  |2  1 3|
#  | /  \ |
#  |/  1 \|
#  3 ==== 4

for face in mesh.faces():
    mesh.set_color(face, [0.67578125, 0.296875, 0.3515625])

om.write_mesh('test.obj', mesh)

but this gives me

IndexError: index 3 is out of bounds for axis 0 with size 3

How can I add color to faces in OpenMesh?

Lyrk
  • 1,936
  • 4
  • 26
  • 48

2 Answers2

3

There are several issues:

  1. mesh.request_face_colors() is required for the TriMesh object to support storing face colors.
  2. mesh.set_color expects an alpha channel, so your color is actually [0.67578125, 0.296875, 0.3515625, 1.]
  3. write_mesh requires face_color=True argument.
  4. .obj file format doesn't support vertex/face color. Color is saved in a separate .mtl file ("material"). You can use other formats instead, ie .ply.

Full code:

import openmesh as om

mesh = om.TriMesh()

# add a a couple of vertices to the mesh
vh0 = mesh.add_vertex([0, 1, 0])
vh1 = mesh.add_vertex([1, 0, 0])
vh2 = mesh.add_vertex([2, 1, 0])
vh3 = mesh.add_vertex([0,-1, 0])
vh4 = mesh.add_vertex([2,-1, 0])

# add a couple of faces to the mesh
fh0 = mesh.add_face(vh0, vh1, vh2)
fh1 = mesh.add_face(vh1, vh3, vh4)
fh2 = mesh.add_face(vh0, vh3, vh1)

# add another face to the mesh, this time using a list
vh_list = [vh2, vh1, vh4]
fh3 = mesh.add_face(vh_list)

#  0 ==== 2
#  |\  0 /|
#  | \  / |
#  |2  1 3|
#  | /  \ |
#  |/  1 \|
#  3 ==== 4

mesh.request_face_colors()

for face in mesh.faces():
    mesh.set_color(face, [0.67578125, 0.296875, 0.3515625, 1.])

for face in mesh.faces():
    print(mesh.color(face))

om.write_mesh('test.obj', mesh, face_color=True)
om.write_mesh('test.ply', mesh, face_color=True)

Console output (color attribute was successfully added to the mesh):

[0.67578125 0.296875   0.3515625  1.        ]
[0.67578125 0.296875   0.3515625  1.        ]
[0.67578125 0.296875   0.3515625  1.        ]
[0.67578125 0.296875   0.3515625  1.        ]

Content of test.obj:

# 5 vertices, 4 faces
mtllib test.mat
v 0.000000 1.000000 0.000000
v 1.000000 0.000000 0.000000
v 2.000000 1.000000 0.000000
v 0.000000 -1.000000 0.000000
v 2.000000 -1.000000 0.000000
usemtl mat0
f 1 2 3
f 2 4 5
f 1 4 2
f 3 2 5

Content of test.mat (this file specifies what "mat0" in the test.obj file means):

newmtl mat0
Ka 0.5000 0.5000 0.5000
Kd 0.67451 0.298039 0.352941
illum 1

Content of test.ply (everything in a single file):

ply
format ascii 1.0
element vertex 5
property float x
property float y
property float z
element face 4
property list uchar int vertex_indices
property uchar red
property uchar green
property uchar blue
end_header
0 1 0
1 0 0
2 1 0
0 -1 0
2 -1 0
3 0 1 2 172 76 90
3 1 3 4 172 76 90
3 0 3 1 172 76 90
3 2 1 4 172 76 90
Mark Loyman
  • 1,983
  • 1
  • 14
  • 23
  • is color added to .obj file? It doesn't seem so from the output. – Lyrk Aug 01 '21 at 09:30
  • 1
    No. `obj` file format doesn't support vertex/face color attributes. Which is why I suggested to use `ply` instead. – Mark Loyman Aug 01 '21 at 18:06
  • Clarification: '.obj' files do allow encoding color (but not as vertex/face color attributes) using an additional `.mtl` file. I'm not familiar with this, but you can try to take a look at blender if using `obj` is mandatory. – Mark Loyman Aug 01 '21 at 19:39
  • Openmesh created another .mtl file as you said for storing face colors. But .off file is more useful I think. It includes colors in a single file and can be viewed by most of the programs. thank you. – Lyrk Aug 02 '21 at 05:39
0

Face color is one of the standard properties in OpenMesh.

To add a standard property to an entity simply use the appropriate request method.

In your case it will be mesh.request_face_colors().

referenced documentation

K450
  • 691
  • 5
  • 17
  • Is it possible that you add to the code I supplied above? For example paint fh0 to green and write to a .ply file. – Lyrk Jul 25 '21 at 12:45
  • @Lyrk what I think I understand so far from the documentation is that these request methods adds those properties to your mesh (more like it enables those properties). So I think you just need to request a property before setting it. In your case call `mesh.request_face_colors()` before the loop where you set colors using `mesh.set_color()`. – K450 Jul 25 '21 at 13:11
  • I already did it. It runs without any errors but when I check the .ply file created, there is no color component. @K450 – Lyrk Jul 25 '21 at 17:24
  • The documentation also talks about setting property bits using Options to tell writer what we would like to have stored if supported by the file format. So try this `options = om.Options()` `options += om.Options.FaceColor` `om.write_mesh(mesh, "test.obj", options)`. Also other references showed conflicting or no syntax for writing files so not sure if syntax is correct or if it will work. here is the reference I used [ref 1](https://www.graphics.rwth-aachen.de/media/openmesh_static/Documentations/OpenMesh-6.1-Documentation/a00062.html) – K450 Jul 25 '21 at 18:30
  • [ref2](https://www.graphics.rwth-aachen.de/media/openmesh_static/Documentations/OpenMesh-6.1-Documentation/a00036.html#python_cpp) – K450 Jul 25 '21 at 18:30
  • I get this error. AttributeError: module 'openmesh' has no attribute 'Options' – Lyrk Jul 25 '21 at 19:22
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/235291/discussion-between-k450-and-lyrk). – K450 Jul 26 '21 at 05:57