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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/startup/bl_operators/object_align.py')
-rw-r--r--release/scripts/startup/bl_operators/object_align.py218
1 files changed, 168 insertions, 50 deletions
diff --git a/release/scripts/startup/bl_operators/object_align.py b/release/scripts/startup/bl_operators/object_align.py
index 644f30a4745..7fd769c40c9 100644
--- a/release/scripts/startup/bl_operators/object_align.py
+++ b/release/scripts/startup/bl_operators/object_align.py
@@ -16,106 +16,212 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
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 = matrix_world * verts[-1].co
+
+ 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 = matrix_world * verts[i].co
+
+ # 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
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]
+ matrix_world = obj.matrix_world.copy()
+ bb_world = [matrix_world * Vector(v[:]) 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]
+
+ 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:
+ matrix_world = obj.matrix_world.copy()
+ bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box]
- loc_world = obj.location
- 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_Up_Front = bb_world[1]
- Right_Down_Back = bb_world[7]
+ Left_Front_Up = GBB[0]
+ Right_Back_Down = GBB[1]
- 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
@@ -230,7 +336,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):
@@ -239,6 +345,13 @@ 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=True)
+
align_mode = EnumProperty(items=(
('OPT_1', "Negative Sides", ""),
('OPT_2', "Centers", ""),
@@ -271,7 +384,12 @@ 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")