2
$\begingroup$

I started using blender and python a couple weeks ago, and have been doing okay with the documentation that is available on the internet. Now I ran into a problem though. I am trying use a hook as a way of animating a bar that is able to flex in different directions. In order to achieve this I am able to add a hook to either control point of the MidLine curve, but that only controls the location, and rotation in Y and Z-axis, so I have to add a driver to the tilt (rotation around the X-axis). Here you can see what I managed to achieve for one leaf spring without scripting, but now the leaf spring has to be animated from inputs that will be provided in a list. The leaf spring flexure with two hooks

So the problem is as follows: I have the hook, and control point, but how do I add a driver to the tilt attribute of this control point (see red arrow in the picture)? I want to add a driver to this attribute (indicated with red arrow) I was easily able to do it manually, but I can't seem to find the proper syntax for accessing this feature with python... Here is a picture of what I want the driver to look like for clarification:

Driver look

When I first do it manually, and then copy the following info window lines into my script it doesn't work:

bpy.context.object.data.id = bpy.data.objects["Control Point 1"]
bpy.context.object.data.transform_type = 'ROT_X'
bpy.context.object.data.rotation_mode = 'QUATERNION'

I also looked around a bunch online, but the documentation didn't make it clear enough for me. I feel the code below is as close as I got. I also included the rest of the code that gets you to the same blender workspace.

# IMPORT LIBRARIES
import bpy
import csv
from os import system

# CLEAR CONSOLE
cls = lambda: system('cls')
cls()

width = 1
thickness = 0.2

# START WITH INITIALIZING CROSS SECTION
CrossSection = bpy.data.curves.new('Cross Section Curve', type='CURVE')
CrossSection.dimensions = '3D'
CrossSection.resolution_u = 12

polyline = CrossSection.splines.new('POLY')
polyline.points.add(3)
polyline.points[0].co = (-width/2, thickness/2, 0, 1)
polyline.points[1].co = (-width/2, -thickness/2, 0, 1)
polyline.points[2].co = (width/2, -thickness/2, 0, 1)
polyline.points[3].co = (width/2, thickness/2, 0, 1)

# Create Object
curveOB = bpy.data.objects.new('Cross Section', CrossSection)

# Attach to scene
bpy.context.scene.collection.objects.link(curveOB)

# Select object and set it to cyclic
bpy.data.objects["Cross Section"].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects['Cross Section']
bpy.ops.object.editmode_toggle()
bpy.ops.curve.select_all(action='SELECT')
bpy.ops.curve.cyclic_toggle()
bpy.ops.object.editmode_toggle()
bpy.ops.object.select_all(action='DESELECT')


# INITIALIZE UNIT MIDLINE NEXT
MidLine = bpy.data.curves.new('MidLine Curve', type='CURVE')
MidLine.dimensions = '3D'
MidLine.resolution_u = 12

polyline = MidLine.splines.new('BEZIER')
polyline.bezier_points.add(1)
print(len(polyline.bezier_points))

polyline.bezier_points[0].handle_left = (-1, 0, 0)
polyline.bezier_points[0].handle_right = (1, 0, 0)
polyline.bezier_points[0].co = (0, 0, 0)

polyline.bezier_points[1].handle_left = (3-1, 0, 0)
polyline.bezier_points[1].handle_right = (3+1, 0, 0)
polyline.bezier_points[1].co = (3, 0, 0)

# Create Object
curveOB = bpy.data.objects.new('MidLine', MidLine)

# Attach to scene and validate context
bpy.context.scene.collection.objects.link(curveOB)

# Select object and assign the cross section bevel
bpy.data.objects["MidLine"].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects['MidLine']
bpy.ops.object.editmode_toggle()
bpy.ops.curve.select_all(action='SELECT')
bpy.context.object.data.bevel_mode = 'OBJECT'
bpy.context.object.data.bevel_object = bpy.data.objects["Cross Section"]
bpy.context.object.data.splines[0].use_smooth = False
bpy.context.object.data.use_fill_caps = True
bpy.ops.curve.select_all(action='DESELECT')
#bpy.ops.object.editmode_toggle()
#bpy.ops.object.select_all(action='DESELECT')

# CREATE THE HOOKS AND LINK THEM TO THE CONTROL POINTS
# Control point 1
bpy.context.active_object.data.splines[0].bezier_points[0].select_control_point = True
bpy.ops.object.hook_add_newob()
bpy.data.objects['Empty'].name = "Control Point 1"
bpy.data.curves['MidLine Curve'].splines[0].bezier_points[0].driver_add('ROT_X')
#The following were attempts that also don't work:
#bpy.context.object.driver_add("ROT_X", 2)
#bpy.context.object.data.id = bpy.data.objects["Control Point 1"]

Hopefully someone is able to clarify how to use these drivers with bpy. It is probably a lot easier for adding drivers to simple cubes, but this niche part of blender is quite ... well niche :P. I feel the documentation could be much easier to understand if some examples of how to use the syntax were included, by the way. I think the bpy_struct (bpy_struct), also could be of use, but I just don't understand how. Furthermore, for reference, here is a link to the question where I learned of the trick to add a driver to use a hook to control a bezier point.

Thanks in advance!

Ruben

$\endgroup$
3
  • 3
    $\begingroup$ If you manually add the driver via UI, can use the python console to see the driver settings, and then code them. There are numerous answers re adding drivers via python. Might find the second example useful, blender.stackexchange.com/questions/183694/… adds a driver to face index color using distance from empty. In this case its bezier control point tilt. Will get back with an answer if someone doesn't beat me to it. $\endgroup$ – batFINGER May 26 at 18:19
  • $\begingroup$ Thanks for the response! I tried copying the info-window output after adding the driver myself via the normal UI, but that did not work unfortunately. I took a look at the link you gave me, and that indeed seems very helpful for what I need. The only problem is that I have a hard time understanding and thus also rewriting their code to suit my tilting needs. The specific syntax needed to add a driver to the tilt attribute of a bezier point is still not clear to me. I look forward to your answer! $\endgroup$ – Rublie14 May 28 at 9:12
  • $\begingroup$ @batFINGER I'm sorry, I don't mean to rush you, but I was wondering if you have had some time to look into my question. I would be really grateful for some help! Thanks in advance again. $\endgroup$ – Rublie14 May 31 at 12:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.