Page MenuHome

test_rotate_op.py

Authored By
nBurn (nBurn)
Mar 23 2021, 3:07 PM
Size
3 KB
Subscribers
None

test_rotate_op.py

from copy import deepcopy
import bpy
from mathutils import Matrix, Vector
bl_info = {
"name": "Test Rotate Operator",
"description": "Simple addon to test rotations",
"author": "nBurn",
"version": (0, 0, 0),
"blender": (2, 80, 0),
"location": "Search Menu > Test Rotate Operator",
"category": "Development"
}
def flt_lists_alm_eq(ls_a, ls_b, tol=0.001):
for i in range(len(ls_a)):
if not (ls_a[i] > (ls_b[i] - tol) and ls_a[i] < (ls_b[i] + tol)):
return False
return True
def mat_world_match_existing(exp_data):
exp_m_w = exp_data["matrix_world"]
m_w = bpy.context.object.matrix_world.copy()
for i, row in enumerate(m_w):
if not flt_lists_alm_eq(row, exp_m_w[i]):
return False
return True
def create_z_orient(rot_vec):
x_dir_p = Vector(( 1.0, 0.0, 0.0))
y_dir_p = Vector(( 0.0, 1.0, 0.0))
z_dir_p = Vector(( 0.0, 0.0, 1.0))
if flt_lists_alm_eq(rot_vec, (0.0, 0.0, 0.0)) or \
flt_lists_alm_eq(rot_vec, z_dir_p):
return Matrix((x_dir_p, y_dir_p, z_dir_p)) # 3x3 identity
new_z = rot_vec.copy() # rot_vec already normalized
new_y = new_z.cross(z_dir_p)
if flt_lists_alm_eq(new_y, (0.0, 0.0, 0.0)):
new_y = y_dir_p
new_x = new_y.cross(new_z)
new_x.normalize()
new_y.normalize()
return Matrix(((new_x.x, new_y.x, new_z.x),
(new_x.y, new_y.y, new_z.y),
(new_x.z, new_y.z, new_z.z)))
def do_rotate(piv_co, piv_norm, ang_diff_r):
# back up settings before changing them
piv_back = deepcopy(bpy.context.tool_settings.transform_pivot_point)
curs_back = bpy.context.scene.cursor.location.copy()
bpy.context.tool_settings.transform_pivot_point = 'CURSOR'
bpy.context.scene.cursor.location = Vector(piv_co)
o_mat = create_z_orient(Vector(piv_norm))
bpy.ops.transform.rotate(value=ang_diff_r, orient_axis='Z',
orient_matrix=o_mat, center_override=Vector(piv_co),
constraint_axis=(False, False, False))
# restore settings back to their pre "do_rotate" state
bpy.context.scene.cursor.location = curs_back.copy()
bpy.context.tool_settings.transform_pivot_point = deepcopy(piv_back)
def run_test():
test_data = (
{ # [0] rotation around z axis
"piv_co": ( 1.0, 1.0, 1.0),
"piv_norm": ( 0.0000, 0.0000, -1.0000),
"ang_diff_rad": -0.5235987755982988,
"matrix_world": (
( 0.8660, -0.5000, 0.0000, 0.6340),
( 0.5000, 0.8660, 0.0000, -0.3660),
( 0.0000, 0.0000, 1.0000, 0.0000),
( 0.0000, 0.0000, 0.0000, 1.0000)
)
},
{ # [1] rotation around arbitrary axis
"piv_co": ( 1.0, -1.0, 1.0),
"piv_norm": ( 0.7071, 0.7071, 0.0000),
"ang_diff_rad": 0.5235987755982988,
"matrix_world": (
( 0.9330, 0.0670, 0.3536, -0.2196),
( 0.0670, 0.9330, -0.3536, 0.2196),
(-0.3536, 0.3536, 0.8660, 0.8411),
( 0.0000, 0.0000, 0.0000, 1.0000)
)
}
)
t_dat = test_data[1]
orig_m_w = bpy.context.object.matrix_world.copy()
print("\nrunning test.")
do_rotate(t_dat["piv_co"], t_dat["piv_norm"], t_dat["ang_diff_rad"])
print("matrix_world match expected?", mat_world_match_existing(t_dat))
print()
#bpy.context.object.matrix_world = orig_m_w.copy()
class TEST_ROTATE_OT_main(bpy.types.Operator):
bl_idname = "object.test_rotate_op"
bl_label = "Test Rotate Operator"
def execute(self,context):
run_test()
return {'FINISHED'}
def register():
bpy.utils.register_class(TEST_ROTATE_OT_main)
def unregister():
bpy.utils.unregister_class(TEST_ROTATE_OT_main)
if __name__ == "__main__":
register()

File Metadata

Mime Type
text/x-python
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
7f/0d/90bd61b2f16c927e62fa0be69ecf

Event Timeline