在执行任何对齐操作前,务必先应用物体的缩放,否则边界框的计算会出错:
python
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.transform_apply(scale=True)
方案一:基于边界框对齐(最常用,按底部 Z 轴)
让物体B的底部(最低点)对齐到物体A的底部。
python
import bpy
def align_bottom(obj_a, obj_b):
"""将 obj_b 的底部对齐到 obj_a 的底部"""
# 确保是物体模式
bpy.context.view_layer.objects.active = obj_a
bpy.ops.object.mode_set(mode='OBJECT')
# 获取物体的世界坐标最低点
min_z_a = obj_a.matrix_world @ obj_a.bound_box[0][2] # 注意索引0通常是z最小
# 更准确的方法:遍历边界框的8个点找最小值
min_z_a = min([(obj_a.matrix_world @ v)[2] for v in obj_a.bound_box])
min_z_b = min([(obj_b.matrix_world @ v)[2] for v in obj_b.bound_box])
# 计算位移量
delta_z = min_z_a - min_z_b
# 移动物体B
obj_b.location.z += delta_z
# 使用方法:在Outliner里选中两个物体,再运行
selected = bpy.context.selected_objects
if len(selected) == 2:
align_bottom(selected[0], selected[1])
else:
print("请选中两个物体")
方案二:精确对齐(利用游标法)
完全模拟手动操作,适用于需要对齐特定顶点或面的情况。
python
import bpy
def align_by_cursor(obj_target, obj_to_move):
# 选中目标物体的特定顶点(需提前在编辑模式选好)
# 或者直接对齐到原心:跳过此步,直接用 obj_target.location
bpy.context.view_layer.objects.active = obj_target
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
# 手动选中一个底部顶点后运行...
bpy.ops.object.mode_set(mode='OBJECT')
# 游标到选中项
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.view3d.snap_cursor_to_selected()
bpy.ops.object.mode_set(mode='OBJECT')
# 移动物体
obj_to_move.location = obj_target.location
# 重置原点(可选)
bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
方案三:一键落地到世界地面
常用于3D打印前,让所有选中的物体稳稳站在世界坐标的Z=0平面上。
python
import bpy
def drop_to_ground():
for obj in bpy.context.selected_objects:
if obj.type == 'MESH':
# 获取底部最低点
min_z = min([(obj.matrix_world @ v)[2] for v in obj.bound_box])
# 移动到地面
obj.location.z -= min_z
drop_to_ground()