ラベル オブジェクト の投稿を表示しています。 すべての投稿を表示
ラベル オブジェクト の投稿を表示しています。 すべての投稿を表示

2025年4月9日水曜日

技術メモ 点群から1つのオブジェクトを生成する方法

 Technical Note: How to generate an object from a point cloud


I have confirmed five methods to convert the distribution shape of a point cloud (a group of objects) in Blender3D space into a single object.


Blender3D空間における点群(オブジェクト群)の分布形状を1つのオブジェクトに変換生成する方法を5つ確かめました。

1 元データ


元データ

CUBEが分布する例です。

2 凸包


凸包

CUBE分布の殻を生成します。内部構造は見えなくなります。

3 ポイントクラウドの拡大


ポイントクラウドの拡大

内部構造が見えますが、点群ボリュームが連結するまで拡大するので、分布実体より肥大化します。

4 CUBEの拡大


CUBEの拡大

元データを拡大したもので、内部構造が見えますが、分布実体より肥大化します。

5 バウンディングスフェア


バウンディングスフェア

分布形状を内包する最小球です。

6 バウンディングボックス


バウンディングボックス

分布形状を内包する最小直方体です。

7 メモ

バウンディングスフェア以外はBlenderのgeometry nodesで数個のnodeを連結することで生成しています。

geometry nodesで作業することにより、元データに対して非破壊的です。

バウンディングスフェアは専用nodeがないのでPythonで生成しています。

上記以外にもメタボールを使った方法などがあります。

3D空間で遺物密度の分級を行った際、高密度分布域を強調して表現したい場合などに、この技術を利用します。


2024年4月28日日曜日

技術メモ BlenderPythonによるオブジェクトの干渉色塗色

 Technical memo

Interference coloring of objects with BlenderPython


I created a BlenderPython script with the help of ChatGPT that can paint selected objects with interference colors in Blender and make adjustments. The interference color scheme was developed by Koji Yamada.


Blenderで、選択したオブジェクトを干渉色に塗り、調整ができるBlenderPythonスクリプトをChatGPT支援により作成しました。干渉色配色はやまだこーじさん開発によるものです。

1 オブジェクトの例

次のオブジェクト(フォトグラメトリで作成した土偶3Dモデル)を例に説明します。


オブジェクト


オブジェクトのノード

以下、このオブジェクトに干渉色を塗色する手順をメモします。

2 オブジェクトのテクスチャ画像ノードを外す

オブジェクトのテクスチャ画像ノードをプリンシプルBSDFから外します。オブジェクトを選択します。


オブジェクトの様子


オブジェクトのノード

2 BlenderPythonスクリプト「干渉色ノード生成」をテキストエディターに読み込み、スクリプトを実行します。

BlenderPythonスクリプト「干渉色ノード生成」


import bpy

# 選択されたオブジェクトのアクティブなマテリアルを取得
obj = bpy.context.object
material = obj.active_material
nodes = material.node_tree.nodes

# テクスチャ座標設定
ndtc = nodes.new("ShaderNodeTexCoord")
ndtc.location = -1140, 350

# マッピング設定
ndmp = nodes.new("ShaderNodeMapping")
ndmp.location = -970, 350

# 波テクスチャ設定
ndtw = nodes.new("ShaderNodeTexWave")
ndtw.location = -800, 350

# グラデーションテクスチャ設定
ndgr = nodes.new("ShaderNodeTexGradient")
ndgr.location = -630, 350

# カラーランプノードの追加と設定
ndvr = nodes.new("ShaderNodeValToRGB")
ndvr.location = -450, 350
ndvr.color_ramp.color_mode = "RGB"
ndvr.color_ramp.interpolation = "LINEAR"

