initial commit of sequencer_jumptocut
authorCarlos Padial <palidoestudio2@gmail.com>
Wed, 3 Oct 2012 12:37:21 +0000 (12:37 +0000)
committerCarlos Padial <palidoestudio2@gmail.com>
Wed, 3 Oct 2012 12:37:21 +0000 (12:37 +0000)
sequencer_jumptocut.py [new file with mode: 0644]

diff --git a/sequencer_jumptocut.py b/sequencer_jumptocut.py
new file mode 100644 (file)
index 0000000..f51bfde
--- /dev/null
@@ -0,0 +1,439 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+
+bl_info = {
+    "name": "Jump to Cut",
+    "author": "Carlos Padial",
+    "version": (5,0,2),
+    "blender": (2, 6, 3, 0),
+    "api": 44539,
+    "category": "Sequencer",
+    "location": "Sequencer > UI > Jump to Cut",
+    "description": "Tool collection to help speed up editting and grade videos with blender",
+    "warning": "",
+    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Sequencer/Jump_to_cut",
+    "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=24279",}
+
+#
+# 
+#
+#-----------------------------------------------------------------------------------------------------
+import bpy
+
+class Jumptocut(bpy.types.Panel):
+    bl_space_type = "SEQUENCE_EDITOR"
+    bl_region_type = "UI"
+    bl_label = "Jump to Cut"  
+
+    def draw_header(self, context):
+        layout = self.layout
+        layout.label(text="", icon="NLA")
+    
+    def draw(self, context):
+        layout = self.layout
+       
+        row=layout.row()
+        split=row.split(percentage=0.5)
+        colL = split.column()
+        colR = split.column()
+        colL.operator("sequencer.jumpprev", icon="PLAY_REVERSE")
+        colR.operator("sequencer.jumpnext", icon='PLAY')
+
+        row=layout.row()
+        split=row.split()
+        colL = split.column()
+        colR = split.column()
+        colL.operator("sequencer.markprev", icon="MARKER_HLT")
+        colR.operator("sequencer.marknext", icon='MARKER_HLT')
+        
+        row=layout.row()
+        split=row.split()
+        colL1 = split.column()
+        colL2 = split.column()
+        colL1.operator("sequencer.sourcein", icon="REW")
+        colL2.operator("sequencer.sourceout", icon='FF')
+        
+        row=layout.row()
+        split=row.split()
+        colR1 = split.column()
+        colR1.operator("sequencer.setinout", icon="ARROW_LEFTRIGHT")
+        row=layout.row()
+        split=row.split(percentage=0.5)
+        colR1 = split.column()
+        colR1.operator("sequencer.triminout", icon="FULLSCREEN_EXIT") 
+        colR2 = split.column()
+        colR2.operator("sequencer.setstartend", icon="SETTINGS")
+
+        row=layout.row()
+        split=row.split()
+        colR1 = split.column()
+        colR2 = split.column()
+        colR1.operator("sequencer.metacopy", icon="COPYDOWN")
+        colR2.operator("sequencer.metapaste", icon='PASTEDOWN')
+        
+#-----------------------------------------------------------------------------------------------------
+
+class OBJECT_OT_Setinout(bpy.types.Operator):  
+    bl_label = "Mark in & out to active strip"
+    bl_idname = "sequencer.setinout"
+    bl_description = "set IN and OUT markers to the active strip limits"
+        
+    def invoke(self, context, event):
+        scene=bpy.context.scene
+        markers=scene.timeline_markers
+        seq=scene.sequence_editor
+        if seq:
+            strip= seq.active_strip
+            if strip != None:
+                sin = strip.frame_start + strip.frame_offset_start
+                sout = sin + strip.frame_final_duration 
+                if "IN" not in markers:
+                    mark=markers.new(name="IN")
+                    mark.frame=sin
+                else:
+                    mark=markers["IN"]
+                    mark.frame=sin
+                if "OUT" not in markers:
+                    mark= markers.new(name="OUT")
+                    mark.frame=sout
+                else:
+                    mark=markers["OUT"]
+                    mark.frame=sout 
+        return {'FINISHED'}
+    
+
+def triminout(strip,sin,sout):
+    start = strip.frame_start+strip.frame_offset_start 
+    end = start+strip.frame_final_duration
+    if end > sin:
+        if start < sin:
+            strip.select_right_handle = False            
+            strip.select_left_handle = True
+            bpy.ops.sequencer.snap(frame=sin)
+            strip.select_left_handle = False
+    if start < sout:
+        if end > sout:
+            strip.select_left_handle = False            
+            strip.select_right_handle = True
+            bpy.ops.sequencer.snap(frame=sout)
+            strip.select_right_handle = False    
+    return {'FINISHED'}
+
+
+class OBJECT_OT_Triminout(bpy.types.Operator):  
+    bl_label = "Trim to in & out"
+    bl_idname = "sequencer.triminout"
+    bl_description = "trim the selected strip to IN and OUT markers (if exists)"
+        
+    def invoke(self, context, event):
+        scene=bpy.context.scene
+        markers=scene.timeline_markers
+        seq=scene.sequence_editor
+        if seq:
+            strip= seq.active_strip
+            if strip != None:
+                if "IN" and "OUT" in markers:
+                    sin=markers["IN"].frame
+                    sout=markers["OUT"].frame
+                    triminout(strip,sin,sout)
+                else:
+                    self.report({'WARNING'}, "there is no IN and OUT")
+            bpy.ops.sequencer.reload()
+        return {'FINISHED'}
+
+def searchprev(j, list):
+    list.sort()
+    list.reverse()
+    for i in list:
+        if i < j:
+            result = i
+            break 
+    else: result = j
+    return result
+
+def searchnext(j, list): 
+    list.sort()
+    for i in list:
+        if i > j:
+            result = i
+            break
+    else: result = j
+    return result  
+
+def geteditpoints(seq):
+    #this create a list of editpoints including strips from
+    # inside metastrips. It reads only 1 level into the metastrip
+    editpoints = []
+    cliplist = []
+    metalist = []
+    if seq:
+        for i in seq.sequences:
+            if i.type == 'META':
+                metalist.append(i)
+                start = i.frame_start + i.frame_offset_start
+                end = start + i.frame_final_duration
+                editpoints.append(start)
+                editpoints.append(end)
+            else:
+                cliplist.append(i)
+        for i in metalist:
+            for j in i.sequences:
+                cliplist.append(j)  
+        for i in cliplist:
+            start = i.frame_start + i.frame_offset_start
+            end = start + i.frame_final_duration
+            editpoints.append(start)
+            editpoints.append(end)
+            #print(start," ",end)
+    return editpoints
+
+#JUMP    
+class OBJECT_OT_Jumpprev(bpy.types.Operator):  #Operator jump previous edit point
+    bl_label = "Cut previous"
+    bl_idname = "sequencer.jumpprev"
+    bl_description = "jump to previous edit point"
+    
+    editpoints = []
+        
+    def invoke(self, context, event):
+        scene=bpy.context.scene
+        seq=scene.sequence_editor
+        editpoints = geteditpoints(seq)
+        bpy.context.scene.frame_current = searchprev(scene.frame_current, editpoints) 
+        return {'FINISHED'}   
+           
+class OBJECT_OT_Jumpnext(bpy.types.Operator):  #Operator jump next edit point
+    bl_label = "Cut next"
+    bl_idname = "sequencer.jumpnext"
+    bl_description = "jump to next edit point"
+    
+    def invoke(self, context, event):
+        scene=bpy.context.scene
+        seq=scene.sequence_editor
+        editpoints = geteditpoints(seq)
+        bpy.context.scene.frame_current = searchnext(scene.frame_current, editpoints)
+        last = 0
+        for i in editpoints:
+            if i > last: last = i
+        if bpy.context.scene.frame_current == last:
+            bpy.context.scene.frame_current = last-1
+            self.report({'INFO'},'Last Frame')
+        return {'FINISHED'}
+# MARKER 
+class OBJECT_OT_Markerprev(bpy.types.Operator): 
+    bl_label = "Marker previous"
+    bl_idname = "sequencer.markprev"
+    bl_description = "jump to previous marker"
+        
+    def invoke(self, context, event):
+        markerlist = []
+        scene= bpy.context.scene
+        markers = scene.timeline_markers
+        for i in markers: markerlist.append(i.frame)
+        bpy.context.scene.frame_current = searchprev(scene.frame_current, markerlist)
+        return {'FINISHED'}
+    
+class OBJECT_OT_Markernext(bpy.types.Operator):  
+    bl_label = "Marker next"
+    bl_idname = "sequencer.marknext"
+    bl_description = "jump to next marker"
+        
+    def invoke(self, context, event):
+        markerlist = []
+        scene= bpy.context.scene
+        markers = scene.timeline_markers
+        for i in markers: markerlist.append(i.frame)
+        bpy.context.scene.frame_current = searchnext(scene.frame_current, markerlist)
+        return {'FINISHED'}
+
+# SOURCE IN OUT
+              
+class OBJECT_OT_Sourcein(bpy.types.Operator):  #Operator source in
+    bl_label = "Source IN"
+    bl_idname = "sequencer.sourcein"
+    bl_description = "add a marker named IN"
+    
+    def invoke(self, context, event):
+        scene=bpy.context.scene
+        seq = scene.sequence_editor
+        markers=scene.timeline_markers
+        if "OUT" in markers:
+            sout=markers["OUT"]
+            if scene.frame_current <= sout.frame:
+                if "IN" not in markers:
+                    sin=markers.new(name="IN")
+                    sin.frame=scene.frame_current
+                else:
+                    sin=markers["IN"]
+                    sin.frame=scene.frame_current
+            #trying to set in after out
+            else:  
+                if "IN" not in markers:
+                    sin=markers.new(name="IN")
+                    sin.frame=sout.frame
+                else:
+                    sin=markers["IN"]
+                    sin.frame=sout.frame
+                self.report({'WARNING'},'IN after OUT')
+        else:
+            if "IN" not in markers:
+                sin=markers.new(name="IN")
+                sin.frame=scene.frame_current
+            else:
+                sin=markers["IN"]
+                sin.frame=scene.frame_current
+        if seq:
+            bpy.ops.sequencer.reload()
+        return {'FINISHED'}
+
+class OBJECT_OT_Sourceout(bpy.types.Operator):  #Operator source out
+    bl_label = "Source OUT"
+    bl_idname = "sequencer.sourceout"
+    bl_description = "add a marker named OUT"
+    
+    def invoke(self, context, event):
+        scene=bpy.context.scene
+        seq = scene.sequence_editor
+        markers=scene.timeline_markers
+        if "IN" in markers:
+            sin=markers["IN"]
+            if scene.frame_current >= sin.frame:
+                if "OUT" not in markers:
+                    sout= markers.new(name="OUT")
+                    sout.frame=scene.frame_current
+                else:
+                    sout=markers["OUT"]
+                    sout.frame=scene.frame_current 
+            #trying to set out before in 
+            else:
+                if "OUT" not in markers:
+                    sout= markers.new(name="OUT")
+                    sout.frame = sin.frame
+                else:
+                    sout=markers["OUT"]
+                    sout.frame = sin.frame 
+                self.report({'WARNING'}, "OUT before IN")
+        else:
+            sout= markers.new(name="OUT")
+            sout.frame=scene.frame_current
+        if seq:
+            bpy.ops.sequencer.reload()
+        return {'FINISHED'}
+
+
+
+class OBJECT_OT_Setstartend(bpy.types.Operator):  #Operator set start & end
+    bl_label = "set Start & End"
+    bl_idname = "sequencer.setstartend"
+    bl_description = "set Start = In and End = Out"
+    
+    def invoke(self, context, event):
+        scene=bpy.context.scene
+        seq = scene.sequence_editor
+        markers=scene.timeline_markers
+        if seq:
+            if "IN" and "OUT" in markers:
+                sin=markers["IN"]
+                sout=markers["OUT"]
+                scene.frame_start = sin.frame
+                scene.frame_end = sout.frame
+                print("change")
+            else:
+                self.report({'WARNING'}, "there is no IN and OUT")
+            bpy.ops.sequencer.reload()
+        return {'FINISHED'}
+
+    
+# COPY PASTE
+
+class OBJECT_OT_Metacopy(bpy.types.Operator):  #Operator copy source in/out
+    bl_label = "Trim & Meta-Copy"
+    bl_idname = "sequencer.metacopy"
+    bl_description = "make meta from selected strips, trim it to in/out (if available) and copy it to clipboard"
+    
+    def invoke(self, context, event):
+        # rehacer
+        scene=bpy.context.scene
+        seq = scene.sequence_editor
+        markers=scene.timeline_markers
+        strip1= seq.active_strip
+        if strip1 != None:
+            if "IN" and "OUT" in markers:
+                sin=markers["IN"].frame
+                sout=markers["OUT"].frame
+                bpy.ops.sequencer.meta_make()
+                strip2= seq.active_strip
+                triminout(strip2,sin,sout)
+                bpy.ops.sequencer.copy()
+                bpy.ops.sequencer.meta_separate()
+                self.report({'INFO'}, "META has been trimed and copied")              
+            else:
+                bpy.ops.sequencer.meta_make()
+                bpy.ops.sequencer.copy()
+                bpy.ops.sequencer.meta_separate()
+                self.report({'WARNING'}, "No In & Out!! META has been copied")
+        else:
+            self.report({'ERROR'}, "No strip selected")
+        return {'FINISHED'}
+        
+class OBJECT_OT_Metapaste(bpy.types.Operator):  #Operator paste source in/out
+    bl_label = "Paste in current Frame"
+    bl_idname = "sequencer.metapaste"
+    bl_description = "paste source from clipboard to current frame"
+    
+    def invoke(self, context, event):
+        # rehacer
+        scene=bpy.context.scene
+        bpy.ops.sequencer.paste()
+        bpy.ops.sequencer.snap(frame=scene.frame_current)
+        return {'FINISHED'}
+
+# Registering / Unregister
+def register():
+    bpy.utils.register_class(Jumptocut)
+    bpy.utils.register_class(OBJECT_OT_Jumpprev)
+    bpy.utils.register_class(OBJECT_OT_Jumpnext)
+    bpy.utils.register_class(OBJECT_OT_Markerprev)
+    bpy.utils.register_class(OBJECT_OT_Markernext)    
+    bpy.utils.register_class(OBJECT_OT_Sourcein)
+    bpy.utils.register_class(OBJECT_OT_Sourceout)
+    bpy.utils.register_class(OBJECT_OT_Metacopy)
+    bpy.utils.register_class(OBJECT_OT_Metapaste)
+    bpy.utils.register_class(OBJECT_OT_Triminout)
+    bpy.utils.register_class(OBJECT_OT_Setinout)
+    bpy.utils.register_class(OBJECT_OT_Setstartend)
+    
+def unregister():
+    bpy.utils.unregister_class(Jumptocut)
+    bpy.utils.unregister_class(OBJECT_OT_Jumpprev)
+    bpy.utils.unregister_class(OBJECT_OT_Jumpnext)
+    bpy.utils.unregister_class(OBJECT_OT_Markerprev)
+    bpy.utils.unregister_class(OBJECT_OT_Markernext)      
+    bpy.utils.unregister_class(OBJECT_OT_Sourcein)
+    bpy.utils.unregister_class(OBJECT_OT_Sourceout)
+    bpy.utils.unregister_class(OBJECT_OT_Metacopy)
+    bpy.utils.unregister_class(OBJECT_OT_Metapaste)
+    bpy.utils.unregister_class(OBJECT_OT_Triminout)
+    bpy.utils.unregister_class(OBJECT_OT_Setinout)
+    bpy.utils.unregister_class(OBJECT_OT_Setstartend)
+if __name__ == "__main__":
+    register()