# Assigning Array and Curve for a large number of curves

I have a very large number of curves (OpenStreetMap data imported as curves) on which I wish to array objects (streetlights). Since there are thousands of curve objects, duplicating my streetlight object and then manually adding an array and curve modifier and point them to the right curve is a slow if not impossible process when there is this many curve objects.

The best solution I can think of is a script, however I am not familiar with the process. I've only gone as far as making the script add an array modifier.

Here is my script so far

import bpy

bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":False, "mode":'TRANSLATION'}, TRANSFORM_OT_translate={"value":(-0, 0, 0), "orient_type":'GLOBAL', "orient_matrix":((1, 0, 0), (0, 1, 0), (0, 0, 1)), "orient_matrix_type":'GLOBAL', "constraint_axis":(False, False, False), "mirror":True, "use_proportional_edit":False, "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "use_proportional_connected":False, "use_proportional_projected":False, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "cursor_transform":False, "texture_space":False, "remove_on_cancel":False, "release_confirm":False, "use_accurate":False})
bpy.context.object.modifiers["Array"].fit_type = 'FIT_CURVE'
bpy.context.object.modifiers["Array"].relative_offset_displace[0] = 50


I basically need a way to make that last 0 increment every time I run the script

Sample Blend file:

Any help is appreciated.

• Could you add some information about the curves and the object to be dupli? Eventually, a simple blend file with sample of them that you could upload here using blend-exchange.giantcowfilms.com – lemon Aug 15 at 11:05
• There's nothing special I'd say about the objects and curves, I have included the blend file now. – John 514 Aug 15 at 11:44

This script can do the job I think:

Basically, it will loop over the collection where the roads are,

then copy the base lamp, put it at the current road location and create the two needed modifiers (array and curve).

the copies are placed in a separate collection.

The script is commented below:

import bpy
import bmesh

# get an existing collection or create it if it does not exist
# if created, the collection is added to the scene main collection
def get_or_create_collection( scene, collection_name ):
collection = bpy.data.collections.get( collection_name )
if collection is None:
collection = bpy.data.collections.new( collection_name )
return collection

# duplicate an object and link it to a collection
# copy_data allow to know if the objects will share their data or not (are dupli or not)
def duplicate( obj, collection, copy_data ):
new_obj = obj.copy()
if copy_data:
new_obj.data = obj.data.copy()
return new_obj

# get the scene
scene = bpy.context.scene

# get the base lamp
base_lamp = bpy.data.objects["Lamp_LowPoly"]

# names of the collections
lamps_collection_name = "created_lamps"

# get the source collection

if road_collection is None or base_lamp is None:
print( "will not work" )
else:
# get the destination collection
lamps_collection = get_or_create_collection( scene, lamps_collection_name )

for road in [r for r in road_collection.objects if r.type == 'CURVE']:
# Duplicate the base lamp (True => not linked)
lamp = duplicate( base_lamp, lamps_collection, True )
# Set the lamp at the road location so that curve can work
array_modifier = lamp.modifiers.new( "array", 'ARRAY' )
array_modifier.fit_type = 'FIT_CURVE'
array_modifier.relative_offset_displace[0] = 50