WIP: use generic copy-on-write system to avoid unnecessary data copies #104470
|
@ -32,6 +32,9 @@ class IDPropertyDeleter {
|
|||
}
|
||||
};
|
||||
|
||||
/** \brief Allocate a new IDProperty of type IDP_BOOLEAN, set its name and value. */
|
||||
std::unique_ptr<IDProperty, IDPropertyDeleter> create_bool(StringRefNull prop_name, bool value);
|
||||
|
||||
/** \brief Allocate a new IDProperty of type IDP_INT, set its name and value. */
|
||||
std::unique_ptr<IDProperty, IDPropertyDeleter> create(StringRefNull prop_name, int32_t value);
|
||||
|
||||
|
|
|
@ -21,6 +21,15 @@ std::unique_ptr<IDProperty, IDPropertyDeleter> create(const StringRefNull prop_n
|
|||
return std::unique_ptr<IDProperty, IDPropertyDeleter>(property);
|
||||
}
|
||||
|
||||
std::unique_ptr<IDProperty, IDPropertyDeleter> create_bool(const StringRefNull prop_name,
|
||||
bool value)
|
||||
{
|
||||
IDPropertyTemplate prop_template{0};
|
||||
prop_template.i = value;
|
||||
IDProperty *property = IDP_New(IDP_BOOLEAN, &prop_template, prop_name.c_str());
|
||||
return std::unique_ptr<IDProperty, IDPropertyDeleter>(property);
|
||||
}
|
||||
|
||||
std::unique_ptr<IDProperty, IDPropertyDeleter> create(const StringRefNull prop_name, float value)
|
||||
{
|
||||
IDPropertyTemplate prop_template{0};
|
||||
|
|
|
@ -4216,7 +4216,9 @@ static int get_particle_uv(Mesh *mesh,
|
|||
int i;
|
||||
|
||||
tf = static_cast<const MTFace *>(CustomData_get_layer_named(&mesh->fdata, CD_MTFACE, name));
|
||||
|
||||
if (tf == nullptr) {
|
||||
tf = static_cast<const MTFace *>(CustomData_get_layer(&mesh->fdata, CD_MTFACE));
|
||||
}
|
||||
if (tf == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ static eDRWColorManagementType drw_color_management_type_for_space_image(const S
|
|||
{
|
||||
Image *image = sima.image;
|
||||
|
||||
/* Use inverse logic as there isn't a setting for `Color And Alpha`. */
|
||||
/* Use inverse logic as there isn't a setting for `Color & Alpha`. */
|
||||
const eSpaceImage_Flag display_channels_mode = static_cast<eSpaceImage_Flag>(sima.flag);
|
||||
const bool display_color_channel = (display_channels_mode & (SI_SHOW_ALPHA | SI_SHOW_ZBUF)) == 0;
|
||||
|
||||
|
|
|
@ -89,7 +89,8 @@ static void generate_strokes_actual(
|
|||
lmd->silhouette_selection,
|
||||
lmd->source_vertex_group,
|
||||
lmd->vgname,
|
||||
lmd->flags);
|
||||
lmd->flags,
|
||||
lmd->calculation_flags);
|
||||
}
|
||||
|
||||
static bool isModifierDisabled(GpencilModifierData *md)
|
||||
|
|
|
@ -923,7 +923,8 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
|
|||
uint8_t silhouette_mode,
|
||||
const char *source_vgname,
|
||||
const char *vgname,
|
||||
int modifier_flags);
|
||||
int modifier_flags,
|
||||
int modifier_calculation_flags);
|
||||
|
||||
/**
|
||||
* Length is in image space.
|
||||
|
|
|
@ -5156,7 +5156,8 @@ static void lineart_gpencil_generate(LineartCache *cache,
|
|||
uchar silhouette_mode,
|
||||
const char *source_vgname,
|
||||
const char *vgname,
|
||||
int modifier_flags)
|
||||
int modifier_flags,
|
||||
int modifier_calculation_flags)
|
||||
{
|
||||
if (cache == nullptr) {
|
||||
if (G.debug_value == 4000) {
|
||||
|
@ -5182,8 +5183,8 @@ static void lineart_gpencil_generate(LineartCache *cache,
|
|||
/* (!orig_col && !orig_ob) means the whole scene is selected. */
|
||||
|
||||
int enabled_types = cache->all_enabled_edge_types;
|
||||
bool invert_input = modifier_flags & LRT_GPENCIL_INVERT_SOURCE_VGROUP;
|
||||
bool match_output = modifier_flags & LRT_GPENCIL_MATCH_OUTPUT_VGROUP;
|
||||
bool invert_input = modifier_calculation_flags & LRT_GPENCIL_INVERT_SOURCE_VGROUP;
|
||||
bool match_output = modifier_calculation_flags & LRT_GPENCIL_MATCH_OUTPUT_VGROUP;
|
||||
bool inverse_silhouette = modifier_flags & LRT_GPENCIL_INVERT_SILHOUETTE_FILTER;
|
||||
|
||||
LISTBASE_FOREACH (LineartEdgeChain *, ec, &cache->chains) {
|
||||
|
@ -5381,7 +5382,8 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
|
|||
uchar silhouette_mode,
|
||||
const char *source_vgname,
|
||||
const char *vgname,
|
||||
int modifier_flags)
|
||||
int modifier_flags,
|
||||
int modifier_calculation_flags)
|
||||
{
|
||||
|
||||
if (!gpl || !gpf || !ob) {
|
||||
|
@ -5427,5 +5429,6 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
|
|||
silhouette_mode,
|
||||
source_vgname,
|
||||
vgname,
|
||||
modifier_flags);
|
||||
modifier_flags,
|
||||
modifier_calculation_flags);
|
||||
}
|
||||
|
|
|
@ -136,7 +136,8 @@ static bool bake_strokes(Object *ob,
|
|||
lmd->silhouette_selection,
|
||||
lmd->source_vertex_group,
|
||||
lmd->vgname,
|
||||
lmd->flags);
|
||||
lmd->flags,
|
||||
lmd->calculation_flags);
|
||||
|
||||
if (!(lmd->flags & LRT_GPENCIL_USE_CACHE)) {
|
||||
/* Clear local cache. */
|
||||
|
|
|
@ -986,16 +986,128 @@ static char *rna_MeshUVLoopLayer_path(const PointerRNA *ptr)
|
|||
|
||||
static void rna_MeshUVLoopLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
Mesh *me = rna_mesh(ptr);
|
||||
Mesh *mesh = rna_mesh(ptr);
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
rna_iterator_array_begin(
|
||||
iter, layer->data, sizeof(float[2]), (me->edit_mesh) ? 0 : me->totloop, 0, NULL);
|
||||
iter, layer->data, sizeof(float[2]), (mesh->edit_mesh) ? 0 : mesh->totloop, 0, NULL);
|
||||
}
|
||||
|
||||
static int rna_MeshUVLoopLayer_data_length(PointerRNA *ptr)
|
||||
{
|
||||
Mesh *mesh = rna_mesh(ptr);
|
||||
return (mesh->edit_mesh) ? 0 : mesh->totloop;
|
||||
}
|
||||
|
||||
static MBoolProperty *MeshUVLoopLayer_get_bool_layer(Mesh *mesh, char const *name)
|
||||
{
|
||||
void *layer = CustomData_get_layer_named_for_write(
|
||||
&mesh->ldata, CD_PROP_BOOL, name, mesh->totloop);
|
||||
if (layer == NULL) {
|
||||
layer = CustomData_add_layer_named(
|
||||
&mesh->ldata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, mesh->totloop, name);
|
||||
}
|
||||
|
||||
BLI_assert(layer);
|
||||
|
||||
return (MBoolProperty *)layer;
|
||||
}
|
||||
|
||||
static void bool_layer_begin(CollectionPropertyIterator *iter,
|
||||
PointerRNA *ptr,
|
||||
const char *(*layername_func)(const char *uv_name, char *name))
|
||||
{
|
||||
char bool_layer_name[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
Mesh *mesh = rna_mesh(ptr);
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
layername_func(layer->name, bool_layer_name);
|
||||
|
||||
rna_iterator_array_begin(iter,
|
||||
MeshUVLoopLayer_get_bool_layer(mesh, bool_layer_name),
|
||||
sizeof(MBoolProperty),
|
||||
(mesh->edit_mesh) ? 0 : mesh->totloop,
|
||||
0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int bool_layer_lookup_int(PointerRNA *ptr,
|
||||
int index,
|
||||
PointerRNA *r_ptr,
|
||||
const char *(*layername_func)(const char *uv_name, char *name))
|
||||
{
|
||||
char bool_layer_name[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
Mesh *mesh = rna_mesh(ptr);
|
||||
if (mesh->edit_mesh || index < 0 || index >= mesh->totloop) {
|
||||
return 0;
|
||||
}
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
layername_func(layer->name, bool_layer_name);
|
||||
|
||||
r_ptr->owner_id = &mesh->id;
|
||||
r_ptr->type = &RNA_BoolAttributeValue;
|
||||
r_ptr->data = MeshUVLoopLayer_get_bool_layer(mesh, bool_layer_name) + index;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Collection accessors for vert_select. */
|
||||
static void rna_MeshUVLoopLayer_vert_select_begin(CollectionPropertyIterator *iter,
|
||||
PointerRNA *ptr)
|
||||
{
|
||||
bool_layer_begin(iter, ptr, BKE_uv_map_vert_select_name_get);
|
||||
}
|
||||
|
||||
static int rna_MeshUVLoopLayer_vert_select_lookup_int(PointerRNA *ptr,
|
||||
int index,
|
||||
PointerRNA *r_ptr)
|
||||
{
|
||||
return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_vert_select_name_get);
|
||||
}
|
||||
|
||||
/* Collection accessors for edge_select. */
|
||||
static void rna_MeshUVLoopLayer_edge_select_begin(CollectionPropertyIterator *iter,
|
||||
PointerRNA *ptr)
|
||||
{
|
||||
bool_layer_begin(iter, ptr, BKE_uv_map_edge_select_name_get);
|
||||
}
|
||||
|
||||
static int rna_MeshUVLoopLayer_edge_select_lookup_int(PointerRNA *ptr,
|
||||
int index,
|
||||
PointerRNA *r_ptr)
|
||||
{
|
||||
return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_edge_select_name_get);
|
||||
}
|
||||
|
||||
/* Collection accessors for pin. */
|
||||
static void rna_MeshUVLoopLayer_pin_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
bool_layer_begin(iter, ptr, BKE_uv_map_pin_name_get);
|
||||
}
|
||||
|
||||
static int rna_MeshUVLoopLayer_pin_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
|
||||
{
|
||||
return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_pin_name_get);
|
||||
}
|
||||
|
||||
static void rna_MeshUVLoopLayer_uv_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
Mesh *me = rna_mesh(ptr);
|
||||
return (me->edit_mesh) ? 0 : me->totloop;
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
|
||||
rna_iterator_array_begin(
|
||||
iter, layer->data, sizeof(float[2]), (me->edit_mesh) ? 0 : me->totloop, 0, NULL);
|
||||
}
|
||||
|
||||
int rna_MeshUVLoopLayer_uv_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
|
||||
{
|
||||
Mesh *mesh = rna_mesh(ptr);
|
||||
if (mesh->edit_mesh || index < 0 || index >= mesh->totloop) {
|
||||
return 0;
|
||||
}
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
|
||||
r_ptr->owner_id = &mesh->id;
|
||||
r_ptr->type = &RNA_Float2AttributeValue;
|
||||
r_ptr->data = (float *)layer->data + 2 * index;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool rna_MeshUVLoopLayer_active_render_get(PointerRNA *ptr)
|
||||
|
@ -2801,8 +2913,63 @@ static void rna_def_mloopuv(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Active Clone", "Set the map as active for cloning");
|
||||
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
|
||||
|
||||
prop = RNA_def_property(srna, "uv", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "Float2AttributeValue");
|
||||
RNA_def_property_ui_text(prop, "UV", "UV coordinates on face corners");
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_MeshUVLoopLayer_uv_begin",
|
||||
"rna_iterator_array_next",
|
||||
"rna_iterator_array_end",
|
||||
"rna_iterator_array_get",
|
||||
"rna_MeshUVLoopLayer_data_length",
|
||||
"rna_MeshUVLoopLayer_uv_lookup_int",
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "vertex_selection", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "BoolAttributeValue");
|
||||
RNA_def_property_ui_text(
|
||||
prop, "UV Vertex Selection", "Selection state of the face corner the UV editor");
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_MeshUVLoopLayer_vert_select_begin",
|
||||
"rna_iterator_array_next",
|
||||
"rna_iterator_array_end",
|
||||
"rna_iterator_array_get",
|
||||
"rna_MeshUVLoopLayer_data_length",
|
||||
"rna_MeshUVLoopLayer_vert_select_lookup_int",
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "edge_selection", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "BoolAttributeValue");
|
||||
RNA_def_property_ui_text(
|
||||
prop, "UV Edge Selection", "Selection state of the edge in the UV editor");
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_MeshUVLoopLayer_edge_select_begin",
|
||||
"rna_iterator_array_next",
|
||||
"rna_iterator_array_end",
|
||||
"rna_iterator_array_get",
|
||||
"rna_MeshUVLoopLayer_data_length",
|
||||
"rna_MeshUVLoopLayer_edge_select_lookup_int",
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "pin", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "BoolAttributeValue");
|
||||
RNA_def_property_ui_text(prop, "UV Pin", "UV pinned state in the uv editor");
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_MeshUVLoopLayer_pin_begin",
|
||||
"rna_iterator_array_next",
|
||||
"rna_iterator_array_end",
|
||||
"rna_iterator_array_get",
|
||||
"rna_MeshUVLoopLayer_data_length",
|
||||
"rna_MeshUVLoopLayer_pin_lookup_int",
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
srna = RNA_def_struct(brna, "MeshUVLoop", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Mesh UV Layer", "Layer of UV coordinates in a Mesh data-block");
|
||||
RNA_def_struct_ui_text(
|
||||
srna, "Mesh UV Layer", "(Deprecated) Layer of UV coordinates in a Mesh data-block");
|
||||
RNA_def_struct_path_func(srna, "rna_MeshUVLoop_path");
|
||||
|
||||
prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_XYZ);
|
||||
|
|
|
@ -9197,11 +9197,13 @@ static void def_cmp_denoise(StructRNA *srna)
|
|||
|
||||
prop = RNA_def_property(srna, "use_hdr", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "hdr", 0);
|
||||
RNA_def_property_boolean_default(prop, true);
|
||||
RNA_def_property_ui_text(prop, "HDR", "Process HDR images");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "prefilter", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, prefilter_items);
|
||||
RNA_def_property_enum_default(prop, CMP_NODE_DENOISE_PREFILTER_ACCURATE);
|
||||
RNA_def_property_ui_text(prop, "", "Denoising prefilter");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
|
|
@ -371,7 +371,7 @@ static const EnumPropertyItem display_channels_items[] = {
|
|||
{SI_USE_ALPHA,
|
||||
"COLOR_ALPHA",
|
||||
ICON_IMAGE_RGB_ALPHA,
|
||||
"Color and Alpha",
|
||||
"Color & Alpha",
|
||||
"Display image with RGB colors and alpha transparency"},
|
||||
{0, "COLOR", ICON_IMAGE_RGB, "Color", "Display image with RGB colors"},
|
||||
{SI_SHOW_ALPHA, "ALPHA", ICON_IMAGE_ALPHA, "Alpha", "Display alpha transparency channel"},
|
||||
|
@ -5773,7 +5773,7 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
|
|||
{SEQ_USE_ALPHA,
|
||||
"COLOR_ALPHA",
|
||||
ICON_IMAGE_RGB_ALPHA,
|
||||
"Color and Alpha",
|
||||
"Color & Alpha",
|
||||
"Display image with RGB colors and alpha transparency"},
|
||||
{0, "COLOR", ICON_IMAGE_RGB, "Color", "Display image with RGB colors"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
|
@ -7363,7 +7363,7 @@ static void rna_def_space_node(BlenderRNA *brna)
|
|||
{SNODE_USE_ALPHA,
|
||||
"COLOR_ALPHA",
|
||||
ICON_IMAGE_RGB_ALPHA,
|
||||
"Color and Alpha",
|
||||
"Color & Alpha",
|
||||
"Display image with RGB colors and alpha transparency"},
|
||||
{0, "COLOR", ICON_IMAGE_RGB, "Color", "Display image with RGB colors"},
|
||||
{SNODE_SHOW_ALPHA, "ALPHA", ICON_IMAGE_ALPHA, "Alpha", "Display alpha transparency channel"},
|
||||
|
|
|
@ -496,10 +496,8 @@ id_property_create_from_socket(const bNodeSocket &socket)
|
|||
case SOCK_BOOLEAN: {
|
||||
const bNodeSocketValueBoolean *value = static_cast<const bNodeSocketValueBoolean *>(
|
||||
socket.default_value);
|
||||
auto property = bke::idprop::create(socket.identifier, int(value->value));
|
||||
IDPropertyUIDataInt *ui_data = (IDPropertyUIDataInt *)IDP_ui_data_ensure(property.get());
|
||||
ui_data->min = ui_data->soft_min = 0;
|
||||
ui_data->max = ui_data->soft_max = 1;
|
||||
auto property = bke::idprop::create_bool(socket.identifier, value->value);
|
||||
IDPropertyUIDataBool *ui_data = (IDPropertyUIDataBool *)IDP_ui_data_ensure(property.get());
|
||||
ui_data->default_value = value->value != 0;
|
||||
return property;
|
||||
}
|
||||
|
@ -553,7 +551,7 @@ static bool id_property_type_matches_socket(const bNodeSocket &socket, const IDP
|
|||
case SOCK_RGBA:
|
||||
return property.type == IDP_ARRAY && property.subtype == IDP_FLOAT && property.len == 4;
|
||||
case SOCK_BOOLEAN:
|
||||
return property.type == IDP_INT;
|
||||
return property.type == IDP_BOOLEAN;
|
||||
case SOCK_STRING:
|
||||
return property.type == IDP_STRING;
|
||||
case SOCK_OBJECT:
|
||||
|
@ -601,7 +599,7 @@ static void init_socket_cpp_value_from_property(const IDProperty &property,
|
|||
break;
|
||||
}
|
||||
case SOCK_BOOLEAN: {
|
||||
bool value = IDP_Int(&property) != 0;
|
||||
const bool value = IDP_Bool(&property);
|
||||
new (r_value) ValueOrField<bool>(value);
|
||||
break;
|
||||
}
|
||||
|
@ -682,16 +680,23 @@ void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd)
|
|||
|
||||
if (old_properties != nullptr) {
|
||||
IDProperty *old_prop = IDP_GetPropertyFromGroup(old_properties, socket->identifier);
|
||||
if (old_prop != nullptr && id_property_type_matches_socket(*socket, *old_prop)) {
|
||||
/* #IDP_CopyPropertyContent replaces the UI data as well, which we don't (we only
|
||||
* want to replace the values). So release it temporarily and replace it after. */
|
||||
IDPropertyUIData *ui_data = new_prop->ui_data;
|
||||
new_prop->ui_data = nullptr;
|
||||
IDP_CopyPropertyContent(new_prop, old_prop);
|
||||
if (new_prop->ui_data != nullptr) {
|
||||
IDP_ui_data_free(new_prop);
|
||||
if (old_prop != nullptr) {
|
||||
if (id_property_type_matches_socket(*socket, *old_prop)) {
|
||||
/* #IDP_CopyPropertyContent replaces the UI data as well, which we don't (we only
|
||||
* want to replace the values). So release it temporarily and replace it after. */
|
||||
IDPropertyUIData *ui_data = new_prop->ui_data;
|
||||
new_prop->ui_data = nullptr;
|
||||
IDP_CopyPropertyContent(new_prop, old_prop);
|
||||
if (new_prop->ui_data != nullptr) {
|
||||
IDP_ui_data_free(new_prop);
|
||||
}
|
||||
new_prop->ui_data = ui_data;
|
||||
}
|
||||
else if (old_prop->type == IDP_INT && new_prop->type == IDP_BOOLEAN) {
|
||||
/* Support versioning from integer to boolean property values. The actual value is stored
|
||||
* in the same variable for both types. */
|
||||
new_prop->data.val = old_prop->data.val != 0;
|
||||
}
|
||||
new_prop->ui_data = ui_data;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1575,9 +1580,30 @@ static void add_attribute_search_or_value_buttons(const bContext &C,
|
|||
uiLayout *split = uiLayoutSplit(layout, 0.4f, false);
|
||||
uiLayout *name_row = uiLayoutRow(split, false);
|
||||
uiLayoutSetAlignment(name_row, UI_LAYOUT_ALIGN_RIGHT);
|
||||
uiItemL(name_row, socket.name, ICON_NONE);
|
||||
|
||||
const int use_attribute = RNA_int_get(md_ptr, rna_path_use_attribute.c_str()) != 0;
|
||||
if (socket.type == SOCK_BOOLEAN && !use_attribute) {
|
||||
uiItemL(name_row, "", ICON_NONE);
|
||||
}
|
||||
else {
|
||||
uiItemL(name_row, socket.name, ICON_NONE);
|
||||
}
|
||||
|
||||
uiLayout *prop_row = uiLayoutRow(split, true);
|
||||
if (socket.type == SOCK_BOOLEAN) {
|
||||
uiLayoutSetPropSep(prop_row, false);
|
||||
uiLayoutSetAlignment(prop_row, UI_LAYOUT_ALIGN_EXPAND);
|
||||
}
|
||||
|
||||
if (use_attribute) {
|
||||
add_attribute_search_button(C, prop_row, nmd, md_ptr, rna_path_attribute_name, socket, false);
|
||||
uiItemL(layout, "", ICON_BLANK1);
|
||||
}
|
||||
else {
|
||||
const char *name = socket.type == SOCK_BOOLEAN ? socket.name : "";
|
||||
uiItemR(prop_row, md_ptr, rna_path.c_str(), 0, name, ICON_NONE);
|
||||
uiItemDecoratorR(layout, md_ptr, rna_path.c_str(), -1);
|
||||
}
|
||||
|
||||
PointerRNA props;
|
||||
uiItemFullO(prop_row,
|
||||
|
@ -1590,16 +1616,6 @@ static void add_attribute_search_or_value_buttons(const bContext &C,
|
|||
&props);
|
||||
RNA_string_set(&props, "modifier_name", nmd.modifier.name);
|
||||
RNA_string_set(&props, "prop_path", rna_path_use_attribute.c_str());
|
||||
|
||||
const int use_attribute = RNA_int_get(md_ptr, rna_path_use_attribute.c_str()) != 0;
|
||||
if (use_attribute) {
|
||||
add_attribute_search_button(C, prop_row, nmd, md_ptr, rna_path_attribute_name, socket, false);
|
||||
uiItemL(layout, "", ICON_BLANK1);
|
||||
}
|
||||
else {
|
||||
uiItemR(prop_row, md_ptr, rna_path.c_str(), 0, "", ICON_NONE);
|
||||
uiItemDecoratorR(layout, md_ptr, rna_path.c_str(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Drawing the properties manually with #uiItemR instead of #uiDefAutoButsRNA allows using
|
||||
|
@ -1665,6 +1681,9 @@ static void draw_property_for_socket(const bContext &C,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!input_has_attribute_toggle(*nmd->node_group, socket_index)) {
|
||||
uiItemL(row, "", ICON_BLANK1);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_property_for_output_socket(const bContext &C,
|
||||
|
@ -1854,9 +1873,33 @@ static void blendWrite(BlendWriter *writer, const ID * /*id_owner*/, const Modif
|
|||
BLO_write_struct(writer, NodesModifierData, nmd);
|
||||
|
||||
if (nmd->settings.properties != nullptr) {
|
||||
/* Boolean properties are added automatically for boolean node group inputs. Integer properties
|
||||
* are automatically converted to boolean sockets where applicable as well. However, boolean
|
||||
* properties will crash old versions of Blender, so convert them to integer properties for
|
||||
* writing. The actual value is stored in the same variable for both types */
|
||||
Map<IDProperty *, IDPropertyUIDataBool *> boolean_props;
|
||||
LISTBASE_FOREACH (IDProperty *, prop, &nmd->settings.properties->data.group) {
|
||||
if (prop->type == IDP_BOOLEAN) {
|
||||
boolean_props.add_new(prop, reinterpret_cast<IDPropertyUIDataBool *>(prop->ui_data));
|
||||
prop->type = IDP_INT;
|
||||
prop->ui_data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that the property settings are based on the socket type info
|
||||
* and don't necessarily need to be written, but we can't just free them. */
|
||||
IDP_BlendWrite(writer, nmd->settings.properties);
|
||||
|
||||
LISTBASE_FOREACH (IDProperty *, prop, &nmd->settings.properties->data.group) {
|
||||
if (prop->type == IDP_INT) {
|
||||
if (IDPropertyUIDataBool **ui_data = boolean_props.lookup_ptr(prop)) {
|
||||
prop->type = IDP_BOOLEAN;
|
||||
if (ui_data) {
|
||||
prop->ui_data = reinterpret_cast<IDPropertyUIData *>(*ui_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue