diff options
Diffstat (limited to 'release/scripts/startup/bl_operators/object_align.py')
-rw-r--r-- | release/scripts/startup/bl_operators/object_align.py | 201 |
1 files changed, 153 insertions, 48 deletions
diff --git a/release/scripts/startup/bl_operators/object_align.py b/release/scripts/startup/bl_operators/object_align.py index 3202a717001..d215f3476cf 100644 --- a/release/scripts/startup/bl_operators/object_align.py +++ b/release/scripts/startup/bl_operators/object_align.py @@ -21,13 +21,102 @@ import bpy from mathutils import Vector - -def align_objects(align_x, align_y, align_z, align_mode, relative_to): +def GlobalBB_LQ(bb_world): + + # Initialize the variables with the 8th vertex + left, right, front, back, down, up =\ + bb_world[7][0],\ + bb_world[7][0],\ + bb_world[7][1],\ + bb_world[7][1],\ + bb_world[7][2],\ + bb_world[7][2] + + # Test against the other 7 verts + for i in range (7): + + # X Range + val = bb_world[i][0] + if val < left: + left = val + + if val > right: + right = val + + # Y Range + val = bb_world[i][1] + if val < front: + front = val + + if val > back: + back = val + + # Z Range + val = bb_world[i][2] + if val < down: + down = val + + if val > up: + up = val + + return (Vector((left, front, up)), Vector((right, back, down))) + +def GlobalBB_HQ(obj): + + matrix_world = obj.matrix_world.copy() + + # Initialize the variables with the last vertex + + verts = obj.data.vertices + + val = verts[-1].co * matrix_world + + left, right, front, back, down, up =\ + val[0],\ + val[0],\ + val[1],\ + val[1],\ + val[2],\ + val[2] + + # Test against all other verts + for i in range (len(verts)-1): + + vco = verts[i].co * matrix_world + + # X Range + val = vco[0] + if val < left: + left = val + + if val > right: + right = val + + # Y Range + val = vco[1] + if val < front: + front = val + + if val > back: + back = val + + # Z Range + val = vco[2] + if val < down: + down = val + + if val > up: + up = val + + return (Vector((left, front, up)), Vector((right, back, down))) + + +def align_objects(align_x, align_y, align_z, align_mode, relative_to, bb_quality): 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] + Left_Front_Up_SEL = [0.0, 0.0, 0.0] + Right_Back_Down_SEL = [0.0, 0.0, 0.0] flag_first = True @@ -42,78 +131,89 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to): return False for obj, bb_world in objs: - Left_Up_Front = bb_world[1] - Right_Down_Back = bb_world[7] + + if bb_quality: + GBB = GlobalBB_HQ(obj) + else: + GBB = GlobalBB_LQ(bb_world) + + Left_Front_Up = GBB[0] + Right_Back_Down = GBB[1] # 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 + 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 + center_active_z = (Left_Front_Up[2] + Right_Back_Down[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 + size_active_x = (Right_Back_Down[0] - Left_Front_Up[0]) / 2.0 + size_active_y = (Right_Back_Down[1] - Left_Front_Up[1]) / 2.0 + size_active_z = (Left_Front_Up[2] - Right_Back_Down[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] + Left_Front_Up_SEL[0] = Left_Front_Up[0] + Left_Front_Up_SEL[1] = Left_Front_Up[1] + Left_Front_Up_SEL[2] = Left_Front_Up[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] + Right_Back_Down_SEL[0] = Right_Back_Down[0] + Right_Back_Down_SEL[1] = Right_Back_Down[1] + Right_Back_Down_SEL[2] = Right_Back_Down[2] else: # X axis - if Left_Up_Front[0] < Left_Up_Front_SEL[0]: - Left_Up_Front_SEL[0] = Left_Up_Front[0] + if Left_Front_Up[0] < Left_Front_Up_SEL[0]: + Left_Front_Up_SEL[0] = Left_Front_Up[0] # Y axis - if Left_Up_Front[1] < Left_Up_Front_SEL[1]: - Left_Up_Front_SEL[1] = Left_Up_Front[1] + if Left_Front_Up[1] < Left_Front_Up_SEL[1]: + Left_Front_Up_SEL[1] = Left_Front_Up[1] # Z axis - if Left_Up_Front[2] > Left_Up_Front_SEL[2]: - Left_Up_Front_SEL[2] = Left_Up_Front[2] + if Left_Front_Up[2] > Left_Front_Up_SEL[2]: + Left_Front_Up_SEL[2] = Left_Front_Up[2] # X axis - if Right_Down_Back[0] > Right_Down_Back_SEL[0]: - Right_Down_Back_SEL[0] = Right_Down_Back[0] + if Right_Back_Down[0] > Right_Back_Down_SEL[0]: + Right_Back_Down_SEL[0] = Right_Back_Down[0] # Y axis - if Right_Down_Back[1] > Right_Down_Back_SEL[1]: - Right_Down_Back_SEL[1] = Right_Down_Back[1] + if Right_Back_Down[1] > Right_Back_Down_SEL[1]: + Right_Back_Down_SEL[1] = Right_Back_Down[1] # Z axis - if Right_Down_Back[2] < Right_Down_Back_SEL[2]: - Right_Down_Back_SEL[2] = Right_Down_Back[2] + if Right_Back_Down[2] < Right_Back_Down_SEL[2]: + Right_Back_Down_SEL[2] = Right_Back_Down[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 + center_sel_x = (Left_Front_Up_SEL[0] + Right_Back_Down_SEL[0]) / 2.0 + center_sel_y = (Left_Front_Up_SEL[1] + Right_Back_Down_SEL[1]) / 2.0 + center_sel_z = (Left_Front_Up_SEL[2] + Right_Back_Down_SEL[2]) / 2.0 # Main Loop for obj, bb_world in objs: bb_world = [Vector(v[:]) * obj.matrix_world for v in obj.bound_box] + + if bb_quality: + GBB = GlobalBB_HQ(obj) + else: + GBB = GlobalBB_LQ(bb_world) + + Left_Front_Up = GBB[0] + Right_Back_Down = GBB[1] - 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 + center_x = (Left_Front_Up[0] + Right_Back_Down[0]) / 2.0 + center_y = (Left_Front_Up[1] + Right_Back_Down[1]) / 2.0 + center_z = (Left_Front_Up[2] + Right_Back_Down[2]) / 2.0 - positive_x = Right_Down_Back[0] - positive_y = Right_Down_Back[1] - positive_z = Left_Up_Front[2] + positive_x = Right_Back_Down[0] + positive_y = Right_Back_Down[1] + positive_z = Left_Front_Up[2] - negative_x = Left_Up_Front[0] - negative_y = Left_Up_Front[1] - negative_z = Right_Down_Back[2] + negative_x = Left_Front_Up[0] + negative_y = Left_Front_Up[1] + negative_z = Right_Back_Down[2] obj_loc = obj.location @@ -228,7 +328,7 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to): return True -from bpy.props import EnumProperty +from bpy.props import EnumProperty, BoolProperty class AlignObjects(bpy.types.Operator): @@ -237,6 +337,11 @@ class AlignObjects(bpy.types.Operator): bl_label = "Align Objects" bl_options = {'REGISTER', 'UNDO'} + bb_quality = BoolProperty( + name="High Quality", + description="Enables high quality calculation of the bounding box for perfect results on complex shape meshes with rotation/scale (Slow)", + default=False) + align_mode = EnumProperty(items=( ('OPT_1', "Negative Sides", ""), ('OPT_2', "Centers", ""), @@ -269,10 +374,10 @@ class AlignObjects(bpy.types.Operator): 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) + ret = align_objects('X' in align_axis, 'Y' in align_axis, 'Z' in align_axis, self.align_mode, self.relative_to, self.bb_quality) if not ret: self.report({'WARNING'}, "No objects with bound-box selected") return {'CANCELLED'} else: - return {'FINISHED'} + return {'FINISHED'}
\ No newline at end of file |