应用布料修改器提取每帧的顶点坐标

问题描述 投票:0回答:1

我想创建一个动画,在其中提取顶点坐标,存储它们,并使用存储的坐标数据在没有物理的情况下重新激活对象。我目前正在捕获每个帧的顶点坐标并将它们保存到文件中:

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
            ],

如您所见,对于刚体,顶点位置随时间变化,但对于布料,顶点位置保持静态。

python animation blender vertices
1个回答
0
投票

我明白了!感谢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)
© www.soinside.com 2019 - 2024. All rights reserved.