見出し画像

【3D×LLMメモ2】Blenderの操作をLLMに手伝ってもらう(VRMの修正)

以下の記事で、モーションの更新を試したが、モデル自体の更新が可能か挑戦する。


環境構築

VRM修正用のスクリプトの作成

以下のスクリプトをBlender上で実行し、VRMが保持しているオブジェクトの情報を抽出する。

import bpy
import os

output_folder = r"C:\Users\XXXXX\20241005_blender"
output_file = os.path.join(output_folder, "scene_analysis.txt")

def print_hierarchy(obj, level=0):
    indent = "  " * level
    return f"{indent}{obj.name} ({obj.type})\n"

def print_materials(obj):
    output = f"Materials for {obj.name}:\n"
    for slot in obj.material_slots:
        if slot.material:
            output += f"  - {slot.material.name}\n"
    return output

def analyze_scene():
    output = "Scene Hierarchy:\n"
    for obj in bpy.context.scene.objects:
        if obj.parent is None:  # Top-level objects only
            output += print_hierarchy(obj)
    
    output += "\nDetailed Object Information:\n"
    for obj in bpy.context.scene.objects:
        output += f"\nObject: {obj.name}\n"
        output += f"Type: {obj.type}\n"
        output += f"Location: {obj.location}\n"
        output += f"Scale: {obj.scale}\n"
        
        if obj.type == 'MESH':
            output += f"Vertices: {len(obj.data.vertices)}\n"
            output += f"Polygons: {len(obj.data.polygons)}\n"
        
        output += print_materials(obj)
        
        if obj.parent:
            output += f"Parent: {obj.parent.name}\n"
        
        if len(obj.children) > 0:
            output += "Children:\n"
            for child in obj.children:
                output += f"  - {child.name}\n"

        if obj.animation_data:
            output += "Has animations\n"
    
    return output

# シーンを分析し、結果をファイルに書き込む
analysis_result = analyze_scene()
with open(output_file, 'w', encoding='utf-8') as f:
    f.write(analysis_result)

print(f"Analysis complete. Results saved to: {output_file}")

以下の結果が得られる。

Scene Hierarchy:
Armature (ARMATURE)
Light (LIGHT)
Camera (CAMERA)
Icosphere (MESH)

Detailed Object Information:

