1
$\begingroup$

i am working with an alembic file which contains points and movement information. for project reasons, i need the movement information in keyframes, so i am writing myself a script that grabs for a given frame the transformation and stores it in a separate object and inserts a keyframe.

problem is, the movement of the point is not represented in the transform window. enter image description here

so my solution for that problem is the "Visual Transform" action, as shown manually below

enter image description here

though, when i try to perform the action target.visual_transform_apply(), i get the error message AttributeError: 'Object' object has no attribute 'visual_transform_apply'

why does it work doing it by hand, and it doesn't when performing it with code?

here is a reduced code snippet of my problem.


target = bpy.context.active_object

bpy.ops.mesh.primitive_plane_add()
new_obj = bpy.context.active_object

target.visual_transform_apply()     

new_obj.location[0] = target.location[0]
new_obj.location[1] = target.location[1]
new_obj.location[2] = target.location[2]

new_obj.keyframe_insert(data_path = "location", frame = 1)

my alembic testfile, i hope a filehoster link is fine https://rapidgator.net/file/d4d4f04912c8fb24a0f716276fa11ca9/Export_01a.abc.html

$\endgroup$
2
  • 1
    $\begingroup$ Can you provide the alembic file to test with? $\endgroup$
    – Crantisz
    Commented Feb 15, 2022 at 10:50
  • $\begingroup$ i added a download link at the bottom. and if you come up with a different solution, that does not include the visual transform, that works for me as well. $\endgroup$
    – Coccolino
    Commented Feb 15, 2022 at 12:10

2 Answers 2

1
$\begingroup$

found a solution for my own problem.

the transformation tooltip for python didn't help me here.enter image description here

somewhere else i found this line of code

new_obj.location[0] = target.matrix_world.translation[0]

this returned me the actual vector of the transformation. by accessing the items of the array one by one, you can work with each value individually.

here is the code snippet from the beginning fixed.


def set_active_object(obj):
    bpy.context.view_layer.objects.active = obj

target = bpy.context.active_object

bpy.ops.mesh.primitive_plane_add()
new_obj = bpy.context.active_object

set_active_object(target)
bpy.ops.object.visual_transform_apply()
set_active_object(new_obj)
    
new_obj.location[0] = target.matrix_world.translation[0]
new_obj.location[1] = target.matrix_world.translation[1]
new_obj.location[2] = target.matrix_world.translation[2]

new_obj.keyframe_insert(data_path = "location", frame = 1)

And if anybody stumbles across here, looking for how to get the rotation and scale value, here they are:

new_obj.rotation_euler[0] = target.matrix_world.to_euler('XYZ')[0]
new_obj.rotation_euler[1] = target.matrix_world.to_euler('XYZ')[1]
new_obj.rotation_euler[2] = target.matrix_world.to_euler('XYZ')[2]

new_obj.scale[0] = my_target.matrix_world.to_scale()[0]
new_obj.scale[1] = my_target.matrix_world.to_scale()[1]
new_obj.scale[2] = my_target.matrix_world.to_scale()[2]

This is by far not the cleanest code, i apologize for that. it's my first blender script.

$\endgroup$
0
$\begingroup$

I just had to do this for one of my scripts to duplicate an object and remove any constraints/armature settings.

My code is below (Blender 3.x) that does what I need it to for now: obj is the source mesh object to duplicate, o_tmp is the duplicated copy with the visual transformation of the source object applied to it.

        o_tmp = obj.copy()
        o_tmp.data = obj.data.copy()
        o_tmp.animation_data_clear()
        bpy.context.collection.objects.link(o_tmp)
        o_tmp.parent = None

        dg = bpy.context.evaluated_depsgraph_get()
        o = obj.evaluated_get(dg)
        m = o.matrix_world.copy()
        o_tmp.matrix_world = m
$\endgroup$

You must log in to answer this question.

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