I have also been trying to add lamp posts along a road path via blender scripting, and here's the solution I applied:
- Add a lamp post mesh which will become the parent of your light source (If your mesh consists of multiple parts, join them by 'Boolean Modifier > Union')
- Add array modifier (and curve modifier if your road path is a curve) to your lamp post object to copy it along the road, then apply the modifiers
- Apply 'Seperate > By Loose Parts' to your lamp post object to get multiple objects instead of one
- For every lamp post, add a light source and make the lamp post the parent of light source
You can see my approach in code down below:
bpy.ops.import_mesh.stl(filepath=os.path.join(os.path.dirname(bpy.data.filepath), "models/lamp.stl"))
lamp_ob = bpy.context.selected_objects[0]
bpy.data.collections["Lights"].objects.link(lamp_ob)
bpy.context.scene.collection.objects.unlink(lamp_ob)
if laneCount == 3:
lamp_ob.location = (0,4.2,0)
else:
lamp_ob.location = (0,3.2,0)
lamp_array_mod = lamp_ob.modifiers.new("LampArray", 'ARRAY')
lamp_array_mod.fit_type = "FIT_CURVE"
lamp_array_mod.curve = road_curve
lamp_array_mod.constant_offset_displace = (15,0,0)
lamp_array_mod.use_constant_offset = True
lamp_curve_mod = lamp_ob.modifiers.new("LampCurve", 'CURVE')
lamp_curve_mod.object = road_curve
for modifier in lamp_ob.modifiers:
bpy.ops.object.modifier_apply(modifier=modifier.name)
bpy.ops.mesh.separate(type='LOOSE')
bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_VOLUME')
for index, obj in enumerate(light_collection.all_objects):
bpy.ops.object.light_add(type='POINT', radius=2.0, location=(0,-0.25,1.25))
light_ob = bpy.context.selected_objects[0]
light_ob.name = "Light" + str(index)
light_ob.parent = obj
light_ob.data.energy = 500
light_ob.data.specular_factor = 10
This may not be the best scripting practice and there are some lines not related to the solution, so anyone can reach me out if any further explanation is needed :)
Footnote: I use .stl models since texture is not required for models in my case.