Blender V5.0
bmesh_py_types_meshdata.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2012 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
19
20#include <Python.h>
21
23
24#include "DNA_meshdata_types.h"
25
26#include "BKE_customdata.hh"
27
28#include "BLI_math_base.h"
29#include "BLI_math_color.h"
30#include "BLI_math_vector.h"
31#include "BLI_utildefines.h"
32
33#include "BKE_deform.hh"
34
35#include "bmesh.hh"
37
40
41/* Mesh Loop UV
42 * ************ */
43
44#define BPy_BMLoopUV_Check(v) (Py_TYPE(v) == &BPy_BMLoopUV_Type)
45
47 PyObject_VAR_HEAD
48 float *uv;
58 bool *pin;
60};
61
63 /* Wrap. */
64 bpy_bmloopuv_uv_doc,
65 "Loops UV (as a 2D Vector).\n"
66 "\n"
67 ":type: :class:`mathutils.Vector`\n");
68static PyObject *bpy_bmloopuv_uv_get(BPy_BMLoopUV *self, void * /*closure*/)
69{
70 return Vector_CreatePyObject_wrap(self->uv, 2, nullptr);
71}
72
73static int bpy_bmloopuv_uv_set(BPy_BMLoopUV *self, PyObject *value, void * /*closure*/)
74{
75 float tvec[2];
76 if (mathutils_array_parse(tvec, 2, 2, value, "BMLoopUV.uv") != -1) {
77 copy_v2_v2(self->uv, tvec);
78 return 0;
79 }
80
81 return -1;
82}
83
85 /* Wrap. */
86 bpy_bmloopuv_pin_uv_doc,
87 "UV pin state.\n"
88 "\n"
89 ":type: bool\n");
90
91static PyObject *bpy_bmloopuv_pin_uv_get(BPy_BMLoopUV *self, void * /*closure*/)
92{
93 /* A non existing pin layer means nothing is currently pinned */
94 return self->pin ? PyBool_FromLong(*self->pin) : nullptr;
95}
96
97static int bpy_bmloopuv_pin_uv_set(BPy_BMLoopUV *self, PyObject *value, void * /*closure*/)
98{
99 /* TODO: if we add lazy allocation of the associated uv map bool layers to BMesh we need
100 * to add a pin layer and update self->pin in the case of self->pin being nullptr.
101 * This isn't easy to do currently as adding CustomData layers to a BMesh invalidates
102 * existing python objects. So for now lazy allocation isn't done and self->pin should
103 * never be nullptr. */
104 BLI_assert(self->pin);
105 if (self->pin) {
106 *self->pin = PyC_Long_AsBool(value);
107 }
108 else {
109 PyErr_SetString(PyExc_RuntimeError,
110 "active uv layer has no associated pin layer. This is a bug!");
111 return -1;
112 }
113 return 0;
114}
115
116static PyGetSetDef bpy_bmloopuv_getseters[] = {
117 /* attributes match rna_def_mloopuv. */
118 {"uv", (getter)bpy_bmloopuv_uv_get, (setter)bpy_bmloopuv_uv_set, bpy_bmloopuv_uv_doc, nullptr},
119 {"pin_uv",
122 bpy_bmloopuv_pin_uv_doc,
123 nullptr},
124 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
125};
126
127PyTypeObject BPy_BMLoopUV_Type; /* bm.loops.layers.uv.active */
128
130{
131 BPy_BMLoopUV_Type.tp_basicsize = sizeof(BPy_BMLoopUV);
132
133 BPy_BMLoopUV_Type.tp_name = "BMLoopUV";
134
135 BPy_BMLoopUV_Type.tp_doc = nullptr; /* todo */
136
138
139 BPy_BMLoopUV_Type.tp_flags = Py_TPFLAGS_DEFAULT;
140
141 PyType_Ready(&BPy_BMLoopUV_Type);
142}
143
144int BPy_BMLoopUV_AssignPyObject(BMesh *bm, BMLoop *loop, PyObject *value)
145{
146 if (UNLIKELY(!BPy_BMLoopUV_Check(value))) {
147 PyErr_Format(PyExc_TypeError, "expected BMLoopUV, not a %.200s", Py_TYPE(value)->tp_name);
148 return -1;
149 }
150
151 BPy_BMLoopUV *src = (BPy_BMLoopUV *)value;
152 const BMUVOffsets offsets = BM_uv_map_offsets_get(bm);
153
154 float *luv = BM_ELEM_CD_GET_FLOAT_P(loop, offsets.uv);
155 copy_v2_v2(luv, src->uv);
156 if (src->pin) {
157 BM_ELEM_CD_SET_BOOL(loop, offsets.pin, *src->pin);
158 }
159 return 0;
160}
161
162PyObject *BPy_BMLoopUV_CreatePyObject(BMesh *bm, BMLoop *loop, int layer)
163{
165
166 const BMUVOffsets offsets = BM_uv_map_offsets_from_layer(bm, layer);
167
168 self->uv = BM_ELEM_CD_GET_FLOAT_P(loop, offsets.uv);
169 self->pin = offsets.pin >= 0 ? BM_ELEM_CD_GET_BOOL_P(loop, offsets.pin) : nullptr;
170
171 return (PyObject *)self;
172}
173
174/* --- End Mesh Loop UV --- */
175
176/* Mesh Vert Skin
177 * ************ */
178
179#define BPy_BMVertSkin_Check(v) (Py_TYPE(v) == &BPy_BMVertSkin_Type)
180
182 PyObject_VAR_HEAD
184};
185
187 /* Wrap. */
188 bpy_bmvertskin_radius_doc,
189 "Vert skin radii (as a 2D Vector).\n"
190 "\n"
191 ":type: :class:`mathutils.Vector`\n");
192static PyObject *bpy_bmvertskin_radius_get(BPy_BMVertSkin *self, void * /*closure*/)
193{
194 return Vector_CreatePyObject_wrap(self->data->radius, 2, nullptr);
195}
196
197static int bpy_bmvertskin_radius_set(BPy_BMVertSkin *self, PyObject *value, void * /*closure*/)
198{
199 float tvec[2];
200 if (mathutils_array_parse(tvec, 2, 2, value, "BMVertSkin.radius") != -1) {
201 copy_v2_v2(self->data->radius, tvec);
202 return 0;
203 }
204
205 return -1;
206}
207
209 /* Wrap. */
210 bpy_bmvertskin_flag__use_root_doc,
211 "Use as root vertex. Setting this flag does not clear other roots in the same mesh island.\n"
212 "\n"
213 ":type: bool\n");
215 /* Wrap. */
216 bpy_bmvertskin_flag__use_loose_doc,
217 "Use loose vertex.\n"
218 "\n"
219 ":type: bool\n");
220
221static PyObject *bpy_bmvertskin_flag_get(BPy_BMVertSkin *self, void *flag_p)
222{
223 const int flag = POINTER_AS_INT(flag_p);
224 return PyBool_FromLong(self->data->flag & flag);
225}
226
227static int bpy_bmvertskin_flag_set(BPy_BMVertSkin *self, PyObject *value, void *flag_p)
228{
229 const int flag = POINTER_AS_INT(flag_p);
230
231 switch (PyC_Long_AsBool(value)) {
232 case true:
233 self->data->flag |= flag;
234 return 0;
235 case false:
236 self->data->flag &= ~flag;
237 return 0;
238 default:
239 /* error is set */
240 return -1;
241 }
242}
243
244static PyGetSetDef bpy_bmvertskin_getseters[] = {
245 /* attributes match rna_mesh_gen. */
246 {"radius",
249 bpy_bmvertskin_radius_doc,
250 nullptr},
251 {"use_root",
254 bpy_bmvertskin_flag__use_root_doc,
255 (void *)MVERT_SKIN_ROOT},
256 {"use_loose",
259 bpy_bmvertskin_flag__use_loose_doc,
260 (void *)MVERT_SKIN_LOOSE},
261
262 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
263};
264
265static PyTypeObject BPy_BMVertSkin_Type; /* bm.loops.layers.skin.active */
266
268{
269 BPy_BMVertSkin_Type.tp_basicsize = sizeof(BPy_BMVertSkin);
270
271 BPy_BMVertSkin_Type.tp_name = "BMVertSkin";
272
273 BPy_BMVertSkin_Type.tp_doc = nullptr; /* todo */
274
276
277 BPy_BMVertSkin_Type.tp_flags = Py_TPFLAGS_DEFAULT;
278
279 PyType_Ready(&BPy_BMVertSkin_Type);
280}
281
282int BPy_BMVertSkin_AssignPyObject(MVertSkin *mvertskin, PyObject *value)
283{
284 if (UNLIKELY(!BPy_BMVertSkin_Check(value))) {
285 PyErr_Format(PyExc_TypeError, "expected BMVertSkin, not a %.200s", Py_TYPE(value)->tp_name);
286 return -1;
287 }
288
289 *(mvertskin) = *(((BPy_BMVertSkin *)value)->data);
290 return 0;
291}
292
294{
296 self->data = mvertskin;
297 return (PyObject *)self;
298}
299
300/* --- End Mesh Vert Skin --- */
301
302/* Mesh Loop Color
303 * *************** */
304
305/* This simply provides a color wrapper for
306 * color which uses mathutils callbacks for mathutils.Color
307 */
308
309#define MLOOPCOL_FROM_CAPSULE(color_capsule) \
310 ((MLoopCol *)PyCapsule_GetPointer(color_capsule, nullptr))
311
312static void mloopcol_to_float(const MLoopCol *mloopcol, float r_col[4])
313{
314 rgba_uchar_to_float(r_col, (const uchar *)&mloopcol->r);
315}
316
317static void mloopcol_from_float(MLoopCol *mloopcol, const float col[4])
318{
319 rgba_float_to_uchar((uchar *)&mloopcol->r, col);
320}
321
323
325{
326 /* always ok */
327 return 0;
328}
329
330static int mathutils_bmloopcol_get(BaseMathObject *bmo, int /*subtype*/)
331{
332 MLoopCol *mloopcol = MLOOPCOL_FROM_CAPSULE(bmo->cb_user);
333 mloopcol_to_float(mloopcol, bmo->data);
334 return 0;
335}
336
337static int mathutils_bmloopcol_set(BaseMathObject *bmo, int /*subtype*/)
338{
339 MLoopCol *mloopcol = MLOOPCOL_FROM_CAPSULE(bmo->cb_user);
340 mloopcol_from_float(mloopcol, bmo->data);
341 return 0;
342}
343
344static int mathutils_bmloopcol_get_index(BaseMathObject *bmo, int subtype, int /*index*/)
345{
346 /* Lazy, avoid repeating the case statement. */
347 if (mathutils_bmloopcol_get(bmo, subtype) == -1) {
348 return -1;
349 }
350 return 0;
351}
352
353static int mathutils_bmloopcol_set_index(BaseMathObject *bmo, int subtype, int index)
354{
355 const float f = bmo->data[index];
356
357 /* Lazy, avoid repeating the case statement. */
358 if (mathutils_bmloopcol_get(bmo, subtype) == -1) {
359 return -1;
360 }
361
362 bmo->data[index] = f;
363 return mathutils_bmloopcol_set(bmo, subtype);
364}
365
373
379
380int BPy_BMLoopColor_AssignPyObject(MLoopCol *mloopcol, PyObject *value)
381{
382 float tvec[4];
383 if (mathutils_array_parse(tvec, 4, 4, value, "BMLoopCol") != -1) {
384 mloopcol_from_float(mloopcol, tvec);
385 return 0;
386 }
387
388 return -1;
389}
390
392{
393 PyObject *color_capsule;
394 color_capsule = PyCapsule_New(mloopcol, nullptr, nullptr);
395 return Vector_CreatePyObject_cb(color_capsule, 4, mathutils_bmloopcol_cb_index, 0);
396}
397
398#undef MLOOPCOL_FROM_CAPSULE
399
400/* --- End Mesh Loop Color --- */
401
402/* Mesh Deform Vert
403 * **************** */
404
428
429#define BPy_BMDeformVert_Check(v) (Py_TYPE(v) == &BPy_BMDeformVert_Type)
430
432 PyObject_VAR_HEAD
434};
435
436/* Mapping Protocols
437 * ================= */
438
440{
441 return self->data->totweight;
442}
443
444static PyObject *bpy_bmdeformvert_subscript(BPy_BMDeformVert *self, PyObject *key)
445{
446 if (PyIndex_Check(key)) {
447 int i;
448 i = PyNumber_AsSsize_t(key, PyExc_IndexError);
449 if (i == -1 && PyErr_Occurred()) {
450 return nullptr;
451 }
452
454
455 if (dw == nullptr) {
456 PyErr_SetString(PyExc_KeyError,
457 "BMDeformVert[key] = x: "
458 "key not found");
459 return nullptr;
460 }
461
462 return PyFloat_FromDouble(dw->weight);
463 }
464
465 PyErr_Format(
466 PyExc_TypeError, "BMDeformVert keys must be integers, not %.200s", Py_TYPE(key)->tp_name);
467 return nullptr;
468}
469
470static int bpy_bmdeformvert_ass_subscript(BPy_BMDeformVert *self, PyObject *key, PyObject *value)
471{
472 if (PyIndex_Check(key)) {
473 int i;
474
475 i = PyNumber_AsSsize_t(key, PyExc_IndexError);
476 if (i == -1 && PyErr_Occurred()) {
477 return -1;
478 }
479
480 if (value) {
481 /* Handle `dvert[group_index] = 0.5`. */
482 if (i < 0) {
483 PyErr_SetString(PyExc_KeyError,
484 "BMDeformVert[key] = x: "
485 "weight keys cannot be negative");
486 return -1;
487 }
488
490 const float f = PyFloat_AsDouble(value);
491 if (f == -1 && PyErr_Occurred()) { /* Parsed key not a number. */
492 PyErr_SetString(PyExc_TypeError,
493 "BMDeformVert[key] = x: "
494 "assigned value not a number");
495 return -1;
496 }
497
498 dw->weight = clamp_f(f, 0.0f, 1.0f);
499 }
500 else {
501 /* Handle `del dvert[group_index]`. */
503
504 if (dw == nullptr) {
505 PyErr_SetString(PyExc_KeyError,
506 "del BMDeformVert[key]: "
507 "key not found");
508 }
510 }
511
512 return 0;
513 }
514
515 PyErr_Format(
516 PyExc_TypeError, "BMDeformVert keys must be integers, not %.200s", Py_TYPE(key)->tp_name);
517 return -1;
518}
519
521{
522 const int key = PyLong_AsSsize_t(value);
523
524 if (key == -1 && PyErr_Occurred()) {
525 PyErr_SetString(PyExc_TypeError, "BMDeformVert.__contains__: expected an int");
526 return -1;
527 }
528
529 return (BKE_defvert_find_index(self->data, key) != nullptr) ? 1 : 0;
530}
531
532/* only defined for __contains__ */
533static PySequenceMethods bpy_bmdeformvert_as_sequence = {
534 /*sq_length*/ (lenfunc)bpy_bmdeformvert_len,
535 /*sq_concat*/ nullptr,
536 /*sq_repeat*/ nullptr,
537 /* NOTE: if this is set #PySequence_Check() returns True,
538 * but in this case we don't want to be treated as a seq. */
539 /*sq_item*/ nullptr,
540 /*was_sq_slice*/ nullptr, /* DEPRECATED. */
541 /*sq_ass_item*/ nullptr,
542 /*was_sq_ass_slice*/ nullptr, /* DEPRECATED. */
543 /*sq_contains*/ (objobjproc)bpy_bmdeformvert_contains,
544 /*sq_inplace_concat*/ nullptr,
545 /*sq_inplace_repeat*/ nullptr,
546};
547
548static PyMappingMethods bpy_bmdeformvert_as_mapping = {
549 /*mp_length*/ (lenfunc)bpy_bmdeformvert_len,
550 /*mp_subscript*/ (binaryfunc)bpy_bmdeformvert_subscript,
551 /*mp_ass_subscript*/ (objobjargproc)bpy_bmdeformvert_ass_subscript,
552};
553
554/* Methods
555 * ======= */
556
558 /* Wrap. */
559 bpy_bmdeformvert_keys_doc,
560 ".. method:: keys()\n"
561 "\n"
562 " Return the group indices used by this vertex\n"
563 " (matching Python's dict.keys() functionality).\n"
564 "\n"
565 " :return: the deform group this vertex uses\n"
566 " :rtype: list[int]\n");
568{
569 PyObject *ret;
570 int i;
571 MDeformWeight *dw = self->data->dw;
572
573 ret = PyList_New(self->data->totweight);
574 for (i = 0; i < self->data->totweight; i++, dw++) {
575 PyList_SET_ITEM(ret, i, PyLong_FromLong(dw->def_nr));
576 }
577
578 return ret;
579}
580
582 /* Wrap. */
583 bpy_bmdeformvert_values_doc,
584 ".. method:: values()\n"
585 "\n"
586 " Return the weights of the deform vertex\n"
587 " (matching Python's dict.values() functionality).\n"
588 "\n"
589 " :return: The weights that influence this vertex\n"
590 " :rtype: list[float]\n");
592{
593 PyObject *ret;
594 int i;
595 MDeformWeight *dw = self->data->dw;
596
597 ret = PyList_New(self->data->totweight);
598 for (i = 0; i < self->data->totweight; i++, dw++) {
599 PyList_SET_ITEM(ret, i, PyFloat_FromDouble(dw->weight));
600 }
601
602 return ret;
603}
604
606 /* Wrap. */
607 bpy_bmdeformvert_items_doc,
608 ".. method:: items()\n"
609 "\n"
610 " Return (group, weight) pairs for this vertex\n"
611 " (matching Python's dict.items() functionality).\n"
612 "\n"
613 " :return: (key, value) pairs for each deform weight of this vertex.\n"
614 " :rtype: list[tuple[int, float]]\n");
616{
617 PyObject *ret;
618 PyObject *item;
619 int i;
620 MDeformWeight *dw = self->data->dw;
621
622 ret = PyList_New(self->data->totweight);
623 for (i = 0; i < self->data->totweight; i++, dw++) {
624 item = PyTuple_New(2);
625 PyTuple_SET_ITEMS(item, PyLong_FromLong(dw->def_nr), PyFloat_FromDouble(dw->weight));
626 PyList_SET_ITEM(ret, i, item);
627 }
628
629 return ret;
630}
631
633 /* Wrap. */
634 bpy_bmdeformvert_get_doc,
635 ".. method:: get(key, default=None)\n"
636 "\n"
637 " Returns the deform weight matching the key or default\n"
638 " when not found (matches Python's dictionary function of the same name).\n"
639 "\n"
640 " :arg key: The key associated with deform weight.\n"
641 " :type key: int\n"
642 " :arg default: Optional argument for the value to return if\n"
643 " *key* is not found.\n"
644 " :type default: Any\n");
645static PyObject *bpy_bmdeformvert_get(BPy_BMDeformVert *self, PyObject *args)
646{
647 int key;
648 PyObject *def = Py_None;
649
650 if (!PyArg_ParseTuple(args, "i|O:get", &key, &def)) {
651 return nullptr;
652 }
653
654 MDeformWeight *dw = BKE_defvert_find_index(self->data, key);
655
656 if (dw) {
657 return PyFloat_FromDouble(dw->weight);
658 }
659
660 return Py_NewRef(def);
661}
662
664 /* Wrap. */
665 bpy_bmdeformvert_clear_doc,
666 ".. method:: clear()\n"
667 "\n"
668 " Clears all weights.\n");
670{
671 BKE_defvert_clear(self->data);
672
673 Py_RETURN_NONE;
674}
675
676#ifdef __GNUC__
677# ifdef __clang__
678# pragma clang diagnostic push
679# pragma clang diagnostic ignored "-Wcast-function-type"
680# else
681# pragma GCC diagnostic push
682# pragma GCC diagnostic ignored "-Wcast-function-type"
683# endif
684#endif
685
686static PyMethodDef bpy_bmdeformvert_methods[] = {
687 {"keys", (PyCFunction)bpy_bmdeformvert_keys, METH_NOARGS, bpy_bmdeformvert_keys_doc},
688 {"values", (PyCFunction)bpy_bmdeformvert_values, METH_NOARGS, bpy_bmdeformvert_values_doc},
689 {"items", (PyCFunction)bpy_bmdeformvert_items, METH_NOARGS, bpy_bmdeformvert_items_doc},
690 {"get", (PyCFunction)bpy_bmdeformvert_get, METH_VARARGS, bpy_bmdeformvert_get_doc},
691 /* BMESH_TODO `pop`, `popitem`, `update`. */
692 {"clear", (PyCFunction)bpy_bmdeformvert_clear, METH_NOARGS, bpy_bmdeformvert_clear_doc},
693 {nullptr, nullptr, 0, nullptr},
694};
695
696#ifdef __GNUC__
697# ifdef __clang__
698# pragma clang diagnostic pop
699# else
700# pragma GCC diagnostic pop
701# endif
702#endif
703
704PyTypeObject BPy_BMDeformVert_Type; /* bm.loops.layers.uv.active */
705
707{
708 BPy_BMDeformVert_Type.tp_basicsize = sizeof(BPy_BMDeformVert);
709
710 BPy_BMDeformVert_Type.tp_name = "BMDeformVert";
711
712 BPy_BMDeformVert_Type.tp_doc = nullptr; /* todo */
713
716
718
719 BPy_BMDeformVert_Type.tp_flags = Py_TPFLAGS_DEFAULT;
720
721 PyType_Ready(&BPy_BMDeformVert_Type);
722}
723
725{
726 if (UNLIKELY(!BPy_BMDeformVert_Check(value))) {
727 PyErr_Format(PyExc_TypeError, "expected BMDeformVert, not a %.200s", Py_TYPE(value)->tp_name);
728 return -1;
729 }
730
731 MDeformVert *dvert_src = ((BPy_BMDeformVert *)value)->data;
732 if (LIKELY(dvert != dvert_src)) {
733 BKE_defvert_copy(dvert, dvert_src);
734 }
735 return 0;
736}
737
739{
741 self->data = dvert;
742 return (PyObject *)self;
743}
744
745/* --- End Mesh Deform Vert --- */
746
CustomData interface, see also DNA_customdata_types.h.
support for deformation groups and hooks.
MDeformWeight * BKE_defvert_ensure_index(MDeformVert *dv, int defgroup)
Definition deform.cc:825
MDeformWeight * BKE_defvert_find_index(const MDeformVert *dv, int defgroup)
Definition deform.cc:806
void BKE_defvert_clear(MDeformVert *dvert)
Definition deform.cc:913
void BKE_defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src)
Definition deform.cc:127
void BKE_defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
Definition deform.cc:880
#define BLI_assert(a)
Definition BLI_assert.h:46
MINLINE float clamp_f(float value, float min, float max)
MINLINE void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
MINLINE void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
MINLINE void copy_v2_v2(float r[2], const float a[2])
unsigned char uchar
#define POINTER_AS_INT(i)
#define UNLIKELY(x)
#define LIKELY(x)
@ MVERT_SKIN_LOOSE
@ MVERT_SKIN_ROOT
#define BM_ELEM_CD_GET_FLOAT_P(ele, offset)
#define BM_ELEM_CD_SET_BOOL(ele, offset, f)
#define BM_ELEM_CD_GET_BOOL_P(ele, offset)
BMesh const char void * data
BMesh * bm
static PyObject * bpy_bmdeformvert_items(BPy_BMDeformVert *self)
static int bpy_bmloopuv_uv_set(BPy_BMLoopUV *self, PyObject *value, void *)
static PySequenceMethods bpy_bmdeformvert_as_sequence
static int mathutils_bmloopcol_set(BaseMathObject *bmo, int)
int BPy_BMVertSkin_AssignPyObject(MVertSkin *mvertskin, PyObject *value)
static PyObject * bpy_bmdeformvert_clear(BPy_BMDeformVert *self)
static void bm_init_types_bmloopuv()
static PyObject * bpy_bmloopuv_pin_uv_get(BPy_BMLoopUV *self, void *)
static int bpy_bmvertskin_flag_set(BPy_BMVertSkin *self, PyObject *value, void *flag_p)
static PyObject * bpy_bmdeformvert_subscript(BPy_BMDeformVert *self, PyObject *key)
static void mloopcol_to_float(const MLoopCol *mloopcol, float r_col[4])
static PyObject * bpy_bmvertskin_flag_get(BPy_BMVertSkin *self, void *flag_p)
static PyMethodDef bpy_bmdeformvert_methods[]
PyObject * BPy_BMDeformVert_CreatePyObject(MDeformVert *dvert)
static int bpy_bmloopuv_pin_uv_set(BPy_BMLoopUV *self, PyObject *value, void *)
static PyObject * bpy_bmdeformvert_keys(BPy_BMDeformVert *self)
#define MLOOPCOL_FROM_CAPSULE(color_capsule)
static PyObject * bpy_bmdeformvert_get(BPy_BMDeformVert *self, PyObject *args)
int BPy_BMDeformVert_AssignPyObject(MDeformVert *dvert, PyObject *value)
static void bm_init_types_bmdvert()
void BPy_BM_init_types_meshdata()
PyObject * BPy_BMLoopColor_CreatePyObject(MLoopCol *mloopcol)
PyDoc_STRVAR(bpy_bmloopuv_uv_doc, "Loops UV (as a 2D Vector).\n" "\n" ":type: :class:`mathutils.Vector`\n")
static int mathutils_bmloopcol_get_index(BaseMathObject *bmo, int subtype, int)
static int mathutils_bmloopcol_set_index(BaseMathObject *bmo, int subtype, int index)
static Mathutils_Callback mathutils_bmloopcol_cb
static PyObject * bpy_bmvertskin_radius_get(BPy_BMVertSkin *self, void *)
static PyGetSetDef bpy_bmloopuv_getseters[]
static void bm_init_types_bmvertskin()
static int mathutils_bmloopcol_get(BaseMathObject *bmo, int)
PyObject * BPy_BMLoopUV_CreatePyObject(BMesh *bm, BMLoop *loop, int layer)
static PyObject * bpy_bmloopuv_uv_get(BPy_BMLoopUV *self, void *)
static int bpy_bmdeformvert_contains(BPy_BMDeformVert *self, PyObject *value)
static int bpy_bmdeformvert_ass_subscript(BPy_BMDeformVert *self, PyObject *key, PyObject *value)
PyTypeObject BPy_BMDeformVert_Type
static PyGetSetDef bpy_bmvertskin_getseters[]
static PyObject * bpy_bmdeformvert_values(BPy_BMDeformVert *self)
#define BPy_BMVertSkin_Check(v)
static int bpy_bmvertskin_radius_set(BPy_BMVertSkin *self, PyObject *value, void *)
static void mloopcol_from_float(MLoopCol *mloopcol, const float col[4])
#define BPy_BMDeformVert_Check(v)
int BPy_BMLoopColor_AssignPyObject(MLoopCol *mloopcol, PyObject *value)
static uchar mathutils_bmloopcol_cb_index
static void bm_init_types_bmloopcol()
int BPy_BMLoopUV_AssignPyObject(BMesh *bm, BMLoop *loop, PyObject *value)
static Py_ssize_t bpy_bmdeformvert_len(BPy_BMDeformVert *self)
PyTypeObject BPy_BMLoopUV_Type
static int mathutils_bmloopcol_check(BaseMathObject *)
PyObject * BPy_BMVertSkin_CreatePyObject(MVertSkin *mvertskin)
#define BPy_BMLoopUV_Check(v)
static PyMappingMethods bpy_bmdeformvert_as_mapping
static PyTypeObject BPy_BMVertSkin_Type
BMUVOffsets BM_uv_map_offsets_get(const BMesh *bm)
BMUVOffsets BM_uv_map_offsets_from_layer(const BMesh *bm, const int layer)
PyObject * self
uint col
int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
Definition mathutils.cc:96
uchar Mathutils_RegisterCallback(Mathutils_Callback *cb)
Definition mathutils.cc:521
PyObject * Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type, uchar cb_subtype)
PyObject * Vector_CreatePyObject_wrap(float *vec, const int vec_num, PyTypeObject *base_type)
int PyC_Long_AsBool(PyObject *value)
header-only utilities
#define PyTuple_SET_ITEMS(op_arg,...)
return ret
PyObject_VAR_HEAD MDeformVert * data
PyObject_VAR_HEAD float * uv
PyObject_VAR_HEAD MVertSkin * data
unsigned int def_nr
unsigned char r
i
Definition text_draw.cc:230
uint8_t flag
Definition wm_window.cc:145