From 31ec00895f25613c5952fe557daa596a69e30618 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Oct 2023 12:35:40 +0200 Subject: [PATCH] Curves: Add edit mode operator to set attribute values Similar to #104426, this adds a simple operator to set attribute values for curves edit mode. The operator is very basic and is only meant to be a first step for more attribute editing features. Some of the functionality could be achieved with node tools, but without dynamic socket types or access to the active attribute, it would be incomplete. Some of the RNA property registration, retrieval, and setting is reused from the mesh edit mode operator. The rest of the logic is similar but harder to de-duplicate. Pull Request: https://projects.blender.org/blender/blender/pulls/105076 --- scripts/startup/bl_ui/space_view3d.py | 1 + source/blender/editors/curves/CMakeLists.txt | 1 + .../editors/curves/intern/attribute_set.cc | 227 ++++++++++++++++++ .../editors/curves/intern/curves_ops.cc | 1 + .../editors/geometry/geometry_attributes.cc | 133 ++++++++++ source/blender/editors/include/ED_curves.hh | 8 + source/blender/editors/include/ED_geometry.hh | 27 +++ .../editors/mesh/editmesh_attribute.cc | 161 +------------ 8 files changed, 405 insertions(+), 154 deletions(-) create mode 100644 source/blender/editors/curves/intern/attribute_set.cc diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index 7cdb190a66a..9b963d1820a 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -5823,6 +5823,7 @@ class VIEW3D_MT_edit_curves(Menu): layout.menu("VIEW3D_MT_transform") layout.separator() + layout.operator("curves.attribute_set") layout.operator("curves.delete") layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label) diff --git a/source/blender/editors/curves/CMakeLists.txt b/source/blender/editors/curves/CMakeLists.txt index d5fcf758a33..ed4e3e98ea1 100644 --- a/source/blender/editors/curves/CMakeLists.txt +++ b/source/blender/editors/curves/CMakeLists.txt @@ -23,6 +23,7 @@ set(INC_SYS ) set(SRC + intern/attribute_set.cc intern/curves_add.cc intern/curves_data.cc intern/curves_edit.cc diff --git a/source/blender/editors/curves/intern/attribute_set.cc b/source/blender/editors/curves/intern/attribute_set.cc new file mode 100644 index 00000000000..84e9524d4b7 --- /dev/null +++ b/source/blender/editors/curves/intern/attribute_set.cc @@ -0,0 +1,227 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup edmesh + */ + +#include "BLI_generic_pointer.hh" + +#include "BKE_attribute.h" +#include "BKE_attribute_math.hh" +#include "BKE_context.h" +#include "BKE_report.h" +#include "BKE_type_conversions.hh" + +#include "WM_api.hh" +#include "WM_types.hh" + +#include "ED_curves.hh" +#include "ED_geometry.hh" +#include "ED_object.hh" +#include "ED_screen.hh" +#include "ED_transform.hh" +#include "ED_view3d.hh" + +#include "RNA_access.hh" + +#include "BLT_translation.h" + +#include "UI_interface.hh" +#include "UI_resources.hh" + +#include "DNA_object_types.h" + +#include "DEG_depsgraph.hh" +#include "DEG_depsgraph_query.hh" + +/* -------------------------------------------------------------------- */ +/** \name Delete Operator + * \{ */ + +namespace blender::ed::curves { + +static bool active_attribute_poll(bContext *C) +{ + if (!editable_curves_in_edit_mode_poll(C)) { + return false; + } + Object *object = CTX_data_active_object(C); + Curves &curves_id = *static_cast(object->data); + const CustomDataLayer *layer = BKE_id_attributes_active_get(&const_cast(curves_id.id)); + if (!layer) { + CTX_wm_operator_poll_msg_set(C, "No active attribute"); + return false; + } + if (layer->type == CD_PROP_STRING) { + CTX_wm_operator_poll_msg_set(C, "Active string attribute not supported"); + return false; + } + return true; +} + +static IndexMask retrieve_selected_elements(const Curves &curves_id, + const eAttrDomain domain, + IndexMaskMemory &memory) +{ + switch (domain) { + case ATTR_DOMAIN_POINT: + return retrieve_selected_points(curves_id, memory); + case ATTR_DOMAIN_CURVE: + return retrieve_selected_curves(curves_id, memory); + default: + BLI_assert_unreachable(); + return {}; + } +} + +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); }); + + const IndexMask single_mask(1); + mf::ParamsBuilder params(*validator.function, &single_mask); + params.add_readonly_single_input(GPointer(type, buffer)); + params.add_uninitialized_single_output({type, validated_buffer, 1}); + mf::ContextBuilder context; + validator.function->call(single_mask, 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); + Curves &active_curves_id = *static_cast(active_object->data); + + CustomDataLayer *active_attribute = BKE_id_attributes_active_get(&active_curves_id.id); + const eCustomDataType active_type = eCustomDataType(active_attribute->type); + const CPPType &type = *bke::custom_data_type_to_cpp_type(active_type); + + BUFFER_FOR_CPP_TYPE_VALUE(type, buffer); + BLI_SCOPED_DEFER([&]() { type.destruct(buffer); }); + const GPointer value = geometry::rna_property_for_attribute_type_retrieve_value( + *op->ptr, active_type, buffer); + + const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions(); + + for (Curves *curves_id : get_unique_editable_curves(*C)) { + bke::CurvesGeometry &curves = curves_id->geometry.wrap(); + CustomDataLayer *layer = BKE_id_attributes_active_get(&curves_id->id); + if (!layer) { + continue; + } + bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); + bke::GSpanAttributeWriter attribute = attributes.lookup_for_write_span(layer->name); + + /* Use implicit conversions to try to handle the case where the active attribute has a + * different type on multiple objects. */ + const CPPType &dst_type = attribute.span.type(); + if (&type != &dst_type && !conversions.is_convertible(type, dst_type)) { + continue; + } + 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); + + validate_value(attributes, layer->name, dst_type, dst_buffer); + const GPointer dst_value(type, dst_buffer); + + IndexMaskMemory memory; + const IndexMask selection = retrieve_selected_elements(*curves_id, attribute.domain, memory); + if (selection.is_empty()) { + attribute.finish(); + continue; + } + dst_type.fill_assign_indices(dst_value.get(), attribute.span.data(), selection); + attribute.finish(); + + DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id); + } + + return OPERATOR_FINISHED; +} + +static int set_attribute_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Object *active_object = CTX_data_active_object(C); + Curves &active_curves_id = *static_cast(active_object->data); + + CustomDataLayer *active_attribute = BKE_id_attributes_active_get(&active_curves_id.id); + const bke::CurvesGeometry &curves = active_curves_id.geometry.wrap(); + const bke::AttributeAccessor attributes = curves.attributes(); + const bke::GAttributeReader attribute = attributes.lookup(active_attribute->name); + const eAttrDomain domain = attribute.domain; + + IndexMaskMemory memory; + const IndexMask selection = retrieve_selected_elements(active_curves_id, domain, memory); + + const CPPType &type = attribute.varray.type(); + + 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); + } + + BUFFER_FOR_CPP_TYPE_VALUE(type, buffer); + BLI_SCOPED_DEFER([&]() { type.destruct(buffer); }); + + bke::attribute_math::convert_to_static_type(type, [&](auto dummy) { + using T = decltype(dummy); + const VArray values_typed = attribute.varray.typed(); + bke::attribute_math::DefaultMixer mixer{MutableSpan(static_cast(buffer), 1)}; + selection.foreach_index([&](const int i) { mixer.mix_in(0, values_typed[i]); }); + mixer.finalize(); + }); + + geometry::rna_property_for_attribute_type_set_value(*op->ptr, *prop, GPointer(type, buffer)); + + return WM_operator_props_popup(C, op, event); +} + +static void set_attribute_ui(bContext *C, wmOperator *op) +{ + uiLayout *layout = uiLayoutColumn(op->layout, true); + uiLayoutSetPropSep(layout, true); + uiLayoutSetPropDecorate(layout, false); + + Object *object = CTX_data_active_object(C); + Curves &curves_id = *static_cast(object->data); + + CustomDataLayer *active_attribute = BKE_id_attributes_active_get(&curves_id.id); + const eCustomDataType active_type = eCustomDataType(active_attribute->type); + const StringRefNull prop_name = geometry::rna_property_name_for_type(active_type); + const char *name = active_attribute->name; + uiItemR(layout, op->ptr, prop_name.c_str(), UI_ITEM_NONE, name, ICON_NONE); +} + +void CURVES_OT_attribute_set(wmOperatorType *ot) +{ + using namespace blender::ed; + using namespace blender::ed::curves; + ot->name = "Set Attribute"; + ot->description = "Set values of the active attribute for selected elements"; + ot->idname = "CURVES_OT_attribute_set"; + + ot->exec = set_attribute_exec; + ot->invoke = set_attribute_invoke; + ot->poll = active_attribute_poll; + ot->ui = set_attribute_ui; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + geometry::register_rna_properties_for_attribute_types(*ot->srna); +} + +} // namespace blender::ed::curves + +/** \} */ diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index e37af75f360..637a82b0318 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -1236,6 +1236,7 @@ static void CURVES_OT_delete(wmOperatorType *ot) void ED_operatortypes_curves() { using namespace blender::ed::curves; + WM_operatortype_append(CURVES_OT_attribute_set); WM_operatortype_append(CURVES_OT_convert_to_particle_system); WM_operatortype_append(CURVES_OT_convert_from_particle_system); WM_operatortype_append(CURVES_OT_snap_curves_to_surface); diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index f01385f219a..708403ab679 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -12,6 +12,8 @@ #include "DNA_meshdata_types.h" #include "DNA_scene_types.h" +#include "BLI_color.hh" + #include "BKE_attribute.h" #include "BKE_context.h" #include "BKE_deform.h" @@ -42,6 +44,137 @@ namespace blender::ed::geometry { +StringRefNull rna_property_name_for_type(const eCustomDataType type) +{ + switch (type) { + case CD_PROP_FLOAT: + return "value_float"; + case CD_PROP_FLOAT2: + return "value_float_vector_2d"; + case CD_PROP_FLOAT3: + return "value_float_vector_3d"; + case CD_PROP_COLOR: + case CD_PROP_BYTE_COLOR: + return "value_color"; + case CD_PROP_BOOL: + return "value_bool"; + case CD_PROP_INT8: + case CD_PROP_INT32: + return "value_int"; + default: + BLI_assert_unreachable(); + return ""; + } +} + +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); + + RNA_def_float(&srna, "value_float", 0.0f, -FLT_MAX, FLT_MAX, "Value", "", -FLT_MAX, FLT_MAX); + RNA_def_float_array(&srna, + "value_float_vector_2d", + 2, + nullptr, + -FLT_MAX, + FLT_MAX, + "Value", + "", + -FLT_MAX, + FLT_MAX); + RNA_def_float_array(&srna, + "value_float_vector_3d", + 3, + nullptr, + -FLT_MAX, + FLT_MAX, + "Value", + "", + -FLT_MAX, + FLT_MAX); + RNA_def_int(&srna, "value_int", 0, INT_MIN, INT_MAX, "Value", "", INT_MIN, INT_MAX); + RNA_def_float_color( + &srna, "value_color", 4, color_default, -FLT_MAX, FLT_MAX, "Value", "", 0.0f, 1.0f); + RNA_def_boolean(&srna, "value_bool", false, "Value", ""); +} + +GPointer rna_property_for_attribute_type_retrieve_value(PointerRNA &ptr, + const eCustomDataType type, + void *buffer) +{ + const StringRefNull prop_name = rna_property_name_for_type(type); + switch (type) { + case CD_PROP_FLOAT: + *static_cast(buffer) = RNA_float_get(&ptr, prop_name.c_str()); + break; + case CD_PROP_FLOAT2: + RNA_float_get_array(&ptr, prop_name.c_str(), static_cast(buffer)); + break; + case CD_PROP_FLOAT3: + RNA_float_get_array(&ptr, prop_name.c_str(), static_cast(buffer)); + break; + case CD_PROP_COLOR: + RNA_float_get_array(&ptr, prop_name.c_str(), static_cast(buffer)); + break; + case CD_PROP_BYTE_COLOR: + ColorGeometry4f value; + RNA_float_get_array(&ptr, prop_name.c_str(), value); + *static_cast(buffer) = value.encode(); + break; + case CD_PROP_BOOL: + *static_cast(buffer) = RNA_boolean_get(&ptr, prop_name.c_str()); + break; + case CD_PROP_INT8: + *static_cast(buffer) = RNA_int_get(&ptr, prop_name.c_str()); + break; + case CD_PROP_INT32: + *static_cast(buffer) = RNA_int_get(&ptr, prop_name.c_str()); + break; + default: + BLI_assert_unreachable(); + } + return GPointer(bke::custom_data_type_to_cpp_type(type), buffer); +} + +void rna_property_for_attribute_type_set_value(PointerRNA &ptr, + PropertyRNA &prop, + const GPointer value) +{ + switch (bke::cpp_type_to_custom_data_type(*value.type())) { + case CD_PROP_FLOAT: + RNA_property_float_set(&ptr, &prop, *value.get()); + break; + case CD_PROP_FLOAT2: + RNA_property_float_set_array(&ptr, &prop, *value.get()); + break; + case CD_PROP_FLOAT3: + RNA_property_float_set_array(&ptr, &prop, *value.get()); + break; + case CD_PROP_BYTE_COLOR: + RNA_property_float_set_array(&ptr, &prop, value.get()->decode()); + break; + case CD_PROP_COLOR: + RNA_property_float_set_array(&ptr, &prop, *value.get()); + break; + case CD_PROP_BOOL: + RNA_property_boolean_set(&ptr, &prop, *value.get()); + break; + case CD_PROP_INT8: + RNA_property_int_set(&ptr, &prop, *value.get()); + break; + case CD_PROP_INT32: + RNA_property_int_set(&ptr, &prop, *value.get()); + break; + default: + BLI_assert_unreachable(); + } +} + /*********************** Attribute Operators ************************/ static bool geometry_attributes_poll(bContext *C) diff --git a/source/blender/editors/include/ED_curves.hh b/source/blender/editors/include/ED_curves.hh index 524c54dcc83..1606baa5f31 100644 --- a/source/blender/editors/include/ED_curves.hh +++ b/source/blender/editors/include/ED_curves.hh @@ -70,6 +70,14 @@ bool curves_poll(bContext *C); /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Operators + * \{ */ + +void CURVES_OT_attribute_set(wmOperatorType *ot); + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Mask Functions * \{ */ diff --git a/source/blender/editors/include/ED_geometry.hh b/source/blender/editors/include/ED_geometry.hh index fb9ebb256f6..72172d50f3c 100644 --- a/source/blender/editors/include/ED_geometry.hh +++ b/source/blender/editors/include/ED_geometry.hh @@ -18,6 +18,33 @@ struct Mesh; struct ReportList; +#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 + void ED_operatortypes_geometry(); /** diff --git a/source/blender/editors/mesh/editmesh_attribute.cc b/source/blender/editors/mesh/editmesh_attribute.cc index 09e5d981781..1e676712f47 100644 --- a/source/blender/editors/mesh/editmesh_attribute.cc +++ b/source/blender/editors/mesh/editmesh_attribute.cc @@ -25,6 +25,7 @@ #include "RNA_define.hh" #include "RNA_enum_types.hh" +#include "ED_geometry.hh" #include "ED_mesh.hh" #include "ED_object.hh" #include "ED_screen.hh" @@ -88,33 +89,6 @@ static bool mesh_active_attribute_poll(bContext *C) namespace set_attribute { -static StringRefNull rna_property_name_for_type(const eCustomDataType type) -{ - switch (type) { - case CD_PROP_FLOAT: - return "value_float"; - case CD_PROP_FLOAT2: - return "value_float_vector_2d"; - case CD_PROP_FLOAT3: - return "value_float_vector_3d"; - case CD_PROP_COLOR: - case CD_PROP_BYTE_COLOR: - return "value_color"; - case CD_PROP_BOOL: - return "value_bool"; - case CD_PROP_INT8: - case CD_PROP_INT32: - return "value_int"; - case CD_PROP_INT32_2D: - return "value_int_vector_2d"; - case CD_PROP_QUATERNION: - return "value_quat"; - default: - BLI_assert_unreachable(); - return ""; - } -} - static void bmesh_vert_edge_face_layer_selected_values_set(BMesh &bm, const BMIterType iter_type, const GPointer value, @@ -186,48 +160,9 @@ static int mesh_set_attribute_exec(bContext *C, wmOperator *op) BUFFER_FOR_CPP_TYPE_VALUE(type, buffer); BLI_SCOPED_DEFER([&]() { type.destruct(buffer); }); + const GPointer value = geometry::rna_property_for_attribute_type_retrieve_value( + *op->ptr, active_type, buffer); - const StringRefNull prop_name = rna_property_name_for_type(active_type); - switch (active_type) { - case CD_PROP_FLOAT: - *static_cast(buffer) = RNA_float_get(op->ptr, prop_name.c_str()); - break; - case CD_PROP_FLOAT2: - RNA_float_get_array(op->ptr, prop_name.c_str(), static_cast(buffer)); - break; - case CD_PROP_FLOAT3: - RNA_float_get_array(op->ptr, prop_name.c_str(), static_cast(buffer)); - break; - case CD_PROP_COLOR: - RNA_float_get_array(op->ptr, prop_name.c_str(), static_cast(buffer)); - break; - case CD_PROP_QUATERNION: { - float4 value; - RNA_float_get_array(op->ptr, prop_name.c_str(), value); - *static_cast(buffer) = math::normalize(math::Quaternion(value)); - break; - } - case CD_PROP_BYTE_COLOR: - ColorGeometry4f value; - RNA_float_get_array(op->ptr, prop_name.c_str(), value); - *static_cast(buffer) = value.encode(); - break; - case CD_PROP_BOOL: - *static_cast(buffer) = RNA_boolean_get(op->ptr, prop_name.c_str()); - break; - case CD_PROP_INT8: - *static_cast(buffer) = RNA_int_get(op->ptr, prop_name.c_str()); - break; - case CD_PROP_INT32: - *static_cast(buffer) = RNA_int_get(op->ptr, prop_name.c_str()); - break; - case CD_PROP_INT32_2D: - RNA_int_get_array(op->ptr, prop_name.c_str(), static_cast(buffer)); - break; - default: - BLI_assert_unreachable(); - } - const GPointer value(type, buffer); const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions(); bool changed = false; @@ -305,48 +240,12 @@ static int mesh_set_attribute_invoke(bContext *C, wmOperator *op, const wmEvent return WM_operator_props_popup(C, op, event); } - const StringRefNull prop_name = 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)) { - switch (data_type) { - case CD_PROP_FLOAT: - RNA_property_float_set(op->ptr, prop, *active_value.get()); - break; - case CD_PROP_FLOAT2: - RNA_property_float_set_array(op->ptr, prop, *active_value.get()); - break; - case CD_PROP_FLOAT3: - RNA_property_float_set_array(op->ptr, prop, *active_value.get()); - break; - case CD_PROP_BYTE_COLOR: - RNA_property_float_set_array(op->ptr, prop, active_value.get()->decode()); - break; - case CD_PROP_COLOR: - RNA_property_float_set_array(op->ptr, prop, *active_value.get()); - break; - case CD_PROP_BOOL: - RNA_property_boolean_set(op->ptr, prop, *active_value.get()); - break; - case CD_PROP_INT8: - RNA_property_int_set(op->ptr, prop, *active_value.get()); - break; - case CD_PROP_INT32: - RNA_property_int_set(op->ptr, prop, *active_value.get()); - break; - case CD_PROP_INT32_2D: - RNA_property_int_set_array(op->ptr, prop, *active_value.get()); - break; - case CD_PROP_QUATERNION: { - const math::Quaternion value = math::normalize(*active_value.get()); - RNA_property_float_set_array(op->ptr, prop, float4(value)); - break; - } - default: - BLI_assert_unreachable(); - } + geometry::rna_property_for_attribute_type_set_value(*op->ptr, *prop, active_value); } return WM_operator_props_popup(C, op, event); @@ -361,7 +260,7 @@ static void mesh_set_attribute_ui(bContext *C, wmOperator *op) Mesh *mesh = ED_mesh_context(C); CustomDataLayer *active_attribute = BKE_id_attributes_active_get(&mesh->id); const eCustomDataType active_type = eCustomDataType(active_attribute->type); - const StringRefNull prop_name = rna_property_name_for_type(active_type); + const StringRefNull prop_name = geometry::rna_property_name_for_type(active_type); const char *name = active_attribute->name; uiItemR(layout, op->ptr, prop_name.c_str(), UI_ITEM_NONE, name, ICON_NONE); } @@ -385,53 +284,7 @@ void MESH_OT_attribute_set(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - static blender::float4 color_default(1); - - RNA_def_float(ot->srna, "value_float", 0.0f, -FLT_MAX, FLT_MAX, "Value", "", -FLT_MAX, FLT_MAX); - RNA_def_float_array(ot->srna, - "value_float_vector_2d", - 2, - nullptr, - -FLT_MAX, - FLT_MAX, - "Value", - "", - -FLT_MAX, - FLT_MAX); - RNA_def_float_array(ot->srna, - "value_float_vector_3d", - 3, - nullptr, - -FLT_MAX, - FLT_MAX, - "Value", - "", - -FLT_MAX, - FLT_MAX); - RNA_def_int(ot->srna, "value_int", 0, INT_MIN, INT_MAX, "Value", "", INT_MIN, INT_MAX); - RNA_def_int_array(ot->srna, - "value_int_vector_2d", - 2, - nullptr, - INT_MIN, - INT_MAX, - "Value", - "", - INT_MIN, - INT_MAX); - RNA_def_float_color( - ot->srna, "value_color", 4, color_default, -FLT_MAX, FLT_MAX, "Value", "", 0.0f, 1.0f); - RNA_def_boolean(ot->srna, "value_bool", false, "Value", ""); - RNA_def_float_array(ot->srna, - "value_quat", - 4, - rna_default_quaternion, - -FLT_MAX, - FLT_MAX, - "Value", - "", - FLT_MAX, - FLT_MAX); + blender::ed::geometry::register_rna_properties_for_attribute_types(*ot->srna); } /** \} */