# やまだこーじさん開発干渉色カラーグラデーションの設定
ndvr.color_ramp.elements[0].position = 0.0
ndvr.color_ramp.elements[0].color = 0.949,0.996,0.984,1.000
ndvr.color_ramp.elements.new(position=0.042).color = 1.000,0.965,0.784,1.000
ndvr.color_ramp.elements.new(position=0.083).color = 0.961,0.784,0.369,1.000
ndvr.color_ramp.elements.new(position=0.125).color = 0.796,0.455,0.020,1.000
ndvr.color_ramp.elements.new(position=0.167).color = 0.490,0.000,0.627,1.000
ndvr.color_ramp.elements.new(position=0.208).color = 0.000,0.408,0.925,1.000
ndvr.color_ramp.elements.new(position=0.250).color = 0.000,0.757,1.000,1.000
ndvr.color_ramp.elements.new(position=0.292).color = 0.525,0.961,0.871,1.000
ndvr.color_ramp.elements.new(position=0.333).color = 0.863,1.000,0.522,1.000
ndvr.color_ramp.elements.new(position=0.375).color = 1.000,0.886,0.000,1.000
ndvr.color_ramp.elements.new(position=0.417).color = 1.000,0.620,0.482,1.000
ndvr.color_ramp.elements.new(position=0.458).color = 0.945,0.220,0.835,1.000
ndvr.color_ramp.elements.new(position=0.500).color = 0.604,0.259,0.984,1.000
ndvr.color_ramp.elements.new(position=0.542).color = 0.000,0.639,0.929,1.000
ndvr.color_ramp.elements.new(position=0.583).color = 0.000,0.882,0.694,1.000
ndvr.color_ramp.elements.new(position=0.625).color = 0.306,0.976,0.373,1.000
ndvr.color_ramp.elements.new(position=0.667).color = 0.839,0.925,0.412,1.000
ndvr.color_ramp.elements.new(position=0.708).color = 1.000,0.749,0.718,1.000
ndvr.color_ramp.elements.new(position=0.750).color = 1.000,0.498,0.902,1.000
ndvr.color_ramp.elements.new(position=0.792).color = 0.957,0.380,0.922,1.000
ndvr.color_ramp.elements.new(position=0.833).color = 0.616,0.561,0.788,1.000
ndvr.color_ramp.elements.new(position=0.875).color = 0.000,0.769,0.584,1.000
ndvr.color_ramp.elements.new(position=0.917).color = 0.000,0.890,0.510,1.000
ndvr.color_ramp.elements.new(position=0.958).color = 0.420,0.902,0.659,1.000
ndvr.color_ramp.elements.new(position=1.000).color = 0.812,0.820,0.816,1.000

# ガンマ設定
ndgm = nodes.new("ShaderNodeGamma")
ndgm.inputs[1].default_value = 2.2  # ガンマ値を設定
ndgm.location = -180, 350

# ノード間のリンク設定
material.node_tree.links.new(ndtc.outputs[0], ndmp.inputs[0])
material.node_tree.links.new(ndmp.outputs[0], ndtw.inputs[0])
material.node_tree.links.new(ndtw.outputs[0], ndgr.inputs[0])
material.node_tree.links.new(ndgr.outputs[0], ndvr.inputs[0])
material.node_tree.links.new(ndvr.outputs[0], ndgm.inputs[0])

# ガンマ設定ノード(ndgm)をプリンシパルBSDFにリンクする
# アクティブなマテリアルのプリンシパルBSDFノードを取得
principled_bsdf = None
for node in nodes:
    if node.type == 'BSDF_PRINCIPLED':
        principled_bsdf = node
        break

# プリンシパルBSDFノードが見つかった場合にのみリンクを作成
if principled_bsdf:
    material.node_tree.links.new(ndgm.outputs[0], principled_bsdf.inputs[0])
else:
    print("Principled BSDF node not found in material.")

3 オブジェクトが干渉色で塗色される

オブジェクトが干渉色で塗色されます。


オブジェクトの様子


オブジェクトのノード

ノードは左からテクスチャ座標、マッピング、波テクスチャ、グラデーション、カラーランプ、ガンマが生成し、プリンシブルBSDFにリンクします。

マッピングと波テクスチャはデフォルト設定になっていますので、干渉色塗色は望むような塗色になっていない可能性が高いので、調整が必要です。


マッピングと波テクスチャによる調整項目

カラーランプはやまだこーじさん開発干渉色の設定になっています。


干渉色設定のカラーランプ

ガンマはRGBのガンマ補正値2.2が設定されています。これは、BlenderのRGBはガンマ補正がされていないためです。ちなみに、ガンマ補正値に2.2より大きな数を入力すると全体が濃い色に小さな数を入力すると薄い色になります。

4 「マッピング 回転」の調整


「マッピング 回転」でYに90°を入力した様子


「マッピング 回転」でYに90°を入力した様子(上から)

この事例では「マッピング 回転」にY:90°を入力し、私が望むようなカラーランプ軸を設定しました。

5 「波テクスチャ スケール」の調整


「波テクスチャ スケール」の値に3を入力した様子

「波テクスチャ スケール」のデフォルト値5を3に変更してみました。

「波テクスチャ スケール」の値は干渉色セットの繰り返し回数の係数です。

6 「波テクスチャ 位相オフセット」の調整


「波テクスチャ 位相オフセット」の値に0.2を入力した様子

「波テクスチャ 位相オフセット」のデフォルト値0を0.2に変更してみました。

「波テクスチャ 位相オフセット」の値は干渉色セットの始まる位置をずらす係数です。

7 感想メモ

やまだこーじさん開発の干渉色変換ツール機能に相当する機能を、今回Blenderで実現できたと考えます。

干渉色カラーランプの原型は2023.06.17記事「干渉色生成BlenderPythonスクリプトを作成して干渉色を楽しむ」で作成しましたが、今回新たに次の工夫を行いました。

・干渉色のガンマ補正

