I'm trying to color the vertices of an object. I have list of values like this: values_list = [0.1, 0.5, 0.2, 0.4, etc...]
which means the vertex with index 0 has a value of 0.1, the vertex with index 1 has a value of 0.5 and so on. This value is the intensity of the color red. I'm using this code to get the work done but as you can see the result is kinda "pixelated". What's wrong with my code?
Short Code:
import bpy
# Obviosuly there should be some other numbers but for shortness I dont fully write vertices and faces
verts = [0,1,2,3,4 ...]
faces = [(0,1,2),(2,1,4), ...]
# Creating mesh
mesh = bpy.data.meshes.new("New mesh")
obj = bpy.data.objects.new("My object",mesh)
col = bpy.data.collections.get("Collection")
col.objects.link(obj)
bpy.context.view_layer.objects.active = obj
mesh.from_pydata(verts, [], faces)
# For shortness again I don't write every number
values_list = [0.1, 0.5, 0.2, 0.4 ...]
if not obj.data.vertex_colors:
obj.data.vertex_colors.new()
color_layer = obj.data.vertex_colors.active
i = 0
for poly in mesh.polygons:
for idx in poly.loop_indices:
loop = mesh.loops[idx]
color_layer.data[i].color = (values_list[loop.vertex_index], 0, 0, 1)
i += 1
# setting to vertex paint mode to see the result
bpy.ops.object.mode_set(mode='VERTEX_PAINT')
Full code
import bpy
import vtkmodules.all as vtk
# The source file
file_name = "time_solution_stress_004.0.vtu"
# Read the source file.
reader = vtk.vtkXMLUnstructuredGridReader()
reader.SetFileName(file_name)
reader.Update()
output = reader.GetOutput()
points = output.GetPoints()
vms = output.GetPointData().GetArray("Von_Mises_stress") # get the array containing the von mises stress value for every vertex
# get vertices
verts = []
if points:
for x in range(points.GetNumberOfPoints()):
vertex=[0,0,0]
points.GetPoint(x,vertex) # fill the vertex variable
verts.append(vertex)
# get faces
faces = []
for i in range(output.GetNumberOfCells()):
cell = output.GetCell(i)
cell_points_ids = []
for face_index in range(cell.GetNumberOfFaces()):
idlist=[]
for id_index in range( cell.GetFace(face_index).GetNumberOfPoints() ): #4
idlist.append( cell.GetFace(face_index).GetPointIds().GetId(id_index) )
faces.append(idlist)
mesh = bpy.data.meshes.new("New mesh")
obj = bpy.data.objects.new("Cube",mesh)
col = bpy.data.collections.get("Collection")
col.objects.link(obj)
bpy.context.view_layer.objects.active = obj
mesh.from_pydata(verts, [], faces)
# Creation of a list where the element with index i is the von mises stress value of the i vertex
# This value isn't the original but it's converted in 0 to 1 range (so i can use it as the intensity of the color red)
red_intensity_list = []
vms_min, vms_max = vms.GetRange()
input_start, input_end, output_start, output_end = vms_min, vms_max, 0, 1
slope = (output_end - output_start) / (input_end - input_start)
for i in range(vms.GetNumberOfTuples()):
vms_value = vms.GetTuple1(i)
zero_to_1_output = output_start + slope * (vms_value - input_start)
red_intensity_list.append(zero_to_1_output)
if not obj.data.vertex_colors:
obj.data.vertex_colors.new()
color_layer = obj.data.vertex_colors.active
i = 0
for poly in mesh.polygons:
for idx in poly.loop_indices:
loop = mesh.loops[idx]
color_layer.data[i].color = (red_intensity_list[loop.vertex_index], 0, 0, 1)
i += 1
# setting to vertex paint mode to see the result
bpy.ops.object.mode_set(mode='VERTEX_PAINT')