How to update rotation value controlled other property which set keys?

Hi I made test script, which can change context obj Eular rotation to learn python. from this topic.

I hoped to solve problem,( I use his plug-in much for daz figures, then hope to improve, and I am making
simple add-on to rename amature daz genesis bones for blender symmetely,)

Then, I hoped to know why it not work. but I just start learning python, then hope to ask as new python user question,so can someone help me to undersatnd basic things clear? :eek:

bl_info = {
    "name": "Test",
    "category": "Test"}


import bpy
from bpy.props import FloatVectorProperty
from mathutils import Vector
import math


class MyPanel(bpy.types.Panel):
    bl_label = "MyPanel"
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_category = "Test"


    def draw(self, context):
        ob = context.object
        layout = self.layout
        layout.prop(ob, "ctrl1")
        layout.prop(ob, "rotation_euler")
    
def Update_ctrl1(self, context):
    print(self.rotation_euler)
    self.rotation_euler = 2*Vector(self.ctrl1)*math.pi/180 


def register():
    bpy.types.Object.ctrl1 = FloatVectorProperty(
        default = (0,0,0),
        size = 3,      
        update = Update_ctrl1)
        
    bpy.utils.register_module(__name__)


def unregister():
    bpy.utils.unregister_module(__name__)


if __name__ == "__main__":
    register()

it can work as I expected, when I change ctrl1 values, active obj rotate twice in 3d view.
then next, I set keys for ctrl1 vector values on frame 0 , then change ctrl1 values , on frame 10, and set keys,
when I check animation, it not change “Eular rotation” real time. only ctrl1 values are change with timeline.

then If I change ctrl1 values manually, suddenly obj Eular rotation values change belong to current ctrl1 values.

Is there any way, set keys for ctrl1, then real time up-date obj rotation on each frame?
I know, if I set keys for ctrl1 and Eural rotation, it seems work, but Do I really need to set keys both?
or is there way to set keys only about ctrl1, then make cube rotate with timeline by code?

You may want to make a handler

Thank you, I do not clear understand each handler option, but check some codes, then get it work now.

bl_info = {
    "name": "Test",
    "category": "Test"}


import bpy
from bpy.props import FloatVectorProperty
from mathutils import Vector
import math


class MyPanel(bpy.types.Panel):
    bl_label = "MyPanel"
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_category = "Test"


    def draw(self, context):
        ob = context.object
        layout = self.layout
        layout.prop(ob, "ctrl1")
        layout.prop(ob, "rotation_euler")
        
def Update_ctrl1(self, context):
    self.rotation_euler = 2*Vector(self.ctrl1)*math.pi/180
    
def my_handler(scene):
    n = scene.frame_current       
    if n != 0:        
        bpy.context.active_object.rotation_euler = math.degrees(2*Vector(bpy.types.Object.ctrl1))
    
def register():
    bpy.types.Object.ctrl1 = FloatVectorProperty(
        default = (0,0,0),
        size = 3,
        update = Update_ctrl1)
        
    bpy.app.handlers.frame_change_pre.append(my_handler)
        
    bpy.utils.register_module(__name__)


def unregister():
    bpy.utils.unregister_module(__name__)


if __name__ == "__main__":
    register()

It seems work,but there is still one TypeError message,

line 28, in my_handler
TypeError: mathutils.Vector(): sequence index 1 expected a number, found ‘dict’ type

how can I correct it?

and I do not know why I need to use “scene” argument for my_handler, and need to set it, can it make more simple?

In line 28, I think you should be passing you objects ‘ctrl1’ property:


def my_handler(scene):
    ob = bpy.context.active_object
    n = scene.frame_current       
    if n != 0:        
        obj.rotation_euler = math.degrees(2*Vector(obj.ctrl1))

I would like to thank waitinfuture for raising this topic, and cmomoney for pointing us to handlers, a topic that I had not heard of before. Creating a persistent handler that acts pre scene update and frame change seems to solve my orginal problem in the other thread.

However, a small detail remains. The docs suggest that the handler is added with the line


bpy.app.handlers.frame_change_pre.append(my_handler)

AFAIU, this means that a new handler is added every time the add-on is loaded, i.e. every time you hit F8. This may not be a disaster, since the handler performs a rather quick task, but piling up a lot of handlers that do the same thing does not seem to be a very good idea. To avoid this, I currently check if the list of frame_change_pre handlers is empty, but this only works if there isn’t another add-on adding handlers.

Is there some way to avoid loading the handler multiple times? Checking if the handler is in the list does not work, because a different function object seems to be created each time the file is loaded.

You just remove it in your unregister:


bpy.app.handlers.frame_change_pre.remove(my_handler)

Thnaks cmomoney.


def my_handler(scene):
    n = scene.frame_current
    ob = bpy.context.active_object
    print(ob.rotation_euler)
    if n != 0:     
        ob.rotation_euler[0] = math.degrees(ob.ctrl1[0])
        ob.rotation_euler[1] = math.degrees(ob.ctrl1[1])
        ob.rotation_euler[2] = math.degrees(ob.ctrl1[2])

it seems work now. I did not know, when I use math.degrees(), it did not work with Vector properties.
ot I needed to use math.pi avoid type erroer to ghater as Vector.

if n != 0:     
        ob.rotation_euler= 2*Vector(ob.ctrl1)*math.pi/180

ThomasL I’m glad if I could help you a little ^^; y
I did not know at all about "handler"but after Thomas answered me, actually I think, I need to set handle for key animation. At current it is difficult enough for me to use correctly for each case. I still have some questions, to manage dirver target properties,like daz way for my learning, but will ask after learn more basic python.

And your current up-dated importer plug in is really useful. I found many options what I hoped so (pose face bone layer ,divided from controller, etc) ( I have many things which I hope to tell, (question or requeti, or a little erroler message etc), but I just follow each up-date version with expectations )