Curves: Add edit mode operator to set attribute values #105076

Merged
Hans Goudey merged 9 commits from HooglyBoogly/blender:curves-attribute-set into main 2023-10-17 12:35:50 +02:00
4 changed files with 49 additions and 11 deletions
Showing only changes of commit 0812374525 - Show all commits

View File

@ -59,9 +59,11 @@ static bool active_attribute_poll(bContext *C)
return true;
}
static IndexMask retrieve_selected_elements(const Curves &curves_id, Vector<int64_t> &r_indices)
static IndexMask retrieve_selected_elements(const Curves &curves_id,
const eAttrDomain domain,
Vector<int64_t> &r_indices)
{
switch (eAttrDomain(curves_id.selection_domain)) {
switch (domain) {
case ATTR_DOMAIN_POINT:
return retrieve_selected_points(curves_id, r_indices);
case ATTR_DOMAIN_CURVE:
@ -72,6 +74,27 @@ static IndexMask retrieve_selected_elements(const Curves &curves_id, Vector<int6
}
}
static void validate_value(const bke::AttributeAccessor attributes,
const StringRef name,
const CPPType &type,
void *buffer)
{
const bke::AttributeValidator validator = attributes.lookup_validator(name);
if (!validator) {
return;
}
BUFFER_FOR_CPP_TYPE_VALUE(type, validated_buffer);
BLI_SCOPED_DEFER([&]() { type.destruct(validated_buffer); });
mf::ParamsBuilder params(*validator.function, 1);
params.add_readonly_single_input(GPointer(type, buffer));
params.add_uninitialized_single_output({type, validated_buffer, 1});
mf::ContextBuilder context;
validator.function->call(IndexMask(1), params, context);
type.copy_assign(validated_buffer, buffer);
}
static int set_attribute_exec(bContext *C, wmOperator *op)
{
Object *active_object = CTX_data_active_object(C);
@ -106,13 +129,12 @@ static int set_attribute_exec(bContext *C, wmOperator *op)
BUFFER_FOR_CPP_TYPE_VALUE(dst_type, dst_buffer);
BLI_SCOPED_DEFER([&]() { dst_type.destruct(dst_buffer); });
conversions.convert_to_uninitialized(type, dst_type, value.get(), dst_buffer);
const GPointer dst_value(dst_type, dst_buffer);
const bke::AttributeValidator validator = attributes.lookup_validator(layer->name);
// validator.function->call()
validate_value(attributes, layer->name, dst_type, dst_buffer);
const GPointer dst_value(type, dst_buffer);
Vector<int64_t> indices;
const IndexMask selection = retrieve_selected_elements(*curves_id, indices);
const IndexMask selection = retrieve_selected_elements(*curves_id, attribute.domain, indices);
if (selection.is_empty()) {
continue;
}
@ -139,9 +161,8 @@ static int set_attribute_invoke(bContext *C, wmOperator *op, const wmEvent *even
const VArray<bool> selection = attributes.lookup_or_default<bool>(".selection", domain, true);
const CPPType &type = attribute.varray.type();
const StringRefNull prop_name = geometry::rna_property_name_for_type(
bke::cpp_type_to_custom_data_type(type));
PropertyRNA *prop = RNA_struct_find_property(op->ptr, prop_name.c_str());
PropertyRNA *prop = geometry::rna_property_for_type(*op->ptr,
bke::cpp_type_to_custom_data_type(type));
if (RNA_property_is_set(op->ptr, prop)) {
return WM_operator_props_popup(C, op, event);
}

View File

@ -64,6 +64,11 @@ StringRefNull rna_property_name_for_type(const eCustomDataType type)
}
}
PropertyRNA *rna_property_for_type(PointerRNA &ptr, const eCustomDataType type)
{
return RNA_struct_find_property(&ptr, rna_property_name_for_type(type).c_str());
}
void register_rna_properties_for_attribute_types(StructRNA &srna)
{
static blender::float4 color_default(1);

View File

@ -15,15 +15,28 @@
# include "BLI_generic_pointer.hh"
# include "BLI_string_ref.hh"
struct PointerRNA;
struct PropertyRNA;
namespace blender::ed::geometry {
/* -------------------------------------------------------------------- */
/** \name Attribute Value RNA Property Helpers
*
* Functions to make it easier to register RNA properties for the various attribute types and
* retrieve/set their values.
* \{ */
StringRefNull rna_property_name_for_type(eCustomDataType type);
PropertyRNA *rna_property_for_type(PointerRNA &ptr, const eCustomDataType type);
void register_rna_properties_for_attribute_types(StructRNA &srna);
GPointer rna_property_for_attribute_type_retrieve_value(PointerRNA &ptr,
const eCustomDataType type,
void *buffer);
void rna_property_for_attribute_type_set_value(PointerRNA &ptr, PropertyRNA &prop, GPointer value);
/** \} */
} // namespace blender::ed::geometry
#endif

View File

@ -237,11 +237,10 @@ static int mesh_set_attribute_invoke(bContext *C, wmOperator *op, const wmEvent
return WM_operator_props_popup(C, op, event);
}
const StringRefNull prop_name = geometry::rna_property_name_for_type(data_type);
const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
const GPointer active_value(type, POINTER_OFFSET(active_elem->head.data, layer->offset));
PropertyRNA *prop = RNA_struct_find_property(op->ptr, prop_name.c_str());
PropertyRNA *prop = geometry::rna_property_for_type(*op->ptr, data_type);
if (!RNA_property_is_set(op->ptr, prop)) {
geometry::rna_property_for_attribute_type_set_value(*op->ptr, *prop, active_value);
}