Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Picard <dam.pic@free.fr>2019-12-17 13:11:37 +0300
committerDamien Picard <dam.pic@free.fr>2020-01-24 02:50:51 +0300
commit81ed56cbce99c9991c989163c802b4cea42be58e (patch)
tree43843eeb00ae6173767fbf8b5ad0c47fe0b26235 /add_camera_rigs/operators.py
parentf5f442a7a665bf219755a014701aafe967f806e7 (diff)
add_camera_rigs: refactor and cleanup
- Fix widgets’ names: they were hardcoded and didn’t follow the preferences, leading to crashes. - The UI was put back into the Item category, instead of Create, because it is not related to object creation. - Fix some strange topology in two widget shapes. - UI and operators use a new poll method, so that they work when either the rig or the camera is selected. - The composition guides UI was converted to a panel, so that they may be drag-selected. - Marker binding and DOF object operators were converted to the `bpy.data` API, making them simpler. - Bones were moved around so that they are more similar between rigs. - They were scaled down to be 1 unit long, a simpler length — for instance, widgets are the same size as modeled. Widgets were scaled up to compensate. - The camera and aim bones were placed at 1.7 unit high, to be approximately at a standing human’s eyes’ height if the scene is in meters. - Much of the rig generation was refactored to deduplicate code between the two rig types. - Automatic renaming to `.000` was removed, since Blender already handles duplicate names. - Widget prefix and collection were renamed to `WGT-` and `Widgets` respectively. This is to be closer to Rigify, hopefully unifying them. - The GPL license header was added to every file. - Some cleanup was done to better respect Python’s PEP 8. Reviewed By: Wayne Dixon Differential Revision: https://developer.blender.org/D6543
Diffstat (limited to 'add_camera_rigs/operators.py')
-rw-r--r--add_camera_rigs/operators.py162
1 files changed, 76 insertions, 86 deletions
diff --git a/add_camera_rigs/operators.py b/add_camera_rigs/operators.py
index fe93041d..7468007e 100644
--- a/add_camera_rigs/operators.py
+++ b/add_camera_rigs/operators.py
@@ -1,118 +1,108 @@
+# ##### 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 #####
+
import bpy
from bpy.types import Operator
-def set_scene_camera():
- '''Makes the camera the active and sets it to the scene camera'''
- ob = bpy.context.active_object
- # find the children on the rig (the camera name)
- active_cam = ob.children[0].name
- # cam = bpy.data.cameras[bpy.data.objects[active_cam]]
- scene_cam = bpy.context.scene.camera
+def get_arm_and_cam(obj):
+ if obj.type == 'ARMATURE':
+ cam = None
+ for child in obj.children:
+ if child.type == 'CAMERA':
+ cam = child
+ break
+ if cam is not None:
+ return obj, cam
+ elif (obj.type == 'CAMERA'
+ and obj.parent is not None
+ and "rig_id" in obj.parent
+ and obj.parent["rig_id"].lower() in {"dolly_rig", "crane_rig"}):
+ return obj.parent, obj
+ return None, None
+
+
+class CameraRigMixin():
+ @classmethod
+ def poll(cls, context):
+ if context.active_object is not None:
+ return get_arm_and_cam(context.active_object) != (None, None)
- if active_cam != scene_cam.name:
- bpy.context.scene.camera = bpy.data.objects[active_cam]
- else:
- return None
+ return False
-class ADD_CAMERA_RIGS_OT_set_scene_camera(Operator):
+class ADD_CAMERA_RIGS_OT_set_scene_camera(Operator, CameraRigMixin):
bl_idname = "add_camera_rigs.set_scene_camera"
bl_label = "Make Camera Active"
bl_description = "Makes the camera parented to this rig the active scene camera"
- @classmethod
- def poll(cls, context):
- return context.active_object is not None
-
def execute(self, context):
- set_scene_camera()
+ arm, cam = get_arm_and_cam(context.active_object)
+ scene_cam = context.scene.camera
- return {'FINISHED'}
+ if cam is not None and cam is not scene_cam:
+ context.scene.camera = cam
+ return {'FINISHED'}
+ return {'CANCELLED'}
-def markerBind():
- '''Defines the function to add a marker to timeling and bind camera'''
- rig = bpy.context.active_object # rig object
- active_cam = rig.children[0] # camera object
-
- # switch area to DOPESHEET to add marker
- bpy.context.area.type = 'DOPESHEET_EDITOR'
- # add marker
- bpy.ops.marker.add() # it will automatiically have the name of the camera
- # select rig camera
- bpy.context.view_layer.objects.active = active_cam
- # bind marker to selected camera
- bpy.ops.marker.camera_bind()
- # make the rig the active object before finishing
- bpy.context.view_layer.objects.active = rig
- bpy.data.objects[active_cam.name].select_set(False)
- bpy.data.objects[rig.name].select_set(True)
- # switch back to 3d view
- bpy.context.area.type = 'VIEW_3D'
-
-
-class ADD_CAMERA_RIGS_OT_add_marker_bind(Operator):
+
+class ADD_CAMERA_RIGS_OT_add_marker_bind(Operator, CameraRigMixin):
bl_idname = "add_camera_rigs.add_marker_bind"
bl_label = "Add Marker and Bind Camera"
bl_description = "Add marker to current frame then bind rig camera to it (for camera switching)"
- @classmethod
- def poll(cls, context):
- return context.active_object is not None
-
def execute(self, context):
- markerBind()
-
- return {'FINISHED'}
+ arm, cam = get_arm_and_cam(context.active_object)
+ marker = context.scene.timeline_markers.new(
+ "cam_" + str(context.scene.frame_current),
+ frame=context.scene.frame_current
+ )
+ marker.camera = cam
-def add_DOF_object():
- """Define the function to add an Empty as DOF object """
- smode = bpy.context.mode
- rig = bpy.context.active_object
- bone = rig.data.bones['aim_MCH']
- active_cam = rig.children[0].name
- cam = bpy.data.cameras[bpy.data.objects[active_cam].data.name]
-
- bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
- # Add Empty
- bpy.ops.object.empty_add()
- obj = bpy.context.active_object
-
- obj.name = "Empty_DOF"
- # parent to aim_MCH
- obj.parent = rig
- obj.parent_type = "BONE"
- obj.parent_bone = "aim_MCH"
- # clear loc and rot
- bpy.ops.object.location_clear()
- bpy.ops.object.rotation_clear()
- # move to bone head
- obj.location = bone.head
-
- # make this new empty the dof_object
- cam.dof.focus_object = obj
-
- # make the rig the active object before finishing
- bpy.context.view_layer.objects.active = rig
- bpy.data.objects[obj.name].select_set(False)
- bpy.data.objects[rig.name].select_set(True)
-
- bpy.ops.object.mode_set(mode=smode, toggle=False)
+ return {'FINISHED'}
-class ADD_CAMERA_RIGS_OT_add_dof_object(Operator):
+class ADD_CAMERA_RIGS_OT_add_dof_object(Operator, CameraRigMixin):
bl_idname = "add_camera_rigs.add_dof_object"
bl_label = "Add DOF Object"
bl_description = "Create Empty and add as DOF Object"
- @classmethod
- def poll(cls, context):
- return context.active_object is not None
-
def execute(self, context):
- add_DOF_object()
+ arm, cam = get_arm_and_cam(context.active_object)
+ bone = arm.data.bones['Aim_shape_rotation-MCH']
+
+ # Add Empty
+ empty_obj = bpy.data.objects.new("EmptyDOF", None)
+ context.scene.collection.objects.link(empty_obj)
+
+ # Parent to Aim Child bone
+ empty_obj.parent = arm
+ empty_obj.parent_type = "BONE"
+ empty_obj.parent_bone = "Aim_shape_rotation-MCH"
+
+ # Move to bone head
+ empty_obj.location = bone.head
+
+ # Make this new empty the dof_object
+ cam.data.dof.use_dof = True
+ cam.data.dof.focus_object = empty_obj
return {'FINISHED'}