3
$\begingroup$

I'm working on a custom exporter for an external software. I need to get a list of the vertex colors from a triangulated mesh.

To get the triangulated mesh I use this code:

bm = bmesh.new()
bm.from_mesh(SceneObj.to_mesh())
bmesh.ops.triangulate(bm, faces=bm.faces, quad_method='BEAUTY', ngon_method='BEAUTY')

With normal meshes I use this code:

#Get vertex color list without duplicates
VertexColList = []
if len(MeshObject.vertex_colors):
    if hasattr(MeshObject.vertex_colors.active, 'data'):
        for layer in MeshObject.vertex_colors:
            for vertex in layer.data:
                VertexColList.append(
                    (vertex.color[0] * .5, vertex.color[1] * .5, vertex.color[2] * .5, vertex.color[3])
                )
        VertexColList = list(dict.fromkeys(VertexColList))

But that piece of code not works in a bmesh, what should I change to make it works?

$\endgroup$
4
$\begingroup$

Bmesh.from_object

Doh, @scurest Answered while I was putting the bins out, may as well post

import bpy
import bmesh

context = bpy.context
ob = context.object
dg = context.evaluated_depsgraph_get()

bm = bmesh.new()
bm.from_object(ob, dg)
print("Evaluated bmesh object", ob.name, "mesh:", ob.data.name)
tris = bm.calc_loop_triangles()
print(
    "faces", len(bm.faces), 
    "edges", len(bm.edges),
    "verts", len(bm.verts),
    "tris", len(tris)
    )

for name, cl in bm.loops.layers.color.items():
    print("Colour Layer", name)

    for i, tri in enumerate(tris):
        print("Tri", i)
        for loop in tri:
            print(
                "loop", loop.index, 
                "face", loop.face.index,
                "edge", loop.edge.index,
                "vert", loop.vert.index, 
                "colour", loop[cl][:]
                )

Result on default plane, one vertex colour layer added, one subsurf modifier.

Evaluated bmesh object Plane mesh: Plane
faces 4 edges 12 verts 9 tris 8
Colour Layer Col
Tri 0
loop 0 face 0 edge 2 vert 0 colour (1.0, 1.0, 1.0, 1.0)
loop 1 face 0 edge 8 vert 5 colour (1.0, 1.0, 1.0, 1.0)
loop 2 face 0 edge 11 vert 8 colour (1.0, 1.0, 1.0, 1.0)
Tri 1
loop 0 face 0 edge 2 vert 0 colour (1.0, 1.0, 1.0, 1.0)
loop 2 face 0 edge 11 vert 8 colour (1.0, 1.0, 1.0, 1.0)
loop 3 face 0 edge 1 vert 4 colour (1.0, 1.0, 1.0, 1.0)
Tri 2
loop 4 face 1 edge 3 vert 5 colour (1.0, 1.0, 1.0, 1.0)
loop 5 face 1 edge 4 vert 1 colour (1.0, 1.0, 1.0, 1.0)
loop 6 face 1 edge 9 vert 6 colour (1.0, 1.0, 1.0, 1.0)
Tri 3
loop 4 face 1 edge 3 vert 5 colour (1.0, 1.0, 1.0, 1.0)
loop 6 face 1 edge 9 vert 6 colour (1.0, 1.0, 1.0, 1.0)
loop 7 face 1 edge 8 vert 8 colour (1.0, 1.0, 1.0, 1.0)
Tri 4
loop 8 face 2 edge 9 vert 8 colour (1.0, 1.0, 1.0, 1.0)
loop 9 face 2 edge 5 vert 6 colour (1.0, 1.0, 1.0, 1.0)
loop 10 face 2 edge 6 vert 3 colour (1.0, 1.0, 1.0, 1.0)
Tri 5
loop 8 face 2 edge 9 vert 8 colour (1.0, 1.0, 1.0, 1.0)
loop 10 face 2 edge 6 vert 3 colour (1.0, 1.0, 1.0, 1.0)
loop 11 face 2 edge 10 vert 7 colour (1.0, 1.0, 1.0, 1.0)
Tri 6
loop 12 face 3 edge 11 vert 4 colour (1.0, 1.0, 1.0, 1.0)
loop 13 face 3 edge 10 vert 8 colour (1.0, 1.0, 1.0, 1.0)
loop 14 face 3 edge 7 vert 7 colour (1.0, 1.0, 1.0, 1.0)
Tri 7
loop 12 face 3 edge 11 vert 4 colour (1.0, 1.0, 1.0, 1.0)
loop 14 face 3 edge 7 vert 7 colour (1.0, 1.0, 1.0, 1.0)
loop 15 face 3 edge 0 vert 2 colour (1.0, 1.0, 1.0, 1.0)

Applying per-vertex colors to new Bmesh

set a specified vertex color to black via python

$\endgroup$
5
$\begingroup$

Each loop (= corner of a poly) has its own vertex color. You can print the vertex color for each corner with

# Get the first Vertex Color layer; can also use its name (eg. "Col")
layer = bm.loops.layers.color[0]

for face in bm.faces:
    for loop in face.loops:
        color = loop[layer]  # gives a Vector((R, G, B, A))
        print(color)

Btw, if possible you should get the triangulation with calc_loop_triangles instead, since it gives you the triangulation that Blender actually draws.

$\endgroup$
3
  • $\begingroup$ About the calc_loop_triangles not sure what I should change, I'm very inexperienced in those script types. $\endgroup$
    – jms2505
    Feb 15 at 12:30
  • $\begingroup$ For a bmesh, bm.calc_loop_triangles gives a list of tuples of loops, one tuple per tri. So you'd do for tri in bm.calc_loop_triangles(): for loop in tri:. A regular mesh has calc_loop_triangles too, but it's slightly different. $\endgroup$
    – scurest
    Feb 15 at 12:34
  • $\begingroup$ Yeah I see, thanks! Will get it in mind. $\endgroup$
    – jms2505
    Feb 15 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.