質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

3DCG

コンピュータの演算により、3次元空間の仮想物体を、2次元平面上で表現する手法である。

Blender

Blenderとは、オープンソースの3DCGソフトウェアです。フリーでありながら、3Dモデル作成、レンダリング、アニメーション、コンポジットなどのハイエンドに匹敵する高い機能を持ち、さらにゲームエンジンも搭載しています。

Q&A

解決済

1回答

1080閲覧

Blender Pythonでオブジェクトを他のオブジェクトの任意の辺と同じ角度にしたい

super64

総合スコア10

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

3DCG

コンピュータの演算により、3次元空間の仮想物体を、2次元平面上で表現する手法である。

Blender

Blenderとは、オープンソースの3DCGソフトウェアです。フリーでありながら、3Dモデル作成、レンダリング、アニメーション、コンポジットなどのハイエンドに匹敵する高い機能を持ち、さらにゲームエンジンも搭載しています。

0グッド

0クリップ

投稿2022/03/26 10:10

Blender、python上での3Dオブジェクトの操作についての質問です。

イメージ説明

キューブ(オレンジ)のXZ軸を逆T字のフレーム(赤)に合わせたいです

逆T字は、変形するオブジェクトからガイド用に切り出した物のなので
明確に90度ではありません

X軸を合わせる所まではできたのですが
Z軸をあわせる方法がどうしても分かりませんでした
図中水色の点が実現したい事になります

合わせ具合は厳密ではなくても良いです

詳しい方、どうか教えて頂けないでしょうか
よろしくお願いいたします

以下は上記画像のコードです

python

1import bpy 2import bmesh 3from mathutils import * 4 5#逆T図形 6obj_target=bpy.context.scene.collection.objects["target_line.004"] 7 8"""逆T図形の頂点番号は正面(Y方向)から見るとこんな感じ 9 0 1011 1──3──2 12""" 13 14bm = bmesh.new() 15bm.from_mesh(obj_target.data) 16 17vert_local = [ 18 Vector((v.co[0], v.co[1], v.co[2])) 19 for v in bm.verts 20] 21 22#ワールド座標への変換 23vert_global = [ 24 obj_target.matrix_world @ v 25 for v in vert_local 26] 27 28#逆T図形(水平)のベクトル 29v1 = (vert_global[1]) - (vert_global[2]) 30#逆T図形(垂直)のベクトル(未使用) 31v2 = (vert_global[0]) - (vert_global[3]) 32 33#シーン内から回転するオブジェクトを探す 34obj_to=bpy.context.scene.collection.objects["Cube_to.004"] 35 36#回転を適用 37obj_to.rotation_mode = 'QUATERNION' 38obj_to.rotation_quaternion = v1.to_track_quat('-X',"Z") 39

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決です

コードに下段部分を追加し対応

2つのオブジェクトのベクトルのなす角度を求め その角度を一方に適用し
角度が一定以下に合うまでループする力技になりました(最大5回ぐらいで収束)

python

1import bpy 2import bmesh 3from mathutils import * 4 5#逆T図形 6obj_target=bpy.context.scene.objects["target_line.004"] 7 8"""逆T図形の頂点番号は正面(Y方向)から見るとこんな感じ 9 0 1011 1──3──2 12""" 13 14bm = bmesh.new() 15bm.from_mesh(obj_target.data) 16 17vert_local = [ 18 Vector((v.co[0], v.co[1], v.co[2])) 19 for v in bm.verts 20] 21 22#ワールド座標への変換 23vert_global = [ 24 obj_target.matrix_world @ v 25 for v in vert_local 26] 27 28#逆T図形(水平)のベクトル 29v1 = (vert_global[1]) - (vert_global[2]) 30#逆T図形(垂直)のベクトル(未使用) 31v2 = (vert_global[0]) - (vert_global[3]) 32 33#シーン内から回転するオブジェクトを探す 34obj_to=bpy.context.scene.objects["Cube_to.004"] 35 36#回転を適用 37obj_to.rotation_mode = 'QUATERNION' 38obj_to.rotation_quaternion = v1.to_track_quat('-X',"Z") 39 40#回転を適用 41obj_to.rotation_mode = 'QUATERNION' 42obj_to.rotation_quaternion = v1.to_track_quat('-X',"Z") 43 44#(New)Z軸がT(垂直)に近くなるまで繰り返す 45for i in range(100): 46 47 print("Z軸合わせ"+str(i)+"回目") 48 49 #この時点の回転結果が反映されてな 50 51 #これやるBlender上の回転がデータに 52 #オブジェクトをすべて非選択 53 bpy.ops.object.select_all(action='DESELECT') 54 #キューブを選択 55 obj_to.select_set(True) 56 #エディットモードにして戻す 57 #bpy.ops.object.mode_set(mode='EDIT') 58 bpy.ops.object.mode_set(mode='OBJECT') 59 60 #//////////////////////////////// 61 #キューブのZ軸のベクトルを取得 62 #Is there a simpler way to get the Vectors of a local axis? 63 #https://blender.stackexchange.com/questions/156170/is-there-a-simpler-way-to-get-the-vectors-of-a-local-axis 64 (translation, rotation, scale) = obj_to.matrix_world.decompose() 65 local_z_axis = Vector((0.0, 0.0, 1.0)) 66 local_z_axis_global_coords = rotation @ local_z_axis 67 print("z axis:"+str(local_z_axis_global_coords)) 68 69 #//////////////////////////////// 70 #T字垂直と キューブZ軸 71 #2つのベクトルのなす角を求める 72 vec_a=v2 73 vec_c=local_z_axis_global_coords 74 75 #【Python】座標上の3点からなる角度を計算 - Qiita 76 #https://qiita.com/hacchi_/items/7e6f433d465df9378d7a 77 # コサインの計算 78 length_vec_a = np.linalg.norm(vec_a) 79 length_vec_c = np.linalg.norm(vec_c) 80 inner_product = np.inner(vec_a, vec_c) 81 cos = inner_product / (length_vec_a * length_vec_c) 82 83 # 角度(ラジアン)の計算 84 rad = np.arccos(cos) 85 86 # 弧度法から度数法(rad ➔ 度)への変換 87 degree = np.rad2deg(rad) 88 89 print("degree:"+str(degree)) 90 91 #一定以下なら終了 92 if degree<1.0: 93 print("Z軸合わせ完了") 94 break 95 96 #回転実施 97 obj_to.rotation_mode = 'XYZ' 98 obj_to.rotation_euler.rotate_axis("X", radians(degree)) 99

投稿2022/03/26 22:27

super64

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問