I'm trying to write a script to create some objects along and around a curve object, set up for a generative modeling thing, to make randomized "tentacles" out of paths.
Anyways! I'm approaching this by creating an empty at the root of any selected curve, putting a "follow path" constraint on the empty, targeting the curve, animating the path, and then creating objects relative to the empty's location and orientation on different frames, staggering some objects like that.
What I've got so far looks like this:
for curve in operable:
print("Doing curve")
rootLoc = curve.data.splines[0].points[0].co
emptyLoc = (curve.matrix_world * rootLoc)
bpy.ops.object.empty_add(type='ARROWS')
bpy.context.object.name = "empty_" + curve.name
bpy.ops.object.constraint_add(type='FOLLOW_PATH')
bpy.context.object.constraints['Follow Path'].target = curve
old_area = bpy.context.area.type
bpy.context.area.type = 'PROPERTIES'
bpy.context.space_data.context = 'CONSTRAINT'
bpy.ops.constraint.followpath_path_animate(constraint='Follow Path', length=frame_steps)
bpy.context.object.constraints['Follow Path'].use_curve_follow = True
bpy.context.area.type = old_area
bpy.data.objects['empty_' + curve.name].location = emptyLoc.xyz
However, in the "followpath_path_animate" line, I get an error from that function's "poll()" saying only that "the context is incorrect".
For one, if someone could tell me what context I need to be in and how to get there, that would be great.
It would also be great if someone could explain to me how in the world I'm supposed to figure out what context to be in to run these functions! You'd think this would be at least vaguely documented...
I found the code related to this function in the source code, found that this is the poll() function used:
static int edit_constraint_poll_generic(bContext *C, StructRNA *rna_type)
{
PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", rna_type);
Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C);
if (!ptr.data) {
CTX_wm_operator_poll_msg_set(C, "Context missing 'constraint'");
return 0;
}
if (!ob) {
CTX_wm_operator_poll_msg_set(C, "Context missing active object");
return 0;
}
if (ob->id.lib || (ptr.id.data && ((ID *)ptr.id.data)->lib)) {
CTX_wm_operator_poll_msg_set(C, "Cannot edit library data");
return 0;
}
return 1;
}
This is pretty cryptic to me, seems to check whether the active context is of type "constraint", but I thought I'd done that. Not sure how to resolve that.