[Blender×Python]   頂点アニメーションのつくりかた

#目次
1.１つの頂点を１つの軸に関して動かす
2.複数の頂点を１つの軸に関して動かす
3.複数の頂点を複数の軸に関して動かす
4.頂点を少しづつずらしていく(Part1)
5.頂点を少しづつずらしていく(Part2)

#1.１つの頂点を１つの軸に関して動かす

![ezgif.com-gif-maker (13).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/6ddb59ed-7f18-8d0e-1b61-b3d47934a192.gif)

```.py
import bpy
from random import random

#平面を形成する頂点と面を定義する
verts = [(0,0,0),(0,5,0),(5,5,0),(5,0,0)]
faces = [(0,1,2,3)]

#メッシュを定義する
mesh = bpy.data.meshes.new("Plane_mesh")
#頂点と面のデータからメッシュを生成する
mesh.from_pydata(verts,[],faces)
mesh.update(calc_edges=True)

#メッシュのデータからオブジェクトを定義する
obj = bpy.data.objects.new("Plane", mesh)   
#オブジェクトの生成場所をカーソルに指定する
obj.location = bpy.context.scene.cursor.location
#オブジェクトをシーンにリンク(表示)させる
bpy.context.scene.collection.objects.link(obj)

frame_num = 0
#アニメーションの終了フレームの設定
bpy.context.scene.frame_end = 20

for i in range(0,10):
    #頂点リストの中から頂点を1つ選択して、xyzのどの軸に関して動かすか決定する
    mesh.vertices[0].co[2] += 3
    mesh.update(calc_edges=True)
    #選択した頂点の動きを選択した軸と、フレーム数とともにキーフレームに挿入する
    mesh.vertices[0].keyframe_insert('co',index = 2,frame = frame_num)
    
    frame_num += 5
```

Point:**co[]**
頂点をどの軸に関してcoordinateするかを決定します。
-1 → xyz軸
0  → x軸
1  → y軸
2  → z軸

#2.複数の頂点を１つの軸に関して動かす

![ezgif.com-gif-maker (11).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/bb1a4e07-9650-01dc-14b1-9a3094e680b4.gif)

```.py
import bpy
from random import random

bpy.ops.mesh.primitive_monkey_add()

obj = bpy.context.object
frame_num = 0

for f in range(0,100):
    for v in obj.data.vertices:
        m = random() * 0.02
        #フレーム数が偶数の場合
        if f%2:
            #z軸方向にランダムに動かす
            v.co.z += m
        #それ以外(フレーム数が奇数)の場合
        else:
            #z軸方向にランダムに動かす
            v.co.z -= m
        v.keyframe_insert('co',index = 2,frame = frame_num)
    
    frame_num += 1
```



#3.複数の頂点を複数の軸に関して動かす


![ezgif.com-gif-maker (12).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/ed11d46f-1ade-0d79-b54b-088f5745cb5b.gif)

```.py
import bpy
from random import random

#立方体を形成する頂点と面を定義する
verts = [(0,0,0),(0,5,0),(5,5,0),(5,0,0),(0,0,5),(0,5,5),(5,5,5),(5,0,5)]
faces = [(0,1,2,3), (4,5,6,7), (0,4,5,1), (1,5,6,2), (2,6,7,3), (3,7,4,0)]

#メッシュを定義する
mesh = bpy.data.meshes.new("Cube_mesh")
#頂点と面のデータからメッシュを生成する
mesh.from_pydata(verts,[],faces)
mesh.update(calc_edges=True)

#メッシュのデータからオブジェクトを定義する
obj = bpy.data.objects.new("Cube", mesh)   
#オブジェクトの生成場所をカーソルに指定する
obj.location = bpy.context.scene.cursor.location
#オブジェクトをシーンにリンク(表示)させる
bpy.context.scene.collection.objects.link(obj)


frame_num = 0

for f in range(0,100):
    for v in obj.data.vertices:
        m = random()
        if f%2:
            v.co.x += m
            v.co.y += m
        else:
            v.co.x -= m
            v.co.y -= m
        v.keyframe_insert('co',index = -1,frame = frame_num)
    
    frame_num += 3
```






#4.頂点を少しづつずらしていく(Part1)

![ezgif.com-gif-maker (14).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/081299e0-0de5-78a2-8185-129926c9e5d4.gif)


```.py
import bpy
import math

#何角形か指定する
p = 24

#中心を起点に頂点を配置する
verts = [(0,0,0)]
for i in range(0,p + 1):
    x = 2 *math.pi / p * i
    verts.append([math.cos(x),math.sin(x),0])

#中心と円周上の2点の合計3点で面を形成する
faces = []
for i in range(0,p):
    faces.append([0,i + 1,i + 2])

mesh = bpy.data.meshes.new("Polygon_mesh") 
mesh.from_pydata(verts, [], faces) 
obj = bpy.data.objects.new("Polygon", mesh) 
bpy.context.scene.collection.objects.link(obj)

#編集モードにする
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='EDIT')

#重複頂点を削除する
bpy.ops.mesh.remove_doubles()

#オブジェクトモードに戻る
bpy.ops.object.mode_set(mode='OBJECT')

frame_num = 0
bpy.context.scene.frame_end = 600


for f in range(0,600):
    #中心を除く頂点を上下させていく
    for i in range(1,p + 1):
        mesh.vertices[i].co[2] += 5
        mesh.update(calc_edges=True)
        mesh.vertices[i].keyframe_insert('co',index = 2,frame = frame_num)
        frame_num += 15
        
        mesh.vertices[i].co[2] -= 5
        mesh.update(calc_edges=True)
        mesh.vertices[i].keyframe_insert('co',index = 2,frame = frame_num)
        frame_num += 1
```


#頂点を少しづつずらしていく(Part2)

![ezgif.com-gif-maker (16).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/06d30df1-287c-4f96-4c5a-7935101de54e.gif)




```.py
import bpy
import math

verts = []
faces = []

# meshに関する変数
numX = 10
numY = 10

#頂点座標を生成する
for i in range (0, numX):
    for j in range(0,numY):

        x = scale * i
        y = scale * j
        z = 0

        vert = (x,y,z) 
        verts.append(vert)

#4つの頂点から面を生成する
count = 0
for i in range (0, numY *(numX-1)):
    if count < numY-1:
        A = i
        B = i+1
        C = (i+numY)+1
        D = (i+numY)

        face = (A,B,C,D)
        faces.append(face)
        count = count + 1
    else:
        count = 0

mesh = bpy.data.meshes.new("Wave_mesh")
mesh.from_pydata(verts,[],faces)
mesh.update(calc_edges=True)

obj = bpy.data.objects.new("Wave",mesh)
obj.location = (0,0,0)
bpy.context.scene.collection.objects.link(obj)

#サブディビジョンサーフェスを適応する
obj.modifiers.new("subd", type='SUBSURF')
obj.modifiers['subd'].levels = 3

#スムーズシェードを適応する
mypolys = mesh.polygons
for p in mypolys:
    p.use_smooth = True
    
    

frame_num = 0
bpy.context.scene.frame_end = 300


for f in range(0,600):
    for i in range(0,numX * numY):
        mesh.vertices[i].co[2] += 5
        mesh.update(calc_edges=True)
        mesh.vertices[i].keyframe_insert('co',index = 2,frame = frame_num)
        frame_num += 1
        
        mesh.vertices[i].co[2] -= 5
        mesh.update(calc_edges=True)
        mesh.vertices[i].keyframe_insert('co',index = 2,frame = frame_num)
        frame_num += 1
```