Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/modules/rna_prop_ui.py19
-rw-r--r--release/scripts/startup/bl_operators/object.py44
-rw-r--r--release/scripts/startup/bl_operators/wm.py55
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py5
-rw-r--r--source/blender/editors/interface/interface_context_menu.c9
-rw-r--r--source/blender/editors/interface/interface_ops.c53
-rw-r--r--source/blender/makesrna/RNA_access.h3
-rw-r--r--source/blender/makesrna/intern/rna_access.c171
8 files changed, 350 insertions, 9 deletions
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index fc17cc60c6c..f08390cfd6d 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -96,6 +96,25 @@ def rna_idprop_has_properties(rna_item):
return (nbr_props > 1) or (nbr_props and '_RNA_UI' not in keys)
+def rna_idprop_ui_prop_default_set(item, prop, value):
+ defvalue = None
+ try:
+ prop_type = type(item[prop])
+
+ if prop_type in {int, float}:
+ defvalue = prop_type(value)
+ except KeyError:
+ pass
+
+ if defvalue:
+ rna_ui = rna_idprop_ui_prop_get(item, prop, True)
+ rna_ui["default"] = defvalue
+ else:
+ rna_ui = rna_idprop_ui_prop_get(item, prop)
+ if rna_ui and "default" in rna_ui:
+ del rna_ui["default"]
+
+
def draw(layout, context, context_member, property_type, use_edit=True):
def assign_props(prop, val, key):
diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py
index 949e2baff03..660f87aea0d 100644
--- a/release/scripts/startup/bl_operators/object.py
+++ b/release/scripts/startup/bl_operators/object.py
@@ -943,6 +943,49 @@ class LoadReferenceImage(LoadImageAsEmpty, Operator):
pass
+class OBJECT_OT_assign_property_defaults(Operator):
+ """Assign the current values of custom properties as their defaults, for use as part of the rest pose state in NLA track mixing"""
+ bl_idname = "object.assign_property_defaults"
+ bl_label = "Assign Custom Property Values as Default"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ process_data: BoolProperty(name="Process data properties", default=True)
+ process_bones: BoolProperty(name="Process bone properties", default=True)
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return obj is not None and obj.library is None and obj.mode in {'POSE', 'OBJECT'}
+
+ @staticmethod
+ def assign_defaults(obj):
+ from rna_prop_ui import rna_idprop_ui_prop_default_set
+
+ rna_properties = {'_RNA_UI'} | {prop.identifier for prop in obj.bl_rna.properties if prop.is_runtime}
+
+ for prop, value in obj.items():
+ if prop not in rna_properties:
+ rna_idprop_ui_prop_default_set(obj, prop, value)
+
+ def execute(self, context):
+ obj = context.active_object
+
+ self.assign_defaults(obj)
+
+ if self.process_bones and obj.pose:
+ for pbone in obj.pose.bones:
+ self.assign_defaults(pbone)
+
+ if self.process_data and obj.data and obj.data.library is None:
+ self.assign_defaults(obj.data)
+
+ if self.process_bones and isinstance(obj.data, bpy.types.Armature):
+ for bone in obj.data.bones:
+ self.assign_defaults(bone)
+
+ return {'FINISHED'}
+
+
classes = (
ClearAllRestrictRender,
DupliOffsetFromCursor,
@@ -958,4 +1001,5 @@ classes = (
SubdivisionSet,
TransformsToDeltas,
TransformsToDeltasAnim,
+ OBJECT_OT_assign_property_defaults,
)
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index e26e2ddf214..bf968de8641 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -1052,6 +1052,12 @@ rna_value = StringProperty(
maxlen=1024,
)
+rna_default = StringProperty(
+ name="Default Value",
+ description="Default value of the property. Important for NLA mixing",
+ maxlen=1024,
+)
+
rna_property = StringProperty(
name="Property Name",
description="Property name edit",
@@ -1089,6 +1095,7 @@ class WM_OT_properties_edit(Operator):
data_path: rna_path
property: rna_property
value: rna_value
+ default: rna_default
min: rna_min
max: rna_max
use_soft_limits: rna_use_soft_limits
@@ -1107,6 +1114,28 @@ class WM_OT_properties_edit(Operator):
"hard_range": (self.min, self.max),
}
+ def get_value_eval(self):
+ try:
+ value_eval = eval(self.value)
+ # assert else None -> None, not "None", see [#33431]
+ assert(type(value_eval) in {str, float, int, bool, tuple, list})
+ except:
+ value_eval = self.value
+
+ return value_eval
+
+
+ def get_default_eval(self):
+ try:
+ default_eval = eval(self.default)
+ # assert else None -> None, not "None", see [#33431]
+ assert(type(default_eval) in {str, float, int, bool, tuple, list})
+ except:
+ default_eval = self.default
+
+ return default_eval
+
+
def execute(self, context):
from rna_prop_ui import (
rna_idprop_ui_prop_get,
@@ -1124,12 +1153,8 @@ class WM_OT_properties_edit(Operator):
self.report({'ERROR'}, "Direct execution not supported")
return {'CANCELLED'}
- try:
- value_eval = eval(value)
- # assert else None -> None, not "None", see [#33431]
- assert(type(value_eval) in {str, float, int, bool, tuple, list})
- except:
- value_eval = value
+ value_eval = self.get_value_eval()
+ default_eval = self.get_default_eval()
# First remove
item = eval("context.%s" % data_path)
@@ -1159,6 +1184,8 @@ class WM_OT_properties_edit(Operator):
if prop_type in {float, int}:
prop_ui["min"] = prop_type(self.min)
prop_ui["max"] = prop_type(self.max)
+ if type(default_eval) in {float, int} and default_eval != 0:
+ prop_ui["default"] = prop_type(default_eval)
if self.use_soft_limits:
prop_ui["soft_min"] = prop_type(self.soft_min)
@@ -1223,6 +1250,13 @@ class WM_OT_properties_edit(Operator):
exec_str = "item.is_property_overridable_static('[\"%s\"]')" % (self.property)
self.is_overridable_static = bool(eval(exec_str))
+ # default default value
+ prop_type = type(self.get_value_eval())
+ if prop_type in {int,float}:
+ self.default = str(prop_type(0))
+ else:
+ self.default = ""
+
# setup defaults
prop_ui = rna_idprop_ui_prop_get(item, self.property, False) # don't create
if prop_ui:
@@ -1230,6 +1264,10 @@ class WM_OT_properties_edit(Operator):
self.max = prop_ui.get("max", 1000000000)
self.description = prop_ui.get("description", "")
+ defval = prop_ui.get("default", None)
+ if defval is not None:
+ self.default = str(defval)
+
self.soft_min = prop_ui.get("soft_min", self.min)
self.soft_max = prop_ui.get("soft_max", self.max)
self.use_soft_limits = (
@@ -1275,6 +1313,11 @@ class WM_OT_properties_edit(Operator):
layout = self.layout
layout.prop(self, "property")
layout.prop(self, "value")
+
+ row = layout.row()
+ row.enabled = type(self.get_value_eval()) in {int,float}
+ row.prop(self, "default")
+
row = layout.row(align=True)
row.prop(self, "min")
row.prop(self, "max")
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index fa58fed6102..7922cdb90ec 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2662,6 +2662,11 @@ class VIEW3D_MT_pose_apply(Menu):
layout.operator("pose.armature_apply")
layout.operator("pose.visual_transform_apply")
+ layout.separator()
+
+ props = layout.operator("object.assign_property_defaults")
+ props.process_bones = True
+
class VIEW3D_MT_pose_specials(Menu):
bl_label = "Pose Context Menu"
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 84460f9f149..d9967625199 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -404,7 +404,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
const PropertySubType subtype = RNA_property_subtype(prop);
bool is_anim = RNA_property_animateable(ptr, prop);
bool is_editable = RNA_property_editable(ptr, prop);
- /*bool is_idprop = RNA_property_is_idprop(prop);*/ /* XXX does not work as expected, not strictly needed */
+ bool is_idprop = RNA_property_is_idprop(prop);
bool is_set = RNA_property_is_set(ptr, prop);
/* second slower test, saved people finding keyframe items in menus when its not possible */
@@ -643,6 +643,13 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
ICON_NONE, "UI_OT_unset_property_button");
}
+ if (is_idprop && !is_array_component && ELEM(type, PROP_INT, PROP_FLOAT)) {
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Assign Value as Default"),
+ ICON_NONE, "UI_OT_assign_default_button");
+
+ uiItemS(layout);
+ }
+
if (is_array_component) {
uiItemBooleanO(
layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy All To Selected"),
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index b4b59cae75b..1cb9f156eeb 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -301,6 +301,58 @@ static void UI_OT_reset_default_button(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array");
}
+/* Assign Value as Default Button Operator ------------------------ */
+
+static bool assign_default_button_poll(bContext *C)
+{
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+
+ if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
+ PropertyType type = RNA_property_type(prop);
+
+ return RNA_property_is_idprop(prop) && !RNA_property_array_check(prop) && ELEM(type, PROP_INT, PROP_FLOAT);
+ }
+
+ return false;
+}
+
+static int assign_default_button_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+
+ /* try to reset the nominated setting to its default value */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+
+ /* if there is a valid property that is editable... */
+ if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
+ if (RNA_property_assign_default(&ptr, prop))
+ return operator_button_property_finish(C, &ptr, prop);
+ }
+
+ return OPERATOR_CANCELLED;
+}
+
+static void UI_OT_assign_default_button(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Assign Value as Default";
+ ot->idname = "UI_OT_assign_default_button";
+ ot->description = "Set this property's current value as the new default";
+
+ /* callbacks */
+ ot->poll = assign_default_button_poll;
+ ot->exec = assign_default_button_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+}
+
/* Unset Property Button Operator ------------------------ */
static int unset_property_button_exec(bContext *C, wmOperator *UNUSED(op))
@@ -1557,6 +1609,7 @@ void ED_operatortypes_ui(void)
WM_operatortype_append(UI_OT_copy_data_path_button);
WM_operatortype_append(UI_OT_copy_python_command_button);
WM_operatortype_append(UI_OT_reset_default_button);
+ WM_operatortype_append(UI_OT_assign_default_button);
WM_operatortype_append(UI_OT_unset_property_button);
WM_operatortype_append(UI_OT_override_type_set_button);
WM_operatortype_append(UI_OT_override_remove_button);
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index f6bfcb2bb32..03a879c9cf7 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -952,6 +952,7 @@ int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index);
void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values);
void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value);
int RNA_property_int_get_default(PointerRNA *ptr, PropertyRNA *prop);
+bool RNA_property_int_set_default(PointerRNA *ptr, PropertyRNA *prop, int value);
void RNA_property_int_get_default_array(PointerRNA *ptr, PropertyRNA *prop, int *values);
int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index);
@@ -963,6 +964,7 @@ float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values);
void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value);
float RNA_property_float_get_default(PointerRNA *ptr, PropertyRNA *prop);
+bool RNA_property_float_set_default(PointerRNA *ptr, PropertyRNA *prop, float value);
void RNA_property_float_get_default_array(PointerRNA *ptr, PropertyRNA *prop, float *values);
float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index);
@@ -1015,6 +1017,7 @@ bool RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, i
/* copy/reset */
bool RNA_property_copy(struct Main *bmain, PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index);
bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index);
+bool RNA_property_assign_default(PointerRNA *ptr, PropertyRNA *prop);
/* Path
*
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 2f23bc5eea9..1a212097c31 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -257,8 +257,7 @@ static void rna_idproperty_touch(IDProperty *idprop)
idprop->flag &= ~IDP_FLAG_GHOST;
}
-/* return a UI local ID prop definition for this prop */
-static IDProperty *rna_idproperty_ui(PropertyRNA *prop)
+static IDProperty *rna_idproperty_ui_container(PropertyRNA *prop)
{
IDProperty *idprop;
@@ -274,6 +273,14 @@ static IDProperty *rna_idproperty_ui(PropertyRNA *prop)
}
}
+ return idprop;
+}
+
+/* return a UI local ID prop definition for this prop */
+static IDProperty *rna_idproperty_ui(PropertyRNA *prop)
+{
+ IDProperty *idprop = rna_idproperty_ui_container(prop);
+
if (idprop) {
return IDP_GetPropertyTypeFromGroup(idprop, ((IDProperty *)prop)->name, IDP_GROUP);
}
@@ -281,6 +288,94 @@ static IDProperty *rna_idproperty_ui(PropertyRNA *prop)
return NULL;
}
+/* return or create a UI local ID prop definition for this prop */
+static IDProperty *rna_idproperty_ui_ensure(PointerRNA *ptr, PropertyRNA *prop, bool create)
+{
+ IDProperty *idprop = rna_idproperty_ui_container(prop);
+ IDPropertyTemplate dummy = { 0 };
+
+ if (idprop == NULL && create) {
+ IDProperty *props = RNA_struct_idprops(ptr, false);
+
+ /* Sanity check: props is the actual container of this property. */
+ if (props != NULL && BLI_findindex(&props->data.group, prop) >= 0) {
+ idprop = IDP_New(IDP_GROUP, &dummy, RNA_IDP_UI);
+
+ if (!IDP_AddToGroup(props, idprop)) {
+ IDP_FreeProperty(idprop);
+ return NULL;
+ }
+ }
+ }
+
+ if (idprop) {
+ const char *name = ((IDProperty *)prop)->name;
+ IDProperty *rv = IDP_GetPropertyTypeFromGroup(idprop, name, IDP_GROUP);
+
+ if (rv == NULL && create) {
+ rv = IDP_New(IDP_GROUP, &dummy, name);
+
+ if (!IDP_AddToGroup(idprop, rv)) {
+ IDP_FreeProperty(rv);
+ return NULL;
+ }
+ }
+
+ return rv;
+ }
+
+ return NULL;
+}
+
+static bool rna_idproperty_ui_set_default(PointerRNA *ptr, PropertyRNA *prop, const char type, IDPropertyTemplate *value)
+{
+ BLI_assert(ELEM(type, IDP_INT, IDP_DOUBLE));
+
+ if (prop->magic == RNA_MAGIC) {
+ return false;
+ }
+
+ /* attempt to get the local ID values */
+ IDProperty *idp_ui = rna_idproperty_ui_ensure(ptr, prop, value != NULL);
+
+ if (idp_ui == NULL) {
+ return (value == NULL);
+ }
+
+ IDProperty *item = IDP_GetPropertyTypeFromGroup(idp_ui, "default", type);
+
+ if (value == NULL) {
+ if (item != NULL) {
+ IDP_RemoveFromGroup(idp_ui, item);
+ }
+ }
+ else {
+ if (item != NULL) {
+ switch (type) {
+ case IDP_INT:
+ IDP_Int(item) = value->i;
+ break;
+ case IDP_DOUBLE:
+ IDP_Double(item) = value->d;
+ break;
+ default:
+ BLI_assert(false);
+ return false;
+ }
+ }
+ else {
+ item = IDP_New(type, value, "default");
+
+ if (!IDP_AddToGroup(idp_ui, item)) {
+ IDP_FreeProperty(item);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
IDProperty *RNA_struct_idprops(PointerRNA *ptr, bool create)
{
StructRNA *type = ptr->type;
@@ -2726,9 +2821,33 @@ void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, i
int RNA_property_int_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
{
IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
+
+ if (prop->magic != RNA_MAGIC) {
+ /* attempt to get the local ID values */
+ IDProperty *idp_ui = rna_idproperty_ui(prop);
+
+ if (idp_ui) {
+ IDProperty *item;
+
+ item = IDP_GetPropertyTypeFromGroup(idp_ui, "default", IDP_INT);
+ return item ? IDP_Int(item) : iprop->defaultvalue;
+ }
+ }
+
return iprop->defaultvalue;
}
+bool RNA_property_int_set_default(PointerRNA *ptr, PropertyRNA *prop, int value)
+{
+ if (value != 0) {
+ IDPropertyTemplate val = { .i = value };
+ return rna_idproperty_ui_set_default(ptr, prop, IDP_INT, &val);
+ }
+ else {
+ return rna_idproperty_ui_set_default(ptr, prop, IDP_INT, NULL);
+ }
+}
+
void RNA_property_int_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
{
IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
@@ -3023,9 +3142,32 @@ float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
BLI_assert(RNA_property_array_check(prop) == false);
+ if (prop->magic != RNA_MAGIC) {
+ /* attempt to get the local ID values */
+ IDProperty *idp_ui = rna_idproperty_ui(prop);
+
+ if (idp_ui) {
+ IDProperty *item;
+
+ item = IDP_GetPropertyTypeFromGroup(idp_ui, "default", IDP_DOUBLE);
+ return item ? IDP_Double(item) : fprop->defaultvalue;
+ }
+ }
+
return fprop->defaultvalue;
}
+bool RNA_property_float_set_default(PointerRNA *ptr, PropertyRNA *prop, float value)
+{
+ if (value != 0) {
+ IDPropertyTemplate val = { .d = value };
+ return rna_idproperty_ui_set_default(ptr, prop, IDP_DOUBLE, &val);
+ }
+ else {
+ return rna_idproperty_ui_set_default(ptr, prop, IDP_DOUBLE, NULL);
+ }
+}
+
void RNA_property_float_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, float *values)
{
FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
@@ -7257,6 +7399,31 @@ bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
}
}
+bool RNA_property_assign_default(PointerRNA *ptr, PropertyRNA *prop)
+{
+ if (!RNA_property_is_idprop(prop) || RNA_property_array_check(prop)) {
+ return false;
+ }
+
+ /* get and set the default values as appropriate for the various types */
+ switch (RNA_property_type(prop)) {
+ case PROP_INT:
+ {
+ int value = RNA_property_int_get(ptr, prop);
+ return RNA_property_int_set_default(ptr, prop, value);
+ }
+
+ case PROP_FLOAT:
+ {
+ float value = RNA_property_float_get(ptr, prop);
+ return RNA_property_float_set_default(ptr, prop, value);
+ }
+
+ default:
+ return false;
+ }
+}
+
static bool rna_property_override_operation_apply(
Main *bmain,
PointerRNA *ptr_local, PointerRNA *ptr_override, PointerRNA *ptr_storage,