Skip to content

Instantly share code, notes, and snippets.

@aobond2
Created July 31, 2023 14:46
Show Gist options
  • Save aobond2/e3eaaf4c63f4793ffe5cad5a2c72c09b to your computer and use it in GitHub Desktop.
Save aobond2/e3eaaf4c63f4793ffe5cad5a2c72c09b to your computer and use it in GitHub Desktop.
Vertex color to material blender
import bpy
def create_material(color_name, color):
# Create a new material with the given color
mat = bpy.data.materials.new(name=color_name)
mat.use_nodes = True
nodes = mat.node_tree.nodes
principled_bsdf = nodes.get("Principled BSDF")
if principled_bsdf is not None:
principled_bsdf.inputs["Base Color"].default_value = (color)
else:
diffuse_shader = nodes.get("Diffuse BSDF")
if diffuse_shader is not None:
diffuse_shader.inputs["Color"].default_value = (color)
return mat
# Get active object
obj = bpy.context.active_object
if obj is not None and obj.type == "MESH" and obj.data.vertex_colors:
vertex_colors = obj.data.vertex_colors.active.data
# Dictionary to store unique colors
unique_colors = {}
# Loop through each vertex
for loop_idx, loop in enumerate(obj.data.loops):
color = vertex_colors[loop_idx].color
# Round color vgalues
rounded_color = tuple(round(c, 3) for c in color)
# Add the color to the dictionary if it doesn't exist already
if rounded_color not in unique_colors:
unique_colors[rounded_color] = []
# Append the vertex index to the list associated with the color
unique_colors[rounded_color].append(loop.vertex_index)
# Create a material for each unique color
for idx, (color, vertex_indices) in enumerate(unique_colors.items()):
color_name = f"ColorMaterial_{idx}"
material = create_material(color_name, color)
# Assign the material to the selected vertices
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='OBJECT')
for vertex_index in vertex_indices:
obj.data.vertices[vertex_index].select = True
bpy.context.view_layer.objects.active = obj
bpy.ops.object.material_slot_add()
obj.data.materials[-1] = material
bpy.ops.object.mode_set(mode='OBJECT')
# Link the material to the corresponding faces
for poly in obj.data.polygons:
for loop_index in poly.loop_indices:
vertex_index = obj.data.loops[loop_index].vertex_index
if vertex_index in vertex_indices:
poly.material_index = len(obj.data.materials) - 1
break
bpy.ops.object.mode_set(mode='OBJECT')
bpy.context.view_layer.update()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment