2025年1月30日木曜日

Illustrator作成断面線のBlender移植

 Porting Illustrator-created section lines to Blender


I confirmed how to port section line objects created in Illustrator to Blender 3D space, so I made a note of it. This involves moving the origin in Blender to the center of the bounding box instead of the center of gravity.


Illustratorで作成した断面線オブジェクトをBlender3D空間に移植する方法を確認しましたので、メモしました。Blenderで原点を重心ではなくバウンディングボックス中心へ移動する操作を伴います。

1 Illustratorで作成した断面線オブジェクト


Illustratorで作成した断面線オブジェクト

Illustratorの設定はpixelではなく㎜で行い、50㎜を地物1mに対応した縮尺で断面図を作成しています。

画面横軸がBlenderX軸、画面縦軸がBlenderZ軸に対応しています。

断面線(この例は地山地形断面線)を描画して、そのバウンディングボックスの断面図上の座標を読みとります。読み取りはゲージ(50㎜×50㎜のグリッドを10×10グリッドに細分したゲージ)を利用して行います。(Illustratorの固有座標は使いません。)

この例ではX,Y,Zが9.1,24,24.4という座標値になります。

2 IllustratorからSVGファイル書き出し

Illustratorから断面線だけをSVGファイルで書き出します。


断面線書き出し画面(Illustrator画面)

3 Blender読み込みと設定

BlenderにSVGファイルを読み込みます。Blenderにはカーブとして読み込まれます。

次の設定を行います。

回転:X軸を90度回転

スケール:X軸を25倍、Y軸を25倍

原点をバウンディングボックス中心に移動(特製BlenderPythonスクリプトによる移動)

原点の座標値をアイテム位置欄に記入(この例ではX,Y,Zが9.1,24,24.4)(Z座標はローカル設定上4.4で記入)

以上でカーブが所定の三次元空間に配置されました。


カーブが所定の三次元空間に配置された様子(Blender画面)

4 感想

断面図作成や断面図に関わる図面上の解析的検討はIllustratorで行うことが効率的です。その結果をBlenderに移植する方法を確認できたので、自分にとってはかなり画期的です。Blenderで断面図トレースをしなくてすみますから、作業精度や作業効率性が格段に向上します。Blenderを3Dモデル作成専用ツールとして使うことができます。

Illustratorのオブジェクト中心がバウンディングボックスの中心であり、Blenderの重心と異なることを今回意識的に理解することができました。

Blenderにおいて、カーブの原点をバウンディングボックス中心に移動するBlenderPythonスクリプトはChatGPT支援で作成しました。

5 参考 アクティブになっているカーブのバウンディングボックスの中心に原点を移動するBlenderPythonスクリプト

import bpy
import mathutils

# アクティブオブジェクトを取得(カーブ)
obj = bpy.context.object
if obj is None or obj.type != 'CURVE':
    raise ValueError("アクティブなオブジェクトがカーブであることを確認してください。")

# カーブをメッシュに変換(元に戻せるように複製する)
bpy.ops.object.duplicate()
bpy.ops.object.convert(target='MESH')
mesh_obj = bpy.context.object
mesh = mesh_obj.data

# バウンディングボックスの計算(ワールド座標で計算)
min_x, max_x = float('inf'), float('-inf')
min_z, max_z = float('inf'), float('-inf')

for v in mesh.vertices:
    world_co = mesh_obj.matrix_world @ v.co  # ローカル座標をワールド座標に変換
    min_x = min(min_x, world_co.x)
    max_x = max(max_x, world_co.x)
    min_z = min(min_z, world_co.z)
    max_z = max(max_z, world_co.z)

# バウンディングボックスの中心を求める(ワールド座標)
center_x = (min_x + max_x) / 2
center_y = obj.location.y  # Y座標は一定なのでオブジェクトのY座標
center_z = (min_z + max_z) / 2
center = mathutils.Vector((center_x, center_y, center_z))

# 一時的に作成したメッシュオブジェクトを削除
bpy.data.objects.remove(mesh_obj)

# 3Dカーソルを四角形の中心に移動
bpy.context.scene.cursor.location = center

# オブジェクトの原点を3Dカーソルの位置に設定
bpy.ops.object.select_all(action='DESELECT')  # 他のオブジェクトの選択を解除
obj.select_set(True)  # カーブを選択
bpy.context.view_layer.objects.active = obj  # アクティブオブジェクトをカーブに設定
bpy.ops.object.origin_set(type='ORIGIN_CURSOR')

print(f"原点を移動しました: {center}")
以下のようにスクリプトを変更することで、カーブの X座標値を一定 にし、Y座標値とZ座標値が変化する 場合のバウンディングボックスの中心に原点を移動するようにできます。

変更点:
min_x, max_x を min_y, max_y に変更
center_x の計算を obj.location.x に変更(X座標は一定)
center_y を (min_y + max_y) / 2 に変更(Y座標が変化)

0 件のコメント:

コメントを投稿