2
$\begingroup$

For animation purposes I set a few keyframes manually. Now I want to get the transformation difference between frames, so the difference in two frames of this property:

bpy.context.object.location

Using the code above I can only get the current position of the current frame. How can I add a diagnostic box where I input two frames, and calculate the difference in location between them?

enter image description here

$\endgroup$

1 Answer 1

3
$\begingroup$

Slapped together a quick test script from Panel template. A custom property '["frame"]' on the object is used to hold the other frame, calculated against movement from current frame.

Script simply queries the location fcurves of the object, and uses fcurve.evaluate(frame) to retrieve the value at obj["frame"].

enter image description here

import bpy

class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    @classmethod
    def poll(cls, context):
        obj = context.object
        if "frame" not in obj.keys():
            return False
        if not hasattr(obj, "animation_data"):
            return False
        if not obj.animation_data.action:
            return False
        return True

    def draw(self, context):
        obj = context.object
        scene = context.scene
        layout = self.layout
        # get current frame location
        loc_current = obj.location.copy()
        row = layout.row()
        col = row.column()
        col.prop(scene, "frame_current")
        col.prop(obj, "location")
        loc = loc_current.copy()

        # using fcurves
        frame = obj["frame"]
        action = obj.animation_data.action
        col = layout.column()

        col.label("Moved")
        col.prop(obj, '["frame"]', text="From Frame")
        row = layout.row()
        for index in [0, 1, 2]:
            fcurve = action.fcurves.find('location', index)
            if fcurve:
                loc[index] = fcurve.evaluate(frame)
            row.label("%7.4f" % (loc - loc_current)[index])

def register():
    bpy.utils.register_class(HelloWorldPanel)

def unregister():
    bpy.utils.unregister_class(HelloWorldPanel)

if __name__ == "__main__":
    bpy.context.object["frame"] = 33 # set another frame in custom prop
    register()
$\endgroup$
6
  • $\begingroup$ Wow this works amazing! I am trying to get additional result from object.rotation_euler but no luck, any suggestions? / Can this script modified for local axis instead of global axis? $\endgroup$ Sep 5, 2016 at 13:59
  • $\begingroup$ Would have thought ob.location is local? You can't subtract Eulers like Vectors. Converting to quaternions and back could be one way to go. Subtracting the components of eulers would I suppose give an "indication" of rotation difference. $\endgroup$
    – batFINGER
    Sep 5, 2016 at 14:56
  • $\begingroup$ ob.local is global vector. I'm trying to covert it into local vector which is more direct to see the change of individual objects. Eulers is another hard issue to overcome. however your script inspired me a lot. $\endgroup$ Sep 7, 2016 at 7:11
  • $\begingroup$ If I have an object with location (0, 0, 0) parented to another object with location (3, 4, 4), are you saying the child objects global location is (0, 0, 0)? $\endgroup$
    – batFINGER
    Sep 7, 2016 at 7:19
  • $\begingroup$ I want to change the objects differ_global(X,Y,Z) vectors into local(X,Y,Z) to evaluate the change amount alone local axis. and see the differ in local orientation. $\endgroup$ Sep 7, 2016 at 11:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .