Fix #76704: resetting socket values always resets to zero instead of default value

The fundamental limitation here was that RNA did not support different default values
for the same property yet (and all sockets of the same type have the same property).
This patch solves this by adding a new callback to rna property types to retrieve a
default value dynamically. Together with the socket declarations it's fairly easy to get
this working nowadays.

This also works for group nodes, because they use the socket declaration internally too.

Pull Request: https://projects.blender.org/blender/blender/pulls/122216
This commit is contained in:
Jacques Lucke
2024-05-24 22:16:59 +02:00
parent a6a5fd053a
commit 6b6657405f
6 changed files with 206 additions and 20 deletions

View File

@@ -494,6 +494,11 @@ void RNA_def_property_collection_funcs(PropertyRNA *prop,
const char *lookupint,
const char *lookupstring,
const char *assignint);
void RNA_def_property_float_default_func(PropertyRNA *prop, const char *get_default);
void RNA_def_property_int_default_func(PropertyRNA *prop, const char *get_default);
void RNA_def_property_boolean_default_func(PropertyRNA *prop, const char *get_default);
void RNA_def_property_srna(PropertyRNA *prop, const char *type);
void RNA_def_py_data(PropertyRNA *prop, void *py_data);

View File

@@ -4383,7 +4383,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_BOOLEAN: {
BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
fprintf(f,
"\t%s, %s, %s, %s, %s, %s, %s, %s, %d, ",
"\t%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, ",
rna_function_string(bprop->get),
rna_function_string(bprop->set),
rna_function_string(bprop->getarray),
@@ -4392,6 +4392,8 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
rna_function_string(bprop->set_ex),
rna_function_string(bprop->getarray_ex),
rna_function_string(bprop->setarray_ex),
rna_function_string(bprop->get_default),
rna_function_string(bprop->get_default_array),
bprop->defaultvalue);
if (prop->arraydimension && prop->totarraylength) {
fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
@@ -4427,6 +4429,11 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
fprintf(f, ", ");
rna_int_print(f, iprop->step);
fprintf(f, ", ");
fprintf(f,
"%s, %s",
rna_function_string(iprop->get_default),
rna_function_string(iprop->get_default_array));
fprintf(f, ", ");
rna_int_print(f, iprop->defaultvalue);
fprintf(f, ", ");
if (prop->arraydimension && prop->totarraylength) {
@@ -4464,6 +4471,11 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
fprintf(f, ", ");
rna_int_print(f, int(fprop->precision));
fprintf(f, ", ");
fprintf(f,
"%s, %s",
rna_function_string(fprop->get_default),
rna_function_string(fprop->get_default_array));
fprintf(f, ", ");
rna_float_print(f, fprop->defaultvalue);
fprintf(f, ", ");
if (prop->arraydimension && prop->totarraylength) {

View File

@@ -2512,6 +2512,11 @@ static void rna_property_boolean_get_default_array_values(PointerRNA *ptr,
BoolPropertyRNA *bprop,
bool *r_values)
{
if (bprop->get_default_array) {
bprop->get_default_array(ptr, &bprop->property, r_values);
return;
}
int length = bprop->property.totarraylength;
int out_length = RNA_property_array_length(ptr, (PropertyRNA *)bprop);
@@ -2674,7 +2679,7 @@ void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int inde
}
}
bool RNA_property_boolean_get_default(PointerRNA * /*ptr*/, PropertyRNA *prop)
bool RNA_property_boolean_get_default(PointerRNA *ptr, PropertyRNA *prop)
{
/* TODO: Make defaults work for IDProperties. */
BoolPropertyRNA *bprop = (BoolPropertyRNA *)rna_ensure_property(prop);
@@ -2701,6 +2706,9 @@ bool RNA_property_boolean_get_default(PointerRNA * /*ptr*/, PropertyRNA *prop)
}
return false;
}
if (bprop->get_default) {
return bprop->get_default(ptr, prop);
}
return bprop->defaultvalue;
}
@@ -2854,6 +2862,11 @@ static void rna_property_int_get_default_array_values(PointerRNA *ptr,
IntPropertyRNA *iprop,
int *r_values)
{
if (iprop->get_default_array) {
iprop->get_default_array(ptr, &iprop->property, r_values);
return;
}
int length = iprop->property.totarraylength;
int out_length = RNA_property_array_length(ptr, (PropertyRNA *)iprop);
@@ -3020,7 +3033,7 @@ void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, i
}
}
int RNA_property_int_get_default(PointerRNA * /*ptr*/, PropertyRNA *prop)
int RNA_property_int_get_default(PointerRNA *ptr, PropertyRNA *prop)
{
IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
@@ -3031,6 +3044,9 @@ int RNA_property_int_get_default(PointerRNA * /*ptr*/, PropertyRNA *prop)
return ui_data->default_value;
}
}
if (iprop->get_default) {
return iprop->get_default(ptr, prop);
}
return iprop->defaultvalue;
}
@@ -3207,6 +3223,11 @@ static void rna_property_float_get_default_array_values(PointerRNA *ptr,
FloatPropertyRNA *fprop,
float *r_values)
{
if (fprop->get_default_array) {
fprop->get_default_array(ptr, &fprop->property, r_values);
return;
}
int length = fprop->property.totarraylength;
int out_length = RNA_property_array_length(ptr, (PropertyRNA *)fprop);
@@ -3390,7 +3411,7 @@ void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index,
}
}
float RNA_property_float_get_default(PointerRNA * /*ptr*/, PropertyRNA *prop)
float RNA_property_float_get_default(PointerRNA *ptr, PropertyRNA *prop)
{
FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
@@ -3405,6 +3426,9 @@ float RNA_property_float_get_default(PointerRNA * /*ptr*/, PropertyRNA *prop)
return float(ui_data->default_value);
}
}
if (fprop->get_default) {
return fprop->get_default(ptr, prop);
}
return fprop->defaultvalue;
}

View File

@@ -3587,6 +3587,99 @@ void RNA_def_property_collection_funcs(PropertyRNA *prop,
}
}
void RNA_def_property_float_default_func(PropertyRNA *prop, const char *get_default)
{
StructRNA *srna = DefRNA.laststruct;
if (!DefRNA.preprocess) {
CLOG_ERROR(&LOG, "only during preprocessing");
return;
}
switch (prop->type) {
case PROP_FLOAT: {
FloatPropertyRNA *fprop = reinterpret_cast<FloatPropertyRNA *>(prop);
if (prop->arraydimension) {
if (get_default) {
fprop->get_default_array = (PropFloatArrayGetFuncEx)get_default;
}
}
else {
if (get_default) {
fprop->get_default = (PropFloatGetFuncEx)get_default;
}
}
break;
}
default: {
CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
DefRNA.error = true;
break;
}
}
}
void RNA_def_property_int_default_func(PropertyRNA *prop, const char *get_default)
{
StructRNA *srna = DefRNA.laststruct;
if (!DefRNA.preprocess) {
CLOG_ERROR(&LOG, "only during preprocessing");
return;
}
switch (prop->type) {
case PROP_INT: {
IntPropertyRNA *iprop = reinterpret_cast<IntPropertyRNA *>(prop);
if (prop->arraydimension) {
if (get_default) {
iprop->get_default_array = (PropIntArrayGetFuncEx)get_default;
}
}
else {
if (get_default) {
iprop->get_default = (PropIntGetFuncEx)get_default;
}
}
break;
}
default: {
CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
DefRNA.error = true;
break;
}
}
}
void RNA_def_property_boolean_default_func(PropertyRNA *prop, const char *get_default)
{
StructRNA *srna = DefRNA.laststruct;
if (!DefRNA.preprocess) {
CLOG_ERROR(&LOG, "only during preprocessing");
return;
}
switch (prop->type) {
case PROP_BOOLEAN: {
BoolPropertyRNA *bprop = reinterpret_cast<BoolPropertyRNA *>(prop);
if (prop->arraydimension) {
if (get_default) {
bprop->get_default_array = (PropBooleanArrayGetFuncEx)get_default;
}
}
else {
if (get_default) {
bprop->get_default = (PropBooleanGetFuncEx)get_default;
}
}
break;
}
default: {
CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
DefRNA.error = true;
break;
}
}
}
void RNA_def_property_srna(PropertyRNA *prop, const char *type)
{
const char *error = nullptr;

View File

@@ -411,6 +411,8 @@ struct BoolPropertyRNA {
PropBooleanArrayGetFuncEx getarray_ex;
PropBooleanArraySetFuncEx setarray_ex;
PropBooleanGetFuncEx get_default;
PropBooleanArrayGetFuncEx get_default_array;
bool defaultvalue;
const bool *defaultarray;
};
@@ -435,6 +437,8 @@ struct IntPropertyRNA {
int hardmin, hardmax;
int step;
PropIntGetFuncEx get_default;
PropIntArrayGetFuncEx get_default_array;
int defaultvalue;
const int *defaultarray;
};
@@ -460,6 +464,9 @@ struct FloatPropertyRNA {
float step;
int precision;
PropFloatGetFuncEx get_default;
PropFloatArrayGetFuncEx get_default_array;
float defaultvalue;
const float *defaultarray;
};

View File

@@ -52,6 +52,8 @@ const EnumPropertyItem rna_enum_node_socket_type_items[] = {
# include "DEG_depsgraph_build.hh"
# include "NOD_socket_declarations.hh"
# include "ED_node.hh"
extern FunctionRNA rna_NodeSocket_draw_func;
@@ -400,6 +402,60 @@ void rna_NodeSocketStandard_vector_range(
*softmax = dval->max;
}
float rna_NodeSocketStandard_float_default(PointerRNA *ptr, PropertyRNA * /*prop*/)
{
bNodeSocket *sock = static_cast<bNodeSocket *>(ptr->data);
if (!sock->runtime->declaration) {
return 0.0f;
}
auto *decl = static_cast<const blender::nodes::decl::Float *>(sock->runtime->declaration);
return decl->default_value;
}
int rna_NodeSocketStandard_int_default(PointerRNA *ptr, PropertyRNA * /*prop*/)
{
bNodeSocket *sock = static_cast<bNodeSocket *>(ptr->data);
if (!sock->runtime->declaration) {
return 0;
}
auto *decl = static_cast<const blender::nodes::decl::Int *>(sock->runtime->declaration);
return decl->default_value;
}
bool rna_NodeSocketStandard_boolean_default(PointerRNA *ptr, PropertyRNA * /*prop*/)
{
bNodeSocket *sock = static_cast<bNodeSocket *>(ptr->data);
if (!sock->runtime->declaration) {
return false;
}
auto *decl = static_cast<const blender::nodes::decl::Bool *>(sock->runtime->declaration);
return decl->default_value;
}
void rna_NodeSocketStandard_vector_default(PointerRNA *ptr,
PropertyRNA * /*prop*/,
float *r_values)
{
bNodeSocket *sock = static_cast<bNodeSocket *>(ptr->data);
if (!sock->runtime->declaration) {
std::fill_n(r_values, 3, 0.0f);
return;
}
auto *decl = static_cast<const blender::nodes::decl::Vector *>(sock->runtime->declaration);
std::copy_n(&decl->default_value.x, 3, r_values);
}
void rna_NodeSocketStandard_color_default(PointerRNA *ptr, PropertyRNA * /*prop*/, float *r_values)
{
bNodeSocket *sock = static_cast<bNodeSocket *>(ptr->data);
if (!sock->runtime->declaration) {
std::fill_n(r_values, 4, 0.0f);
return;
}
auto *decl = static_cast<const blender::nodes::decl::Color *>(sock->runtime->declaration);
std::copy_n(&decl->default_value.r, 4, r_values);
}
/* using a context update function here, to avoid searching the node if possible */
static void rna_NodeSocketStandard_value_update(bContext *C, PointerRNA *ptr)
{
@@ -778,6 +834,7 @@ static void rna_def_node_socket_float(BlenderRNA *brna,
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype);
RNA_def_property_float_sdna(prop, nullptr, "value");
RNA_def_property_float_funcs(prop, nullptr, nullptr, "rna_NodeSocketStandard_float_range");
RNA_def_property_float_default_func(prop, "rna_NodeSocketStandard_float_default");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
@@ -879,6 +936,7 @@ static void rna_def_node_socket_int(BlenderRNA *brna,
RNA_def_property_int_sdna(prop, nullptr, "value");
RNA_def_property_int_default(prop, value_default);
RNA_def_property_int_funcs(prop, nullptr, nullptr, "rna_NodeSocketStandard_int_range");
RNA_def_property_int_default_func(prop, "rna_NodeSocketStandard_int_default");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
@@ -947,6 +1005,7 @@ static void rna_def_node_socket_bool(BlenderRNA *brna, const char *identifier)
prop = RNA_def_property(srna, "default_value", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "value", 1);
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_boolean_default_func(prop, "rna_NodeSocketStandard_boolean_default");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
@@ -1049,21 +1108,6 @@ static void rna_def_node_socket_vector(BlenderRNA *brna,
{
StructRNA *srna;
PropertyRNA *prop;
const float *value_default;
/* choose sensible common default based on subtype */
switch (subtype) {
case PROP_DIRECTION: {
static const float default_direction[3] = {0.0f, 0.0f, 1.0f};
value_default = default_direction;
break;
}
default: {
static const float default_vector[3] = {0.0f, 0.0f, 0.0f};
value_default = default_vector;
break;
}
}
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Vector Node Socket", "3D vector socket of a node");
@@ -1073,7 +1117,7 @@ static void rna_def_node_socket_vector(BlenderRNA *brna,
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype);
RNA_def_property_float_sdna(prop, nullptr, "value");
RNA_def_property_float_array_default(prop, value_default);
RNA_def_property_float_default_func(prop, "rna_NodeSocketStandard_vector_default");
RNA_def_property_float_funcs(prop, nullptr, nullptr, "rna_NodeSocketStandard_vector_range");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
@@ -1143,6 +1187,7 @@ static void rna_def_node_socket_color(BlenderRNA *brna, const char *identifier)
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, nullptr, "value");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_float_default_func(prop, "rna_NodeSocketStandard_color_default");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);