diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-03-21 15:35:49 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-03-21 15:35:49 +0300 |
commit | 2e6a02438e997f1024f3ba6c332314f09f01a3b4 (patch) | |
tree | 7b9427c972858a2b0950b0328bb500f11294161b /release/scripts/startup/bl_operators/object_align.py | |
parent | 28d39473fc65543cbf3adc44964d4a9703d3076a (diff) |
move script directories for internal blender scripts.
ui/ --> startup/bl_ui
op/ --> startup/bl_operators
scripts/startup/ is now the only auto-loading script dir which gives some speedup for blender loading too.
~/.blender/2.56/scripts/startup works for auto-loading scripts too.
Diffstat (limited to 'release/scripts/startup/bl_operators/object_align.py')
-rw-r--r-- | release/scripts/startup/bl_operators/object_align.py | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/release/scripts/startup/bl_operators/object_align.py b/release/scripts/startup/bl_operators/object_align.py new file mode 100644 index 00000000000..644f30a4745 --- /dev/null +++ b/release/scripts/startup/bl_operators/object_align.py @@ -0,0 +1,280 @@ +# ##### 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 compliant> + +import bpy +from mathutils import Vector + + +def align_objects(align_x, align_y, align_z, align_mode, relative_to): + + cursor = bpy.context.scene.cursor_location + + Left_Up_Front_SEL = [0.0, 0.0, 0.0] + Right_Down_Back_SEL = [0.0, 0.0, 0.0] + + flag_first = True + + objs = [] + + for obj in bpy.context.selected_objects: + matrix_world = obj.matrix_world + bb_world = [Vector(v[:]) * matrix_world for v in obj.bound_box] + objs.append((obj, bb_world)) + + if not objs: + return False + + for obj, bb_world in objs: + Left_Up_Front = bb_world[1] + Right_Down_Back = bb_world[7] + + # Active Center + + if obj == bpy.context.active_object: + + center_active_x = (Left_Up_Front[0] + Right_Down_Back[0]) / 2.0 + center_active_y = (Left_Up_Front[1] + Right_Down_Back[1]) / 2.0 + center_active_z = (Left_Up_Front[2] + Right_Down_Back[2]) / 2.0 + + size_active_x = (Right_Down_Back[0] - Left_Up_Front[0]) / 2.0 + size_active_y = (Right_Down_Back[1] - Left_Up_Front[1]) / 2.0 + size_active_z = (Left_Up_Front[2] - Right_Down_Back[2]) / 2.0 + + # Selection Center + + if flag_first: + flag_first = False + + Left_Up_Front_SEL[0] = Left_Up_Front[0] + Left_Up_Front_SEL[1] = Left_Up_Front[1] + Left_Up_Front_SEL[2] = Left_Up_Front[2] + + Right_Down_Back_SEL[0] = Right_Down_Back[0] + Right_Down_Back_SEL[1] = Right_Down_Back[1] + Right_Down_Back_SEL[2] = Right_Down_Back[2] + + else: + # X axis + if Left_Up_Front[0] < Left_Up_Front_SEL[0]: + Left_Up_Front_SEL[0] = Left_Up_Front[0] + # Y axis + if Left_Up_Front[1] < Left_Up_Front_SEL[1]: + Left_Up_Front_SEL[1] = Left_Up_Front[1] + # Z axis + if Left_Up_Front[2] > Left_Up_Front_SEL[2]: + Left_Up_Front_SEL[2] = Left_Up_Front[2] + + # X axis + if Right_Down_Back[0] > Right_Down_Back_SEL[0]: + Right_Down_Back_SEL[0] = Right_Down_Back[0] + # Y axis + if Right_Down_Back[1] > Right_Down_Back_SEL[1]: + Right_Down_Back_SEL[1] = Right_Down_Back[1] + # Z axis + if Right_Down_Back[2] < Right_Down_Back_SEL[2]: + Right_Down_Back_SEL[2] = Right_Down_Back[2] + + center_sel_x = (Left_Up_Front_SEL[0] + Right_Down_Back_SEL[0]) / 2.0 + center_sel_y = (Left_Up_Front_SEL[1] + Right_Down_Back_SEL[1]) / 2.0 + center_sel_z = (Left_Up_Front_SEL[2] + Right_Down_Back_SEL[2]) / 2.0 + + # Main Loop + + for obj, bb_world in objs: + + loc_world = obj.location + bb_world = [Vector(v[:]) * obj.matrix_world for v in obj.bound_box] + + Left_Up_Front = bb_world[1] + Right_Down_Back = bb_world[7] + + center_x = (Left_Up_Front[0] + Right_Down_Back[0]) / 2.0 + center_y = (Left_Up_Front[1] + Right_Down_Back[1]) / 2.0 + center_z = (Left_Up_Front[2] + Right_Down_Back[2]) / 2.0 + + positive_x = Right_Down_Back[0] + positive_y = Right_Down_Back[1] + positive_z = Left_Up_Front[2] + + negative_x = Left_Up_Front[0] + negative_y = Left_Up_Front[1] + negative_z = Right_Down_Back[2] + + obj_loc = obj.location + + if align_x: + + # Align Mode + + if relative_to == 'OPT_4': # Active relative + if align_mode == 'OPT_1': + obj_x = obj_loc[0] - negative_x - size_active_x + + elif align_mode == 'OPT_3': + obj_x = obj_loc[0] - positive_x + size_active_x + + else: # Everything else relative + if align_mode == 'OPT_1': + obj_x = obj_loc[0] - negative_x + + elif align_mode == 'OPT_3': + obj_x = obj_loc[0] - positive_x + + if align_mode == 'OPT_2': # All relative + obj_x = obj_loc[0] - center_x + + # Relative To + + if relative_to == 'OPT_1': + loc_x = obj_x + + elif relative_to == 'OPT_2': + loc_x = obj_x + cursor[0] + + elif relative_to == 'OPT_3': + loc_x = obj_x + center_sel_x + + elif relative_to == 'OPT_4': + loc_x = obj_x + center_active_x + + obj.location[0] = loc_x + + if align_y: + # Align Mode + + if relative_to == 'OPT_4': # Active relative + if align_mode == 'OPT_1': + obj_y = obj_loc[1] - negative_y - size_active_y + + elif align_mode == 'OPT_3': + obj_y = obj_loc[1] - positive_y + size_active_y + + else: # Everything else relative + if align_mode == 'OPT_1': + obj_y = obj_loc[1] - negative_y + + elif align_mode == 'OPT_3': + obj_y = obj_loc[1] - positive_y + + if align_mode == 'OPT_2': # All relative + obj_y = obj_loc[1] - center_y + + # Relative To + + if relative_to == 'OPT_1': + loc_y = obj_y + + elif relative_to == 'OPT_2': + loc_y = obj_y + cursor[1] + + elif relative_to == 'OPT_3': + loc_y = obj_y + center_sel_y + + elif relative_to == 'OPT_4': + loc_y = obj_y + center_active_y + + obj.location[1] = loc_y + + if align_z: + # Align Mode + if relative_to == 'OPT_4': # Active relative + if align_mode == 'OPT_1': + obj_z = obj_loc[2] - negative_z - size_active_z + + elif align_mode == 'OPT_3': + obj_z = obj_loc[2] - positive_z + size_active_z + + else: # Everything else relative + if align_mode == 'OPT_1': + obj_z = obj_loc[2] - negative_z + + elif align_mode == 'OPT_3': + obj_z = obj_loc[2] - positive_z + + if align_mode == 'OPT_2': # All relative + obj_z = obj_loc[2] - center_z + + # Relative To + + if relative_to == 'OPT_1': + loc_z = obj_z + + elif relative_to == 'OPT_2': + loc_z = obj_z + cursor[2] + + elif relative_to == 'OPT_3': + loc_z = obj_z + center_sel_z + + elif relative_to == 'OPT_4': + loc_z = obj_z + center_active_z + + obj.location[2] = loc_z + + return True + + +from bpy.props import EnumProperty + + +class AlignObjects(bpy.types.Operator): + '''Align Objects''' + bl_idname = "object.align" + bl_label = "Align Objects" + bl_options = {'REGISTER', 'UNDO'} + + align_mode = EnumProperty(items=( + ('OPT_1', "Negative Sides", ""), + ('OPT_2', "Centers", ""), + ('OPT_3', "Positive Sides", "")), + name="Align Mode:", + description="", + default='OPT_2') + + relative_to = EnumProperty(items=( + ('OPT_1', "Scene Origin", ""), + ('OPT_2', "3D Cursor", ""), + ('OPT_3', "Selection", ""), + ('OPT_4', "Active", "")), + name="Relative To:", + description="", + default='OPT_4') + + align_axis = EnumProperty(items=( + ('X', "X", ""), + ('Y', "Y", ""), + ('Z', "Z", ""), + ), + name="Align", + description="Align to axis", + options={'ENUM_FLAG'}) + + @classmethod + def poll(cls, context): + return context.mode == 'OBJECT' + + def execute(self, context): + align_axis = self.align_axis + ret = align_objects('X' in align_axis, 'Y' in align_axis, 'Z' in align_axis, self.align_mode, self.relative_to) + + if not ret: + self.report({'WARNING'}, "No objects with bound-box selected") + return {'CANCELLED'} + else: + return {'FINISHED'} |