TOPページ   >   Blender

Blenderスクリプトで点、線、面を登録する方法。'from_pydata()'

Blenderスクリプトで頂点、辺、面を登録する

from_pydata()を使って頂点、辺、面を登録するBlenderスクリプトのサンプルです。
ソースコードの全文はページ下のほうにあります。

頂点を登録する

vertsは頂点XYZ座標を配列の配列で格納します。
append(), extend()を使って配列にデータを格納します。

	verts = []
        verts.append( [ -1, 1, 0 ] )
        verts.append( [  1, 1, 0 ] )
        verts.append( [  1, -1, 0 ] )
        verts.append( [ -1, -1, 0 ] )

        n_mesh = bpy.data.meshes.new("new_mesh")
	n_mesh.from_pydata(verts, [], [])
        n_mesh.update()

        object_utils.object_data_add(context, n_mesh, operator=None)

配列データまとめて登録する場合は、extend()を使います。

        verts.extend( [ [ -1, 1, 0 ], [ 1, 1, 0 ],[ 1, -1, 0 ], [ -1, -1, 0 ] ] )

辺を登録する

edgesには始点と終点の頂点インデックス(vertsの配列番号)を格納します。


    verts = []
    verts.extend( [ [ -1, 1, 0 ], [ 1, 1, 0 ],[ 1, -1, 0 ], [ -1, -1, 0 ] ] )

	edges = []
    edges.extend( [ [ 0,1 ], [ 1,2 ],[ 2,3 ], [ 3,0 ] ] )

        n_mesh = bpy.data.meshes.new("new_mesh")
	n_mesh.from_pydata(verts, edges, [])
        n_mesh.update()

        object_utils.object_data_add(context, n_mesh, operator=None)

面を登録する

facesもedgeと同様、頂点インデックスを格納します。
from_pydata()はエッジと面の両方を登録するとデータが壊れるので注意してください
5点以上で構成するの面を登録する場合は特に注意してください。
面を登録する場合、エッジは自動計算にします。

    verts = []
    verts.extend( [ [ -1, 1, 0 ], [ 1, 1, 0 ],[ 1, -1, 0 ], [ -1, -1, 0 ] ] )

        faces = []
        faces.append( [0,1,2,3] )

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

        object_utils.object_data_add(context, n_mesh, operator=None)

ソースコード

正方形の頂点、辺、面を登録するスクリプト

#This source code is able to freely use for Blender and users.

bl_info = {
    "name": "Add mesh sample",
    "author": "TMO",
    "version": (0, 1, 0),
    "blender": (2, 6, 0),
    "location": "View3D > Add > Mesh > Add mesh sample",
    "description": "Sample of add mesh.",
    "warning": "",
    "wiki_url": "http://www.sousakuba.com/blender/index.html",
    "tracker_url": "",
    "category": "Add Mesh"}

import bpy
from bpy_extras import object_utils

class main(bpy.types.Operator):
    bl_idname="mesh.add_mesh_sample"
    bl_label="Add mesh sample"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):

        plane_size = 1.0;

        verts = []
        edges = []
        faces = []

        verts.append( [ -plane_size, plane_size, 0 ] )
        verts.append( [  plane_size, plane_size, 0 ] )
        verts.append( [  plane_size, -plane_size, 0 ] )
        verts.append( [ -plane_size, -plane_size, 0 ] )

        edges.extend( [ [ 0,1 ], [ 1,2 ],[ 2,3 ], [ 3,0 ] ] )

        faces.append( [0,1,2,3] )

        add_mode = 2

        if add_mode == 0:
            #add vertex
            new_mesh = bpy.data.meshes.new("mesh")
            new_mesh.from_pydata(verts, [], [])
            new_mesh.update()
            object_utils.object_data_add(context, new_mesh, operator=None)
        elif add_mode == 1:
            #add edge
            new_mesh = bpy.data.meshes.new("mesh")
            new_mesh.from_pydata(verts, edges, [])
            new_mesh.update()
            object_utils.object_data_add(context, new_mesh, operator=None)
        else:
            #add face
            new_mesh = bpy.data.meshes.new("mesh")
            new_mesh.from_pydata(verts, [], faces)
            new_mesh.update(calc_edges=True)
            object_utils.object_data_add(context, new_mesh, operator=None)

        return {'FINISHED'}

def menu_func(self, context):
    self.layout.operator(main.bl_idname, main.bl_label, icon="PLUGIN")

def register():
    bpy.utils.register_module(__name__)

    bpy.types.INFO_MT_mesh_add.append(menu_func)

def unregister():
    bpy.utils.unregister_module(__name__)

    bpy.types.INFO_MT_mesh_add.remove(menu_func)

if __name__ == "__main__":
    register()