38 #include "../generic/py_capi_utils.h"
39 #include "../generic/python_utildefines.h"
40 #include "../mathutils/mathutils.h"
67 if (index_absolute != -1) {
68 return &
data->layers[index_absolute];
71 PyErr_SetString(PyExc_RuntimeError,
"layer has become invalid");
84 "Generic float custom-data layer.\n\ntype: :class:`BMLayerCollection`");
86 "Generic int custom-data layer.\n\ntype: :class:`BMLayerCollection`");
88 "Generic 3D vector with float precision custom-data layer.\n\ntype: "
89 ":class:`BMLayerCollection`");
91 "Generic RGBA color with float precision custom-data layer.\n\ntype: "
92 ":class:`BMLayerCollection`");
94 "Generic RGBA color with 8-bit precision custom-data layer.\n\ntype: "
95 ":class:`BMLayerCollection`");
97 "Generic string custom-data layer (exposed as bytes, 255 max length).\n\ntype: "
98 ":class:`BMLayerCollection`");
100 "Vertex deform weight :class:`BMDeformVert` (TODO).\n\ntype: "
101 ":class:`BMLayerCollection`"
104 bpy_bmlayeraccess_collection__shape_doc,
105 "Vertex shapekey absolute location (as a 3D Vector).\n\n:type: :class:`BMLayerCollection`");
107 "Bevel weight float in [0 - 1].\n\n:type: :class:`BMLayerCollection`");
109 "Edge crease for subdivision surface - float in [0 - 1].\n\n:type: "
110 ":class:`BMLayerCollection`");
112 bpy_bmlayeraccess_collection__uv_doc,
113 "Accessor for :class:`BMLoopUV` UV (as a 2D Vector).\n\ntype: :class:`BMLayerCollection`");
115 "Accessor for skin layer.\n\ntype: :class:`BMLayerCollection`");
117 "Accessor for paint mask layer.\n\ntype: :class:`BMLayerCollection`");
119 "FaceMap custom-data layer.\n\ntype: :class:`BMLayerCollection`");
120 #ifdef WITH_FREESTYLE
121 PyDoc_STRVAR(bpy_bmlayeraccess_collection__freestyle_edge_doc,
122 "Accessor for Freestyle edge layer.\n\ntype: :class:`BMLayerCollection`");
123 PyDoc_STRVAR(bpy_bmlayeraccess_collection__freestyle_face_doc,
124 "Accessor for Freestyle face layer.\n\ntype: :class:`BMLayerCollection`");
137 "The active layer of this type (read-only).\n\n:type: :class:`BMLayerItem`");
156 bpy_bmlayercollection_is_singleton_doc,
157 "True if there can exists only one layer of this type (read-only).\n\n:type: boolean");
166 "The layers unique name (read-only).\n\n:type: string");
175 return PyUnicode_FromString(layer->
name);
185 bpy_bmlayeraccess_collection__deform_doc,
191 bpy_bmlayeraccess_collection__float_doc,
196 bpy_bmlayeraccess_collection__int_doc,
201 bpy_bmlayeraccess_collection__float_vector_doc,
206 bpy_bmlayeraccess_collection__float_color_doc,
211 bpy_bmlayeraccess_collection__color_doc,
216 bpy_bmlayeraccess_collection__string_doc,
222 bpy_bmlayeraccess_collection__shape_doc,
227 bpy_bmlayeraccess_collection__bevel_weight_doc,
232 bpy_bmlayeraccess_collection__skin_doc,
237 bpy_bmlayeraccess_collection__paint_mask_doc,
247 bpy_bmlayeraccess_collection__float_doc,
252 bpy_bmlayeraccess_collection__int_doc,
257 bpy_bmlayeraccess_collection__float_vector_doc,
262 bpy_bmlayeraccess_collection__float_color_doc,
267 bpy_bmlayeraccess_collection__color_doc,
272 bpy_bmlayeraccess_collection__string_doc,
278 bpy_bmlayeraccess_collection__bevel_weight_doc,
283 bpy_bmlayeraccess_collection__crease_doc,
285 #ifdef WITH_FREESTYLE
289 bpy_bmlayeraccess_collection__freestyle_edge_doc,
300 bpy_bmlayeraccess_collection__float_doc,
305 bpy_bmlayeraccess_collection__int_doc,
310 bpy_bmlayeraccess_collection__float_vector_doc,
315 bpy_bmlayeraccess_collection__float_color_doc,
320 bpy_bmlayeraccess_collection__color_doc,
325 bpy_bmlayeraccess_collection__string_doc,
330 bpy_bmlayeraccess_collection__face_map_doc,
333 #ifdef WITH_FREESTYLE
337 bpy_bmlayeraccess_collection__freestyle_face_doc,
348 bpy_bmlayeraccess_collection__float_doc,
353 bpy_bmlayeraccess_collection__int_doc,
358 bpy_bmlayeraccess_collection__float_vector_doc,
363 bpy_bmlayeraccess_collection__float_color_doc,
368 bpy_bmlayeraccess_collection__string_doc,
373 bpy_bmlayeraccess_collection__uv_doc,
378 bpy_bmlayeraccess_collection__color_doc,
389 bpy_bmlayercollection_active_doc,
394 bpy_bmlayercollection_is_singleton_doc,
414 ".. method:: copy_from(other)\n"
416 " Return a copy of the layer\n"
418 " :arg other: Another layer to copy from.\n"
419 " :arg other: :class:`BMLayerItem`\n");
425 PyErr_Format(PyExc_TypeError,
426 "layer.copy_from(x): expected BMLayerItem, not '%.200s'",
427 Py_TYPE(value)->tp_name);
435 PyErr_SetString(PyExc_ValueError,
"layer.copy_from(other): layer type mismatch");
455 ".. method:: verify()\n"
457 " Create a new layer or return an existing active layer\n"
459 " :return: The newly verified layer.\n"
460 " :rtype: :class:`BMLayerItem`\n");
483 ".. method:: new(name)\n"
485 " Create a new layer\n"
487 " :arg name: Optional name argument (will be made unique).\n"
488 " :type name: string\n"
489 " :return: The newly created layer.\n"
490 " :rtype: :class:`BMLayerItem`\n");
493 const char *name =
NULL;
499 if (!PyArg_ParseTuple(args,
"|s:new", &name)) {
506 PyErr_SetString(PyExc_ValueError,
"layers.new(): is a singleton, use verify() instead");
524 ".. method:: remove(layer)\n"
528 " :arg layer: The layer to remove.\n"
529 " :type layer: :class:`BMLayerItem`\n");
537 PyErr_Format(PyExc_TypeError,
538 "layers.remove(x): expected BMLayerItem, not '%.200s'",
539 Py_TYPE(value)->tp_name);
546 PyErr_SetString(PyExc_ValueError,
"layers.remove(x): x not in layers");
556 ".. method:: keys()\n"
558 " Return the identifiers of collection members\n"
559 " (matching pythons dict.keys() functionality).\n"
561 " :return: the identifiers for each member of this collection.\n"
562 " :rtype: list of strings\n");
580 ret = PyList_New(tot);
582 for (i = 0; tot-- > 0; index++) {
583 item = PyUnicode_FromString(
data->layers[index].name);
584 PyList_SET_ITEM(
ret, i++, item);
591 ".. method:: items()\n"
593 " Return the identifiers of collection members\n"
594 " (matching pythons dict.items() functionality).\n"
596 " :return: (key, value) pairs for each member of this collection.\n"
597 " :rtype: list of tuples\n");
612 ret = PyList_New(tot);
614 for (i = 0; tot-- > 0; index++) {
615 item = PyTuple_New(2);
617 PyUnicode_FromString(
data->layers[index].name),
619 PyList_SET_ITEM(
ret, i++, item);
626 ".. method:: values()\n"
628 " Return the values of collection\n"
629 " (matching pythons dict.values() functionality).\n"
631 " :return: the members of this collection.\n"
647 ret = PyList_New(tot);
649 for (i = 0; tot-- > 0; index++) {
651 PyList_SET_ITEM(
ret, i++, item);
658 ".. method:: get(key, default=None)\n"
660 " Returns the value of the layer matching the key or default\n"
661 " when not found (matches pythons dictionary function of the same name).\n"
663 " :arg key: The key associated with the layer.\n"
664 " :type key: string\n"
665 " :arg default: Optional argument for the value to return if\n"
666 " *key* is not found.\n"
667 " :type default: Undefined\n");
671 PyObject *def = Py_None;
675 if (!PyArg_ParseTuple(args,
"s|O:get", &key, &def)) {
689 return Py_INCREF_RET(def);
701 bpy_bmlayercollection_verify_doc},
706 bpy_bmlayercollection_remove_doc},
712 bpy_bmlayercollection_values_doc},
716 bpy_bmlayercollection_items_doc},
750 PyErr_Format(PyExc_KeyError,
"BMLayerCollection[key]: key \"%.200s\" not found", keyname);
770 PyErr_Format(PyExc_IndexError,
"BMLayerCollection[index]: index %d out of range", keynum);
792 tuple = PyTuple_New(stop - start);
795 PyTuple_SET_ITEM(tuple,
806 if (PyUnicode_Check(key)) {
809 if (PyIndex_Check(key)) {
810 const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
811 if (i == -1 && PyErr_Occurred()) {
816 if (PySlice_Check(key)) {
817 PySliceObject *key_slice = (PySliceObject *)key;
820 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
824 PyErr_SetString(PyExc_TypeError,
"BMLayerCollection[slice]: slice steps not supported");
827 if (key_slice->start == Py_None && key_slice->stop == Py_None) {
831 Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
834 if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
837 if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
841 if (start < 0 || stop < 0) {
854 if (stop - start <= 0) {
855 return PyTuple_New(0);
861 PyErr_SetString(PyExc_AttributeError,
"BMLayerCollection[key]: invalid key, key must be an int");
867 const char *keyname = PyUnicode_AsUTF8(value);
873 if (keyname ==
NULL) {
874 PyErr_SetString(PyExc_TypeError,
"BMLayerCollection.__contains__: expected a string");
881 return (index != -1) ? 1 : 0;
891 (ssizeobjargproc)
NULL,
911 PyObject *iter =
NULL;
918 iter = PyObject_GetIter(
ret);
925 PyDoc_STRVAR(bpy_bmlayeraccess_type_doc,
"Exposes custom-data layer attributes.");
928 "Gives access to a collection of custom-data layers of the same type and behaves "
929 "like python dictionaries, "
930 "except for the ability to do list like index access.");
933 "Exposes a single custom data layer, "
934 "their main purpose is for use as item accessors to custom-data when used with "
935 "vert/edge/face/loop data.");
972 return (PyObject *)
self;
981 return (PyObject *)
self;
991 return (PyObject *)
self;
1078 PyErr_SetString(PyExc_AttributeError,
"BMElem[key]: invalid key, must be a BMLayerItem");
1082 PyErr_SetString(PyExc_ValueError,
"BMElem[layer]: layer is from another mesh");
1086 char namestr_1[32], namestr_2[32];
1087 PyErr_Format(PyExc_ValueError,
1088 "Layer/Element type mismatch, expected %.200s got layer type %.200s",
1100 PyErr_SetString(PyExc_KeyError,
"BMElem[key]: layer not found");
1123 switch (py_layer->
type) {
1130 ret = PyFloat_FromDouble(*(
float *)value);
1135 ret = PyLong_FromLong(*(
int *)value);
1148 ret = PyBytes_FromStringAndSize(mstring->
s, mstring->
s_len);
1164 ret = PyFloat_FromDouble(*(
float *)value);
1168 ret = PyFloat_FromDouble(*(
float *)value);
1176 ret = Py_NotImplemented;
1194 switch (py_layer->
type) {
1201 const float tmp_val = PyFloat_AsDouble(py_value);
1202 if (
UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
1204 PyExc_TypeError,
"expected a float, not a %.200s", Py_TYPE(py_value)->tp_name);
1208 *(
float *)value = tmp_val;
1214 const int tmp_val = PyC_Long_AsI32(py_value);
1215 if (
UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
1220 *(
int *)value = tmp_val;
1239 Py_ssize_t tmp_val_len;
1240 if (
UNLIKELY(PyBytes_AsStringAndSize(py_value, &tmp_val, &tmp_val_len) == -1)) {
1241 PyErr_Format(PyExc_TypeError,
"expected bytes, not a %.200s", Py_TYPE(py_value)->tp_name);
1245 if (tmp_val_len >
sizeof(mstring->
s)) {
1246 tmp_val_len =
sizeof(mstring->
s);
1248 memcpy(mstring->
s, tmp_val, tmp_val_len);
1249 mstring->
s_len = tmp_val_len;
1273 const float tmp_val = PyFloat_AsDouble(py_value);
1274 if (
UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
1276 PyExc_TypeError,
"expected a float, not a %.200s", Py_TYPE(py_value)->tp_name);
1280 *(
float *)value =
clamp_f(tmp_val, 0.0f, 1.0f);
1285 const float tmp_val = PyFloat_AsDouble(py_value);
1286 if (
UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
1288 PyExc_TypeError,
"expected a float, not a %.200s", Py_TYPE(py_value)->tp_name);
1292 *(
float *)value =
clamp_f(tmp_val, 0.0f, 1.0f);
1301 PyErr_SetString(PyExc_AttributeError,
"readonly / unsupported type");
CustomData interface, see also DNA_customdata_types.h.
int CustomData_number_of_layers(const struct CustomData *data, int type)
bool CustomData_has_layer(const struct CustomData *data, int type)
bool CustomData_layertype_is_singleton(int type)
int CustomData_get_named_layer_index(const struct CustomData *data, int type, const char *name)
int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
int CustomData_get_active_layer(const struct CustomData *data, int type)
int CustomData_get_layer_index(const struct CustomData *data, int type)
int CustomData_get_named_layer(const struct CustomData *data, int type, const char *name)
void * CustomData_bmesh_get_n(const struct CustomData *data, void *block, int type, int n)
#define BLI_assert_unreachable()
MINLINE float clamp_f(float value, float min, float max)
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define POINTER_AS_INT(i)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
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(BMesh *bm, CustomData *data, int type)
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name)
ATTR_WARN_UNUSED_RESULT BMesh * bm
char * BPy_BMElem_StringFromHType_ex(const char htype, char ret[32])
#define BPY_BM_CHECK_OBJ(obj)
#define BPY_BM_CHECK_SOURCE_OBJ(bm, errmsg,...)
#define BPY_BM_CHECK_INT(obj)
static PyGetSetDef bpy_bmlayeritem_getseters[]
static PyObject * bpy_bmlayercollection_subscript_int(BPy_BMLayerCollection *self, int keynum)
PyTypeObject BPy_BMLayerCollection_Type
static PyObject * bpy_bmlayercollection_values(BPy_BMLayerCollection *self)
static PyObject * bpy_bmlayercollection_verify(BPy_BMLayerCollection *self)
static PyObject * bpy_bmlayeritem_copy_from(BPy_BMLayerItem *self, BPy_BMLayerItem *value)
static PyObject * bpy_bmlayercollection_keys(BPy_BMLayerCollection *self)
PyObject * BPy_BMLayerCollection_CreatePyObject(BMesh *bm, const char htype, int type)
static PyObject * bpy_bmlayercollection_is_singleton_get(BPy_BMLayerItem *self, void *UNUSED(flag))
PyTypeObject BPy_BMLayerItem_Type
static PyGetSetDef bpy_bmlayercollection_getseters[]
PyObject * BPy_BMLayerAccess_CreatePyObject(BMesh *bm, const char htype)
static PySequenceMethods bpy_bmlayercollection_as_sequence
static PyObject * bpy_bmlayercollection_get(BPy_BMLayerCollection *self, PyObject *args)
PyTypeObject BPy_BMLayerAccessLoop_Type
static struct PyMethodDef bpy_bmlayeritem_methods[]
void BPy_BM_init_types_customdata(void)
PyTypeObject BPy_BMLayerAccessVert_Type
static PyGetSetDef bpy_bmlayeraccess_loop_getseters[]
static PyObject * bpy_bmlayeritem_name_get(BPy_BMLayerItem *self, void *UNUSED(flag))
static int bpy_bmlayercollection_contains(BPy_BMLayerCollection *self, PyObject *value)
static PyObject * bpy_bmlayeraccess_collection_get(BPy_BMLayerAccess *self, void *flag)
static PyGetSetDef bpy_bmlayeraccess_edge_getseters[]
static PyObject * bpy_bmlayercollection_iter(BPy_BMLayerCollection *self)
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)
PyTypeObject BPy_BMLayerAccessFace_Type
static void * bpy_bmlayeritem_ptr_get(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
static PyGetSetDef bpy_bmlayeraccess_face_getseters[]
static PyMappingMethods bpy_bmlayercollection_as_mapping
static CustomDataLayer * bpy_bmlayeritem_get(BPy_BMLayerItem *self)
PyTypeObject BPy_BMLayerAccessEdge_Type
PyObject * BPy_BMLayerItem_CreatePyObject(BMesh *bm, const char htype, int type, int index)
static PyObject * bpy_bmlayercollection_items(BPy_BMLayerCollection *self)
static PyObject * bpy_bmlayercollection_active_get(BPy_BMLayerItem *self, void *UNUSED(flag))
static PyObject * bpy_bmlayercollection_new(BPy_BMLayerCollection *self, PyObject *args)
static PyObject * bpy_bmlayercollection_subscript(BPy_BMLayerCollection *self, PyObject *key)
PyDoc_STRVAR(bpy_bmlayeraccess_collection__float_doc, "Generic float custom-data layer.\n\ntype: :class:`BMLayerCollection`")
static PyObject * bpy_bmlayercollection_subscript_str(BPy_BMLayerCollection *self, const char *keyname)
static PyObject * bpy_bmlayercollection_subscript_slice(BPy_BMLayerCollection *self, Py_ssize_t start, Py_ssize_t stop)
static struct PyMethodDef bpy_bmelemseq_methods[]
static CustomData * bpy_bm_customdata_get(BMesh *bm, char htype)
PyObject * BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
BMElem.__getitem__()
static PyObject * bpy_bmlayercollection_remove(BPy_BMLayerCollection *self, BPy_BMLayerItem *value)
static PyGetSetDef bpy_bmlayeraccess_vert_getseters[]
struct BPy_BMLayerItem BPy_BMLayerItem
#define BPy_BMLayerItem_Check(v)
struct BPy_BMLayerCollection BPy_BMLayerCollection
struct BPy_BMLayerAccess BPy_BMLayerAccess
int BPy_BMLoopColor_AssignPyObject(struct MLoopCol *mloopcol, PyObject *value)
PyObject * BPy_BMLoopColor_CreatePyObject(struct MLoopCol *mloopcol)
int BPy_BMDeformVert_AssignPyObject(struct MDeformVert *dvert, PyObject *value)
int BPy_BMVertSkin_AssignPyObject(struct MVertSkin *mvertskin, PyObject *value)
PyObject * BPy_BMDeformVert_CreatePyObject(struct MDeformVert *dvert)
int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *mloopuv, PyObject *value)
PyObject * BPy_BMLoopUV_CreatePyObject(struct MLoopUV *mloopuv)
PyObject * BPy_BMVertSkin_CreatePyObject(struct MVertSkin *mvertskin)
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
PyObject * Vector_CreatePyObject_wrap(float *vec, const int size, PyTypeObject *base_type)
#define PyTuple_SET_ITEMS(op_arg,...)
PyObject_VAR_HEAD struct BMesh * bm
PyObject_VAR_HEAD struct BMesh * bm