Adding material to spheres sequentially using Python I have the following script, which I was hoping would add a basic red material to my spheres as they are sequentially created. Unfortunately, the script does not work, in the sense that no material is added to any sphere. Indeed, no spheres are created, but in the absence of "bpy.ops.material.new()" and "bpy.context.object.active_material.diffuse_color = (1, 0, 0)", the script produces spheres. 

Could someone please help me tweak the script to make it function as desired?  

import bpy, csv
fp = "C:/Blender/Spheres.csv"
with open( fp ) as csvfile:
    rdr = csv.reader(csvfile, delimiter=';')
    for i, row in enumerate( rdr ):
        if i == 0: continue # Skip column title
        # Generate UV sphere at x = row0, y = row1, z = row2, and radius = row3.
        bpy.ops.mesh.primitive_uv_sphere_add(size = float(row[3]), location = float(row[0]),float(row[1]),float(row[2])))
        bpy.ops.material.new()
        bpy.context.object.active_material.diffuse_color = (1, 0, 0) 


A snippet of my CSV. spheres.csv

x;y;z;r
2.34;2.45;7.65;0.024
6.78;9.31;6.33;0.0467
3.36;8;1.04;0.3626
Since each sphere's material gets the same properties, I think it's a shame to create a new material for each sphere. Here's my solution, which:


Doesn't use an operator to create a new material, but rather calls a regular function bpy.data.materials.new(). This is faster, doesn't create unnecessary undo steps, and directly returns the material;
Uses next(rdr) to skip the first row, rather than using enumerate and checking the index each and every iteration;
Uses bpy.path.abspath to convert a blendfile-relative path to an absolute path that Python understands;
Separates data conversion from the strings obtained by the CSV reader to the floats you need for Blender;
Uses slice notation to shorten the b.o.m.primitive_uv_sphere_add call;
Follows PEP-8 for readability.




import csv

import bpy

# Create the material
try:
    mat = bpy.data.materials['Sphere']
except KeyError:
    mat = bpy.data.materials.new('Sphere')
mat.diffuse_color = (1, 0, 0)

fp = "//spheres.csv"
with open(bpy.path.abspath(fp)) as csvfile:
    rdr = csv.reader(csvfile, delimiter=';')
    next(rdr)  # Skip column title
    for row in rdr:
        # Generate UV sphere at x = row0, y = row1, z = row2, and radius = row3.
        data = [float(x) for x in row]    
        bpy.ops.mesh.primitive_uv_sphere_add(location=data[0:3], size=data[3])
        bpy.ops.object.material_slot_add()
        bpy.context.object.material_slots[0].material = mat