diff options
author | meta-androcto <meta.androcto1@gmail.com> | 2019-12-02 02:54:05 +0300 |
---|---|---|
committer | meta-androcto <meta.androcto1@gmail.com> | 2019-12-02 02:54:05 +0300 |
commit | 7cfd041403732d6913415eeda89769ea7d424cfe (patch) | |
tree | e9d22bb3991f096dbf395c5734b38585ddbe0df9 /add_camera_rigs | |
parent | 44680646e7111881f723729637e617ad35d63b1a (diff) |
add camera rigs: update, move to folder structure: T71763
Diffstat (limited to 'add_camera_rigs')
-rw-r--r-- | add_camera_rigs/__init__.py | 63 | ||||
-rw-r--r-- | add_camera_rigs/build_rigs.py | 544 | ||||
-rw-r--r-- | add_camera_rigs/composition_guides_menu.py | 41 | ||||
-rw-r--r-- | add_camera_rigs/create_widgets.py | 241 | ||||
-rw-r--r-- | add_camera_rigs/operators.py | 136 | ||||
-rw-r--r-- | add_camera_rigs/prefs.py | 46 | ||||
-rw-r--r-- | add_camera_rigs/ui_panels.py | 89 |
7 files changed, 1160 insertions, 0 deletions
diff --git a/add_camera_rigs/__init__.py b/add_camera_rigs/__init__.py new file mode 100644 index 00000000..9d296e6c --- /dev/null +++ b/add_camera_rigs/__init__.py @@ -0,0 +1,63 @@ +# ##### 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": "Add Camera Rigs", + "author": "Wayne Dixon, Brian Raschko, Kris Wittig", + "version": (1, 4, 1), + "blender": (2, 80, 0), + "location": "View3D > Add > Camera > Dolly or Crane Rig", + "description": "Adds a Camera Rig with UI", + "wiki_url": "https://docs.blender.org/manual/en/dev/addons/" + "camera/camera_rigs.html", + "tracker_url": "https://github.com/waylow/add_camera_rigs/issues", + "category": "Camera", +} + +import bpy +import os + +from . import build_rigs +from . import operators +from . import ui_panels +from . import prefs +from . import composition_guides_menu + +# ========================================================================= +# Registration: +# ========================================================================= + +def register(): + build_rigs.register() + operators.register() + ui_panels.register() + prefs.register() + composition_guides_menu.register() + + +def unregister(): + build_rigs.unregister() + operators.unregister() + ui_panels.unregister() + prefs.unregister() + composition_guides_menu.unregister() + + +if __name__ == "__main__": + register() diff --git a/add_camera_rigs/build_rigs.py b/add_camera_rigs/build_rigs.py new file mode 100644 index 00000000..c7303198 --- /dev/null +++ b/add_camera_rigs/build_rigs.py @@ -0,0 +1,544 @@ +import bpy +from bpy.types import Operator +from math import radians +from rna_prop_ui import rna_idprop_ui_prop_get +from .create_widgets import (create_root_widget, + create_widget, + create_camera_widget, + create_aim_widget, + ) + + +def build_dolly_rig(context): + """Operator to build the dolly rig""" + # Set the bone layers + boneLayer = (False, True, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False) + + # Add the new armature object: + bpy.ops.object.armature_add() + rig = context.active_object + + # it will try to name the rig "Dolly_rig" but if that name exists it will + # add 000 to the name + if "Dolly_rig" not in context.scene.objects: + rig.name = "Dolly_rig" + else: + rig.name = "Dolly_rig.000" + rig["rig_id"] = "Dolly_rig" + + bpy.ops.object.mode_set(mode='EDIT') + + # Remove default bone: + bones = rig.data.edit_bones + bones.remove(bones[0]) + + # Add new bones: + root = bones.new("Root") + root.tail = (0.0, 3.0, 0.0) + + bpy.ops.object.mode_set(mode='EDIT') + ctrlAimChild = bones.new("aim_MCH") + ctrlAimChild.head = (0.0, 5.0, 3.0) + ctrlAimChild.tail = (0.0, 7.0, 3.0) + ctrlAimChild.layers = boneLayer + + ctrlAim = bones.new("Aim") + ctrlAim.head = (0.0, 5.0, 3.0) + ctrlAim.tail = (0.0, 7.0, 3.0) + + ctrl = bones.new("Camera") + ctrl.head = (0.0, 0.0, 3.0) + ctrl.tail = (0.0, 2.0, 3.0) + + # Setup hierarchy: + ctrl.parent = root + ctrlAim.parent = root + ctrlAimChild.parent = ctrlAim + + # jump into pose mode and change bones to euler + bpy.ops.object.mode_set(mode='POSE') + for x in bpy.context.object.pose.bones: + x.rotation_mode = 'XYZ' + + # jump into pose mode and add the custom bone shapes + bpy.ops.object.mode_set(mode='POSE') + bpy.context.object.pose.bones["Root"].custom_shape = bpy.data.objects[ + "WDGT_Camera_root"] # add the widget as custom shape + # set the wireframe checkbox to true + bpy.context.object.data.bones["Root"].show_wire = True + bpy.context.object.pose.bones[ + "Aim"].custom_shape = bpy.data.objects["WDGT_Aim"] + bpy.context.object.data.bones["Aim"].show_wire = True + bpy.context.object.pose.bones["Aim"].custom_shape_transform = bpy.data.objects[ + rig.name].pose.bones["aim_MCH"] # sets the "At" field to the child + bpy.context.object.pose.bones[ + "Camera"].custom_shape = bpy.data.objects["WDGT_Camera"] + bpy.context.object.data.bones["Camera"].show_wire = True + + # jump into object mode + bpy.ops.object.mode_set(mode='OBJECT') + + # Add constraints to bones: + con = rig.pose.bones['aim_MCH'].constraints.new('COPY_ROTATION') + con.target = rig + con.subtarget = "Camera" + + con = rig.pose.bones['Camera'].constraints.new('TRACK_TO') + con.target = rig + con.subtarget = "Aim" + con.use_target_z = True + + # Add custom Bone property to Camera bone + ob = bpy.context.object.pose.bones['Camera'] + prop = rna_idprop_ui_prop_get(ob, "lock", create=True) + ob["lock"] = 1.0 + prop["soft_min"] = prop["min"] = 0.0 + prop["soft_max"] = prop["max"] = 1.0 + + # Add Driver to Lock/Unlock Camera from Aim Target + rig = bpy.context.view_layer.objects.active + pose_bone = bpy.data.objects[rig.name].pose.bones['Camera'] + + constraint = pose_bone.constraints["Track To"] + inf_driver = constraint.driver_add('influence') + inf_driver.driver.type = 'SCRIPTED' + var = inf_driver.driver.variables.new() + var.name = 'var' + var.type = 'SINGLE_PROP' + + # Target the Custom bone property + var.targets[0].id = bpy.data.objects[rig.name] + var.targets[0].data_path = 'pose.bones["Camera"]["lock"]' + inf_driver.driver.expression = 'var' + + # Add custom property for the lens / add the driver after the camera is created + ob = bpy.context.object.pose.bones['Camera'] + prop = rna_idprop_ui_prop_get(ob, "focal_length", create=True) + ob["focal_length"] = 50.0 + prop["soft_min"] = prop["min"] = 1.0 + prop["default"] = 50.0 + prop["soft_max"] = prop["max"] = 5000.0 + + # Add custom property for the focus distance / add the driver after the camera is created + ob = bpy.context.object.pose.bones['Camera'] + prop = rna_idprop_ui_prop_get(ob, "focus_distance", create=True) + ob["focus_distance"] = 10.00 + prop["soft_min"] = prop["min"] = 0.0 + prop["soft_max"] = prop["max"] = 1000.0 + + # Add custom property for the f-stop / add the driver after the camera is created + ob = bpy.context.object.pose.bones['Camera'] + prop = rna_idprop_ui_prop_get(ob, "f-stop", create=True) + ob["f-stop"] = 2.8 + prop["soft_min"] = prop["min"] = 0.1 + prop["soft_max"] = prop["max"] = 128.00 + + # Add the camera object: + bpy.ops.object.mode_set(mode='OBJECT') + + bpy.ops.object.camera_add() + cam = bpy.context.active_object + + # Name the Camera Object + if 'Dolly_camera' not in context.scene.objects: + cam.name = "Dolly_camera" + else: + cam.name = "Dolly_camera.000" + + # this will name the camera data + cam.data.name = cam.name + + cam_data_name = bpy.context.object.data.name + bpy.data.cameras[cam_data_name].display_size = 1.0 + cam.rotation_euler = [radians(90), 0, 0] # rotate the camera 90 degrees in x + + cam.location = (0.0, -2.0, 0.0) # move the camera to the correct postion + cam.parent = rig + cam.parent_type = "BONE" + cam.parent_bone = "Camera" + + # Add Driver to link the camera lens to the custom property on the armature + pose_bone = bpy.data.objects[rig.name].pose.bones['Camera'] + lens_driver = cam.data.driver_add("lens") + lens_driver.driver.type = 'SCRIPTED' + var = lens_driver.driver.variables.new() + var.name = 'var' + var.type = 'SINGLE_PROP' + + # Target the Custom bone property + var.targets[0].id = bpy.data.objects[rig.name] + var.targets[0].data_path = 'pose.bones["Camera"]["focal_length"]' + lens_driver.driver.expression = 'var' + + # Add Driver to link the camera focus distance to the custom property on the armature + pose_bone = bpy.data.objects[rig.name].pose.bones['Camera'] + lens_driver = cam.data.driver_add("dof.focus_distance") + lens_driver.driver.type = 'SCRIPTED' + var = lens_driver.driver.variables.new() + var.name = 'var' + var.type = 'SINGLE_PROP' + + # Target the Custom bone property + var.targets[0].id = bpy.data.objects[rig.name] + var.targets[0].data_path = 'pose.bones["Camera"]["focus_distance"]' + lens_driver.driver.expression = 'var' + + # Add Driver to link the camera f-stop to the custom property on the armature + pose_bone = bpy.data.objects[rig.name].pose.bones['Camera'] + lens_driver = cam.data.driver_add("dof.aperture_fstop") + lens_driver.driver.type = 'SCRIPTED' + var = lens_driver.driver.variables.new() + var.name = 'var' + var.type = 'SINGLE_PROP' + + # Target the Custom bone property + var.targets[0].id = bpy.data.objects[rig.name] + var.targets[0].data_path = 'pose.bones["Camera"]["f-stop"]' + lens_driver.driver.expression = 'var' + + # lock the location/rotation/scale of the camera + cam.lock_location = [True, True, True] + cam.lock_rotation = [True, True, True] + cam.lock_scale = [True, True, True] + + # Set new camera as active camera + bpy.context.scene.camera = cam + + # make sure the camera is selectable by default (this can be locked in the UI) + bpy.context.object.hide_select = False + + # make the rig the active object before finishing + bpy.context.view_layer.objects.active = rig + bpy.data.objects[cam.name].select_set(False) + bpy.data.objects[rig.name].select_set(True) + + return rig + + +class ADD_CAMERA_RIGS_OT_build_dolly_rig(Operator): + bl_idname = "add_camera_rigs.build_dolly_rig" + bl_label = "Build Dolly Camera Rig" + bl_description = "Build a Camera Dolly Rig" + bl_options = {'REGISTER', 'UNDO'} + + def execute(self, context): + # build the Widgets + if not "WDGT_Camera_root" in bpy.context.scene.objects: + create_root_widget(self, "Camera_root") + if not "WDGT_Camera" in bpy.context.scene.objects: + create_camera_widget(self, "Camera") + if not "WDGT_Aim" in bpy.context.scene.objects: + create_aim_widget(self, "Aim") + + # call the function to build the rig + build_dolly_rig(context) + + return {'FINISHED'} + + +def build_crane_rig(context): + # Define some useful variables: + boneLayer = (False, True, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False) + + # Add the new armature object: + bpy.ops.object.armature_add() + rig = context.active_object + + # it will try to name the rig "Crane_rig" but if that name exists it will + # add .000 to the name + if "Crane_rig" not in context.scene.objects: + rig.name = "Crane_rig" + else: + rig.name = "Crane_rig.000" + rig["rig_id"] = "Crane_rig" + + bpy.ops.object.mode_set(mode='EDIT') + + # Remove default bone: + bones = rig.data.edit_bones + bones.remove(bones[0]) + + # Add new bones: + root = bones.new("Root") + root.tail = (0.0, 3.0, 0.0) + + ctrlAimChild = bones.new("aim_MCH") + ctrlAimChild.head = (0.0, 10.0, 1.0) + ctrlAimChild.tail = (0.0, 12.0, 1.0) + ctrlAimChild.layers = boneLayer + + ctrlAim = bones.new("Aim") + ctrlAim.head = (0.0, 10.0, 1.0) + ctrlAim.tail = (0.0, 12.0, 1.0) + + ctrl = bones.new("Camera") + ctrl.head = (0.0, 1.0, 1.0) + ctrl.tail = (0.0, 3.0, 1.0) + + arm = bones.new("Crane_arm") + arm.head = (0.0, 0.0, 1.0) + arm.tail = (0.0, 1.0, 1.0) + + height = bones.new("Crane_height") + height.head = (0.0, 0.0, 0.0) + height.tail = (0.0, 0.0, 1.0) + + # Setup hierarchy: + ctrl.parent = arm + ctrl.use_inherit_rotation = False + ctrl.use_inherit_scale = False + + arm.parent = height + arm.use_inherit_scale = False + + height.parent = root + ctrlAim.parent = root + ctrlAimChild.parent = ctrlAim + + # change display to BBone: it just looks nicer + bpy.context.object.data.display_type = 'BBONE' + # change display to wire for object + bpy.context.object.display_type = 'WIRE' + + # jump into pose mode and change bones to euler + bpy.ops.object.mode_set(mode='POSE') + for x in bpy.context.object.pose.bones: + x.rotation_mode = 'XYZ' + + # lock the relevant loc, rot and scale + bpy.context.object.pose.bones[ + "Crane_arm"].lock_rotation = [False, True, False] + bpy.context.object.pose.bones["Crane_arm"].lock_scale = [True, False, True] + bpy.context.object.pose.bones["Crane_height"].lock_location = [True, True, True] + bpy.context.object.pose.bones["Crane_height"].lock_rotation = [True, True, True] + bpy.context.object.pose.bones["Crane_height"].lock_scale = [True, False, True] + + # add the custom bone shapes + bpy.context.object.pose.bones["Root"].custom_shape = bpy.data.objects[ + "WDGT_Camera_root"] # add the widget as custom shape + # set the wireframe checkbox to true + bpy.context.object.data.bones["Root"].show_wire = True + bpy.context.object.pose.bones[ + "Aim"].custom_shape = bpy.data.objects["WDGT_Aim"] + bpy.context.object.data.bones["Aim"].show_wire = True + bpy.context.object.pose.bones["Aim"].custom_shape_transform = bpy.data.objects[ + rig.name].pose.bones["aim_MCH"] # sets the "At" field to the child + bpy.context.object.pose.bones[ + "Camera"].custom_shape = bpy.data.objects["WDGT_Camera"] + bpy.context.object.data.bones["Camera"].show_wire = True + + # jump into object mode + bpy.ops.object.mode_set(mode='OBJECT') + + # Add constraints to bones: + con = rig.pose.bones['aim_MCH'].constraints.new('COPY_ROTATION') + con.target = rig + con.subtarget = "Camera" + + con = rig.pose.bones['Camera'].constraints.new('TRACK_TO') + con.target = rig + con.subtarget = "Aim" + con.use_target_z = True + + # Add custom Bone property to Camera bone + ob = bpy.context.object.pose.bones['Camera'] + prop = rna_idprop_ui_prop_get(ob, "lock", create=True) + ob["lock"] = 1.0 + prop["soft_min"] = prop["min"] = 0.0 + prop["soft_max"] = prop["max"] = 1.0 + + # Add Driver to Lock/Unlock Camera from Aim Target + rig = bpy.context.view_layer.objects.active + pose_bone = bpy.data.objects[rig.name].pose.bones['Camera'] + + constraint = pose_bone.constraints["Track To"] + inf_driver = constraint.driver_add('influence') + inf_driver.driver.type = 'SCRIPTED' + var = inf_driver.driver.variables.new() + var.name = 'var' + var.type = 'SINGLE_PROP' + + # Target the Custom bone property + var.targets[0].id = bpy.data.objects[rig.name] + var.targets[0].data_path = 'pose.bones["Camera"]["lock"]' + inf_driver.driver.expression = 'var' + + # Add custom property for the lens / add the driver after the camera is created + ob = bpy.context.object.pose.bones['Camera'] + prop = rna_idprop_ui_prop_get(ob, "focal_length", create=True) + ob["focal_length"] = 50.0 + prop["soft_min"] = prop["min"] = 1.0 + prop["default"] = 50.0 + prop["soft_max"] = prop["max"] = 5000.0 + + # Add custom property for the focus distance / add the driver after the camera is created + ob = bpy.context.object.pose.bones['Camera'] + prop = rna_idprop_ui_prop_get(ob, "focus_distance", create=True) + ob["focus_distance"] = 10.00 + prop["soft_min"] = prop["min"] = 0.0 + prop["soft_max"] = prop["max"] = 1000.0 + + # Add custom property for the focus distance / add the driver after the camera is created + ob = bpy.context.object.pose.bones['Camera'] + prop = rna_idprop_ui_prop_get(ob, "focus_distance", create=True) + ob["focus_distance"] = 10.00 + prop["soft_min"] = prop["min"] = 0.0 + prop["soft_max"] = prop["max"] = 1000.0 + + # Add custom property for the f-stop / add the driver after the camera is created + ob = bpy.context.object.pose.bones['Camera'] + prop = rna_idprop_ui_prop_get(ob, "f-stop", create=True) + ob["f-stop"] = 2.8 + prop["soft_min"] = prop["min"] = 0.1 + prop["soft_max"] = prop["max"] = 128.00 + + # Add the camera object: + bpy.ops.object.mode_set(mode='OBJECT') + + bpy.ops.object.camera_add() + cam = bpy.context.active_object + + # this will name the Camera Object + if 'Crane_camera' not in context.scene.objects: + cam.name = "Crane_camera" + else: + cam.name = "Crane_camera.000" + + # this will name the camera Data Object + if "Crane_camera" not in bpy.context.scene.objects.data.camera: + cam.data.name = "Crane_camera" + else: + cam.data.name = "Crane_camera.000" + + cam_data_name = bpy.context.object.data.name + bpy.data.cameras[cam_data_name].display_size = 1.0 + cam.rotation_euler = [radians(90), 0, 0] # rotate the camera 90 degrees in x + cam.location = (0.0, -2.0, 0.0) # move the camera to the correct postion + cam.parent = rig + cam.parent_type = "BONE" + cam.parent_bone = "Camera" + + # Add Driver to link the camera lens to the custom property on the armature + pose_bone = bpy.data.objects[rig.name].pose.bones['Camera'] + lens_driver = cam.data.driver_add("lens") + lens_driver.driver.type = 'SCRIPTED' + var = lens_driver.driver.variables.new() + var.name = 'var' + var.type = 'SINGLE_PROP' + + # Target the Custom bone property + var.targets[0].id = bpy.data.objects[rig.name] + var.targets[0].data_path = 'pose.bones["Camera"]["focal_length"]' + lens_driver.driver.expression = 'var' + + # Add Driver to link the camera focus distance to the custom property on the armature + pose_bone = bpy.data.objects[rig.name].pose.bones['Camera'] + lens_driver = cam.data.driver_add("dof.focus_distance") + lens_driver.driver.type = 'SCRIPTED' + var = lens_driver.driver.variables.new() + var.name = 'var' + var.type = 'SINGLE_PROP' + + # Target the Custom bone property + var.targets[0].id = bpy.data.objects[rig.name] + var.targets[0].data_path = 'pose.bones["Camera"]["focus_distance"]' + lens_driver.driver.expression = 'var' + + # Add Driver to link the camera f-stop to the custom property on the armature + pose_bone = bpy.data.objects[rig.name].pose.bones['Camera'] + lens_driver = cam.data.driver_add("dof.aperture_fstop") + lens_driver.driver.type = 'SCRIPTED' + var = lens_driver.driver.variables.new() + var.name = 'var' + var.type = 'SINGLE_PROP' + + # Target the Custom bone property + var.targets[0].id = bpy.data.objects[rig.name] + var.targets[0].data_path = 'pose.bones["Camera"]["f-stop"]' + lens_driver.driver.expression = 'var' + + # the location/rotation/scale of the camera + cam.lock_location = [True, True, True] + cam.lock_rotation = [True, True, True] + cam.lock_scale = [True, True, True] + + # Set new camera as active camera + bpy.context.scene.camera = cam + + # make sure the camera is selectable by default (this can be locked in the UI) + bpy.context.object.hide_select = False + + # make the rig the active object before finishing + bpy.context.view_layer.objects.active = rig + bpy.data.objects[cam.name].select_set(False) + bpy.data.objects[rig.name].select_set(True) + + return rig + + +class ADD_CAMERA_RIGS_OT_build_crane_rig(Operator): + bl_idname = "add_camera_rigs.build_crane_rig" + bl_label = "Build Crane Camera Rig" + bl_description = "Build a Camera Crane Rig" + bl_options = {'REGISTER', 'UNDO'} + + def execute(self, context): + # build the Widgets + if not "WDGT_Camera_root" in bpy.context.scene.objects: + create_root_widget(self, "Camera_root") + if not "WDGT_Camera" in bpy.context.scene.objects: + create_camera_widget(self, "Camera") + if not "WDGT_Aim" in bpy.context.scene.objects: + create_aim_widget(self, "Aim") + + # call the function to build the rig + build_crane_rig(context) + + return {'FINISHED'} + + +# dolly and crane entries in the Add Object > Camera Menu +def add_dolly_crane_buttons(self, context): + if context.mode == 'OBJECT': + self.layout.operator( + ADD_CAMERA_RIGS_OT_build_dolly_rig.bl_idname, + text="Dolly Camera Rig", + icon='CAMERA_DATA' + ) + self.layout.operator( + ADD_CAMERA_RIGS_OT_build_crane_rig.bl_idname, + text="Crane Camera Rig", + icon='CAMERA_DATA' + ) + + +classes = ( + ADD_CAMERA_RIGS_OT_build_dolly_rig, + ADD_CAMERA_RIGS_OT_build_crane_rig, +) + + +def register(): + from bpy.utils import register_class + for cls in classes: + register_class(cls) + + bpy.types.VIEW3D_MT_camera_add.append(add_dolly_crane_buttons) + + +def unregister(): + from bpy.utils import unregister_class + for cls in classes: + unregister_class(cls) + + bpy.types.VIEW3D_MT_camera_add.remove(add_dolly_crane_buttons) + + +if __name__ == "__main__": + register() diff --git a/add_camera_rigs/composition_guides_menu.py b/add_camera_rigs/composition_guides_menu.py new file mode 100644 index 00000000..7ce8dc27 --- /dev/null +++ b/add_camera_rigs/composition_guides_menu.py @@ -0,0 +1,41 @@ +import bpy +from bpy.types import Menu + + +class ADD_CAMERA_RIGS_MT_composition_guides_menu(Menu): + bl_label = "Composition Guides" + bl_idname = "ADD_CAMERA_RIGS_MT_composition_guides_menu" + + def draw(self, context): + layout = self.layout + + activeCameraName = bpy.context.active_object.children[0].name + cam = bpy.data.cameras[bpy.data.objects[activeCameraName].data.name] + + layout.prop(cam, "show_safe_areas") + layout.row().separator() + layout.prop(cam, "show_composition_center") + layout.prop(cam, "show_composition_center_diagonal") + layout.prop(cam, "show_composition_golden") + layout.prop(cam, "show_composition_golden_tria_a") + layout.prop(cam, "show_composition_golden_tria_b") + layout.prop(cam, "show_composition_harmony_tri_a") + layout.prop(cam, "show_composition_harmony_tri_b") + layout.prop(cam, "show_composition_thirds") + + +def draw_item(self, context): + layout = self.layout + layout.menu(CustomMenu.bl_idname) + + +def register(): + bpy.utils.register_class(ADD_CAMERA_RIGS_MT_composition_guides_menu) + + +def unregister(): + bpy.utils.unregister_class(ADD_CAMERA_RIGS_MT_composition_guides_menu) + + +if __name__ == "__main__": + register() diff --git a/add_camera_rigs/create_widgets.py b/add_camera_rigs/create_widgets.py new file mode 100644 index 00000000..788a868d --- /dev/null +++ b/add_camera_rigs/create_widgets.py @@ -0,0 +1,241 @@ +import bpy + + +def create_widget(self, name): + """ Creates an empty widget object and returns the object.""" + widget_prefix = bpy.context.preferences.addons["add_camera_rigs"].preferences.widget_prefix + obj_name = widget_prefix + name + scene = bpy.context.scene + + mesh = bpy.data.meshes.new(obj_name) + obj = bpy.data.objects.new(obj_name, mesh) + + # create a new collection for the wigets + collection_name = bpy.context.preferences.addons["add_camera_rigs"].preferences.camera_widget_collection_name + c = bpy.data.collections.get(collection_name) + if c is not None: + c.objects.link(obj) + else: + c = bpy.data.collections.new(collection_name) + c.hide_viewport = True + c.hide_render = True + + # link the collection + scene.collection.children.link(c) + c.objects.link(obj) + + return obj + + +def create_root_widget(self, name): + # Creates a compass-shaped widget + obj = create_widget(self, name) + if obj is not None: + verts = [(0.210255, 0.209045, 0), (0.113789, 0.273501, -2.98023e-08), + (-3.07015e-08, 0.296135, 0), (-0.113789, 0.273501, 0), + (-0.210255, 0.209045, 0), (-0.274712, 0.112579, 7.45058e-09), + (-0.297346, -0.00121052, 1.48165e-08), (0.297346, -0.00121046, -1.49858e-08), + (0.274711, 0.112579, 7.45058e-09), (0.071529, 0.505864, 0), + (-0.0715289, 0.505864, 0), (-0.071529, 0.379091, 2.98023e-08), + (0.071529, 0.379091, 0), (-0.132587, 0.505864, 0), + (0.132587, 0.505864, 0), (-3.07015e-08, 0.667601, 1.19209e-07), + (-0.274712, -0.115, 2.23517e-08), (0.274712, -0.115, -7.45058e-09), + (0.210255, -0.211466, 0), (0.113789, -0.275922, 0), + (-9.03062e-08, -0.298556, 0), (-0.113789, -0.275922, 2.98023e-08), + (-0.210255, -0.211466, 0), (-0.668811, -0.00121029, 4.46188e-08), + (-0.507075, 0.131377, 4.47035e-08), (-0.507075, -0.133798, -1.49012e-08), + (-0.380301, 0.0703187, 1.49012e-08), (-0.380301, -0.0727393, 1.49012e-08), + (-0.507075, -0.0727393, -1.49012e-08), (-0.507075, 0.0703187, 4.47035e-08), + (0.507075, -0.0727393, -1.49012e-08), (0.507075, 0.0703187, -1.49012e-08), + (0.380301, 0.0703187, 1.49012e-08), (0.380301, -0.0727393, -1.49012e-08), + (0.507075, 0.131377, -1.49012e-08), (0.507075, -0.133798, -1.49012e-08), + (0.668811, -0.0012103, -1.49858e-08), (1.48112e-07, -0.670021, 0), + (-0.132587, -0.508285, 0), (0.132587, -0.508285, 0), + (-0.0715289, -0.381512, 2.98023e-08), (0.0715291, -0.381512, -2.98023e-08), + (0.0715291, -0.508285, 0), (-0.0715289, -0.508285, 0), + ] + + edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (7, 8), (0, 8), (10, 11), (9, 12), + (11, 12), (10, 13), (9, 14), (13, 15), (14, 15), (16, + 22), (17, 18), (18, 19), (19, 20), (20, 21), + (21, 22), (7, 17), (6, 16), (23, 24), (23, 25), (24, + 29), (25, 28), (26, 27), (26, 29), (27, 28), + (31, 32), (30, 33), (32, 33), (31, 34), (30, 35), (34, + 36), (35, 36), (37, 38), (37, 39), (38, 43), + (39, 42), (40, 41), (40, 43), (41, 42), ] + + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, []) + mesh.update() + + +def create_camera_widget(self, name): + # Creates a camera ctrl widget + + obj = create_widget(self, name) + if obj != None: + verts = [(0.13756819069385529, 1.0706068032106941e-08, -0.13756819069385529), + (0.1797415018081665, 5.353034016053471e-09, -0.07445136457681656), + (0.19455081224441528, -6.381313819948996e-16, 8.504085435845354e-09), + (0.1797415018081665, -5.353034016053471e-09, 0.07445138692855835), + (0.13756819069385529, -1.0706068032106941e-08, 0.13756819069385529), + (0.07445137947797775, -2.1412136064213882e-08, 0.1797415018081665), + (-9.740904971522468e-08, -2.1412136064213882e-08, 0.19455081224441528), + (-5.87527146933553e-08, 2.1412136064213882e-08, -0.19455081224441528), + (0.0744515135884285, 2.1412136064213882e-08, -0.17974145710468292), + (0.3317747414112091, 5.353034016053471e-09, -0.04680081456899643), + (0.3317747414112091, -5.353034016053471e-09, 0.04680081456899643), + (0.24882805347442627, -5.353034016053471e-09, 0.04680081456899643), + (0.24882805347442627, 5.353034016053471e-09, -0.04680084437131882), + (0.3317747414112091, -5.353034016053471e-09, 0.08675074577331543), + (0.3317747414112091, 5.353034016053471e-09, -0.08675074577331543), + (0.43759751319885254, 0.0, 0.0), (-0.07445148378610611, - + 2.1412136064213882e-08, 0.17974145710468292), + (-0.07445141673088074, 2.1412136064213882e-08, -0.1797415018081665), + (-0.13756820559501648, 1.0706068032106941e-08, -0.1375681608915329), + (-0.1797415018081665, 5.353034016053471e-09, -0.07445136457681656), + (-0.19455081224441528, -1.2762627639897992e-15, 2.0872269246297037e-08), + (-0.1797415018081665, -5.353034016053471e-09, 0.07445140182971954), + (-0.1375681608915329, -1.0706068032106941e-08, 0.13756820559501648), + (5.1712785165136665e-08, -4.2824272128427765e-08, 0.43759751319885254), + (0.08675077557563782, -2.1412136064213882e-08, 0.3317747414112091), + (-0.08675073087215424, -2.1412136064213882e-08, 0.3317747414112091), + (0.046800870448350906, -2.1412136064213882e-08, 0.24882805347442627), + (-0.04680079594254494, -2.1412136064213882e-08, 0.24882805347442627), + (-0.04680079594254494, -2.1412136064213882e-08, 0.3317747414112091), + (0.04680084437131882, -2.1412136064213882e-08, 0.3317747414112091), + (-0.04680076241493225, 2.1412136064213882e-08, -0.3317747414112091), + (0.046800874173641205, 2.1412136064213882e-08, -0.3317747414112091), + (0.04680086299777031, 2.1412136064213882e-08, -0.24882805347442627), + (-0.046800799667835236, 2.1412136064213882e-08, -0.24882805347442627), + (0.0867508053779602, 2.1412136064213882e-08, -0.3317747414112091), + (-0.08675070106983185, 2.1412136064213882e-08, -0.3317747414112091), + (4.711345980012993e-08, 4.2824272128427765e-08, -0.43759751319885254), + (-0.43759751319885254, 1.0210102111918393e-14, -9.882624141255292e-08), + (-0.3317747414112091, -5.353034016053471e-09, 0.08675065636634827), + (-0.3317747414112091, 5.353034016053471e-09, -0.08675083518028259), + (-0.24882805347442627, -5.353034016053471e-09, 0.04680076986551285), + (-0.24882805347442627, 5.353034016053471e-09, -0.0468008853495121), + (-0.3317747414112091, 5.353034016053471e-09, -0.046800896525382996), + (-0.3317747414112091, -5.353034016053471e-09, 0.04680073633790016), + (-0.08263588696718216, -7.0564780685344886e-09, 0.08263592422008514), + (-0.10796899348497391, -3.5282390342672443e-09, 0.04472224414348602), + (-0.11686481535434723, -8.411977372806655e-16, 1.2537773486087644e-08), + (-0.10796899348497391, 3.5282390342672443e-09, -0.04472222551703453), + (-0.08263592422008514, 7.0564780685344886e-09, -0.08263588696718216), + (-0.04472225159406662, 7.0564780685344886e-09, -0.10796899348497391), + (-0.0447222925722599, -7.0564780685344886e-09, 0.10796897858381271), + (0.0447223074734211, 7.0564780685344886e-09, -0.10796897858381271), + (-3.529219583242593e-08, 7.0564780685344886e-09, -0.11686481535434723), + (-5.8512675593647145e-08, -7.0564780685344886e-09, 0.11686481535434723), + (0.04472222924232483, -7.0564780685344886e-09, 0.10796899348497391), + (0.08263590186834335, -7.0564780685344886e-09, 0.08263590186834335), + (0.10796899348497391, -3.5282390342672443e-09, 0.04472223296761513), + (0.11686481535434723, -4.2059886864033273e-16, 5.108323541946902e-09), + (0.10796899348497391, 3.5282390342672443e-09, -0.04472222924232483), + (0.08263590186834335, 7.0564780685344886e-09, -0.08263590186834335), + (3.725290298461914e-08, -2.1412136064213882e-08, 0.24882805347442627)] + + edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (7, 8), (0, 8), + (10, 11), (9, 12), (11, 12), (10, 13), (9, 14), (13, 15), (14, 15), (16, 22), + (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (7, 17), (6, 16), (23, 24), + (23, 25), (24, 29), (25, 28), (26, 29), (27, 28), (31, 32), (30, 33), (32, 33), + (31, 34), (30, 35), (34, 36), (35, 36), (37, 38), (37, 39), (38, 43), (39, 42), + (40, 41), (40, 43), (41, 42), (50, 53), (49, 52), (44, 45), (45, 46), (46, 47), + (47, 48), (48, 49), (44, 50), (51, 59), (51, 52), (53, 54), (54, 55), (55, 56), + (56, 57), (57, 58), (58, 59), (26, 60), (27, 60), (23, 60)] + + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, []) + mesh.update() + + +def create_aim_widget(self, name): + # Creates a camera aim widget + + obj = create_widget(self, name) + if obj != None: + verts = [(0.15504144132137299, 1.4901161193847656e-08, 0.15504144132137299), + (0.20257140696048737, 7.450580596923828e-09, 0.0839078277349472), + (0.21926172077655792, -8.881784197001252e-16, -9.584233851001045e-09), + (0.20257140696048737, -7.450580596923828e-09, -0.0839078426361084), + (0.15504144132137299, -1.4901161193847656e-08, -0.15504144132137299), + (0.0839078351855278, -1.4901161193847656e-08, -0.20257140696048737), + (-1.0978147457763043e-07, -1.4901161193847656e-08, -0.21926172077655792), + (-6.621520043381679e-08, 1.4901161193847656e-08, 0.21926172077655792), + (0.08390798419713974, 1.4901161193847656e-08, 0.2025713473558426), + (0.39969685673713684, 3.725290298461914e-09, 0.05274524539709091), + (0.39969685673713684, -3.725290298461914e-09, -0.05274524167180061), + (0.4931790232658386, -3.725290298461914e-09, -0.05274524167180061), + (0.4931790232658386, 3.725290298461914e-09, 0.052745271474123), + (0.39969685673713684, -7.450580596923828e-09, -0.09776943176984787), + (0.39969685673713684, 7.450580596923828e-09, 0.09776943176984787), + (0.28043296933174133, 6.226862126577502e-17, -6.226862788321993e-17), + (-0.08390796184539795, -1.4901161193847656e-08, -0.2025713473558426), + (-0.08390787988901138, 1.4901161193847656e-08, 0.20257140696048737), + (-0.15504147112369537, 1.4901161193847656e-08, 0.1550414115190506), + (-0.20257140696048737, 7.450580596923828e-09, 0.08390782028436661), + (-0.21926172077655792, -1.7763568394002505e-15, -2.352336458955051e-08), + (-0.20257140696048737, -7.450580596923828e-09, -0.08390786498785019), + (-0.1550414115190506, -1.4901161193847656e-08, -0.15504147112369537), + (2.9140544199890428e-08, 2.9802322387695312e-08, 0.2804329991340637), + (-0.09776944667100906, 2.9802322387695312e-08, 0.3996969163417816), + (0.09776947647333145, 2.9802322387695312e-08, 0.3996969163417816), + (-0.052745264023542404, 2.9802322387695312e-08, 0.4931790828704834), + (0.05274529010057449, 2.9802322387695312e-08, 0.4931790828704834), + (0.052745264023542404, 2.9802322387695312e-08, 0.3996969163417816), + (-0.052745234221220016, 2.9802322387695312e-08, 0.3996969163417816), + (0.05274517461657524, -2.9802322387695312e-08, -0.3996969759464264), + (-0.052745334804058075, -2.9802322387695312e-08, -0.3996969759464264), + (-0.05274537205696106, -2.9802322387695312e-08, -0.49317920207977295), + (0.05274519696831703, -2.9802322387695312e-08, -0.49317920207977295), + (-0.09776955097913742, -2.9802322387695312e-08, -0.3996969163417816), + (0.09776940196752548, -2.9802322387695312e-08, -0.39969703555107117), + (-7.148475589247028e-08, -2.9802322387695312e-08, -0.2804329991340637), + (-0.2804330289363861, 3.552713678800501e-15, 4.234420103443881e-08), + (-0.3996969759464264, -7.450580596923828e-09, -0.09776938706636429), + (-0.39969685673713684, 7.450580596923828e-09, 0.09776950627565384), + (-0.4931790232658386, -3.725290298461914e-09, -0.05274520441889763), + (-0.4931790232658386, 3.725290298461914e-09, 0.05274531990289688), + (-0.3996969163417816, 3.725290298461914e-09, 0.052745312452316284), + (-0.3996969163417816, -3.725290298461914e-09, -0.05274519324302673), + (-0.06401804089546204, -7.450580596923828e-09, -0.06401806324720383), + (-0.0836436077952385, -3.725290298461914e-09, -0.03464633598923683), + (-0.09053517132997513, -8.881784197001252e-16, -9.713016169143884e-09), + (-0.0836436077952385, 3.725290298461914e-09, 0.03464631363749504), + (-0.06401806324720383, 7.450580596923828e-09, 0.06401804089546204), + (-0.03464633598923683, 7.450580596923828e-09, 0.0836436077952385), + (-0.034646373242139816, -7.450580596923828e-09, -0.0836435854434967), + (0.03464638441801071, 7.450580596923828e-09, 0.0836435854434967), + (-2.734086912425937e-08, 7.450580596923828e-09, 0.09053517132997513), + (-4.532979147597871e-08, -7.450580596923828e-09, -0.09053517132997513), + (0.034646324813365936, -7.450580596923828e-09, -0.0836436077952385), + (0.06401804834604263, -7.450580596923828e-09, -0.06401804834604263), + (0.0836436077952385, -3.725290298461914e-09, -0.034646324813365936), + (0.09053517132997513, -4.440892098500626e-16, -3.957419281164221e-09), + (0.0836436077952385, 3.725290298461914e-09, 0.03464632108807564), + (0.06401804834604263, 7.450580596923828e-09, 0.06401804834604263), + (1.1175870895385742e-08, 2.9802322387695312e-08, 0.4931790828704834), + (-3.3337176574832483e-08, 2.4835267176115394e-09, 0.030178390443325043), + (-3.9333485801762436e-08, -2.4835271617007493e-09, -0.030178390443325043), + (-0.030178390443325043, -7.40148665436918e-16, -7.794483281031717e-09), + (0.030178390443325043, -5.921189111737107e-16, -5.875951281097969e-09)] + + edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (7, 8), (0, 8), + (10, 11), (9, 12), (11, 12), (10, 13), (9, 14), (13, 15), (14, 15), (16, 22), + (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (7, 17), (6, 16), (23, 24), + (23, 25), (24, 29), (25, 28), (26, 29), (27, 28), (31, 32), (30, 33), (32, 33), + (31, 34), (30, 35), (34, 36), (35, 36), (37, 38), (37, 39), (38, 43), (39, 42), + (40, 41), (40, 43), (41, 42), (50, 53), (49, 52), (44, 45), (45, 46), (46, 47), + (47, 48), (48, 49), (44, 50), (51, 59), (51, 52), (53, 54), (54, 55), (55, 56), + (56, 57), (57, 58), (58, 59), (26, 60), (27, 60), (23, 60), (61, 62), (63, 64)] + + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, []) + mesh.update() diff --git a/add_camera_rigs/operators.py b/add_camera_rigs/operators.py new file mode 100644 index 00000000..fe93041d --- /dev/null +++ b/add_camera_rigs/operators.py @@ -0,0 +1,136 @@ +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 + + if active_cam != scene_cam.name: + bpy.context.scene.camera = bpy.data.objects[active_cam] + else: + return None + + +class ADD_CAMERA_RIGS_OT_set_scene_camera(Operator): + 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() + + return {'FINISHED'} + + +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): + 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'} + + +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) + + +class ADD_CAMERA_RIGS_OT_add_dof_object(Operator): + 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() + + return {'FINISHED'} + + +classes = ( + ADD_CAMERA_RIGS_OT_set_scene_camera, + ADD_CAMERA_RIGS_OT_add_marker_bind, + ADD_CAMERA_RIGS_OT_add_dof_object, +) + + +def register(): + from bpy.utils import register_class + for cls in classes: + register_class(cls) + + +def unregister(): + from bpy.utils import unregister_class + for cls in classes: + unregister_class(cls) diff --git a/add_camera_rigs/prefs.py b/add_camera_rigs/prefs.py new file mode 100644 index 00000000..18c75bc4 --- /dev/null +++ b/add_camera_rigs/prefs.py @@ -0,0 +1,46 @@ +import bpy +from bpy.types import AddonPreferences +from bpy.props import StringProperty + + +class Add_Camera_Rigs_Preferences(AddonPreferences): + bl_idname = 'add_camera_rigs' + + # widget prefix + widget_prefix: StringProperty( + name="Camera Widget prefix", + description="Choose a prefix for the widget objects", + default="WDGT_", + ) + + # collection name + camera_widget_collection_name: StringProperty( + name="Bone Widget collection name", + description="Choose a name for the collection the widgets will appear", + default="WDGTS_camera", + ) + + def draw(self, context): + layout = self.layout + + row = layout.row() + col = row.column() + col.prop(self, "widget_prefix", text="Widget Prefix") + col.prop(self, "camera_widget_collection_name", text="Collection name") + + +classes = ( + Add_Camera_Rigs_Preferences, +) + + +def register(): + from bpy.utils import register_class + for cls in classes: + register_class(cls) + + +def unregister(): + from bpy.utils import unregister_class + for cls in classes: + unregister_class(cls) diff --git a/add_camera_rigs/ui_panels.py b/add_camera_rigs/ui_panels.py new file mode 100644 index 00000000..3356d389 --- /dev/null +++ b/add_camera_rigs/ui_panels.py @@ -0,0 +1,89 @@ +import bpy +from bpy.types import Panel + + +class ADD_CAMERA_RIGS_PT_camera_rig_ui(Panel): + bl_category = 'Create' + bl_label = "Camera Rig UI" + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + + _ACTIVE_OBJECT: object = None + + _ACTIVE_RIG_TYPE: str = None + + @classmethod + def poll(self, context): + self._ACTIVE_OBJECT = bpy.context.active_object + + if self._ACTIVE_OBJECT != None and "rig_id" in self._ACTIVE_OBJECT: + rigType = self._ACTIVE_OBJECT["rig_id"] + + if rigType == "Dolly_rig" or rigType == "Crane_rig": + self._ACTIVE_RIG_TYPE = rigType + return True + + return False + + def draw(self, context): + arm = self._ACTIVE_OBJECT.data + poseBones = self._ACTIVE_OBJECT.pose.bones + activeCameraName = self._ACTIVE_OBJECT.children[0].name + + cam = bpy.data.cameras[bpy.data.objects[activeCameraName].data.name] + + layout = self.layout.box().column() + layout.label(text="Clipping:") + layout.prop(cam, "clip_start", text="Start") + layout.prop(cam, "clip_end", text="End") + layout.prop(cam, "type") + layout.prop(cam.dof, "use_dof") + if cam.dof.use_dof: + if cam.dof.focus_object is None: + layout.operator("add_camera_rigs.add_dof_object", text="Add DOF Empty") + layout.prop(poseBones["Camera"], '["focus_distance"]', text="Focus Distance") + layout.prop(poseBones["Camera"], '["f-stop"]', text="F-Stop") + + layout.prop(self._ACTIVE_OBJECT, 'show_in_front', toggle=False, text='Show in front') + layout.prop(cam, "show_limits") + layout.prop(cam, "show_passepartout") + if cam.show_passepartout: + layout.prop(cam, "passepartout_alpha") + + layout.row().separator() + # added the comp guides here + layout.operator( + "wm.call_menu", text="Composition Guides").name = "ADD_CAMERA_RIGS_MT_composition_guides_menu" + layout.row().separator() + + layout.prop(bpy.data.objects[activeCameraName], + "hide_select", text="Make Camera Unselectable") + + layout.operator("add_camera_rigs.add_marker_bind", + text="Add Marker and Bind") + if bpy.context.scene.camera.name != activeCameraName: + layout.operator("add_camera_rigs.set_scene_camera", + text="Make Camera Active", icon='CAMERA_DATA') + # Camera Lens + layout.label(text="Focal Length:") + layout.prop(poseBones["Camera"], '["focal_length"]', text="Focal Length (mm)") + + if self._ACTIVE_RIG_TYPE == "Crane_rig": + layout = layout.box().column() + + # Crane arm stuff + layout.label(text="Crane Arm:") + layout.prop(poseBones["Crane_height"], 'scale', index=1, text="Arm Height") + layout.prop(poseBones["Crane_arm"], 'scale', index=1, text="Arm Length") + + # Track to Constraint + layout.label(text="Tracking:") + layout.prop(poseBones["Camera"], '["lock"]', text="Aim Lock", slider=True) + + +def register(): + bpy.utils.register_class(ADD_CAMERA_RIGS_PT_camera_rig_ui) + + +def unregister(): + bpy.utils.unregister_class(ADD_CAMERA_RIGS_PT_camera_rig_ui) |