Attributes: Hide internal UI attributes and disallow procedural access
This commit hides "UI attributes" described in T97452 from the UI lists in mesh, curve, and point cloud properties, and disallow accessing them in geometry nodes. Internal UI attributes like selection and hiding values should use the attribute system for simplicity and performance, but we don't want to expose those attributes in the attribute panel, which is meant for regular user interaction. Procedural access may be misleading or cause problems, as described in the design task above. These attributes are added by two upcoming patches: D14934, D14685 Differential Revision: https://developer.blender.org/D15069
This commit is contained in:
parent
39c14f4e84
commit
4669178fc3
Notes:
blender-bot
2023-02-14 09:33:11 +01:00
Referenced by commit 997ff54d30
, Fix: UI: broken texpaintslot/color attributes/attributes name filtering
Referenced by issue #102878, Regression: UI texpaintslot/color attributes/attributes name filtering broken
|
@ -78,6 +78,16 @@ class CURVES_MT_add_attribute(Menu):
|
|||
|
||||
|
||||
class CURVES_UL_attributes(UIList):
|
||||
def filter_items(self, context, data, property):
|
||||
attributes = getattr(data, property)
|
||||
flags = []
|
||||
indices = [i for i in range(len(attributes))]
|
||||
|
||||
for index, item in enumerate(attributes):
|
||||
flags.append(self.bitflag_filter_item if item.is_internal else 0)
|
||||
|
||||
return flags, indices
|
||||
|
||||
def draw_item(self, _context, layout, _data, attribute, _icon, _active_data, _active_propname, _index):
|
||||
data_type = attribute.bl_rna.properties['data_type'].enum_items[attribute.data_type]
|
||||
domain = attribute.bl_rna.properties['domain'].enum_items[attribute.domain]
|
||||
|
|
|
@ -497,6 +497,16 @@ class MESH_UL_attributes(UIList):
|
|||
'CORNER': "Face Corner",
|
||||
}
|
||||
|
||||
def filter_items(self, context, data, property):
|
||||
attributes = getattr(data, property)
|
||||
flags = []
|
||||
indices = [i for i in range(len(attributes))]
|
||||
|
||||
for index, item in enumerate(attributes):
|
||||
flags.append(self.bitflag_filter_item if item.is_internal else 0)
|
||||
|
||||
return flags, indices
|
||||
|
||||
def draw_item(self, _context, layout, _data, attribute, _icon, _active_data, _active_propname, _index):
|
||||
data_type = attribute.bl_rna.properties['data_type'].enum_items[attribute.data_type]
|
||||
|
||||
|
@ -576,7 +586,7 @@ class ColorAttributesListBase():
|
|||
'CORNER': "Face Corner",
|
||||
}
|
||||
|
||||
def filter_items(self, _context, data, property):
|
||||
def filter_items(self, context, data, property):
|
||||
attrs = getattr(data, property)
|
||||
ret = []
|
||||
idxs = []
|
||||
|
@ -584,7 +594,8 @@ class ColorAttributesListBase():
|
|||
for idx, item in enumerate(attrs):
|
||||
skip = (
|
||||
(item.domain not in {"POINT", "CORNER"}) or
|
||||
(item.data_type not in {"FLOAT_COLOR", "BYTE_COLOR"})
|
||||
(item.data_type not in {"FLOAT_COLOR", "BYTE_COLOR"}) or
|
||||
(not item.is_internal)
|
||||
)
|
||||
ret.append(self.bitflag_filter_item if not skip else 0)
|
||||
idxs.append(idx)
|
||||
|
|
|
@ -67,6 +67,16 @@ class POINTCLOUD_MT_add_attribute(Menu):
|
|||
|
||||
|
||||
class POINTCLOUD_UL_attributes(UIList):
|
||||
def filter_items(self, context, data, property):
|
||||
attributes = getattr(data, property)
|
||||
flags = []
|
||||
indices = [i for i in range(len(attributes))]
|
||||
|
||||
for index, item in enumerate(attributes):
|
||||
flags.append(self.bitflag_filter_item if item.is_internal else 0)
|
||||
|
||||
return flags, indices
|
||||
|
||||
def draw_item(self, _context, layout, _data, attribute, _icon, _active_data, _active_propname, _index):
|
||||
data_type = attribute.bl_rna.properties['data_type'].enum_items[attribute.data_type]
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ typedef enum AttributeDomainMask {
|
|||
/* Attributes. */
|
||||
|
||||
bool BKE_id_attributes_supported(struct ID *id);
|
||||
bool BKE_attribute_allow_procedural_access(const char *attribute_name);
|
||||
|
||||
/**
|
||||
* Create a new attribute layer.
|
||||
|
|
|
@ -77,6 +77,9 @@ class AttributeIDRef {
|
|||
friend std::ostream &operator<<(std::ostream &stream, const AttributeIDRef &attribute_id);
|
||||
};
|
||||
|
||||
bool allow_procedural_attribute_access(StringRef attribute_name);
|
||||
extern const char *no_procedural_access_message;
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_attribute_access.hh"
|
||||
#include "BKE_curves.h"
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_editmesh.h"
|
||||
|
@ -116,6 +117,11 @@ bool BKE_id_attributes_supported(ID *id)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool BKE_attribute_allow_procedural_access(const char *attribute_name)
|
||||
{
|
||||
return blender::bke::allow_procedural_attribute_access(attribute_name);
|
||||
}
|
||||
|
||||
bool BKE_id_attribute_rename(ID *id,
|
||||
CustomDataLayer *layer,
|
||||
const char *new_name,
|
||||
|
|
|
@ -55,6 +55,14 @@ std::ostream &operator<<(std::ostream &stream, const AttributeIDRef &attribute_i
|
|||
return stream;
|
||||
}
|
||||
|
||||
const char *no_procedural_access_message =
|
||||
"This attribute can not be accessed in a procedural context";
|
||||
|
||||
bool allow_procedural_attribute_access(StringRef attribute_name)
|
||||
{
|
||||
return !attribute_name.startswith(".selection");
|
||||
}
|
||||
|
||||
static int attribute_data_type_complexity(const CustomDataType data_type)
|
||||
{
|
||||
switch (data_type) {
|
||||
|
|
|
@ -91,6 +91,9 @@ void attribute_search_add_items(StringRefNull str,
|
|||
if (item->name == "normal" && item->domain == ATTR_DOMAIN_FACE) {
|
||||
continue;
|
||||
}
|
||||
if (!bke::allow_procedural_attribute_access(item->name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BLI_string_search_add(search, item->name.c_str(), (void *)item, 0);
|
||||
}
|
||||
|
|
|
@ -81,6 +81,9 @@ void GeometryDataSource::foreach_default_column_ids(
|
|||
if (attribute_id.is_anonymous()) {
|
||||
return true;
|
||||
}
|
||||
if (!bke::allow_procedural_attribute_access(attribute_id.name())) {
|
||||
return true;
|
||||
}
|
||||
SpreadsheetColumnID column_id;
|
||||
column_id.name = (char *)attribute_id.name().data();
|
||||
fn(column_id, false);
|
||||
|
|
|
@ -232,6 +232,12 @@ static int rna_Attribute_domain_get(PointerRNA *ptr)
|
|||
return BKE_id_attribute_domain(ptr->owner_id, ptr->data);
|
||||
}
|
||||
|
||||
static bool rna_Attribute_is_internal_get(PointerRNA *ptr)
|
||||
{
|
||||
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
|
||||
return BKE_attribute_allow_procedural_access(layer->name);
|
||||
}
|
||||
|
||||
static void rna_Attribute_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
ID *id = ptr->owner_id;
|
||||
|
@ -930,6 +936,12 @@ static void rna_def_attribute(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Domain", "Domain of the Attribute");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
|
||||
prop = RNA_def_property(srna, "is_internal", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_Attribute_is_internal_get", NULL);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Is Internal", "The attribute is meant for internal use by Blender");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
|
||||
/* types */
|
||||
rna_def_attribute_float(brna);
|
||||
rna_def_attribute_float_vector(brna);
|
||||
|
@ -942,7 +954,7 @@ static void rna_def_attribute(BlenderRNA *brna)
|
|||
rna_def_attribute_int8(brna);
|
||||
}
|
||||
|
||||
/* Mesh/PointCloud/Hair.attributes */
|
||||
/* Mesh/PointCloud/Curves.attributes */
|
||||
static void rna_def_attribute_group(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
|
|
@ -82,6 +82,11 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
if (!bke::allow_procedural_attribute_access(name)) {
|
||||
params.error_message_add(NodeWarningType::Info, TIP_(bke::no_procedural_access_message));
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
|
||||
params.used_named_attribute(name, NamedAttributeUsage::Read);
|
||||
|
||||
|
|
|
@ -21,6 +21,11 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
params.set_output("Geometry", std::move(geometry_set));
|
||||
return;
|
||||
}
|
||||
if (!bke::allow_procedural_attribute_access(name)) {
|
||||
params.error_message_add(NodeWarningType::Info, TIP_(bke::no_procedural_access_message));
|
||||
params.set_output("Geometry", std::move(geometry_set));
|
||||
return;
|
||||
}
|
||||
|
||||
std::atomic<bool> attribute_exists = false;
|
||||
std::atomic<bool> cannot_delete = false;
|
||||
|
|
|
@ -131,6 +131,11 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
params.set_output("Geometry", std::move(geometry_set));
|
||||
return;
|
||||
}
|
||||
if (!bke::allow_procedural_attribute_access(name)) {
|
||||
params.error_message_add(NodeWarningType::Info, TIP_(bke::no_procedural_access_message));
|
||||
params.set_output("Geometry", std::move(geometry_set));
|
||||
return;
|
||||
}
|
||||
|
||||
params.used_named_attribute(name, NamedAttributeUsage::Write);
|
||||
|
||||
|
|
Loading…
Reference in New Issue