我想创建一个动画,在其中提取顶点坐标,存储它们,并使用存储的坐标数据在没有物理的情况下重新激活对象。我目前正在捕获每个帧的顶点坐标并将它们保存到文件中:
def get_vertices_info(obj_name):
obj = bpy.data.objects[obj_name]
obj_data = obj.data
vertices_data = {}
for vertex_index, vertex in enumerate(obj_data.vertices):
vertex_data = []
for frame in range(bpy.context.scene.frame_start, bpy.context.scene.frame_end + 1):
bpy.context.scene.frame_set(frame)
vertex_world_co = obj.matrix_world @ vertex.co
frame_data = tuple(vertex_world_co)
vertex_data.append(frame_data)
vertices_data[f"Vertex {vertex_index + 1}"] = vertex_data
return vertices_data
#(wind_strength, wind_directions, wind_coordinates) = get_wind_info("Wind")
vertices_data = get_vertices_info("Plane")
data = {
"wind": {
"strength": wind_strength,
"directions": wind_directions,
"coordinates": wind_coordinates
},
"verticies": vertices_data
}
然后在另一个场景上制作动画:
new_scene = bpy.data.scenes.new("Animated Scene")
original_obj = bpy.data.objects['Plane']
flag = original_obj.copy()
flag.data = original_obj.data.copy()
flag.modifiers.remove(flag.modifiers.get("Cloth"))
new_scene.collection.objects.link(flag)
bpy.context.window.scene = new_scene
vertex_data = list(data["meshes"].values())
# https://blender.stackexchange.com/questions/36902/how-to-keyframe-mesh-vertices-in-python
def insert_keyframe(fcurves, frame, values):
for fcu, val in zip(fcurves, values):
fcu.keyframe_points.insert(frame, val, options={'FAST'})
obj = bpy.context.active_object
mesh = flag.data
action = bpy.data.actions.new("MeshAnimation")
mesh.animation_data_create()
mesh.animation_data.action = action
data_path = "vertices[%d].co"
values = vertex_data
frames = list(range(0,len(values[0]) + 1))
for i,v in enumerate(mesh.vertices):
fcurves = [action.fcurves.new(data_path % v.index, index = i) for i in range(3)]
co_rest = v.co
for t, value in zip(frames, values[i]):
insert_keyframe(fcurves, t, value)
如果我从没有布料修改器的对象收集数据,它会部分起作用。(可能我弄乱了坐标方向)。然而,当对象应用了布料修改器时,平面保持静止。
但是,当我使用这些数据制作动画时,什么也没有发生;飞机保持静止。
我尝试了几种不同的功能,因为我怀疑问题出在数据收集上。这是刚体收集的数据:
"verticies": {
"Vertex 1": [
[
0.0683371052145958,
-1.5310348272323608,
0.931662917137146
],
[
0.5171984434127808,
-1.5432056188583374,
0.40158990025520325
],
...
这是带布的:
"verticies": {
"Vertex 1": [
[
0.0683371052145958,
-1.5310348272323608,
0.931662917137146
],
[
0.0683371052145958,
-1.5310348272323608,
0.931662917137146
],
如您所见,对于刚体,顶点位置随时间变化,但对于布料,顶点位置保持静态。
我明白了!感谢this问题向我介绍了
bmesh
这是重新审视的保存功能:
def get_vertices_frame_by_frame(end_frame):
data = {}
flag_obj = bpy.data.objects.get("Flag")
for frame in range(1,end_frame + 1):
bpy.context.scene.frame_current = frame
dg = bpy.context.evaluated_depsgraph_get()
bm = bmesh.new()
bm.from_object(flag_obj, dg)
vert_tuples = tuple((vert.co.x, vert.co.y, vert.co.z) for vert in bm.verts)
data[f"Frame-{frame}"] = vert_tuples
bm.free()
return data
vertices_data = get_vertices_by_frame(30)
data = {
"vertices" : vertices_data
}
以及加载功能:
vertex_data_by_frame = data["vertices"].values()
for frame_num, vertices in enumerate(vertex_data_by_frame):
for i, v in enumerate(vertices):
vertex = flag.data.vertices[i]
vertex.co = v
vertex.keyframe_insert(data_path="co", frame=frame_num + 1)