3

How to copy all object properties to another object with Python?

Could you suggest the simplest way.

Desired process

CodeManX
  • 29,298
  • 3
  • 89
  • 128
mifth
  • 2,341
  • 28
  • 36

2 Answers2

5

Custom Properties on object level are contained in Object.keys(), but there's also a helper property _RNA_UI and some API-defined properties such as cycles_visibility.

Therefore, it's better to test for _RNA_UI and get all actual Custom Properties there:

import bpy

ob_sel = bpy.context.selected_editable_objects
ob_act = bpy.context.object

try:
    props = ob_act["_RNA_UI"]
except KeyError:
    pass
else:
    for ob in ob_sel:
        if ob == ob_act:
            continue
        for p in props.keys():
            print(p, ob_act[p])
            ob[p] = ob_act[p]

Note that properties will added or overwritten, but not removed if the target has some the source does not have. You could change that by deleting all Custom Properties of the target before copying the properties from the source object.

CodeManX
  • 29,298
  • 3
  • 89
  • 128
  • I got exception with "props = ob_act["_RNA_UI"]" I got it working only like this http://pastebin.com/Di0r5JrY – mifth Feb 01 '15 at 17:09
  • My bad, try/except needs to catch KeyError, not AttributeError to make it work as intended. If you iterate over Object.keys(), keep in mind it may copy more properties than you may want. – CodeManX Feb 01 '15 at 22:28
  • the problem is that i always get exception or None with "props = ob_act["_RNA_UI"]". Right now i found the only way to copy all stuff to iterate over Object.keys(). – mifth Feb 02 '15 at 11:45
  • Please upload a sample .blend, it appears to work just fine on my side. – CodeManX Feb 02 '15 at 11:56
  • Here is the test https://dl.dropboxusercontent.com/u/26887202/blender/test_RNAUI.blend Create an object and run the script - you will get exception. – mifth Feb 03 '15 at 12:05
  • Of course there's an exception, because ["_RNA_UI"] is not created before there's any ID property. You need to catch that exception, see my code above. – CodeManX Feb 04 '15 at 11:01
1

I'll add to the other answer to expand a little bit.

For some reason the other method won't copy the subtype of the origin property. This can be interesting if you are working with a Color or Euler subtypes. Example :

enter image description here

Also there is now a is_library_overridable flag that is not copied over with the script.

enter image description here

We just need to add a few lines to the origin script :

import bpy

ob_sel = bpy.context.selected_editable_objects ob_act = bpy.context.object

for ob in ob_sel: if ob == ob_act: continue for p in ob_act.keys(): if p == '_RNA_UI': # Make sure the dictionary is initialized (Mainly for empty objects) : if p not in ob.keys(): ob[p] = {} for sub_p in ob_act[p].keys(): # This will copy over the subtype field : ob[p][sub_p] = ob_act[p][sub_p].to_dict() else: # This is a "standard" property (not under '_RNA_UI') - for some reason: ob[p] = ob_act[p] for p in ob_act.keys(): if p == '_RNA_UI': continue # Copy over the overridable flag : ob.property_overridable_library_set(f'["{p}"]', ob_act.is_property_overridable_library(f'["{p}"]'))

This has been made into a handy add-on by user Scorpion81 (and the help of batFINGER) on this thread (Needs a bit of tweaking though to actually copy over the subtype and overridable flag) : https://blenderartists.org/t/addon-copy-custom-properties/591562/13

Gorgious
  • 30,723
  • 2
  • 44
  • 101