Blender V4.3
geometry_attributes.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "MEM_guardedalloc.h"
10
11#include "DNA_mesh_types.h"
12#include "DNA_meshdata_types.h"
13#include "DNA_scene_types.h"
14
15#include "BLI_color.hh"
16
17#include "BKE_attribute.hh"
18#include "BKE_context.hh"
19#include "BKE_customdata.hh"
20#include "BKE_deform.hh"
21#include "BKE_geometry_set.hh"
22#include "BKE_lib_id.hh"
23#include "BKE_mesh.hh"
24#include "BKE_object_deform.h"
25#include "BKE_paint.hh"
26#include "BKE_report.hh"
27
28#include "BLI_string.h"
29
30#include "BLT_translation.hh"
31
32#include "RNA_access.hh"
33#include "RNA_define.hh"
34#include "RNA_enum_types.hh"
35
36#include "DEG_depsgraph.hh"
37
38#include "WM_api.hh"
39#include "WM_types.hh"
40
41#include "UI_interface.hh"
42#include "UI_resources.hh"
43
44#include "ED_geometry.hh"
45#include "ED_mesh.hh"
46#include "ED_object.hh"
47#include "ED_sculpt.hh"
48
49#include "geometry_intern.hh"
50
52
54{
55 switch (type) {
56 case CD_PROP_FLOAT:
57 return "value_float";
58 case CD_PROP_FLOAT2:
59 return "value_float_vector_2d";
60 case CD_PROP_FLOAT3:
61 return "value_float_vector_3d";
62 case CD_PROP_COLOR:
64 return "value_color";
65 case CD_PROP_BOOL:
66 return "value_bool";
67 case CD_PROP_INT8:
68 case CD_PROP_INT32:
69 return "value_int";
71 return "value_int_vector_2d";
72 default:
74 return "";
75 }
76}
77
82
84{
85 static blender::float4 color_default(1);
86
87 RNA_def_float(&srna, "value_float", 0.0f, -FLT_MAX, FLT_MAX, "Value", "", -FLT_MAX, FLT_MAX);
89 "value_float_vector_2d",
90 2,
91 nullptr,
92 -FLT_MAX,
93 FLT_MAX,
94 "Value",
95 "",
96 -FLT_MAX,
97 FLT_MAX);
99 "value_float_vector_3d",
100 3,
101 nullptr,
102 -FLT_MAX,
103 FLT_MAX,
104 "Value",
105 "",
106 -FLT_MAX,
107 FLT_MAX);
108 RNA_def_int(&srna, "value_int", 0, INT_MIN, INT_MAX, "Value", "", INT_MIN, INT_MAX);
110 &srna, "value_int_vector_2d", 2, nullptr, INT_MIN, INT_MAX, "Value", "", INT_MIN, INT_MAX);
112 &srna, "value_color", 4, color_default, -FLT_MAX, FLT_MAX, "Value", "", 0.0f, 1.0f);
113 RNA_def_boolean(&srna, "value_bool", false, "Value", "");
114}
115
117 const eCustomDataType type,
118 void *buffer)
119{
120 const StringRefNull prop_name = rna_property_name_for_type(type);
121 switch (type) {
122 case CD_PROP_FLOAT:
123 *static_cast<float *>(buffer) = RNA_float_get(&ptr, prop_name.c_str());
124 break;
125 case CD_PROP_FLOAT2:
126 RNA_float_get_array(&ptr, prop_name.c_str(), static_cast<float *>(buffer));
127 break;
128 case CD_PROP_FLOAT3:
129 RNA_float_get_array(&ptr, prop_name.c_str(), static_cast<float *>(buffer));
130 break;
131 case CD_PROP_COLOR:
132 RNA_float_get_array(&ptr, prop_name.c_str(), static_cast<float *>(buffer));
133 break;
135 ColorGeometry4f value;
136 RNA_float_get_array(&ptr, prop_name.c_str(), value);
137 *static_cast<ColorGeometry4b *>(buffer) = value.encode();
138 break;
139 case CD_PROP_BOOL:
140 *static_cast<bool *>(buffer) = RNA_boolean_get(&ptr, prop_name.c_str());
141 break;
142 case CD_PROP_INT8:
143 *static_cast<int8_t *>(buffer) = RNA_int_get(&ptr, prop_name.c_str());
144 break;
145 case CD_PROP_INT32:
146 *static_cast<int32_t *>(buffer) = RNA_int_get(&ptr, prop_name.c_str());
147 break;
148 case CD_PROP_INT32_2D:
149 RNA_int_get_array(&ptr, prop_name.c_str(), static_cast<int *>(buffer));
150 break;
151 default:
153 return {};
154 }
155 return GPointer(bke::custom_data_type_to_cpp_type(type), buffer);
156}
157
159 PropertyRNA &prop,
160 const GPointer value)
161{
162 switch (bke::cpp_type_to_custom_data_type(*value.type())) {
163 case CD_PROP_FLOAT:
164 RNA_property_float_set(&ptr, &prop, *value.get<float>());
165 break;
166 case CD_PROP_FLOAT2:
167 RNA_property_float_set_array(&ptr, &prop, *value.get<float2>());
168 break;
169 case CD_PROP_FLOAT3:
170 RNA_property_float_set_array(&ptr, &prop, *value.get<float3>());
171 break;
173 RNA_property_float_set_array(&ptr, &prop, value.get<ColorGeometry4b>()->decode());
174 break;
175 case CD_PROP_COLOR:
176 RNA_property_float_set_array(&ptr, &prop, *value.get<ColorGeometry4f>());
177 break;
178 case CD_PROP_BOOL:
179 RNA_property_boolean_set(&ptr, &prop, *value.get<bool>());
180 break;
181 case CD_PROP_INT8:
182 RNA_property_int_set(&ptr, &prop, *value.get<int8_t>());
183 break;
184 case CD_PROP_INT32:
185 RNA_property_int_set(&ptr, &prop, *value.get<int32_t>());
186 break;
187 case CD_PROP_INT32_2D:
188 RNA_property_int_set_array(&ptr, &prop, *value.get<int2>());
189 break;
190 default:
192 }
193}
194
195bool attribute_set_poll(bContext &C, const ID &object_data)
196{
197 AttributeOwner owner = AttributeOwner::from_id(&const_cast<ID &>(object_data));
198 const CustomDataLayer *layer = BKE_attributes_active_get(owner);
199 if (!layer) {
200 CTX_wm_operator_poll_msg_set(&C, "No active attribute");
201 return false;
202 }
204 CTX_wm_operator_poll_msg_set(&C, "The active attribute has an unsupported type");
205 return false;
206 }
207 return true;
208}
209
210/*********************** Attribute Operators ************************/
211
213{
214 using namespace blender::bke;
215 const Object *ob = object::context_object(C);
216 const Main *bmain = CTX_data_main(C);
217 if (!ob || !BKE_id_is_editable(bmain, &ob->id)) {
218 return false;
219 }
220 const ID *data = (ob) ? static_cast<const ID *>(ob->data) : nullptr;
221 if (!data || !BKE_id_is_editable(bmain, data)) {
222 return false;
223 }
224 return AttributeAccessor::from_id(*data).has_value();
225}
226
228{
229 if (!geometry_attributes_poll(C)) {
230 return false;
231 }
232
234 ID *data = (ob) ? static_cast<ID *>(ob->data) : nullptr;
236 if (BKE_attributes_active_get(owner) != nullptr) {
237 return true;
238 }
239
240 return false;
241}
242
244 PointerRNA * /*ptr*/,
245 PropertyRNA * /*prop*/,
246 bool *r_free)
247{
248 if (C == nullptr) {
250 }
251
253 if (ob == nullptr) {
255 }
256
257 const AttributeOwner owner = AttributeOwner::from_id(static_cast<ID *>(ob->data));
258 return rna_enum_attribute_domain_itemf(owner, false, r_free);
259}
260
262{
264 ID *id = static_cast<ID *>(ob->data);
265
266 char name[MAX_NAME];
267 RNA_string_get(op->ptr, "name", name);
268 eCustomDataType type = (eCustomDataType)RNA_enum_get(op->ptr, "data_type");
269 bke::AttrDomain domain = bke::AttrDomain(RNA_enum_get(op->ptr, "domain"));
271 CustomDataLayer *layer = BKE_attribute_new(owner, name, type, domain, op->reports);
272
273 if (layer == nullptr) {
274 return OPERATOR_CANCELLED;
275 }
276
277 BKE_attributes_active_set(owner, layer->name);
278
281
282 return OPERATOR_FINISHED;
283}
284
286{
287 PropertyRNA *prop;
288 prop = RNA_struct_find_property(op->ptr, "name");
289 if (!RNA_property_is_set(op->ptr, prop)) {
290 RNA_property_string_set(op->ptr, prop, DATA_("Attribute"));
291 }
292 /* Set a valid default domain, in case Point domain is not supported. */
293 prop = RNA_struct_find_property(op->ptr, "domain");
294 if (!RNA_property_is_set(op->ptr, prop)) {
295 EnumPropertyItem *items;
296 int totitems;
297 bool free;
299 C, op->ptr, prop, const_cast<const EnumPropertyItem **>(&items), &totitems, &free);
300 if (totitems > 0) {
301 RNA_property_enum_set(op->ptr, prop, items[0].value);
302 }
303 if (free) {
304 MEM_freeN(items);
305 }
306 }
308 C, op, event, IFACE_("Add Attribute"), CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add"));
309}
310
312{
313 /* identifiers */
314 ot->name = "Add Attribute";
315 ot->description = "Add attribute to geometry";
316 ot->idname = "GEOMETRY_OT_attribute_add";
317
318 /* api callbacks */
322
323 /* flags */
325
326 /* properties */
327 PropertyRNA *prop;
328
329 /* The default name of the new attribute can be translated if new data translation is enabled,
330 * but since the user can choose it at invoke time, the translation happens in the invoke
331 * callback instead of here. */
332 prop = RNA_def_string(ot->srna, "name", nullptr, MAX_NAME, "Name", "Name of new attribute");
334
335 prop = RNA_def_enum(ot->srna,
336 "domain",
339 "Domain",
340 "Type of element that attribute is stored on");
343
344 prop = RNA_def_enum(ot->srna,
345 "data_type",
348 "Data Type",
349 "Type of data stored in attribute");
351}
352
354{
356 ID *id = static_cast<ID *>(ob->data);
359
360 if (!BKE_attribute_remove(owner, layer->name, op->reports)) {
361 return OPERATOR_CANCELLED;
362 }
363
364 int *active_index = BKE_attributes_active_index_p(owner);
365 if (*active_index > 0) {
366 *active_index -= 1;
367 }
368
371
372 return OPERATOR_FINISHED;
373}
374
376{
377 /* identifiers */
378 ot->name = "Remove Attribute";
379 ot->description = "Remove attribute from geometry";
380 ot->idname = "GEOMETRY_OT_attribute_remove";
381
382 /* api callbacks */
385
386 /* flags */
388}
389
391{
393 ID *id = static_cast<ID *>(ob->data);
394
395 char name[MAX_NAME];
396 RNA_string_get(op->ptr, "name", name);
397 eCustomDataType type = (eCustomDataType)RNA_enum_get(op->ptr, "data_type");
398 bke::AttrDomain domain = bke::AttrDomain(RNA_enum_get(op->ptr, "domain"));
400 CustomDataLayer *layer = BKE_attribute_new(owner, name, type, domain, op->reports);
401
402 float color[4];
403 RNA_float_get_array(op->ptr, "color", color);
404
405 if (layer == nullptr) {
406 return OPERATOR_CANCELLED;
407 }
408
409 BKE_id_attributes_active_color_set(id, layer->name);
410
413 }
414
416
419
420 return OPERATOR_FINISHED;
421}
422
424{
425 PropertyRNA *prop;
426 prop = RNA_struct_find_property(op->ptr, "name");
427 if (!RNA_property_is_set(op->ptr, prop)) {
428 RNA_property_string_set(op->ptr, prop, DATA_("Color"));
429 }
431 op,
432 event,
433 IFACE_("Add Color Attribute"),
435}
436
438 Generic = 0,
439 VertexGroup = 1,
440};
441
443{
444 if (!geometry_attributes_poll(C)) {
445 return false;
446 }
447
449 ID *data = static_cast<ID *>(ob->data);
451 if (GS(data->name) != ID_ME) {
452 return false;
453 }
454 if (CTX_data_edit_object(C) != nullptr) {
455 CTX_wm_operator_poll_msg_set(C, "Operation is not allowed in edit mode");
456 return false;
457 }
458 if (BKE_attributes_active_get(owner) == nullptr) {
459 return false;
460 }
461 return true;
462}
463
465{
467 ID *ob_data = static_cast<ID *>(ob->data);
470 const ConvertAttributeMode mode = static_cast<ConvertAttributeMode>(
471 RNA_enum_get(op->ptr, "mode"));
472 Mesh *mesh = reinterpret_cast<Mesh *>(ob_data);
473 bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
474
475 const std::string name = layer->name;
476
477 /* General conversion steps are always the same:
478 * 1. Convert old data to right domain and data type.
479 * 2. Copy the data into a new array so that it does not depend on the old attribute anymore.
480 * 3. Delete the old attribute.
481 * 4. Create a new attribute based on the previously copied data. */
482 switch (mode) {
485 name.c_str(),
486 eCustomDataType(RNA_enum_get(op->ptr, "data_type")),
487 bke::AttrDomain(RNA_enum_get(op->ptr, "domain")),
488 op->reports))
489 {
490 return OPERATOR_CANCELLED;
491 }
492 break;
493 }
495 Array<float> src_weights(mesh->verts_num);
496 VArray<float> src_varray = *attributes.lookup_or_default<float>(
497 name, bke::AttrDomain::Point, 0.0f);
498 src_varray.materialize(src_weights);
499 attributes.remove(name);
500
501 bDeformGroup *defgroup = BKE_object_defgroup_new(ob, name.c_str());
502 const int defgroup_index = BLI_findindex(BKE_id_defgroup_list_get(&mesh->id), defgroup);
503 MDeformVert *dverts = BKE_object_defgroup_data_create(&mesh->id);
504 for (const int i : IndexRange(mesh->verts_num)) {
505 const float weight = src_weights[i];
506 if (weight > 0.0f) {
507 BKE_defvert_add_index_notest(dverts + i, defgroup_index, weight);
508 }
509 }
510 AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
511 int *active_index = BKE_attributes_active_index_p(owner);
512 if (*active_index > 0) {
513 *active_index -= 1;
514 }
515 break;
516 }
517 }
518
521 return OPERATOR_FINISHED;
522}
523
525{
526 uiLayout *layout = op->layout;
527 uiLayoutSetPropSep(layout, true);
528 uiLayoutSetPropDecorate(layout, false);
529
530 uiItemR(layout, op->ptr, "name", UI_ITEM_NONE, nullptr, ICON_NONE);
531 uiItemR(layout, op->ptr, "domain", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
532 uiItemR(layout, op->ptr, "data_type", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
533 uiItemR(layout, op->ptr, "color", UI_ITEM_NONE, nullptr, ICON_NONE);
534}
535
537{
538 /* identifiers */
539 ot->name = "Add Color Attribute";
540 ot->description = "Add color attribute to geometry";
541 ot->idname = "GEOMETRY_OT_color_attribute_add";
542
543 /* api callbacks */
548
549 /* flags */
551
552 /* properties */
553 PropertyRNA *prop;
554
555 /* The default name of the new attribute can be translated if new data translation is enabled,
556 * but since the user can choose it at invoke time, the translation happens in the invoke
557 * callback instead of here. */
558 prop = RNA_def_string(
559 ot->srna, "name", nullptr, MAX_NAME, "Name", "Name of new color attribute");
561
562 prop = RNA_def_enum(ot->srna,
563 "domain",
566 "Domain",
567 "Type of element that attribute is stored on");
568
569 prop = RNA_def_enum(ot->srna,
570 "data_type",
573 "Data Type",
574 "Type of data stored in attribute");
575
576 static float default_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
577
578 prop = RNA_def_float_color(
579 ot->srna, "color", 4, nullptr, 0.0f, FLT_MAX, "Color", "Default fill color", 0.0f, 1.0f);
581 RNA_def_property_float_array_default(prop, default_color);
582}
583
585{
587 ID *id = static_cast<ID *>(ob->data);
588
589 char name[MAX_NAME];
590 RNA_string_get(op->ptr, "name", name);
591
592 if (BKE_id_attributes_color_find(id, name)) {
594
597
598 return OPERATOR_FINISHED;
599 }
600
601 return OPERATOR_CANCELLED;
602}
603
605{
606 /* identifiers */
607 ot->name = "Set Render Color";
608 ot->description = "Set default color attribute used for rendering";
609 ot->idname = "GEOMETRY_OT_color_attribute_render_set";
610
611 /* api callbacks */
614
615 /* flags */
617
618 /* properties */
619 PropertyRNA *prop;
620
621 prop = RNA_def_string(ot->srna, "name", "Color", MAX_NAME, "Name", "Name of color attribute");
623}
624
626{
628 ID *id = static_cast<ID *>(ob->data);
629 const std::string active_name = StringRef(BKE_id_attributes_active_color_name(id));
630 if (active_name.empty()) {
631 return OPERATOR_CANCELLED;
632 }
634 if (!BKE_attribute_remove(owner, active_name.c_str(), op->reports)) {
635 return OPERATOR_CANCELLED;
636 }
637
640
641 return OPERATOR_FINISHED;
642}
643
645{
646 if (!geometry_attributes_poll(C)) {
647 return false;
648 }
649
650 const Object *ob = object::context_object(C);
651 const ID *data = static_cast<ID *>(ob->data);
652
654 return true;
655 }
656
657 return false;
658}
659
661{
662 /* identifiers */
663 ot->name = "Remove Color Attribute";
664 ot->description = "Remove color attribute from geometry";
665 ot->idname = "GEOMETRY_OT_color_attribute_remove";
666
667 /* api callbacks */
670
671 /* flags */
673}
674
676{
678 ID *id = static_cast<ID *>(ob->data);
679 const char *active_name = BKE_id_attributes_active_color_name(id);
680 if (active_name == nullptr) {
681 return OPERATOR_CANCELLED;
682 }
683
685 CustomDataLayer *new_layer = BKE_attribute_duplicate(owner, active_name, op->reports);
686 if (new_layer == nullptr) {
687 return OPERATOR_CANCELLED;
688 }
689
691
694
695 return OPERATOR_FINISHED;
696}
697
699{
700 if (!geometry_attributes_poll(C)) {
701 return false;
702 }
703 if (CTX_data_edit_object(C) != nullptr) {
704 CTX_wm_operator_poll_msg_set(C, "Operation is not allowed in edit mode");
705 return false;
706 }
707
708 const Object *ob = object::context_object(C);
709 const ID *data = static_cast<ID *>(ob->data);
710
712 return true;
713 }
714
715 return false;
716}
717
719{
720 /* identifiers */
721 ot->name = "Duplicate Color Attribute";
722 ot->description = "Duplicate color attribute";
723 ot->idname = "GEOMETRY_OT_color_attribute_duplicate";
724
725 /* api callbacks */
728
729 /* flags */
731}
732
734 wmOperator *op,
735 const wmEvent * /*event*/)
736{
738 Mesh *mesh = static_cast<Mesh *>(ob->data);
739 AttributeOwner owner = AttributeOwner::from_id(&mesh->id);
740
741 const bke::AttributeMetaData meta_data = *mesh->attributes().lookup_meta_data(
742 BKE_attributes_active_get(owner)->name);
743
744 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "domain");
745 if (!RNA_property_is_set(op->ptr, prop)) {
746 RNA_property_enum_set(op->ptr, prop, int(meta_data.domain));
747 }
748 prop = RNA_struct_find_property(op->ptr, "data_type");
749 if (!RNA_property_is_set(op->ptr, prop)) {
750 RNA_property_enum_set(op->ptr, prop, meta_data.data_type);
751 }
752
754 C, op, 300, IFACE_("Convert Attribute Domain"), IFACE_("Convert"));
755}
756
758{
759 uiLayout *layout = op->layout;
760 uiLayoutSetPropSep(layout, true);
761 uiLayoutSetPropDecorate(layout, false);
762
763 uiItemR(layout, op->ptr, "mode", UI_ITEM_NONE, nullptr, ICON_NONE);
764
765 const ConvertAttributeMode mode = static_cast<ConvertAttributeMode>(
766 RNA_enum_get(op->ptr, "mode"));
767
768 if (mode == ConvertAttributeMode::Generic) {
769 uiItemR(layout, op->ptr, "domain", UI_ITEM_NONE, nullptr, ICON_NONE);
770 uiItemR(layout, op->ptr, "data_type", UI_ITEM_NONE, nullptr, ICON_NONE);
771 }
772}
773
775{
776 if (!geometry_attributes_poll(C)) {
777 return false;
778 }
779
780 if (CTX_data_edit_object(C) != nullptr) {
781 CTX_wm_operator_poll_msg_set(C, "Operation is not allowed in edit mode");
782 return false;
783 }
784
786 ID *id = static_cast<ID *>(ob->data);
787 if (GS(id->name) != ID_ME) {
788 return false;
789 }
790 const Mesh *mesh = static_cast<const Mesh *>(ob->data);
791 const char *name = mesh->active_color_attribute;
792 const bke::AttributeAccessor attributes = mesh->attributes();
793 const std::optional<bke::AttributeMetaData> meta_data = attributes.lookup_meta_data(name);
794 if (!meta_data) {
795 return false;
796 }
797 if (!(ATTR_DOMAIN_AS_MASK(meta_data->domain) & ATTR_DOMAIN_MASK_COLOR) ||
798 !(CD_TYPE_AS_MASK(meta_data->data_type) & CD_MASK_COLOR_ALL))
799 {
800 return false;
801 }
802
803 return true;
804}
805
807{
809 Mesh *mesh = static_cast<Mesh *>(ob->data);
810 const char *name = mesh->active_color_attribute;
812 name,
813 eCustomDataType(RNA_enum_get(op->ptr, "data_type")),
814 bke::AttrDomain(RNA_enum_get(op->ptr, "domain")),
815 op->reports);
818 return OPERATOR_FINISHED;
819}
820
822 wmOperator *op,
823 const wmEvent * /*event*/)
824{
826 Mesh *mesh = static_cast<Mesh *>(ob->data);
827 const char *name = mesh->active_color_attribute;
828 const bke::AttributeMetaData meta_data = *mesh->attributes().lookup_meta_data(name);
829
830 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "domain");
831 if (!RNA_property_is_set(op->ptr, prop)) {
832 RNA_property_enum_set(op->ptr, prop, int(meta_data.domain));
833 }
834 prop = RNA_struct_find_property(op->ptr, "data_type");
835 if (!RNA_property_is_set(op->ptr, prop)) {
836 RNA_property_enum_set(op->ptr, prop, meta_data.data_type);
837 }
838
840 C, op, 300, IFACE_("Convert Color Attribute Domain"), IFACE_("Convert"));
841}
842
844{
845 uiLayout *layout = op->layout;
846 uiLayoutSetPropSep(layout, true);
847 uiLayoutSetPropDecorate(layout, false);
848
849 uiItemR(layout, op->ptr, "domain", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
850 uiItemR(layout, op->ptr, "data_type", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
851}
852
854{
855 ot->name = "Convert Color Attribute";
856 ot->description = "Change how the color attribute is stored";
857 ot->idname = "GEOMETRY_OT_color_attribute_convert";
858
863
865
866 PropertyRNA *prop;
867
868 prop = RNA_def_enum(ot->srna,
869 "domain",
872 "Domain",
873 "Type of element that attribute is stored on");
875
876 prop = RNA_def_enum(ot->srna,
877 "data_type",
880 "Data Type",
881 "Type of data stored in attribute");
883}
884
886{
887 ot->name = "Convert Attribute";
888 ot->description = "Change how the attribute is stored";
889 ot->idname = "GEOMETRY_OT_attribute_convert";
890
895
897
898 static EnumPropertyItem mode_items[] = {
899 {int(ConvertAttributeMode::Generic), "GENERIC", 0, "Generic", ""},
900 {int(ConvertAttributeMode::VertexGroup), "VERTEX_GROUP", 0, "Vertex Group", ""},
901 {0, nullptr, 0, nullptr, nullptr},
902 };
903
904 PropertyRNA *prop;
905
906 RNA_def_enum(ot->srna, "mode", mode_items, int(ConvertAttributeMode::Generic), "Mode", "");
907
908 prop = RNA_def_enum(ot->srna,
909 "domain",
912 "Domain",
913 "Which geometry element to move the attribute to");
915
917 ot->srna, "data_type", rna_enum_attribute_type_items, CD_PROP_FLOAT, "Data Type", "");
918}
919
920} // namespace blender::ed::geometry
921
923 const char *name,
924 const eCustomDataType dst_type,
925 const blender::bke::AttrDomain dst_domain,
926 ReportList *reports)
927{
928 using namespace blender;
929 bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
930 BLI_assert(mesh->attributes().contains(name));
931 BLI_assert(mesh->runtime->edit_mesh == nullptr);
932 if (ELEM(dst_type, CD_PROP_STRING)) {
933 if (reports) {
934 BKE_report(reports, RPT_ERROR, "Cannot convert to the selected type");
935 }
936 return false;
937 }
938
939 const std::string name_copy = name;
940 const GVArray varray = *attributes.lookup_or_default(name_copy, dst_domain, dst_type);
941
942 const CPPType &cpp_type = varray.type();
943 void *new_data = MEM_mallocN_aligned(
944 varray.size() * cpp_type.size(), cpp_type.alignment(), __func__);
945 varray.materialize_to_uninitialized(new_data);
946 attributes.remove(name_copy);
947 if (!attributes.add(name_copy, dst_domain, dst_type, bke::AttributeInitMoveArray(new_data))) {
948 MEM_freeN(new_data);
949 }
950
951 return true;
952}
const char * BKE_id_attributes_default_color_name(const struct ID *id)
const struct CustomDataLayer * BKE_id_attributes_color_find(const struct ID *id, const char *name)
void BKE_id_attributes_default_color_set(struct ID *id, const char *name)
Definition attribute.cc:994
void BKE_id_attributes_active_color_set(struct ID *id, const char *name)
Definition attribute.cc:965
struct CustomDataLayer * BKE_attribute_new(AttributeOwner &owner, const char *name, eCustomDataType type, blender::bke::AttrDomain domain, struct ReportList *reports)
const char * BKE_id_attributes_active_color_name(const struct ID *id)
struct CustomDataLayer * BKE_attribute_duplicate(AttributeOwner &owner, const char *name, struct ReportList *reports)
Definition attribute.cc:432
int * BKE_attributes_active_index_p(AttributeOwner &owner)
Definition attribute.cc:832
bool BKE_attribute_remove(AttributeOwner &owner, const char *name, struct ReportList *reports)
Definition attribute.cc:501
void BKE_attributes_active_set(AttributeOwner &owner, const char *name)
Definition attribute.cc:817
#define ATTR_DOMAIN_MASK_COLOR
#define ATTR_DOMAIN_AS_MASK(domain)
struct CustomDataLayer * BKE_attributes_active_get(AttributeOwner &owner)
Definition attribute.cc:781
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
Object * CTX_data_edit_object(const bContext *C)
Main * CTX_data_main(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
#define CD_TYPE_AS_MASK(_type)
support for deformation groups and hooks.
bDeformGroup * BKE_object_defgroup_new(Object *ob, blender::StringRef name)
Definition deform.cc:51
void BKE_defvert_add_index_notest(MDeformVert *dv, int defgroup, float weight)
Definition deform.cc:846
const ListBase * BKE_id_defgroup_list_get(const ID *id)
Definition deform.cc:464
bool BKE_id_is_editable(const Main *bmain, const ID *id)
Definition lib_id.cc:2456
Functions for dealing with objects and deform verts, used by painting and tools.
struct MDeformVert * BKE_object_defgroup_data_create(struct ID *id)
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
void BLI_kdtree_nd_ free(KDTree *tree)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define ELEM(...)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
#define IFACE_(msgid)
#define DATA_(msgid)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ ID_ME
#define CD_MASK_COLOR_ALL
@ CD_PROP_BYTE_COLOR
@ CD_PROP_FLOAT
@ CD_PROP_FLOAT3
@ CD_PROP_INT32_2D
@ CD_PROP_COLOR
@ CD_PROP_QUATERNION
@ CD_PROP_INT32
@ CD_PROP_FLOAT2
@ CD_PROP_STRING
@ CD_PROP_FLOAT4X4
#define MAX_NAME
Definition DNA_defs.h:50
Read Guarded memory(de)allocation.
const EnumPropertyItem * rna_enum_attribute_domain_itemf(const AttributeOwner &owner, bool include_instances, bool *r_free)
@ PROP_SKIP_SAVE
Definition RNA_types.hh:245
@ PROP_COLOR
Definition RNA_types.hh:163
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
#define UI_ITEM_NONE
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_ITEM_R_EXPAND
@ OPTYPE_INTERNAL
Definition WM_types.hh:182
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define NC_GEOM
Definition WM_types.hh:360
#define ND_DATA
Definition WM_types.hh:475
static AttributeOwner from_id(ID *id)
Definition attribute.cc:43
int64_t size() const
int64_t alignment() const
ColorSceneLinear4f< Alpha > decode() const
Definition BLI_color.hh:224
void materialize_to_uninitialized(void *dst) const
constexpr const char * c_str() const
void materialize(MutableSpan< T > r_span) const
std::optional< AttributeMetaData > lookup_meta_data(const StringRef attribute_id) const
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
bool ED_geometry_attribute_convert(Mesh *mesh, const char *name, const eCustomDataType dst_type, const blender::bke::AttrDomain dst_domain, ReportList *reports)
#define GS(x)
Definition iris.cc:202
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str)
Definition mallocn.cc:110
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type)
const CPPType * custom_data_type_to_cpp_type(eCustomDataType type)
GPointer rna_property_for_attribute_type_retrieve_value(PointerRNA &ptr, const eCustomDataType type, void *buffer)
static bool geometry_attributes_poll(bContext *C)
void GEOMETRY_OT_attribute_add(wmOperatorType *ot)
static const EnumPropertyItem * geometry_attribute_domain_itemf(bContext *C, PointerRNA *, PropertyRNA *, bool *r_free)
static int geometry_attribute_add_exec(bContext *C, wmOperator *op)
void GEOMETRY_OT_color_attribute_add(wmOperatorType *ot)
StringRefNull rna_property_name_for_type(const eCustomDataType type)
static int geometry_attribute_add_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void GEOMETRY_OT_attribute_convert(wmOperatorType *ot)
void GEOMETRY_OT_color_attribute_duplicate(wmOperatorType *ot)
static int geometry_attribute_remove_exec(bContext *C, wmOperator *op)
void GEOMETRY_OT_color_attribute_convert(wmOperatorType *ot)
static bool geometry_attributes_remove_poll(bContext *C)
static int geometry_color_attribute_convert_exec(bContext *C, wmOperator *op)
static void geometry_color_attribute_convert_ui(bContext *, wmOperator *op)
void register_rna_properties_for_attribute_types(StructRNA &srna)
void GEOMETRY_OT_attribute_remove(wmOperatorType *ot)
void GEOMETRY_OT_color_attribute_render_set(wmOperatorType *ot)
static int geometry_color_attribute_add_exec(bContext *C, wmOperator *op)
void rna_property_for_attribute_type_set_value(PointerRNA &ptr, PropertyRNA &prop, const GPointer value)
bool attribute_set_poll(bContext &C, const ID &object_data)
static bool geometry_color_attributes_remove_poll(bContext *C)
static bool geometry_attribute_convert_poll(bContext *C)
static void geometry_color_attribute_add_ui(bContext *, wmOperator *op)
static int geometry_color_attribute_duplicate_exec(bContext *C, wmOperator *op)
static int geometry_color_attribute_set_render_exec(bContext *C, wmOperator *op)
static int geometry_attribute_convert_exec(bContext *C, wmOperator *op)
PropertyRNA * rna_property_for_type(PointerRNA &ptr, const eCustomDataType type)
static int geometry_color_attribute_convert_invoke(bContext *C, wmOperator *op, const wmEvent *)
static bool geometry_color_attribute_convert_poll(bContext *C)
static int geometry_color_attribute_remove_exec(bContext *C, wmOperator *op)
static bool geometry_color_attributes_duplicate_poll(bContext *C)
void GEOMETRY_OT_color_attribute_remove(wmOperatorType *ot)
static void geometry_attribute_convert_ui(bContext *, wmOperator *op)
static int geometry_attribute_convert_invoke(bContext *C, wmOperator *op, const wmEvent *)
static int geometry_color_attribute_add_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Object * context_object(const bContext *C)
bool object_active_color_fill(Object &ob, const float fill_color[4], bool only_selected)
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
int RNA_int_get(PointerRNA *ptr, const char *name)
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
float RNA_float_get(PointerRNA *ptr, const char *name)
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
int RNA_enum_get(PointerRNA *ptr, const char *name)
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
const EnumPropertyItem rna_enum_color_attribute_domain_items[]
const EnumPropertyItem rna_enum_attribute_domain_items[]
const EnumPropertyItem rna_enum_attribute_type_items[]
const EnumPropertyItem rna_enum_color_attribute_type_items[]
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_int_array(StructOrFunctionRNA *cont_, const char *identifier, const int len, const int *default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
PropertyRNA * RNA_def_float_color(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
const EnumPropertyItem rna_enum_dummy_NULL_items[]
Definition rna_rna.cc:29
#define FLT_MAX
Definition stdcycles.h:14
signed int int32_t
Definition stdint.h:77
signed char int8_t
Definition stdint.h:75
Definition DNA_ID.h:413
char * active_color_attribute
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
void(* ui)(bContext *C, wmOperator *op)
Definition WM_types.hh:1053
StructRNA * srna
Definition WM_types.hh:1080
struct ReportList * reports
struct uiLayout * layout
struct PointerRNA * ptr
void WM_main_add_notifier(uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4126
wmOperatorType * ot
Definition wm_files.cc:4125
int WM_operator_props_popup_confirm_ex(bContext *C, wmOperator *op, const wmEvent *, std::optional< std::string > title, std::optional< std::string > confirm_text, const bool cancel_default)
int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, std::optional< std::string > title, std::optional< std::string > confirm_text, const bool cancel_default)