I made a script that duplicates objects along a curve, but why it is slow?

<a href=“http://www.youtube.com/watch?v=WGF-E7XSrbM” target="_blank">
https://youtu.be/WGF-E7XSrbM

The advantage of using this script in place of modifiers is:

  • Do not deform the object;
  • Acts in lamps;
  • Rotates each object in the direction of the curve (under review).

However (as seen in the video) why it is slow?
There is a better way of doing it?

Code:

import bpyimport mathutils
from mathutils import Vector


dist = 35.0 # Distance between duplicate objects


# Referencing the selected object
curvob = bpy.context.active_object
curve = bpy.context.active_object.data




for c in range(0,len(bpy.context.object.data.splines)): # For each spline on the curve
    
    dx = 0.0 # Length of initial calculation of section
    
    for e in range(0,len(bpy.context.object.data.splines[c].bezier_points)): # For each point on the spline
        
        vetorx = bpy.context.object.data.splines[c].bezier_points[e].co-bpy.context.object.data.splines[c].bezier_points[e-1].co # Vector spline section
        dx += vetorx.length # Defined length calculation equal total length of the spline section
        #theta = mathutils.Vector.angle(mathutils.Vector.to_2d(vetorx), ((1.0, 0.0))) # Angle section
        
        while dx &gt; dist: # While calculating the total length of the section is larger than the set distance proceed:
            
            x = dx - dist # Calculating the remaining length of the section
            
            bpy.context.active_object.select = False # Unselected curve
            bpy.context.scene.objects.active = bpy.context.selected_objects[0] # Enabling the penultimate selected object
            bpy.ops.object.duplicate(linked=True) # Duplicating selected objects
            bpy.context.object.location = curve.splines[c].bezier_points[e].co - (vetorx/vetorx.length)*x # Putting in the correct position
            #bpy.context.object.rotation_euler[2]=theta # Rotating the selected objects
            bpy.context.scene.objects.active = curvob # Reactivating the curve
            
            dx = x # Defining the new length calculation remainder of the section

because you use the duplicate operator:
bpy.ops.object.duplicate(linked=True) # Duplicating selected objects

Need Help Optimizing A Script To Make It Less Time Consuming
Duplicate Linked Object

Thanks @CoDEmanX, good to know where the problem is :). The hard part is knowing how to fix this.

I managed to greatly accelerate the execution of the script. For a while I was satisfied but:

  • It just copies the penultimate selected object.
    If anyone has any idea how to fix this problem, it would be helpful.
    No similar addon exists, and I’ve needed this function for:
  • Lampposts, curbs, fences.
    And it would also be useful for:
  • Grilles, railings, books on shelving curves, pergolas, and every architectural rhythm without distortion.

New Code:

import bpyimport mathutils
from mathutils import Vector


dist = 35.0 # Distance between duplicate objects
curve = bpy.context.active_object.data # Referencing the selected object
qt = 0 #(To see in System Console)
bpy.context.active_object.select = False # Unselect curve
bpy.context.scene.objects.active = bpy.context.selected_objects[0] # Activing the penultimate selected object


for c in range(0,len(curve.splines)): # For each spline on the curve


    dx = 0.0 # Length of initial calculation of section


    for e in range(0,len(curve.splines[c].bezier_points)): # For each point on the spline


        vetorx = curve.splines[c].bezier_points[e].co-curve.splines[c].bezier_points[e-1].co # Vector spline section
        dx += vetorx.length # Defined length calculation equal total length of the spline section


        while dx &gt; dist: # While calculating the total length of the section is larger than the set distance proceed:
            
            x = dx - dist # Calculating the remaining length of the section
            
            obj = bpy.context.scene.objects.active.copy()
            bpy.context.scene.objects.link(obj)
            obj.location = curve.splines[c].bezier_points[e].co - (vetorx/vetorx.length)*x # Putting in the correct position
            obj.rotation_quaternion = mathutils.Vector.to_track_quat(vetorx, 'X', 'Z') # Tracking the selected objects
            
            dx = x # Defining the new length calculation remainder of the section
            qt+=1
            print('duplicate', qt)

Example of what I want (in Blender):