Blender Pythonを使用して外部データを読み込みGeometry Nodeで使用する
Pythonを使用して外部データを読み込みGeometry Nodeで使用する
GeometryNodeのみでは、CSVなどの外部データを読み込むことができません。外部データを使用したい場合は、Pythonで事前にデータを読み込んだ点群を作って、それをGeometryNodeで使用する方法がいいかと思われます。
Pythonによるデータ読み込みの簡単なサンプル
Blender上に4点を作成する簡単なサンプルです。 その4点に10から40までの値(dummydata)を与えています。
import bpy # make mesh vertices = [(10, 0, 0),(0, 10, 0),(-10,0,0), (0,-10,0)] edges = [] faces = [] plotDataMesh = bpy.data.meshes.new('plot_data') plotDataMesh.from_pydata(vertices, edges, faces) attr = plotDataMesh.attributes.new("dummydata", 'FLOAT', 'POINT') dummyData = [10,20,30,40] attr.data.foreach_set("value", dummyData) plotDataMesh.update() # make object from mesh plotDataObject = bpy.data.objects.new('plot_data_object', plotDataMesh) curScene = bpy.context.scene curScene.collection.objects.link(plotDataObject)
このスクリプトを実行し、アトリビュートをGeometryNodeから見るとdummydataのフィールドにdummydataというフィールドがそれぞれ値が入っていることが分かります。
GeometryNodeからはNamedAttributeのノードを使用してデータを活用します。
世界の人口数をビジュアライズしてみる
次に以下のページで公開されていた世界の人口データをPython+GeometryNodeで映像化します。
City, Latitude, Longitude, Country, Population · GitHub
コードはこのような形になります。先ほどのものにCSVを読み込む部分を追加した形です。
import bpy import os class population_data(object): city = "" country = "" longitude = 0.0 latitude = 0.0 population = 0 def load_csv_population_data(fileName): dataSet = [] ### load csv curDir = os.path.dirname(bpy.data.filepath) dataFilePath = os.path.join(curDir, fileName) if os.path.exists(dataFilePath) : f = open(dataFilePath, "r") for line in f.readlines(): parts = line.strip().split(",") if len(parts) == 5: data = population_data() isValid = True try: data.city = parts[0] data.latitude = float(parts[1]) data.longitude = float(parts[2]) data.country = parts[3] data.population = float(parts[4]) / 10000.0 except: isValid = False if isValid: dataSet.append(data) return dataSet vertices = [] edges = [] faces = [] populations = [] for data in load_csv_population_data("data.csv"): vertices.append((data.longitude, data.latitude, 0.0)) populations.append(data.population) # make mesh plotDataMesh = bpy.data.meshes.new('plot_data') plotDataMesh.from_pydata(vertices, edges, faces) attr = plotDataMesh.attributes.new("population", 'FLOAT', 'POINT') attr.data.foreach_set("value", populations) plotDataMesh.update() # make object from mesh plotDataObject = bpy.data.objects.new('plot_data_object', plotDataMesh) curScene = bpy.context.scene curScene.collection.objects.link(plotDataObject)
これを実行すると以下のような点群が生成されます。 populationフィールドを使用して、縦棒グラフを作成するGeometryNodeは以下のようになります。
アトリビュートを使用してShaderで色付けします。
完成したものがこちらになります。
まとめ
BlenderのPythonは点群を作るだけであれば、非常に高速で、この組み合わせはデータビジュアライゼーションにおいて、他のソフト(Maya、Houdiniなど)に対しても十分なアドバンテージがあるように思います。 このブログがなんらかの参考になれば幸いです。