# How to use Python script to generate many lines in Blender and then animate line color and thickness?

I'm very new to Blender and to writing Python scripts for Blender. For the project I'm working on, I'd like to be able to create 10,000+ straight lines (see image below) and animate them so that their colors and thicknesses change (individually) over the course of the animation.

What is the most efficient way to create the lines using a python script? My understanding is that I can't use simple edges because they don't have any thickness.

I tried making the lines as Bezier Curves, however, the script couldn't run in a reasonable amount of time once there were over several thousand lines/curves.

Any help on how to create a large number of lines like this would be very much appreciated.

• Just an idea I can't verify now, but you can first make edges and then convert them to bezier curves. Making the edges can be done by calculating the coords with numpy and generating actual mesh data with from_pydata blender.stackexchange.com/questions/23086/… . As for getting the bezier curve, Alt-C should provide you the fit function. – Allosteric Oct 10 '18 at 21:59
• Related Avoid using operators where you can. – batFINGER Oct 11 '18 at 7:33

You can do this easily with Animation Nodes.

For connections we need initial locations and final locations, So I'm using planes i.e vertices location but you can choose anything (Sphere/Cube mesh, number of objects etc). Now, to connect each vertices a plane (say A) to all vertices of a plane (say B), I have made two "Subprogram Loop" Nodes which basically make individual sets of vector lists. Then using using "Spline from points" node make the connections from those vector lists. In the "Curve Object Output" node, you can animate any parameter (Bevel depth, Bevel Start, Bevel End etc) of a curve.

Here is, examples with two, three planes and with a icosphere, but you can add any number planes (or other mesh object). To make more complex and control connections, you can also use other nodes like "KD Tree" and "BVH Tree" which are available in Animation Nodes.

:)

Here is Node Tree:-

Here, for two planes and subdividing them:

For three planes, so on:

For different type of objects:

• Thanks! After scanning the documentation for the Animations Node add-on, it looks like this is going to be exactly what I need both in terms of creating the lines and animating them. – bsyzek Oct 11 '18 at 16:30

I don't know if this is possible with 10.000+ lines but I'd try this:

Make a "template line" with only two points. (I added a Path and removed all but the endpoints). Make a profile curve, i.g. a circle.

Apply the circle as the line's bevel object.

Then run the script.

import bpy

# line with only 2 points
original_line = bpy.data.objects["NurbsPath"]
# profile curve for "pipe" (circle, triangle, etc.)
original_profile = bpy.data.objects["BezierCircle"]

startpoints = [[9.47, -0.64, -3.65], [9.75, -6.49, -9.01], [1.06, 8.28, -1.46], [0.17, -5.79,1.02], [-2.44, -8.83, -7.47]]
endpoints = [[6.92, -1.32, 9.88], [8.86, -4.57, -7.88], [0.89, -3.18, -4.54], [5.69, 1.37, -9.0], [-4.58, -1.05, -4.58]]

for s,e in zip(startpoints, endpoints):
new_line = original_line.copy()
new_line.data = original_line.data.copy()
new_line.name = "Line" # + automatically added number
# set the start- and endpoint
new_line.data.splines[0].points[0].co = s + [1.0] #add nurbs weight
new_line.data.splines[0].points[1].co = e + [1.0]


If you run this all the generated lines will have the same profile curve (original_profile). If you change the original profile curve (i.g. scale it) they all will change. You can give each one their individual profile curve if you add this to the for loop:

    new_profile = original_profile.copy()
new_profile.data = original_profile.data.copy()
new_profile.name = new_line.name + "_profile"
new_line.data.bevel_object = new_profile


You can get all the profiles from i.g. a bunch of curves you have selected like this:

profiles_of_selected = []
for line in bpy.context.selected_objects:
# make sure it's a line, else skip
if not line.name.startswith("Line"): continue
individual_profile = line.data.bevel_object
profiles_of_selected.append(individual_profile)


And select these profile curves (for example to scale them in the 3d-view):

# deselect all
for obj in bpy.context.selected_objects:
obj.select = False
# select all profiles
for obj in profiles_of_selected:
obj.select = True


Or i.g. set their scale via code:

for obj in profiles_of_selected:
obj.scale = (3, 3, 3)