Blender - 移动网格,使最小 Z 点位于 Z = 0 平面上
Blender - Move mesh so that smallest Z point is on the Z = 0 plane
我正在尝试在搅拌机中移动网格,使最低 z 点为 z=0。这将使最低点位于 Z = 0 平面上。这更加困难,因为我首先按最大轴缩放模型。这不仅仅是我正在处理的一个案例,所以我正在尝试使它适用于任何单个网格模型。
这是我目前的尝试:
mesh_obj = bpy.context.scene.objects[0]
# I first find the min and max of the mesh. The largest and smallest points on the Z-axis
max_floats = [mesh_obj.data.vertices[0].co[0], mesh_obj.data.vertices[0].co[1], mesh_obj.data.vertices[0].co[2]]
min_floats = [mesh_obj.data.vertices[0].co[0], mesh_obj.data.vertices[0].co[1], mesh_obj.data.vertices[0].co[2]]
for vertex in mesh_obj.data.vertices:
if vertex.co[0] > max_floats[0]:
max_floats[0] = vertex.co[0]
if vertex.co[0] < min_floats[0]:
min_floats[0] = vertex.co[0]
if vertex.co[1] > max_floats[1]:
max_floats[1] = vertex.co[1]
if vertex.co[1] < min_floats[1]:
min_floats[1] = vertex.co[1]
if vertex.co[2] > max_floats[2]:
max_floats[2] = vertex.co[2]
if vertex.co[2] < min_floats[2]:
min_floats[2] = vertex.co[2]
max_float = max(max_floats)
min_float = min(min_floats)
# I then get the the point with the biggest magnitude
if max_float < math.fabs(min_float):
max_float = math.fabs(min_float)
recip = 1.0 / max_float
# And use that point to scale the model
# This needs to be taken into account when moving the model by its min z_point
# since that point is now smaller
mesh_obj.scale.x = recip
mesh_obj.scale.y = recip
mesh_obj.scale.z = recip
# naive attempt at moving the model so the lowest z-point = 0
mesh_obj.location.z = -(min_floats[2] * recip / 2.0)
您应该知道的第一件事是顶点位置在对象中 space - 与对象原点的距离。您需要使用对象 matrix_world
将其转换为世界 space.
如果您只希望最低 z 位置等于零,则可以忽略 x 和 y 值。
import bpy
import mathutils
mesh_obj = bpy.context.active_object
minz = 999999.0
for vertex in mesh_obj.data.vertices:
# object vertices are in object space, translate to world space
v_world = mesh_obj.matrix_world * mathutils.Vector((vertex.co[0],vertex.co[1],vertex.co[2]))
if v_world[2] < minz:
minz = v_world[2]
mesh_obj.location.z = mesh_obj.location.z - minz
另一个解决方案:
def object_lowest_point(obj):
matrix_w = obj.matrix_world
vectors = [matrix_w * vertex.co for vertex in obj.data.vertices]
return min(vectors, key=lambda item: item.z)
我正在尝试在搅拌机中移动网格,使最低 z 点为 z=0。这将使最低点位于 Z = 0 平面上。这更加困难,因为我首先按最大轴缩放模型。这不仅仅是我正在处理的一个案例,所以我正在尝试使它适用于任何单个网格模型。
这是我目前的尝试:
mesh_obj = bpy.context.scene.objects[0]
# I first find the min and max of the mesh. The largest and smallest points on the Z-axis
max_floats = [mesh_obj.data.vertices[0].co[0], mesh_obj.data.vertices[0].co[1], mesh_obj.data.vertices[0].co[2]]
min_floats = [mesh_obj.data.vertices[0].co[0], mesh_obj.data.vertices[0].co[1], mesh_obj.data.vertices[0].co[2]]
for vertex in mesh_obj.data.vertices:
if vertex.co[0] > max_floats[0]:
max_floats[0] = vertex.co[0]
if vertex.co[0] < min_floats[0]:
min_floats[0] = vertex.co[0]
if vertex.co[1] > max_floats[1]:
max_floats[1] = vertex.co[1]
if vertex.co[1] < min_floats[1]:
min_floats[1] = vertex.co[1]
if vertex.co[2] > max_floats[2]:
max_floats[2] = vertex.co[2]
if vertex.co[2] < min_floats[2]:
min_floats[2] = vertex.co[2]
max_float = max(max_floats)
min_float = min(min_floats)
# I then get the the point with the biggest magnitude
if max_float < math.fabs(min_float):
max_float = math.fabs(min_float)
recip = 1.0 / max_float
# And use that point to scale the model
# This needs to be taken into account when moving the model by its min z_point
# since that point is now smaller
mesh_obj.scale.x = recip
mesh_obj.scale.y = recip
mesh_obj.scale.z = recip
# naive attempt at moving the model so the lowest z-point = 0
mesh_obj.location.z = -(min_floats[2] * recip / 2.0)
您应该知道的第一件事是顶点位置在对象中 space - 与对象原点的距离。您需要使用对象 matrix_world
将其转换为世界 space.
如果您只希望最低 z 位置等于零,则可以忽略 x 和 y 值。
import bpy
import mathutils
mesh_obj = bpy.context.active_object
minz = 999999.0
for vertex in mesh_obj.data.vertices:
# object vertices are in object space, translate to world space
v_world = mesh_obj.matrix_world * mathutils.Vector((vertex.co[0],vertex.co[1],vertex.co[2]))
if v_world[2] < minz:
minz = v_world[2]
mesh_obj.location.z = mesh_obj.location.z - minz
另一个解决方案:
def object_lowest_point(obj):
matrix_w = obj.matrix_world
vectors = [matrix_w * vertex.co for vertex in obj.data.vertices]
return min(vectors, key=lambda item: item.z)