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$
  • $\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 Dec 31 '13 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 Dec 31 '13 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 Dec 31 '13 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 Dec 31 '13 at 1:12
4
$\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$

Your Answer

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

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