1
$\begingroup$

When I create some property in object:

bpy.types.Object.my_prop = bpy.props.IntProperty(name="MyProp",
    default=-1,
    description="My Property"
)

and I set the value of this property e.g.: bpy.context.active_object.my_prop = 10, then duplicated object will have copied value of original object.

Is there any way how to force to use default value (-1) of property in duplicated object?

$\endgroup$
1
$\begingroup$

Each property can have callback functions: update(), set(), get() and get(), set() callback functions allows force to use default value:

import bpy

values = {}

def cb_get(self):
    try:
        value = values[self.name]
    except KeyError:
        value = -1 # default value
    return value

def cb_set(self, value):
    values[self.name] = value
    return None

bpy.types.Object.my_prop = bpy.props.IntProperty(name="MyProp",
    description="My Property",
    get=cb_get,
    set=cb_set
    )

print(bpy.context.active_object.my_prop)
bpy.context.active_object.my_prop = 10
print(bpy.context.active_object.my_prop)

Example with more explanation can be found in this gist:

https://gist.github.com/jirihnidek/2e5218dd8bf06787e538

Edit: Reloading blend file using previous concept is risky (look at comments). Following solution tries to fix problems with reloading blend file. import bpy

def cb_get(self):
    if self.name != self.name_:
        self.name_ = self.name
        self.my_prop_ = -1 # default value
    return self.my_prop_

def cb_set(self, value):
    self.my_prop_ = value
    return None

bpy.types.Object.my_prop_ = bpy.props.IntProperty(name="MySecretProp",
    default=-1,
    description="My Secret Property",
    options={'HIDDEN'}
    )

bpy.types.Object.name_ = bpy.props.StringProperty(name="SecretName",
    default="",
    description="Expected name of object storing properties",
    options={'HIDDEN'}
    )

bpy.types.Object.my_prop = bpy.props.IntProperty(name="MyProp",
    description="My Property",
    update=cb_update,
    get=cb_get,
    set=cb_set
    )

print(bpy.context.active_object.my_prop)
bpy.context.active_object.my_prop = 10
print(bpy.context.active_object.my_prop)
$\endgroup$
  • 2
    $\begingroup$ This is a bit risky, it will work in simple cases - but could give invalid results if you reload files, especially with many names like Cube.001, You could have a bpy.app.handler.load_post callback to clear the dictionary on file load, but that still wont account for undo/redo. I don't think there is really a fool-proof way to do this. $\endgroup$ – ideasman42 Mar 19 '15 at 11:45
  • 1
    $\begingroup$ If you are willing to consider the name a UUID, you could store some hidden __name__ custom property. Then on access, check if they don't match, clear all properties, and write into that name. This could cause problems when renaming though. $\endgroup$ – ideasman42 Mar 19 '15 at 11:53
  • $\begingroup$ Any custom property can not start with '_' character. When you will try to do this, then ValueError will be raised. Previous idea is right, but the custom property will have to be named e.g. name__ and not __name__ :-). $\endgroup$ – JiriHnidek Mar 19 '15 at 12:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.