多角形の内角を知りたい。
bmeshを使う場合
一枚のポリゴンの場合
import bpy, bmesh from math import degrees obj = bpy.context.object bpy.ops.object.mode_set(mode = 'EDIT') bm = bmesh.from_edit_mesh(obj.data) bm.faces.ensure_lookup_table() rad = bm.faces[0].loops[0].calc_angle() deg = degrees(rad) print(deg) bpy.ops.object.mode_set(mode = 'OBJECT')
結果
119.99998967892589
複数のポリゴンの場合
以下のようなものを考えてみたが隣り合う面が順番に並んでいるか確信が持てない。
メッシュをコピーして外側だけ取ってcalc_angle()した方が手っ取り早い気がする。
is_boundaryは境界かどうか調べてくれるコマンド。
import bpy, bmesh from math import degrees obj = bpy.context.object bpy.ops.object.mode_set(mode = 'EDIT') bm = bmesh.from_edit_mesh(obj.data) bm.edges.ensure_lookup_table() bou = [] for e in bm.edges: if e.is_boundary == True: bou.append(e) for i , b in enumerate(bou): ang = bou[i-1].verts[1].link_loops[0].calc_angle() + bou[i].verts[0].link_loops[1].calc_angle() print(degrees(ang))
loopsは便利だけどループ選択順と頂点IDが一緒かどうかはまだ調べれてない。
loopsの詳しい解説は以下のサイトがめちゃめちゃ参考になった。
bm.faces[0].loops[0].link_loop_next.calc_angle()など、前後の値が取得できるのは超便利だと思う。
b3d.interplanety.org
複数のポリゴンの外側を選択する方法
全選択したのちに選択→ループ選択→境界選択
pythonの場合
bpy.ops.mesh.select_all(action = 'SELECT')
bpy.ops.mesh.region_to_loop()
ベクトルを使う方法
import bpy from math import acos ,pi,degrees from mathutils import Vector p0 = Vector((0.866025,-0.5,0)) p1 = Vector((0.866025,0.5,0)) p2 = Vector((0,-1,0)) a = p0-p1 b = p0-p2 rad = acos(a.normalized().dot( b.normalized() )) deg = degrees(rad) print(deg)
結果
120.0000118302354
問題点
acosがー1から1の範囲外になるとmath domain errorになってしまう。
誤差から結構こういうの起きるので以下のように回避する。
三角関数はこういうの結構あってホント面倒orz
if a.normalized().dot( b.normalized() ) < -1: rad = 2 * pi elif a.normalized().dot( b.normalized() ) > 1: rad = 0 else: rad = acos(a.normalized().dot( b.normalized() )) print(deg)