2023年6月28日水曜日

3D空間におけるオブジェクト密度を表現する初歩的BlenderPythonスクリプト

 A rudimentary BlenderPython script to represent object density in 3D space


I wrote a rudimentary BlenderPython script that expresses the distribution density of a mesh object (CUBE) in Blender3D space. Backed by ChatGPT. Creating 3D heatmaps is no longer a dream.


Blender3D空間におけるメッシュオブジェクト(CUBE)の分布密度を表現する初歩的BlenderPythonスクリプトを作成しましたので、メモします。ChatGPTの支援を受けました。3Dヒートマップ作成が夢ではなくなりました。

1 オブジェクト密度表現の初歩的BlenderPythonスクリプト

このスクリプトは次の要件を満たすBlenderPythonスクリプトです。

1 Blenderで多数のCUBEが密集して配置され、それらが選択されています。

2 1つ1つのCUBEについて、他のすべてのCUBEとの距離を計測し、その距離の逆数をもとめ、さらにその逆数の合計をもとめ、その値をr値とします。

3 全CUBEのr値の平均値(s値)と標準偏差値(t値)を求めます。

4 1つ1つのCUBEに新たに区分値(u値)を与えます。区分値(u値)は次の式に示すとおり、平均値(s値)と標準偏差値(t値)から計算します。

r>(t+s)あるいはr=(t+s)の時 u=0

(t+s)>r>sあるいはr=sのときu=1

s>r>(t-s)あるいはr=(t-s)のときu=2

(t-s)>rのときu=3

5 全CUBEに新しいマテリアルを作成し、そのマテリアルにノードを追加してベースカラーを設定します。

6 ベースカラーの設定は

u=0のときRGB値(1,0,0,1) 赤

u=1のときRGB値(0.8,0.2,0.2,1) 薄赤

u=2のときRGB値(0.1,0.2,0.8,1) 薄青

u=0のときRGB値(0,0,1,1) 青

とします。

7 全CUBEのr値、平均値(s値)と標準偏差値(t値)、全CUBEの区分値(u値)をprintします。


import bpy
from mathutils import Vector
import statistics

def calculate_r_value(cube_obj):
    r_value = 0.0
    all_cubes = bpy.context.selected_objects

    for other_cube in all_cubes:
        if other_cube != cube_obj and other_cube.type == 'MESH':
            distance = (other_cube.location - cube_obj.location).length
            if distance != 0:
                r_value += 1 / distance

    return r_value

# 選択されたオブジェクトがCUBEであることを確認
selected_objects = bpy.context.selected_objects
cube_objects = [obj for obj in selected_objects if obj.type == 'MESH']
if not cube_objects:
    print("No CUBE objects selected.")
else:
    r_values = []
    for cube in cube_objects:
        r_value = calculate_r_value(cube)
        r_values.append(r_value)
        print(f"r value for {cube.name}: {r_value}")

    # 平均値と標準偏差値の計算と表示
    mean_value = statistics.mean(r_values)
    std_deviation = statistics.stdev(r_values)

    print(f"Mean value (s value): {mean_value}")
    print(f"Standard deviation (t value): {std_deviation}")

    for cube in cube_objects:
        r_value = calculate_r_value(cube)

        if r_value > (mean_value + std_deviation) or r_value == (mean_value + std_deviation):
            u_value = 0
        elif (mean_value + std_deviation) > r_value > mean_value or r_value == mean_value:
            u_value = 1
        elif mean_value > r_value > (mean_value - std_deviation) or r_value == (mean_value - std_deviation):
            u_value = 2
        elif r_value < (mean_value - std_deviation):
            u_value = 3

        print(f"u value for {cube.name}: {u_value}")

        # マテリアルの作成とベースカラーの設定
        material = bpy.data.materials.new(name=f"{cube.name}_Material")
        material.use_nodes = True
        principled_bsdf = material.node_tree.nodes.get("Principled BSDF")

        if u_value == 0:
            principled_bsdf.inputs["Base Color"].default_value = (1, 0, 0, 1)
        elif u_value == 1:
            principled_bsdf.inputs["Base Color"].default_value = (0.8, 0.2, 0.2, 1)
        elif u_value == 2:
            principled_bsdf.inputs["Base Color"].default_value = (0.1, 0.2, 0.8, 1)
        elif u_value == 3:
            principled_bsdf.inputs["Base Color"].default_value = (0, 0, 1, 1)

        if cube.data.materials:
            cube.data.materials[0] = material
        else:
            cube.data.materials.append(material)
 
2 3Dモデル例
オブジェクト密度表現の初歩的BlenderPythonスクリプト 3Dモデル例

オブジェクト密度表現の初歩的BlenderPythonスクリプト 3Dモデル例画像

オブジェクト密度表現の初歩的BlenderPythonスクリプトでprintされた情報

オブジェクト密度表現の初歩的BlenderPythonスクリプト 3Dモデル例の動画
3 メモ
このBlenderPythonスクリプトを踏み台にして、色分けをするための統計的手法、区分の仕方、配色はいくらでも精緻化、展開応用が可能です。
3DヒートマップをBlenderPythonスクリプトで作成することが射程圏内に入ったと感じます。
このBlenderPythonスクリプトはChatGPTとのやりとりの中で生成しました。ChatGPTを活用することによって趣味活動のPython化が急加速しています。

0 件のコメント:

コメントを投稿