5
$\begingroup$

I want to use timeline markers for driver expression, is it possible? And is it need to be added to bpy.app.driver_namespace for quick driver add like #frame? If yes, then how?

Thanks

$\endgroup$
4
  • $\begingroup$ May I ask, what effect do you want to achieve? There'll be a bit more work, because the driver expression have to choose which marker to use. $\endgroup$
    – Adhi
    Commented Dec 31, 2013 at 0:53
  • $\begingroup$ I want to integrate the functionality with batch render add-on. So defining end frame value for each batch only use drivers $\endgroup$
    – aditia
    Commented Dec 31, 2013 at 1:03
  • $\begingroup$ is it possible like this, e.g: for the first marker will be #marker and for the next will be #marker.001 and soon. This behavior consistent in blender, right? $\endgroup$
    – aditia
    Commented Dec 31, 2013 at 1:08
  • $\begingroup$ It is possible. That way, the end marker for each render batch will be the start marker for the next one. $\endgroup$
    – Adhi
    Commented Dec 31, 2013 at 1:12

1 Answer 1

5
$\begingroup$

It is possible to use marker for rendering frame ranges, but not through driver, which is normally used to trigger value change based on Scene.frame_current. What you need instead, is property manipulation based on TimeLineMarker.frame.

The only thing you need to do is iterating over Scene.timeline_markers, because manipulation of Scene.frame_start and Scene.frame_end for each render batch is already taken care of by the addon. Get the list of frame ranges used by the addon, which is Scene.batch_render.frame_ranges, and insert positions of the pair of markers into it. It is this last step that wouldn't be made simpler by a driver.

Below's an operator for you to edit and use. It converts each pair of markers named start and end directly into frame ranges:

class OBJECT_OT_MarkerToFrameRanges(bpy.types.Operator):
    bl_idname = "batch_render.marker_to_frame_ranges"
    bl_label = "Marker To Frame Ranges"

    def execute(self, context):
        batcher = context.scene.batch_render
        marker_list = sorted(context.scene.timeline_markers,
                             key=lambda x: x.frame)
        marker_frame_ranges = []

        for marker in marker_list:
            if marker.name == 'start':
                marker_frame_ranges.append({'start': marker.frame})
            elif marker.name == 'end':
                range_dict = marker_frame_ranges[-1] if marker_frame_ranges\
                    else {}                
                range_dict['end'] = marker.frame

        for index, range_dict in enumerate(marker_frame_ranges):
            marker_start = range_dict.get('start', 0)
            marker_end = range_dict.get('end', context.scene.frame_end)

            if index >= len(batcher.frame_ranges):
                bpy.ops.batch_render.add_new()

            batcher.frame_ranges[index].start_frame = marker_start
            batcher.frame_ranges[index].end_frame = marker_end

        return {'FINISHED'}

EDIT: To strictly answer your question: Yes, it is possible to use timeline marker for driver expression. The function below will return True only if there's a marker at the current frame:

def any_marker_at_frame():
    frame_current = bpy.context.scene.frame_current
    markers = bpy.context.scene.timeline_markers

    for m in markers:
        if m.frame == frame_current:
            return True
    return False

bpy.app.driver_namespace['any_marker_at_frame'] = any_marker_at_frame

You can then use any_marker_at_frame() in your scripted expression.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .