Blender V5.0
bpy_props.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12
13/* Future-proof, See https://docs.python.org/3/c-api/arg.html#strings-and-buffers */
14#define PY_SSIZE_T_CLEAN
15
16#include <algorithm>
17#include <string>
18
19#include <Python.h>
20
21#include "RNA_types.hh"
22
23#include "BLI_array.hh"
24#include "BLI_listbase.h"
25#include "BLI_utildefines.h"
26
27#include "bpy_capi_utils.hh"
28#include "bpy_props.hh"
29#include "bpy_rna.hh"
30
31#include "RNA_access.hh"
32#include "RNA_define.hh" /* for defining our own rna */
33#include "RNA_enum_types.hh"
34#include "RNA_prototypes.hh"
35
36#include "MEM_guardedalloc.h"
37
38#include "DNA_ID.h" /* MAX_IDPROP_NAME */
39
42#include "../generic/python_compat.hh" /* IWYU pragma: keep. */
44
45using blender::Array;
46
47/* Disabled duplicating strings because the array can still be freed and
48 * the strings from it referenced, for now we can't support dynamically
49 * created strings from Python. */
50// #define USE_ENUM_COPY_STRINGS
51
52/* -------------------------------------------------------------------- */
55
56#define BPY_PROPDEF_OPTIONS_DOC \
57 " :arg options: Enumerator in :ref:`rna_enum_property_flag_items`.\n" \
58 " :type options: set[str]\n"
59
60#define BPY_PROPDEF_OPTIONS_ENUM_DOC \
61 " :arg options: Enumerator in :ref:`rna_enum_property_flag_enum_items`.\n" \
62 " :type options: set[str]\n"
63
64#define BPY_PROPDEF_OPTIONS_OVERRIDE_DOC \
65 " :arg override: Enumerator in :ref:`rna_enum_property_override_flag_items`.\n" \
66 " :type override: set[str]\n"
67
68#define BPY_PROPDEF_OPTIONS_OVERRIDE_COLLECTION_DOC \
69 " :arg override: Enumerator in :ref:`rna_enum_property_override_flag_collection_items`.\n" \
70 " :type override: set[str]\n"
71
72#define BPY_PROPDEF_SUBTYPE_STRING_DOC \
73 " :arg subtype: Enumerator in :ref:`rna_enum_property_subtype_string_items`.\n" \
74 " :type subtype: str\n"
75
76#define BPY_PROPDEF_SUBTYPE_NUMBER_DOC \
77 " :arg subtype: Enumerator in :ref:`rna_enum_property_subtype_number_items`.\n" \
78 " :type subtype: str\n"
79
80#define BPY_PROPDEF_SUBTYPE_NUMBER_ARRAY_DOC \
81 " :arg subtype: Enumerator in :ref:`rna_enum_property_subtype_number_array_items`.\n" \
82 " :type subtype: str\n"
83
85
86/* -------------------------------------------------------------------- */
91
126
131 struct {
151 PyObject *get_fn;
152 PyObject *set_fn;
156 PyObject *update_fn;
157
159 union {
161 struct {
163 PyObject *itemf_fn;
166 struct {
168 PyObject *poll_fn;
171 struct {
173 PyObject *search_fn;
175 };
177};
178
179#define BPY_PROP_STORE_PY_DATA_SIZE (sizeof(BPyPropStore::py_data) / sizeof(PyObject *))
180
181#define ASSIGN_PYOBJECT_INCREF(a, b) \
182 { \
183 BLI_assert((a) == nullptr); \
184 Py_INCREF(b); \
185 a = b; \
186 } \
187 ((void)0)
188
193static ListBase g_bpy_prop_store_list = {nullptr, nullptr};
194
196{
197 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
198 if (prop_store == nullptr) {
199 prop_store = MEM_callocN<BPyPropStore>(__func__);
200 RNA_def_py_data(prop, prop_store);
202 }
203 return prop_store;
204}
205
210{
211 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
212 if (prop_store == nullptr) {
213 return;
214 }
215
216 PyObject **py_data = (PyObject **)&prop_store->py_data;
217 for (int i = 0; i < BPY_PROP_STORE_PY_DATA_SIZE; i++) {
218 Py_XDECREF(py_data[i]);
219 }
221}
222
224
225/* -------------------------------------------------------------------- */
232
234{
235 PyObject_GC_UnTrack(self);
236 Py_CLEAR(self->kw);
237 PyObject_GC_Del(self);
238}
239
240static int bpy_prop_deferred_traverse(BPy_PropDeferred *self, visitproc visit, void *arg)
241{
242 Py_VISIT(self->kw);
243 return 0;
244}
245
247{
248 Py_CLEAR(self->kw);
249 return 0;
250}
251
253{
254 return PyUnicode_FromFormat("<%.200s, %R, %R>", Py_TYPE(self)->tp_name, self->fn, self->kw);
255}
256
263static PyObject *bpy_prop_deferred_call(BPy_PropDeferred * /*self*/,
264 PyObject * /*args*/,
265 PyObject * /*kw*/)
266{
267 /* Dummy value. */
268 Py_RETURN_NONE;
269}
270
271/* Get/Set Items. */
272
277static PyObject *bpy_prop_deferred_function_get(BPy_PropDeferred *self, void * /*closure*/)
278{
279 PyObject *ret = static_cast<PyObject *>(self->fn);
280 Py_IncRef(ret);
281 return ret;
282}
283
288static PyObject *bpy_prop_deferred_keywords_get(BPy_PropDeferred *self, void * /*closure*/)
289{
290 PyObject *ret = self->kw;
291 Py_IncRef(ret);
292 return ret;
293}
294
295static PyGetSetDef bpy_prop_deferred_getset[] = {
296 {"function", (getter)bpy_prop_deferred_function_get, (setter) nullptr, nullptr, nullptr},
297 {"keywords", (getter)bpy_prop_deferred_keywords_get, (setter) nullptr, nullptr, nullptr},
298 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
299};
300
302 /* Wrap. */
303 bpy_prop_deferred_doc,
304 "Intermediate storage for properties before registration.\n"
305 "\n"
306 ".. note::\n"
307 "\n"
308 " This is not part of the stable API and may change between releases.\n");
310 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
311 /*tp_name*/ "_PropertyDeferred",
312 /*tp_basicsize*/ sizeof(BPy_PropDeferred),
313 /*tp_itemsize*/ 0,
314 /*tp_dealloc*/ (destructor)bpy_prop_deferred_dealloc,
315 /*tp_vectorcall_offset*/ 0,
316 /*tp_getattr*/ nullptr,
317 /*tp_setattr*/ nullptr,
318 /*tp_as_async*/ nullptr,
319 /*tp_repr*/ (reprfunc)bpy_prop_deferred_repr,
320 /*tp_as_number*/ nullptr,
321 /*tp_as_sequence*/ nullptr,
322 /*tp_as_mapping*/ nullptr,
323 /*tp_hash*/ nullptr,
324 /*tp_call*/ (ternaryfunc)bpy_prop_deferred_call,
325 /*tp_str*/ nullptr,
326 /*tp_getattro*/ nullptr,
327 /*tp_setattro*/ nullptr,
328 /*tp_as_buffer*/ nullptr,
329 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
330 /*tp_doc*/ bpy_prop_deferred_doc,
331 /*tp_traverse*/ (traverseproc)bpy_prop_deferred_traverse,
332 /*tp_clear*/ (inquiry)bpy_prop_deferred_clear,
333 /*tp_richcompare*/ nullptr,
334 /*tp_weaklistoffset*/ 0,
335 /*tp_iter*/ nullptr,
336 /*tp_iternext*/ nullptr,
337 /*tp_methods*/ nullptr,
338 /*tp_members*/ nullptr,
339 /*tp_getset*/ bpy_prop_deferred_getset,
340 /*tp_base*/ nullptr,
341 /*tp_dict*/ nullptr,
342 /*tp_descr_get*/ nullptr,
343 /*tp_descr_set*/ nullptr,
344 /*tp_dictoffset*/ 0,
345 /*tp_init*/ nullptr,
346 /*tp_alloc*/ nullptr,
347 /*tp_new*/ nullptr,
348 /*tp_free*/ nullptr,
349 /*tp_is_gc*/ nullptr,
350 /*tp_bases*/ nullptr,
351 /*tp_mro*/ nullptr,
352 /*tp_cache*/ nullptr,
353 /*tp_subclasses*/ nullptr,
354 /*tp_weaklist*/ nullptr,
355 /*tp_del*/ nullptr,
356 /*tp_version_tag*/ 0,
357 /*tp_finalize*/ nullptr,
358 /*tp_vectorcall*/ nullptr,
359};
360
361static PyObject *bpy_prop_deferred_data_CreatePyObject(PyObject *fn, PyObject *kw)
362{
364 self->fn = fn;
365 if (kw == nullptr) {
366 kw = PyDict_New();
367 }
368 else {
369 Py_INCREF(kw);
370 }
371 self->kw = kw;
372 BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
373 PyObject_GC_Track(self);
374 return (PyObject *)self;
375}
376
378
379/* -------------------------------------------------------------------- */
382
383/* PyObject's */
384static PyObject *pymeth_BoolProperty = nullptr;
385static PyObject *pymeth_BoolVectorProperty = nullptr;
386static PyObject *pymeth_IntProperty = nullptr;
387static PyObject *pymeth_IntVectorProperty = nullptr;
388static PyObject *pymeth_FloatProperty = nullptr;
389static PyObject *pymeth_FloatVectorProperty = nullptr;
390static PyObject *pymeth_StringProperty = nullptr;
391static PyObject *pymeth_EnumProperty = nullptr;
392static PyObject *pymeth_PointerProperty = nullptr;
393static PyObject *pymeth_CollectionProperty = nullptr;
394static PyObject *pymeth_RemoveProperty = nullptr;
395
397{
398 PyObject *self = nullptr;
399 /* first get self */
400 /* operators can store their own instance for later use */
401 if (ptr->data) {
402 void **instance = RNA_struct_instance(ptr);
403
404 if (instance) {
405 if (*instance) {
406 self = static_cast<PyObject *>(*instance);
407 Py_INCREF(self);
408 }
409 }
410 }
411
412 /* in most cases this will run */
413 if (self == nullptr) {
415 }
416
417 return self;
418}
419
420static void bpy_prop_assign_flag(PropertyRNA *prop, int flag)
421{
422 /* Map `READ_ONLY` to `EDITABLE`. */
424
425 /* The default is editable. */
426 const int flag_mask_set = (flag & ~PROP_EDITABLE);
427 const int flag_mask_clear = ((PROP_ANIMATABLE | PROP_EDITABLE) & ~flag);
428
429 if (flag_mask_set) {
430 RNA_def_property_flag(prop, PropertyFlag(flag_mask_set));
431 }
432
433 if (flag_mask_clear) {
434 RNA_def_property_clear_flag(prop, PropertyFlag(flag_mask_clear));
435 }
436}
437
438static void bpy_prop_assign_flag_override(PropertyRNA *prop, const int flag_override)
439{
441}
442
443/* These utility functions de-duplicate boiler plate code used by most property callbacks.
444 * It's important they're at the beginning & end of the callbacks and both are always called. */
445
447 PyGILState_STATE gilstate;
449};
450
452{
453 /* It's important to acquire the lock before reading other state information, see: #127767. */
454 const PyGILState_STATE gilstate = PyGILState_Ensure();
455 const bool is_write_ok = pyrna_write_check();
456 return {
457 /*gilstate*/ gilstate,
458 /*is_write_ok*/ is_write_ok,
459 };
460}
461
463{
464 if (!prop_state.is_write_ok) {
465 pyrna_write_set(false);
466 }
467 PyGILState_Release(prop_state.gilstate);
468}
469
471
472/* -------------------------------------------------------------------- */
475
477 int len_total = 0;
480 int dims_len = 0;
481
484 {
485 this->len_total = RNA_property_array_length(ptr, prop);
486 this->dims_len = RNA_property_array_dimension(ptr, prop, this->dims);
487 }
488
489 bool operator==(const BPyPropArrayLength &other) const
490 {
491 if ((this->len_total != other.len_total) || (this->dims_len != other.dims_len)) {
492 return false;
493 }
494 for (int i = 0; i < this->dims_len; i++) {
495 if (this->dims[i] != other.dims[i]) {
496 return false;
497 }
498 }
499 return true;
500 }
501};
502
506static int bpy_prop_array_length_parse(PyObject *o, void *p)
507{
508 BPyPropArrayLength *array_len_info = static_cast<BPyPropArrayLength *>(p);
509
510 if (PyLong_CheckExact(o)) {
511 int size;
512 if ((size = PyLong_AsLong(o)) == -1) {
513 PyErr_Format(
514 PyExc_ValueError, "expected number or sequence of numbers, got %s", Py_TYPE(o)->tp_name);
515 return 0;
516 }
518 PyErr_Format(
519 PyExc_TypeError, "(size=%d) must be between 1 and " STRINGIFY(PYRNA_STACK_ARRAY), size);
520 return 0;
521 }
522 array_len_info->len_total = size;
523
524 /* Don't use this value. */
525 array_len_info->dims_len = 0;
526 }
527 else {
528 PyObject *seq_fast;
529 if (!(seq_fast = PySequence_Fast(o, "size must be a number of a sequence of numbers"))) {
530 return 0;
531 }
532 const int seq_len = PySequence_Fast_GET_SIZE(seq_fast);
533 if (seq_len < 1 || seq_len > RNA_MAX_ARRAY_DIMENSION) {
534 PyErr_Format(
535 PyExc_TypeError,
536 "(len(size)=%d) length must be between 1 and " STRINGIFY(RNA_MAX_ARRAY_DIMENSION),
537 seq_len);
538 Py_DECREF(seq_fast);
539 return 0;
540 }
541
542 PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
543 array_len_info->len_total = 1;
544 for (int i = 0; i < seq_len; i++) {
545 int size;
546 if ((size = PyLong_AsLong(seq_items[i])) == -1) {
547 Py_DECREF(seq_fast);
548 PyErr_Format(PyExc_ValueError,
549 "expected number in sequence, got %s at index %d",
550 Py_TYPE(o)->tp_name,
551 i);
552 return 0;
553 }
555 Py_DECREF(seq_fast);
556 PyErr_Format(PyExc_TypeError,
557 "(size[%d]=%d) must be between 1 and " STRINGIFY(PYRNA_STACK_ARRAY),
558 i,
559 size);
560 return 0;
561 }
562
563 array_len_info->dims[i] = size;
564 array_len_info->dims_len = seq_len;
565 array_len_info->len_total *= size;
566 }
567 }
568 return 1;
569}
570
574static int bpy_prop_array_from_py_with_dims(void *values,
575 size_t values_elem_size,
576 PyObject *py_values,
577 const BPyPropArrayLength *array_len_info,
578 const PyTypeObject *type,
579 const char *error_str)
580{
581 if (array_len_info->dims_len == 0) {
582 return PyC_AsArray(
583 values, values_elem_size, py_values, array_len_info->len_total, type, error_str);
584 }
585 const int *dims = array_len_info->dims;
586 const int dims_len = array_len_info->dims_len;
587 return PyC_AsArray_Multi(values, values_elem_size, py_values, dims, dims_len, type, error_str);
588}
589
590/* NOTE: Always increases refcount of the returned value. */
591static PyObject *bpy_py_object_from_prop_array_with_dims(const void *values,
592 const BPyPropArrayLength &array_len_info,
593 const PyTypeObject &type)
594{
595 PyObject *py_values = nullptr;
596
597 if (&type == &PyBool_Type) {
598 if (array_len_info.dims_len == 0) {
599 py_values = PyC_Tuple_PackArray_Bool(static_cast<const bool *>(values),
600 uint(array_len_info.len_total));
601 }
602 else {
604 static_cast<const bool *>(values), array_len_info.dims, array_len_info.dims_len);
605 }
606 }
607 else if (&type == &PyLong_Type) {
608 if (array_len_info.dims_len == 0) {
609 py_values = PyC_Tuple_PackArray_I32(static_cast<const int *>(values),
610 uint(array_len_info.len_total));
611 }
612 else {
614 static_cast<const int *>(values), array_len_info.dims, array_len_info.dims_len);
615 }
616 }
617 else if (&type == &PyFloat_Type) {
618 if (array_len_info.dims_len == 0) {
619 py_values = PyC_Tuple_PackArray_F32(static_cast<const float *>(values),
620 uint(array_len_info.len_total));
621 }
622 else {
623 /* No need for matrix column/row swapping here unless the matrix data is read directly. */
625 static_cast<const float *>(values), array_len_info.dims, array_len_info.dims_len);
626 }
627 }
628 else {
630 }
631
632 return py_values;
633}
634
636 const BPyPropArrayLength *array_len_info)
637{
638 return ((subtype == PROP_MATRIX) && (array_len_info->dims_len == 2) &&
639 ((array_len_info->dims[0] >= 2) && (array_len_info->dims[0] <= 4)) &&
640 ((array_len_info->dims[1] >= 2) && (array_len_info->dims[1] <= 4)));
641}
642
644 const BPyPropArrayLength *array_len_info)
645{
648}
649
654 const float *values_src,
655 const BPyPropArrayLength *array_len_info)
656{
657 BLI_assert(values_dst != values_src);
658 const int dim0 = array_len_info->dims[0], dim1 = array_len_info->dims[1];
659 BLI_assert(dim0 <= 4 && dim1 <= 4);
660 for (int i = 0; i < dim0; i++) {
661 for (int j = 0; j < dim1; j++) {
662 values_dst[(j * dim0) + i] = values_src[(i * dim1) + j];
663 }
664 }
665}
666
668 const BPyPropArrayLength *array_len_info)
669{
670 const int dim0 = array_len_info->dims[0], dim1 = array_len_info->dims[1];
671 BLI_assert(dim0 <= 4 && dim1 <= 4);
672 float values_orig[4 * 4];
673 memcpy(values_orig, values, sizeof(float) * (dim0 * dim1));
674 bpy_prop_array_matrix_swap_row_column_vn_vn(values, values_orig, array_len_info);
675}
676
678
679/* -------------------------------------------------------------------- */
684
685/* callbacks */
687{
688 PyGILState_STATE gilstate;
689 bpy_context_set(C, &gilstate);
690 const bool is_write_ok = pyrna_write_check();
691 if (!is_write_ok) {
692 pyrna_write_set(true);
693 }
694
695 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
696 PyObject *py_func;
697 PyObject *ret;
698
699 BLI_assert(prop_store != nullptr);
700
701 py_func = prop_store->py_data.update_fn;
702
703 {
704 PyObject *args = PyTuple_New(2);
705 PyObject *self = pyrna_struct_as_instance(ptr);
706 PyTuple_SET_ITEMS(args, self, reinterpret_cast<PyObject *>(bpy_context_module));
707 Py_INCREF(bpy_context_module);
708
709 ret = PyObject_CallObject(py_func, args);
710
711 Py_DECREF(args);
712 }
713
714 if (ret == nullptr) {
715 PyC_Err_PrintWithFunc(py_func);
716 }
717 else {
718 if (ret != Py_None) {
719 PyErr_SetString(PyExc_ValueError, "the return value must be None");
720 PyC_Err_PrintWithFunc(py_func);
721 }
722
723 Py_DECREF(ret);
724 }
725
726 if (!is_write_ok) {
727 pyrna_write_set(false);
728 }
729
730 bpy_context_clear(C, &gilstate);
731}
732
734
735/* -------------------------------------------------------------------- */
738
740{
742
743 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
744 PyObject *py_func;
745 PyObject *ret;
746 bool value;
747
748 BLI_assert(prop_store != nullptr);
749
750 py_func = prop_store->py_data.get_fn;
751
752 {
753 PyObject *args = PyTuple_New(1);
754 PyObject *self = pyrna_struct_as_instance(ptr);
755 PyTuple_SET_ITEMS(args, self);
756
757 ret = PyObject_CallObject(py_func, args);
758
759 Py_DECREF(args);
760 }
761
762 if (ret == nullptr) {
763 PyC_Err_PrintWithFunc(py_func);
764 value = false;
765 }
766 else {
767 const int value_i = PyC_Long_AsBool(ret);
768
769 if (value_i == -1 && PyErr_Occurred()) {
770 PyC_Err_PrintWithFunc(py_func);
771 value = false;
772 }
773 else {
774 value = bool(value_i);
775 }
776
777 Py_DECREF(ret);
778 }
779
781
782 return value;
783}
784
786 PropertyRNA *prop,
787 bool curr_value,
788 bool is_set)
789{
791
792 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
793 PyObject *py_func;
794 PyObject *ret;
795
796 BLI_assert(prop_store != nullptr);
797
798 py_func = prop_store->py_data.get_transform_fn;
799
800 {
801 PyObject *args = PyTuple_New(3);
802 PyObject *self = pyrna_struct_as_instance(ptr);
803 PyTuple_SET_ITEMS(args, self, PyBool_FromLong(curr_value), PyBool_FromLong(is_set));
804
805 ret = PyObject_CallObject(py_func, args);
806
807 Py_DECREF(args);
808 }
809
810 bool ret_value = curr_value;
811 if (ret == nullptr) {
812 PyC_Err_PrintWithFunc(py_func);
813 }
814 else {
815 const int value_i = PyC_Long_AsBool(ret);
816
817 if (value_i == -1 && PyErr_Occurred()) {
818 PyC_Err_PrintWithFunc(py_func);
819 }
820 else {
821 ret_value = bool(value_i);
822 }
823
824 Py_DECREF(ret);
825 }
826
828
829 return ret_value;
830}
831
832static void bpy_prop_boolean_set_fn(PointerRNA *ptr, PropertyRNA *prop, bool value)
833{
835
836 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
837 PyObject *py_func;
838 PyObject *ret;
839
840 BLI_assert(prop_store != nullptr);
841
842 py_func = prop_store->py_data.set_fn;
843
844 {
845 PyObject *args = PyTuple_New(2);
846 PyObject *self = pyrna_struct_as_instance(ptr);
847 PyTuple_SET_ITEMS(args, self, PyBool_FromLong(value));
848
849 ret = PyObject_CallObject(py_func, args);
850
851 Py_DECREF(args);
852 }
853
854 if (ret == nullptr) {
855 PyC_Err_PrintWithFunc(py_func);
856 }
857 else {
858 if (ret != Py_None) {
859 PyErr_SetString(PyExc_ValueError, "the return value must be None");
860 PyC_Err_PrintWithFunc(py_func);
861 }
862
863 Py_DECREF(ret);
864 }
865
867}
868
870 PointerRNA *ptr, PropertyRNA *prop, bool new_value, bool curr_value, bool is_set)
871{
873
874 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
875 PyObject *py_func;
876 PyObject *ret;
877
878 BLI_assert(prop_store != nullptr);
879
880 py_func = prop_store->py_data.set_transform_fn;
881
882 {
883 PyObject *args = PyTuple_New(4);
884 PyObject *self = pyrna_struct_as_instance(ptr);
886 self,
887 PyBool_FromLong(new_value),
888 PyBool_FromLong(curr_value),
889 PyBool_FromLong(is_set));
890
891 ret = PyObject_CallObject(py_func, args);
892
893 Py_DECREF(args);
894 }
895
896 bool ret_value = curr_value;
897 if (ret == nullptr) {
898 PyC_Err_PrintWithFunc(py_func);
899 }
900 else {
901 const int value_i = PyC_Long_AsBool(ret);
902
903 if (value_i == -1 && PyErr_Occurred()) {
904 PyC_Err_PrintWithFunc(py_func);
905 }
906 else {
907 ret_value = bool(value_i);
908 }
909
910 Py_DECREF(ret);
911 }
912
914
915 return ret_value;
916}
917
918static void bpy_prop_boolean_array_from_callback_or_error(PyObject *bool_array_obj,
919 const BPyPropArrayLength &array_len_info,
920 PyObject *py_func,
921 bool *r_values)
922{
923 bool is_values_set = false;
924
925 if (bool_array_obj != nullptr) {
927 sizeof(*r_values),
928 bool_array_obj,
929 &array_len_info,
930 &PyBool_Type,
931 "BoolVectorProperty get callback") == -1)
932 {
933 PyC_Err_PrintWithFunc(py_func);
934 }
935 else {
936 is_values_set = true;
937 }
938 }
939
940 if (is_values_set == false) {
941 /* This is the flattened length for multi-dimensional arrays. */
942 for (int i = 0; i < array_len_info.len_total; i++) {
943 r_values[i] = false;
944 }
945 }
946
947 Py_XDECREF(bool_array_obj);
948}
949
950static void bpy_prop_boolean_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, bool *values)
951{
953
954 const BPyPropArrayLength array_len_info{ptr, prop};
955 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
956 PyObject *py_func;
957 PyObject *ret;
958
959 BLI_assert(prop_store != nullptr);
960
961 py_func = prop_store->py_data.get_fn;
962
963 {
964 PyObject *args = PyTuple_New(1);
965 PyObject *self = pyrna_struct_as_instance(ptr);
966 PyTuple_SET_ITEMS(args, self);
967
968 ret = PyObject_CallObject(py_func, args);
969
970 Py_DECREF(args);
971 }
972
973 bpy_prop_boolean_array_from_callback_or_error(ret, array_len_info, py_func, values);
974
976}
977
979 PointerRNA *ptr, PropertyRNA *prop, const bool *curr_values, bool is_set, bool *r_values)
980{
982
983 const BPyPropArrayLength array_len_info{ptr, prop};
984 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
985 PyObject *py_func;
986 PyObject *ret;
987
988 BLI_assert(prop_store != nullptr);
989
990 py_func = prop_store->py_data.get_transform_fn;
991
992 {
993 PyObject *args = PyTuple_New(3);
994 PyObject *self = pyrna_struct_as_instance(ptr);
996 args,
997 self,
998 bpy_py_object_from_prop_array_with_dims(curr_values, array_len_info, PyBool_Type),
999 PyBool_FromLong(is_set));
1000
1001 ret = PyObject_CallObject(py_func, args);
1002
1003 Py_DECREF(args);
1004 }
1005
1006 bpy_prop_boolean_array_from_callback_or_error(ret, array_len_info, py_func, r_values);
1007
1009}
1010
1011static void bpy_prop_boolean_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const bool *values)
1012{
1014
1015 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1016 PyObject *py_func;
1017 PyObject *ret;
1018
1019 const BPyPropArrayLength array_len_info{ptr, prop};
1020
1021 BLI_assert(prop_store != nullptr);
1022
1023 py_func = prop_store->py_data.set_fn;
1024
1025 {
1026 PyObject *args = PyTuple_New(2);
1027 PyObject *self = pyrna_struct_as_instance(ptr);
1029 args, self, bpy_py_object_from_prop_array_with_dims(values, array_len_info, PyBool_Type));
1030
1031 ret = PyObject_CallObject(py_func, args);
1032
1033 Py_DECREF(args);
1034 }
1035
1036 if (ret == nullptr) {
1037 PyC_Err_PrintWithFunc(py_func);
1038 }
1039 else {
1040 if (ret != Py_None) {
1041 PyErr_SetString(PyExc_ValueError, "the return value must be None");
1042 PyC_Err_PrintWithFunc(py_func);
1043 }
1044
1045 Py_DECREF(ret);
1046 }
1047
1049}
1050
1052 PropertyRNA *prop,
1053 const bool *new_values,
1054 const bool *curr_values,
1055 bool is_set,
1056 bool *r_final_values)
1057{
1059
1060 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1061 PyObject *py_func;
1062 PyObject *ret;
1063
1064 const BPyPropArrayLength array_len_info{ptr, prop};
1065
1066 BLI_assert(prop_store != nullptr);
1067
1068 py_func = prop_store->py_data.set_transform_fn;
1069
1070 {
1071 PyObject *args = PyTuple_New(4);
1072 PyObject *self = pyrna_struct_as_instance(ptr);
1074 args,
1075 self,
1076 bpy_py_object_from_prop_array_with_dims(new_values, array_len_info, PyBool_Type),
1077 bpy_py_object_from_prop_array_with_dims(curr_values, array_len_info, PyBool_Type),
1078 PyBool_FromLong(is_set));
1079
1080 ret = PyObject_CallObject(py_func, args);
1081
1082 Py_DECREF(args);
1083 }
1084
1085 bpy_prop_boolean_array_from_callback_or_error(ret, array_len_info, py_func, r_final_values);
1086
1088}
1089
1091
1092/* -------------------------------------------------------------------- */
1095
1097{
1099
1100 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1101 PyObject *py_func;
1102 PyObject *ret;
1103 int value;
1104
1105 BLI_assert(prop_store != nullptr);
1106
1107 py_func = prop_store->py_data.get_fn;
1108
1109 {
1110 PyObject *args = PyTuple_New(1);
1111 PyObject *self = pyrna_struct_as_instance(ptr);
1112 PyTuple_SET_ITEMS(args, self);
1113
1114 ret = PyObject_CallObject(py_func, args);
1115
1116 Py_DECREF(args);
1117 }
1118
1119 if (ret == nullptr) {
1120 PyC_Err_PrintWithFunc(py_func);
1121 value = 0;
1122 }
1123 else {
1124 value = PyC_Long_AsI32(ret);
1125
1126 if (value == -1 && PyErr_Occurred()) {
1127 PyC_Err_PrintWithFunc(py_func);
1128 value = 0;
1129 }
1130
1131 Py_DECREF(ret);
1132 }
1133
1135
1136 return value;
1137}
1138
1140 PropertyRNA *prop,
1141 int curr_value,
1142 bool is_set)
1143{
1145
1146 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1147 PyObject *py_func;
1148 PyObject *ret;
1149
1150 BLI_assert(prop_store != nullptr);
1151
1152 py_func = prop_store->py_data.get_transform_fn;
1153
1154 {
1155 PyObject *args = PyTuple_New(3);
1156 PyObject *self = pyrna_struct_as_instance(ptr);
1157 PyTuple_SET_ITEMS(args, self, PyLong_FromLong(curr_value), PyBool_FromLong(is_set));
1158
1159 ret = PyObject_CallObject(py_func, args);
1160
1161 Py_DECREF(args);
1162 }
1163
1164 int ret_value = curr_value;
1165 if (ret == nullptr) {
1166 PyC_Err_PrintWithFunc(py_func);
1167 }
1168 else {
1169 ret_value = PyC_Long_AsI32(ret);
1170
1171 if (ret_value == -1 && PyErr_Occurred()) {
1172 PyC_Err_PrintWithFunc(py_func);
1173 ret_value = curr_value;
1174 }
1175
1176 Py_DECREF(ret);
1177 }
1178
1180
1181 return ret_value;
1182}
1183
1184static void bpy_prop_int_set_fn(PointerRNA *ptr, PropertyRNA *prop, int value)
1185{
1187
1188 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1189 PyObject *py_func;
1190 PyObject *ret;
1191
1192 BLI_assert(prop_store != nullptr);
1193
1194 py_func = prop_store->py_data.set_fn;
1195
1196 {
1197 PyObject *args = PyTuple_New(2);
1198 PyObject *self = pyrna_struct_as_instance(ptr);
1199 PyTuple_SET_ITEMS(args, self, PyLong_FromLong(value));
1200
1201 ret = PyObject_CallObject(py_func, args);
1202
1203 Py_DECREF(args);
1204 }
1205
1206 if (ret == nullptr) {
1207 PyC_Err_PrintWithFunc(py_func);
1208 }
1209 else {
1210 if (ret != Py_None) {
1211 PyErr_SetString(PyExc_ValueError, "the return value must be None");
1212 PyC_Err_PrintWithFunc(py_func);
1213 }
1214
1215 Py_DECREF(ret);
1216 }
1217
1219}
1220
1222 PointerRNA *ptr, PropertyRNA *prop, int new_value, int curr_value, bool is_set)
1223{
1225
1226 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1227 PyObject *py_func;
1228 PyObject *ret;
1229
1230 BLI_assert(prop_store != nullptr);
1231
1232 py_func = prop_store->py_data.set_transform_fn;
1233
1234 {
1235 PyObject *args = PyTuple_New(4);
1236 PyObject *self = pyrna_struct_as_instance(ptr);
1237 PyTuple_SET_ITEMS(args,
1238 self,
1239 PyLong_FromLong(new_value),
1240 PyLong_FromLong(curr_value),
1241 PyBool_FromLong(is_set));
1242
1243 ret = PyObject_CallObject(py_func, args);
1244
1245 Py_DECREF(args);
1246 }
1247
1248 int ret_value = curr_value;
1249 if (ret == nullptr) {
1250 PyC_Err_PrintWithFunc(py_func);
1251 }
1252 else {
1253 ret_value = PyC_Long_AsI32(ret);
1254
1255 if (ret_value == -1 && PyErr_Occurred()) {
1256 PyC_Err_PrintWithFunc(py_func);
1257 ret_value = curr_value;
1258 }
1259
1260 Py_DECREF(ret);
1261 }
1262
1264
1265 return ret_value;
1266}
1267
1268static void bpy_prop_int_array_from_callback_or_error(PyObject *int_array_obj,
1269 const BPyPropArrayLength &array_len_info,
1270 PyObject *py_func,
1271 int *r_values)
1272{
1273 bool is_values_set = false;
1274
1275 if (int_array_obj != nullptr) {
1277 sizeof(*r_values),
1278 int_array_obj,
1279 &array_len_info,
1280 &PyLong_Type,
1281 "IntVectorProperty get callback") == -1)
1282 {
1283 PyC_Err_PrintWithFunc(py_func);
1284 }
1285 else {
1286 is_values_set = true;
1287 }
1288 }
1289
1290 if (is_values_set == false) {
1291 /* This is the flattened length for multi-dimensional arrays. */
1292 for (int i = 0; i < array_len_info.len_total; i++) {
1293 r_values[i] = 0;
1294 }
1295 }
1296
1297 Py_XDECREF(int_array_obj);
1298}
1299
1300static void bpy_prop_int_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, int *values)
1301{
1303
1304 const BPyPropArrayLength array_len_info{ptr, prop};
1305 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1306 PyObject *py_func;
1307 PyObject *ret;
1308
1309 BLI_assert(prop_store != nullptr);
1310
1311 py_func = prop_store->py_data.get_fn;
1312
1313 {
1314 PyObject *args = PyTuple_New(1);
1315 PyObject *self = pyrna_struct_as_instance(ptr);
1316 PyTuple_SET_ITEMS(args, self);
1317
1318 ret = PyObject_CallObject(py_func, args);
1319
1320 Py_DECREF(args);
1321 }
1322
1323 bpy_prop_int_array_from_callback_or_error(ret, array_len_info, py_func, values);
1324
1326}
1327
1329 PointerRNA *ptr, PropertyRNA *prop, const int *curr_values, bool is_set, int *r_values)
1330{
1332
1333 const BPyPropArrayLength array_len_info{ptr, prop};
1334 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1335 PyObject *py_func;
1336 PyObject *ret;
1337
1338 BLI_assert(prop_store != nullptr);
1339
1340 py_func = prop_store->py_data.get_transform_fn;
1341
1342 {
1343 PyObject *args = PyTuple_New(3);
1344 PyObject *self = pyrna_struct_as_instance(ptr);
1346 args,
1347 self,
1348 bpy_py_object_from_prop_array_with_dims(curr_values, array_len_info, PyLong_Type),
1349 PyBool_FromLong(is_set));
1350
1351 ret = PyObject_CallObject(py_func, args);
1352
1353 Py_DECREF(args);
1354 }
1355
1356 bpy_prop_int_array_from_callback_or_error(ret, array_len_info, py_func, r_values);
1357
1359}
1360
1361static void bpy_prop_int_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1362{
1364
1365 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1366 PyObject *py_func;
1367 PyObject *ret;
1368
1369 const BPyPropArrayLength array_len_info{ptr, prop};
1370
1371 BLI_assert(prop_store != nullptr);
1372
1373 py_func = prop_store->py_data.set_fn;
1374
1375 {
1376 PyObject *args = PyTuple_New(2);
1377 PyObject *self = pyrna_struct_as_instance(ptr);
1379 args, self, bpy_py_object_from_prop_array_with_dims(values, array_len_info, PyLong_Type));
1380
1381 ret = PyObject_CallObject(py_func, args);
1382
1383 Py_DECREF(args);
1384 }
1385
1386 if (ret == nullptr) {
1387 PyC_Err_PrintWithFunc(py_func);
1388 }
1389 else {
1390 if (ret != Py_None) {
1391 PyErr_SetString(PyExc_ValueError, "the return value must be None");
1392 PyC_Err_PrintWithFunc(py_func);
1393 }
1394
1395 Py_DECREF(ret);
1396 }
1397
1399}
1400
1402 PropertyRNA *prop,
1403 const int *new_values,
1404 const int *curr_values,
1405 bool is_set,
1406 int *r_final_values)
1407{
1409
1410 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1411 PyObject *py_func;
1412 PyObject *ret;
1413
1414 const BPyPropArrayLength array_len_info{ptr, prop};
1415
1416 BLI_assert(prop_store != nullptr);
1417
1418 py_func = prop_store->py_data.set_transform_fn;
1419
1420 {
1421 PyObject *args = PyTuple_New(4);
1422 PyObject *self = pyrna_struct_as_instance(ptr);
1424 args,
1425 self,
1426 bpy_py_object_from_prop_array_with_dims(new_values, array_len_info, PyLong_Type),
1427 bpy_py_object_from_prop_array_with_dims(curr_values, array_len_info, PyLong_Type),
1428 PyBool_FromLong(is_set));
1429
1430 ret = PyObject_CallObject(py_func, args);
1431
1432 Py_DECREF(args);
1433 }
1434
1435 bpy_prop_int_array_from_callback_or_error(ret, array_len_info, py_func, r_final_values);
1436
1438}
1439
1441
1442/* -------------------------------------------------------------------- */
1445
1447{
1449
1450 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1451 PyObject *py_func;
1452 PyObject *ret;
1453 float value;
1454
1455 BLI_assert(prop_store != nullptr);
1456
1457 py_func = prop_store->py_data.get_fn;
1458
1459 {
1460 PyObject *args = PyTuple_New(1);
1461 PyObject *self = pyrna_struct_as_instance(ptr);
1462 PyTuple_SET_ITEMS(args, self);
1463
1464 ret = PyObject_CallObject(py_func, args);
1465
1466 Py_DECREF(args);
1467 }
1468
1469 if (ret == nullptr) {
1470 PyC_Err_PrintWithFunc(py_func);
1471 value = 0.0f;
1472 }
1473 else {
1474 value = PyFloat_AsDouble(ret);
1475
1476 if (value == -1.0f && PyErr_Occurred()) {
1477 PyC_Err_PrintWithFunc(py_func);
1478 value = 0.0f;
1479 }
1480
1481 Py_DECREF(ret);
1482 }
1483
1485
1486 return value;
1487}
1488
1490 PropertyRNA *prop,
1491 float curr_value,
1492 bool is_set)
1493{
1495
1496 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1497 PyObject *py_func;
1498 PyObject *ret;
1499
1500 BLI_assert(prop_store != nullptr);
1501
1502 py_func = prop_store->py_data.get_transform_fn;
1503
1504 {
1505 PyObject *args = PyTuple_New(3);
1506 PyObject *self = pyrna_struct_as_instance(ptr);
1507 PyTuple_SET_ITEMS(args, self, PyFloat_FromDouble(curr_value), PyBool_FromLong(is_set));
1508
1509 ret = PyObject_CallObject(py_func, args);
1510
1511 Py_DECREF(args);
1512 }
1513
1514 float ret_value = curr_value;
1515 if (ret == nullptr) {
1516 PyC_Err_PrintWithFunc(py_func);
1517 }
1518 else {
1519 ret_value = PyFloat_AsDouble(ret);
1520
1521 if (ret_value == -1.0f && PyErr_Occurred()) {
1522 PyC_Err_PrintWithFunc(py_func);
1523 ret_value = curr_value;
1524 }
1525
1526 Py_DECREF(ret);
1527 }
1528
1530
1531 return ret_value;
1532}
1533
1534static void bpy_prop_float_set_fn(PointerRNA *ptr, PropertyRNA *prop, float value)
1535{
1537
1538 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1539 PyObject *py_func;
1540 PyObject *ret;
1541
1542 BLI_assert(prop_store != nullptr);
1543
1544 py_func = prop_store->py_data.set_fn;
1545
1546 {
1547 PyObject *args = PyTuple_New(2);
1548 PyObject *self = pyrna_struct_as_instance(ptr);
1549 PyTuple_SET_ITEMS(args, self, PyFloat_FromDouble(value));
1550
1551 ret = PyObject_CallObject(py_func, args);
1552
1553 Py_DECREF(args);
1554 }
1555
1556 if (ret == nullptr) {
1557 PyC_Err_PrintWithFunc(py_func);
1558 }
1559 else {
1560 if (ret != Py_None) {
1561 PyErr_SetString(PyExc_ValueError, "the return value must be None");
1562 PyC_Err_PrintWithFunc(py_func);
1563 }
1564
1565 Py_DECREF(ret);
1566 }
1567
1569}
1570
1572 PointerRNA *ptr, PropertyRNA *prop, float new_value, float curr_value, bool is_set)
1573{
1575
1576 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1577 PyObject *py_func;
1578 PyObject *ret;
1579
1580 BLI_assert(prop_store != nullptr);
1581
1582 py_func = prop_store->py_data.set_transform_fn;
1583
1584 {
1585 PyObject *args = PyTuple_New(4);
1586 PyObject *self = pyrna_struct_as_instance(ptr);
1587 PyTuple_SET_ITEMS(args,
1588 self,
1589 PyFloat_FromDouble(new_value),
1590 PyFloat_FromDouble(curr_value),
1591 PyBool_FromLong(is_set));
1592
1593 ret = PyObject_CallObject(py_func, args);
1594
1595 Py_DECREF(args);
1596 }
1597
1598 float ret_value = curr_value;
1599 if (ret == nullptr) {
1600 PyC_Err_PrintWithFunc(py_func);
1601 }
1602 else {
1603 ret_value = PyFloat_AsDouble(ret);
1604
1605 if (ret_value == -1.0f && PyErr_Occurred()) {
1606 PyC_Err_PrintWithFunc(py_func);
1607 ret_value = curr_value;
1608 }
1609
1610 Py_DECREF(ret);
1611 }
1612
1614
1615 return ret_value;
1616}
1617
1619 PyObject *float_array_obj,
1620 const BPyPropArrayLength &array_len_info,
1621 PyObject *py_func,
1622 const bool do_matrix_row_col_swap,
1623 float *r_values)
1624{
1625 bool is_values_set = false;
1626
1627 if (float_array_obj != nullptr) {
1629 sizeof(*r_values),
1630 float_array_obj,
1631 &array_len_info,
1632 &PyFloat_Type,
1633 "FloatVectorProperty get callback") == -1)
1634 {
1635 PyC_Err_PrintWithFunc(py_func);
1636 }
1637 else {
1638 /* Only for float types. */
1639 /* TODO: Clear and comnplete explanations about this matrix swap? */
1640 if (do_matrix_row_col_swap && bpy_prop_array_is_matrix_compatible(prop, &array_len_info)) {
1641 bpy_prop_array_matrix_swap_row_column_vn(r_values, &array_len_info);
1642 }
1643 is_values_set = true;
1644 }
1645 }
1646
1647 if (is_values_set == false) {
1648 /* This is the flattened length for multi-dimensional arrays. */
1649 for (int i = 0; i < array_len_info.len_total; i++) {
1650 r_values[i] = 0.0f;
1651 }
1652 }
1653
1654 Py_XDECREF(float_array_obj);
1655}
1656
1657static void bpy_prop_float_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, float *values)
1658{
1660
1661 const BPyPropArrayLength array_len_info{ptr, prop};
1662 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1663 PyObject *py_func;
1664 PyObject *ret;
1665
1666 BLI_assert(prop_store != nullptr);
1667
1668 py_func = prop_store->py_data.get_fn;
1669
1670 {
1671 PyObject *args = PyTuple_New(1);
1672 PyObject *self = pyrna_struct_as_instance(ptr);
1673 PyTuple_SET_ITEMS(args, self);
1674
1675 ret = PyObject_CallObject(py_func, args);
1676
1677 Py_DECREF(args);
1678 }
1679
1680 /* Custom getter always needs to perform the matrix row/col swap. */
1681 bpy_prop_float_array_from_callback_or_error(prop, ret, array_len_info, py_func, true, values);
1682
1684}
1685
1687 PointerRNA *ptr, PropertyRNA *prop, const float *curr_values, bool is_set, float *r_values)
1688{
1690
1691 const BPyPropArrayLength array_len_info{ptr, prop};
1692 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1693 PyObject *py_func;
1694 PyObject *ret;
1695
1696 BLI_assert(prop_store != nullptr);
1697
1698 py_func = prop_store->py_data.get_transform_fn;
1699
1700 {
1701 PyObject *args = PyTuple_New(3);
1702 PyObject *self = pyrna_struct_as_instance(ptr);
1704 args,
1705 self,
1706 bpy_py_object_from_prop_array_with_dims(curr_values, array_len_info, PyFloat_Type),
1707 PyBool_FromLong(is_set));
1708
1709 ret = PyObject_CallObject(py_func, args);
1710
1711 Py_DECREF(args);
1712 }
1713
1714 /* If there is a custom py-defined 'get' callback, the row/col matrix swap has already been
1715 * performed, otherwise it needs to be done here. */
1716 const bool do_matrix_row_col_swap = prop_store->py_data.get_fn == nullptr;
1718 prop, ret, array_len_info, py_func, do_matrix_row_col_swap, r_values);
1719
1721}
1722
1723static void bpy_prop_float_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const float *values)
1724{
1726
1727 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1728 PyObject *py_func;
1729 PyObject *ret;
1730
1731 const BPyPropArrayLength array_len_info{ptr, prop};
1732
1733 BLI_assert(prop_store != nullptr);
1734
1735 py_func = prop_store->py_data.set_fn;
1736
1737 {
1738 PyObject *args = PyTuple_New(2);
1739 PyObject *self = pyrna_struct_as_instance(ptr);
1741 args, self, bpy_py_object_from_prop_array_with_dims(values, array_len_info, PyFloat_Type));
1742
1743 ret = PyObject_CallObject(py_func, args);
1744
1745 Py_DECREF(args);
1746 }
1747
1748 if (ret == nullptr) {
1749 PyC_Err_PrintWithFunc(py_func);
1750 }
1751 else {
1752 if (ret != Py_None) {
1753 PyErr_SetString(PyExc_ValueError, "the return value must be None");
1754 PyC_Err_PrintWithFunc(py_func);
1755 }
1756
1757 Py_DECREF(ret);
1758 }
1759
1761}
1762
1764 PropertyRNA *prop,
1765 const float *new_values,
1766 const float *curr_values,
1767 bool is_set,
1768 float *r_final_values)
1769{
1771
1772 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1773 PyObject *py_func;
1774 PyObject *ret;
1775
1776 const BPyPropArrayLength array_len_info{ptr, prop};
1777
1778 BLI_assert(prop_store != nullptr);
1779
1780 py_func = prop_store->py_data.set_transform_fn;
1781
1782 {
1783 PyObject *args = PyTuple_New(4);
1784 PyObject *self = pyrna_struct_as_instance(ptr);
1786 args,
1787 self,
1788 bpy_py_object_from_prop_array_with_dims(new_values, array_len_info, PyFloat_Type),
1789 bpy_py_object_from_prop_array_with_dims(curr_values, array_len_info, PyFloat_Type),
1790 PyBool_FromLong(is_set));
1791
1792 ret = PyObject_CallObject(py_func, args);
1793
1794 Py_DECREF(args);
1795 }
1796
1797 /* No need for matrix column/row swapping here unless the matrix data is read directly. */
1799 prop, ret, array_len_info, py_func, false, r_final_values);
1800
1802}
1803
1805
1806/* -------------------------------------------------------------------- */
1809
1810static std::optional<std::string> bpy_prop_string_from_callback_or_error(PyObject *str_obj,
1811 const size_t max_length,
1812 PyObject *py_func)
1813{
1814 std::optional<std::string> ret_value{};
1815
1816 /* TODO: handle bytes strings. */
1817 if (str_obj == nullptr) {
1818 PyC_Err_PrintWithFunc(py_func);
1819 }
1820 else if (!PyUnicode_Check(str_obj)) {
1821 PyErr_Format(
1822 PyExc_TypeError, "return value must be a string, not %.200s", Py_TYPE(str_obj)->tp_name);
1823 PyC_Err_PrintWithFunc(py_func);
1824 }
1825 else {
1826 /* NOTE: Python returns the length _without_ the `\0` terminator. */
1827 Py_ssize_t length;
1828 const char *ret_cstr = PyUnicode_AsUTF8AndSize(str_obj, &length);
1829 if (max_length && size_t(length) + 1 > max_length) {
1830 PyErr_Format(PyExc_ValueError,
1831 "return string must be of max length %zu, not %d",
1832 max_length - 1,
1833 length);
1834 PyC_Err_PrintWithFunc(py_func);
1835 }
1836 else {
1837 ret_value = {ret_cstr, size_t(length)};
1838 }
1839 }
1840
1841 Py_XDECREF(str_obj);
1842 return ret_value;
1843}
1844
1846{
1847 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1848 PyObject *py_func;
1849 PyObject *ret;
1850
1851 BLI_assert(prop_store != nullptr);
1852
1853 py_func = prop_store->py_data.get_fn;
1854
1855 {
1856 PyObject *args = PyTuple_New(1);
1857 PyObject *self = pyrna_struct_as_instance(ptr);
1858 PyTuple_SET_ITEMS(args, self);
1859
1860 ret = PyObject_CallObject(py_func, args);
1861
1862 Py_DECREF(args);
1863 }
1864
1866 .value_or("");
1867}
1868
1870{
1872
1873 std::string ret_value = bpy_prop_string_get_locked_fn(ptr, prop);
1874
1876
1877 return ret_value;
1878}
1879
1881 PropertyRNA *prop,
1882 const std::string &curr_value,
1883 bool is_set)
1884{
1885 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1886 PyObject *py_func;
1887 PyObject *ret;
1888
1889 BLI_assert(prop_store != nullptr);
1890
1891 /* TODO: handle bytes strings. */
1892 py_func = prop_store->py_data.get_transform_fn;
1893
1894 {
1895 PyObject *args = PyTuple_New(3);
1896 PyObject *self = pyrna_struct_as_instance(ptr);
1898 args,
1899 self,
1900 PyUnicode_FromStringAndSize(curr_value.c_str(), Py_ssize_t(curr_value.size())),
1901 PyBool_FromLong(is_set));
1902
1903 ret = PyObject_CallObject(py_func, args);
1904
1905 Py_DECREF(args);
1906 }
1907
1909 .value_or(curr_value);
1910}
1911
1913 PropertyRNA *prop,
1914 const std::string &curr_value,
1915 bool is_set)
1916{
1918
1919 std::string ret_value = bpy_prop_string_get_transform_locked_fn(ptr, prop, curr_value, is_set);
1920
1922
1923 return ret_value;
1924}
1925
1927{
1929
1930 /* This bpyprops-specific length callback is only called when there is a custom `get` function.
1931 */
1932 std::string ret = bpy_prop_string_get_locked_fn(ptr, prop);
1933 const int length = int(ret.size());
1934
1936
1937 return length;
1938}
1939
1940static void bpy_prop_string_set_fn(PointerRNA *ptr, PropertyRNA *prop, const std::string &value)
1941{
1943
1944 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
1945 PyObject *py_func;
1946 PyObject *ret;
1947
1948 BLI_assert(prop_store != nullptr);
1949
1950 py_func = prop_store->py_data.set_fn;
1951
1952 {
1953 PyObject *args = PyTuple_New(2);
1954 PyObject *self = pyrna_struct_as_instance(ptr);
1955
1956 /* TODO: handle bytes strings. */
1957 const size_t max_length = RNA_property_string_maxlength(prop);
1958 if (max_length && value.size() >= max_length) {
1959 PyErr_Format(PyExc_ValueError,
1960 "the given string must be of max length %zu, not %zu",
1961 max_length - 1,
1962 value.size());
1963 PyC_Err_PrintWithFunc(py_func);
1964 }
1965 PyObject *py_value = PyUnicode_FromStringAndSize(value.c_str(), value.size());
1966 if (!py_value) {
1967 PyErr_SetString(PyExc_ValueError,
1968 "the given string value cannot be converted into a python string");
1969 PyC_Err_PrintWithFunc(py_func);
1970 py_value = Py_None;
1971 Py_INCREF(py_value);
1972 }
1973 PyTuple_SET_ITEMS(args, self, py_value);
1974
1975 ret = PyObject_CallObject(py_func, args);
1976
1977 Py_DECREF(args);
1978 }
1979
1980 if (ret == nullptr) {
1981 PyC_Err_PrintWithFunc(py_func);
1982 }
1983 else {
1984 if (ret != Py_None) {
1985 PyErr_SetString(PyExc_ValueError, "the return value must be None");
1986 PyC_Err_PrintWithFunc(py_func);
1987 }
1988
1989 Py_DECREF(ret);
1990 }
1991
1993}
1994
1996 PropertyRNA *prop,
1997 const std::string &new_value,
1998 const std::string &curr_value,
1999 bool is_set)
2000{
2002
2003 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
2004 PyObject *py_func;
2005 PyObject *ret;
2006
2007 BLI_assert(prop_store != nullptr);
2008
2009 py_func = prop_store->py_data.set_transform_fn;
2010
2011 {
2012 PyObject *args = PyTuple_New(4);
2013 PyObject *self = pyrna_struct_as_instance(ptr);
2015 args,
2016 self,
2017 PyUnicode_FromStringAndSize(new_value.c_str(), Py_ssize_t(new_value.size())),
2018 PyUnicode_FromStringAndSize(curr_value.c_str(), Py_ssize_t(curr_value.size())),
2019 PyBool_FromLong(is_set));
2020
2021 ret = PyObject_CallObject(py_func, args);
2022
2023 Py_DECREF(args);
2024 }
2025
2026 std::string ret_value = bpy_prop_string_from_callback_or_error(
2027 ret, RNA_property_string_maxlength(prop), py_func)
2028 .value_or(curr_value);
2029
2031
2032 return ret_value;
2033}
2034
2036 PyObject *py_func,
2037 PyObject *item,
2039{
2040 const char *text;
2041 const char *info = nullptr;
2042
2043 if (PyTuple_CheckExact(item)) {
2044 /* Positional only. */
2045 static const char *_keywords[] = {
2046 "",
2047 "",
2048 nullptr,
2049 };
2050 static _PyArg_Parser _parser = {
2052 "s" /* `text` */
2053 "s" /* `info` */
2054 ":search",
2055 _keywords,
2056 nullptr,
2057 };
2058 if (!_PyArg_ParseTupleAndKeywordsFast(item, nullptr, &_parser, &text, &info)) {
2059 PyC_Err_PrintWithFunc(py_func);
2060 return false;
2061 }
2062 }
2063 else {
2064 text = PyUnicode_AsUTF8(item);
2065 if (UNLIKELY(text == nullptr)) {
2066 PyErr_Clear();
2067 PyErr_Format(PyExc_TypeError,
2068 "expected sequence of strings or tuple pairs of strings, not %.200s",
2069 Py_TYPE(item)->tp_name);
2070 PyC_Err_PrintWithFunc(py_func);
2071 return false;
2072 }
2073 }
2074
2075 StringPropertySearchVisitParams visit_params{};
2076 visit_params.text = text;
2077 visit_params.info = info ? info : "";
2078 visit_fn(visit_params);
2079 return true;
2080}
2081
2083 const bContext *C,
2084 PointerRNA *ptr,
2085 PropertyRNA *prop,
2086 const char *edit_text,
2088{
2089 PyGILState_STATE gilstate;
2090 if (C) {
2091 bpy_context_set((bContext *)C, &gilstate);
2092 }
2093 else {
2094 gilstate = PyGILState_Ensure();
2095 }
2096
2097 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
2098 PyObject *py_func;
2099 PyObject *ret;
2100
2101 BLI_assert(prop_store != nullptr);
2102
2103 py_func = prop_store->py_data.string_data.search_fn;
2104
2105 {
2106 PyObject *args = PyTuple_New(3);
2107 PyObject *self = pyrna_struct_as_instance(ptr);
2108 PyObject *py_context = reinterpret_cast<PyObject *>(bpy_context_module);
2109 PyObject *py_edit_text = PyUnicode_FromString(edit_text);
2110 Py_INCREF(py_context);
2111 PyTuple_SET_ITEMS(args, self, py_context, py_edit_text);
2112
2113 ret = PyObject_CallObject(py_func, args);
2114
2115 Py_DECREF(args);
2116 }
2117
2118 if (ret == nullptr) {
2119 PyC_Err_PrintWithFunc(py_func);
2120 }
2121 else {
2122 if (PyIter_Check(ret)) {
2123 /* Iterators / generator types. */
2124 PyObject *it;
2125 PyObject *(*iternext)(PyObject *);
2126 it = PyObject_GetIter(ret);
2127 if (it == nullptr) {
2128 PyC_Err_PrintWithFunc(py_func);
2129 }
2130 else {
2131 iternext = *Py_TYPE(it)->tp_iternext;
2132 for (;;) {
2133 PyObject *py_text = iternext(it);
2134 if (py_text == nullptr) {
2135 break;
2136 }
2137 const bool ok = bpy_prop_string_visit_fn_call(py_func, py_text, visit_fn);
2138 Py_DECREF(py_text);
2139 if (!ok) {
2140 break;
2141 }
2142 }
2143 Py_DECREF(it);
2144 if (PyErr_Occurred()) {
2145 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
2146 PyErr_Clear();
2147 }
2148 else {
2149 PyC_Err_PrintWithFunc(py_func);
2150 }
2151 }
2152 }
2153 }
2154 else {
2155 /* Sequence (typically list/tuple). */
2156 PyObject *ret_fast = PySequence_Fast(
2157 ret,
2158 "StringProperty(...): "
2159 "return value from search callback was not a sequence, iterator or generator");
2160 if (ret_fast == nullptr) {
2161 PyC_Err_PrintWithFunc(py_func);
2162 }
2163 else {
2164 const Py_ssize_t ret_num = PySequence_Fast_GET_SIZE(ret_fast);
2165 PyObject **ret_fast_items = PySequence_Fast_ITEMS(ret_fast);
2166 for (Py_ssize_t i = 0; i < ret_num; i++) {
2167 const bool ok = bpy_prop_string_visit_fn_call(py_func, ret_fast_items[i], visit_fn);
2168 if (!ok) {
2169 break;
2170 }
2171 }
2172 Py_DECREF(ret_fast);
2173 }
2174 }
2175
2176 Py_DECREF(ret);
2177 }
2178
2179 if (C) {
2180 bpy_context_clear((bContext *)C, &gilstate);
2181 }
2182 else {
2183 PyGILState_Release(gilstate);
2184 }
2185}
2186
2188
2189/* -------------------------------------------------------------------- */
2192
2194{
2196
2197 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
2198 PyObject *py_func;
2199 PyObject *ret;
2200 bool result;
2201
2202 BLI_assert(self != nullptr);
2203
2204 py_func = prop_store->py_data.pointer_data.poll_fn;
2205
2206 {
2207 PyObject *args = PyTuple_New(2);
2208 PyObject *py_self = pyrna_struct_as_instance(self);
2209 PyObject *py_candidate = pyrna_struct_as_instance(&candidate);
2210 PyTuple_SET_ITEMS(args, py_self, py_candidate);
2211
2212 ret = PyObject_CallObject(py_func, args);
2213
2214 Py_DECREF(args);
2215 }
2216
2217 if (ret == nullptr) {
2218 PyC_Err_PrintWithFunc(py_func);
2219 result = false;
2220 }
2221 else {
2222 result = PyObject_IsTrue(ret);
2223 Py_DECREF(ret);
2224 }
2225
2227
2228 return result;
2229}
2230
2232
2233/* -------------------------------------------------------------------- */
2236
2238{
2240
2241 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
2242 PyObject *py_func;
2243 PyObject *ret;
2244 int value;
2245
2246 BLI_assert(prop_store != nullptr);
2247
2248 py_func = prop_store->py_data.get_fn;
2249
2250 {
2251 PyObject *args = PyTuple_New(1);
2252 PyObject *self = pyrna_struct_as_instance(ptr);
2253 PyTuple_SET_ITEMS(args, self);
2254
2255 ret = PyObject_CallObject(py_func, args);
2256
2257 Py_DECREF(args);
2258 }
2259
2260 if (ret == nullptr) {
2261 PyC_Err_PrintWithFunc(py_func);
2262 value = RNA_property_enum_get_default(ptr, prop);
2263 }
2264 else {
2265 value = PyC_Long_AsI32(ret);
2266
2267 if (value == -1 && PyErr_Occurred()) {
2268 PyC_Err_PrintWithFunc(py_func);
2269 value = RNA_property_enum_get_default(ptr, prop);
2270 }
2271
2272 Py_DECREF(ret);
2273 }
2274
2276
2277 return value;
2278}
2279
2281 PropertyRNA *prop,
2282 int curr_value,
2283 bool is_set)
2284{
2286
2287 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
2288 PyObject *py_func;
2289 PyObject *ret;
2290
2291 BLI_assert(prop_store != nullptr);
2292
2293 py_func = prop_store->py_data.get_transform_fn;
2294
2295 {
2296 PyObject *args = PyTuple_New(3);
2297 PyObject *self = pyrna_struct_as_instance(ptr);
2298 PyTuple_SET_ITEMS(args, self, PyLong_FromLong(curr_value), PyBool_FromLong(is_set));
2299
2300 ret = PyObject_CallObject(py_func, args);
2301
2302 Py_DECREF(args);
2303 }
2304
2305 int ret_value = curr_value;
2306 if (ret == nullptr) {
2307 PyC_Err_PrintWithFunc(py_func);
2308 }
2309 else {
2310 ret_value = PyC_Long_AsI32(ret);
2311
2312 if (ret_value == -1 && PyErr_Occurred()) {
2313 PyC_Err_PrintWithFunc(py_func);
2314 ret_value = curr_value;
2315 }
2316
2317 Py_DECREF(ret);
2318 }
2319
2321
2322 return ret_value;
2323}
2324
2325static void bpy_prop_enum_set_fn(PointerRNA *ptr, PropertyRNA *prop, int value)
2326{
2328
2329 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
2330 PyObject *py_func;
2331 PyObject *ret;
2332
2333 BLI_assert(prop_store != nullptr);
2334
2335 py_func = prop_store->py_data.set_fn;
2336
2337 {
2338 PyObject *args = PyTuple_New(2);
2339 PyObject *self = pyrna_struct_as_instance(ptr);
2340 PyTuple_SET_ITEMS(args, self, PyLong_FromLong(value));
2341
2342 ret = PyObject_CallObject(py_func, args);
2343
2344 Py_DECREF(args);
2345 }
2346
2347 if (ret == nullptr) {
2348 PyC_Err_PrintWithFunc(py_func);
2349 }
2350 else {
2351 if (ret != Py_None) {
2352 PyErr_SetString(PyExc_ValueError, "the return value must be None");
2353 PyC_Err_PrintWithFunc(py_func);
2354 }
2355
2356 Py_DECREF(ret);
2357 }
2358
2360}
2361
2363 PointerRNA *ptr, PropertyRNA *prop, int new_value, int curr_value, bool is_set)
2364{
2366
2367 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
2368 PyObject *py_func;
2369 PyObject *ret;
2370
2371 BLI_assert(prop_store != nullptr);
2372
2373 py_func = prop_store->py_data.set_transform_fn;
2374
2375 {
2376 PyObject *args = PyTuple_New(4);
2377 PyObject *self = pyrna_struct_as_instance(ptr);
2378 PyTuple_SET_ITEMS(args,
2379 self,
2380 PyLong_FromLong(new_value),
2381 PyLong_FromLong(curr_value),
2382 PyBool_FromLong(is_set));
2383
2384 ret = PyObject_CallObject(py_func, args);
2385
2386 Py_DECREF(args);
2387 }
2388
2389 int ret_value = curr_value;
2390 if (ret == nullptr) {
2391 PyC_Err_PrintWithFunc(py_func);
2392 }
2393 else {
2394 ret_value = PyC_Long_AsI32(ret);
2395
2396 if (ret_value == -1 && PyErr_Occurred()) {
2397 PyC_Err_PrintWithFunc(py_func);
2398 ret_value = curr_value;
2399 }
2400
2401 Py_DECREF(ret);
2402 }
2403
2405
2406 return ret_value;
2407}
2408
2409/* utility function we need for parsing int's in an if statement */
2410static bool py_long_as_int(PyObject *py_long, int *r_int)
2411{
2412 if (PyLong_CheckExact(py_long)) {
2413 *r_int = int(PyLong_AS_LONG(py_long));
2414 return true;
2415 }
2416
2417 return false;
2418}
2419
2420#ifdef USE_ENUM_COPY_STRINGS
2421/* copies orig to buf, then sets orig to buf, returns copy length */
2422static size_t strswapbufcpy(char *buf, const char **orig)
2423{
2424 const char *src = *orig;
2425 char *dst = buf;
2426 size_t i = 0;
2427 *orig = buf;
2428 while ((*dst = *src)) {
2429 dst++;
2430 src++;
2431 i++;
2432 }
2433 return i + 1; /* include '\0' */
2434}
2435#endif
2436
2437static int icon_id_from_name(const char *name)
2438{
2439 const EnumPropertyItem *item;
2440 int id;
2441
2442 if (name[0]) {
2443 for (item = rna_enum_icon_items, id = 0; item->identifier; item++, id++) {
2444 if (STREQ(item->name, name)) {
2445 return item->value;
2446 }
2447 }
2448 }
2449
2450 return 0;
2451}
2452
2453static const EnumPropertyItem *enum_items_from_py(PyObject *seq_fast,
2454 const bool is_enum_flag,
2455 PyObject *default_py,
2456 int *r_default_value)
2457{
2458 EnumPropertyItem *items;
2459 PyObject *item;
2460 const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
2461 PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
2462 int i;
2463#ifdef USE_ENUM_COPY_STRINGS
2464 Py_ssize_t totbuf = 0;
2465#endif
2466 short default_used = 0;
2467 const char *default_str_cmp = nullptr;
2468 int default_int_cmp = 0;
2469
2470 if (is_enum_flag) {
2471 if (seq_len > RNA_ENUM_BITFLAG_SIZE) {
2472 PyErr_SetString(PyExc_TypeError,
2473 "EnumProperty(...): maximum " STRINGIFY(
2474 RNA_ENUM_BITFLAG_SIZE) " members for a ENUM_FLAG type property");
2475 return nullptr;
2476 }
2477 if (default_py && !PySet_Check(default_py)) {
2478 PyErr_Format(PyExc_TypeError,
2479 "EnumProperty(...): default option must be a 'set' "
2480 "type when ENUM_FLAG is enabled, not a '%.200s'",
2481 Py_TYPE(default_py)->tp_name);
2482 return nullptr;
2483 }
2484 }
2485 else {
2486 if (default_py) {
2487 if (!py_long_as_int(default_py, &default_int_cmp)) {
2488 default_str_cmp = PyUnicode_AsUTF8(default_py);
2489 if (default_str_cmp == nullptr) {
2490 PyErr_Format(PyExc_TypeError,
2491 "EnumProperty(...): default option must be a 'str' or 'int' "
2492 "type when ENUM_FLAG is disabled, not a '%.200s'",
2493 Py_TYPE(default_py)->tp_name);
2494 return nullptr;
2495 }
2496 }
2497 }
2498 }
2499
2500 /* blank value */
2501 *r_default_value = 0;
2502
2503 items = MEM_calloc_arrayN<EnumPropertyItem>(size_t(seq_len) + 1, "enum_items_from_py1");
2504
2505 for (i = 0; i < seq_len; i++) {
2506 EnumPropertyItem tmp = {0, "", 0, "", ""};
2507 const char *tmp_icon = nullptr;
2508 Py_ssize_t item_size;
2509 Py_ssize_t id_str_len;
2510 Py_ssize_t name_str_len;
2511 Py_ssize_t desc_str_len;
2512
2513 item = seq_fast_items[i];
2514
2515 if (PyTuple_CheckExact(item) && (item_size = PyTuple_GET_SIZE(item)) &&
2516 (item_size >= 3 && item_size <= 5) &&
2517 (tmp.identifier = PyUnicode_AsUTF8AndSize(PyTuple_GET_ITEM(item, 0), &id_str_len)) &&
2518 (tmp.name = PyUnicode_AsUTF8AndSize(PyTuple_GET_ITEM(item, 1), &name_str_len)) &&
2519 (tmp.description = PyUnicode_AsUTF8AndSize(PyTuple_GET_ITEM(item, 2), &desc_str_len)) &&
2520 /* TODO: number isn't ensured to be unique from the script author. */
2521 (item_size != 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value)) &&
2522 (item_size != 5 || ((py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.icon) ||
2523 (tmp_icon = PyUnicode_AsUTF8(PyTuple_GET_ITEM(item, 3)))) &&
2524 py_long_as_int(PyTuple_GET_ITEM(item, 4), &tmp.value))))
2525 {
2526 if (is_enum_flag) {
2527 if (item_size < 4) {
2528 tmp.value = 1 << i;
2529 }
2530
2531 if (default_py && PySet_Contains(default_py, PyTuple_GET_ITEM(item, 0))) {
2532 *r_default_value |= tmp.value;
2533 default_used++;
2534 }
2535 }
2536 else {
2537 if (item_size < 4) {
2538 tmp.value = i;
2539 }
2540
2541 if (default_py && default_used == 0) {
2542 if ((default_str_cmp != nullptr && STREQ(default_str_cmp, tmp.identifier)) ||
2543 (default_str_cmp == nullptr && default_int_cmp == tmp.value))
2544 {
2545 *r_default_value = tmp.value;
2546 default_used++; /* only ever 1 */
2547 }
2548 }
2549 }
2550
2551 if (tmp_icon) {
2552 tmp.icon = icon_id_from_name(tmp_icon);
2553 }
2554
2555 items[i] = tmp;
2556
2557#ifdef USE_ENUM_COPY_STRINGS
2558 /* Calculate combine string length. */
2559 totbuf += id_str_len + name_str_len + desc_str_len + 3; /* 3 is for '\0's */
2560#endif
2561 }
2562 else if (item == Py_None) {
2563 /* Only set since the rest is cleared. */
2564 items[i].identifier = "";
2565 }
2566 else {
2567 MEM_freeN(items);
2568 PyErr_SetString(PyExc_TypeError,
2569 "EnumProperty(...): expected a tuple containing "
2570 "(identifier, name, description) and optionally an "
2571 "icon name and unique number");
2572 return nullptr;
2573 }
2574 }
2575
2576 if (is_enum_flag) {
2577 /* strict check that all set members were used */
2578 if (default_py && default_used != PySet_GET_SIZE(default_py)) {
2579 MEM_freeN(items);
2580
2581 PyErr_Format(PyExc_TypeError,
2582 "EnumProperty(..., default={...}): set has %d unused member(s)",
2583 PySet_GET_SIZE(default_py) - default_used);
2584 return nullptr;
2585 }
2586 }
2587 else {
2588 if (default_py && default_used == 0) {
2589 MEM_freeN(items);
2590
2591 if (default_str_cmp) {
2592 PyErr_Format(PyExc_TypeError,
2593 "EnumProperty(..., default=\'%s\'): not found in enum members",
2594 default_str_cmp);
2595 }
2596 else {
2597 PyErr_Format(PyExc_TypeError,
2598 "EnumProperty(..., default=%d): not found in enum members",
2599 default_int_cmp);
2600 }
2601 return nullptr;
2602 }
2603 }
2604
2605#ifdef USE_ENUM_COPY_STRINGS
2606 /* This would all work perfectly _but_ the python strings may be freed immediately after use,
2607 * so we need to duplicate them, ugh. annoying because it works most of the time without this. */
2608 {
2609 EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) +
2610 (sizeof(char) * totbuf),
2611 "enum_items_from_py2");
2612 EnumPropertyItem *items_ptr = items_dup;
2613 char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1));
2614 memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1));
2615 for (i = 0; i < seq_len; i++, items_ptr++) {
2616 buf += strswapbufcpy(buf, &items_ptr->identifier);
2617 buf += strswapbufcpy(buf, &items_ptr->name);
2618 buf += strswapbufcpy(buf, &items_ptr->description);
2619 }
2620 MEM_freeN(items);
2621 items = items_dup;
2622 }
2623/* end string duplication */
2624#endif
2625
2626 return items;
2627}
2628
2630 PointerRNA *ptr,
2631 PropertyRNA *prop,
2632 bool *r_free)
2633{
2634 PyGILState_STATE gilstate;
2635 if (C) {
2636 bpy_context_set(C, &gilstate);
2637 }
2638 else {
2639 gilstate = PyGILState_Ensure();
2640 }
2641
2642 BPyPropStore *prop_store = static_cast<BPyPropStore *>(RNA_property_py_data_get(prop));
2643 PyObject *py_func = prop_store->py_data.enum_data.itemf_fn;
2644 PyObject *items; /* returned from the function call */
2645
2646 const EnumPropertyItem *eitems = nullptr;
2647 int err = 0;
2648
2649 {
2650 PyObject *args = PyTuple_New(2);
2651 PyObject *self = pyrna_struct_as_instance(ptr);
2652 PyObject *py_context = C ? reinterpret_cast<PyObject *>(bpy_context_module) : Py_None;
2653 Py_INCREF(py_context);
2654 PyTuple_SET_ITEMS(args, self, py_context);
2655
2656 items = PyObject_CallObject(py_func, args);
2657
2658 Py_DECREF(args);
2659 }
2660
2661 if (items == nullptr) {
2662 err = -1;
2663 }
2664 else {
2665 PyObject *items_fast;
2666 int default_value_dummy = 0;
2667
2668 if (!(items_fast = PySequence_Fast(items,
2669 "EnumProperty(...): "
2670 "return value from the callback was not a sequence")))
2671 {
2672 err = -1;
2673 }
2674 else {
2675 eitems = enum_items_from_py(items_fast,
2676 (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0,
2677 nullptr,
2678 &default_value_dummy);
2679
2680 Py_DECREF(items_fast);
2681
2682 if (!eitems) {
2683 err = -1;
2684 }
2685 }
2686
2687 Py_DECREF(items);
2688 }
2689
2690 if (err != -1) { /* worked */
2691 *r_free = true;
2692 }
2693 else {
2694 PyC_Err_PrintWithFunc(py_func);
2695
2697 }
2698
2699 if (C) {
2700 bpy_context_clear(C, &gilstate);
2701 }
2702 else {
2703 PyGILState_Release(gilstate);
2704 }
2705
2706 return eitems;
2707}
2708
2709static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int argcount)
2710{
2711 if (py_func && py_func != Py_None) {
2712 if (!PyFunction_Check(py_func)) {
2713 PyErr_Format(PyExc_TypeError,
2714 "%s keyword: expected a function type, not a %.200s",
2715 keyword,
2716 Py_TYPE(py_func)->tp_name);
2717 return -1;
2718 }
2719
2720 PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
2721 if (f_code->co_argcount != argcount) {
2722 PyErr_Format(PyExc_TypeError,
2723 "%s keyword: expected a function taking %d arguments, not %d",
2724 keyword,
2725 argcount,
2726 f_code->co_argcount);
2727 return -1;
2728 }
2729 }
2730
2731 return 0;
2732}
2733
2735
2736/* -------------------------------------------------------------------- */
2739
2740static void bpy_prop_callback_assign_update(PropertyRNA *prop, PyObject *update_fn)
2741{
2742 /* assume this is already checked for type and arg length */
2743 if (update_fn && update_fn != Py_None) {
2744 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2745
2747 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.update_fn, update_fn);
2748 }
2749}
2750
2751static void bpy_prop_callback_assign_pointer(PropertyRNA *prop, PyObject *poll_fn)
2752{
2753 if (poll_fn && poll_fn != Py_None) {
2754 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2755
2756 RNA_def_property_poll_runtime(prop, reinterpret_cast<const void *>(bpy_prop_pointer_poll_fn));
2757 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.pointer_data.poll_fn, poll_fn);
2758 }
2759}
2760
2762 PyObject *get_fn,
2763 PyObject *set_fn,
2764 PyObject *get_transform_fn,
2765 PyObject *set_transform_fn)
2766{
2767 BooleanPropertyGetFunc rna_get_fn = nullptr;
2768 BooleanPropertySetFunc rna_set_fn = nullptr;
2769 BooleanPropertyGetTransformFunc rna_get_transform_fn = nullptr;
2770 BooleanPropertySetTransformFunc rna_set_transform_fn = nullptr;
2771
2772 if (get_fn && get_fn != Py_None) {
2773 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2774
2775 rna_get_fn = bpy_prop_boolean_get_fn;
2776 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2777 }
2778
2779 if (set_fn && set_fn != Py_None) {
2780 if (!rna_get_fn) {
2781 PyErr_SetString(PyExc_ValueError,
2782 "The `set` callback is defined without a matching `get` function, this is "
2783 "not supported. `set_transform` should probably be used instead?");
2784 return false;
2785 }
2786
2787 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2788
2789 rna_set_fn = bpy_prop_boolean_set_fn;
2790 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2791 }
2792
2793 if (get_transform_fn && get_transform_fn != Py_None) {
2794 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2795
2796 rna_get_transform_fn = bpy_prop_boolean_get_transform_fn;
2797 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_transform_fn, get_transform_fn);
2798 }
2799
2800 if (set_transform_fn && set_transform_fn != Py_None) {
2801 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2802
2803 rna_set_transform_fn = bpy_prop_boolean_set_transform_fn;
2804 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_transform_fn, set_transform_fn);
2805 }
2806
2808 prop, rna_get_fn, rna_set_fn, rna_get_transform_fn, rna_set_transform_fn);
2809
2810 return true;
2811}
2812
2814 PyObject *get_fn,
2815 PyObject *set_fn,
2816 PyObject *get_transform_fn,
2817 PyObject *set_transform_fn)
2818{
2819 BooleanArrayPropertyGetFunc rna_get_fn = nullptr;
2820 BooleanArrayPropertySetFunc rna_set_fn = nullptr;
2821 BooleanArrayPropertyGetTransformFunc rna_get_transform_fn = nullptr;
2822 BooleanArrayPropertySetTransformFunc rna_set_transform_fn = nullptr;
2823
2824 if (get_fn && get_fn != Py_None) {
2825 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2826
2827 rna_get_fn = bpy_prop_boolean_array_get_fn;
2828 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2829 }
2830
2831 if (set_fn && set_fn != Py_None) {
2832 if (!rna_get_fn) {
2833 PyErr_SetString(PyExc_ValueError,
2834 "The `set` callback is defined without a matching `get` function, this is "
2835 "not supported. `set_transform` should probably be used instead?");
2836 return false;
2837 }
2838
2839 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2840
2841 rna_set_fn = bpy_prop_boolean_array_set_fn;
2842 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2843 }
2844
2845 if (get_transform_fn && get_transform_fn != Py_None) {
2846 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2847
2848 rna_get_transform_fn = bpy_prop_boolean_array_get_transform_fn;
2849 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_transform_fn, get_transform_fn);
2850 }
2851
2852 if (set_transform_fn && set_transform_fn != Py_None) {
2853 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2854
2855 rna_set_transform_fn = bpy_prop_boolean_array_set_transform_fn;
2856 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_transform_fn, set_transform_fn);
2857 }
2858
2860 prop, rna_get_fn, rna_set_fn, rna_get_transform_fn, rna_set_transform_fn);
2861
2862 return true;
2863}
2864
2866 PyObject *get_fn,
2867 PyObject *set_fn,
2868 PyObject *get_transform_fn,
2869 PyObject *set_transform_fn)
2870{
2871 IntPropertyGetFunc rna_get_fn = nullptr;
2872 IntPropertySetFunc rna_set_fn = nullptr;
2873 IntPropertyGetTransformFunc rna_get_transform_fn = nullptr;
2874 IntPropertySetTransformFunc rna_set_transform_fn = nullptr;
2875
2876 if (get_fn && get_fn != Py_None) {
2877 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2878
2879 rna_get_fn = bpy_prop_int_get_fn;
2880 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2881 }
2882
2883 if (set_fn && set_fn != Py_None) {
2884 if (!rna_get_fn) {
2885 PyErr_SetString(PyExc_ValueError,
2886 "The `set` callback is defined without a matching `get` function, this is "
2887 "not supported. `set_transform` should probably be used instead?");
2888 return false;
2889 }
2890
2891 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2892
2893 rna_set_fn = bpy_prop_int_set_fn;
2894 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2895 }
2896
2897 if (get_transform_fn && get_transform_fn != Py_None) {
2898 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2899
2900 rna_get_transform_fn = bpy_prop_int_get_transform_fn;
2901 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_transform_fn, get_transform_fn);
2902 }
2903
2904 if (set_transform_fn && set_transform_fn != Py_None) {
2905 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2906
2907 rna_set_transform_fn = bpy_prop_int_set_transform_fn;
2908 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_transform_fn, set_transform_fn);
2909 }
2910
2912 prop, rna_get_fn, rna_set_fn, nullptr, rna_get_transform_fn, rna_set_transform_fn);
2913
2914 return true;
2915}
2916
2918 PyObject *get_fn,
2919 PyObject *set_fn,
2920 PyObject *get_transform_fn,
2921 PyObject *set_transform_fn)
2922{
2923 IntArrayPropertyGetFunc rna_get_fn = nullptr;
2924 IntArrayPropertySetFunc rna_set_fn = nullptr;
2925 IntArrayPropertyGetTransformFunc rna_get_transform_fn = nullptr;
2926 IntArrayPropertySetTransformFunc rna_set_transform_fn = nullptr;
2927
2928 if (get_fn && get_fn != Py_None) {
2929 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2930
2931 rna_get_fn = bpy_prop_int_array_get_fn;
2932 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2933 }
2934
2935 if (set_fn && set_fn != Py_None) {
2936 if (!rna_get_fn) {
2937 PyErr_SetString(PyExc_ValueError,
2938 "The `set` callback is defined without a matching `get` function, this is "
2939 "not supported. `set_transform` should probably be used instead?");
2940 }
2941
2942 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2943
2944 rna_set_fn = bpy_prop_int_array_set_fn;
2945 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2946 }
2947
2948 if (get_transform_fn && get_transform_fn != Py_None) {
2949 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2950
2951 rna_get_transform_fn = bpy_prop_int_array_get_transform_fn;
2952 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_transform_fn, get_transform_fn);
2953 }
2954
2955 if (set_transform_fn && set_transform_fn != Py_None) {
2956 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2957
2958 rna_set_transform_fn = bpy_prop_int_array_set_transform_fn;
2959 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_transform_fn, set_transform_fn);
2960 }
2961
2963 prop, rna_get_fn, rna_set_fn, nullptr, rna_get_transform_fn, rna_set_transform_fn);
2964}
2965
2967 PyObject *get_fn,
2968 PyObject *set_fn,
2969 PyObject *get_transform_fn,
2970 PyObject *set_transform_fn)
2971{
2972 FloatPropertyGetFunc rna_get_fn = nullptr;
2973 FloatPropertySetFunc rna_set_fn = nullptr;
2974 FloatPropertyGetTransformFunc rna_get_transform_fn = nullptr;
2975 FloatPropertySetTransformFunc rna_set_transform_fn = nullptr;
2976
2977 if (get_fn && get_fn != Py_None) {
2978 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2979
2980 rna_get_fn = bpy_prop_float_get_fn;
2981 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
2982 }
2983
2984 if (set_fn && set_fn != Py_None) {
2985 if (!rna_get_fn) {
2986 PyErr_SetString(PyExc_ValueError,
2987 "The `set` callback is defined without a matching `get` function, this is "
2988 "not supported. `set_transform` should probably be used instead?");
2989 return false;
2990 }
2991
2992 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
2993
2994 rna_set_fn = bpy_prop_float_set_fn;
2995 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
2996 }
2997
2998 if (get_transform_fn && get_transform_fn != Py_None) {
2999 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3000
3001 rna_get_transform_fn = bpy_prop_float_get_transform_fn;
3002 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_transform_fn, get_transform_fn);
3003 }
3004
3005 if (set_transform_fn && set_transform_fn != Py_None) {
3006 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3007
3008 rna_set_transform_fn = bpy_prop_float_set_transform_fn;
3009 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_transform_fn, set_transform_fn);
3010 }
3011
3013 prop, rna_get_fn, rna_set_fn, nullptr, rna_get_transform_fn, rna_set_transform_fn);
3014
3015 return true;
3016}
3017
3019 PyObject *get_fn,
3020 PyObject *set_fn,
3021 PyObject *get_transform_fn,
3022 PyObject *set_transform_fn)
3023{
3024 FloatArrayPropertyGetFunc rna_get_fn = nullptr;
3025 FloatArrayPropertySetFunc rna_set_fn = nullptr;
3026 FloatArrayPropertyGetTransformFunc rna_get_transform_fn = nullptr;
3027 FloatArrayPropertySetTransformFunc rna_set_transform_fn = nullptr;
3028
3029 if (get_fn && get_fn != Py_None) {
3030 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3031
3032 rna_get_fn = bpy_prop_float_array_get_fn;
3033 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
3034 }
3035
3036 if (set_fn && set_fn != Py_None) {
3037 if (!rna_get_fn) {
3038 PyErr_SetString(PyExc_ValueError,
3039 "The `set` callback is defined without a matching `get` function, this is "
3040 "not supported. `set_transform` should probably be used instead?");
3041 }
3042
3043 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3044
3045 rna_set_fn = bpy_prop_float_array_set_fn;
3046 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
3047 }
3048
3049 if (get_transform_fn && get_transform_fn != Py_None) {
3050 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3051
3052 rna_get_transform_fn = bpy_prop_float_array_get_transform_fn;
3053 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_transform_fn, get_transform_fn);
3054 }
3055
3056 if (set_transform_fn && set_transform_fn != Py_None) {
3057 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3058
3059 rna_set_transform_fn = bpy_prop_float_array_set_transform_fn;
3060 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_transform_fn, set_transform_fn);
3061 }
3062
3064 prop, rna_get_fn, rna_set_fn, nullptr, rna_get_transform_fn, rna_set_transform_fn);
3065}
3066
3068 PyObject *get_fn,
3069 PyObject *set_fn,
3070 PyObject *get_transform_fn,
3071 PyObject *set_transform_fn,
3072 PyObject *search_fn,
3073 const eStringPropertySearchFlag search_flag)
3074{
3075 StringPropertyGetFunc rna_get_fn = nullptr;
3076 StringPropertyLengthFunc rna_length_fn = nullptr;
3077 StringPropertySetFunc rna_set_fn = nullptr;
3078 StringPropertySearchFunc rna_search_fn = nullptr;
3079 StringPropertyGetTransformFunc rna_get_transform_fn = nullptr;
3080 StringPropertySetTransformFunc rna_set_transform_fn = nullptr;
3081
3082 if (get_fn && get_fn != Py_None) {
3083 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3084
3085 rna_get_fn = bpy_prop_string_get_fn;
3086 rna_length_fn = bpy_prop_string_length_fn;
3087 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
3088 }
3089
3090 if (set_fn && set_fn != Py_None) {
3091 if (!rna_get_fn) {
3092 PyErr_SetString(PyExc_ValueError,
3093 "The `set` callback is defined without a matching `get` function, this is "
3094 "not supported. `set_transform` should probably be used instead?");
3095 return false;
3096 }
3097
3098 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3099
3100 rna_set_fn = bpy_prop_string_set_fn;
3101 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
3102 }
3103
3104 if (get_transform_fn && get_transform_fn != Py_None) {
3105 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3106
3107 rna_get_transform_fn = bpy_prop_string_get_transform_fn;
3108 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_transform_fn, get_transform_fn);
3109 }
3110
3111 if (set_transform_fn && set_transform_fn != Py_None) {
3112 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3113
3114 rna_set_transform_fn = bpy_prop_string_set_transform_fn;
3115 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_transform_fn, set_transform_fn);
3116 }
3117
3118 if (search_fn) {
3119 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3120
3122 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.string_data.search_fn, search_fn);
3123 }
3124
3126 prop, rna_get_fn, rna_length_fn, rna_set_fn, rna_get_transform_fn, rna_set_transform_fn);
3127 if (rna_search_fn) {
3128 RNA_def_property_string_search_func_runtime(prop, rna_search_fn, search_flag);
3129 }
3130
3131 return true;
3132}
3133
3135 PyObject *get_fn,
3136 PyObject *set_fn,
3137 PyObject *itemf_fn,
3138 PyObject *get_transform_fn,
3139 PyObject *set_transform_fn)
3140{
3141 EnumPropertyGetFunc rna_get_fn = nullptr;
3142 EnumPropertySetFunc rna_set_fn = nullptr;
3143 EnumPropertyGetTransformFunc rna_get_transform_fn = nullptr;
3144 EnumPropertySetTransformFunc rna_set_transform_fn = nullptr;
3145 EnumPropertyItemFunc rna_itemf_fn = nullptr;
3146
3147 if (get_fn && get_fn != Py_None) {
3148 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3149
3150 rna_get_fn = bpy_prop_enum_get_fn;
3151 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_fn, get_fn);
3152 }
3153
3154 if (set_fn && set_fn != Py_None) {
3155 if (!rna_get_fn) {
3156 PyErr_SetString(PyExc_ValueError,
3157 "The `set` callback is defined without a matching `get` function, this is "
3158 "not supported. `set_transform` should probably be used instead?");
3159 return false;
3160 }
3161
3162 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3163
3164 rna_set_fn = bpy_prop_enum_set_fn;
3165 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_fn, set_fn);
3166 }
3167
3168 if (itemf_fn && itemf_fn != Py_None) {
3169 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3170 rna_itemf_fn = bpy_prop_enum_itemf_fn;
3171 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.enum_data.itemf_fn, itemf_fn);
3172 }
3173
3174 if (get_transform_fn && get_transform_fn != Py_None) {
3175 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3176
3177 rna_get_transform_fn = bpy_prop_enum_get_transform_fn;
3178 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.get_transform_fn, get_transform_fn);
3179 }
3180
3181 if (set_transform_fn && set_transform_fn != Py_None) {
3182 BPyPropStore *prop_store = bpy_prop_py_data_ensure(prop);
3183
3184 rna_set_transform_fn = bpy_prop_enum_set_transform_fn;
3185 ASSIGN_PYOBJECT_INCREF(prop_store->py_data.set_transform_fn, set_transform_fn);
3186 }
3187
3189 prop, rna_get_fn, rna_set_fn, rna_itemf_fn, rna_get_transform_fn, rna_set_transform_fn);
3190
3191 return true;
3192}
3193
3195
3196/* -------------------------------------------------------------------- */
3199
3214 PyObject *args,
3215 PyObject *kw,
3216 PyObject *method_object,
3217 PyObject **r_deferred_result)
3218{
3219 /* This must be the methods of one of the main property types defined in this file. */
3220 BLI_assert(PyCFunction_CheckExact(method_object));
3221
3222 const int args_len = PyTuple_GET_SIZE(args);
3223 PyMethodDef *method_def = ((PyCFunctionObject *)method_object)->m_ml;
3224
3225 /* Call this function with the first argument set to `self`. */
3226 if (args_len == 1) {
3227 self = PyTuple_GET_ITEM(args, 0);
3228 args = PyTuple_New(0);
3229
3230 /* This will be #BPy_BoolProperty or one of the functions that define a type. */
3231 PyCFunctionWithKeywords method_fn = (PyCFunctionWithKeywords)(void *)method_def->ml_meth;
3232 *r_deferred_result = method_fn(self, args, kw);
3233 Py_DECREF(args);
3234 /* May be an error (depending on `r_deferred_result`). */
3235 return nullptr;
3236 }
3237
3238 const char *error_prefix = method_def->ml_name;
3239 if (args_len > 1) {
3240 PyErr_Format(PyExc_ValueError, "%s: all args must be keywords", error_prefix);
3241 *r_deferred_result = nullptr;
3242 /* An error. */
3243 return nullptr;
3244 }
3245
3246 StructRNA *srna = srna_from_self(self, error_prefix);
3247 if (srna == nullptr) {
3248 *r_deferred_result = PyErr_Occurred() ?
3249 nullptr :
3250 bpy_prop_deferred_data_CreatePyObject(method_object, kw);
3251 /* May be an error (depending on `r_deferred_result`). */
3252 return nullptr;
3253 }
3254
3255/* Crash if this is ever used by accident! */
3256#ifndef NDEBUG
3257 *r_deferred_result = (PyObject *)intptr_t(1);
3258#endif
3259
3260 /* No error or deferred result, perform registration immediately. */
3261 return srna;
3262}
3263
3275
3279static int bpy_prop_arg_parse_id(PyObject *o, void *p)
3280{
3281 BPy_PropIDParse *parse_data = static_cast<BPy_PropIDParse *>(p);
3282 StructRNA *srna = parse_data->srna;
3283
3284 if (!PyUnicode_Check(o)) {
3285 PyErr_Format(PyExc_TypeError, "expected a string (got %.200s)", Py_TYPE(o)->tp_name);
3286 return 0;
3287 }
3288
3289 Py_ssize_t id_len;
3290 const char *id;
3291
3292 id = PyUnicode_AsUTF8AndSize(o, &id_len);
3293 if (UNLIKELY(id_len >= MAX_IDPROP_NAME)) {
3294 PyErr_Format(PyExc_TypeError, "'%.200s' too long, max length is %d", id, MAX_IDPROP_NAME - 1);
3295 return 0;
3296 }
3297
3298 parse_data->prop_free_handle = nullptr;
3300 srna, id, &parse_data->prop_free_handle) == -1))
3301 {
3302 PyErr_Format(PyExc_TypeError,
3303 "'%s' is defined as a non-dynamic type for '%s'",
3304 id,
3305 RNA_struct_identifier(srna));
3306 return 0;
3307 }
3308 parse_data->value = id;
3309 return 1;
3310}
3311
3319
3324static int bpy_prop_arg_parse_tag_defines(PyObject *o, void *p)
3325{
3327 parse_data->base.items = RNA_struct_property_tag_defines(parse_data->srna);
3328 if (parse_data->base.items == nullptr) {
3329 PyErr_Format(PyExc_TypeError,
3330 "property-tags not available for '%s'",
3331 RNA_struct_identifier(parse_data->srna));
3332 return 0;
3333 }
3334 return pyrna_enum_bitfield_parse_set(o, &parse_data->base);
3335}
3336
3338
3339/* -------------------------------------------------------------------- */
3342
3343#define BPY_PROPDEF_NAME_DOC \
3344 " :arg name: Name used in the user interface.\n" \
3345 " :type name: str\n"
3346
3347#define BPY_PROPDEF_DESC_DOC \
3348 " :arg description: Text used for the tooltip and api documentation.\n" \
3349 " :type description: str\n"
3350
3351#define BPY_PROPDEF_CTXT_DOC \
3352 " :arg translation_context: Text used as context to disambiguate translations.\n" \
3353 " :type translation_context: str\n"
3354
3355#define BPY_PROPDEF_UNIT_DOC \
3356 " :arg unit: Enumerator in :ref:`rna_enum_property_unit_items`.\n" \
3357 " :type unit: str\n"
3358
3359#define BPY_PROPDEF_NUM_MIN_DOC_(ty) \
3360 " :arg min: Hard minimum, trying to assign a value below will silently assign this minimum " \
3361 "instead.\n" \
3362 " :type min: " ty "\n"
3363
3364#define BPY_PROPDEF_NUM_MAX_DOC_(ty) \
3365 " :arg max: Hard maximum, trying to assign a value above will silently assign this maximum " \
3366 "instead.\n" \
3367 " :type max: " ty "\n"
3368
3369#define BPY_PROPDEF_NUM_MINMAX_DOC(ty) BPY_PROPDEF_NUM_MIN_DOC_(ty) BPY_PROPDEF_NUM_MAX_DOC_(ty)
3370
3371#define BPY_PROPDEF_NUM_SOFT_MIN_DOC_(ty) \
3372 " :arg soft_min: Soft minimum (>= *min*), " \
3373 "user won't be able to drag the widget below this value in the UI.\n" \
3374 " :type soft_min: " ty "\n"
3375
3376#define BPY_PROPDEF_NUM_SOFT_MAX_DOC_(ty) \
3377 " :arg soft_max: Soft maximum (<= *max*), " \
3378 "user won't be able to drag the widget above this value in the UI.\n" \
3379 " :type soft_max: " ty "\n"
3380
3381#define BPY_PROPDEF_NUM_SOFT_MINMAX_DOC(ty) \
3382 BPY_PROPDEF_NUM_SOFT_MIN_DOC_(ty) BPY_PROPDEF_NUM_SOFT_MAX_DOC_(ty)
3383
3384#define BPY_PROPDEF_VECSIZE_DOC \
3385 " :arg size: Vector dimensions in [1, " STRINGIFY(PYRNA_STACK_ARRAY) "]. " \
3386"An int sequence can be used to define multi-dimension arrays.\n" \
3387" :type size: int | Sequence[int]\n"
3388
3389#define BPY_PROPDEF_INT_STEP_DOC \
3390 " :arg step: Step of increment/decrement in UI, in [1, 100], defaults to 1 (WARNING: unused " \
3391 "currently!).\n" \
3392 " :type step: int\n"
3393
3394#define BPY_PROPDEF_FLOAT_STEP_DOC \
3395 " :arg step: Step of increment/decrement in UI, in [1, 100], defaults to 3 (WARNING: actual " \
3396 "value is /100).\n" \
3397 " :type step: int\n"
3398
3399#define BPY_PROPDEF_FLOAT_PREC_DOC \
3400 " :arg precision: Maximum number of decimal digits to display, in [0, 6]. Fraction is " \
3401 "automatically hidden for exact integer values of fields with unit 'NONE' or 'TIME' (frame " \
3402 "count) and step divisible by 100.\n" \
3403 " :type precision: int\n"
3404
3405#define BPY_PROPDEF_UPDATE_DOC \
3406 " :arg update: Function to be called when this value is modified,\n" \
3407 " This function must take 2 values (self, context) and return None.\n" \
3408 " *Warning* there are no safety checks to avoid infinite recursion.\n" \
3409 " :type update: Callable[[:class:`bpy.types.bpy_struct`, :class:`bpy.types.Context`], " \
3410 "None]\n"
3411
3412#define BPY_PROPDEF_POLL_DOC \
3413 " :arg poll: Function that determines whether an item is valid for this property.\n" \
3414 " The function must take 2 values (self, object) and return a boolean.\n" \
3415 "\n" \
3416 " .. note:: The return value will be checked only when assigning an item from the UI, " \
3417 "but it is still possible to assign an \"invalid\" item to the property directly.\n" \
3418 "\n" \
3419 " :type poll: Callable[[:class:`bpy.types.bpy_struct`, :class:`bpy.types.ID`], " \
3420 "bool]\n"
3421
3422#define BPY_PROPDEF_GET_DOC(ty) \
3423 " :arg get: Function to be called when this value is 'read', and the default,\n" \
3424 " system-defined storage is not used for this property.\n" \
3425 " This function must take 1 value (self) and return the value of the property.\n" \
3426 "\n" \
3427 " .. note:: Defining this callback without a matching ``set`` one will make " \
3428 "the property read-only (even if ``READ_ONLY`` option is not set)." \
3429 "\n" \
3430 " :type get: Callable[[:class:`bpy.types.bpy_struct`], " ty "]\n"
3431
3432#define BPY_PROPDEF_SET_DOC(ty) \
3433 " :arg set: Function to be called when this value is 'written', and the default,\n" \
3434 " system-defined storage is not used for this property.\n" \
3435 " This function must take 2 values (self, value) and return None.\n" \
3436 "\n" \
3437 " .. note:: Defining this callback without a matching ``get`` one is invalid." \
3438 "\n" \
3439 " :type set: Callable[[:class:`bpy.types.bpy_struct`, " ty "], None]\n"
3440
3441#define BPY_PROPDEF_GET_TRANSFORM_DOC(ty) \
3442 " :arg get_transform: Function to be called when this value is 'read',\n" \
3443 " if some additional processing must be performed on the stored value.\n" \
3444 " This function must take three arguments (self, the stored value,\n" \
3445 " and a boolean indicating if the property is currently set),\n" \
3446 " and return the final, transformed value of the property.\n" \
3447 "\n" \
3448 " .. note:: The callback is responsible to ensure that value limits of the property " \
3449 "(min/max, length...) are respected. Otherwise a ValueError exception is raised.\n" \
3450 "\n" \
3451 " :type get_transform: Callable[[:class:`bpy.types.bpy_struct`, " ty ", bool], " ty "]\n"
3452
3453#define BPY_PROPDEF_SET_TRANSFORM_DOC(ty) \
3454 " :arg set_transform: Function to be called when this value is 'written',\n" \
3455 " if some additional processing must be performed on the given value before storing it.\n" \
3456 " This function must take four arguments (self, the given value to store,\n" \
3457 " the currently stored value ('raw' value, without any ``get_transform`` applied to " \
3458 "it),\n" \
3459 " and a boolean indicating if the property is currently set),\n" \
3460 " and return the final, transformed value of the property.\n" \
3461 "\n" \
3462 " .. note:: The callback is responsible to ensure that value limits (min/max, " \
3463 "length...) are respected. Otherwise a ValueError exception is raised.\n" \
3464 "\n" \
3465 " :type set_transform: " \
3466 "Callable[[:class:`bpy.types.bpy_struct`, " ty ", " ty ", bool], " ty "]\n"
3467
3468#define BPY_PROPDEF_SEARCH_DOC \
3469 " :arg search: Function to be called to show candidates for this string (shown in the UI).\n" \
3470 " This function must take 3 values (self, context, edit_text)\n" \
3471 " and return a sequence, iterator or generator where each item must be:\n" \
3472 "\n" \
3473 " - A single string (representing a candidate to display).\n" \
3474 " - A tuple-pair of strings, where the first is a candidate and the second\n" \
3475 " is additional information about the candidate.\n" \
3476 " :type search: Callable[[:class:`bpy.types.bpy_struct`, :class:`bpy.types.Context`, str], " \
3477 "Iterable[str | tuple[str, str]]" \
3478 "]\n" \
3479 " :arg search_options: Set of strings in:\n" \
3480 "\n" \
3481 " - 'SORT' sorts the resulting items.\n" \
3482 " - 'SUGGESTION' lets the user enter values not found in search candidates.\n" \
3483 " **WARNING** disabling this flag causes the search callback to run on redraw,\n" \
3484 " so only disable this flag if it's not likely to cause performance issues.\n" \
3485 "\n" \
3486 " :type search_options: set[str]\n"
3487
3488#define BPY_PROPDEF_POINTER_TYPE_DOC \
3489 " :arg type: A subclass of a property group or ID types.\n" \
3490 " :type type: type[:class:`bpy.types.PropertyGroup` | :class:`bpy.types.ID`]\n"
3491
3492#define BPY_PROPDEF_COLLECTION_TYPE_DOC \
3493 " :arg type: A subclass of a property group.\n" \
3494 " :type type: type[:class:`bpy.types.PropertyGroup`]\n"
3495
3496#define BPY_PROPDEF_TAGS_DOC \
3497 " :arg tags: Enumerator of tags that are defined by parent class.\n" \
3498 " :type tags: set[str]\n"
3499
3500#if 0
3501static int bpy_struct_id_used(StructRNA *srna, char *identifier)
3502{
3503 PointerRNA ptr = RNA_pointer_create_discrete(nullptr, srna, nullptr);
3504 return (RNA_struct_find_property(&ptr, identifier) != nullptr);
3505}
3506#endif
3507
3509
3510/* -------------------------------------------------------------------- */
3520
3522 /* Wrap. */
3523 BPy_BoolProperty_doc,
3524 ".. function:: BoolProperty("
3525 "*, "
3526 "name=\"\", "
3527 "description=\"\", "
3528 "translation_context=\"*\", "
3529 "default=False, "
3530 "options={'ANIMATABLE'}, "
3531 "override=set(), "
3532 "tags=set(), "
3533 "subtype='NONE', "
3534 "update=None, "
3535 "get=None, "
3536 "set=None, "
3537 "get_transform=None, "
3538 "set_transform=None)\n"
3539 "\n"
3540 " Returns a new boolean property definition.\n"
3545static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
3546{
3547 StructRNA *srna;
3548 { /* Keep this block first. */
3549 PyObject *deferred_result;
3550 srna = bpy_prop_deferred_data_or_srna(self, args, kw, pymeth_BoolProperty, &deferred_result);
3551 if (srna == nullptr) {
3552 return deferred_result;
3553 }
3554 }
3555
3556 BPy_PropIDParse id_data{};
3557 id_data.srna = srna;
3558
3559 const char *name = nullptr, *description = "";
3560 const char *translation_context = nullptr;
3561 bool default_value = false;
3562 PropertyRNA *prop;
3563 BPy_EnumProperty_Parse options_enum{};
3564 options_enum.items = rna_enum_property_flag_items;
3565 options_enum.value = 0;
3566
3567 BPy_EnumProperty_Parse override_enum{};
3569 override_enum.value = 0;
3570
3572 tags_enum.srna = srna;
3573
3574 BPy_EnumProperty_Parse subtype_enum{};
3576 subtype_enum.value = PROP_NONE;
3577
3578 PyObject *update_fn = nullptr;
3579 PyObject *get_fn = nullptr;
3580 PyObject *set_fn = nullptr;
3581
3582 PyObject *get_transform_fn = nullptr;
3583 PyObject *set_transform_fn = nullptr;
3584
3585 static const char *_keywords[] = {
3586 "attr",
3587 "name",
3588 "description",
3589 "translation_context",
3590 "default",
3591 "options",
3592 "override",
3593 "tags",
3594 "subtype",
3595 "update",
3596 "get",
3597 "set",
3598 "get_transform",
3599 "set_transform",
3600 nullptr,
3601 };
3602 static _PyArg_Parser _parser = {
3604 "O&" /* `attr` */
3605 "|$" /* Optional, keyword only arguments. */
3606 "s" /* `name` */
3607 "s" /* `description` */
3608 "s" /* `translation_context` */
3609 "O&" /* `default` */
3610 "O&" /* `options` */
3611 "O&" /* `override` */
3612 "O&" /* `tags` */
3613 "O&" /* `subtype` */
3614 "O" /* `update` */
3615 "O" /* `get` */
3616 "O" /* `set` */
3617 "O" /* `get_transform` */
3618 "O" /* `set_transform` */
3619 ":BoolProperty",
3620 _keywords,
3621 nullptr,
3622 };
3623 if (!_PyArg_ParseTupleAndKeywordsFast(args,
3624 kw,
3625 &_parser,
3627 &id_data,
3628 &name,
3629 &description,
3630 &translation_context,
3632 &default_value,
3634 &options_enum,
3636 &override_enum,
3638 &tags_enum,
3640 &subtype_enum,
3641 &update_fn,
3642 &get_fn,
3643 &set_fn,
3644 &get_transform_fn,
3645 &set_transform_fn))
3646 {
3647 return nullptr;
3648 }
3649
3650 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
3651 return nullptr;
3652 }
3653 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
3654 return nullptr;
3655 }
3656 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
3657 return nullptr;
3658 }
3659 if (bpy_prop_callback_check(get_transform_fn, "get_transform", 3) == -1) {
3660 return nullptr;
3661 }
3662 if (bpy_prop_callback_check(set_transform_fn, "set_transform", 4) == -1) {
3663 return nullptr;
3664 }
3665
3666 if (id_data.prop_free_handle != nullptr) {
3668 }
3669 prop = RNA_def_property(srna, id_data.value, PROP_BOOLEAN, subtype_enum.value);
3670
3671 RNA_def_property_boolean_default(prop, default_value);
3672 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
3673 if (translation_context) {
3674 RNA_def_property_translation_context(prop, translation_context);
3675 }
3676
3677 if (tags_enum.base.is_set) {
3678 RNA_def_property_tags(prop, tags_enum.base.value);
3679 }
3680 if (options_enum.is_set) {
3681 bpy_prop_assign_flag(prop, options_enum.value);
3682 }
3683 if (override_enum.is_set) {
3684 bpy_prop_assign_flag_override(prop, override_enum.value);
3685 }
3686 bpy_prop_callback_assign_update(prop, update_fn);
3687 if (!bpy_prop_callback_assign_boolean(prop, get_fn, set_fn, get_transform_fn, set_transform_fn))
3688 {
3689 return nullptr;
3690 }
3692
3693 Py_RETURN_NONE;
3694}
3695
3697 /* Wrap. */
3698 BPy_BoolVectorProperty_doc,
3699 ".. function:: BoolVectorProperty("
3700 "*, "
3701 "name=\"\", "
3702 "description=\"\", "
3703 "translation_context=\"*\", "
3704 "default=(False, False, False), "
3705 "options={'ANIMATABLE'}, "
3706 "override=set(), "
3707 "tags=set(), "
3708 "subtype='NONE', "
3709 "size=3, "
3710 "update=None, "
3711 "get=None, "
3712 "set=None, "
3713 "get_transform=None, "
3714 "set_transform=None)\n"
3715 "\n"
3716 " Returns a new vector boolean property definition.\n"
3718 " :arg default: sequence of booleans the length of *size*.\n"
3719 " :type default: Sequence[bool]\n" BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_DOC
3722 BPY_PROPDEF_SET_DOC("tuple[bool, ...]")
3723 BPY_PROPDEF_GET_TRANSFORM_DOC("Sequence[bool]")
3724 BPY_PROPDEF_SET_TRANSFORM_DOC("Sequence[bool]"));
3725static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
3726{
3727 StructRNA *srna;
3728 { /* Keep this block first. */
3729 PyObject *deferred_result;
3731 self, args, kw, pymeth_BoolVectorProperty, &deferred_result);
3732 if (srna == nullptr) {
3733 return deferred_result;
3734 }
3735 }
3736
3737 BPy_PropIDParse id_data{};
3738 id_data.srna = srna;
3739
3740 const char *name = nullptr, *description = "";
3741 const char *translation_context = nullptr;
3742 Array<bool, RNA_STACK_ARRAY> default_value;
3743 BPyPropArrayLength array_len_info{};
3744 array_len_info.len_total = 3;
3745 PropertyRNA *prop;
3746 PyObject *default_py = nullptr;
3747
3748 BPy_EnumProperty_Parse options_enum{};
3749 options_enum.items = rna_enum_property_flag_items;
3750 options_enum.value = 0;
3751
3752 BPy_EnumProperty_Parse override_enum{};
3754 override_enum.value = 0;
3755
3757 tags_enum.srna = srna;
3758
3759 BPy_EnumProperty_Parse subtype_enum{};
3761 subtype_enum.value = PROP_NONE;
3762
3763 PyObject *update_fn = nullptr;
3764 PyObject *get_fn = nullptr;
3765 PyObject *set_fn = nullptr;
3766 PyObject *get_transform_fn = nullptr;
3767 PyObject *set_transform_fn = nullptr;
3768
3769 static const char *_keywords[] = {
3770 "attr",
3771 "name",
3772 "description",
3773 "translation_context",
3774 "default",
3775 "options",
3776 "override",
3777 "tags",
3778 "subtype",
3779 "size",
3780 "update",
3781 "get",
3782 "set",
3783 "get_transform",
3784 "set_transform",
3785 nullptr,
3786 };
3787 static _PyArg_Parser _parser = {
3789 "O&" /* `attr` */
3790 "|$" /* Optional, keyword only arguments. */
3791 "s" /* `name` */
3792 "s" /* `description` */
3793 "s" /* `translation_context` */
3794 "O" /* `default` */
3795 "O&" /* `options` */
3796 "O&" /* `override` */
3797 "O&" /* `tags` */
3798 "O&" /* `subtype` */
3799 "O&" /* `size` */
3800 "O" /* `update` */
3801 "O" /* `get` */
3802 "O" /* `set` */
3803 "O" /* `get_transform` */
3804 "O" /* `set_transform` */
3805 ":BoolVectorProperty",
3806 _keywords,
3807 nullptr,
3808 };
3809 if (!_PyArg_ParseTupleAndKeywordsFast(args,
3810 kw,
3811 &_parser,
3813 &id_data,
3814 &name,
3815 &description,
3816 &translation_context,
3817 &default_py,
3819 &options_enum,
3821 &override_enum,
3823 &tags_enum,
3825 &subtype_enum,
3827 &array_len_info,
3828 &update_fn,
3829 &get_fn,
3830 &set_fn,
3831 &get_transform_fn,
3832 &set_transform_fn))
3833 {
3834 return nullptr;
3835 }
3836
3837 if (default_py != nullptr) {
3838 default_value.reinitialize(array_len_info.len_total);
3839 if (bpy_prop_array_from_py_with_dims(default_value.data(),
3840 sizeof(*default_value.data()),
3841 default_py,
3842 &array_len_info,
3843 &PyBool_Type,
3844 "BoolVectorProperty(default=sequence)") == -1)
3845 {
3846 return nullptr;
3847 }
3848 }
3849
3850 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
3851 return nullptr;
3852 }
3853 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
3854 return nullptr;
3855 }
3856 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
3857 return nullptr;
3858 }
3859 if (bpy_prop_callback_check(get_transform_fn, "get_transform", 3) == -1) {
3860 return nullptr;
3861 }
3862 if (bpy_prop_callback_check(set_transform_fn, "set_transform", 4) == -1) {
3863 return nullptr;
3864 }
3865
3866 if (id_data.prop_free_handle != nullptr) {
3868 }
3869 prop = RNA_def_property(srna, id_data.value, PROP_BOOLEAN, subtype_enum.value);
3870
3871 if (array_len_info.dims_len == 0) {
3872 RNA_def_property_array(prop, array_len_info.len_total);
3873 if (default_py != nullptr) {
3874 RNA_def_property_boolean_array_default(prop, default_value.data());
3875 }
3876 }
3877 else {
3878 RNA_def_property_multi_array(prop, array_len_info.dims_len, array_len_info.dims);
3879 if (default_py != nullptr) {
3880 RNA_def_property_boolean_array_default(prop, default_value.data());
3881 }
3882 }
3883
3884 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
3885 if (translation_context) {
3886 RNA_def_property_translation_context(prop, translation_context);
3887 }
3888
3889 if (tags_enum.base.is_set) {
3890 RNA_def_property_tags(prop, tags_enum.base.value);
3891 }
3892 if (options_enum.is_set) {
3893 bpy_prop_assign_flag(prop, options_enum.value);
3894 }
3895 if (override_enum.is_set) {
3896 bpy_prop_assign_flag_override(prop, override_enum.value);
3897 }
3898 bpy_prop_callback_assign_update(prop, update_fn);
3899 bpy_prop_callback_assign_boolean_array(prop, get_fn, set_fn, get_transform_fn, set_transform_fn);
3901
3902 Py_RETURN_NONE;
3903}
3904
3906 /* Wrap. */
3907 BPy_IntProperty_doc,
3908 ".. function:: IntProperty("
3909 "*, "
3910 "name=\"\", "
3911 "description=\"\", "
3912 "translation_context=\"*\", "
3913 "default=0, "
3914 "min=-2**31, max=2**31-1, "
3915 "soft_min=-2**31, soft_max=2**31-1, "
3916 "step=1, "
3917 "options={'ANIMATABLE'}, "
3918 "override=set(), "
3919 "tags=set(), "
3920 "subtype='NONE', "
3921 "update=None, "
3922 "get=None, "
3923 "set=None, "
3924 "get_transform=None, "
3925 "set_transform=None)\n"
3926 "\n"
3927 " Returns a new int property definition.\n"
3934static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
3935{
3936 StructRNA *srna;
3937 { /* Keep this block first. */
3938 PyObject *deferred_result;
3939 srna = bpy_prop_deferred_data_or_srna(self, args, kw, pymeth_IntProperty, &deferred_result);
3940 if (srna == nullptr) {
3941 return deferred_result;
3942 }
3943 }
3944
3945 BPy_PropIDParse id_data{};
3946 id_data.srna = srna;
3947
3948 const char *name = nullptr, *description = "";
3949 const char *translation_context = nullptr;
3950 int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX;
3951 int step = 1;
3952 int default_value = 0;
3953 PropertyRNA *prop;
3954
3955 BPy_EnumProperty_Parse options_enum{};
3956 options_enum.items = rna_enum_property_flag_items;
3957 options_enum.value = 0;
3958
3959 BPy_EnumProperty_Parse override_enum{};
3961 override_enum.value = 0;
3962
3964 tags_enum.srna = srna;
3965
3966 BPy_EnumProperty_Parse subtype_enum{};
3968 subtype_enum.value = PROP_NONE;
3969
3970 PyObject *update_fn = nullptr;
3971 PyObject *get_fn = nullptr;
3972 PyObject *set_fn = nullptr;
3973 PyObject *get_transform_fn = nullptr;
3974 PyObject *set_transform_fn = nullptr;
3975
3976 static const char *_keywords[] = {
3977 "attr", "name", "description", "translation_context",
3978 "default", "min", "max", "soft_min",
3979 "soft_max", "step", "options", "override",
3980 "tags", "subtype", "update", "get",
3981 "set", "get_transform", "set_transform", nullptr,
3982 };
3983 static _PyArg_Parser _parser = {
3985 "O&" /* `attr` */
3986 "|$" /* Optional, keyword only arguments. */
3987 "s" /* `name` */
3988 "s" /* `description` */
3989 "s" /* `translation_context` */
3990 "i" /* `default` */
3991 "i" /* `min` */
3992 "i" /* `max` */
3993 "i" /* `soft_min` */
3994 "i" /* `soft_max` */
3995 "i" /* `step` */
3996 "O&" /* `options` */
3997 "O&" /* `override` */
3998 "O&" /* `tags` */
3999 "O&" /* `subtype` */
4000 "O" /* `update` */
4001 "O" /* `get` */
4002 "O" /* `set` */
4003 "O" /* `get_transform` */
4004 "O" /* `set_transform` */
4005 ":IntProperty",
4006 _keywords,
4007 nullptr,
4008 };
4009 if (!_PyArg_ParseTupleAndKeywordsFast(args,
4010 kw,
4011 &_parser,
4013 &id_data,
4014 &name,
4015 &description,
4016 &translation_context,
4017 &default_value,
4018 &min,
4019 &max,
4020 &soft_min,
4021 &soft_max,
4022 &step,
4024 &options_enum,
4026 &override_enum,
4028 &tags_enum,
4030 &subtype_enum,
4031 &update_fn,
4032 &get_fn,
4033 &set_fn,
4034 &get_transform_fn,
4035 &set_transform_fn))
4036 {
4037 return nullptr;
4038 }
4039
4040 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
4041 return nullptr;
4042 }
4043 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
4044 return nullptr;
4045 }
4046 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
4047 return nullptr;
4048 }
4049 if (bpy_prop_callback_check(get_transform_fn, "get_transform", 3) == -1) {
4050 return nullptr;
4051 }
4052 if (bpy_prop_callback_check(set_transform_fn, "set_transform", 4) == -1) {
4053 return nullptr;
4054 }
4055
4056 if (id_data.prop_free_handle != nullptr) {
4058 }
4059 prop = RNA_def_property(srna, id_data.value, PROP_INT, subtype_enum.value);
4060
4061 RNA_def_property_int_default(prop, default_value);
4062 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
4063 if (translation_context) {
4064 RNA_def_property_translation_context(prop, translation_context);
4065 }
4067 RNA_def_property_ui_range(prop, std::max(soft_min, min), std::min(soft_max, max), step, 3);
4068
4069 if (tags_enum.base.is_set) {
4070 RNA_def_property_tags(prop, tags_enum.base.value);
4071 }
4072 if (options_enum.is_set) {
4073 bpy_prop_assign_flag(prop, options_enum.value);
4074 }
4075 if (override_enum.is_set) {
4076 bpy_prop_assign_flag_override(prop, override_enum.value);
4077 }
4078 bpy_prop_callback_assign_update(prop, update_fn);
4079 bpy_prop_callback_assign_int(prop, get_fn, set_fn, get_transform_fn, set_transform_fn);
4081
4082 Py_RETURN_NONE;
4083}
4084
4086 /* Wrap. */
4087 BPy_IntVectorProperty_doc,
4088 ".. function:: IntVectorProperty("
4089 "*, "
4090 "name=\"\", "
4091 "description=\"\", "
4092 "translation_context=\"*\", "
4093 "default=(0, 0, 0), min=-2**31, max=2**31-1, "
4094 "soft_min=-2**31, "
4095 "soft_max=2**31-1, "
4096 "step=1, "
4097 "options={'ANIMATABLE'}, "
4098 "override=set(), "
4099 "tags=set(), "
4100 "subtype='NONE', "
4101 "size=3, "
4102 "update=None, "
4103 "get=None, "
4104 "set=None, "
4105 "get_transform=None, "
4106 "set_transform=None)\n"
4107 "\n"
4108 " Returns a new vector int property definition.\n"
4110 " :arg default: sequence of ints the length of *size*.\n"
4111 " :type default: Sequence[int]\n" BPY_PROPDEF_NUM_MINMAX_DOC("int")
4116 BPY_PROPDEF_SET_DOC("tuple[int, ...]")
4117 BPY_PROPDEF_GET_TRANSFORM_DOC("Sequence[int]")
4118 BPY_PROPDEF_SET_TRANSFORM_DOC("Sequence[int]"));
4119static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
4120{
4121 StructRNA *srna;
4122 { /* Keep this block first. */
4123 PyObject *deferred_result;
4125 self, args, kw, pymeth_IntVectorProperty, &deferred_result);
4126 if (srna == nullptr) {
4127 return deferred_result;
4128 }
4129 }
4130
4131 BPy_PropIDParse id_data{};
4132 id_data.srna = srna;
4133
4134 const char *name = nullptr, *description = "";
4135 const char *translation_context = nullptr;
4136 int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX;
4137 int step = 1;
4138 Array<int, RNA_STACK_ARRAY> default_value;
4139 BPyPropArrayLength array_len_info{};
4140 array_len_info.len_total = 3;
4141 PropertyRNA *prop;
4142 PyObject *default_py = nullptr;
4143
4144 BPy_EnumProperty_Parse options_enum{};
4145 options_enum.items = rna_enum_property_flag_items;
4146 options_enum.value = 0;
4147
4148 BPy_EnumProperty_Parse override_enum{};
4150 override_enum.value = 0;
4151
4153 tags_enum.srna = srna;
4154
4155 BPy_EnumProperty_Parse subtype_enum{};
4157 subtype_enum.value = PROP_NONE;
4158
4159 PyObject *update_fn = nullptr;
4160 PyObject *get_fn = nullptr;
4161 PyObject *set_fn = nullptr;
4162 PyObject *get_transform_fn = nullptr;
4163 PyObject *set_transform_fn = nullptr;
4164
4165 static const char *_keywords[] = {
4166 "attr", "name", "description", "translation_context",
4167 "default", "min", "max", "soft_min",
4168 "soft_max", "step", "options", "override",
4169 "tags", "subtype", "size", "update",
4170 "get", "set", "get_transform", "set_transform",
4171 nullptr,
4172 };
4173 static _PyArg_Parser _parser = {
4175 "O&" /* `attr` */
4176 "|$" /* Optional, keyword only arguments. */
4177 "s" /* `name` */
4178 "s" /* `description` */
4179 "s" /* `translation_context` */
4180 "O" /* `default` */
4181 "i" /* `min` */
4182 "i" /* `max` */
4183 "i" /* `soft_min` */
4184 "i" /* `soft_max` */
4185 "i" /* `step` */
4186 "O&" /* `options` */
4187 "O&" /* `override` */
4188 "O&" /* `tags` */
4189 "O&" /* `subtype` */
4190 "O&" /* `size` */
4191 "O" /* `update` */
4192 "O" /* `get` */
4193 "O" /* `set` */
4194 "O" /* `get_transform` */
4195 "O" /* `set_transform` */
4196 ":IntVectorProperty",
4197 _keywords,
4198 nullptr,
4199 };
4200 if (!_PyArg_ParseTupleAndKeywordsFast(args,
4201 kw,
4202 &_parser,
4204 &id_data,
4205 &name,
4206 &description,
4207 &translation_context,
4208 &default_py,
4209 &min,
4210 &max,
4211 &soft_min,
4212 &soft_max,
4213 &step,
4215 &options_enum,
4217 &override_enum,
4219 &tags_enum,
4221 &subtype_enum,
4223 &array_len_info,
4224 &update_fn,
4225 &get_fn,
4226 &set_fn,
4227 &get_transform_fn,
4228 &set_transform_fn))
4229 {
4230 return nullptr;
4231 }
4232
4233 if (default_py != nullptr) {
4234 default_value.reinitialize(array_len_info.len_total);
4235 if (bpy_prop_array_from_py_with_dims(default_value.data(),
4236 sizeof(*default_value.data()),
4237 default_py,
4238 &array_len_info,
4239 &PyLong_Type,
4240 "IntVectorProperty(default=sequence)") == -1)
4241 {
4242 return nullptr;
4243 }
4244 }
4245
4246 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
4247 return nullptr;
4248 }
4249 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
4250 return nullptr;
4251 }
4252 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
4253 return nullptr;
4254 }
4255 if (bpy_prop_callback_check(get_transform_fn, "get_transform", 3) == -1) {
4256 return nullptr;
4257 }
4258 if (bpy_prop_callback_check(set_transform_fn, "set_transform", 4) == -1) {
4259 return nullptr;
4260 }
4261
4262 if (id_data.prop_free_handle != nullptr) {
4264 }
4265 prop = RNA_def_property(srna, id_data.value, PROP_INT, subtype_enum.value);
4266
4267 if (array_len_info.dims_len == 0) {
4268 RNA_def_property_array(prop, array_len_info.len_total);
4269 if (default_py != nullptr) {
4270 RNA_def_property_int_array_default(prop, default_value.data());
4271 }
4272 }
4273 else {
4274 RNA_def_property_multi_array(prop, array_len_info.dims_len, array_len_info.dims);
4275 if (default_py != nullptr) {
4276 RNA_def_property_int_array_default(prop, default_value.data());
4277 }
4278 }
4279
4281 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
4282 if (translation_context) {
4283 RNA_def_property_translation_context(prop, translation_context);
4284 }
4285 RNA_def_property_ui_range(prop, std::max(soft_min, min), std::min(soft_max, max), step, 3);
4286
4287 if (tags_enum.base.is_set) {
4288 RNA_def_property_tags(prop, tags_enum.base.value);
4289 }
4290 if (options_enum.is_set) {
4291 bpy_prop_assign_flag(prop, options_enum.value);
4292 }
4293 if (override_enum.is_set) {
4294 bpy_prop_assign_flag_override(prop, override_enum.value);
4295 }
4296 bpy_prop_callback_assign_update(prop, update_fn);
4297 bpy_prop_callback_assign_int_array(prop, get_fn, set_fn, get_transform_fn, set_transform_fn);
4299
4300 Py_RETURN_NONE;
4301}
4302
4304 /* Wrap. */
4305 BPy_FloatProperty_doc,
4306 ".. function:: FloatProperty("
4307 "*, "
4308 "name=\"\", "
4309 "description=\"\", "
4310 "translation_context=\"*\", "
4311 "default=0.0, "
4312 "min=-3.402823e+38, max=3.402823e+38, "
4313 "soft_min=-3.402823e+38, soft_max=3.402823e+38, "
4314 "step=3, "
4315 "precision=2, "
4316 "options={'ANIMATABLE'}, "
4317 "override=set(), "
4318 "tags=set(), "
4319 "subtype='NONE', "
4320 "unit='NONE', "
4321 "update=None, "
4322 "get=None, "
4323 "set=None, "
4324 "get_transform=None, "
4325 "set_transform=None)\n"
4326 "\n"
4327 " Returns a new float (single precision) property definition.\n"
4329 "float") BPY_PROPDEF_NUM_SOFT_MINMAX_DOC("float")
4335static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
4336{
4337 StructRNA *srna;
4338 { /* Keep this block first. */
4339 PyObject *deferred_result;
4340 srna = bpy_prop_deferred_data_or_srna(self, args, kw, pymeth_FloatProperty, &deferred_result);
4341 if (srna == nullptr) {
4342 return deferred_result;
4343 }
4344 }
4345
4346 BPy_PropIDParse id_data{};
4347 id_data.srna = srna;
4348
4349 const char *name = nullptr, *description = "";
4350 const char *translation_context = nullptr;
4351 float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX;
4352 float step = 3;
4353 float default_value = 0.0f;
4354 int precision = 2;
4355 PropertyRNA *prop;
4356
4357 BPy_EnumProperty_Parse options_enum{};
4358 options_enum.items = rna_enum_property_flag_items;
4359 options_enum.value = 0;
4360
4361 BPy_EnumProperty_Parse override_enum{};
4363 override_enum.value = 0;
4364
4366 tags_enum.srna = srna;
4367
4368 BPy_EnumProperty_Parse subtype_enum{};
4370 subtype_enum.value = PROP_NONE;
4371
4372 BPy_EnumProperty_Parse unit_enum{};
4374 unit_enum.value = PROP_UNIT_NONE;
4375
4376 PyObject *update_fn = nullptr;
4377 PyObject *get_fn = nullptr;
4378 PyObject *set_fn = nullptr;
4379 PyObject *get_transform_fn = nullptr;
4380 PyObject *set_transform_fn = nullptr;
4381
4382 static const char *_keywords[] = {
4383 "attr", "name", "description", "translation_context",
4384 "default", "min", "max", "soft_min",
4385 "soft_max", "step", "precision", "options",
4386 "override", "tags", "subtype", "unit",
4387 "update", "get", "set", "get_transform",
4388 "set_transform", nullptr,
4389 };
4390 static _PyArg_Parser _parser = {
4392 "O&" /* `attr` */
4393 "|$" /* Optional, keyword only arguments. */
4394 "s" /* `name` */
4395 "s" /* `description` */
4396 "s" /* `translation_context` */
4397 "f" /* `default` */
4398 "f" /* `min` */
4399 "f" /* `max` */
4400 "f" /* `soft_min` */
4401 "f" /* `soft_max` */
4402 "f" /* `step` */
4403 "i" /* `precision` */
4404 "O&" /* `options` */
4405 "O&" /* `override` */
4406 "O&" /* `tags` */
4407 "O&" /* `subtype` */
4408 "O&" /* `unit` */
4409 "O" /* `update` */
4410 "O" /* `get` */
4411 "O" /* `set` */
4412 "O" /* `get_transform` */
4413 "O" /* `set_transform` */
4414 ":FloatProperty",
4415 _keywords,
4416 nullptr,
4417 };
4418 if (!_PyArg_ParseTupleAndKeywordsFast(args,
4419 kw,
4420 &_parser,
4422 &id_data,
4423 &name,
4424 &description,
4425 &translation_context,
4426 &default_value,
4427 &min,
4428 &max,
4429 &soft_min,
4430 &soft_max,
4431 &step,
4432 &precision,
4434 &options_enum,
4436 &override_enum,
4438 &tags_enum,
4440 &subtype_enum,
4442 &unit_enum,
4443 &update_fn,
4444 &get_fn,
4445 &set_fn,
4446 &get_transform_fn,
4447 &set_transform_fn))
4448 {
4449 return nullptr;
4450 }
4451
4452 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
4453 return nullptr;
4454 }
4455 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
4456 return nullptr;
4457 }
4458 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
4459 return nullptr;
4460 }
4461 if (bpy_prop_callback_check(get_transform_fn, "get_transform", 3) == -1) {
4462 return nullptr;
4463 }
4464 if (bpy_prop_callback_check(set_transform_fn, "set_transform", 4) == -1) {
4465 return nullptr;
4466 }
4467
4468 if (id_data.prop_free_handle != nullptr) {
4470 }
4471 prop = RNA_def_property(srna, id_data.value, PROP_FLOAT, subtype_enum.value | unit_enum.value);
4472
4473 RNA_def_property_float_default(prop, default_value);
4475 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
4476 if (translation_context) {
4477 RNA_def_property_translation_context(prop, translation_context);
4478 }
4480 prop, std::max(soft_min, min), std::min(soft_max, max), step, precision);
4481
4482 if (tags_enum.base.is_set) {
4483 RNA_def_property_tags(prop, tags_enum.base.value);
4484 }
4485 if (options_enum.is_set) {
4486 bpy_prop_assign_flag(prop, options_enum.value);
4487 }
4488 if (override_enum.is_set) {
4489 bpy_prop_assign_flag_override(prop, override_enum.value);
4490 }
4491 bpy_prop_callback_assign_update(prop, update_fn);
4492 bpy_prop_callback_assign_float(prop, get_fn, set_fn, get_transform_fn, set_transform_fn);
4494
4495 Py_RETURN_NONE;
4496}
4497
4499 /* Wrap. */
4500 BPy_FloatVectorProperty_doc,
4501 ".. function:: FloatVectorProperty("
4502 "*, "
4503 "name=\"\", "
4504 "description=\"\", "
4505 "translation_context=\"*\", "
4506 "default=(0.0, 0.0, 0.0), "
4507 "min=sys.float_info.min, max=sys.float_info.max, "
4508 "soft_min=sys.float_info.min, soft_max=sys.float_info.max, "
4509 "step=3, "
4510 "precision=2, "
4511 "options={'ANIMATABLE'}, "
4512 "override=set(), "
4513 "tags=set(), "
4514 "subtype='NONE', "
4515 "unit='NONE', "
4516 "size=3, "
4517 "update=None, "
4518 "get=None, "
4519 "set=None)\n"
4520 "\n"
4521 " Returns a new vector float property definition.\n"
4523 " :arg default: Sequence of floats the length of *size*.\n"
4524 " :type default: Sequence[float]\n" BPY_PROPDEF_NUM_MINMAX_DOC(
4525 "float") BPY_PROPDEF_NUM_SOFT_MINMAX_DOC("float")
4530 BPY_PROPDEF_SET_DOC("tuple[float, ...]")
4531 BPY_PROPDEF_GET_TRANSFORM_DOC("Sequence[float]")
4532 BPY_PROPDEF_SET_TRANSFORM_DOC("Sequence[float]"));
4533static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
4534{
4535 StructRNA *srna;
4536 { /* Keep this block first. */
4537 PyObject *deferred_result;
4539 self, args, kw, pymeth_FloatVectorProperty, &deferred_result);
4540 if (srna == nullptr) {
4541 return deferred_result;
4542 }
4543 }
4544
4545 BPy_PropIDParse id_data{};
4546 id_data.srna = srna;
4547
4548 const char *name = nullptr, *description = "";
4549 const char *translation_context = nullptr;
4550 float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX;
4551 float step = 3;
4552 Array<float, RNA_STACK_ARRAY> default_value;
4553 int precision = 2;
4554 BPyPropArrayLength array_len_info{};
4555 array_len_info.len_total = 3;
4556 PropertyRNA *prop;
4557 PyObject *default_py = nullptr;
4558
4559 BPy_EnumProperty_Parse options_enum{};
4560 options_enum.items = rna_enum_property_flag_items;
4561 options_enum.value = 0;
4562
4563 BPy_EnumProperty_Parse override_enum{};
4565 override_enum.value = 0;
4566
4568 tags_enum.srna = srna;
4569
4570 BPy_EnumProperty_Parse subtype_enum{};
4572 subtype_enum.value = PROP_NONE;
4573
4574 BPy_EnumProperty_Parse unit_enum{};
4576 unit_enum.value = PROP_UNIT_NONE;
4577
4578 PyObject *update_fn = nullptr;
4579 PyObject *get_fn = nullptr;
4580 PyObject *set_fn = nullptr;
4581 PyObject *get_transform_fn = nullptr;
4582 PyObject *set_transform_fn = nullptr;
4583
4584 static const char *_keywords[] = {
4585 "attr", "name", "description", "translation_context",
4586 "default", "min", "max", "soft_min",
4587 "soft_max", "step", "precision", "options",
4588 "override", "tags", "subtype", "unit",
4589 "size", "update", "get", "set",
4590 "get_transform", "set_transform", nullptr,
4591 };
4592 static _PyArg_Parser _parser = {
4594 "O&" /* `attr` */
4595 "|$" /* Optional, keyword only arguments. */
4596 "s" /* `name` */
4597 "s" /* `description` */
4598 "s" /* `translation_context` */
4599 "O" /* `default` */
4600 "f" /* `min` */
4601 "f" /* `max` */
4602 "f" /* `soft_min` */
4603 "f" /* `soft_max` */
4604 "f" /* `step` */
4605 "i" /* `precision` */
4606 "O&" /* `options` */
4607 "O&" /* `override` */
4608 "O&" /* `tags` */
4609 "O&" /* `subtype` */
4610 "O&" /* `unit` */
4611 "O&" /* `size` */
4612 "O" /* `update` */
4613 "O" /* `get` */
4614 "O" /* `set` */
4615 "O" /* `get_transform` */
4616 "O" /* `set_transform` */
4617 ":FloatVectorProperty",
4618 _keywords,
4619 nullptr,
4620 };
4621 if (!_PyArg_ParseTupleAndKeywordsFast(args,
4622 kw,
4623 &_parser,
4625 &id_data,
4626 &name,
4627 &description,
4628 &translation_context,
4629 &default_py,
4630 &min,
4631 &max,
4632 &soft_min,
4633 &soft_max,
4634 &step,
4635 &precision,
4637 &options_enum,
4639 &override_enum,
4641 &tags_enum,
4643 &subtype_enum,
4645 &unit_enum,
4647 &array_len_info,
4648 &update_fn,
4649 &get_fn,
4650 &set_fn,
4651 &get_transform_fn,
4652 &set_transform_fn))
4653 {
4654 return nullptr;
4655 }
4656
4657 if (default_py != nullptr) {
4658 default_value.reinitialize(array_len_info.len_total);
4659 if (bpy_prop_array_from_py_with_dims(default_value.data(),
4660 sizeof(*default_value.data()),
4661 default_py,
4662 &array_len_info,
4663 &PyFloat_Type,
4664 "FloatVectorProperty(default=sequence)") == -1)
4665 {
4666 return nullptr;
4667 }
4668 if (bpy_prop_array_is_matrix_compatible_ex(subtype_enum.value, &array_len_info)) {
4669 bpy_prop_array_matrix_swap_row_column_vn(default_value.data(), &array_len_info);
4670 }
4671 }
4672
4673 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
4674 return nullptr;
4675 }
4676 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
4677 return nullptr;
4678 }
4679 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
4680 return nullptr;
4681 }
4682 if (bpy_prop_callback_check(get_transform_fn, "get_transform", 3) == -1) {
4683 return nullptr;
4684 }
4685 if (bpy_prop_callback_check(set_transform_fn, "set_transform", 4) == -1) {
4686 return nullptr;
4687 }
4688
4689 if (id_data.prop_free_handle != nullptr) {
4691 }
4692 prop = RNA_def_property(srna, id_data.value, PROP_FLOAT, subtype_enum.value | unit_enum.value);
4693
4694 if (array_len_info.dims_len == 0) {
4695 RNA_def_property_array(prop, array_len_info.len_total);
4696 if (default_py != nullptr) {
4697 RNA_def_property_float_array_default(prop, default_value.data());
4698 }
4699 }
4700 else {
4701 RNA_def_property_multi_array(prop, array_len_info.dims_len, array_len_info.dims);
4702 if (default_py != nullptr) {
4703 RNA_def_property_float_array_default(prop, default_value.data());
4704 }
4705 }
4706
4708 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
4709 if (translation_context) {
4710 RNA_def_property_translation_context(prop, translation_context);
4711 }
4713 prop, std::max(soft_min, min), std::min(soft_max, max), step, precision);
4714
4715 if (tags_enum.base.is_set) {
4716 RNA_def_property_tags(prop, tags_enum.base.value);
4717 }
4718 if (options_enum.is_set) {
4719 bpy_prop_assign_flag(prop, options_enum.value);
4720 }
4721 if (override_enum.is_set) {
4722 bpy_prop_assign_flag_override(prop, override_enum.value);
4723 }
4724 bpy_prop_callback_assign_update(prop, update_fn);
4725 bpy_prop_callback_assign_float_array(prop, get_fn, set_fn, get_transform_fn, set_transform_fn);
4727
4728 Py_RETURN_NONE;
4729}
4730
4732 /* Wrap. */
4733 BPy_StringProperty_doc,
4734 ".. function:: StringProperty("
4735 "*, "
4736 "name=\"\", "
4737 "description=\"\", "
4738 "translation_context=\"*\", "
4739 "default=\"\", "
4740 "maxlen=0, "
4741 "options={'ANIMATABLE'}, "
4742 "override=set(), "
4743 "tags=set(), "
4744 "subtype='NONE', "
4745 "update=None, "
4746 "get=None, "
4747 "set=None, "
4748 "get_transform=None, "
4749 "set_transform=None, "
4750 "search=None, "
4751 "search_options={'SUGGESTION'})\n"
4752 "\n"
4753 " Returns a new string property definition.\n"
4755 " :arg default: initializer string.\n"
4756 " :type default: str\n"
4757 " :arg maxlen: maximum length of the string.\n"
4763static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
4764{
4765 StructRNA *srna;
4766 { /* Keep this block first. */
4767 PyObject *deferred_result;
4768 srna = bpy_prop_deferred_data_or_srna(self, args, kw, pymeth_StringProperty, &deferred_result);
4769 if (srna == nullptr) {
4770 return deferred_result;
4771 }
4772 }
4773
4774 BPy_PropIDParse id_data{};
4775 id_data.srna = srna;
4776
4777 const char *name = nullptr, *description = "";
4778 const char *translation_context = nullptr, *default_value = "";
4779 int maxlen = 0;
4780 PropertyRNA *prop;
4781
4782 BPy_EnumProperty_Parse options_enum{};
4783 options_enum.items = rna_enum_property_flag_items;
4784 options_enum.value = 0;
4785
4786 BPy_EnumProperty_Parse override_enum{};
4788 override_enum.value = 0;
4789
4791 tags_enum.srna = srna;
4792
4793 BPy_EnumProperty_Parse subtype_enum{};
4795 subtype_enum.value = PROP_NONE;
4796
4797 PyObject *update_fn = nullptr;
4798 PyObject *get_fn = nullptr;
4799 PyObject *set_fn = nullptr;
4800 PyObject *get_transform_fn = nullptr;
4801 PyObject *set_transform_fn = nullptr;
4802 PyObject *search_fn = nullptr;
4803 BPy_EnumProperty_Parse search_options_enum{};
4805 search_options_enum.value = PROP_STRING_SEARCH_SUGGESTION;
4806
4807 static const char *_keywords[] = {
4808 "attr",
4809 "name",
4810 "description",
4811 "translation_context",
4812 "default",
4813 "maxlen",
4814 "options",
4815 "override",
4816 "tags",
4817 "subtype",
4818 "update",
4819 "get",
4820 "set",
4821 "get_transform",
4822 "set_transform",
4823 "search",
4824 "search_options",
4825 nullptr,
4826 };
4827 static _PyArg_Parser _parser = {
4829 "O&" /* `attr` */
4830 "|$" /* Optional, keyword only arguments. */
4831 "s" /* `name` */
4832 "s" /* `description` */
4833 "s" /* `translation_context` */
4834 "s" /* `default` */
4835 "i" /* `maxlen` */
4836 "O&" /* `options` */
4837 "O&" /* `override` */
4838 "O&" /* `tags` */
4839 "O&" /* `subtype` */
4840 "O" /* `update` */
4841 "O" /* `get` */
4842 "O" /* `set` */
4843 "O" /* `get_transform` */
4844 "O" /* `set_transform` */
4845 "O" /* `search` */
4846 "O&" /* `search_options` */
4847 ":StringProperty",
4848 _keywords,
4849 nullptr,
4850 };
4851 if (!_PyArg_ParseTupleAndKeywordsFast(args,
4852 kw,
4853 &_parser,
4855 &id_data,
4856 &name,
4857 &description,
4858 &translation_context,
4859 &default_value,
4860 &maxlen,
4862 &options_enum,
4864 &override_enum,
4866 &tags_enum,
4868 &subtype_enum,
4869 &update_fn,
4870 &get_fn,
4871 &set_fn,
4872 &get_transform_fn,
4873 &set_transform_fn,
4874 &search_fn,
4876 &search_options_enum))
4877 {
4878 return nullptr;
4879 }
4880
4881 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
4882 return nullptr;
4883 }
4884 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
4885 return nullptr;
4886 }
4887 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
4888 return nullptr;
4889 }
4890 if (bpy_prop_callback_check(get_transform_fn, "get_transform", 3) == -1) {
4891 return nullptr;
4892 }
4893 if (bpy_prop_callback_check(set_transform_fn, "set_transform", 4) == -1) {
4894 return nullptr;
4895 }
4896 if (bpy_prop_callback_check(search_fn, "search", 3) == -1) {
4897 return nullptr;
4898 }
4899
4900 if (id_data.prop_free_handle != nullptr) {
4902 }
4903 prop = RNA_def_property(srna, id_data.value, PROP_STRING, subtype_enum.value);
4904
4905 if (maxlen != 0) {
4906 /* +1 since it includes null terminator. */
4907 RNA_def_property_string_maxlength(prop, maxlen + 1);
4908 }
4909 if (default_value && default_value[0]) {
4910 RNA_def_property_string_default(prop, default_value);
4911 }
4912 RNA_def_property_ui_text(prop, name ? name : id_data.value, description);
4913 if (translation_context) {
4914 RNA_def_property_translation_context(prop, translation_context);
4915 }
4916
4917 if (tags_enum.base.is_set) {
4918 RNA_def_property_tags(prop, tags_enum.base.value);
4919 }
4920 if (options_enum.is_set) {
4921 bpy_prop_assign_flag(prop, options_enum.value);
4922 }
4923 if (override_enum.is_set) {
4924 bpy_prop_assign_flag_override(prop, override_enum.value);
4925 }
4926 bpy_prop_callback_assign_update(prop, update_fn);
4928 get_fn,
4929 set_fn,
4930 get_transform_fn,
4931 set_transform_fn,
4932 search_fn,
4933 eStringPropertySearchFlag(search_options_enum.value));
4935
4936 Py_RETURN_NONE;
4937}
4938
4940 /* Wrap. */
4941 BPy_EnumProperty_doc,
4942 ".. function:: EnumProperty("
4943 "items, "
4944 "*, "
4945 "name=\"\", "
4946 "description=\"\", "
4947 "translation_context=\"*\", "
4948 "default=None, "
4949 "options={'ANIMATABLE'}, "
4950 "override=set(), "
4951 "tags=set(), "
4952 "update=None, "
4953 "get=None, "
4954 "set=None, "
4955 "get_transform=None, "
4956 "set_transform=None)\n"
4957 "\n"
4958 " Returns a new enumerator property definition.\n"
4959 "\n"
4960 " :arg items: sequence of enum items formatted:\n"
4961 " ``[(identifier, name, description, icon, number), ...]``.\n"
4962 "\n"
4963 " The first three elements of the tuples are mandatory.\n"
4964 "\n"
4965 " :identifier: The identifier is used for Python access.\n"
4966 " An empty identifier means that the item is a separator\n"
4967 " :name: Name for the interface.\n"
4968 " :description: Used for documentation and tooltips.\n"
4969 " :icon: An icon string identifier or integer icon value\n"
4970 " (e.g. returned by :class:`bpy.types.UILayout.icon`)\n"
4971 " :number: Unique value used as the identifier for this item (stored in file data).\n"
4972 " Use when the identifier may need to change. If the *ENUM_FLAG* option is used,\n"
4973 " the values are bit-masks and should be powers of two.\n"
4974 "\n"
4975 " When an item only contains 4 items they define ``(identifier, name, description, "
4976 "number)``.\n"
4977 "\n"
4978 " Separators may be added using either None (nameless separator),\n"
4979 " or a regular item tuple with an empty identifier string, in which case the name,\n"
4980 " if non-empty, will be displayed in the UI above the separator line."
4981 "\n"
4982 " For dynamic values a callback can be passed which returns a list in\n"
4983 " the same format as the static list.\n"
4984 " This function must take 2 arguments ``(self, context)``, **context may be None**.\n"
4985 "\n"
4986 " .. warning::\n"
4987 "\n"
4988 " There is a known bug with using a callback,\n"
4989 " Python must keep a reference to the strings returned by the callback or Blender\n"
4990 " will misbehave or even crash."
4991 "\n"
4992 " :type items: Iterable["
4993 "tuple[str, str, str] | "
4994 "tuple[str, str, str, int] | "
4995 "tuple[str, str, str, int, int] | "
4996 "None] | "
4997 "Callable[[:class:`bpy.types.bpy_struct`, :class:`bpy.types.Context` | None], "
4998 /* NOTE(@ideasman42): a type alias would be useful here (same as above). */
4999 "Iterable["
5000 "tuple[str, str, str] | "
5001 "tuple[str, str, str, int] | "
5002 "tuple[str, str, str, int, int] | "
5003 "None]"
5005 " :arg default: The default value for this enum, a string from the identifiers used in "
5006 "*items*, or integer matching an item number.\n"
5007 " If the *ENUM_FLAG* option is used this must be a set of such string identifiers "
5008 "instead.\n"
5009 " WARNING: Strings cannot be specified for dynamic enums\n"
5010 " (i.e. if a callback function is given as *items* parameter).\n"
5011 " :type default: str | int | set[str]\n" BPY_PROPDEF_OPTIONS_ENUM_DOC
5015static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
5016{
5017 StructRNA *srna;
5018 { /* Keep this block first. */
5019 PyObject *deferred_result;
5020 srna = bpy_prop_deferred_data_or_srna(self, args, kw, pymeth_EnumProperty, &deferred_result);
5021 if (srna == nullptr) {
5022 return deferred_result;
5023 }
5024 }
5025
5026 BPy_PropIDParse id_data{};
5027 id_data.srna = srna;
5028
5029 const char *name = nullptr, *description = "";
5030 const char *translation_context = nullptr;
5031 PyObject *default_py = nullptr;
5032 int default_value = 0;
5033 PyObject *items, *items_fast;
5034 const EnumPropertyItem *eitems;
5035 PropertyRNA *prop;
5036
5037 BPy_EnumProperty_Parse options_enum{};
5039 options_enum.value = 0;
5040
5041 BPy_EnumProperty_Parse override_enum{};
5043 override_enum.value = 0;
5044
5046 tags_enum.srna = srna;
5047
5048 bool is_itemf = false;
5049 PyObject *update_fn = nullptr;
5050 PyObject *get_fn = nullptr;
5051 PyObject *set_fn = nullptr;
5052 PyObject *get_transform_fn = nullptr;
5053 PyObject *set_transform_fn = nullptr;
5054
5055 static const char *_keywords[] = {
5056 "attr",
5057 "items",
5058 "name",
5059 "description",
5060 "translation_context",
5061 "default",
5062 "options",
5063 "override",
5064 "tags",
5065 "update",
5066 "get",
5067 "set",
5068 "get_transform",
5069 "set_transform",
5070 nullptr,
5071 };
5072 static _PyArg_Parser _parser = {
5074 "O&" /* `attr` */
5075 "O" /* `items` */
5076 "|$" /* Optional, keyword only arguments. */
5077 "s" /* `name` */
5078 "s" /* `description` */
5079 "s" /* `translation_context` */
5080 "O" /* `default` */
5081 "O&" /* `options` */
5082 "O&" /* `override` */
5083 "O&" /* `tags` */
5084 "O" /* `update` */
5085 "O" /* `get` */
5086 "O" /* `set` */
5087 "O" /* `get_transform` */
5088 "O" /* `set_transform` */
5089 ":EnumProperty",
5090 _keywords,
5091 nullptr,
5092 };
5093 if (!_PyArg_ParseTupleAndKeywordsFast(args,
5094 kw,
5095 &_parser,
5097 &id_data,
5098 &items,
5099 &name,
5100 &description,
5101 &translation_context,
5102 &default_py,
5104 &options_enum,
5106 &override_enum,
5108 &tags_enum,
5109 &update_fn,
5110 &get_fn,
5111 &set_fn,
5112 &get_transform_fn,
5113 &set_transform_fn))
5114 {
5115 return nullptr;
5116 }
5117
5118 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
5119 return nullptr;
5120 }
5121 if (bpy_prop_callback_check(get_fn, "get", 1) == -1) {
5122 return nullptr;
5123 }
5124 if (bpy_prop_callback_check(set_fn, "set", 2) == -1) {
5125 return nullptr;
5126 }
5127 if (bpy_prop_callback_check(get_transform_fn, "get_transform", 3) == -1) {
5128 return nullptr;
5129 }
5130 if (bpy_prop_callback_check(set_transform_fn, "set_transform", 4) == -1) {
5131 return nullptr;
5132 }
5133
5134 if (default_py == Py_None) {
5135 /* This allows to get same behavior when explicitly passing None as default value,
5136 * and not defining a default value at all! */
5137 default_py = nullptr;
5138 }
5139
5140 /* Items can be a list or a callable.
5141 * NOTE: Don't use #PyCallable_Check because we need the function code for errors. */
5142 if (PyFunction_Check(items)) {
5143 PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(items);
5144 if (f_code->co_argcount != 2) {
5145 PyErr_Format(PyExc_ValueError,
5146 "EnumProperty(...): expected 'items' function to take 2 arguments, not %d",
5147 f_code->co_argcount);
5148 return nullptr;
5149 }
5150
5151 if (default_py) {
5152 /* Only support getting integer default values here. */
5153 if (!py_long_as_int(default_py, &default_value)) {
5154 /* NOTE: using type error here is odd but python does this for invalid arguments. */
5155 PyErr_SetString(
5156 PyExc_TypeError,
5157 "EnumProperty(...): 'default' can only be an integer when 'items' is a function");
5158 return nullptr;
5159 }
5160 }
5161
5162 is_itemf = true;
5164 }
5165 else {
5166 if (!(items_fast = PySequence_Fast(
5167 items,
5168 "EnumProperty(...): "
5169 "expected a sequence of tuples for the enum items or a function")))
5170 {
5171 return nullptr;
5172 }
5173
5174 eitems = enum_items_from_py(
5175 items_fast, (options_enum.value & PROP_ENUM_FLAG) != 0, default_py, &default_value);
5176
5177 if (!eitems) {
5178 Py_DECREF(items_fast);
5179 return nullptr;
5180 }
5181 }
5182
5183 if (id_data.prop_free_handle != nullptr) {
5185 }
5186 if (options_enum.value & PROP_ENUM_FLAG) {
5187 prop = RNA_def_enum_flag(
5188 srna, id_data.value, eitems, default_value, name ? name : id_data.value, description);
5189 }
5190 else {
5191 prop = RNA_def_enum(
5192 srna, id_data.value, eitems, default_value, name ? name : id_data.value, description);
5193 }
5194 if (translation_context) {
5195 RNA_def_property_translation_context(prop, translation_context);
5196 }
5197
5198 if (tags_enum.base.is_set) {
5199 RNA_def_property_tags(prop, tags_enum.base.value);
5200 }
5201 if (options_enum.is_set) {
5202 bpy_prop_assign_flag(prop, options_enum.value);
5203 }
5204 if (override_enum.is_set) {
5205 bpy_prop_assign_flag_override(prop, override_enum.value);
5206 }
5207 bpy_prop_callback_assign_update(prop, update_fn);
5209 prop, get_fn, set_fn, (is_itemf ? items : nullptr), get_transform_fn, set_transform_fn);
5211
5212 if (is_itemf == false) {
5213 /* NOTE: this must be postponed until after #RNA_def_property_duplicate_pointers
5214 * otherwise if this is a generator it may free the strings before we copy them */
5215 Py_DECREF(items_fast);
5216
5217 MEM_freeN(eitems);
5218 }
5219
5220 Py_RETURN_NONE;
5221}
5222
5223StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix)
5224{
5225 StructRNA *srna;
5226
5227 srna = srna_from_self(value, "");
5228 if (!srna) {
5229 if (PyErr_Occurred()) {
5230 PyObject *msg = PyC_ExceptionBuffer();
5231 const char *msg_char = PyUnicode_AsUTF8(msg);
5232 PyErr_Clear();
5233
5234 PyErr_Format(
5235 PyExc_TypeError, "%.200s expected an RNA type, failed with: %s", error_prefix, msg_char);
5236 Py_DECREF(msg);
5237 }
5238 else {
5239 PyErr_Format(PyExc_TypeError,
5240 "%.200s expected an RNA type, failed with type '%s'",
5241 error_prefix,
5242 Py_TYPE(value)->tp_name);
5243 }
5244 return nullptr;
5245 }
5246
5247 return srna;
5248}
5249
5251 /* Wrap. */
5252 BPy_PointerProperty_doc,
5253 ".. function:: PointerProperty("
5254 "type, "
5255 "*, "
5256 "name=\"\", "
5257 "description=\"\", "
5258 "translation_context=\"*\", "
5259 "options={'ANIMATABLE'}, "
5260 "override=set(), "
5261 "tags=set(), "
5262 "poll=None, "
5263 "update=None)\n"
5264 "\n"
5265 " Returns a new pointer property definition.\n"
5269 "\n"
5270 ".. note:: Pointer properties do not support storing references to embedded IDs "
5271 "(e.g. :class:`bpy.types.Scene.collection`, :class:`bpy.types.Material.node_tree`).\n"
5272 " These should exclusively be referenced and accessed through their owner ID "
5273 "(e.g. the scene or material).\n");
5274PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
5275{
5276 StructRNA *srna;
5277 { /* Keep this block first. */
5278 PyObject *deferred_result;
5280 self, args, kw, pymeth_PointerProperty, &deferred_result);
5281 if (srna == nullptr) {
5282 return deferred_result;
5283 }
5284 }
5285
5286 BPy_PropIDParse id_data{};
5287 id_data.srna = srna;
5288
5289 const char *name = nullptr, *description = "";
5290 const char *translation_context = nullptr;
5291 PropertyRNA *prop;
5292 StructRNA *ptype;
5293 PyObject *type = Py_None;
5294
5295 BPy_EnumProperty_Parse options_enum{};
5296 options_enum.items = rna_enum_property_flag_items;
5297 options_enum.value = 0;
5298
5299 BPy_EnumProperty_Parse override_enum{};
5301 override_enum.value = 0;
5302
5304 tags_enum.srna = srna;
5305
5306 PyObject *update_fn = nullptr, *poll_fn = nullptr;
5307
5308 static const char *_keywords[] = {
5309 "attr",
5310 "type",
5311 "name",
5312 "description",
5313 "translation_context",
5314 "options",
5315 "override",
5316 "tags",
5317 "poll",
5318 "update",
5319 nullptr,
5320 };
5321 static _PyArg_Parser _parser = {
5323 "O&" /* `attr` */
5324 "O" /* `type` */
5325 "|$" /* Optional, keyword only arguments. */
5326 "s" /* `name` */
5327 "s" /* `description` */
5328 "s" /* `translation_context` */
5329 "O&" /* `options` */
5330 "O&" /* `override` */
5331 "O&" /* `tags` */
5332 "O" /* `poll` */
5333 "O" /* `update` */
5334 ":PointerProperty",
5335 _keywords,
5336 nullptr,
5337 };
5338 if (!_PyArg_ParseTupleAndKeywordsFast(args,
5339 kw,
5340 &_parser,
5342 &id_data,
5343 &type,
5344 &name,
5345 &description,
5346 &translation_context,
5348 &options_enum,
5350 &override_enum,
5352 &tags_enum,
5353 &poll_fn,
5354 &update_fn))
5355 {
5356 return nullptr;
5357 }
5358
5359 ptype = pointer_type_from_py(type, "PointerProperty(...)");
5360 if (!ptype) {
5361 return nullptr;
5362 }
5363 if (!RNA_struct_is_a(ptype, &RNA_PropertyGroup) && !RNA_struct_is_ID(ptype)) {
5364 PyErr_Format(PyExc_TypeError,
5365 "PointerProperty(...) expected an RNA type derived from %.200s or %.200s",
5366 RNA_struct_ui_name(&RNA_ID),
5368 return nullptr;
5369 }
5370 if (bpy_prop_callback_check(update_fn, "update", 2) == -1) {
5371 return nullptr;
5372 }
5373 if (bpy_prop_callback_check(poll_fn, "poll", 2) == -1) {
5374 return nullptr;
5375 }
5376
5377 if (id_data.prop_free_handle != nullptr) {
5379 }
5381 srna, id_data.value, ptype, name ? name : id_data.value, description);
5382 if (translation_context) {
5383 RNA_def_property_translation_context(prop, translation_context);
5384 }
5385
5386 if (tags_enum.base.is_set) {
5387 RNA_def_property_tags(prop, tags_enum.base.value);
5388 }
5389 if (options_enum.is_set) {
5390 bpy_prop_assign_flag(prop, options_enum.value);
5391 }
5392 if (override_enum.is_set) {
5393 bpy_prop_assign_flag_override(prop, override_enum.value);
5394 }
5395
5397 if (RNA_struct_is_a(srna, &RNA_PropertyGroup)) {
5399 }
5400 }
5401 bpy_prop_callback_assign_update(prop, update_fn);
5402 bpy_prop_callback_assign_pointer(prop, poll_fn);
5404
5405 Py_RETURN_NONE;
5406}
5407
5409 /* Wrap. */
5410 BPy_CollectionProperty_doc,
5411 ".. function:: CollectionProperty("
5412 "type, "
5413 "*, "
5414 "name=\"\", "
5415 "description=\"\", "
5416 "translation_context=\"*\", "
5417 "options={'ANIMATABLE'}, "
5418 "override=set(), "
5419 "tags=set())\n"
5420 "\n"
5421 " Returns a new collection property definition.\n"
5425PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
5426{
5427 StructRNA *srna;
5428 { /* Keep this block first. */
5429 PyObject *deferred_result;
5431 self, args, kw, pymeth_CollectionProperty, &deferred_result);
5432 if (srna == nullptr) {
5433 return deferred_result;
5434 }
5435 }
5436
5437 BPy_PropIDParse id_data{};
5438 id_data.srna = srna;
5439
5440 const char *name = nullptr, *description = "";
5441 const char *translation_context = nullptr;
5442 PropertyRNA *prop;
5443 StructRNA *ptype;
5444 PyObject *type = Py_None;
5445
5446 BPy_EnumProperty_Parse options_enum{};
5447 options_enum.items = rna_enum_property_flag_items;
5448 options_enum.value = 0;
5449
5450 BPy_EnumProperty_Parse override_enum{};
5452 override_enum.value = 0;
5453
5455 tags_enum.srna = srna;
5456
5457 static const char *_keywords[] = {
5458 "attr",
5459 "type",
5460 "name",
5461 "description",
5462 "translation_context",
5463 "options",
5464 "override",
5465 "tags",
5466 nullptr,
5467 };
5468 static _PyArg_Parser _parser = {
5470 "O&" /* `attr` */
5471 "O" /* `type` */
5472 "|$" /* Optional, keyword only arguments. */
5473 "s" /* `name` */
5474 "s" /* `description` */
5475 "s" /* `translation_context` */
5476 "O&" /* `options` */
5477 "O&" /* `override` */
5478 "O&" /* `tags` */
5479 ":CollectionProperty",
5480 _keywords,
5481 nullptr,
5482 };
5483 if (!_PyArg_ParseTupleAndKeywordsFast(args,
5484 kw,
5485 &_parser,
5487 &id_data,
5488 &type,
5489 &name,
5490 &description,
5491 &translation_context,
5493 &options_enum,
5495 &override_enum,
5497 &tags_enum))
5498 {
5499 return nullptr;
5500 }
5501
5502 ptype = pointer_type_from_py(type, "CollectionProperty(...):");
5503 if (!ptype) {
5504 return nullptr;
5505 }
5506
5507 if (!RNA_struct_is_a(ptype, &RNA_PropertyGroup)) {
5508 PyErr_Format(PyExc_TypeError,
5509 "CollectionProperty(...) expected an RNA type derived from %.200s",
5511 return nullptr;
5512 }
5513
5514 if (id_data.prop_free_handle != nullptr) {
5516 }
5518 srna, id_data.value, ptype, name ? name : id_data.value, description);
5519 if (translation_context) {
5520 RNA_def_property_translation_context(prop, translation_context);
5521 }
5522
5523 if (tags_enum.base.is_set) {
5524 RNA_def_property_tags(prop, tags_enum.base.value);
5525 }
5526 if (options_enum.is_set) {
5527 bpy_prop_assign_flag(prop, options_enum.value);
5528 }
5529 if (override_enum.is_set) {
5530 bpy_prop_assign_flag_override(prop, override_enum.value);
5531 }
5532
5534 if (RNA_struct_is_a(srna, &RNA_PropertyGroup)) {
5536 }
5537 }
5539
5540 Py_RETURN_NONE;
5541}
5542
5544 /* Wrap. */
5545 BPy_RemoveProperty_doc,
5546 ".. function:: RemoveProperty(cls, attr)\n"
5547 "\n"
5548 " Removes a dynamically defined property.\n"
5549 "\n"
5550 " :arg cls: The class containing the property (must be a positional argument).\n"
5551 " :type cls: type\n"
5552 " :arg attr: Property name (must be passed as a keyword).\n"
5553 " :type attr: str\n"
5554 "\n"
5555 ".. note:: Typically this function doesn't need to be accessed directly.\n"
5556 " Instead use ``del cls.attr``\n");
5557static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw)
5558{
5559 StructRNA *srna;
5560
5561 if (PyTuple_GET_SIZE(args) == 1) {
5562 PyObject *ret;
5563 self = PyTuple_GET_ITEM(args, 0);
5564 args = PyTuple_New(0);
5565 ret = BPy_RemoveProperty(self, args, kw);
5566 Py_DECREF(args);
5567 return ret;
5568 }
5569 if (PyTuple_GET_SIZE(args) > 1) {
5570 PyErr_SetString(PyExc_ValueError, "expected one positional arg, one keyword arg");
5571 return nullptr;
5572 }
5573
5574 srna = srna_from_self(self, "RemoveProperty(...):");
5575 if (srna == nullptr && PyErr_Occurred()) {
5576 return nullptr; /* self's type was compatible but error getting the srna */
5577 }
5578 if (srna == nullptr) {
5579 PyErr_SetString(PyExc_TypeError, "RemoveProperty(): struct rna not available for this type");
5580 return nullptr;
5581 }
5582
5583 const char *id = nullptr;
5584
5585 static const char *_keywords[] = {
5586 "attr",
5587 nullptr,
5588 };
5589 static _PyArg_Parser _parser = {
5591 "s" /* `attr` */
5592 ":RemoveProperty",
5593 _keywords,
5594 nullptr,
5595 };
5596 if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &id)) {
5597 return nullptr;
5598 }
5599
5600 if (RNA_def_property_free_identifier(srna, id) != 1) {
5601 PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property", id);
5602 return nullptr;
5603 }
5604
5605 Py_RETURN_NONE;
5606}
5607
5609
5610/* -------------------------------------------------------------------- */
5613
5614#ifdef __GNUC__
5615# ifdef __clang__
5616# pragma clang diagnostic push
5617# pragma clang diagnostic ignored "-Wcast-function-type"
5618# else
5619# pragma GCC diagnostic push
5620# pragma GCC diagnostic ignored "-Wcast-function-type"
5621# endif
5622#endif
5623
5624static PyMethodDef props_methods[] = {
5625 {"BoolProperty",
5626 (PyCFunction)BPy_BoolProperty,
5627 METH_VARARGS | METH_KEYWORDS,
5628 BPy_BoolProperty_doc},
5629 {"BoolVectorProperty",
5630 (PyCFunction)BPy_BoolVectorProperty,
5631 METH_VARARGS | METH_KEYWORDS,
5632 BPy_BoolVectorProperty_doc},
5633 {"IntProperty",
5634 (PyCFunction)BPy_IntProperty,
5635 METH_VARARGS | METH_KEYWORDS,
5636 BPy_IntProperty_doc},
5637 {"IntVectorProperty",
5638 (PyCFunction)BPy_IntVectorProperty,
5639 METH_VARARGS | METH_KEYWORDS,
5640 BPy_IntVectorProperty_doc},
5641 {"FloatProperty",
5642 (PyCFunction)BPy_FloatProperty,
5643 METH_VARARGS | METH_KEYWORDS,
5644 BPy_FloatProperty_doc},
5645 {"FloatVectorProperty",
5646 (PyCFunction)BPy_FloatVectorProperty,
5647 METH_VARARGS | METH_KEYWORDS,
5648 BPy_FloatVectorProperty_doc},
5649 {"StringProperty",
5650 (PyCFunction)BPy_StringProperty,
5651 METH_VARARGS | METH_KEYWORDS,
5652 BPy_StringProperty_doc},
5653 {"EnumProperty",
5654 (PyCFunction)BPy_EnumProperty,
5655 METH_VARARGS | METH_KEYWORDS,
5656 BPy_EnumProperty_doc},
5657 {"PointerProperty",
5658 (PyCFunction)BPy_PointerProperty,
5659 METH_VARARGS | METH_KEYWORDS,
5660 BPy_PointerProperty_doc},
5661 {"CollectionProperty",
5662 (PyCFunction)BPy_CollectionProperty,
5663 METH_VARARGS | METH_KEYWORDS,
5664 BPy_CollectionProperty_doc},
5665
5666 {"RemoveProperty",
5667 (PyCFunction)BPy_RemoveProperty,
5668 METH_VARARGS | METH_KEYWORDS,
5669 BPy_RemoveProperty_doc},
5670 {nullptr, nullptr, 0, nullptr},
5671};
5672
5673#ifdef __GNUC__
5674# ifdef __clang__
5675# pragma clang diagnostic pop
5676# else
5677# pragma GCC diagnostic pop
5678# endif
5679#endif
5680
5681static int props_visit(PyObject * /*self*/, visitproc visit, void *arg)
5682{
5684 PyObject **py_data = (PyObject **)&prop_store->py_data;
5685 for (int i = 0; i < BPY_PROP_STORE_PY_DATA_SIZE; i++) {
5686 Py_VISIT(py_data[i]);
5687 }
5688 }
5689 return 0;
5690}
5691
5692static int props_clear(PyObject * /*self*/)
5693{
5695 PyObject **py_data = (PyObject **)&prop_store->py_data;
5696 for (int i = 0; i < BPY_PROP_STORE_PY_DATA_SIZE; i++) {
5697 Py_CLEAR(py_data[i]);
5698 }
5699 }
5700 return 0;
5701}
5702
5704 /* Wrap. */
5705 props_module_doc,
5706 "This module defines properties to extend Blender's internal data. The result of these "
5707 "functions"
5708 " is used to assign properties to classes registered with Blender and can't be used "
5709 "directly.\n"
5710 "\n"
5711 ".. note:: All parameters to these functions must be passed as keywords.\n");
5712static PyModuleDef props_module = {
5713 /*m_base*/ PyModuleDef_HEAD_INIT,
5714 /*m_name*/ "bpy.props",
5715 /*m_doc*/ props_module_doc,
5716 /*m_size*/ -1, /* multiple "initialization" just copies the module dict. */
5717 /*m_methods*/ props_methods,
5718 /*m_slots*/ nullptr,
5719 /*m_traverse*/ props_visit,
5720 /*m_clear*/ props_clear,
5721 /*m_free*/ nullptr,
5722};
5723
5724PyObject *BPY_rna_props()
5725{
5726 PyObject *submodule;
5727 PyObject *submodule_dict;
5728
5729 submodule = PyModule_Create(&props_module);
5730 PyDict_SetItemString(PyImport_GetModuleDict(), props_module.m_name, submodule);
5731
5732 /* API needs the PyObjects internally. */
5733 submodule_dict = PyModule_GetDict(submodule);
5734
5735#define ASSIGN_STATIC(_name) pymeth_##_name = PyDict_GetItemString(submodule_dict, #_name)
5736
5737 ASSIGN_STATIC(BoolProperty);
5738 ASSIGN_STATIC(BoolVectorProperty);
5739 ASSIGN_STATIC(IntProperty);
5740 ASSIGN_STATIC(IntVectorProperty);
5741 ASSIGN_STATIC(FloatProperty);
5742 ASSIGN_STATIC(FloatVectorProperty);
5743 ASSIGN_STATIC(StringProperty);
5744 ASSIGN_STATIC(EnumProperty);
5745 ASSIGN_STATIC(PointerProperty);
5746 ASSIGN_STATIC(CollectionProperty);
5747 ASSIGN_STATIC(RemoveProperty);
5748
5749 if (PyType_Ready(&bpy_prop_deferred_Type) < 0) {
5750 return nullptr;
5751 }
5752 PyModule_AddType(submodule, &bpy_prop_deferred_Type);
5753
5754 /* Run this when properties are freed. */
5756
5757 return submodule;
5758}
5759
5761{
5762 /* Remove all user counts, so this isn't considered a leak from Python's perspective. */
5763 props_clear(nullptr);
5764
5765 /* Running is harmless, but redundant. */
5767
5768 /* Include as it's correct, in practice this should never be used again. */
5770}
5771
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
unsigned int uint
#define STRINGIFY(x)
#define UNLIKELY(x)
#define STREQ(a, b)
ID and Library types, which are fundamental for SDNA.
#define MAX_IDPROP_NAME
Definition DNA_ID.h:186
Read Guarded memory(de)allocation.
int RNA_def_property_free_identifier(StructOrFunctionRNA *cont_, const char *identifier)
void RNA_def_property_duplicate_pointers(StructOrFunctionRNA *cont_, PropertyRNA *prop)
void RNA_def_property_free_pointers_set_py_data_callback(void(*py_data_clear_fn)(PropertyRNA *prop))
void RNA_def_property_free_identifier_deferred_finish(StructOrFunctionRNA *cont_, void *handle)
int RNA_def_property_free_identifier_deferred_prepare(StructOrFunctionRNA *cont_, const char *identifier, void **handle)
#define RNA_MAX_ARRAY_DIMENSION
Definition RNA_define.hh:27
int(*)(PointerRNA *ptr, PropertyRNA *prop) EnumPropertyGetFunc
Definition RNA_types.hh:821
void(*)(PointerRNA *ptr, PropertyRNA *prop, const std::string &value) StringPropertySetFunc
Definition RNA_types.hh:756
void(*)(PointerRNA *ptr, PropertyRNA *prop, const float *new_values, const float *curr_values, bool is_set, float *r_values) FloatArrayPropertySetTransformFunc
Definition RNA_types.hh:745
float(*)(PointerRNA *ptr, PropertyRNA *prop, float value, bool is_set) FloatPropertyGetTransformFunc
Definition RNA_types.hh:733
int(*)(PointerRNA *ptr, PropertyRNA *prop) StringPropertyLengthFunc
Definition RNA_types.hh:755
@ STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES
Definition RNA_types.hh:972
void(*)(PointerRNA *ptr, PropertyRNA *prop, const int *new_values, const int *curr_values, bool is_set, int *r_values) IntArrayPropertySetTransformFunc
Definition RNA_types.hh:722
void(*)(PointerRNA *ptr, PropertyRNA *prop, const bool *r_values) BooleanArrayPropertySetFunc
Definition RNA_types.hh:698
const EnumPropertyItem *(*)(bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free) EnumPropertyItemFunc
Definition RNA_types.hh:830
int(*)(PointerRNA *ptr, PropertyRNA *prop, int value, bool is_set) EnumPropertyGetTransformFunc
Definition RNA_types.hh:823
void(*)(PointerRNA *ptr, PropertyRNA *prop, float *values) FloatArrayPropertyGetFunc
Definition RNA_types.hh:739
int(*)(PointerRNA *ptr, PropertyRNA *prop, int value, bool is_set) IntPropertyGetTransformFunc
Definition RNA_types.hh:712
void(*)(PointerRNA *ptr, PropertyRNA *prop, bool *r_values) BooleanArrayPropertyGetFunc
Definition RNA_types.hh:697
#define RNA_ENUM_BITFLAG_SIZE
Definition RNA_types.hh:222
void(*)(PointerRNA *ptr, PropertyRNA *prop, const bool *new_values, const bool *curr_values, bool is_set, bool *r_values) BooleanArrayPropertySetTransformFunc
Definition RNA_types.hh:703
eStringPropertySearchFlag
Definition RNA_types.hh:778
@ PROP_STRING_SEARCH_SUGGESTION
Definition RNA_types.hh:792
void(*)(PointerRNA *ptr, PropertyRNA *prop, int *values) IntArrayPropertyGetFunc
Definition RNA_types.hh:718
void(*)( PointerRNA *ptr, PropertyRNA *prop, const bool *curr_values, bool is_set, bool *r_values) BooleanArrayPropertyGetTransformFunc
Definition RNA_types.hh:701
void(*)(PointerRNA *ptr, PropertyRNA *prop, int value) EnumPropertySetFunc
Definition RNA_types.hh:822
std::string(*)(PointerRNA *ptr, PropertyRNA *prop) StringPropertyGetFunc
Definition RNA_types.hh:754
void(*)(PointerRNA *ptr, PropertyRNA *prop, const int *values) IntArrayPropertySetFunc
Definition RNA_types.hh:719
@ PROP_FLOAT
Definition RNA_types.hh:164
@ PROP_BOOLEAN
Definition RNA_types.hh:162
@ PROP_INT
Definition RNA_types.hh:163
@ PROP_STRING
Definition RNA_types.hh:165
void(*)( PointerRNA *ptr, PropertyRNA *prop, const float *curr_values, bool is_set, float *r_values) FloatArrayPropertyGetTransformFunc
Definition RNA_types.hh:743
std::string(*)(PointerRNA *ptr, PropertyRNA *prop, const std::string &value, bool is_set) StringPropertyGetTransformFunc
Definition RNA_types.hh:759
bool(*)(PointerRNA *ptr, PropertyRNA *prop) BooleanPropertyGetFunc
Definition RNA_types.hh:688
void(*)(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *edit_text, blender::FunctionRef< void(StringPropertySearchVisitParams)> visit_fn) StringPropertySearchFunc
Definition RNA_types.hh:806
@ PROP_UNIT_NONE
Definition RNA_types.hh:173
bool(*)(PointerRNA *ptr, PropertyRNA *prop, bool value, bool is_set) BooleanPropertyGetTransformFunc
Definition RNA_types.hh:690
int(*)(PointerRNA *ptr, PropertyRNA *prop, int new_value, int curr_value, bool is_set) IntPropertySetTransformFunc
Definition RNA_types.hh:716
float(*)(PointerRNA *ptr, PropertyRNA *prop) FloatPropertyGetFunc
Definition RNA_types.hh:731
int(*)(PointerRNA *ptr, PropertyRNA *prop) IntPropertyGetFunc
Definition RNA_types.hh:710
void(*)( PointerRNA *ptr, PropertyRNA *prop, const int *curr_values, bool is_set, int *r_values) IntArrayPropertyGetTransformFunc
Definition RNA_types.hh:720
float(*)(PointerRNA *ptr, PropertyRNA *prop, float new_value, float curr_value, bool is_set) FloatPropertySetTransformFunc
Definition RNA_types.hh:737
void(*)(PointerRNA *ptr, PropertyRNA *prop, float value) FloatPropertySetFunc
Definition RNA_types.hh:732
PropertyOverrideFlag
Definition RNA_types.hh:501
bool(*)(PointerRNA *ptr, PropertyRNA *prop, bool new_value, bool curr_value, bool is_set) BooleanPropertySetTransformFunc
Definition RNA_types.hh:694
int(*)(PointerRNA *ptr, PropertyRNA *prop, int new_value, int curr_value, bool is_set) EnumPropertySetTransformFunc
Definition RNA_types.hh:827
void(*)(PointerRNA *ptr, PropertyRNA *prop, int value) IntPropertySetFunc
Definition RNA_types.hh:711
std::string(*)(PointerRNA *ptr, PropertyRNA *prop, const std::string &new_value, const std::string &curr_value, bool is_set) StringPropertySetTransformFunc
Definition RNA_types.hh:763
void(*)(PointerRNA *ptr, PropertyRNA *prop, const float *values) FloatArrayPropertySetFunc
Definition RNA_types.hh:740
PropertyFlag
Definition RNA_types.hh:300
@ PROP_ANIMATABLE
Definition RNA_types.hh:319
@ PROP_EDITABLE
Definition RNA_types.hh:306
@ PROP_ENUM_FLAG
Definition RNA_types.hh:404
void(*)(PointerRNA *ptr, PropertyRNA *prop, bool value) BooleanPropertySetFunc
Definition RNA_types.hh:689
@ PROP_MATRIX
Definition RNA_types.hh:265
@ PROP_NONE
Definition RNA_types.hh:233
#define C
Definition RandGen.cpp:29
void bpy_context_clear(struct bContext *C, const PyGILState_STATE *gilstate)
void bpy_context_set(struct bContext *C, PyGILState_STATE *gilstate)
PyObject * self
static std::string bpy_prop_string_get_transform_locked_fn(PointerRNA *ptr, PropertyRNA *prop, const std::string &curr_value, bool is_set)
#define BPY_PROPDEF_SUBTYPE_STRING_DOC
Definition bpy_props.cc:72
static void bpy_prop_string_visit_for_search_fn(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *edit_text, blender::FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
PyDoc_STRVAR(bpy_prop_deferred_doc, "Intermediate storage for properties before registration.\n" "\n" ".. note::\n" "\n" " This is not part of the stable API and may change between releases.\n")
static PyObject * pymeth_FloatProperty
Definition bpy_props.cc:388
static bool bpy_prop_string_visit_fn_call(PyObject *py_func, PyObject *item, blender::FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
static void bpy_prop_string_set_fn(PointerRNA *ptr, PropertyRNA *prop, const std::string &value)
static void bpy_prop_boolean_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const bool *values)
static PyObject * BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
#define ASSIGN_PYOBJECT_INCREF(a, b)
Definition bpy_props.cc:181
static void bpy_prop_array_matrix_swap_row_column_vn_vn(float *values_dst, const float *values_src, const BPyPropArrayLength *array_len_info)
Definition bpy_props.cc:653
static PyObject * BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
static PyModuleDef props_module
static bool bpy_prop_pointer_poll_fn(PointerRNA *self, PointerRNA candidate, PropertyRNA *prop)
static void bpy_prop_callback_assign_int_array(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn, PyObject *get_transform_fn, PyObject *set_transform_fn)
#define BPY_PROPDEF_OPTIONS_OVERRIDE_COLLECTION_DOC
Definition bpy_props.cc:68
static PyObject * bpy_py_object_from_prop_array_with_dims(const void *values, const BPyPropArrayLength &array_len_info, const PyTypeObject &type)
Definition bpy_props.cc:591
static bool py_long_as_int(PyObject *py_long, int *r_int)
static std::string bpy_prop_string_set_transform_fn(PointerRNA *ptr, PropertyRNA *prop, const std::string &new_value, const std::string &curr_value, bool is_set)
PyObject * BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
static bool bpy_prop_array_is_matrix_compatible_ex(int subtype, const BPyPropArrayLength *array_len_info)
Definition bpy_props.cc:635
static std::string bpy_prop_string_get_locked_fn(PointerRNA *ptr, PropertyRNA *prop)
static float bpy_prop_float_get_fn(PointerRNA *ptr, PropertyRNA *prop)
static int bpy_prop_int_get_transform_fn(PointerRNA *ptr, PropertyRNA *prop, int curr_value, bool is_set)
static bool bpy_prop_callback_assign_string(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn, PyObject *get_transform_fn, PyObject *set_transform_fn, PyObject *search_fn, const eStringPropertySearchFlag search_flag)
#define BPY_PROPDEF_NAME_DOC
static int bpy_prop_int_get_fn(PointerRNA *ptr, PropertyRNA *prop)
static PyGetSetDef bpy_prop_deferred_getset[]
Definition bpy_props.cc:295
static int bpy_prop_int_set_transform_fn(PointerRNA *ptr, PropertyRNA *prop, int new_value, int curr_value, bool is_set)
#define BPY_PROPDEF_FLOAT_STEP_DOC
static PyObject * pymeth_IntVectorProperty
Definition bpy_props.cc:387
static void bpy_prop_boolean_array_set_transform_fn(PointerRNA *ptr, PropertyRNA *prop, const bool *new_values, const bool *curr_values, bool is_set, bool *r_final_values)
#define BPY_PROPDEF_UPDATE_DOC
static float bpy_prop_float_set_transform_fn(PointerRNA *ptr, PropertyRNA *prop, float new_value, float curr_value, bool is_set)
static bool bpy_prop_array_is_matrix_compatible(PropertyRNA *prop, const BPyPropArrayLength *array_len_info)
Definition bpy_props.cc:643
static void bpy_prop_boolean_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, bool *values)
Definition bpy_props.cc:950
static int bpy_prop_string_length_fn(PointerRNA *ptr, PropertyRNA *prop)
static PyObject * pymeth_EnumProperty
Definition bpy_props.cc:391
static bool bpy_prop_callback_assign_boolean(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn, PyObject *get_transform_fn, PyObject *set_transform_fn)
#define BPY_PROPDEF_NUM_SOFT_MINMAX_DOC(ty)
static float bpy_prop_float_get_transform_fn(PointerRNA *ptr, PropertyRNA *prop, float curr_value, bool is_set)
static std::optional< std::string > bpy_prop_string_from_callback_or_error(PyObject *str_obj, const size_t max_length, PyObject *py_func)
static PyObject * bpy_prop_deferred_keywords_get(BPy_PropDeferred *self, void *)
Definition bpy_props.cc:288
static int bpy_prop_deferred_clear(BPy_PropDeferred *self)
Definition bpy_props.cc:246
static void bpy_prop_callback_assign_float_array(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn, PyObject *get_transform_fn, PyObject *set_transform_fn)
static void bpy_prop_py_data_remove(PropertyRNA *prop)
Definition bpy_props.cc:209
static void bpy_prop_int_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, int *values)
#define BPY_PROPDEF_FLOAT_PREC_DOC
static void bpy_prop_float_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const float *values)
#define BPY_PROPDEF_POLL_DOC
#define BPY_PROPDEF_NUM_MINMAX_DOC(ty)
static bool bpy_prop_callback_assign_enum(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn, PyObject *itemf_fn, PyObject *get_transform_fn, PyObject *set_transform_fn)
static PyObject * BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
static std::string bpy_prop_string_get_fn(PointerRNA *ptr, PropertyRNA *prop)
static PyObject * pymeth_FloatVectorProperty
Definition bpy_props.cc:389
static PyObject * BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
PyObject * BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
static void bpy_prop_int_set_fn(PointerRNA *ptr, PropertyRNA *prop, int value)
static PyObject * pymeth_IntProperty
Definition bpy_props.cc:386
static int bpy_prop_enum_set_transform_fn(PointerRNA *ptr, PropertyRNA *prop, int new_value, int curr_value, bool is_set)
static bool bpy_prop_boolean_get_transform_fn(PointerRNA *ptr, PropertyRNA *prop, bool curr_value, bool is_set)
Definition bpy_props.cc:785
#define BPY_PROPDEF_SET_DOC(ty)
static void bpy_prop_int_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const int *values)
static int bpy_prop_enum_get_transform_fn(PointerRNA *ptr, PropertyRNA *prop, int curr_value, bool is_set)
static void bpy_prop_int_array_set_transform_fn(PointerRNA *ptr, PropertyRNA *prop, const int *new_values, const int *curr_values, bool is_set, int *r_final_values)
#define BPY_PROPDEF_POINTER_TYPE_DOC
PyObject * BPY_rna_props()
static PyMethodDef props_methods[]
static bool bpy_prop_boolean_set_transform_fn(PointerRNA *ptr, PropertyRNA *prop, bool new_value, bool curr_value, bool is_set)
Definition bpy_props.cc:869
static void bpy_prop_float_array_set_transform_fn(PointerRNA *ptr, PropertyRNA *prop, const float *new_values, const float *curr_values, bool is_set, float *r_final_values)
static void bpy_prop_callback_assign_pointer(PropertyRNA *prop, PyObject *poll_fn)
static PyObject * pyrna_struct_as_instance(PointerRNA *ptr)
Definition bpy_props.cc:396
static bool bpy_prop_callback_assign_float(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn, PyObject *get_transform_fn, PyObject *set_transform_fn)
static PyObject * BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
static bool bpy_prop_callback_assign_boolean_array(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn, PyObject *get_transform_fn, PyObject *set_transform_fn)
static PyObject * bpy_prop_deferred_function_get(BPy_PropDeferred *self, void *)
Definition bpy_props.cc:277
static void bpy_prop_deferred_dealloc(BPy_PropDeferred *self)
Definition bpy_props.cc:233
#define BPY_PROPDEF_GET_TRANSFORM_DOC(ty)
static int props_clear(PyObject *)
static void bpy_prop_boolean_set_fn(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition bpy_props.cc:832
static void bpy_prop_float_array_get_transform_fn(PointerRNA *ptr, PropertyRNA *prop, const float *curr_values, bool is_set, float *r_values)
void BPY_rna_props_clear_all()
static PyObject * pymeth_RemoveProperty
Definition bpy_props.cc:394
static void bpy_prop_enum_set_fn(PointerRNA *ptr, PropertyRNA *prop, int value)
static int icon_id_from_name(const char *name)
static PyObject * pymeth_CollectionProperty
Definition bpy_props.cc:393
static void bpy_prop_int_array_get_transform_fn(PointerRNA *ptr, PropertyRNA *prop, const int *curr_values, bool is_set, int *r_values)
static void bpy_prop_boolean_array_from_callback_or_error(PyObject *bool_array_obj, const BPyPropArrayLength &array_len_info, PyObject *py_func, bool *r_values)
Definition bpy_props.cc:918
static const EnumPropertyItem * enum_items_from_py(PyObject *seq_fast, const bool is_enum_flag, PyObject *default_py, int *r_default_value)
static PyObject * BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
static PyObject * BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
#define BPY_PROPDEF_CTXT_DOC
#define BPY_PROPDEF_COLLECTION_TYPE_DOC
#define BPY_PROPDEF_TAGS_DOC
static int bpy_prop_deferred_traverse(BPy_PropDeferred *self, visitproc visit, void *arg)
Definition bpy_props.cc:240
#define BPY_PROP_STORE_PY_DATA_SIZE
Definition bpy_props.cc:179
static int bpy_prop_array_length_parse(PyObject *o, void *p)
Definition bpy_props.cc:506
static void bpy_prop_float_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, float *values)
static bool bpy_prop_callback_assign_int(PropertyRNA *prop, PyObject *get_fn, PyObject *set_fn, PyObject *get_transform_fn, PyObject *set_transform_fn)
static void bpy_prop_int_array_from_callback_or_error(PyObject *int_array_obj, const BPyPropArrayLength &array_len_info, PyObject *py_func, int *r_values)
static PyObject * pymeth_PointerProperty
Definition bpy_props.cc:392
#define BPY_PROPDEF_OPTIONS_DOC
Definition bpy_props.cc:56
static int bpy_prop_arg_parse_id(PyObject *o, void *p)
static int bpy_prop_array_from_py_with_dims(void *values, size_t values_elem_size, PyObject *py_values, const BPyPropArrayLength *array_len_info, const PyTypeObject *type, const char *error_str)
Definition bpy_props.cc:574
static void bpy_prop_gil_rna_writable_end(const BPyPropGIL_RNAWritable_State &prop_state)
Definition bpy_props.cc:462
static bool bpy_prop_boolean_get_fn(PointerRNA *ptr, PropertyRNA *prop)
Definition bpy_props.cc:739
#define BPY_PROPDEF_GET_DOC(ty)
#define BPY_PROPDEF_SET_TRANSFORM_DOC(ty)
static void bpy_prop_float_set_fn(PointerRNA *ptr, PropertyRNA *prop, float value)
static std::string bpy_prop_string_get_transform_fn(PointerRNA *ptr, PropertyRNA *prop, const std::string &curr_value, bool is_set)
static BPyPropStore * bpy_prop_py_data_ensure(PropertyRNA *prop)
Definition bpy_props.cc:195
static StructRNA * bpy_prop_deferred_data_or_srna(PyObject *self, PyObject *args, PyObject *kw, PyObject *method_object, PyObject **r_deferred_result)
#define BPY_PROPDEF_SEARCH_DOC
static void bpy_prop_float_array_from_callback_or_error(PropertyRNA *prop, PyObject *float_array_obj, const BPyPropArrayLength &array_len_info, PyObject *py_func, const bool do_matrix_row_col_swap, float *r_values)
StructRNA * pointer_type_from_py(PyObject *value, const char *error_prefix)
static PyObject * bpy_prop_deferred_data_CreatePyObject(PyObject *fn, PyObject *kw)
Definition bpy_props.cc:361
static int bpy_prop_enum_get_fn(PointerRNA *ptr, PropertyRNA *prop)
static const EnumPropertyItem * bpy_prop_enum_itemf_fn(bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free)
static PyObject * pymeth_BoolProperty
Definition bpy_props.cc:384
static void bpy_prop_array_matrix_swap_row_column_vn(float *values, const BPyPropArrayLength *array_len_info)
Definition bpy_props.cc:667
static void bpy_prop_boolean_array_get_transform_fn(PointerRNA *ptr, PropertyRNA *prop, const bool *curr_values, bool is_set, bool *r_values)
Definition bpy_props.cc:978
static BPyPropGIL_RNAWritable_State bpy_prop_gil_rna_writable_begin()
Definition bpy_props.cc:451
#define BPY_PROPDEF_OPTIONS_ENUM_DOC
Definition bpy_props.cc:60
static int bpy_prop_arg_parse_tag_defines(PyObject *o, void *p)
static void bpy_prop_update_fn(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition bpy_props.cc:686
static void bpy_prop_callback_assign_update(PropertyRNA *prop, PyObject *update_fn)
#define BPY_PROPDEF_UNIT_DOC
#define BPY_PROPDEF_SUBTYPE_NUMBER_DOC
Definition bpy_props.cc:76
static PyObject * bpy_prop_deferred_call(BPy_PropDeferred *, PyObject *, PyObject *)
Definition bpy_props.cc:263
static void bpy_prop_assign_flag(PropertyRNA *prop, int flag)
Definition bpy_props.cc:420
static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int argcount)
static PyObject * BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw)
#define ASSIGN_STATIC(_name)
#define BPY_PROPDEF_SUBTYPE_NUMBER_ARRAY_DOC
Definition bpy_props.cc:80
#define BPY_PROPDEF_VECSIZE_DOC
#define BPY_PROPDEF_INT_STEP_DOC
#define BPY_PROPDEF_DESC_DOC
PyTypeObject bpy_prop_deferred_Type
Definition bpy_props.cc:309
static PyObject * pymeth_BoolVectorProperty
Definition bpy_props.cc:385
static PyObject * BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
static ListBase g_bpy_prop_store_list
Definition bpy_props.cc:193
static void bpy_prop_assign_flag_override(PropertyRNA *prop, const int flag_override)
Definition bpy_props.cc:438
#define BPY_PROPDEF_OPTIONS_OVERRIDE_DOC
Definition bpy_props.cc:64
static int props_visit(PyObject *, visitproc visit, void *arg)
static PyObject * bpy_prop_deferred_repr(BPy_PropDeferred *self)
Definition bpy_props.cc:252
static PyObject * pymeth_StringProperty
Definition bpy_props.cc:390
#define PYRNA_STACK_ARRAY
Definition bpy_props.hh:39
bool pyrna_write_check()
Definition bpy_rna.cc:457
StructRNA * srna_from_self(PyObject *self, const char *error_prefix)
Definition bpy_rna.cc:9058
void pyrna_write_set(bool val)
Definition bpy_rna.cc:464
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
Definition bpy_rna.cc:8496
BPy_StructRNA * bpy_context_module
Definition bpy_rna.cc:96
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
const T * data() const
Definition BLI_array.hh:312
void reinitialize(const int64_t new_size)
Definition BLI_array.hh:419
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
float length(VecOp< float, D >) RET
static bool py_long_as_int(PyObject *py_long, int *r_int)
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
int pyrna_enum_bitfield_parse_set(PyObject *o, void *p)
int pyrna_enum_value_parse_string(PyObject *o, void *p)
PyObject * PyC_Tuple_PackArray_Bool(const bool *array, uint len)
PyObject * PyC_Tuple_PackArray_Multi_Bool(const bool *array, const int dims[], const int dims_len)
PyObject * PyC_Tuple_PackArray_I32(const int *array, uint len)
PyObject * PyC_ExceptionBuffer()
int PyC_Long_AsBool(PyObject *value)
int PyC_AsArray(void *array, const size_t array_item_size, PyObject *value, const Py_ssize_t length, const PyTypeObject *type, const char *error_prefix)
PyObject * PyC_Tuple_PackArray_Multi_F32(const float *array, const int dims[], const int dims_len)
int PyC_AsArray_Multi(void *array, const size_t array_item_size, PyObject *value, const int *dims, const int dims_len, const PyTypeObject *type, const char *error_prefix)
void PyC_Err_PrintWithFunc(PyObject *py_func)
PyObject * PyC_Tuple_PackArray_F32(const float *array, uint len)
PyObject * PyC_Tuple_PackArray_Multi_I32(const int *array, const int dims[], const int dims_len)
int PyC_ParseBool(PyObject *o, void *p)
header-only compatibility defines.
Py_DECREF(oname)
#define PY_ARG_PARSER_HEAD_COMPAT()
const char * name
header-only utilities
#define PyTuple_SET_ITEMS(op_arg,...)
return ret
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
bool RNA_struct_is_ID(const StructRNA *type)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
const EnumPropertyItem * RNA_struct_property_tag_defines(const StructRNA *type)
int RNA_property_enum_get_default(PointerRNA *ptr, PropertyRNA *prop)
PropertyType RNA_property_type(PropertyRNA *prop)
void ** RNA_struct_instance(PointerRNA *ptr)
const char * RNA_struct_identifier(const StructRNA *type)
bool RNA_struct_idprops_contains_datablock(const StructRNA *type)
int RNA_property_array_dimension(const PointerRNA *ptr, PropertyRNA *prop, int length[])
void * RNA_property_py_data_get(PropertyRNA *prop)
int RNA_property_flag(PropertyRNA *prop)
const char * RNA_struct_ui_name(const StructRNA *type)
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
int RNA_property_string_maxlength(PropertyRNA *prop)
PropertySubType RNA_property_subtype(PropertyRNA *prop)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc, IntArrayPropertyGetTransformFunc get_transform_fn, IntArrayPropertySetTransformFunc set_transform_fn)
void RNA_def_property_string_search_func_runtime(PropertyRNA *prop, StringPropertySearchFunc search_fn, const eStringPropertySearchFlag search_flag)
void RNA_def_struct_flag(StructRNA *srna, int flag)
PropertyRNA * RNA_def_pointer_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description)
void RNA_def_property_float_default(PropertyRNA *prop, float value)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
void RNA_def_property_boolean_default(PropertyRNA *prop, bool value)
void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[])
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_int_default(PropertyRNA *prop, int value)
void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop, BooleanPropertyGetFunc getfunc, BooleanPropertySetFunc setfunc, BooleanPropertyGetTransformFunc get_transform_fn, BooleanPropertySetTransformFunc set_transform_fn)
void RNA_def_py_data(PropertyRNA *prop, void *py_data)
void RNA_def_property_array(PropertyRNA *prop, int length)
void RNA_def_property_range(PropertyRNA *prop, double min, double max)
void RNA_def_property_poll_runtime(PropertyRNA *prop, const void *func)
void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
void RNA_def_property_update_runtime_with_context_and_property(PropertyRNA *prop, RNAPropertyUpdateFuncWithContextAndProperty func)
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc, FloatArrayPropertyGetTransformFunc get_transform_fn, FloatArrayPropertySetTransformFunc set_transform_fn)
PropertyRNA * RNA_def_collection_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description)
void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc, EnumPropertyGetTransformFunc get_transform_fn, EnumPropertySetTransformFunc set_transform_fn)
PropertyRNA * RNA_def_enum_flag(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_string_funcs_runtime(PropertyRNA *prop, StringPropertyGetFunc getfunc, StringPropertyLengthFunc lengthfunc, StringPropertySetFunc setfunc, StringPropertyGetTransformFunc get_transform_fn, StringPropertySetTransformFunc set_transform_fn)
void RNA_def_property_int_array_default(PropertyRNA *prop, const int *array)
void RNA_def_property_float_funcs_runtime(PropertyRNA *prop, FloatPropertyGetFunc getfunc, FloatPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc, FloatPropertyGetTransformFunc get_transform_fn, FloatPropertySetTransformFunc set_transform_fn)
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
void RNA_def_property_int_funcs_runtime(PropertyRNA *prop, IntPropertyGetFunc getfunc, IntPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc, IntPropertyGetTransformFunc get_transform_fn, IntPropertySetTransformFunc set_transform_fn)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_boolean_array_default(PropertyRNA *prop, const bool *array)
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
void RNA_def_property_tags(PropertyRNA *prop, int tags)
void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop, BooleanArrayPropertyGetFunc getfunc, BooleanArrayPropertySetFunc setfunc, BooleanArrayPropertyGetTransformFunc get_transform_fn, BooleanArrayPropertySetTransformFunc set_transform_fn)
void RNA_def_property_override_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
StructRNA RNA_PropertyGroup
const EnumPropertyItem rna_enum_property_override_flag_collection_items[]
Definition rna_rna.cc:266
const EnumPropertyItem rna_enum_dummy_NULL_items[]
Definition rna_rna.cc:26
const EnumPropertyItem rna_enum_property_subtype_number_array_items[]
Definition rna_rna.cc:119
const EnumPropertyItem rna_enum_property_unit_items[]
Definition rna_rna.cc:141
const EnumPropertyItem rna_enum_property_subtype_number_items[]
Definition rna_rna.cc:112
const EnumPropertyItem rna_enum_property_string_search_flag_items[]
Definition rna_rna.cc:281
const EnumPropertyItem rna_enum_property_override_flag_items[]
Definition rna_rna.cc:261
const EnumPropertyItem rna_enum_property_subtype_string_items[]
Definition rna_rna.cc:105
const EnumPropertyItem rna_enum_property_flag_items[]
Definition rna_rna.cc:186
const EnumPropertyItem rna_enum_property_flag_enum_items[]
Definition rna_rna.cc:230
const EnumPropertyItem rna_enum_icon_items[]
Definition rna_ui_api.cc:26
#define min(a, b)
Definition sort.cc:36
#define FLT_MAX
Definition stdcycles.h:14
bool operator==(const BPyPropArrayLength &other) const
Definition bpy_props.cc:489
BPyPropArrayLength(PointerRNA *ptr, PropertyRNA *prop)
Definition bpy_props.cc:483
BPyPropArrayLength()=default
int dims[RNA_MAX_ARRAY_DIMENSION]
Definition bpy_props.cc:479
PyGILState_STATE gilstate
Definition bpy_props.cc:447
PyObject * get_fn
Definition bpy_props.cc:151
PyObject * update_fn
Definition bpy_props.cc:156
BPyPropStore * next
Definition bpy_props.cc:125
struct BPyPropStore::@011277245316035333236375302160165252076054344031 py_data
struct BPyPropStore::@011277245316035333236375302160165252076054344031::@161001040054361261366031313257143126255124070321::@035000154373154163256114102376000262050350366117 pointer_data
BPyPropStore * prev
Definition bpy_props.cc:125
PyObject * set_transform_fn
Definition bpy_props.cc:154
PyObject * itemf_fn
Definition bpy_props.cc:163
PyObject * poll_fn
Definition bpy_props.cc:168
struct BPyPropStore::@011277245316035333236375302160165252076054344031::@161001040054361261366031313257143126255124070321::@357037322072311333322324224201060265100110237071 string_data
struct BPyPropStore::@011277245316035333236375302160165252076054344031::@161001040054361261366031313257143126255124070321::@153150171102020060327110151332372002250132146302 enum_data
PyObject * get_transform_fn
Definition bpy_props.cc:153
PyObject * set_fn
Definition bpy_props.cc:152
PyObject * search_fn
Definition bpy_props.cc:173
BPy_EnumProperty_Parse base
const EnumPropertyItem * items
void * prop_free_handle
const char * value
StructRNA * srna
const char * identifier
Definition RNA_types.hh:657
const char * name
Definition RNA_types.hh:661
const char * description
Definition RNA_types.hh:663
std::optional< std::string > info
Definition RNA_types.hh:773
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
PointerRNA * ptr
Definition wm_files.cc:4238
uint8_t flag
Definition wm_window.cc:145