55 if (index_absolute != -1) {
56 return &
data->layers[index_absolute];
59 PyErr_SetString(PyExc_RuntimeError,
"layer has become invalid");
73 bpy_bmlayeraccess_collection__float_doc,
74 "Generic float custom-data layer.\n"
76 ":type: :class:`BMLayerCollection` of float");
79 bpy_bmlayeraccess_collection__int_doc,
80 "Generic int custom-data layer.\n"
82 ":type: :class:`BMLayerCollection` of int");
85 bpy_bmlayeraccess_collection__bool_doc,
86 "Generic boolean custom-data layer.\n"
88 ":type: :class:`BMLayerCollection` of boolean");
91 bpy_bmlayeraccess_collection__float_vector_doc,
92 "Generic 3D vector with float precision custom-data layer.\n"
95 ":class:`BMLayerCollection` of :class:`mathutils.Vector`");
98 bpy_bmlayeraccess_collection__float_color_doc,
99 "Generic RGBA color with float precision custom-data layer.\n"
102 ":class:`BMLayerCollection` of :class:`mathutils.Vector`");
105 bpy_bmlayeraccess_collection__color_doc,
106 "Generic RGBA color with 8-bit precision custom-data layer.\n"
109 ":class:`BMLayerCollection` of :class:`mathutils.Vector`");
112 bpy_bmlayeraccess_collection__string_doc,
113 "Generic string custom-data layer (exposed as bytes, 255 max length).\n"
116 ":class:`BMLayerCollection` of bytes");
119 bpy_bmlayeraccess_collection__deform_doc,
120 "Vertex deform weight :class:`BMDeformVert` (TODO).\n"
123 ":class:`BMLayerCollection` of :class:`bmesh.types.BMDeformVert`"
127 bpy_bmlayeraccess_collection__shape_doc,
128 "Vertex shapekey absolute location (as a 3D Vector).\n"
130 ":type: :class:`BMLayerCollection` of :class:`mathutils.Vector`");
133 bpy_bmlayeraccess_collection__uv_doc,
134 "Accessor for :class:`BMLoopUV` UV (as a 2D Vector).\n"
136 ":type: :class:`BMLayerCollection` of :class:`bmesh.types.BMLoopUV`");
139 bpy_bmlayeraccess_collection__skin_doc,
140 "Accessor for skin layer.\n"
142 ":type: :class:`BMLayerCollection` of :class:`bmesh.types.BMVertSkin`");
146 bpy_bmlayeraccess_collection__freestyle_edge_doc,
147 "Accessor for Freestyle edge layer.\n"
149 ":type: :class:`BMLayerCollection`");
152 bpy_bmlayeraccess_collection__freestyle_face_doc,
153 "Accessor for Freestyle face layer.\n"
155 ":type: :class:`BMLayerCollection`");
169 bpy_bmlayercollection_active_doc,
170 "The active layer of this type (read-only).\n"
172 ":type: :class:`BMLayerItem`");
191 "True if there can exists only one layer of this type (read-only).\n"
203 bpy_bmlayercollection_name_doc,
204 "The layers unique name (read-only).\n"
215 return PyUnicode_FromString(layer->
name);
225 bpy_bmlayeraccess_collection__deform_doc,
231 bpy_bmlayeraccess_collection__float_doc,
236 bpy_bmlayeraccess_collection__bool_doc,
241 bpy_bmlayeraccess_collection__int_doc,
246 bpy_bmlayeraccess_collection__float_vector_doc,
251 bpy_bmlayeraccess_collection__float_color_doc,
256 bpy_bmlayeraccess_collection__color_doc,
261 bpy_bmlayeraccess_collection__string_doc,
267 bpy_bmlayeraccess_collection__shape_doc,
272 bpy_bmlayeraccess_collection__skin_doc,
275 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
282 bpy_bmlayeraccess_collection__float_doc,
287 bpy_bmlayeraccess_collection__int_doc,
292 bpy_bmlayeraccess_collection__bool_doc,
297 bpy_bmlayeraccess_collection__float_vector_doc,
302 bpy_bmlayeraccess_collection__float_color_doc,
307 bpy_bmlayeraccess_collection__color_doc,
312 bpy_bmlayeraccess_collection__string_doc,
318 bpy_bmlayeraccess_collection__freestyle_edge_doc,
321 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
328 bpy_bmlayeraccess_collection__float_doc,
333 bpy_bmlayeraccess_collection__int_doc,
338 bpy_bmlayeraccess_collection__bool_doc,
343 bpy_bmlayeraccess_collection__float_vector_doc,
348 bpy_bmlayeraccess_collection__float_color_doc,
353 bpy_bmlayeraccess_collection__color_doc,
358 bpy_bmlayeraccess_collection__string_doc,
365 bpy_bmlayeraccess_collection__freestyle_face_doc,
369 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
376 bpy_bmlayeraccess_collection__float_doc,
381 bpy_bmlayeraccess_collection__int_doc,
386 bpy_bmlayeraccess_collection__bool_doc,
391 bpy_bmlayeraccess_collection__float_vector_doc,
396 bpy_bmlayeraccess_collection__float_color_doc,
401 bpy_bmlayeraccess_collection__string_doc,
406 bpy_bmlayeraccess_collection__uv_doc,
411 bpy_bmlayeraccess_collection__color_doc,
414 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
422 bpy_bmlayercollection_active_doc,
427 bpy_bmlayercollection_is_singleton_doc,
430 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
438 bpy_bmlayercollection_name_doc,
441 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
452 bpy_bmlayeritem_copy_from_doc,
453 ".. method:: copy_from(other)\n"
455 " Return a copy of the layer\n"
457 " :arg other: Another layer to copy from.\n"
458 " :type other: :class:`BMLayerItem`\n");
464 PyErr_Format(PyExc_TypeError,
465 "layer.copy_from(x): expected BMLayerItem, not '%.200s'",
466 Py_TYPE(value)->tp_name);
474 PyErr_SetString(PyExc_ValueError,
"layer.copy_from(other): layer type mismatch");
495 bpy_bmlayercollection_verify_doc,
496 ".. method:: verify()\n"
498 " Create a new layer or return an existing active layer\n"
500 " :return: The newly verified layer.\n"
501 " :rtype: :class:`BMLayerItem`\n");
531 bpy_bmlayercollection_new_doc,
532 ".. method:: new(name)\n"
534 " Create a new layer\n"
536 " :arg name: Optional name argument (will be made unique).\n"
538 " :return: The newly created layer.\n"
539 " :rtype: :class:`BMLayerItem`\n");
542 const char *name =
nullptr;
548 if (!PyArg_ParseTuple(args,
"|s:new", &name)) {
557 PyErr_SetString(PyExc_ValueError,
"layers.new(): is a singleton, use verify() instead");
583 bpy_bmlayercollection_remove_doc,
584 ".. method:: remove(layer)\n"
588 " :arg layer: The layer to remove.\n"
589 " :type layer: :class:`BMLayerItem`\n");
597 PyErr_Format(PyExc_TypeError,
598 "layers.remove(x): expected BMLayerItem, not '%.200s'",
599 Py_TYPE(value)->tp_name);
606 PyErr_SetString(PyExc_ValueError,
"layers.remove(x): x not in layers");
617 bpy_bmlayercollection_keys_doc,
618 ".. method:: keys()\n"
620 " Return the identifiers of collection members\n"
621 " (matching Python's dict.keys() functionality).\n"
623 " :return: the identifiers for each member of this collection.\n"
624 " :rtype: list[str]\n");
642 ret = PyList_New(tot);
644 for (
i = 0; tot-- > 0; index++) {
645 item = PyUnicode_FromString(
data->layers[index].name);
646 PyList_SET_ITEM(
ret,
i++, item);
654 bpy_bmlayercollection_items_doc,
655 ".. method:: items()\n"
657 " Return the identifiers of collection members\n"
658 " (matching Python's dict.items() functionality).\n"
660 " :return: (key, value) pairs for each member of this collection.\n"
661 " :rtype: list[tuple[str, :class:`BMLayerItem`]]\n");
676 ret = PyList_New(tot);
678 for (
i = 0; tot-- > 0; index++) {
679 item = PyTuple_New(2);
681 PyUnicode_FromString(
data->layers[index].name),
683 PyList_SET_ITEM(
ret,
i++, item);
691 bpy_bmlayercollection_values_doc,
692 ".. method:: values()\n"
694 " Return the values of collection\n"
695 " (matching Python's dict.values() functionality).\n"
697 " :return: the members of this collection.\n"
698 " :rtype: list[:class:`BMLayerItem`]\n");
713 ret = PyList_New(tot);
715 for (
i = 0; tot-- > 0; index++) {
717 PyList_SET_ITEM(
ret,
i++, item);
725 bpy_bmlayercollection_get_doc,
726 ".. method:: get(key, default=None)\n"
728 " Returns the value of the layer matching the key or default\n"
729 " when not found (matches Python's dictionary function of the same name).\n"
731 " :arg key: The key associated with the layer.\n"
733 " :arg default: Optional argument for the value to return if\n"
734 " *key* is not found.\n"
735 " :type default: Any\n");
739 PyObject *def = Py_None;
743 if (!PyArg_ParseTuple(args,
"s|O:get", &key, &def)) {
757 return Py_NewRef(def);
762 {
nullptr,
nullptr, 0,
nullptr},
767# pragma clang diagnostic push
768# pragma clang diagnostic ignored "-Wcast-function-type"
770# pragma GCC diagnostic push
771# pragma GCC diagnostic ignored "-Wcast-function-type"
779 bpy_bmlayercollection_verify_doc},
784 bpy_bmlayercollection_remove_doc},
790 bpy_bmlayercollection_values_doc},
794 bpy_bmlayercollection_items_doc},
796 {
nullptr,
nullptr, 0,
nullptr},
801# pragma clang diagnostic pop
803# pragma GCC diagnostic pop
837 PyErr_Format(PyExc_KeyError,
"BMLayerCollection[key]: key \"%.200s\" not found", keyname);
858 PyErr_Format(PyExc_IndexError,
"BMLayerCollection[index]: index %d out of range", keynum);
873 start = std::min(start,
len);
876 tuple = PyTuple_New(
stop - start);
879 PyTuple_SET_ITEM(tuple,
890 if (PyUnicode_Check(key)) {
893 if (PyIndex_Check(key)) {
894 const Py_ssize_t
i = PyNumber_AsSsize_t(key, PyExc_IndexError);
895 if (
i == -1 && PyErr_Occurred()) {
900 if (PySlice_Check(key)) {
901 PySliceObject *key_slice = (PySliceObject *)key;
904 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &
step)) {
908 PyErr_SetString(PyExc_TypeError,
"BMLayerCollection[slice]: slice steps not supported");
911 if (key_slice->start == Py_None && key_slice->stop == Py_None) {
915 Py_ssize_t start = 0,
stop = PY_SSIZE_T_MAX;
918 if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
921 if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &
stop)) {
925 if (start < 0 ||
stop < 0) {
938 if (
stop - start <= 0) {
939 return PyTuple_New(0);
945 PyErr_SetString(PyExc_AttributeError,
"BMLayerCollection[key]: invalid key, key must be an int");
951 const char *keyname = PyUnicode_AsUTF8(value);
957 if (keyname ==
nullptr) {
958 PyErr_SetString(PyExc_TypeError,
"BMLayerCollection.__contains__: expected a string");
965 return (index != -1) ? 1 : 0;
985 (objobjargproc)
nullptr,
995 PyObject *iter =
nullptr;
1002 iter = PyObject_GetIter(
ret);
1011 bpy_bmlayeraccess_type_doc,
1012 "Exposes custom-data layer attributes.");
1016 bpy_bmlayercollection_type_doc,
1017 "Gives access to a collection of custom-data layers of the same type and behaves "
1018 "like Python dictionaries, "
1019 "except for the ability to do list like index access.");
1023 bpy_bmlayeritem_type_doc,
1024 "Exposes a single custom data layer, "
1025 "their main purpose is for use as item accessors to custom-data when used with "
1026 "vert/edge/face/loop data.");
1062 self->htype = htype;
1063 return (PyObject *)
self;
1070 self->htype = htype;
1072 return (PyObject *)
self;
1079 self->htype = htype;
1081 self->index = index;
1082 return (PyObject *)
self;
1169 PyErr_SetString(PyExc_AttributeError,
"BMElem[key]: invalid key, must be a BMLayerItem");
1173 PyErr_SetString(PyExc_ValueError,
"BMElem[layer]: layer is from another mesh");
1177 char namestr_1[32], namestr_2[32];
1178 PyErr_Format(PyExc_ValueError,
1179 "Layer/Element type mismatch, expected %.200s got layer type %.200s",
1192 PyErr_SetString(PyExc_KeyError,
"BMElem[key]: layer not found");
1208 switch (py_layer->
type) {
1214 ret = PyFloat_FromDouble(*(
float *)value);
1218 ret = PyLong_FromLong(*(
int *)value);
1222 ret = PyBool_FromLong(*(
bool *)value);
1235 ret = PyBytes_FromStringAndSize(mstring->
s, mstring->
s_len);
1240 PyErr_SetString(PyExc_ValueError,
"BMElem[layer]: layer is from another mesh");
1259 ret = Py_NotImplemented;
1277 switch (py_layer->
type) {
1283 const float tmp_val = PyFloat_AsDouble(py_value);
1284 if (
UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
1286 PyExc_TypeError,
"expected a float, not a %.200s", Py_TYPE(py_value)->tp_name);
1290 *(
float *)value = tmp_val;
1295 const int tmp_val = PyC_Long_AsI32(py_value);
1296 if (
UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
1301 *(
int *)value = tmp_val;
1312 *(
bool *)value = tmp_val;
1331 Py_ssize_t tmp_val_len;
1332 if (
UNLIKELY(PyBytes_AsStringAndSize(py_value, &tmp_val, &tmp_val_len) == -1)) {
1333 PyErr_Format(PyExc_TypeError,
"expected bytes, not a %.200s", Py_TYPE(py_value)->tp_name);
1337 tmp_val_len = std::min<ulong>(tmp_val_len,
sizeof(mstring->
s));
1338 memcpy(mstring->
s, tmp_val, tmp_val_len);
1339 mstring->
s_len = tmp_val_len;
1345 PyErr_SetString(PyExc_ValueError,
"BMElem[layer]: layer is from another mesh");
1373 PyErr_SetString(PyExc_AttributeError,
"readonly / unsupported type");
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_layer_index_n(const CustomData *data, eCustomDataType type, int n)
int CustomData_get_named_layer(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_bmesh_get_n(const CustomData *data, void *block, eCustomDataType type, int n)
int CustomData_get_named_layer_index(const CustomData *data, eCustomDataType type, blender::StringRef name)
int CustomData_get_layer_index(const CustomData *data, eCustomDataType type)
int CustomData_get_active_layer(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
bool CustomData_layertype_is_singleton(eCustomDataType type)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
#define BLI_assert_unreachable()
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define POINTER_AS_INT(i)
void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n)
void BM_uv_map_attr_select_and_pin_ensure(BMesh *bm)
void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int dst_n)
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const StringRef name)
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
BMesh const char void * data
char * BPy_BMElem_StringFromHType_ex(const char htype, char ret[32])
static PyMethodDef bpy_bmelemseq_methods[]
#define BPY_BM_CHECK_OBJ(obj)
#define BPY_BM_CHECK_SOURCE_OBJ(bm, errmsg,...)
#define BPY_BM_CHECK_INT(obj)
PyObject * BPy_BMLayerItem_CreatePyObject(BMesh *bm, const char htype, int type, int index)
static PyGetSetDef bpy_bmlayeritem_getseters[]
PyTypeObject BPy_BMLayerCollection_Type
PyObject * BPy_BMLayerAccess_CreatePyObject(BMesh *bm, const char htype)
static PyObject * bpy_bmlayercollection_iter(BPy_BMLayerCollection *self)
static PyObject * bpy_bmlayercollection_subscript_slice(BPy_BMLayerCollection *self, Py_ssize_t start, Py_ssize_t stop)
PyTypeObject BPy_BMLayerItem_Type
static PyGetSetDef bpy_bmlayercollection_getseters[]
static PyObject * bpy_bmlayercollection_keys(BPy_BMLayerCollection *self)
static PySequenceMethods bpy_bmlayercollection_as_sequence
static PyObject * bpy_bmlayercollection_subscript(BPy_BMLayerCollection *self, PyObject *key)
PyTypeObject BPy_BMLayerAccessLoop_Type
PyTypeObject BPy_BMLayerAccessVert_Type
static PyObject * bpy_bmlayercollection_verify(BPy_BMLayerCollection *self)
static PyGetSetDef bpy_bmlayeraccess_loop_getseters[]
static void * bpy_bmlayeritem_ptr_get(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
static int bpy_bmlayercollection_contains(BPy_BMLayerCollection *self, PyObject *value)
static PyGetSetDef bpy_bmlayeraccess_edge_getseters[]
static PyObject * bpy_bmlayercollection_subscript_int(BPy_BMLayerCollection *self, Py_ssize_t keynum)
static Py_ssize_t bpy_bmlayercollection_length(BPy_BMLayerCollection *self)
int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObject *py_value)
static PyObject * bpy_bmlayeritem_copy_from(BPy_BMLayerItem *self, BPy_BMLayerItem *value)
PyTypeObject BPy_BMLayerAccessFace_Type
static PyObject * bpy_bmlayercollection_new(BPy_BMLayerCollection *self, PyObject *args)
static PyObject * bpy_bmlayercollection_is_singleton_get(BPy_BMLayerItem *self, void *)
static PyGetSetDef bpy_bmlayeraccess_face_getseters[]
static PyObject * bpy_bmlayercollection_items(BPy_BMLayerCollection *self)
static PyMappingMethods bpy_bmlayercollection_as_mapping
static PyObject * bpy_bmlayercollection_subscript_str(BPy_BMLayerCollection *self, const char *keyname)
PyTypeObject BPy_BMLayerAccessEdge_Type
static PyObject * bpy_bmlayeraccess_collection_get(BPy_BMLayerAccess *self, void *flag)
static PyObject * bpy_bmlayercollection_values(BPy_BMLayerCollection *self)
static CustomDataLayer * bpy_bmlayeritem_get(BPy_BMLayerItem *self)
static PyObject * bpy_bmlayercollection_get(BPy_BMLayerCollection *self, PyObject *args)
static PyObject * bpy_bmlayeritem_name_get(BPy_BMLayerItem *self, void *)
void BPy_BM_init_types_customdata()
static PyObject * bpy_bmlayercollection_remove(BPy_BMLayerCollection *self, BPy_BMLayerItem *value)
PyObject * BPy_BMLayerCollection_CreatePyObject(BMesh *bm, const char htype, int type)
static PyObject * bpy_bmlayercollection_active_get(BPy_BMLayerItem *self, void *)
PyDoc_STRVAR(bpy_bmlayeraccess_collection__float_doc, "Generic float custom-data layer.\n" "\n" ":type: :class:`BMLayerCollection` of float")
static PyMethodDef bpy_bmlayeritem_methods[]
PyObject * BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
BMElem.__getitem__() / setitem().
static PyGetSetDef bpy_bmlayeraccess_vert_getseters[]
static CustomData * bpy_bm_customdata_get(BMesh *bm, char htype)
#define BPy_BMLayerItem_Check(v)
int BPy_BMVertSkin_AssignPyObject(MVertSkin *mvertskin, PyObject *value)
PyObject * BPy_BMDeformVert_CreatePyObject(MDeformVert *dvert)
int BPy_BMDeformVert_AssignPyObject(MDeformVert *dvert, PyObject *value)
PyObject * BPy_BMLoopColor_CreatePyObject(MLoopCol *mloopcol)
PyObject * BPy_BMLoopUV_CreatePyObject(BMesh *bm, BMLoop *loop, int layer)
int BPy_BMLoopColor_AssignPyObject(MLoopCol *mloopcol, PyObject *value)
int BPy_BMLoopUV_AssignPyObject(BMesh *bm, BMLoop *loop, PyObject *value)
PyObject * BPy_BMVertSkin_CreatePyObject(MVertSkin *mvertskin)
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
PyObject * Vector_CreatePyObject_wrap(float *vec, const int vec_num, PyTypeObject *base_type)
int PyC_Long_AsBool(PyObject *value)
#define PyTuple_SET_ITEMS(op_arg,...)
PyObject_VAR_HEAD BMesh * bm
PyObject_VAR_HEAD BMesh * bm