MRが楽しい

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

SDキャラクターの3Dモデルを作成する その40(メッシュオブジェクトを結合する)

本日はSDキャラクターの作成枠です。
SDホロラボちゃんの3Dモデル作成を進めていきます。
今回はモデル作成の仕上げとしてメッシュオブジェクトを結合します。

メッシュオブジェクトを結合する

オブジェクトが分割されていると描画負荷の原因になるので結合して問題ないオブジェクトは出力前に全て結合しておきます。
各オブジェクトの[モディファイア]タブを開き、ジオメトリ系のモディファイアを適用します。

その後、結合したいオブジェクトを全て選択した状態でメニューから[オブジェクト -> 結合]を実行してオブジェクトを結合します。

仕上げ処理を自動化する

ただしこの作業は不可逆なので保存データは仕上げ処理の前のものを保存しておきたいです。
手直しをするごとに仕上げを手作業で行うのは面倒なので python スクリプトで自動化してみました。
・finishing_sdhololabcha.py

# bpyインポート
import bpy
# 正規表現を利用するためインポート
import re

def apply_modifier_targettype(arg_object:bpy.types.Object, arg_modifier_type:str) -> bool:
    """指定オブジェクトの指定タイプのモディファイアを適用する

    Keyword Arguments:
        arg_object (bpy.types.Object): 指定オブジェクト
        arg_modifier_type {str} -- 指定のモディファイアタイプ

    Returns:
        bool -- 実行成否
    """
    
    # 対象のオブジェクトをアクティブオブジェクトにする
    bpy.context.view_layer.objects.active = arg_object

    # オブジェクト内の全てのモディファイアを走査する
    for check_modifier in arg_object.modifiers:
        # モディファイアの種類が指定のものであるか確認する
        if check_modifier.type == arg_modifier_type:
            # 指定モディファイアなら適用する
            # (https://docs.blender.org/api/current/bpy.ops.object.html#bpy.ops.object.modifier_add)
            bpy.ops.object.modifier_apply(modifier=check_modifier.name)

    # 実行成否を返却する
    return True

# 指定の正規表現とオブジェクト名が一致したオブジェクトの参照リストを返す
def select_object_patternmatch(arg_pattern:str) -> list:
    """指定の正規表現とオブジェクト名が一致したオブジェクトの参照リストを返す

    Keyword Arguments:
        arg_pattern {str} -- 指定文字列

    Returns:
        list -- オブジェクトの参照リスト
    """
    
    # 処理対象のオブジェクトリストを作成する
    targetobject_list = []

    # シーン内の全オブジェクトを走査する
    for check_obj in bpy.context.scene.objects:
        # オブジェクト名が指定の正規表現と一致するか
        if re.fullmatch(arg_pattern, check_obj.name):
            # 一致すれば対象とする
            targetobject_list.append(check_obj)

    # リストを返却する
    return targetobject_list

# 選択中オブジェクトを結合する
def join_objects_selected(arg_objectname="") -> bool:
    """選択中オブジェクトを結合する
    
    Keyword Arguments:
        arg_objectname {str} -- 結合オブジェクト名 (default: {""})

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

    # オブジェクトの結合を実行する
    bpy.ops.object.join()
    
    # 結合オブジェクト名が設定されているか
    if len(arg_objectname):
        # オブジェクト名が設定されていれば名前を変更する
        bpy.context.view_layer.objects.active.name = arg_objectname
  
    return True

# 関数の実行例
# シーン内の全オブジェクトを走査する
for check_obj in bpy.context.scene.objects:
    # 一旦すべてのオブジェクトを非選択状態にする
    check_obj.select_set(False)

# 指定の正規表現(Joint_~)とオブジェクト名が一致したオブジェクトを処理対象にする
targetobj_list = select_object_patternmatch(r"Joint_.*")

# 処理対象のオブジェクトのジオメトリ系モディファイアを適用する
for target_obj in targetobj_list:
    # ミラーモディファイアを適用する
    apply_modifier_targettype(target_obj, 'MIRROR')
    # 辺分離モディファイアを適用する
    apply_modifier_targettype(target_obj, 'EDGE_SPLIT')
    # 対象のオブジェクトを選択状態にする
    target_obj.select_set(True)

# オブジェクトを結合する
if len(targetobj_list) > 0:
    # アクティブオブジェクトを指定する
    bpy.context.view_layer.objects.active = targetobj_list[0]
    # オブジェクトを結合する
    join_objects_selected("JoinedObject")

スクリプトを実行するだけで自動でジオメトリ系のモディファイアの適用とオブジェクトの結合が行われるようにできました。