# Automate many emissive primitives using Python in Blender 2.93

Background: Hello, I'm a researcher looking into the supply chain. A few years ago I was creating a static visualisation of vessels across the globe. I discovered Blender and using several tutorials was able to create a realistic map and using Python place glowing/emissive rods on the map. However, I needed more data and therefore left the project till now.

However, in that time things have changed in Blender and my script no longer work (not even on old versions).

Task: I'd like to run a For Loop, which parses through a preprepared csv file (I have this) and then creates a rod at many specific locations and then later applies colour and emissive properties to that particular rod (not necessarily in that order).

Current situation: When this was working, I was able to perform tasks in Blender (manually) and then copy the Python code for those steps from the console (this is still the case, but it's not working for me). As I recall, I had to add a step by giving each rod a "name", so that it could be assigned a material property (emissiveness and colour).

My old code (for the previous Blender version) looked like this:

import bpy, csv, random, os
fp = _file_path1_
cp = _file_path2_

with open( cp ) as csvfile:
for i, row in enumerate( rdr):
if i == 0: continue # Skip column title
material = bpy.data.materials.new(name=str(row[0]))
material.use_nodes = True
material.node_tree.nodes.remove(material.node_tree.nodes.get('Diffuse BSDF'))
material_output = material.node_tree.nodes.get('Material Output')
emission.inputs['Strength'].default_value = 15.0
emission.inputs['Color'].default_value = (float(row[1]), float(row[2]), float(row[3]), float(1.0))

rands_list = random.sample(range(35000), 2000)

with open( fp ) as csvfile:
for i, row in enumerate( rdr ):
# if i >= 30000 and i < 30050:
if i in rands_list:
vertices=5,
location = (float(row[1]), float(row[2]), float(0.045)),
depth = 0.01
)
bpy.context.object.active_material = bpy.data.materials[str(row[0])]


I'm a bit discouraged now. So would really appreciate help with this task.

• Hello, could you elaborate on what exactly is the error when running the script ? You can see it by going window > toggle system console Jun 24 '21 at 8:50
• can you provide a small csv file, so we can check it out? Jun 24 '21 at 11:11
• Consider adding print statements as a debug option. A quick look at this shows a 2000 integers chosen randomly from 0..34999 and relies on a number in range of length of input file to be in it. Could be the script is adding materials and materials on each run but never a cylinder. Jun 24 '21 at 15:33

This codes now worked on my computer, but since you didn't provide your csv ...i had to make my own. Of course the csv must also be correct so that the code works. I wrote in comments after the code where i had to change things.

import bpy, csv, random, os

fp = # must be right path here
cp = # must be right path here

with open( cp ) as csvfile:
for i, row in enumerate( rdr):
#        if i == 0: continue # Skip column title -> i had no title...
material = bpy.data.materials.new(name=str(row[0]))
print ("new material:", material.name)
material.use_nodes = True
material.node_tree.nodes.remove(material.node_tree.nodes.get('Principled BSDF')) # changed to Principled -> this is not necessary because if you create an object via python it has no default material -> looks like this is left "garbage" from older code...
material_output = material.node_tree.nodes.get('Material Output')
emission.inputs['Strength'].default_value = 15.0
emission.inputs['Color'].default_value = (float(row[1]), float(row[2]), float(row[3]), float(1.0))

rands_list = random.sample(range(35000), 2000)

with open( fp ) as csvfile:
print("fp case", "*"*100)
for i, row in enumerate( rdr ):
print (i, row, "#"*30)
# if i >= 30000 and i < 30050:
#     if i in rands_list: # commented this out because sometimes this code wasn't called at all here ...
vertices=5,
radius= 20, # change, so that i "saw" something
location = (float(row[1]), float(row[2]), float(0.045)),
depth = 0.01
)
print("cylinder created")
bpy.context.object.active_material = bpy.data.materials[str(row[0])]



result with "my" csv data:

but honestly: if you don't provide csv next time...i will downvote your question....

• Appologies for not including a csv file. Jun 28 '21 at 13:55
• It's ok. Just make it better next time, then i am happy! ;) Jun 28 '21 at 13:56