・「マッピング 回転」によるカラーランプ軸設定

・「波テクスチャ スケール」による干渉色セット繰り返し回数設定

・「波テクスチャ 位相オフセット」による干渉色セット始点設定

・作成ノード群とプリンシプルBSDFノードとのリンク

干渉色変換ツールを開発し、その情報を公開しているやまだこーじさんに感謝します。

なお、カラーランプを改変すれば、自由な配色セットによるオブジェクト塗色が可能となります。


2023年5月27日土曜日

オブジェクト(例 貝層断面図)をBlenderにインポートして正置させるBlenderPythonスクリプト

 A Blender Python script that imports an object (e.g. shell layer cross section) into Blender and orients it correctly


I created a BlenderPython script that imports an object (e.g. shell layer cross section) into Blender and orients it in 3D space. With this script and object files, I'm ready to build a Blender file. There is no need to use the Blender file as the original, which improves work efficiency.


オブジェクト(例 貝層断面図)をBlenderにインポートして3D空間に正置させるBlenderPythonスクリプトを作成しました。このスクリプトとオブジェクトファイルがあれば、いつでもBlenderファイルを構築できます。Blenderファイルを原簿とする必要がなく、作業効率が向上します。

1 例 第2貝層断面図


オブジェクト(第2貝層断面図)がBlender3D空間に配置されている様子


オブジェクト(第2貝層断面図)のBlender3D空間における位置・回転・スケール諸元

2 オブジェクト(第2貝層断面図)をインポート・正置させるスクリプト


オブジェクト(第2貝層断面図)をBlenderにインポートし正置させるスクリプト

……………………………………………………………………

# 平面画像オブジェクトをインポートして位置の移動、回転、拡大縮小させて、正置させる。

import bpy

import math

bpy.ops.wm.obj_import(filepath="I:\\20221214有吉北貝塚北斜面貝層プロジェクト\\■貝層断面図等Pythonによるプロット\\20230525Pythonスクリプト基礎検討\\2o4a-01eee.obj", directory="I:\\20221214有吉北貝塚北斜面貝層プロジェクト\\■貝層断面図等Pythonによるプロット\\20230525Pythonスクリプト基礎検討\\", files=[{"name":"2o4a-01eee.obj", "name":"2o4a-01eee.obj"}], forward_axis='X', up_axis='Z')

# 現在選択されているオブジェクトを取得します。

selected_objects = bpy.context.selected_objects

# 選択されたオブジェクトを拡大縮小します。

for obj in selected_objects:

obj.scale[0] = 0.1

obj.scale[1] = 0.1

# 選択されたオブジェクト(の原点)を移動します。

for obj in selected_objects:

obj.location[0] = 10.182

obj.location[1] = 4

obj.location[2] = 5.1797

# 選択されたオブジェクトを回転します。

for obj in selected_objects:

obj.rotation_euler[0] = math.radians(90)

obj.rotation_euler[2] = math.radians(0)

# オブジェクトを原点へ移動。(過去の操作でオブジェクトの原点が移動している場合があるので、それを補正するためのスクリプト。)

bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='MEDIAN')

……………………………………………………………………

3 オブジェクト(第2貝層断面図)のBlenderインポートと正置


オブジェクト(第2貝層断面図)のBlenderインポートと正置の様子

4 感想

4-1 情報パネルに表示されるPythonスクリプトの逆引き的活用

BlenderPythonスクリプトを書くために情報パネルに表示されるPythonスクリプトを逆引き的に利用できることに気が付きました。

Blenderで行う操作は全て情報パネル(Scripting画面におけるPythonコンソールの下)にPythonスクリプトとして記録されます。従って、書きたいスクリプトの操作をBlenderで行えば、そのスクリプトを得ることができます。とても便利です。これを利用することによりスクリプト作成の高い敷居がとても低くなりました。


BlenderのScripting画面における情報パネル

4-2 オブジェクトのインポート・正置BlenderPythonスクリプトの意義

オブジェクト(例 貝層断面図)をBlenderにインポートして3D空間に正置させるBlenderPythonスクリプトを今回作成しました。このスクリプトとオブジェクトファイルがあれば、いつでもBlenderファイルを構築できます。従って、Blenderファイルを原簿とする必要がなくなります。有吉北貝塚北斜面貝層に関する学習活動では多数のBlenderファイルを作成してきていて、その管理が大変面倒になってきています。しかし今回のスクリプトとオブジェクトファイルがあればBlenderファイルを構築できることにより、原簿をオブジェクトファイルとすることができ、煩雑なBlenderファイル管理がなくなり、活動効率が向上します。

4-3 つかまり立ちレベル

自分のPython・BlenderPython学習レベルを幼児発達に例えると、ようやくつかまり立ちができるレベルに到達できたといううれしい状況です。まだヨチヨチ歩きは無理という感じですが、はやくそうなりたいです。