0
$\begingroup$

I'm trying to copy (all) properties from one camera to another by parsing the camera data block rna_type properties.

I'm able to set simple properties, but I'm unable to set any rna property that is defined inside another property - as in camdata.propname.propname.

camdata = bpy.data.objects['camera'].data
setattr(camdata, 'display_size', 100) # works fine
setattr(camdata, 'stereo.convergence_distance', 100) # this Fails
eval("camdata"+ ".stereo.convergence_distance" + " = " + 100) # this also Fails
$\endgroup$

3 Answers 3

1
$\begingroup$

I got this to work by using path_resolve on the camdata object with the full property path. This returns a valid object data block for setattr.

prop_name = "stereo"
tmp = camdata.path_resolve(prop_name)
setattr(tmp, "convergence_distance", 100)
$\endgroup$
1
  • 1
    $\begingroup$ Hello, I took the liberty to tweak your code which wasn't working for me. Feel free to edit back if you think that wasn't called for. Cheers $\endgroup$
    – Gorgious
    Commented Jul 23, 2022 at 6:00
1
$\begingroup$

Based on https://blender.stackexchange.com/a/252519/86891 here's how you can copy all properties from one camera to another one, including nested properties.

import bpy

cam_source = bpy.data.objects["Camera.001"].data
cam_target = bpy.data.objects["Camera"].data

def copy_struct(source, target):
    if not source or not target:
        return
    for name, prop in source.bl_rna.properties.items():
        if name in ("rna_type", "name", "name_full", "original", "is_evaluated"):
            continue
        try:
            setattr(target, name, getattr(source, name))
        except AttributeError:
            new_source = getattr(source, name)
            new_target = getattr(target, name)
            if hasattr(new_source, "bl_rna"):
                copy_struct(new_source, new_target)
        except TypeError:
            pass

copy_struct(cam_source, cam_target)
$\endgroup$
0
$\begingroup$

You would need to do something like this:

camdata = bpy.data.objects['camera'].data
setattr(camdata.stereo, 'convergence_distance', 100)

If you needed to do it dynamically then you would do:

attr = "stereo" # some dynamically set attr value.
stereo_attr = getattr(camdata, attr)
setattr(stereo_attr, 'convergence_distance', 100)


$\endgroup$
1
  • $\begingroup$ I did try the dynamic solution, but getattr did not return a valid object datablock I could operate on. It returns the property only and setattr failed. $\endgroup$
    – aplus
    Commented Jul 22, 2022 at 21:06

You must log in to answer this question.

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