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:`bmesh.types.BMLayerCollection` of float\n");
79 bpy_bmlayeraccess_collection__int_doc,
80 "Generic int custom-data layer.\n"
82 ":type: :class:`bmesh.types.BMLayerCollection` of int\n");
85 bpy_bmlayeraccess_collection__bool_doc,
86 "Generic boolean custom-data layer.\n"
88 ":type: :class:`bmesh.types.BMLayerCollection` of boolean\n");
91 bpy_bmlayeraccess_collection__float_vector_doc,
92 "Generic 3D vector with float precision custom-data layer.\n"
95 ":class:`bmesh.types.BMLayerCollection` of :class:`mathutils.Vector`\n");
98 bpy_bmlayeraccess_collection__float_color_doc,
99 "Generic RGBA color with float precision custom-data layer.\n"
102 ":class:`bmesh.types.BMLayerCollection` of :class:`mathutils.Vector`\n");
105 bpy_bmlayeraccess_collection__color_doc,
106 "Generic RGBA color with 8-bit precision custom-data layer.\n"
109 ":class:`bmesh.types.BMLayerCollection` of :class:`mathutils.Vector`\n");
112 bpy_bmlayeraccess_collection__string_doc,
113 "Generic string custom-data layer (exposed as bytes, 255 max length).\n"
116 ":class:`bmesh.types.BMLayerCollection` of bytes\n");
119 bpy_bmlayeraccess_collection__deform_doc,
120 "Vertex deform weight :class:`bmesh.types.BMDeformVert` (TODO).\n"
124 ":class:`bmesh.types.BMLayerCollection` of :class:`bmesh.types.BMDeformVert`");
127 bpy_bmlayeraccess_collection__shape_doc,
128 "Vertex shape-key absolute location (as a 3D Vector).\n"
130 ":type: :class:`bmesh.types.BMLayerCollection` of :class:`mathutils.Vector`\n");
133 bpy_bmlayeraccess_collection__uv_doc,
134 "Accessor for :class:`bmesh.types.BMLoopUV` UV (as a 2D Vector).\n"
136 ":type: :class:`bmesh.types.BMLayerCollection` of :class:`bmesh.types.BMLoopUV`\n");
139 bpy_bmlayeraccess_collection__skin_doc,
140 "Accessor for skin layer.\n"
142 ":type: :class:`bmesh.types.BMLayerCollection` of :class:`bmesh.types.BMVertSkin`\n");
155 bpy_bmlayercollection_active_doc,
156 "The active layer of this type (read-only).\n"
158 ":type: :class:`bmesh.types.BMLayerItem`\n");
178 bpy_bmlayercollection_is_singleton_doc,
179 "True if there can exists only one layer of this type (read-only).\n"
191 bpy_bmlayercollection_name_doc,
192 "The layers unique name (read-only).\n"
203 return PyUnicode_FromString(layer->
name);
213 bpy_bmlayeraccess_collection__deform_doc,
219 bpy_bmlayeraccess_collection__float_doc,
224 bpy_bmlayeraccess_collection__bool_doc,
229 bpy_bmlayeraccess_collection__int_doc,
234 bpy_bmlayeraccess_collection__float_vector_doc,
239 bpy_bmlayeraccess_collection__float_color_doc,
244 bpy_bmlayeraccess_collection__color_doc,
249 bpy_bmlayeraccess_collection__string_doc,
255 bpy_bmlayeraccess_collection__shape_doc,
260 bpy_bmlayeraccess_collection__skin_doc,
263 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
270 bpy_bmlayeraccess_collection__float_doc,
275 bpy_bmlayeraccess_collection__int_doc,
280 bpy_bmlayeraccess_collection__bool_doc,
285 bpy_bmlayeraccess_collection__float_vector_doc,
290 bpy_bmlayeraccess_collection__float_color_doc,
295 bpy_bmlayeraccess_collection__color_doc,
300 bpy_bmlayeraccess_collection__string_doc,
302 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
309 bpy_bmlayeraccess_collection__float_doc,
314 bpy_bmlayeraccess_collection__int_doc,
319 bpy_bmlayeraccess_collection__bool_doc,
324 bpy_bmlayeraccess_collection__float_vector_doc,
329 bpy_bmlayeraccess_collection__float_color_doc,
334 bpy_bmlayeraccess_collection__color_doc,
339 bpy_bmlayeraccess_collection__string_doc,
342 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
349 bpy_bmlayeraccess_collection__float_doc,
354 bpy_bmlayeraccess_collection__int_doc,
359 bpy_bmlayeraccess_collection__bool_doc,
364 bpy_bmlayeraccess_collection__float_vector_doc,
369 bpy_bmlayeraccess_collection__float_color_doc,
374 bpy_bmlayeraccess_collection__string_doc,
379 bpy_bmlayeraccess_collection__uv_doc,
384 bpy_bmlayeraccess_collection__color_doc,
387 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
395 bpy_bmlayercollection_active_doc,
400 bpy_bmlayercollection_is_singleton_doc,
403 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
411 bpy_bmlayercollection_name_doc,
414 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
425 bpy_bmlayeritem_copy_from_doc,
426 ".. method:: copy_from(other)\n"
428 " Return a copy of the layer\n"
430 " :arg other: Another layer to copy from.\n"
431 " :type other: :class:`bmesh.types.BMLayerItem`\n");
434 const char *error_prefix =
"layer.copy_from(...)";
438 PyErr_Format(PyExc_TypeError,
439 "%s: expected BMLayerItem, not '%.200s'",
441 Py_TYPE(value)->tp_name);
449 PyErr_Format(PyExc_ValueError,
"%s: layer type mismatch", error_prefix);
470 bpy_bmlayercollection_verify_doc,
471 ".. method:: verify()\n"
473 " Create a new layer or return an existing active layer\n"
475 " :return: The newly verified layer.\n"
476 " :rtype: :class:`bmesh.types.BMLayerItem`\n");
506 bpy_bmlayercollection_new_doc,
507 ".. method:: new(name)\n"
509 " Create a new layer\n"
511 " :arg name: Optional name argument (will be made unique).\n"
513 " :return: The newly created layer.\n"
514 " :rtype: :class:`bmesh.types.BMLayerItem`\n");
517 const char *
name =
nullptr;
523 if (!PyArg_ParseTuple(args,
"|s:new", &
name)) {
532 PyErr_SetString(PyExc_ValueError,
"layers.new(): is a singleton, use verify() instead");
558 bpy_bmlayercollection_remove_doc,
559 ".. method:: remove(layer)\n"
563 " :arg layer: The layer to remove.\n"
564 " :type layer: :class:`bmesh.types.BMLayerItem`\n");
572 PyErr_Format(PyExc_TypeError,
573 "layers.remove(x): expected BMLayerItem, not '%.200s'",
574 Py_TYPE(value)->tp_name);
581 PyErr_SetString(PyExc_ValueError,
"layers.remove(x): x not in layers");
592 bpy_bmlayercollection_keys_doc,
593 ".. method:: keys()\n"
595 " Return the identifiers of collection members\n"
596 " (matching Python's dict.keys() functionality).\n"
598 " :return: the identifiers for each member of this collection.\n"
599 " :rtype: list[str]\n");
617 ret = PyList_New(tot);
619 for (
i = 0; tot-- > 0; index++) {
620 item = PyUnicode_FromString(
data->layers[index].name);
621 PyList_SET_ITEM(
ret,
i++, item);
629 bpy_bmlayercollection_items_doc,
630 ".. method:: items()\n"
632 " Return the identifiers of collection members\n"
633 " (matching Python's dict.items() functionality).\n"
635 " :return: (key, value) pairs for each member of this collection.\n"
636 " :rtype: list[tuple[str, :class:`bmesh.types.BMLayerItem`]]\n");
651 ret = PyList_New(tot);
653 for (
i = 0; tot-- > 0; index++) {
654 item = PyTuple_New(2);
656 PyUnicode_FromString(
data->layers[index].name),
658 PyList_SET_ITEM(
ret,
i++, item);
666 bpy_bmlayercollection_values_doc,
667 ".. method:: values()\n"
669 " Return the values of collection\n"
670 " (matching Python's dict.values() functionality).\n"
672 " :return: the members of this collection.\n"
673 " :rtype: list[:class:`bmesh.types.BMLayerItem`]\n");
688 ret = PyList_New(tot);
690 for (
i = 0; tot-- > 0; index++) {
692 PyList_SET_ITEM(
ret,
i++, item);
700 bpy_bmlayercollection_get_doc,
701 ".. method:: get(key, default=None)\n"
703 " Returns the value of the layer matching the key or default\n"
704 " when not found (matches Python's dictionary function of the same name).\n"
706 " :arg key: The key associated with the layer.\n"
708 " :arg default: Optional argument for the value to return if\n"
709 " *key* is not found.\n"
710 " :type default: Any\n");
714 PyObject *def = Py_None;
718 if (!PyArg_ParseTuple(args,
"s|O:get", &key, &def)) {
732 return Py_NewRef(def);
737 {
nullptr,
nullptr, 0,
nullptr},
742# pragma clang diagnostic push
743# pragma clang diagnostic ignored "-Wcast-function-type"
745# pragma GCC diagnostic push
746# pragma GCC diagnostic ignored "-Wcast-function-type"
754 bpy_bmlayercollection_verify_doc},
759 bpy_bmlayercollection_remove_doc},
765 bpy_bmlayercollection_values_doc},
769 bpy_bmlayercollection_items_doc},
771 {
nullptr,
nullptr, 0,
nullptr},
776# pragma clang diagnostic pop
778# pragma GCC diagnostic pop
812 PyErr_Format(PyExc_KeyError,
"BMLayerCollection[key]: key \"%.200s\" not found", keyname);
833 PyErr_Format(PyExc_IndexError,
"BMLayerCollection[index]: index %d out of range", keynum);
848 start = std::min(start,
len);
849 stop = std::min(stop,
len);
851 tuple = PyTuple_New(stop - start);
854 PyTuple_SET_ITEM(tuple,
865 if (PyUnicode_Check(key)) {
868 if (PyIndex_Check(key)) {
869 const Py_ssize_t
i = PyNumber_AsSsize_t(key, PyExc_IndexError);
870 if (
i == -1 && PyErr_Occurred()) {
875 if (PySlice_Check(key)) {
876 PySliceObject *key_slice = (PySliceObject *)key;
879 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &
step)) {
883 PyErr_SetString(PyExc_TypeError,
"BMLayerCollection[slice]: slice steps not supported");
886 if (key_slice->start == Py_None && key_slice->stop == Py_None) {
890 Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
893 if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
896 if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
900 if (start < 0 || stop < 0) {
913 if (stop - start <= 0) {
914 return PyTuple_New(0);
920 PyErr_SetString(PyExc_AttributeError,
"BMLayerCollection[key]: invalid key, key must be an int");
926 const char *keyname = PyUnicode_AsUTF8(value);
932 if (keyname ==
nullptr) {
933 PyErr_SetString(PyExc_TypeError,
"BMLayerCollection.__contains__: expected a string");
940 return (index != -1) ? 1 : 0;
960 (objobjargproc)
nullptr,
970 PyObject *iter =
nullptr;
977 iter = PyObject_GetIter(
ret);
986 bpy_bmlayeraccess_type_doc,
987 "Exposes custom-data layer attributes.\n");
990 bpy_bmlayercollection_type_doc,
991 "Gives access to a collection of custom-data layers of the same type and behaves "
992 "like Python dictionaries, "
993 "except for the ability to do list like index access.\n");
996 bpy_bmlayeritem_type_doc,
997 "Exposes a single custom data layer, "
998 "their main purpose is for use as item accessors to custom-data when used with "
999 "vert/edge/face/loop data.\n");
1035 self->htype = htype;
1036 return (PyObject *)
self;
1043 self->htype = htype;
1045 return (PyObject *)
self;
1052 self->htype = htype;
1054 self->index = index;
1055 return (PyObject *)
self;
1142 PyErr_SetString(PyExc_AttributeError,
"BMElem[key]: invalid key, must be a BMLayerItem");
1146 PyErr_SetString(PyExc_ValueError,
"BMElem[layer]: layer is from another mesh");
1150 char namestr_1[32], namestr_2[32];
1151 PyErr_Format(PyExc_ValueError,
1152 "Layer/Element type mismatch, expected %.200s got layer type %.200s",
1165 PyErr_SetString(PyExc_KeyError,
"BMElem[key]: layer not found");
1181 switch (py_layer->
type) {
1187 ret = PyFloat_FromDouble(*(
float *)value);
1191 ret = PyLong_FromLong(*(
int *)value);
1195 ret = PyBool_FromLong(*(
bool *)value);
1208 ret = PyBytes_FromStringAndSize(mstring->
s, mstring->
s_len);
1213 PyErr_SetString(PyExc_ValueError,
"BMElem[layer]: layer is from another mesh");
1232 ret = Py_NotImplemented;
1250 switch (py_layer->
type) {
1256 const float tmp_val = PyFloat_AsDouble(py_value);
1257 if (
UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
1259 PyExc_TypeError,
"expected a float, not a %.200s", Py_TYPE(py_value)->tp_name);
1263 *(
float *)value = tmp_val;
1268 const int tmp_val = PyC_Long_AsI32(py_value);
1269 if (
UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
1274 *(
int *)value = tmp_val;
1285 *(
bool *)value = tmp_val;
1304 Py_ssize_t tmp_val_len;
1305 if (
UNLIKELY(PyBytes_AsStringAndSize(py_value, &tmp_val, &tmp_val_len) == -1)) {
1306 PyErr_Format(PyExc_TypeError,
"expected bytes, not a %.200s", Py_TYPE(py_value)->tp_name);
1310 tmp_val_len = std::min<ulong>(tmp_val_len,
sizeof(mstring->
s));
1311 memcpy(mstring->
s, tmp_val, tmp_val_len);
1312 mstring->
s_len = tmp_val_len;
1318 PyErr_SetString(PyExc_ValueError,
"BMElem[layer]: layer is from another mesh");
1346 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_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)
void BM_uv_map_attr_pin_ensure_for_all_layers(BMesh *bm)
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)
PyDoc_STRVAR(bpy_bmlayeraccess_collection__float_doc, "Generic float custom-data layer.\n" "\n" ":type: :class:`bmesh.types.BMLayerCollection` of float\n")
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 *)
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