diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-01-27 03:49:13 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-01-27 03:49:13 +0400 |
commit | 556912792ad3c37c294256a558c96b39f264e7b5 (patch) | |
tree | 9b6ee8cf1ad92ee89c04f27a89be11599c5b40c0 /release/scripts/startup/bl_operators | |
parent | 9251d628db0abe599d927d79170025d8545c8ace (diff) | |
parent | c84383301c5a2582e95259a7e4468a23a3566401 (diff) |
Merged changes in the trunk up to revision 54110.
Conflicts resolved:
source/blender/blenfont/SConscript
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/intern/rna_scene.c
Diffstat (limited to 'release/scripts/startup/bl_operators')
11 files changed, 317 insertions, 61 deletions
diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py index c12b0b00f54..64851a3a4c1 100644 --- a/release/scripts/startup/bl_operators/__init__.py +++ b/release/scripts/startup/bl_operators/__init__.py @@ -35,6 +35,7 @@ _modules = [ "object_randomize_transform", "object_quick_effects", "presets", + "rigidbody", "screen_play_rendered_anim", "sequencer", "uvcalc_follow_active", diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py index 39e00f94953..bc0224db765 100644 --- a/release/scripts/startup/bl_operators/node.py +++ b/release/scripts/startup/bl_operators/node.py @@ -22,6 +22,7 @@ import bpy from bpy.types import Operator from bpy.props import BoolProperty, EnumProperty, StringProperty + # Base class for node 'Add' operators class NodeAddOperator(): @staticmethod @@ -78,8 +79,9 @@ class NODE_OT_add_node(NodeAddOperator, Operator): use_transform = BoolProperty( name="Use Transform", description="Start transform operator after inserting the node", - default = False, + default=False, ) + def execute(self, context): node = self.create_node(context, self.type) diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index 9e449f325d6..567ea830409 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -110,6 +110,12 @@ class SelectCamera(Operator): bl_label = "Select Camera" bl_options = {'REGISTER', 'UNDO'} + extend = BoolProperty( + name="Extend", + description="Extend the selection", + default=False + ) + def execute(self, context): scene = context.scene view = context.space_data @@ -123,6 +129,8 @@ class SelectCamera(Operator): elif camera.name not in scene.objects: self.report({'WARNING'}, "Active camera is not in this scene") else: + if not self.extend: + bpy.ops.object.select_all(action='DESELECT') context.scene.objects.active = camera camera.select = True return {'FINISHED'} @@ -297,7 +305,7 @@ class ShapeTransfer(Operator): ('RELATIVE_EDGE', "Relative Edge", "Calculate relative position (using edges)", - ), + ), ), name="Transformation Mode", description="Relative shape positions to the new shape method", @@ -674,7 +682,7 @@ class TransformsToDeltasAnim(Operator): "scale" : "delta_scale" } DELTA_PATHS = STANDARD_TO_DELTA_PATHS.values() - + # try to apply on each selected object success = False for obj in context.selected_editable_objects: @@ -684,7 +692,7 @@ class TransformsToDeltasAnim(Operator): "No animation data to convert on object: %r" % obj.name) continue - + # first pass over F-Curves: ensure that we don't have conflicting # transforms already (e.g. if this was applied already) [#29110] existingFCurves = {} @@ -700,7 +708,7 @@ class TransformsToDeltasAnim(Operator): else: # non-transform - ignore continue - + # a delta path like this for the same index shouldn't # exist already, otherwise we've got a conflict if dpath in existingFCurves: @@ -708,8 +716,9 @@ class TransformsToDeltasAnim(Operator): if fcu.array_index in existingFCurves[dpath]: # conflict self.report({'ERROR'}, - "Object '%r' already has '%r' F-Curve(s). Remove these before trying again" % - (obj.name, dpath)) + "Object '%r' already has '%r' F-Curve(s). " + "Remove these before trying again" % + (obj.name, dpath)) return {'CANCELLED'} else: # no conflict here @@ -717,8 +726,7 @@ class TransformsToDeltasAnim(Operator): else: # no conflict yet existingFCurves[dpath] = [fcu.array_index] - - + # if F-Curve uses standard transform path # just append "delta_" to this path for fcu in adt.action.fcurves: @@ -758,7 +766,7 @@ class DupliOffsetFromCursor(Operator): @classmethod def poll(cls, context): - return context.active_object is not None + return (context.active_object is not None) def execute(self, context): scene = context.scene diff --git a/release/scripts/startup/bl_operators/object_align.py b/release/scripts/startup/bl_operators/object_align.py index a32bb8c5353..dd647733850 100644 --- a/release/scripts/startup/bl_operators/object_align.py +++ b/release/scripts/startup/bl_operators/object_align.py @@ -114,14 +114,15 @@ def GlobalBB_HQ(obj): return Vector((left, front, up)), Vector((right, back, down)) -def align_objects(align_x, +def align_objects(context, + align_x, align_y, align_z, align_mode, relative_to, bb_quality): - cursor = bpy.context.scene.cursor_location + cursor = context.scene.cursor_location Left_Front_Up_SEL = [0.0, 0.0, 0.0] Right_Back_Down_SEL = [0.0, 0.0, 0.0] @@ -130,7 +131,7 @@ def align_objects(align_x, objs = [] - for obj in bpy.context.selected_objects: + for obj in context.selected_objects: matrix_world = obj.matrix_world.copy() bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box] objs.append((obj, bb_world)) @@ -150,7 +151,7 @@ def align_objects(align_x, # Active Center - if obj == bpy.context.active_object: + if obj == context.active_object: center_active_x = (Left_Front_Up[0] + Right_Back_Down[0]) / 2.0 center_active_y = (Left_Front_Up[1] + Right_Back_Down[1]) / 2.0 @@ -386,7 +387,8 @@ class AlignObjects(Operator): def execute(self, context): align_axis = self.align_axis - ret = align_objects('X' in align_axis, + ret = align_objects(context, + 'X' in align_axis, 'Y' in align_axis, 'Z' in align_axis, self.align_mode, diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py index cd0b63a6b78..47012f0c459 100644 --- a/release/scripts/startup/bl_operators/object_quick_effects.py +++ b/release/scripts/startup/bl_operators/object_quick_effects.py @@ -72,7 +72,7 @@ class QuickFur(Operator): ) def execute(self, context): - fake_context = bpy.context.copy() + fake_context = context.copy() mesh_objects = [obj for obj in context.selected_objects if obj.type == 'MESH'] @@ -161,7 +161,7 @@ class QuickExplode(Operator): ) def execute(self, context): - fake_context = bpy.context.copy() + fake_context = context.copy() obj_act = context.active_object if obj_act is None or obj_act.type != 'MESH': @@ -311,7 +311,7 @@ class QuickSmoke(Operator): ) def execute(self, context): - fake_context = bpy.context.copy() + fake_context = context.copy() mesh_objects = [obj for obj in context.selected_objects if obj.type == 'MESH'] min_co = Vector((100000.0, 100000.0, 100000.0)) @@ -432,7 +432,7 @@ class QuickFluid(Operator): ) def execute(self, context): - fake_context = bpy.context.copy() + fake_context = context.copy() mesh_objects = [obj for obj in context.selected_objects if (obj.type == 'MESH' and not 0.0 in obj.dimensions)] min_co = Vector((100000, 100000, 100000)) diff --git a/release/scripts/startup/bl_operators/object_randomize_transform.py b/release/scripts/startup/bl_operators/object_randomize_transform.py index a6efc9dfd85..38110328603 100644 --- a/release/scripts/startup/bl_operators/object_randomize_transform.py +++ b/release/scripts/startup/bl_operators/object_randomize_transform.py @@ -23,7 +23,8 @@ from bpy.types import Operator from mathutils import Vector -def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min): +def randomize_selected(context, seed, delta, + loc, rot, scale, scale_even, scale_min): import random from random import uniform @@ -33,7 +34,7 @@ def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min): def rand_vec(vec_range): return Vector(uniform(-val, val) for val in vec_range) - for obj in bpy.context.selected_objects: + for obj in context.selected_objects: if loc: if delta: @@ -180,6 +181,7 @@ class RandomizeLocRotSize(Operator): #scale_min = self.scale_min scale_min = 0 - randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min) + randomize_selected(context, seed, delta, + loc, rot, scale, scale_even, scale_min) return {'FINISHED'} diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index ee9769d8b43..dac7adecaff 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -320,13 +320,13 @@ class AddPresetFluid(AddPresetBase, Operator): preset_menu = "FLUID_MT_presets" preset_defines = [ - "fluid = bpy.context.fluid" - ] + "fluid = bpy.context.fluid" + ] preset_values = [ - "fluid.settings.viscosity_base", - "fluid.settings.viscosity_exponent", - ] + "fluid.settings.viscosity_base", + "fluid.settings.viscosity_exponent", + ] preset_subdir = "fluid" @@ -477,7 +477,7 @@ class AddPresetNodeColor(AddPresetBase, Operator): class AddPresetInterfaceTheme(AddPresetBase, Operator): """Add a theme preset""" bl_idname = "wm.interface_theme_preset_add" - bl_label = "Add Tracking Settings Preset" + bl_label = "Add Theme Preset" preset_menu = "USERPREF_MT_interface_theme_presets" preset_subdir = "interface_theme" diff --git a/release/scripts/startup/bl_operators/rigidbody.py b/release/scripts/startup/bl_operators/rigidbody.py new file mode 100644 index 00000000000..bad86163932 --- /dev/null +++ b/release/scripts/startup/bl_operators/rigidbody.py @@ -0,0 +1,251 @@ +# ##### 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 ##### + +# <pep8-80 compliant> + +import bpy +from bpy.types import Operator +from bpy.props import IntProperty +from bpy.props import EnumProperty + + +class CopyRigidbodySettings(Operator): + '''Copy Rigid Body settings from active object to selected''' + bl_idname = "rigidbody.object_settings_copy" + bl_label = "Copy Rigidbody Settings" + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body) + + def execute(self, context): + obj = context.object + scn = context.scene + + # deselect all but mesh objects + for o in context.selected_objects: + if o.type != 'MESH': + o.select = False + + sel = context.selected_objects + if sel: + # add selected objects to active one groups and recalculate + bpy.ops.group.objects_add_active() + scn.frame_set(scn.frame_current) + + # copy settings + for o in sel: + if o.rigid_body is None: + continue + + o.rigid_body.type = obj.rigid_body.type + o.rigid_body.kinematic = obj.rigid_body.kinematic + o.rigid_body.mass = obj.rigid_body.mass + o.rigid_body.collision_shape = obj.rigid_body.collision_shape + o.rigid_body.use_margin = obj.rigid_body.use_margin + o.rigid_body.collision_margin = obj.rigid_body.collision_margin + o.rigid_body.friction = obj.rigid_body.friction + o.rigid_body.restitution = obj.rigid_body.restitution + o.rigid_body.use_deactivation = obj.rigid_body.use_deactivation + o.rigid_body.start_deactivated = obj.rigid_body.start_deactivated + o.rigid_body.deactivate_linear_velocity = obj.rigid_body.deactivate_linear_velocity + o.rigid_body.deactivate_angular_velocity = obj.rigid_body.deactivate_angular_velocity + o.rigid_body.linear_damping = obj.rigid_body.linear_damping + o.rigid_body.angular_damping = obj.rigid_body.angular_damping + o.rigid_body.collision_groups = obj.rigid_body.collision_groups + + return {'FINISHED'} + + +class BakeToKeyframes(Operator): + '''Bake rigid body transformations of selected objects to keyframes''' + bl_idname = "rigidbody.bake_to_keyframes" + bl_label = "Bake To Keyframes" + bl_options = {'REGISTER', 'UNDO'} + + frame_start = IntProperty( + name="Start Frame", + description="Start frame for baking", + min=0, max=300000, + default=1, + ) + frame_end = IntProperty( + name="End Frame", + description="End frame for baking", + min=1, max=300000, + default=250, + ) + step = IntProperty( + name="Frame Step", + description="Frame Step", + min=1, max=120, + default=1, + ) + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body) + + def execute(self, context): + bake = [] + objs = [] + scene = context.scene + frame_orig = scene.frame_current + frames = list(range(self.frame_start, self.frame_end + 1, self.step)) + + # filter objects selection + for obj in context.selected_objects: + if not obj.rigid_body or obj.rigid_body.type != 'ACTIVE': + obj.select = False + + objs = context.selected_objects + + if objs: + # store transformation data + for f in list(range(self.frame_start, self.frame_end + 1)): + scene.frame_set(f) + if f in frames: + mat = {} + for i, obj in enumerate(objs): + mat[i] = obj.matrix_world.copy() + bake.append(mat) + + # apply transformations as keyframes + for i, f in enumerate(frames): + scene.frame_set(f) + obj_prev = objs[0] + for j, obj in enumerate(objs): + mat = bake[i][j] + + obj.location = mat.to_translation() + + rot_mode = obj.rotation_mode + if rot_mode == 'QUATERNION': + obj.rotation_quaternion = mat.to_quaternion() + elif rot_mode == 'AXIS_ANGLE': + # this is a little roundabout but there's no better way right now + aa = mat.to_quaternion().to_axis_angle() + obj.rotation_axis_angle = (aa[1], ) + aa[0][:] + else: # euler + # make sure euler rotation is compatible to previous frame + obj.rotation_euler = mat.to_euler(rot_mode, obj_prev.rotation_euler) + + obj_prev = obj + + bpy.ops.anim.keyframe_insert(type='BUILTIN_KSI_LocRot', confirm_success=False) + + # remove baked objects from simulation + bpy.ops.rigidbody.objects_remove() + + # clean up keyframes + for obj in objs: + action = obj.animation_data.action + for fcu in action.fcurves: + keyframe_points = fcu.keyframe_points + i = 1 + # remove unneeded keyframes + while i < len(keyframe_points) - 1: + val_prev = keyframe_points[i - 1].co[1] + val_next = keyframe_points[i + 1].co[1] + val = keyframe_points[i].co[1] + + if abs(val - val_prev) + abs(val - val_next) < 0.0001: + keyframe_points.remove(keyframe_points[i]) + else: + i += 1 + # use linear interpolation for better visual results + for keyframe in keyframe_points: + keyframe.interpolation = 'LINEAR' + + # return to the frame we started on + scene.frame_set(frame_orig) + + return {'FINISHED'} + + def invoke(self, context, event): + scene = context.scene + self.frame_start = scene.frame_start + self.frame_end = scene.frame_end + + wm = context.window_manager + return wm.invoke_props_dialog(self) + + +class ConnectRigidBodies(Operator): + + + '''Connect selected rigid bodies to active''' + bl_idname = "rigidbody.connect" + bl_label = "ConnectRigidBodies" + bl_options = {'REGISTER', 'UNDO'} + + con_type = EnumProperty( + name="Type", + description="Type of generated contraint", + items=(('FIXED', "Fixed", "Glues ridig bodies together"), + ('POINT', "Point", "Constrains rigid bodies to move aound common pivot point"), + ('HINGE', "Hinge", "Restricts rigid body rotation to one axis"), + ('SLIDER', "Slider", "Restricts rigid boddy translation to one axis"), + ('PISTON', "Piston", "Restricts rigid boddy translation and rotation to one axis"), + ('GENERIC', "Generic", "Restricts translation and rotation to specified axes"), + ('GENERIC_SPRING', "Generic Spring", "Restricts translation and rotation to specified axes with springs")), + default='FIXED',) + + pivot_type = EnumProperty( + name="Location", + description="Constraint pivot location", + items=(('CENTER', "Center", "Pivot location is between the constrained rigid bodies"), + ('ACTIVE', "Active", "Pivot location is at the active object position"), + ('SELECTED', "Selected", "Pivot location is at the slected object position")), + default='CENTER',) + + @classmethod + def poll(cls, context): + obj = context.object + objs = context.selected_objects + return (obj and obj.rigid_body and (len(objs) > 1)) + + def execute(self, context): + + objs = context.selected_objects + obj_act = context.active_object + + for obj in objs: + if obj == obj_act: + continue + if self.pivot_type == 'ACTIVE': + loc = obj_act.location + elif self.pivot_type == 'SELECTED': + loc = obj.location + else: + loc = (obj_act.location + obj.location) / 2.0 + bpy.ops.object.add(type='EMPTY', view_align=False, enter_editmode=False, location=loc) + bpy.ops.rigidbody.constraint_add() + con = context.active_object.rigid_body_constraint + con.type = self.con_type + con.object1 = obj_act + con.object2 = obj + + return {'FINISHED'} + + def invoke(self, context, event): + wm = context.window_manager + return wm.invoke_props_dialog(self) diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py index 7b6013f3044..ee3ae2878dc 100644 --- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py +++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py @@ -26,18 +26,18 @@ from bpy.types import Operator def extend(obj, operator, EXTEND_MODE): - + import bmesh me = obj.data # script will fail without UVs if not me.uv_textures: me.uv_textures.new() - + bm = bmesh.from_edit_mesh(me) - + f_act = bm.faces.active uv_act = bm.loops.layers.uv.active - + if f_act is None: operator.report({'ERROR'}, "No active face") return @@ -57,7 +57,7 @@ def extend(obj, operator, EXTEND_MODE): f.tag = False # tag the active face True since we begin there f_act.tag = True - + def walk_face(f): # all faces in this list must be tagged f.tag = True @@ -102,7 +102,6 @@ def extend(obj, operator, EXTEND_MODE): else: break - def extrapolate_uv(fac, l_a_outer, l_a_inner, l_b_outer, l_b_inner): @@ -112,7 +111,7 @@ def extend(obj, operator, EXTEND_MODE): def apply_uv(f_prev, l_prev, f_next): l_a = [None, None, None, None] l_b = [None, None, None, None] - + l_a[0] = l_prev l_a[1] = l_a[0].link_loop_next l_a[2] = l_a[1].link_loop_next @@ -133,7 +132,7 @@ def extend(obj, operator, EXTEND_MODE): # +-----------+ # copy from this face to the one above. - # get the other loops + # get the other loops l_next = l_prev.link_loop_radial_next if l_next.vert != l_prev.vert: l_b[1] = l_next diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py index 198b3660ff8..b24a71365b4 100644 --- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py +++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py @@ -189,14 +189,14 @@ class prettyface(object): def lightmap_uvpack(meshes, - PREF_SEL_ONLY=True, - PREF_NEW_UVLAYER=False, - PREF_PACK_IN_ONE=False, - PREF_APPLY_IMAGE=False, - PREF_IMG_PX_SIZE=512, - PREF_BOX_DIV=8, - PREF_MARGIN_DIV=512 - ): + PREF_SEL_ONLY=True, + PREF_NEW_UVLAYER=False, + PREF_PACK_IN_ONE=False, + PREF_APPLY_IMAGE=False, + PREF_IMG_PX_SIZE=512, + PREF_BOX_DIV=8, + PREF_MARGIN_DIV=512 + ): """ BOX_DIV if the maximum division of the UV map that a box may be consolidated into. @@ -516,7 +516,7 @@ def lightmap_uvpack(meshes, def unwrap(operator, context, **kwargs): - is_editmode = (bpy.context.object.mode == 'EDIT') + is_editmode = (context.object.mode == 'EDIT') if is_editmode: bpy.ops.object.mode_set(mode='OBJECT', toggle=False) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 00cc763c4e1..fa2cb5d5356 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -500,18 +500,16 @@ class WM_MT_context_menu_enum(Menu): def draw(self, context): data_path = self.data_path - value = context_path_validate(bpy.context, data_path) + value = context_path_validate(context, data_path) if value is Ellipsis: return {'PASS_THROUGH'} base_path, prop_string = data_path.rsplit(".", 1) value_base = context_path_validate(context, base_path) + prop = value_base.bl_rna.properties[prop_string] - values = [(i.name, i.identifier) for i in value_base.bl_rna.properties[prop_string].enum_items] - - for name, identifier in values: - props = self.layout.operator("wm.context_set_enum", text=name) - props.data_path = data_path - props.value = identifier + layout = self.layout + layout.label(prop.name, icon=prop.icon) + layout.prop(value_base, prop_string, expand=True) class WM_OT_context_menu_enum(Operator): @@ -1255,13 +1253,6 @@ class WM_OT_copy_prev_settings(Operator): else: shutil.copytree(path_src, path_dst, symlinks=True) - # in 2.57 and earlier windows installers, system scripts were copied - # into the configuration directory, don't want to copy those - system_script = os.path.join(path_dst, "scripts/modules/bpy_types.py") - if os.path.isfile(system_script): - shutil.rmtree(os.path.join(path_dst, "scripts")) - shutil.rmtree(os.path.join(path_dst, "plugins")) - # don't loose users work if they open the splash later. if bpy.data.is_saved is bpy.data.is_dirty is False: bpy.ops.wm.read_homefile() @@ -1596,7 +1587,7 @@ class WM_OT_addon_enable(Operator): "version %d.%d.%d and might not " "function (correctly), " "though it is enabled") % - info_ver) + info_ver) return {'FINISHED'} else: return {'CANCELLED'} @@ -1739,7 +1730,7 @@ class WM_OT_addon_install(Operator): # don't use bpy.utils.script_paths("addons") because we may not be able to write to it. path_addons = bpy.utils.user_resource('SCRIPTS', "addons", create=True) else: - path_addons = bpy.context.user_preferences.filepaths.script_directory + path_addons = context.user_preferences.filepaths.script_directory if path_addons: path_addons = os.path.join(path_addons, "addons") |