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.

Example of the types of lines I'm trying to create.

  • 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 at 21:59
  • Related Avoid using operators where you can. – batFINGER Oct 11 at 7:33
up vote 3 down vote accepted

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:- enter image description here enter image description here

Here, for two planes and subdividing them: enter image description here

For three planes, so on: enter image description here

For different type of objects: enter image description here

  • 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 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]
    bpy.context.scene.objects.link(new_line)

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"
    bpy.context.scene.objects.link(new_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)

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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