1
$\begingroup$
bpy.ops.object.lamp_add(type='POINT', radius=1, view_align=False, location=(1,1,1), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
new_name = bpy.context.active_object.name
bpy.data.lamps[new_name].use_nodes = True
bpy.data.lamps[new_name].node_tree.nodes["Emission"].inputs['Strength'].default_value = 3.0

I am trying to create a series of point source lamps (100s of them) using a script and then change the emission strength of each of them to a custom value - a different value for each light.

Most of the time the above code works. However, every now and again there seems to be a mismatch between the name of the object and some underlying object that it is linked to - see screenshot for example.

In this case my newly created object is called "Point.001", whereas it is linked to some object called "Point.038". Changing the node values for "Point.001" does nothing (as far as I can tell), I need to change the values for "Point.038". The issue is that I cannot figure out how to access the name "Point.038" via Python script. I assume since "Point.038" and "Point.001" are linked in the outliner, there has to be some way to traverse from "Point.001" to "Point.038".

An added wrinkle here is that each point source has a emission custom value, so I can't just cycle through every point light source object and change the value - I need to know that "Point.038" gets the emission that should be assigned "Point.001".

enter image description here

$\endgroup$
1
$\begingroup$

Use the object reference.

When adding an object via an operator, the new object is context.object. The data part, the lamp in this case is context.object.data

import bpy
context = bpy.context 
bpy.ops.object.lamp_add(type='POINT', radius=1, location=(1,1,1))
lamp_obj = context.object
lamp = lamp_obj.data
lamp.use_nodes = True

Ultimately if you are going to be adding hundreds of lamps with code suggest using API methods rather than operators which become slow. Python performance with Blender operators

Test code below written and tested in 2.8. See comments for conversion to prior.

import bpy
context = bpy.context
scene = context.scene
nlamps = 10

for i in range(nlamps):
    lamp = bpy.data.lights.new("Spot%d" % i, type='SPOT') # 2.8
    #lamp = bpy.data.lamps.new("Spot%d" % i, type='SPOT') # prior
    lamp_obj = bpy.data.objects.new("Spot%d" % i, lamp)
    lamp_obj.location.x = i
    scene.collection.objects.link(lamp_obj) # 2.8
    #scene.objects.link(lamp_obj) # prior 2.8
$\endgroup$
  • $\begingroup$ Thank you! This was exactly what I was looking for. Just a slight clarification for anyone who stumbles on this thread, the second line should be: "lamp_obj = bpy.context.object" $\endgroup$ – Ian Vera Feb 13 at 0:41
  • $\begingroup$ Yeah did leave out import and context define. IMO get out of the habit of using bpy.context... I use context = bpy.context in test code, which later if pasted into operator or panel code matches the context argument of the method. Using bpy.context in operators instead of the passed argument completely naffs up overriding context. $\endgroup$ – batFINGER Feb 13 at 0:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.