アストラルプリズム

PC、スマホ、ゲームなどの備忘録と日記

Blender python mesh・bmeshで取得した値がおかしい

毎回ドはまりして死ぬのでしっかりメモをとっていきたい。

 

原因

・コマンドが違う(一度消したデータが残ってる)

・トランスフォームされてる

・matrix_worldを掛ける順番が違う

・ベクトルの掛け算の記号がBlender2.8から@に変わった

 

 

コマンドが違う

meshで以下のようにしても正しいnormalの値が取得できない。

指定したつもりのオブジェクトではなくて一回消した同名のオブジェクトのnormalの値が取れてしまう。

(つまり初回だけはうまくいくので後で大変な目に合う)

#################################################

obj=bpy.context.object

msh=bpy.data.meshes[obj.name]

norm=msh.polygons[0].normal

#################################################

同名の新しいオブジェクトの値が取れないのでbpy.context.view_layer.update()を使えば何とかなるかとも思ったが何ともならなかった。

きちんと値をとるには二行目にdataを追加して以下のようにする。

誤:msh=bpy.data.meshes[obj.name]

正:msh=bpy.data.meshes[obj.data.name]

 

 

トランスフォームされてる

コマンドは間違ってないがグローバル座標で取得出来ない

##############################

obj=bpy.context.object
msh=bpy.data.meshes[obj.data.name]
norm=msh.polygons[0].normal

##############################

オブジェクトのローカル座標をもとにした値しか取れてない。

オブジェクトモードで変形(ここではx軸の回転45度)が入っているのでそれを考慮した値(グローバル座標)が欲しい。

例ではmeshを使ってるけどbmeshも同じくローカル座標しか取れない。

f:id:katsumi3:20191229213445p:plain

・対策

トランスフォームを適用するかマトリックスワールドを使う

 

・トランスフォームの適用方法

3Dビューをオブジェクトモードにしてから→オブジェクト→適用→全トランスフォーム

 

マトリックスワールドをローカル座標に掛ける

import bpy

obj=bpy.context.object

mw=obj.matrix_world

loc2, rot, scale = plane.matrix_world.decompose()

msh=bpy.data.meshes[obj.data.name]

norm=rot.to_matrix()@msh.polygons[0].normal

v=mw@msh.polygons[0].vertces[0].co

【要注意】

・blender2.8からベクトルの掛け算の記号が@に変わった

・matrix_world@ローカル座標という順にしないとダメ

 (ローカル座標@matrix_worldにすると値が変になる)

f:id:katsumi3:20191229215314p:plain