MRが楽しい

MRやVRについて学習したことを書き残す

Blender2.8で利用可能なpythonスクリプトを作る その24(メッシュ情報から辺と面の選択)

本日は Blender の技術調査枠です。
Blender2.8で利用可能なpythonスクリプトを作ります。

縁の辺を選択状態にする

メッシュ情報から辺の情報を取得し、面の境界の部分に当たる辺を選択状態にします。
・mesh_edges_check.py

# bpyインポート
import bpy
# メッシュ操作のため
import bmesh

# 縁の辺を選択状態にする
def mesh_edges_check(arg_objectname="Default") -> bool:
    """縁の辺を選択状態にする

    Keyword Arguments:
        arg_objectname {str} -- 指定オブジェクト名 (default: {"Default"})

    Returns:
        bool -- 実行正否
    """

    # 指定オブジェクトを取得する
    # (get関数は対象が存在しない場合 None が返る)
    selectob = bpy.data.objects.get(arg_objectname)

    # 指定オブジェクトが存在するか確認する
    if selectob == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return False
    
    # 不要なオブジェクトを選択しないように
    # 全てのオブジェクトを走査する
    for ob in bpy.context.scene.objects:
        # 非選択状態に設定する
        ob.select_set(False)

    # 指定のオブジェクトのみを選択状態にする
    selectob.select_set(True)

    # 対象オブジェクトをアクティブに変更する
    bpy.context.view_layer.objects.active = selectob

    # 編集モードに移行する
    # モード切替のマニュアル
    # (https://docs.blender.org/api/current/bpy.ops.object.html#bpy.ops.object.mode_set)
    bpy.ops.object.mode_set(mode='EDIT', toggle=False)

    # メッシュデータを取得する
    # メッシュアクセスのマニュアル
    # (https://docs.blender.org/api/current/bmesh.types.html?highlight=bmedge#bmesh.types.BMesh)
    meshdata = bmesh.from_edit_mesh(selectob.data)

    # 選択モードを面選択モードにする
    meshdata.select_mode = {'EDGE'}
    
    # 一度選択を全てクリアする
    bpy.ops.mesh.select_all(action='DESELECT')
    
    # 辺または面の選択状態を更新する
    meshdata.select_flush_mode()
    
    # 辺または面を操作する場合はテーブルを更新する
    meshdata.verts.ensure_lookup_table()

    # 辺を走査する
    # 辺アクセスのマニュアル
    # (https://docs.blender.org/api/current/bmesh.types.html?highlight=bmedge#bmesh.types.BMEdge)
    for edge in meshdata.edges:
        # 面の境界(is_boundary)の辺か否かを確認する
        if edge.is_boundary == True:
            # 頂点位置の情報をコンソールに表示する
            print(str(edge.verts[0].co) + ',' + str(edge.verts[1].co))

            # 辺を選択状態にする
            edge.select_set(True)
        else:
            # 辺を非選択状態にする
            edge.select_set(False)

    # 辺または面の選択状態を更新する
    meshdata.select_flush_mode()

    # オブジェクトデータを更新する
    selectob.data.update()

    return True

# 関数の実行例
mesh_edges_check(arg_objectname="Cylinder")

f:id:bluebirdofoz:20200508201002j:plain

指定数の面を選択状態にする

メッシュ情報から面の情報を取得し、指定数の面を選択状態にします。
・mesh_faces_check.py

# bpyインポート
import bpy
# メッシュ操作のため
import bmesh

# 指定数の面を選択状態にする
def mesh_faces_check(arg_objectname="Default", arg_selectnum=10) -> bool:
    """指定数の面を選択状態にする

    Keyword Arguments:
        arg_objectname {str} -- 指定オブジェクト名 (default: {"Default"})
        arg_selectnum {int} -- 選択する面の数 (default: {10})

    Returns:
        bool -- 実行正否
    """

    # 指定オブジェクトを取得する
    # (get関数は対象が存在しない場合 None が返る)
    selectob = bpy.data.objects.get(arg_objectname)

    # 指定オブジェクトが存在するか確認する
    if selectob == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return False
    
    # 不要なオブジェクトを選択しないように
    # 全てのオブジェクトを走査する
    for ob in bpy.context.scene.objects:
        # 非選択状態に設定する
        ob.select_set(False)

    # 指定のオブジェクトのみを選択状態にする
    selectob.select_set(True)

    # 対象オブジェクトをアクティブに変更する
    bpy.context.view_layer.objects.active = selectob

    # 編集モードに移行する
    # モード切替のマニュアル
    # (https://docs.blender.org/api/current/bpy.ops.object.html#bpy.ops.object.mode_set)
    bpy.ops.object.mode_set(mode='EDIT', toggle=False)

    # メッシュデータを取得する
    # メッシュアクセスのマニュアル
    # (https://docs.blender.org/api/current/bmesh.types.html?highlight=bmedge#bmesh.types.BMesh)
    meshdata = bmesh.from_edit_mesh(selectob.data)

    # 選択モードを面選択モードにする
    meshdata.select_mode = {'FACE'}
    
    # 一度選択を全てクリアする
    bpy.ops.mesh.select_all(action='DESELECT')
    
    # 辺または面の選択状態を更新する
    meshdata.select_flush_mode()
    
    # 辺または面を操作する場合はテーブルを更新する
    meshdata.verts.ensure_lookup_table()

    # カウントを初期化
    selectcount = 0

    # 辺を走査する
    # 面アクセスのマニュアル
    # (https://docs.blender.org/api/current/bmesh.types.html?highlight=bmedge#bmesh.types.BMFace)
    for face in meshdata.faces:
        # 指定の数の面を選択する
        if selectcount < arg_selectnum:
            # 頂点位置の情報をコンソールに表示する
            print(str(face.verts[0].co) + ',' + str(face.verts[1].co) + ',' + str(face.verts[2].co))

            # 面を選択状態にする
            face.select_set(True)

            # インクリメント
            selectcount += 1
        else:
            # 面を非選択状態にする
            face.select_set(False)

    # 辺または面の選択状態を更新する
    meshdata.select_flush_mode()

    # オブジェクトデータを更新する
    selectob.data.update()

    return True

# 関数の実行例
mesh_faces_check(arg_objectname="Sphere", arg_selectnum=30)

f:id:bluebirdofoz:20200508201011j:plain