1
$\begingroup$

For the record I'm asking this question because it was brought up by a member recently and deleted under my eyes while I was clicking on the submit answer button, but I think it was a worthy question and I'll share my answer.

The premise was :

I have an object with materials assigned to its material slots. The materials are assigned to the object's polygons. Each material has a simple node tree with a single principled BSDF node with a specific base color.

I want to create a new color attribute on the object's mesh which will assign each polygon with its corresponding material color.

$\endgroup$
2
  • $\begingroup$ " it was brought up by a member recently and deleted under my eyes" - I can relate, happened to me in the past… Duarte said to ping a mod in such a case. The question mentioned is this - I myself decided not to answer it because of seemingly low effort of OP (I always wonder if someone uses AI for the script, does he also use it to word out the question...) $\endgroup$ Sep 22, 2023 at 18:20
  • $\begingroup$ Thank you @MarkusvonBroady I didn't know this was the procedure, it makes sense. About the AI generated part, the body of the question was clear enough for me to understand the goal, and the script albeit flawed confirmed my assumptions, so in this case I didn't mind. I also recently used the attribute API for another project so I thought why not. Honestly I'm not so much worried about AI content inside the questions so long as it is understandable. What should be forbidden IMO is raw AI content in the answers. Cheers ! $\endgroup$
    – Gorgious
    Sep 22, 2023 at 19:08

1 Answer 1

2
$\begingroup$

Here's an example script. I'll assume you use V3.6+

  1. Create a new color attribute
  2. Iterate over all materials and fetch their color
  3. Iterate over all polygons and fill out the correct colors into the polygon corners.

Note non-assigned materials or materials with no principled bsdf node will have a black color.

You should be interested in reading bpy.types.Mesh, bpy.types.MeshPolygon, bpy.types.AttributeGroup and bpy.types.Attribute.

enter image description here

import bpy


def main():
    obj = bpy.data.objects.get("House")
    if obj is None or obj.type != "MESH":
        return

    mesh = obj.data   
    color_attribute = mesh.color_attributes.get("Color")
    if not color_attribute:
        color_attribute = mesh.color_attributes.new("Color", "FLOAT_COLOR", "CORNER")

    materials_colors = []
    for material_slot in obj.material_slots:
        material = material_slot.material
        if material is None:
            materials_colors.append((0, 0, 0, 0))
            continue
        principled = next((n for n in material.node_tree.nodes if n.type == "BSDF_PRINCIPLED"), None)
        if principled is None:
            materials_colors.append((0, 0, 0, 0))
            continue
        materials_colors.append(principled.inputs["Base Color"].default_value[:])

    for polygon in mesh.polygons:
        for corner_index in polygon.loop_indices:
            color_attribute.data[corner_index].color = materials_colors[polygon.material_index]


if __name__ == "__main__":
    main()
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .