アストラルプリズム

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

blender python 角度を指定してshearする

角棒の厚みや太さを変えずに端面を角度を指定して変更したいので作ってみた

f:id:katsumi3:20200130212818p:plain


角棒の長手方向をローカルのX軸とする
直方体のみ使用可能(二回目からは指定した角度での辺の移動量しか動かない)

import bpy , bmesh
from math import radians , tan

obj = bpy.context.object
bm = bmesh.from_edit_mesh(obj.data)
bm.faces.ensure_lookup_table()

deg = 45
axis = 'Z'

if axis == 'Z':
    selected = [ v.co.y for v in bm.verts if v.select]
elif axis == 'Y':
    selected = [ v.co.z for v in bm.verts if v.select]

t = max(selected)-min(selected)

shear_va = t*tan(radians(deg))/2

bpy.ops.transform.shear(
    value = shear_va,
    orient_axis = axis, 
    orient_axis_ortho = 'X', 
    orient_type = 'LOCAL', 
    orient_matrix_type = 'GLOBAL'
)

va = [shear_va,0,0]

bpy.ops.transform.translate(
    value = va,
    orient_type = 'LOCAL', 
    orient_matrix_type = 'GLOBAL'
)


bpy.ops.transform.rotateを使ったもの。
複数回使用しても大丈夫。
回転する軸とノーマルのYの向きを調べるのに軸を手打ちしないといけなくなってしまった。
惜しい、あとちょっと。
【注意】面のノーマルのY方向は長手方向に自動的に変えられてしまうので変形前後で軸の方向が変わる・要注意

import bpy,bmesh
from math import radians

obj=bpy.context.object
bm = bmesh.from_edit_mesh(obj.data)
bm.faces.ensure_lookup_table()

p = bm.verts[4].co.copy()

deg = 30

selected = [ v.co.y for v in bm.verts if v.select]
t=max(selected)-min(selected)
    
bpy.ops.transform.rotate(
    value=radians(deg), 
    orient_axis='Z', 
    orient_type='LOCAL', 
    orient_matrix_type='GLOBAL'
)

selected = [ v.co.y for v in bm.verts if v.select]
b=max(selected)-min(selected)

length_5_4 = bm.edges[9].calc_length()
length_4_6 = bm.edges[7].calc_length()

if b == 0:
    a = 0
else:
    a=t/b



if length_5_4 >= length_4_6:
    va=[a,1,1]
else:
    va=[1,a,1]

bpy.ops.transform.resize(
    value=va, 
    orient_type='NORMAL', 
    orient_matrix_type='GLOBAL'
)

new_p = bm.verts[4].co

bpy.ops.transform.translate(
    value=(p-new_p), 
    orient_type='LOCAL', 
    orient_matrix_type='GLOBAL'