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します。


  1. import bpy
  2. from mathutils import Vector
  3. import statistics
  4.  
  5. def calculate_r_value(cube_obj):
  6. r_value = 0.0
  7. all_cubes = bpy.context.selected_objects
  8.  
  9. for other_cube in all_cubes:
  10. if other_cube != cube_obj and other_cube.type == 'MESH':
  11. distance = (other_cube.location - cube_obj.location).length
  12. if distance != 0:
  13. r_value += 1 / distance
  14.  
  15. return r_value
  16.  
  17. # 選択されたオブジェクトがCUBEであることを確認
  18. selected_objects = bpy.context.selected_objects
  19. cube_objects = [obj for obj in selected_objects if obj.type == 'MESH']
  20. if not cube_objects:
  21. print("No CUBE objects selected.")
  22. else:
  23. r_values = []
  24. for cube in cube_objects:
  25. r_value = calculate_r_value(cube)
  26. r_values.append(r_value)
  27. print(f"r value for {cube.name}: {r_value}")
  28.  
  29. # 平均値と標準偏差値の計算と表示
  30. mean_value = statistics.mean(r_values)
  31. std_deviation = statistics.stdev(r_values)
  32.  
  33. print(f"Mean value (s value): {mean_value}")
  34. print(f"Standard deviation (t value): {std_deviation}")
  35.  
  36. for cube in cube_objects:
  37. r_value = calculate_r_value(cube)
  38.  
  39. if r_value > (mean_value + std_deviation) or r_value == (mean_value + std_deviation):
  40. u_value = 0
  41. elif (mean_value + std_deviation) > r_value > mean_value or r_value == mean_value:
  42. u_value = 1
  43. elif mean_value > r_value > (mean_value - std_deviation) or r_value == (mean_value - std_deviation):
  44. u_value = 2
  45. elif r_value < (mean_value - std_deviation):
  46. u_value = 3
  47.  
  48. print(f"u value for {cube.name}: {u_value}")
  49.  
  50. # マテリアルの作成とベースカラーの設定
  51. material = bpy.data.materials.new(name=f"{cube.name}_Material")
  52. material.use_nodes = True
  53. principled_bsdf = material.node_tree.nodes.get("Principled BSDF")
  54.  
  55. if u_value == 0:
  56. principled_bsdf.inputs["Base Color"].default_value = (1, 0, 0, 1)
  57. elif u_value == 1:
  58. principled_bsdf.inputs["Base Color"].default_value = (0.8, 0.2, 0.2, 1)
  59. elif u_value == 2:
  60. principled_bsdf.inputs["Base Color"].default_value = (0.1, 0.2, 0.8, 1)
  61. elif u_value == 3:
  62. principled_bsdf.inputs["Base Color"].default_value = (0, 0, 1, 1)
  63.  
  64. if cube.data.materials:
  65. cube.data.materials[0] = material
  66. else:
  67. cube.data.materials.append(material)
2 3Dモデル例
オブジェクト密度表現の初歩的BlenderPythonスクリプト 3Dモデル例

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

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

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

0 件のコメント:

コメントを投稿