Object: Armature
Type: ARMATURE
Location: <Vector (0.0000, 0.0000, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for Armature:
Children:
  - Body
  - Face
  - Hair
  - J_Bip_C_Head Collider
  - J_Bip_C_Neck Collider
  - J_Bip_C_Spine Collider
  - J_Bip_C_UpperChest Collider
  - J_Bip_C_UpperChest Collider.001
  - J_Bip_C_UpperChest Collider.002
  - J_Bip_L_Hand Collider
  - J_Bip_L_LowerArm Collider
  - J_Bip_L_LowerArm Collider.001
  - J_Bip_L_LowerArm Collider.002
  - J_Bip_L_LowerArm Collider.003
  - J_Bip_L_UpperArm Collider
  - J_Bip_L_UpperArm Collider.001
  - J_Bip_L_UpperArm Collider.002
  - J_Bip_L_UpperLeg Collider
  - J_Bip_L_UpperLeg Collider.001
  - J_Bip_L_UpperLeg Collider.002
  - J_Bip_R_Hand Collider
  - J_Bip_R_LowerArm Collider
  - J_Bip_R_LowerArm Collider.001
  - J_Bip_R_LowerArm Collider.002
  - J_Bip_R_LowerArm Collider.003
  - J_Bip_R_UpperArm Collider
  - J_Bip_R_UpperArm Collider.001
  - J_Bip_R_UpperArm Collider.002
  - J_Bip_R_UpperLeg Collider
  - J_Bip_R_UpperLeg Collider.001
  - J_Bip_R_UpperLeg Collider.002
Has animations

Object: Face
Type: MESH
Location: <Vector (0.0000, 0.0000, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Vertices: 4219
Polygons: 7304
Materials for Face:
  - N00_000_00_FaceMouth_00_FACE (Instance)
  - N00_000_00_EyeIris_00_EYE (Instance)
  - N00_000_00_EyeHighlight_00_EYE (Instance)
  - N00_000_00_Face_00_SKIN (Instance)
  - N00_000_00_EyeWhite_00_EYE (Instance)
  - N00_000_00_FaceBrow_00_FACE (Instance)
  - N00_000_00_FaceEyelash_00_FACE (Instance)
  - N00_000_00_FaceEyeline_00_FACE (Instance)
Parent: Armature

Object: Body
Type: MESH
Location: <Vector (0.0000, 0.0000, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Vertices: 8224
Polygons: 12854
Materials for Body:
  - N00_000_00_Body_00_SKIN (Instance)
  - N00_001_03_Bottoms_01_CLOTH (Instance)
  - N00_001_01_Shoes_01_CLOTH (Instance)
  - N00_000_00_HairBack_00_HAIR (Instance)
  - N00_007_02_Tops_01_CLOTH (Instance)
  - N00_001_02_Accessory_Tie_01_CLOTH (Instance)
Parent: Armature

Object: Hair
Type: MESH
Location: <Vector (0.0000, 0.0000, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Vertices: 16755
Polygons: 20235
Materials for Hair:
  - N00_000_Hair_00_HAIR (Instance)
Parent: Armature

Object: Light
Type: LIGHT
Location: <Vector (4.0762, 1.0055, 5.9039)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for Light:

Object: Camera
Type: CAMERA
Location: <Vector (7.3589, -6.9258, 4.9583)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for Camera:

Object: Icosphere
Type: MESH
Location: <Vector (0.0000, 0.0000, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Vertices: 42
Polygons: 80
Materials for Icosphere:

Object: J_Bip_C_Spine Collider
Type: EMPTY
Location: <Vector (0.0000, -0.1017, -0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_C_Spine Collider:
Parent: Armature

Object: J_Bip_C_UpperChest Collider
Type: EMPTY
Location: <Vector (0.0000, -0.1366, 0.0095)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_C_UpperChest Collider:
Parent: Armature

Object: J_Bip_C_UpperChest Collider.001
Type: EMPTY
Location: <Vector (0.0473, -0.0751, -0.0095)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_C_UpperChest Collider.001:
Parent: Armature

Object: J_Bip_C_UpperChest Collider.002
Type: EMPTY
Location: <Vector (-0.0473, -0.0751, -0.0095)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_C_UpperChest Collider.002:
Parent: Armature

Object: J_Bip_C_Neck Collider
Type: EMPTY
Location: <Vector (0.0000, -0.0505, 0.0123)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_C_Neck Collider:
Parent: Armature

Object: J_Bip_C_Head Collider
Type: EMPTY
Location: <Vector (-0.0000, 0.0019, -0.0142)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_C_Head Collider:
Parent: Armature

Object: J_Bip_L_UpperArm Collider
Type: EMPTY
Location: <Vector (0.0095, -0.2184, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_L_UpperArm Collider:
Parent: Armature

Object: J_Bip_L_UpperArm Collider.001
Type: EMPTY
Location: <Vector (0.0095, -0.1474, -0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_L_UpperArm Collider.001:
Parent: Armature

Object: J_Bip_L_UpperArm Collider.002
Type: EMPTY
Location: <Vector (0.0095, -0.0765, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_L_UpperArm Collider.002:
Parent: Armature

Object: J_Bip_L_LowerArm Collider
Type: EMPTY
Location: <Vector (-0.0000, -0.2128, -0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_L_LowerArm Collider:
Parent: Armature

Object: J_Bip_L_LowerArm Collider.001
Type: EMPTY
Location: <Vector (0.0000, -0.1655, -0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_L_LowerArm Collider.001:
Parent: Armature

Object: J_Bip_L_LowerArm Collider.002
Type: EMPTY
Location: <Vector (0.0000, -0.1181, -0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_L_LowerArm Collider.002:
Parent: Armature

Object: J_Bip_L_LowerArm Collider.003
Type: EMPTY
Location: <Vector (0.0000, -0.0708, -0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_L_LowerArm Collider.003:
Parent: Armature

Object: J_Bip_L_Hand Collider
Type: EMPTY
Location: <Vector (0.0000, -0.0330, -0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_L_Hand Collider:
Parent: Armature

Object: J_Bip_R_UpperArm Collider
Type: EMPTY
Location: <Vector (-0.0095, -0.2184, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_R_UpperArm Collider:
Parent: Armature

Object: J_Bip_R_UpperArm Collider.001
Type: EMPTY
Location: <Vector (-0.0095, -0.1474, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_R_UpperArm Collider.001:
Parent: Armature

Object: J_Bip_R_UpperArm Collider.002
Type: EMPTY
Location: <Vector (-0.0095, -0.0765, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_R_UpperArm Collider.002:
Parent: Armature

Object: J_Bip_R_LowerArm Collider
Type: EMPTY
Location: <Vector (0.0000, -0.2128, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_R_LowerArm Collider:
Parent: Armature

Object: J_Bip_R_LowerArm Collider.001
Type: EMPTY
Location: <Vector (0.0000, -0.1655, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_R_LowerArm Collider.001:
Parent: Armature

Object: J_Bip_R_LowerArm Collider.002
Type: EMPTY
Location: <Vector (0.0000, -0.1181, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_R_LowerArm Collider.002:
Parent: Armature

Object: J_Bip_R_LowerArm Collider.003
Type: EMPTY
Location: <Vector (0.0000, -0.0708, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_R_LowerArm Collider.003:
Parent: Armature

Object: J_Bip_R_Hand Collider
Type: EMPTY
Location: <Vector (-0.0000, -0.0330, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_R_Hand Collider:
Parent: Armature

Object: J_Bip_L_UpperLeg Collider
Type: EMPTY
Location: <Vector (-0.0000, -0.3646, -0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_L_UpperLeg Collider:
Parent: Armature

Object: J_Bip_L_UpperLeg Collider.001
Type: EMPTY
Location: <Vector (-0.0000, -0.2511, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_L_UpperLeg Collider.001:
Parent: Armature

Object: J_Bip_L_UpperLeg Collider.002
Type: EMPTY
Location: <Vector (-0.0000, -0.1564, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_L_UpperLeg Collider.002:
Parent: Armature

Object: J_Bip_R_UpperLeg Collider
Type: EMPTY
Location: <Vector (0.0000, -0.3646, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_R_UpperLeg Collider:
Parent: Armature

Object: J_Bip_R_UpperLeg Collider.001
Type: EMPTY
Location: <Vector (-0.0000, -0.2511, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_R_UpperLeg Collider.001:
Parent: Armature

Object: J_Bip_R_UpperLeg Collider.002
Type: EMPTY
Location: <Vector (-0.0000, -0.1564, 0.0000)>
Scale: <Vector (1.0000, 1.0000, 1.0000)>
Materials for J_Bip_R_UpperLeg Collider.002:
Parent: Armature

LLMに用途と出力結果を渡す。

LLMが出力した以下のスクリプトをBlenderで実行する。

import bpy

def scale_ribbon(scale_factor):
    # "Body" オブジェクトを取得
    body = bpy.data.objects.get("Body")
    
    if body is None:
        print("Body object not found")
        return
    
    # アクティブオブジェクトを Body に設定
    bpy.context.view_layer.objects.active = body
    
    # 編集モードに切り替え
    bpy.ops.object.mode_set(mode='EDIT')
    
    # メッシュデータを取得
    mesh = body.data
    
    # 編集モードの選択を解除
    bpy.ops.mesh.select_all(action='DESELECT')
    
    # 編集モードを一時的に終了してマテリアルインデックスにアクセス
    bpy.ops.object.mode_set(mode='OBJECT')
    
    # リボンのマテリアルインデックスを見つける
    ribbon_material_index = -1
    for i, mat in enumerate(body.material_slots):
        if mat.name == "N00_001_02_Accessory_Tie_01_CLOTH (Instance)":
            ribbon_material_index = i
            break
    
    if ribbon_material_index == -1:
        print("Ribbon material not found")
        return
    
    # リボンマテリアルが適用されているポリゴンを選択
    for poly in mesh.polygons:
        if poly.material_index == ribbon_material_index:
            poly.select = True
    
    # 編集モードに戻る
    bpy.ops.object.mode_set(mode='EDIT')
    
    # 選択された面(リボン)のスケールを変更
    bpy.ops.transform.resize(value=(scale_factor, scale_factor, scale_factor))
    
    # オブジェクトモードに戻る
    bpy.ops.object.mode_set(mode='OBJECT')

# リボンのスケールを1.5倍に変更 (調整したい値に変更してください)
scale_ribbon(1.5)


スクリプト実行結果

スクリプト実行前

スクリプト実行後


VRoid Hubにアップロードしてもリボンが巨大化してます。

この記事が気に入ったらサポートをしてみませんか?