def execute(self, context): if self.bones: bones = eval(self.bones) else: bones = Get.selected_pose_bones(context) if not bones: return {'CANCELLED'} wgts = readWidgets() if self.widget: widget = wgts[self.widget] else: widget = wgts[context.scene.widget_list] for bone in bones: if bone.id_data.proxy: continue slide = list(self.slide) rotate = list(self.rotate) if self.mirror: mirror = findMirrorObject(bone) if mirror and mirror in bones and bone.name.endswith( ('L', 'l')): slide[0] *= -1 rotate[1] *= -1 rotate[2] *= -1 createWidget( context, bone, widget, self.relative_size, self.global_size, [*self.scale], slide, rotate, get_collection(context), ) utils.update(context) pr = utils.prefs(__addon__).bone_widgets # pr = prefs.prefs().bone_widgets if pr.keep_settings: pr.slide = self.slide pr.rotate = self.rotate pr.relative_size = self.relative_size pr.global_size = self.global_size pr.scale = self.scale pr.mirror = self.mirror # Create new object then delete it. # When creating multiple widgets, if the last one tries to enter edit # mode before a particular update occurs, Blender will crash. # If the last object created (I.E. this empty) is not the widget, # Blender can enter edit mode without crash Get.objects(context, link=True).unlink(New.object(context)) return {'FINISHED'}
def execute(self, context): prefs = utils.prefs().inputs old = prefs.use_zoom_to_mouse prefs.use_zoom_to_mouse = True prefs2 = utils.prefs().inputs old2 = prefs2.use_mouse_depth_navigate prefs2.use_mouse_depth_navigate = True bpy.ops.view3d.dolly('INVOKE_DEFAULT') prefs.use_zoom_to_mouse = old prefs2.use_mouse_depth_navigate = old2 return {'FINISHED'}
def draw(self, context): layout = self.layout src = context.src mp = context.mp mpath = src.motion_path layout.prop(mp, 'show_frame_numbers') # , text="Frame Numbers") layout.prop(mp, 'show_keyframe_highlight') # , text="Keyframes") if mp.show_keyframe_highlight: if Is.posebone(src): layout.prop(mp, 'show_keyframe_action_all', text="+ Non-Grouped Keyframes") layout.prop(mp, 'show_keyframe_numbers', text="Keyframe Numbers") layout.separator() if Is.posebone(src): layout.label(text=src.name, icon='BONE_DATA') else: layout.label(text=src.name, icon='OBJECT_DATA') if mpath: layout.prop(mpath, 'lines') # , text="Lines") layout.prop(mpath, 'use_custom_color') # , text="Custom Color") else: op = 'zpy.update_motion_paths' layout.label(text="Add Motion Paths") layout.operator(op, text="At Heads").use_tails = False layout.operator(op, text="At Tails").use_tails = True layout.separator() mot = utils.prefs(__package__).motion layout.prop(mot, 'frame_before') layout.prop(mot, 'frame_after')
def invoke(self, context, event): addon_prefs = utils.prefs(__package__).change_frame scene = context.scene space_data = context.space_data # hide viewport helpers if (context.area.type == 'VIEW_3D'): self.previousManipulator = space_data.show_gizmo # space_data.show_gizmo = False if (self.renderOnly): self.previousOnlyRender = space_data.overlay.show_overlays space_data.overlay.show_overlays = False # start modal if (addon_prefs.boolSmoothDrag): self.frameOffset = scene.frame_current_final else: self.frameOffset = scene.frame_current self.mouseOffset = event.mouse_x self.startButton = event.type # cursor context.window.cursor_set("SCROLL_X") self.text = [] bpy.types.STATUSBAR_HT_header.prepend(self.draw_status) context.window_manager.modal_handler_add(self) found = False # auto sensitivity if (self.autoSensitivity): ratio = (1024 / context.area.width) self.sensitivity = (ratio / 10) # finding end of frame range if (scene.use_preview_range): endFrame = scene.frame_preview_end else: endFrame = scene.frame_end self.sensitivity *= (endFrame / 100) found = True # default if (not found): self.sensitivity = self.defaultSensitivity / 100 if context.screen.is_animation_playing: bpy.ops.screen.animation_cancel(restore_frame=False) return {'RUNNING_MODAL'}
def invoke(self, context, event): if event.alt: for action in bpy.data.actions: # bases = a.base_interpolations. for fc in action.fcurves: for key in fc.keyframe_points: key.interpolation = self.type utils.prefs().edit.keyframe_new_interpolation_type = self.type return {'FINISHED'}
def execute(self, context): prefs = utils.prefs().inputs old = prefs.use_mouse_depth_navigate prefs.use_mouse_depth_navigate = True bpy.ops.view3d.rotate('INVOKE_DEFAULT') prefs.use_mouse_depth_navigate = old return {'FINISHED'}
def draw(self, context): layout = self.layout layout.operator('bonewidget.symmetrize_shape', icon='MOD_MIRROR') layout.operator('bonewidget.match_bone_transforms', icon='GROUP_BONE') layout.operator('bonewidget.add_widgets', icon='ADD', text="Add Widgets") layout.operator('bonewidget.remove_widgets', icon='REMOVE', text="Remove Widgets") pr = utils.prefs(__addon__).bone_widgets layout.prop(pr, 'keep_settings')
def toggle_auto_save(scn, context=None): if not scn: # Prevent error on startup scn = bpy.context.scene prefs = utils.prefs().filepaths if (prefs.use_auto_save_temporary_files != scn.use_auto_save): prefs.use_auto_save_temporary_files = scn.use_auto_save if bpy.data.filepath.startswith(ignored): prefs.use_auto_save_temporary_files = False
def draw(self, context): layout = self.layout row = layout.row(align=True) if len(bpy.types.Scene.widget_list[1]['items']) < 6: row.prop(context.scene, 'widget_list', expand=True) else: row.prop(context.scene, 'widget_list', expand=False, text="") row = layout.row(align=True) row.menu('BONEWIDGET_MT_bw_specials', icon='DOWNARROW_HLT', text="") create = row.operator('bonewidget.create_widget', icon='OBJECT_DATAMODE') if context.mode == "POSE": row.operator('bonewidget.edit_widget', icon='OUTLINER_DATA_MESH') row.operator('bonewidget.remove_widget', text="", icon='X') else: row.operator('bonewidget.return_to_armature', icon='LOOP_BACK', text='To bone') if bpy.ops.bonewidget.create_widget.poll(): pr = utils.prefs(__addon__).bone_widgets row = layout.row() row.label(text="Slide:", icon='ORIENTATION_GLOBAL') row.prop(pr, 'mirror') layout.row().prop(pr, 'slide', text="") create.slide = pr.slide layout.label(text="Rotation:", icon='ORIENTATION_LOCAL') layout.row().prop(pr, 'rotate', text="") create.rotate = pr.rotate row = layout.row() row.label(text="Scale", icon='ORIENTATION_VIEW') row.prop(pr, 'relative_size') layout.prop(pr, 'global_size', expand=False) layout.row().prop(pr, 'scale', text="") create.relative_size = pr.relative_size create.global_size = pr.global_size create.scale = pr.scale
def draw(self, context): layout = self.layout.column(align=True) camera = context.object.data prefs = utils.prefs(__package__) # col = layout.row(align=True) # display_camera = prefs.get("Toggle Camera props") # if display_camera: # draw_camera(context, col.row(), obj) # col = col.row() # col.emboss = 'PULLDOWN_MENU' # prefs.prop( # col, "Toggle Camera props", icon='CAMERA_DATA', # ) # dof_obj = camera.dof.focus_object args = dict(text="", toggle=False) cdtt = prefs.camera_dof_target_type if not camera.dof.focus_object: layout.operator( PROPS_OT_toggle_camera.bl_idname, text=("Value", "Target")[cdtt], icon=('EMPTY_AXIS', 'OBJECT_DATA')[cdtt], ) # row = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=True) row = layout.row(align=True) if cdtt or camera.dof.focus_object: row.prop(camera.dof, 'focus_object', icon='OBJECT_ORIGIN', **args) else: row.prop(camera, 'show_limits', icon='OBJECT_ORIGIN', **args) row.prop(camera.dof, 'focus_distance', icon='NONE', **args) layout.prop(camera.dof, 'aperture_fstop', icon='NONE', **args) row = layout.row(align=True) row.prop(camera, 'display_size', icon='NONE', **args)
def execute(self, context): scn = context.scene active = Get.active(context) selected = Get.selected(context) is_pose = bool(context.mode == 'POSE') if not is_pose: self.use_tails = False mode = ('HEADS', 'TAILS')[self.use_tails] # Use the line thickness of the active item, across the selection if getattr(active, 'motion_path', None): line = active.motion_path.line_thickness else: line = 1 colors = dict() types = dict() for src in Get.selected(context): mp = src.motion_path if not mp: continue if mp.use_custom_color: colors[src] = mp.color if Is.posebone(src): display = src.id_data.pose.animation_visualization.motion_path else: display = src.animation_visualization.motion_path types[src] = display.type # Get the frame range to bake motion paths in motion = utils.prefs(__package__).motion if self.use_start_end: start = self.start_frame end = self.end_frame elif (motion.use_relative_range) or (scn.use_preview_range): start = scn.frame_preview_start end = scn.frame_preview_end fc = scn.frame_current fb = motion.frame_before fa = motion.frame_after if not (scn.use_preview_range) or (abs(end - start) > 100 > (fb + fa)): # If the preview range is too high, just default to nearby start = fc - fb end = fc + fa else: # if (active): # # Use the active object's motion path's in_range distance # if (Is.posebone(active)): # mp = active.id_data.pose.animation_visualization.motion_path # else: # mp = active.animation_visualization.motion_path # fb = mp.frame_before # fa = mp.frame_after # if (fb < 25): fb = 25 # if (fa < 25): fa = 25 # start = scn.frame_current - fb # end = scn.frame_current + fa start = scn.frame_start end = scn.frame_end fc = scn.frame_current if 150 < abs(end - start): start = fc - 50 end = fc + 50 # Create the motion paths args = dict(start_frame=start, end_frame=end + 1) if is_pose: op = bpy.ops.pose args['bake_location'] = mode # Operator only runs on active rig, so repeat for all in pose mode obs = {b.id_data for b in selected} for ob in obs: Set.active(context, ob) op.paths_clear(only_selected=True) op.paths_calculate(**args) else: Set.active(context, active) else: op = bpy.ops.object op.paths_clear(only_selected=True) op.paths_calculate(**args) for src in selected: mp = src.motion_path if not mp: continue mp.line_thickness = line color = colors.get(src) if color: mp.color = color if Is.posebone(src): display = src.id_data.pose.animation_visualization.motion_path else: display = src.animation_visualization.motion_path display.type = types.get(src, 'CURRENT_FRAME') # Set to use the frame hider instead of ever displaying all points # if is_pose: # src.id_data.pose.animation_visualization. \ # motion_path.type = 'CURRENT_FRAME' # else: # src.animation_visualization. \ # motion_path.type = 'CURRENT_FRAME' # scn.frame_set(scn.frame_current) return {'FINISHED'}
def execute(self, context): prefs = utils.prefs(__package__) prefs.camera_dof_target_type = not prefs.camera_dof_target_type return {'INTERFACE'}
def manual(context, src, path, **kargs): "Insert a keyframe manually. Sub is for sub targets, like constraints" # kargs: # sub=None, index=-1, frame=None, value=None, # group=None, insert_key=None, action=None, context=None insert_key = kargs.get('insert_key', None) sub = kargs.get('sub', None) index = kargs.get('index', -1) frame = kargs.get('frame', None) value = kargs.get('value', None) group = kargs.get('group', None) action = kargs.get('action', None) results = kargs.get('results', list()) options = kargs.get('options', set()) delete = kargs.get('delete', False) keyframe_type = kargs.get('type', context.scene.tool_settings.keyframe_type) if not keyframe.poll_insert(context, insert_key, src=src): return results # if frame is None: # frame = context.scene.frame_current # if group is None: # group = keyframe.group_name(src) # src.keyframe_insert(path, index=index, frame=frame, group=group) # return if group is None: group = keyframe.group_name(src) obj = src.id_data anim = obj.animation_data_create() if action is None: key_in_action = True action = anim.action if action is None: action = anim.action = bpy.data.actions.new("Action") else: # When using a specified action, don't insert # keyframes later to determine the property's value key_in_action = False if frame is None: frame = context.scene.frame_current_final strip = Get.active_strip(anim) if anim.use_tweak_mode else None if strip: if not (strip.frame_start <= frame <= strip.frame_end): # frame outside of the strip's bounds key_in_action = False tweak_frame = Get.frame_to_strip(context, anim, frame=frame) else: tweak_frame = frame if Is.posebone(src) and not path.startswith('pose.bones'): keypath = utils.string('pose.bones[\"', src.name, '\"]', '' if path.startswith('[') else '.', path) elif not Is.object(src) and hasattr(src, 'path_from_id'): keypath = src.path_from_id(path) else: keypath = path # Find the value(s) to insert keyframes for if hasattr(sub, path): base = getattr(sub, path) elif hasattr(src, path): base = getattr(src, path) else: base = eval(f'{obj!r}.{keypath}') if value is None: prop = base else: if Is.iterable(base) and not Is.iterable(value): prop = [value for i in base] elif not Is.iterable(base) and Is.iterable(value): prop = value[(index, 0)[index == -1]] else: prop = value if (not Is.iterable(prop)): if index != -1: index = -1 if (not Is.iterable(prop)): props = [(index, prop)] else: props = [(index, prop[index])] elif (index == -1): props = list(enumerate(prop)) else: props = [(index, prop[index])] def save_quats(): quats = [0, 0, 0, 0] for index in range(4): fc = Get.fcurve(action, keypath, index=index) if fc: quats[index] = len(fc.keyframe_points) return quats def restore_quats(skip): nonlocal quats for index in range(4): if index == skip: continue fc = Get.fcurve(action, keypath, index=index) if fc and len(fc.keyframe_points) > quats[index]: for key in fc.keyframe_points: if key.co.x == tweak_frame: fc.keyframe_points.remove(key) break else: # Shouldn't happen but backup in case fail to find key key_args = dict(index=index, frame=frame, group=group) if sub is None: src.keyframe_delete(path, **key_args) else: sub.keyframe_delete(path, **key_args) if path.endswith('rotation_quaternion') and ( (strip and strip.blend_type == 'COMBINE') or (not strip and anim.action_blend_type == 'COMBINE')): # Combine forces keyframe insertion on all 4 channels, so reset them quats = save_quats() else: quats = None # Create curve(s) (if needed) and keyframe(s) for (i, v) in props: fc = Get.fcurve(action, keypath, i) new_fc = not bool(fc) if new_fc: fc = New.fcurve(action, keypath, index=i, group=group) if fc.lock: # Internal ops don't allow keyframing locked channels, so :p results.append((fc, None)) continue if delete: results.append((fc, src.keyframe_delete(path, frame=frame))) continue count = len(fc.keyframe_points) if (value is None) and key_in_action: key_args = dict(index=i, frame=frame, group=group, options=options) if sub is None: src.keyframe_insert(path, **key_args) else: sub.keyframe_insert(path, **key_args) v = fc.evaluate(tweak_frame) key = fc.keyframe_points.insert(tweak_frame, v, options={'FAST'}) # options=set({'REPLACE', 'NEEDED', 'FAST'}) # src.keyframe_insert(path, index=i, frame=frame, group=group) if quats: restore_quats(skip=i) quats[i] = len(fc.keyframe_points) # Update key count for current index, to not remove it later # Update keyframe to use default preferences values edit = utils.prefs().edit key.handle_left_type = key.handle_right_type = \ edit.keyframe_new_handle_type if new_fc: # When inserting keyframes, only change their interpolation type if the fcurve is new key.interpolation = edit.keyframe_new_interpolation_type if len(fc.keyframe_points) > count: # New keyframe was added key.type = keyframe_type results.append((fc, key)) if kargs.get('index', -1) == -1: return results else: return results[0]
def draw_header(self, context): layout = self.layout prefs = utils.prefs(__package__).motion if context.mode == 'POSE': src = context.active_pose_bone else: src = context.object if not src: return layout.separator() sub = layout.row() sub.emboss = ('PULLDOWN_MENU', 'NORMAL')[prefs.show_panel] sub.active = prefs.show_panel sub.prop(prefs, 'show_panel', text="", icon='CURVE_DATA') if not prefs.show_panel: return if Is.posebone(src): mp = src.id_data.pose.animation_visualization.motion_path else: mp = src.animation_visualization.motion_path if mp.type == 'CURRENT_FRAME': mp_text = "Around Frame" mp_icon = 'PREVIEW_RANGE' mp_start = 'frame_before' mp_end = 'frame_after' mp_type = 'RANGE' # value to toggle to else: # mp.type == 'RANGE': mp_icon = 'TIME' mp_text = " In Range " mp_start = 'frame_start' mp_end = 'frame_end' mp_type = 'CURRENT_FRAME' # value to toggle to row = layout.row(align=True) row.context_pointer_set('src', src) row.context_pointer_set('mp', mp) row.menu('MOTIONP_MT_subpanel', text="", icon='THREE_DOTS') sub = row.row(align=True) sub.scale_x = 0.6 sub.prop(mp, mp_start, text="") row.operator('zpy.motion_path_toggle_type', text=mp_text, icon=mp_icon, depress=False).type = mp_type sub = row.row() sub.scale_x = 0.6 sub.prop(mp, mp_end, text="") # prefs.operator(row, 'toggle mp relative range', text="", # icon=('TIME', 'PREVIEW_RANGE') # [prefs.prefs().motion.use_relative_range], # emboss=True, depress=False, code=''' # mot = prefs.prefs().motion # mot.use_relative_range = not mot.use_relative_range sub = row.row() sub.emboss = 'PULLDOWN_MENU' if prefs.use_relative_range: text = "Around" icon = 'PREVIEW_RANGE' else: text = "Range" icon = 'TIME' sub.prop(prefs, 'use_relative_range', text=text, icon=icon, icon_only=True) mpath = src.motion_path if mpath: sub = row.row(align=True) # sub.scale_x = 0.5 if mpath.use_custom_color: sub.prop(mpath, 'color', icon_only=True) else: sub.active = False sub.prop(mpath, 'use_custom_color', icon_only=True, icon='COLORSET_20_VEC') sub = row.row(align=True) sub.scale_x = 0.5 sub.prop(mpath, 'line_thickness', icon_only=True, slider=True) if mp.has_motion_paths: if context.mode == 'POSE': clear = 'pose.paths_clear' else: clear = 'object.paths_clear' row.operator(clear, text="", icon='PANEL_CLOSE')
def modal(self, context, event): addon_prefs = utils.prefs(__package__).change_frame scene = context.scene space_data = context.space_data def set_text(items=None): if items is None: bpy.types.STATUSBAR_HT_header.remove(self.draw_status) context.window.workspace.status_text_set(None) else: context.window.workspace.status_text_set("") self.text = items if scene.use_preview_range: start = scene.frame_preview_start end = scene.frame_preview_end else: start = scene.frame_start end = scene.frame_end scrolled = False if event.value == 'PRESS': if event.type == 'WHEELUPMOUSE': self.sensitivity_factor -= 1 scrolled = True if event.type == 'WHEELDOWNMOUSE': self.sensitivity_factor += 1 scrolled = True sensitivity = self.sensitivity for i in range(abs(self.sensitivity_factor)): if self.sensitivity_factor < 0: # sensitivity += sensitivity * 0.1 # faster sensitivity *= 1.1 # faster else: # sensitivity -= sensitivity * 0.1 # slower sensitivity *= 0.9 # slower looping = addon_prefs.boolLoopTimeline # if (event.value == 'PRESS' and event.type == 'CTRL'): if (event.value == 'PRESS' and event.type == 'LEFT_CTRL'): addon_prefs.boolLoopTimeline = not looping # change frame if (event.type == 'MOUSEMOVE') or scrolled: delta = self.mouseOffset - event.mouse_x offset = (-delta * sensitivity) + self.frameOffset if looping: dist = abs(start - end) if (start != end): # prevent loop freeze/crash if offset > end: while offset > end: offset -= dist elif offset < start: while offset < start: offset += dist if (addon_prefs.boolSmoothDrag): current = int(offset) subframe = offset - int(offset) if (current < 0 and subframe) or subframe < 0: # Negative numbers have to offset a little for frame_set current -= 1 subframe = 1 - abs(subframe) scene.frame_current = current scene.frame_subframe = subframe else: scene.frame_current = offset # end of modal elif (event.type == self.startButton and event.value == 'RELEASE'): set_text() # previous viewport setting if (context.area.type == 'VIEW_3D'): space_data.show_gizmo = self.previousManipulator if (self.renderOnly): space_data.overlay.show_overlays = self.previousOnlyRender # cursor back context.window.cursor_set("DEFAULT") # snap back if (addon_prefs.boolSmoothSnap): scene.frame_subframe = 0 return {'FINISHED'} set_text([ (('REW'), f"<{start :02}>"), (('NONE'), f"({scene.frame_current :05.2f})"), (('FF'), f"<{end :02}>"), (('MOUSE_MMB_DRAG'), F"Sensitivity: {((sensitivity / self.sensitivity) * 100) :.1f}%"), (('PLAY', 'FILE_REFRESH')[looping], f"""{("", "(Loop Animation) Left Ctrl to Disable")[looping]}"""), ]) return {'RUNNING_MODAL'}
def prefs(): return utils.prefs(__addon__).bone_widgets