Blender  V2.93
bmesh_py_types.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2012 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "BLI_math.h"
25 #include "BLI_sort.h"
26 
27 #include "DNA_material_types.h"
28 #include "DNA_mesh_types.h"
29 #include "DNA_object_types.h"
30 
31 #include "BKE_customdata.h"
32 #include "BKE_global.h"
33 #include "BKE_lib_id.h"
34 #include "BKE_mesh.h"
35 #include "BKE_mesh_runtime.h"
36 
37 #include "DEG_depsgraph.h"
38 #include "DEG_depsgraph_query.h"
39 
40 #include "bmesh.h"
41 
42 #include <Python.h>
43 
44 #include "../mathutils/mathutils.h"
45 
46 #include "../generic/py_capi_utils.h"
47 #include "../generic/python_utildefines.h"
48 
49 #include "bmesh_py_types.h" /* own include */
52 #include "bmesh_py_types_select.h"
53 
54 static void bm_dealloc_editmode_warn(BPy_BMesh *self);
55 
56 /* Common Flags
57  * ************ */
58 
59 /* scene does not use BM_* flags. */
61  {1, "VERT"},
62  {2, "EDGE"},
63  {4, "FACE"},
64  {0, NULL},
65 };
66 
68  {BM_VERT, "VERT"},
69  {BM_EDGE, "EDGE"},
70  {BM_FACE, "FACE"},
71  {0, NULL},
72 };
73 
75  {BM_VERT, "VERT"},
76  {BM_LOOP, "EDGE"},
77  {BM_FACE, "FACE"},
78  {BM_LOOP, "LOOP"},
79  {0, NULL},
80 };
81 
82 #define BPY_BM_HFLAG_ALL_STR "('SELECT', 'HIDE', 'SEAM', 'SMOOTH', 'TAG')"
83 
85  {BM_ELEM_SELECT, "SELECT"},
86  {BM_ELEM_HIDDEN, "HIDE"},
87  {BM_ELEM_SEAM, "SEAM"},
88  {BM_ELEM_SMOOTH, "SMOOTH"},
89  {BM_ELEM_TAG, "TAG"},
90  {0, NULL},
91 };
92 
93 /* py-type definitions
94  * ******************* */
95 
96 /* getseters
97  * ========= */
98 
99 /* bmesh elems
100  * ----------- */
101 
102 PyDoc_STRVAR(bpy_bm_elem_select_doc, "Selected state of this element.\n\n:type: boolean");
103 PyDoc_STRVAR(bpy_bm_elem_hide_doc, "Hidden state of this element.\n\n:type: boolean");
104 PyDoc_STRVAR(bpy_bm_elem_tag_doc,
105  "Generic attribute scripts can use for own logic\n\n:type: boolean");
106 PyDoc_STRVAR(bpy_bm_elem_smooth_doc, "Smooth state of this element.\n\n:type: boolean");
107 PyDoc_STRVAR(bpy_bm_elem_seam_doc, "Seam for UV unwrapping.\n\n:type: boolean");
108 
109 static PyObject *bpy_bm_elem_hflag_get(BPy_BMElem *self, void *flag)
110 {
111  const char hflag = (char)POINTER_AS_INT(flag);
112 
113  BPY_BM_CHECK_OBJ(self);
114 
115  return PyBool_FromLong(BM_elem_flag_test(self->ele, hflag));
116 }
117 
118 static int bpy_bm_elem_hflag_set(BPy_BMElem *self, PyObject *value, void *flag)
119 {
120  const char hflag = (char)POINTER_AS_INT(flag);
121  int param;
122 
123  BPY_BM_CHECK_INT(self);
124 
125  if ((param = PyC_Long_AsBool(value)) == -1) {
126  return -1;
127  }
128 
129  if (hflag == BM_ELEM_SELECT) {
130  BM_elem_select_set(self->bm, self->ele, param);
131  }
132  else {
133  BM_elem_flag_set(self->ele, hflag, param);
134  }
135  return 0;
136 }
137 
139  bpy_bm_elem_index_doc,
140  "Index of this element.\n"
141  "\n"
142  ":type: int\n"
143  "\n"
144  ".. note::\n"
145  "\n"
146  " This value is not necessarily valid, while editing the mesh it can become *dirty*.\n"
147  "\n"
148  " It's also possible to assign any number to this attribute for a scripts internal logic.\n"
149  "\n"
150  " To ensure the value is up to date - see :class:`BMElemSeq.index_update`.\n");
151 static PyObject *bpy_bm_elem_index_get(BPy_BMElem *self, void *UNUSED(flag))
152 {
153  BPY_BM_CHECK_OBJ(self);
154 
155  return PyLong_FromLong(BM_elem_index_get(self->ele));
156 }
157 
158 static int bpy_bm_elem_index_set(BPy_BMElem *self, PyObject *value, void *UNUSED(flag))
159 {
160  int param;
161 
162  BPY_BM_CHECK_INT(self);
163 
164  if (((param = PyC_Long_AsI32(value)) == -1) && PyErr_Occurred()) {
165  /* error is set */
166  return -1;
167  }
168 
169  BM_elem_index_set(self->ele, param); /* set_dirty! */
170 
171  /* when setting the index assume its set invalid */
172  self->bm->elem_index_dirty |= self->ele->head.htype;
173 
174  return 0;
175 }
176 
177 /* type specific get/sets
178  * ---------------------- */
179 
180 /* Mesh
181  * ^^^^ */
182 
183 /* doc-strings for all uses of this function */
184 
185 PyDoc_STRVAR(bpy_bmvertseq_doc,
186  "This meshes vert sequence (read-only).\n\n:type: :class:`BMVertSeq`");
187 static PyObject *bpy_bmvertseq_get(BPy_BMesh *self, void *UNUSED(closure))
188 {
189  BPY_BM_CHECK_OBJ(self);
191 }
192 
193 PyDoc_STRVAR(bpy_bmedgeseq_doc,
194  "This meshes edge sequence (read-only).\n\n:type: :class:`BMEdgeSeq`");
195 static PyObject *bpy_bmedgeseq_get(BPy_BMesh *self, void *UNUSED(closure))
196 {
197  BPY_BM_CHECK_OBJ(self);
199 }
200 
201 PyDoc_STRVAR(bpy_bmfaceseq_doc,
202  "This meshes face sequence (read-only).\n\n:type: :class:`BMFaceSeq`");
203 static PyObject *bpy_bmfaceseq_get(BPy_BMesh *self, void *UNUSED(closure))
204 {
205  BPY_BM_CHECK_OBJ(self);
207 }
208 
209 PyDoc_STRVAR(bpy_bmloopseq_doc,
210  "This meshes loops (read-only).\n\n:type: :class:`BMLoopSeq`\n"
211  "\n"
212  ".. note::\n"
213  "\n"
214  " Loops must be accessed via faces, this is only exposed for layer access.\n");
215 static PyObject *bpy_bmloopseq_get(BPy_BMesh *self, void *UNUSED(closure))
216 {
217  BPY_BM_CHECK_OBJ(self);
219 }
220 
221 /* vert */
223  bpy_bmvert_link_edges_doc,
224  "Edges connected to this vertex (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMEdge`");
226  bpy_bmvert_link_faces_doc,
227  "Faces connected to this vertex (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMFace`");
229  bpy_bmvert_link_loops_doc,
230  "Loops that use this vertex (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMLoop`");
231 /* edge */
232 PyDoc_STRVAR(bpy_bmedge_verts_doc,
233  "Verts this edge uses (always 2), (read-only).\n\n:type: :class:`BMElemSeq` of "
234  ":class:`BMVert`");
236  bpy_bmedge_link_faces_doc,
237  "Faces connected to this edge, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMFace`");
239  bpy_bmedge_link_loops_doc,
240  "Loops connected to this edge, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMLoop`");
241 /* face */
242 PyDoc_STRVAR(bpy_bmface_verts_doc,
243  "Verts of this face, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMVert`");
244 PyDoc_STRVAR(bpy_bmface_edges_doc,
245  "Edges of this face, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMEdge`");
246 PyDoc_STRVAR(bpy_bmface_loops_doc,
247  "Loops of this face, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMLoop`");
248 /* loop */
250  bpy_bmloops_link_loops_doc,
251  "Loops connected to this loop, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMLoop`");
252 
253 static PyObject *bpy_bmelemseq_elem_get(BPy_BMElem *self, void *itype)
254 {
255  BPY_BM_CHECK_OBJ(self);
257 }
258 
259 PyDoc_STRVAR(bpy_bm_is_valid_doc,
260  "True when this element is valid (hasn't been removed).\n\n:type: boolean");
261 static PyObject *bpy_bm_is_valid_get(BPy_BMGeneric *self)
262 {
263  return PyBool_FromLong(BPY_BM_IS_VALID(self));
264 }
265 
267  bpy_bmesh_is_wrapped_doc,
268  "True when this mesh is owned by blender (typically the editmode BMesh).\n\n:type: boolean");
269 static PyObject *bpy_bmesh_is_wrapped_get(BPy_BMesh *self)
270 {
271  BPY_BM_CHECK_OBJ(self);
272 
273  return PyBool_FromLong(self->flag & BPY_BMFLAG_IS_WRAPPED);
274 }
275 
276 PyDoc_STRVAR(bpy_bmesh_select_mode_doc,
277  "The selection mode, values can be {'VERT', 'EDGE', 'FACE'}, can't be assigned an "
278  "empty set.\n\n:type: set");
279 static PyObject *bpy_bmesh_select_mode_get(BPy_BMesh *self)
280 {
281  BPY_BM_CHECK_OBJ(self);
282 
284 }
285 
286 static int bpy_bmesh_select_mode_set(BPy_BMesh *self, PyObject *value)
287 {
288  int flag = 0;
289  BPY_BM_CHECK_INT(self);
290 
291  if (PyC_FlagSet_ToBitfield(bpy_bm_scene_vert_edge_face_flags, value, &flag, "bm.select_mode") ==
292  -1) {
293  return -1;
294  }
295  if (flag == 0) {
296  PyErr_SetString(PyExc_TypeError, "bm.select_mode: can't assign an empty value");
297  return -1;
298  }
299 
300  self->bm->selectmode = flag;
301  return 0;
302 }
303 
304 PyDoc_STRVAR(bpy_bmesh_select_history_doc,
305  "Sequence of selected items (the last is displayed as active).\n\n:type: "
306  ":class:`BMEditSelSeq`");
308 {
309  BPY_BM_CHECK_OBJ(self);
310 
312 }
313 
314 static int bpy_bmesh_select_history_set(BPy_BMesh *self, PyObject *value)
315 {
316  BPY_BM_CHECK_INT(self);
317 
318  return BPy_BMEditSel_Assign(self, value);
319 }
320 
321 /* Vert
322  * ^^^^ */
323 
324 PyDoc_STRVAR(bpy_bmvert_co_doc,
325  "The coordinates for this vertex as a 3D, wrapped vector.\n\n:type: "
326  ":class:`mathutils.Vector`");
327 static PyObject *bpy_bmvert_co_get(BPy_BMVert *self)
328 {
329  BPY_BM_CHECK_OBJ(self);
330  return Vector_CreatePyObject_wrap(self->v->co, 3, NULL);
331 }
332 
333 static int bpy_bmvert_co_set(BPy_BMVert *self, PyObject *value)
334 {
335  BPY_BM_CHECK_INT(self);
336 
337  if (mathutils_array_parse(self->v->co, 3, 3, value, "BMVert.co") != -1) {
338  return 0;
339  }
340 
341  return -1;
342 }
343 
345  bpy_bmvert_normal_doc,
346  "The normal for this vertex as a 3D, wrapped vector.\n\n:type: :class:`mathutils.Vector`");
347 static PyObject *bpy_bmvert_normal_get(BPy_BMVert *self)
348 {
349  BPY_BM_CHECK_OBJ(self);
350  return Vector_CreatePyObject_wrap(self->v->no, 3, NULL);
351 }
352 
353 static int bpy_bmvert_normal_set(BPy_BMVert *self, PyObject *value)
354 {
355  BPY_BM_CHECK_INT(self);
356 
357  if (mathutils_array_parse(self->v->no, 3, 3, value, "BMVert.normal") != -1) {
358  return 0;
359  }
360 
361  return -1;
362 }
363 
364 PyDoc_STRVAR(bpy_bmvert_is_manifold_doc,
365  "True when this vertex is manifold (read-only).\n\n:type: boolean");
366 static PyObject *bpy_bmvert_is_manifold_get(BPy_BMVert *self)
367 {
368  BPY_BM_CHECK_OBJ(self);
369  return PyBool_FromLong(BM_vert_is_manifold(self->v));
370 }
371 
372 PyDoc_STRVAR(bpy_bmvert_is_wire_doc,
373  "True when this vertex is not connected to any faces (read-only).\n\n:type: boolean");
374 static PyObject *bpy_bmvert_is_wire_get(BPy_BMVert *self)
375 {
376  BPY_BM_CHECK_OBJ(self);
377  return PyBool_FromLong(BM_vert_is_wire(self->v));
378 }
379 
381  bpy_bmvert_is_boundary_doc,
382  "True when this vertex is connected to boundary edges (read-only).\n\n:type: boolean");
383 static PyObject *bpy_bmvert_is_boundary_get(BPy_BMVert *self)
384 {
385  BPY_BM_CHECK_OBJ(self);
386  return PyBool_FromLong(BM_vert_is_boundary(self->v));
387 }
388 
389 /* Edge
390  * ^^^^ */
391 
392 PyDoc_STRVAR(bpy_bmedge_is_manifold_doc,
393  "True when this edge is manifold (read-only).\n\n:type: boolean");
394 static PyObject *bpy_bmedge_is_manifold_get(BPy_BMEdge *self)
395 {
396  BPY_BM_CHECK_OBJ(self);
397  return PyBool_FromLong(BM_edge_is_manifold(self->e));
398 }
399 
400 PyDoc_STRVAR(bpy_bmedge_is_contiguous_doc,
401  "True when this edge is manifold, between two faces with the same winding "
402  "(read-only).\n\n:type: boolean");
404 {
405  BPY_BM_CHECK_OBJ(self);
406  return PyBool_FromLong(BM_edge_is_contiguous(self->e));
407 }
408 
409 PyDoc_STRVAR(bpy_bmedge_is_convex_doc,
410  "True when this edge joins two convex faces, depends on a valid face normal "
411  "(read-only).\n\n:type: boolean");
412 static PyObject *bpy_bmedge_is_convex_get(BPy_BMEdge *self)
413 {
414  BPY_BM_CHECK_OBJ(self);
415  return PyBool_FromLong(BM_edge_is_convex(self->e));
416 }
417 
418 PyDoc_STRVAR(bpy_bmedge_is_wire_doc,
419  "True when this edge is not connected to any faces (read-only).\n\n:type: boolean");
420 static PyObject *bpy_bmedge_is_wire_get(BPy_BMEdge *self)
421 {
422  BPY_BM_CHECK_OBJ(self);
423  return PyBool_FromLong(BM_edge_is_wire(self->e));
424 }
425 
426 PyDoc_STRVAR(bpy_bmedge_is_boundary_doc,
427  "True when this edge is at the boundary of a face (read-only).\n\n:type: boolean");
428 static PyObject *bpy_bmedge_is_boundary_get(BPy_BMEdge *self)
429 {
430  BPY_BM_CHECK_OBJ(self);
431  return PyBool_FromLong(BM_edge_is_boundary(self->e));
432 }
433 
434 /* Face
435  * ^^^^ */
436 
438  bpy_bmface_normal_doc,
439  "The normal for this face as a 3D, wrapped vector.\n\n:type: :class:`mathutils.Vector`");
440 static PyObject *bpy_bmface_normal_get(BPy_BMFace *self)
441 {
442  BPY_BM_CHECK_OBJ(self);
443  return Vector_CreatePyObject_wrap(self->f->no, 3, NULL);
444 }
445 
446 static int bpy_bmface_normal_set(BPy_BMFace *self, PyObject *value)
447 {
448  BPY_BM_CHECK_INT(self);
449 
450  if (mathutils_array_parse(self->f->no, 3, 3, value, "BMFace.normal") != -1) {
451  return 0;
452  }
453 
454  return -1;
455 }
456 
457 PyDoc_STRVAR(bpy_bmface_material_index_doc, "The face's material index.\n\n:type: int");
459 {
460  BPY_BM_CHECK_OBJ(self);
461  return PyLong_FromLong(self->f->mat_nr);
462 }
463 
464 static int bpy_bmface_material_index_set(BPy_BMFace *self, PyObject *value)
465 {
466  int param;
467 
468  BPY_BM_CHECK_INT(self);
469 
470  if (((param = PyC_Long_AsI32(value)) == -1) && PyErr_Occurred()) {
471  /* error is set */
472  return -1;
473  }
474 
475  if ((param < 0) || (param > MAXMAT)) {
476  /* normally we clamp but in this case raise an error */
477  PyErr_SetString(PyExc_ValueError, "material index outside of usable range (0 - 32766)");
478  return -1;
479  }
480 
481  self->f->mat_nr = (short)param;
482  return 0;
483 }
484 
485 /* Loop
486  * ^^^^ */
487 
488 PyDoc_STRVAR(bpy_bmloop_vert_doc, "The loop's vertex (read-only).\n\n:type: :class:`BMVert`");
489 static PyObject *bpy_bmloop_vert_get(BPy_BMLoop *self)
490 {
491  BPY_BM_CHECK_OBJ(self);
492  return BPy_BMVert_CreatePyObject(self->bm, self->l->v);
493 }
494 
496  bpy_bmloop_edge_doc,
497  "The loop's edge (between this loop and the next), (read-only).\n\n:type: :class:`BMEdge`");
498 static PyObject *bpy_bmloop_edge_get(BPy_BMLoop *self)
499 {
500  BPY_BM_CHECK_OBJ(self);
501  return BPy_BMEdge_CreatePyObject(self->bm, self->l->e);
502 }
503 
504 PyDoc_STRVAR(bpy_bmloop_face_doc,
505  "The face this loop makes (read-only).\n\n:type: :class:`BMFace`");
506 static PyObject *bpy_bmloop_face_get(BPy_BMLoop *self)
507 {
508  BPY_BM_CHECK_OBJ(self);
509  return BPy_BMFace_CreatePyObject(self->bm, self->l->f);
510 }
511 
512 PyDoc_STRVAR(bpy_bmloop_link_loop_next_doc,
513  "The next face corner (read-only).\n\n:type: :class:`BMLoop`");
515 {
516  BPY_BM_CHECK_OBJ(self);
517  return BPy_BMLoop_CreatePyObject(self->bm, self->l->next);
518 }
519 
520 PyDoc_STRVAR(bpy_bmloop_link_loop_prev_doc,
521  "The previous face corner (read-only).\n\n:type: :class:`BMLoop`");
523 {
524  BPY_BM_CHECK_OBJ(self);
525  return BPy_BMLoop_CreatePyObject(self->bm, self->l->prev);
526 }
527 
528 PyDoc_STRVAR(bpy_bmloop_link_loop_radial_next_doc,
529  "The next loop around the edge (read-only).\n\n:type: :class:`BMLoop`");
531 {
532  BPY_BM_CHECK_OBJ(self);
533  return BPy_BMLoop_CreatePyObject(self->bm, self->l->radial_next);
534 }
535 
536 PyDoc_STRVAR(bpy_bmloop_link_loop_radial_prev_doc,
537  "The previous loop around the edge (read-only).\n\n:type: :class:`BMLoop`");
539 {
540  BPY_BM_CHECK_OBJ(self);
541  return BPy_BMLoop_CreatePyObject(self->bm, self->l->radial_prev);
542 }
543 
544 PyDoc_STRVAR(bpy_bmloop_is_convex_doc,
545  "True when this loop is at the convex corner of a face, depends on a valid face "
546  "normal (read-only).\n\n:type: boolean");
547 static PyObject *bpy_bmloop_is_convex_get(BPy_BMLoop *self)
548 {
549  BPY_BM_CHECK_OBJ(self);
550  return PyBool_FromLong(BM_loop_is_convex(self->l));
551 }
552 
553 /* ElemSeq
554  * ^^^^^^^ */
555 
556 /* note: use for bmvert/edge/face/loop seq's use these, not bmelemseq directly */
557 PyDoc_STRVAR(bpy_bmelemseq_layers_vert_doc,
558  "custom-data layers (read-only).\n\n:type: :class:`BMLayerAccessVert`");
559 PyDoc_STRVAR(bpy_bmelemseq_layers_edge_doc,
560  "custom-data layers (read-only).\n\n:type: :class:`BMLayerAccessEdge`");
561 PyDoc_STRVAR(bpy_bmelemseq_layers_face_doc,
562  "custom-data layers (read-only).\n\n:type: :class:`BMLayerAccessFace`");
563 PyDoc_STRVAR(bpy_bmelemseq_layers_loop_doc,
564  "custom-data layers (read-only).\n\n:type: :class:`BMLayerAccessLoop`");
565 static PyObject *bpy_bmelemseq_layers_get(BPy_BMElemSeq *self, void *htype)
566 {
567  BPY_BM_CHECK_OBJ(self);
568 
570 }
571 
572 /* FaceSeq
573  * ^^^^^^^ */
574 
575 PyDoc_STRVAR(bpy_bmfaceseq_active_doc, "active face.\n\n:type: :class:`BMFace` or None");
576 static PyObject *bpy_bmfaceseq_active_get(BPy_BMElemSeq *self, void *UNUSED(closure))
577 {
578  BMesh *bm = self->bm;
579  BPY_BM_CHECK_OBJ(self);
580 
581  if (bm->act_face) {
583  }
584 
585  Py_RETURN_NONE;
586 }
587 
588 static int bpy_bmfaceseq_active_set(BPy_BMElem *self, PyObject *value, void *UNUSED(closure))
589 {
590  BMesh *bm = self->bm;
591  if (value == Py_None) {
592  bm->act_face = NULL;
593  return 0;
594  }
595  if (BPy_BMFace_Check(value)) {
596  BPY_BM_CHECK_SOURCE_INT(bm, "faces.active = f", value);
597 
598  bm->act_face = ((BPy_BMFace *)value)->f;
599  return 0;
600  }
601 
602  PyErr_Format(PyExc_TypeError,
603  "faces.active = f: expected BMFace or None, not %.200s",
604  Py_TYPE(value)->tp_name);
605  return -1;
606 }
607 
608 static PyGetSetDef bpy_bmesh_getseters[] = {
609  {"verts", (getter)bpy_bmvertseq_get, (setter)NULL, bpy_bmvertseq_doc, NULL},
610  {"edges", (getter)bpy_bmedgeseq_get, (setter)NULL, bpy_bmedgeseq_doc, NULL},
611  {"faces", (getter)bpy_bmfaceseq_get, (setter)NULL, bpy_bmfaceseq_doc, NULL},
612  {"loops", (getter)bpy_bmloopseq_get, (setter)NULL, bpy_bmloopseq_doc, NULL},
613  {"select_mode",
616  bpy_bmesh_select_mode_doc,
617  NULL},
618 
619  {"select_history",
622  bpy_bmesh_select_history_doc,
623  NULL},
624 
625  /* readonly checks */
626  {"is_wrapped",
627  (getter)bpy_bmesh_is_wrapped_get,
628  (setter)NULL,
629  bpy_bmesh_is_wrapped_doc,
630  NULL}, /* as with mathutils */
631  {"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, bpy_bm_is_valid_doc, NULL},
632 
633  {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
634 };
635 
636 static PyGetSetDef bpy_bmvert_getseters[] = {
637  /* generic */
638  {"select",
639  (getter)bpy_bm_elem_hflag_get,
640  (setter)bpy_bm_elem_hflag_set,
641  bpy_bm_elem_select_doc,
642  (void *)BM_ELEM_SELECT},
643  {"hide",
644  (getter)bpy_bm_elem_hflag_get,
645  (setter)bpy_bm_elem_hflag_set,
646  bpy_bm_elem_hide_doc,
647  (void *)BM_ELEM_HIDDEN},
648  {"tag",
649  (getter)bpy_bm_elem_hflag_get,
650  (setter)bpy_bm_elem_hflag_set,
651  bpy_bm_elem_tag_doc,
652  (void *)BM_ELEM_TAG},
653  {"index",
654  (getter)bpy_bm_elem_index_get,
655  (setter)bpy_bm_elem_index_set,
656  bpy_bm_elem_index_doc,
657  NULL},
658 
659  {"co", (getter)bpy_bmvert_co_get, (setter)bpy_bmvert_co_set, bpy_bmvert_co_doc, NULL},
660  {"normal",
661  (getter)bpy_bmvert_normal_get,
662  (setter)bpy_bmvert_normal_set,
663  bpy_bmvert_normal_doc,
664  NULL},
665 
666  /* connectivity data */
667  {"link_edges",
668  (getter)bpy_bmelemseq_elem_get,
669  (setter)NULL,
670  bpy_bmvert_link_edges_doc,
671  (void *)BM_EDGES_OF_VERT},
672  {"link_faces",
673  (getter)bpy_bmelemseq_elem_get,
674  (setter)NULL,
675  bpy_bmvert_link_faces_doc,
676  (void *)BM_FACES_OF_VERT},
677  {"link_loops",
678  (getter)bpy_bmelemseq_elem_get,
679  (setter)NULL,
680  bpy_bmvert_link_loops_doc,
681  (void *)BM_LOOPS_OF_VERT},
682 
683  /* readonly checks */
684  {"is_manifold",
686  (setter)NULL,
687  bpy_bmvert_is_manifold_doc,
688  NULL},
689  {"is_wire", (getter)bpy_bmvert_is_wire_get, (setter)NULL, bpy_bmvert_is_wire_doc, NULL},
690  {"is_boundary",
692  (setter)NULL,
693  bpy_bmvert_is_boundary_doc,
694  NULL},
695  {"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, bpy_bm_is_valid_doc, NULL},
696 
697  {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
698 };
699 
700 static PyGetSetDef bpy_bmedge_getseters[] = {
701  /* generic */
702  {"select",
703  (getter)bpy_bm_elem_hflag_get,
704  (setter)bpy_bm_elem_hflag_set,
705  bpy_bm_elem_select_doc,
706  (void *)BM_ELEM_SELECT},
707  {"hide",
708  (getter)bpy_bm_elem_hflag_get,
709  (setter)bpy_bm_elem_hflag_set,
710  bpy_bm_elem_hide_doc,
711  (void *)BM_ELEM_HIDDEN},
712  {"tag",
713  (getter)bpy_bm_elem_hflag_get,
714  (setter)bpy_bm_elem_hflag_set,
715  bpy_bm_elem_tag_doc,
716  (void *)BM_ELEM_TAG},
717  {"index",
718  (getter)bpy_bm_elem_index_get,
719  (setter)bpy_bm_elem_index_set,
720  bpy_bm_elem_index_doc,
721  NULL},
722 
723  {"smooth",
724  (getter)bpy_bm_elem_hflag_get,
725  (setter)bpy_bm_elem_hflag_set,
726  bpy_bm_elem_smooth_doc,
727  (void *)BM_ELEM_SMOOTH},
728  {"seam",
729  (getter)bpy_bm_elem_hflag_get,
730  (setter)bpy_bm_elem_hflag_set,
731  bpy_bm_elem_seam_doc,
732  (void *)BM_ELEM_SEAM},
733 
734  /* connectivity data */
735  {"verts",
736  (getter)bpy_bmelemseq_elem_get,
737  (setter)NULL,
738  bpy_bmedge_verts_doc,
739  (void *)BM_VERTS_OF_EDGE},
740 
741  {"link_faces",
742  (getter)bpy_bmelemseq_elem_get,
743  (setter)NULL,
744  bpy_bmedge_link_faces_doc,
745  (void *)BM_FACES_OF_EDGE},
746  {"link_loops",
747  (getter)bpy_bmelemseq_elem_get,
748  (setter)NULL,
749  bpy_bmedge_link_loops_doc,
750  (void *)BM_LOOPS_OF_EDGE},
751 
752  /* readonly checks */
753  {"is_manifold",
755  (setter)NULL,
756  bpy_bmedge_is_manifold_doc,
757  NULL},
758  {"is_contiguous",
760  (setter)NULL,
761  bpy_bmedge_is_contiguous_doc,
762  NULL},
763  {"is_convex", (getter)bpy_bmedge_is_convex_get, (setter)NULL, bpy_bmedge_is_convex_doc, NULL},
764  {"is_wire", (getter)bpy_bmedge_is_wire_get, (setter)NULL, bpy_bmedge_is_wire_doc, NULL},
765  {"is_boundary",
767  (setter)NULL,
768  bpy_bmedge_is_boundary_doc,
769  NULL},
770  {"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, bpy_bm_is_valid_doc, NULL},
771 
772  {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
773 };
774 
775 static PyGetSetDef bpy_bmface_getseters[] = {
776  /* generic */
777  {"select",
778  (getter)bpy_bm_elem_hflag_get,
779  (setter)bpy_bm_elem_hflag_set,
780  bpy_bm_elem_select_doc,
781  (void *)BM_ELEM_SELECT},
782  {"hide",
783  (getter)bpy_bm_elem_hflag_get,
784  (setter)bpy_bm_elem_hflag_set,
785  bpy_bm_elem_hide_doc,
786  (void *)BM_ELEM_HIDDEN},
787  {"tag",
788  (getter)bpy_bm_elem_hflag_get,
789  (setter)bpy_bm_elem_hflag_set,
790  bpy_bm_elem_tag_doc,
791  (void *)BM_ELEM_TAG},
792  {"index",
793  (getter)bpy_bm_elem_index_get,
794  (setter)bpy_bm_elem_index_set,
795  bpy_bm_elem_index_doc,
796  NULL},
797 
798  {"smooth",
799  (getter)bpy_bm_elem_hflag_get,
800  (setter)bpy_bm_elem_hflag_set,
801  bpy_bm_elem_smooth_doc,
802  (void *)BM_ELEM_SMOOTH},
803 
804  {"normal",
805  (getter)bpy_bmface_normal_get,
806  (setter)bpy_bmface_normal_set,
807  bpy_bmface_normal_doc,
808  NULL},
809 
810  {"material_index",
813  bpy_bmface_material_index_doc,
814  NULL},
815 
816  /* connectivity data */
817  {"verts",
818  (getter)bpy_bmelemseq_elem_get,
819  (setter)NULL,
820  bpy_bmface_verts_doc,
821  (void *)BM_VERTS_OF_FACE},
822  {"edges",
823  (getter)bpy_bmelemseq_elem_get,
824  (setter)NULL,
825  bpy_bmface_edges_doc,
826  (void *)BM_EDGES_OF_FACE},
827  {"loops",
828  (getter)bpy_bmelemseq_elem_get,
829  (setter)NULL,
830  bpy_bmface_loops_doc,
831  (void *)BM_LOOPS_OF_FACE},
832 
833  /* readonly checks */
834  {"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, bpy_bm_is_valid_doc, NULL},
835 
836  {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
837 };
838 
839 static PyGetSetDef bpy_bmloop_getseters[] = {
840 /* generic */
841 /* flags are available but not used for loops. */
842 #if 0
843  {"select",
844  (getter)bpy_bm_elem_hflag_get,
845  (setter)bpy_bm_elem_hflag_set,
846  bpy_bm_elem_select_doc,
847  (void *)BM_ELEM_SELECT},
848  {"hide",
849  (getter)bpy_bm_elem_hflag_get,
850  (setter)bpy_bm_elem_hflag_set,
851  bpy_bm_elem_hide_doc,
852  (void *)BM_ELEM_HIDDEN},
853 #endif
854  {"tag",
855  (getter)bpy_bm_elem_hflag_get,
856  (setter)bpy_bm_elem_hflag_set,
857  bpy_bm_elem_tag_doc,
858  (void *)BM_ELEM_TAG},
859  {"index",
860  (getter)bpy_bm_elem_index_get,
861  (setter)bpy_bm_elem_index_set,
862  bpy_bm_elem_index_doc,
863  NULL},
864 
865  {"vert", (getter)bpy_bmloop_vert_get, (setter)NULL, bpy_bmloop_vert_doc, NULL},
866  {"edge", (getter)bpy_bmloop_edge_get, (setter)NULL, bpy_bmloop_edge_doc, NULL},
867  {"face", (getter)bpy_bmloop_face_get, (setter)NULL, bpy_bmloop_face_doc, NULL},
868 
869  /* connectivity data */
870  {"link_loops",
871  (getter)bpy_bmelemseq_elem_get,
872  (setter)NULL,
873  bpy_bmloops_link_loops_doc,
874  (void *)BM_LOOPS_OF_LOOP},
875  {"link_loop_next",
877  (setter)NULL,
878  bpy_bmloop_link_loop_next_doc,
879  NULL},
880  {"link_loop_prev",
882  (setter)NULL,
883  bpy_bmloop_link_loop_prev_doc,
884  NULL},
885  {"link_loop_radial_next",
887  (setter)NULL,
888  bpy_bmloop_link_loop_radial_next_doc,
889  NULL},
890  {"link_loop_radial_prev",
892  (setter)NULL,
893  bpy_bmloop_link_loop_radial_prev_doc,
894  NULL},
895 
896  /* readonly checks */
897  {"is_convex", (getter)bpy_bmloop_is_convex_get, (setter)NULL, bpy_bmloop_is_convex_doc, NULL},
898  {"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, bpy_bm_is_valid_doc, NULL},
899 
900  {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
901 };
902 
903 static PyGetSetDef bpy_bmvertseq_getseters[] = {
904  {"layers",
905  (getter)bpy_bmelemseq_layers_get,
906  (setter)NULL,
907  bpy_bmelemseq_layers_vert_doc,
908  (void *)BM_VERT},
909  {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
910 };
911 static PyGetSetDef bpy_bmedgeseq_getseters[] = {
912  {"layers",
913  (getter)bpy_bmelemseq_layers_get,
914  (setter)NULL,
915  bpy_bmelemseq_layers_edge_doc,
916  (void *)BM_EDGE},
917  {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
918 };
919 static PyGetSetDef bpy_bmfaceseq_getseters[] = {
920  {"layers",
921  (getter)bpy_bmelemseq_layers_get,
922  (setter)NULL,
923  bpy_bmelemseq_layers_face_doc,
924  (void *)BM_FACE},
925  /* face only */
926  {"active",
927  (getter)bpy_bmfaceseq_active_get,
928  (setter)bpy_bmfaceseq_active_set,
929  bpy_bmfaceseq_active_doc,
930  NULL},
931  {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
932 };
933 static PyGetSetDef bpy_bmloopseq_getseters[] = {
934  {"layers",
935  (getter)bpy_bmelemseq_layers_get,
936  (setter)NULL,
937  bpy_bmelemseq_layers_loop_doc,
938  (void *)BM_LOOP},
939  {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
940 };
941 
942 /* Methods
943  * ======= */
944 
945 /* Mesh
946  * ---- */
947 
948 PyDoc_STRVAR(bpy_bmesh_copy_doc,
949  ".. method:: copy()\n"
950  "\n"
951  " :return: A copy of this BMesh.\n"
952  " :rtype: :class:`BMesh`\n");
953 static PyObject *bpy_bmesh_copy(BPy_BMesh *self)
954 {
955  BMesh *bm;
956  BMesh *bm_copy;
957 
958  BPY_BM_CHECK_OBJ(self);
959 
960  bm = self->bm;
961 
962  bm_copy = BM_mesh_copy(bm);
963 
964  if (bm_copy) {
965  return BPy_BMesh_CreatePyObject(bm_copy, BPY_BMFLAG_NOP);
966  }
967 
968  PyErr_SetString(PyExc_SystemError, "Unable to copy BMesh, internal error");
969  return NULL;
970 }
971 
972 PyDoc_STRVAR(bpy_bmesh_clear_doc,
973  ".. method:: clear()\n"
974  "\n"
975  " Clear all mesh data.\n");
976 static PyObject *bpy_bmesh_clear(BPy_BMesh *self)
977 {
978  BMesh *bm;
979 
980  BPY_BM_CHECK_OBJ(self);
981 
982  bm = self->bm;
983 
984  BM_mesh_clear(bm);
985 
986  Py_RETURN_NONE;
987 }
988 
990  bpy_bmesh_free_doc,
991  ".. method:: free()\n"
992  "\n"
993  " Explicitly free the BMesh data from memory, causing exceptions on further access.\n"
994  "\n"
995  " .. note::\n"
996  "\n"
997  " The BMesh is freed automatically, typically when the script finishes executing.\n"
998  " However in some cases its hard to predict when this will be and its useful to\n"
999  " explicitly free the data.\n");
1000 static PyObject *bpy_bmesh_free(BPy_BMesh *self)
1001 {
1002  if (self->bm) {
1003  BMesh *bm = self->bm;
1004 
1006 
1007  if ((self->flag & BPY_BMFLAG_IS_WRAPPED) == 0) {
1008  BM_mesh_free(bm);
1009  }
1010 
1012  }
1013 
1014  Py_RETURN_NONE;
1015 }
1016 
1017 PyDoc_STRVAR(bpy_bmesh_to_mesh_doc,
1018  ".. method:: to_mesh(mesh)\n"
1019  "\n"
1020  " Writes this BMesh data into an existing Mesh datablock.\n"
1021  "\n"
1022  " :arg mesh: The mesh data to write into.\n"
1023  " :type mesh: :class:`Mesh`\n");
1024 static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
1025 {
1026  PyObject *py_mesh;
1027  Mesh *me;
1028  BMesh *bm;
1029 
1030  BPY_BM_CHECK_OBJ(self);
1031 
1032  if (!PyArg_ParseTuple(args, "O:to_mesh", &py_mesh) ||
1033  !(me = PyC_RNA_AsPointer(py_mesh, "Mesh"))) {
1034  return NULL;
1035  }
1036 
1037  /* we could allow this but its almost certainly _not_ what script authors want */
1038  if (me->edit_mesh) {
1039  PyErr_Format(PyExc_ValueError, "to_mesh(): Mesh '%s' is in editmode", me->id.name + 2);
1040  return NULL;
1041  }
1042 
1043  bm = self->bm;
1044 
1045  struct Main *bmain = NULL;
1046  struct BMeshToMeshParams params = {
1047  .update_shapekey_indices = true,
1048  };
1049  if (me->id.tag & LIB_TAG_NO_MAIN) {
1050  /* Mesh might be coming from a self-contained source like object.to_mesh(). No need to remap
1051  * anything in this case. */
1052  }
1053  else {
1055  bmain = G_MAIN; /* XXX UGLY! */
1056  params.calc_object_remap = true;
1057  }
1058 
1059  BM_mesh_bm_to_me(bmain, bm, me, &params);
1060 
1061  /* we could have the user do this but if they forget blender can easy crash
1062  * since the references arrays for the objects derived meshes are now invalid */
1064 
1065  Py_RETURN_NONE;
1066 }
1067 
1068 PyDoc_STRVAR(bpy_bmesh_from_object_doc,
1069  ".. method:: from_object(object, depsgraph, cage=False, face_normals=True)\n"
1070  "\n"
1071  " Initialize this bmesh from existing object data-block (only meshes are currently "
1072  "supported).\n"
1073  "\n"
1074  " :arg object: The object data to load.\n"
1075  " :type object: :class:`Object`\n"
1076  " :arg cage: Get the mesh as a deformed cage.\n"
1077  " :type cage: boolean\n"
1078  " :arg face_normals: Calculate face normals.\n"
1079  " :type face_normals: boolean\n");
1080 static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject *kw)
1081 {
1082  static const char *kwlist[] = {"object", "depsgraph", "deform", "cage", "face_normals", NULL};
1083  PyObject *py_object;
1084  PyObject *py_depsgraph;
1085  Object *ob, *ob_eval;
1086  struct Depsgraph *depsgraph;
1087  struct Scene *scene_eval;
1088  Mesh *me_eval;
1089  BMesh *bm;
1090  bool use_deform = true;
1091  bool use_cage = false;
1092  bool use_fnorm = true;
1093  const CustomData_MeshMasks data_masks = CD_MASK_BMESH;
1094 
1095  BPY_BM_CHECK_OBJ(self);
1096 
1097  if (!PyArg_ParseTupleAndKeywords(args,
1098  kw,
1099  "OO|O&O&O&:from_object",
1100  (char **)kwlist,
1101  &py_object,
1102  &py_depsgraph,
1103  PyC_ParseBool,
1104  &use_deform,
1105  PyC_ParseBool,
1106  &use_cage,
1107  PyC_ParseBool,
1108  &use_fnorm) ||
1109  !(ob = PyC_RNA_AsPointer(py_object, "Object")) ||
1110  !(depsgraph = PyC_RNA_AsPointer(py_depsgraph, "Depsgraph"))) {
1111  return NULL;
1112  }
1113 
1114  if (ob->type != OB_MESH) {
1115  PyErr_SetString(PyExc_ValueError,
1116  "from_object(...): currently only mesh objects are supported");
1117  return NULL;
1118  }
1119 
1120  if (use_deform == false) {
1121  PyErr_WarnEx(PyExc_FutureWarning,
1122  "from_object(...): the deform parameter is deprecated, assumed to be True, and "
1123  "will be removed in version 3.0",
1124  1);
1125  }
1126 
1127  const bool use_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER;
1128  scene_eval = DEG_get_evaluated_scene(depsgraph);
1129  ob_eval = DEG_get_evaluated_object(depsgraph, ob);
1130  bool need_free = false;
1131 
1132  /* Write the display mesh into the dummy mesh */
1133  if (use_render) {
1134  if (use_cage) {
1135  PyErr_SetString(PyExc_ValueError,
1136  "from_object(...): cage arg is unsupported when dependency graph "
1137  "evaluation mode is RENDER");
1138  return NULL;
1139  }
1140 
1141  me_eval = BKE_mesh_new_from_object(depsgraph, ob_eval, true, false);
1142  need_free = true;
1143  }
1144  else {
1145  if (use_cage) {
1146  me_eval = mesh_get_eval_deform(depsgraph, scene_eval, ob_eval, &data_masks);
1147  }
1148  else {
1149  me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &data_masks);
1150  }
1151  }
1152 
1153  if (me_eval == NULL) {
1154  PyErr_Format(PyExc_ValueError,
1155  "from_object(...): Object '%s' has no usable mesh data",
1156  ob->id.name + 2);
1157  return NULL;
1158  }
1159 
1160  bm = self->bm;
1161 
1163  me_eval,
1164  (&(struct BMeshFromMeshParams){
1165  .calc_face_normal = use_fnorm,
1166  }));
1167 
1168  if (need_free) {
1169  BKE_id_free(NULL, me_eval);
1170  }
1171 
1172  Py_RETURN_NONE;
1173 }
1174 
1176  bpy_bmesh_from_mesh_doc,
1177  ".. method:: from_mesh(mesh, face_normals=True, use_shape_key=False, shape_key_index=0)\n"
1178  "\n"
1179  " Initialize this bmesh from existing mesh datablock.\n"
1180  "\n"
1181  " :arg mesh: The mesh data to load.\n"
1182  " :type mesh: :class:`Mesh`\n"
1183  " :arg use_shape_key: Use the locations from a shape key.\n"
1184  " :type use_shape_key: boolean\n"
1185  " :arg shape_key_index: The shape key index to use.\n"
1186  " :type shape_key_index: int\n"
1187  "\n"
1188  " .. note::\n"
1189  "\n"
1190  " Multiple calls can be used to join multiple meshes.\n"
1191  "\n"
1192  " Custom-data layers are only copied from ``mesh`` on initialization.\n"
1193  " Further calls will copy custom-data to matching layers, layers missing on the target "
1194  "mesh wont be added.\n");
1195 static PyObject *bpy_bmesh_from_mesh(BPy_BMesh *self, PyObject *args, PyObject *kw)
1196 {
1197  static const char *kwlist[] = {"mesh", "face_normals", "use_shape_key", "shape_key_index", NULL};
1198  BMesh *bm;
1199  PyObject *py_mesh;
1200  Mesh *me;
1201  bool use_fnorm = true;
1202  bool use_shape_key = false;
1203  int shape_key_index = 0;
1204 
1205  BPY_BM_CHECK_OBJ(self);
1206 
1207  if (!PyArg_ParseTupleAndKeywords(args,
1208  kw,
1209  "O|O&O&i:from_mesh",
1210  (char **)kwlist,
1211  &py_mesh,
1212  PyC_ParseBool,
1213  &use_fnorm,
1214  PyC_ParseBool,
1215  &use_shape_key,
1216  &shape_key_index) ||
1217  !(me = PyC_RNA_AsPointer(py_mesh, "Mesh"))) {
1218  return NULL;
1219  }
1220 
1221  bm = self->bm;
1222 
1224  me,
1225  (&(struct BMeshFromMeshParams){
1226  .calc_face_normal = use_fnorm,
1227  .use_shapekey = use_shape_key,
1228  .active_shapekey = shape_key_index + 1,
1229  }));
1230 
1231  Py_RETURN_NONE;
1232 }
1233 
1234 PyDoc_STRVAR(bpy_bmesh_select_flush_mode_doc,
1235  ".. method:: select_flush_mode()\n"
1236  "\n"
1237  " flush selection based on the current mode current :class:`BMesh.select_mode`.\n");
1239 {
1240  BPY_BM_CHECK_OBJ(self);
1241 
1243 
1244  Py_RETURN_NONE;
1245 }
1246 
1247 PyDoc_STRVAR(bpy_bmesh_select_flush_doc,
1248  ".. method:: select_flush(select)\n"
1249  "\n"
1250  " Flush selection, independent of the current selection mode.\n"
1251  "\n"
1252  " :arg select: flush selection or de-selected elements.\n"
1253  " :type select: boolean\n");
1254 static PyObject *bpy_bmesh_select_flush(BPy_BMesh *self, PyObject *value)
1255 {
1256  int param;
1257 
1258  BPY_BM_CHECK_OBJ(self);
1259 
1260  if ((param = PyC_Long_AsBool(value)) == -1) {
1261  return NULL;
1262  }
1263 
1264  if (param) {
1266  }
1267  else {
1269  }
1270 
1271  Py_RETURN_NONE;
1272 }
1273 
1274 PyDoc_STRVAR(bpy_bmesh_normal_update_doc,
1275  ".. method:: normal_update()\n"
1276  "\n"
1277  " Update mesh normals.\n");
1278 static PyObject *bpy_bmesh_normal_update(BPy_BMesh *self)
1279 {
1280  BPY_BM_CHECK_OBJ(self);
1281 
1283 
1284  Py_RETURN_NONE;
1285 }
1286 
1287 PyDoc_STRVAR(bpy_bmesh_transform_doc,
1288  ".. method:: transform(matrix, filter=None)\n"
1289  "\n"
1290  " Transform the mesh (optionally filtering flagged data only).\n"
1291  "\n"
1292  " :arg matrix: transform matrix.\n"
1293  " :type matrix: 4x4 :class:`mathutils.Matrix`\n"
1294  " :arg filter: set of values in " BPY_BM_HFLAG_ALL_STR
1295  ".\n"
1296  " :type filter: set\n");
1297 static PyObject *bpy_bmesh_transform(BPy_BMElem *self, PyObject *args, PyObject *kw)
1298 {
1299  static const char *kwlist[] = {"matrix", "filter", NULL};
1300 
1301  MatrixObject *mat;
1302  PyObject *filter = NULL;
1303  int filter_flags = 0;
1304 
1305  BPY_BM_CHECK_OBJ(self);
1306 
1307  if (!PyArg_ParseTupleAndKeywords(args,
1308  kw,
1309  "O!|O!:transform",
1310  (char **)kwlist,
1311  &matrix_Type,
1312  &mat,
1313  &PySet_Type,
1314  &filter)) {
1315  return NULL;
1316  }
1317 
1318  BMVert *eve;
1319  BMIter iter;
1320  void *mat_ptr;
1321 
1322  if (BaseMath_ReadCallback(mat) == -1) {
1323  return NULL;
1324  }
1325  if (mat->num_col != 4 || mat->num_row != 4) {
1326  PyErr_SetString(PyExc_ValueError, "expected a 4x4 matrix");
1327  return NULL;
1328  }
1329 
1331  bpy_bm_hflag_all_flags, filter, &filter_flags, "bm.transform") == -1) {
1332  return NULL;
1333  }
1334 
1335  mat_ptr = mat->matrix;
1336 
1337  if (!filter_flags) {
1338  BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) {
1339  mul_m4_v3((float(*)[4])mat_ptr, eve->co);
1340  }
1341  }
1342  else {
1343  const char filter_flags_ch = (char)filter_flags;
1344  BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) {
1345  if (BM_elem_flag_test(eve, filter_flags_ch)) {
1346  mul_m4_v3((float(*)[4])mat_ptr, eve->co);
1347  }
1348  }
1349  }
1350 
1351  Py_RETURN_NONE;
1352 }
1353 
1354 PyDoc_STRVAR(bpy_bmesh_calc_volume_doc,
1355  ".. method:: calc_volume(signed=False)\n"
1356  "\n"
1357  " Calculate mesh volume based on face normals.\n"
1358  "\n"
1359  " :arg signed: when signed is true, negative values may be returned.\n"
1360  " :type signed: bool\n"
1361  " :return: The volume of the mesh.\n"
1362  " :rtype: float\n");
1363 static PyObject *bpy_bmesh_calc_volume(BPy_BMElem *self, PyObject *args, PyObject *kw)
1364 {
1365  static const char *kwlist[] = {"signed", NULL};
1366  PyObject *is_signed = Py_False;
1367 
1368  BPY_BM_CHECK_OBJ(self);
1369 
1370  if (!PyArg_ParseTupleAndKeywords(
1371  args, kw, "|O!:calc_volume", (char **)kwlist, &PyBool_Type, &is_signed)) {
1372  return NULL;
1373  }
1374 
1375  return PyFloat_FromDouble(BM_mesh_calc_volume(self->bm, is_signed != Py_False));
1376 }
1377 
1378 PyDoc_STRVAR(bpy_bmesh_calc_loop_triangles_doc,
1379  ".. method:: calc_loop_triangles()\n"
1380  "\n"
1381  " Calculate triangle tessellation from quads/ngons.\n"
1382  "\n"
1383  " :return: The triangulated faces.\n"
1384  " :rtype: list of :class:`BMLoop` tuples\n");
1386 {
1387  BMesh *bm;
1388 
1389  int looptris_tot;
1390  int tottri;
1391  BMLoop *(*looptris)[3];
1392 
1393  PyObject *ret;
1394  int i;
1395 
1396  BPY_BM_CHECK_OBJ(self);
1397 
1398  bm = self->bm;
1399 
1400  looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
1401  looptris = PyMem_MALLOC(sizeof(*looptris) * looptris_tot);
1402 
1403  BM_mesh_calc_tessellation(bm, looptris, &tottri);
1404 
1405  ret = PyList_New(tottri);
1406  for (i = 0; i < tottri; i++) {
1407  PyList_SET_ITEM(ret, i, BPy_BMLoop_Array_As_Tuple(bm, looptris[i], 3));
1408  }
1409 
1410  PyMem_FREE(looptris);
1411 
1412  return ret;
1413 }
1414 
1415 /* Elem
1416  * ---- */
1417 
1418 PyDoc_STRVAR(bpy_bm_elem_select_set_doc,
1419  ".. method:: select_set(select)\n"
1420  "\n"
1421  " Set the selection.\n"
1422  " This is different from the *select* attribute because it updates the selection "
1423  "state of associated geometry.\n"
1424  "\n"
1425  " :arg select: Select or de-select.\n"
1426  " :type select: boolean\n"
1427  "\n"
1428  " .. note::\n"
1429  "\n"
1430  " Currently this only flushes down, so selecting a face will select all its "
1431  "vertices but de-selecting a vertex "
1432  " won't de-select all the faces that use it, before finishing with a mesh "
1433  "typically flushing is still needed.\n");
1434 static PyObject *bpy_bm_elem_select_set(BPy_BMElem *self, PyObject *value)
1435 {
1436  int param;
1437 
1438  BPY_BM_CHECK_OBJ(self);
1439 
1440  if ((param = PyC_Long_AsBool(value)) == -1) {
1441  return NULL;
1442  }
1443 
1444  BM_elem_select_set(self->bm, self->ele, param);
1445 
1446  Py_RETURN_NONE;
1447 }
1448 
1449 PyDoc_STRVAR(bpy_bm_elem_hide_set_doc,
1450  ".. method:: hide_set(hide)\n"
1451  "\n"
1452  " Set the hide state.\n"
1453  " This is different from the *hide* attribute because it updates the selection and "
1454  "hide state of associated geometry.\n"
1455  "\n"
1456  " :arg hide: Hidden or visible.\n"
1457  " :type hide: boolean\n");
1458 static PyObject *bpy_bm_elem_hide_set(BPy_BMElem *self, PyObject *value)
1459 {
1460  int param;
1461 
1462  BPY_BM_CHECK_OBJ(self);
1463 
1464  if ((param = PyC_Long_AsBool(value)) == -1) {
1465  return NULL;
1466  }
1467 
1468  BM_elem_hide_set(self->bm, self->ele, param);
1469 
1470  Py_RETURN_NONE;
1471 }
1472 
1473 PyDoc_STRVAR(bpy_bm_elem_copy_from_doc,
1474  ".. method:: copy_from(other)\n"
1475  "\n"
1476  " Copy values from another element of matching type.\n");
1477 static PyObject *bpy_bm_elem_copy_from(BPy_BMElem *self, BPy_BMElem *value)
1478 {
1479  BPY_BM_CHECK_OBJ(self);
1480 
1481  if (Py_TYPE(self) != Py_TYPE(value)) {
1482  PyErr_Format(PyExc_TypeError,
1483  "expected element of type '%.200s' not '%.200s'",
1484  Py_TYPE(self)->tp_name,
1485  Py_TYPE(value)->tp_name);
1486  return NULL;
1487  }
1488 
1489  if (value->ele != self->ele) {
1490  BM_elem_attrs_copy_ex(value->bm, self->bm, value->ele, self->ele, 0xff, CD_MASK_BM_ELEM_PYPTR);
1491  }
1492 
1493  Py_RETURN_NONE;
1494 }
1495 
1496 /* Vert
1497  * ---- */
1498 
1499 PyDoc_STRVAR(bpy_bmvert_copy_from_vert_interp_doc,
1500  ".. method:: copy_from_vert_interp(vert_pair, fac)\n"
1501  "\n"
1502  " Interpolate the customdata from a vert between 2 other verts.\n"
1503  "\n"
1504  " :arg vert_pair: The vert to interpolate data from.\n"
1505  " :type vert_pair: :class:`BMVert`\n");
1506 static PyObject *bpy_bmvert_copy_from_vert_interp(BPy_BMVert *self, PyObject *args)
1507 {
1508  PyObject *vert_seq;
1509  float fac;
1510 
1511  BPY_BM_CHECK_OBJ(self);
1512 
1513  if (!PyArg_ParseTuple(args, "Of:BMVert.copy_from_vert_interp", &vert_seq, &fac)) {
1514  return NULL;
1515  }
1516 
1517  BMesh *bm = self->bm;
1518  BMVert **vert_array = NULL;
1519  Py_ssize_t vert_seq_len; /* always 2 */
1520 
1521  vert_array = BPy_BMElem_PySeq_As_Array(&bm,
1522  vert_seq,
1523  2,
1524  2,
1525  &vert_seq_len,
1526  BM_VERT,
1527  true,
1528  true,
1529  "BMVert.copy_from_vert_interp(...)");
1530 
1531  if (vert_array == NULL) {
1532  return NULL;
1533  }
1534 
1535  BM_data_interp_from_verts(bm, vert_array[0], vert_array[1], self->v, clamp_f(fac, 0.0f, 1.0f));
1536 
1537  PyMem_FREE(vert_array);
1538  Py_RETURN_NONE;
1539 }
1540 
1541 PyDoc_STRVAR(bpy_bmvert_copy_from_face_interp_doc,
1542  ".. method:: copy_from_face_interp(face)\n"
1543  "\n"
1544  " Interpolate the customdata from a face onto this loop (the loops vert should "
1545  "overlap the face).\n"
1546  "\n"
1547  " :arg face: The face to interpolate data from.\n"
1548  " :type face: :class:`BMFace`\n");
1549 static PyObject *bpy_bmvert_copy_from_face_interp(BPy_BMVert *self, PyObject *args)
1550 {
1551  BPy_BMFace *py_face = NULL;
1552 
1553  BPY_BM_CHECK_OBJ(self);
1554 
1555  if (!PyArg_ParseTuple(args, "O!:BMVert.copy_from_face_interp", &BPy_BMFace_Type, &py_face)) {
1556  return NULL;
1557  }
1558 
1559  BMesh *bm = self->bm;
1560 
1561  BPY_BM_CHECK_SOURCE_OBJ(bm, "copy_from_face_interp()", py_face);
1562 
1563  BM_vert_interp_from_face(bm, self->v, py_face->f);
1564 
1565  Py_RETURN_NONE;
1566 }
1567 
1568 PyDoc_STRVAR(bpy_bmvert_calc_edge_angle_doc,
1569  ".. method:: calc_edge_angle(fallback=None)\n"
1570  "\n"
1571  " Return the angle between this vert's two connected edges.\n"
1572  "\n"
1573  " :arg fallback: return this when the vert doesn't have 2 edges\n"
1574  " (instead of raising a :exc:`ValueError`).\n"
1575  " :type fallback: any\n"
1576  " :return: Angle between edges in radians.\n"
1577  " :rtype: float\n");
1578 static PyObject *bpy_bmvert_calc_edge_angle(BPy_BMVert *self, PyObject *args)
1579 {
1580  const float angle_invalid = -1.0f;
1581  float angle;
1582  PyObject *fallback = NULL;
1583 
1584  BPY_BM_CHECK_OBJ(self);
1585 
1586  if (!PyArg_ParseTuple(args, "|O:calc_edge_angle", &fallback)) {
1587  return NULL;
1588  }
1589 
1590  angle = BM_vert_calc_edge_angle_ex(self->v, angle_invalid);
1591 
1592  if (angle == angle_invalid) {
1593  /* avoid exception */
1594  if (fallback) {
1595  Py_INCREF(fallback);
1596  return fallback;
1597  }
1598 
1599  PyErr_SetString(PyExc_ValueError,
1600  "BMVert.calc_edge_angle(): "
1601  "vert must connect to exactly 2 edges");
1602  return NULL;
1603  }
1604 
1605  return PyFloat_FromDouble(angle);
1606 }
1607 
1609  bpy_bmvert_calc_shell_factor_doc,
1610  ".. method:: calc_shell_factor()\n"
1611  "\n"
1612  " Return a multiplier calculated based on the sharpness of the vertex.\n"
1613  " Where a flat surface gives 1.0, and higher values sharper edges.\n"
1614  " This is used to maintain shell thickness when offsetting verts along their normals.\n"
1615  "\n"
1616  " :return: offset multiplier\n"
1617  " :rtype: float\n");
1619 {
1620  BPY_BM_CHECK_OBJ(self);
1621  return PyFloat_FromDouble(BM_vert_calc_shell_factor(self->v));
1622 }
1623 
1624 PyDoc_STRVAR(bpy_bmvert_normal_update_doc,
1625  ".. method:: normal_update()\n"
1626  "\n"
1627  " Update vertex normal.\n");
1628 static PyObject *bpy_bmvert_normal_update(BPy_BMVert *self)
1629 {
1630  BPY_BM_CHECK_OBJ(self);
1631 
1633 
1634  Py_RETURN_NONE;
1635 }
1636 
1637 /* Edge
1638  * ---- */
1639 
1640 PyDoc_STRVAR(bpy_bmedge_calc_length_doc,
1641  ".. method:: calc_length()\n"
1642  "\n"
1643  " :return: The length between both verts.\n"
1644  " :rtype: float\n");
1645 static PyObject *bpy_bmedge_calc_length(BPy_BMEdge *self)
1646 {
1647  BPY_BM_CHECK_OBJ(self);
1648  return PyFloat_FromDouble(len_v3v3(self->e->v1->co, self->e->v2->co));
1649 }
1650 
1651 PyDoc_STRVAR(bpy_bmedge_calc_face_angle_doc,
1652  ".. method:: calc_face_angle(fallback=None)\n"
1653  "\n"
1654  " :arg fallback: return this when the edge doesn't have 2 faces\n"
1655  " (instead of raising a :exc:`ValueError`).\n"
1656  " :type fallback: any\n"
1657  " :return: The angle between 2 connected faces in radians.\n"
1658  " :rtype: float\n");
1659 static PyObject *bpy_bmedge_calc_face_angle(BPy_BMEdge *self, PyObject *args)
1660 {
1661  const float angle_invalid = -1.0f;
1662  float angle;
1663  PyObject *fallback = NULL;
1664 
1665  BPY_BM_CHECK_OBJ(self);
1666 
1667  if (!PyArg_ParseTuple(args, "|O:calc_face_angle", &fallback)) {
1668  return NULL;
1669  }
1670 
1671  angle = BM_edge_calc_face_angle_ex(self->e, angle_invalid);
1672 
1673  if (angle == angle_invalid) {
1674  /* avoid exception */
1675  if (fallback) {
1676  Py_INCREF(fallback);
1677  return fallback;
1678  }
1679 
1680  PyErr_SetString(PyExc_ValueError,
1681  "BMEdge.calc_face_angle(): "
1682  "edge doesn't use 2 faces");
1683  return NULL;
1684  }
1685 
1686  return PyFloat_FromDouble(angle);
1687 }
1688 
1690  bpy_bmedge_calc_face_angle_signed_doc,
1691  ".. method:: calc_face_angle_signed(fallback=None)\n"
1692  "\n"
1693  " :arg fallback: return this when the edge doesn't have 2 faces\n"
1694  " (instead of raising a :exc:`ValueError`).\n"
1695  " :type fallback: any\n"
1696  " :return: The angle between 2 connected faces in radians (negative for concave join).\n"
1697  " :rtype: float\n");
1698 static PyObject *bpy_bmedge_calc_face_angle_signed(BPy_BMEdge *self, PyObject *args)
1699 {
1700  const float angle_invalid = -FLT_MAX;
1701  float angle;
1702  PyObject *fallback = NULL;
1703 
1704  BPY_BM_CHECK_OBJ(self);
1705 
1706  if (!PyArg_ParseTuple(args, "|O:calc_face_angle_signed", &fallback)) {
1707  return NULL;
1708  }
1709 
1710  angle = BM_edge_calc_face_angle_signed_ex(self->e, angle_invalid);
1711 
1712  if (angle == angle_invalid) {
1713  /* avoid exception */
1714  if (fallback) {
1715  Py_INCREF(fallback);
1716  return fallback;
1717  }
1718 
1719  PyErr_SetString(PyExc_ValueError,
1720  "BMEdge.calc_face_angle_signed(): "
1721  "edge doesn't use 2 faces");
1722  return NULL;
1723  }
1724 
1725  return PyFloat_FromDouble(angle);
1726 }
1727 
1729  bpy_bmedge_calc_tangent_doc,
1730  ".. method:: calc_tangent(loop)\n"
1731  "\n"
1732  " Return the tangent at this edge relative to a face (pointing inward into the face).\n"
1733  " This uses the face normal for calculation.\n"
1734  "\n"
1735  " :arg loop: The loop used for tangent calculation.\n"
1736  " :type loop: :class:`BMLoop`\n"
1737  " :return: a normalized vector.\n"
1738  " :rtype: :class:`mathutils.Vector`\n");
1739 static PyObject *bpy_bmedge_calc_tangent(BPy_BMEdge *self, PyObject *args)
1740 {
1741  BPy_BMLoop *py_loop;
1742  BPY_BM_CHECK_OBJ(self);
1743 
1744  if (!PyArg_ParseTuple(args, "O!:BMEdge.calc_face_tangent", &BPy_BMLoop_Type, &py_loop)) {
1745  return NULL;
1746  }
1747 
1748  float vec[3];
1749  BPY_BM_CHECK_OBJ(py_loop);
1750  /* no need to check if they are from the same mesh or even connected */
1751  BM_edge_calc_face_tangent(self->e, py_loop->l, vec);
1752  return Vector_CreatePyObject(vec, 3, NULL);
1753 }
1754 
1756  bpy_bmedge_other_vert_doc,
1757  ".. method:: other_vert(vert)\n"
1758  "\n"
1759  " Return the other vertex on this edge or None if the vertex is not used by this edge.\n"
1760  "\n"
1761  " :arg vert: a vert in this edge.\n"
1762  " :type vert: :class:`BMVert`\n"
1763  " :return: The edges other vert.\n"
1764  " :rtype: :class:`BMVert` or None\n");
1765 static PyObject *bpy_bmedge_other_vert(BPy_BMEdge *self, BPy_BMVert *value)
1766 {
1767  BMVert *other;
1768  BPY_BM_CHECK_OBJ(self);
1769 
1770  if (!BPy_BMVert_Check(value)) {
1771  PyErr_Format(PyExc_TypeError,
1772  "BMEdge.other_vert(vert): BMVert expected, not '%.200s'",
1773  Py_TYPE(value)->tp_name);
1774  return NULL;
1775  }
1776 
1777  BPY_BM_CHECK_SOURCE_OBJ(self->bm, "BMEdge.other_vert(vert)", value);
1778 
1779  other = BM_edge_other_vert(self->e, value->v);
1780 
1781  if (other) {
1782  return BPy_BMVert_CreatePyObject(self->bm, other);
1783  }
1784 
1785  /* could raise an exception here */
1786  Py_RETURN_NONE;
1787 }
1788 
1789 PyDoc_STRVAR(bpy_bmedge_normal_update_doc,
1790  ".. method:: normal_update()\n"
1791  "\n"
1792  " Update edges vertex normals.\n");
1793 static PyObject *bpy_bmedge_normal_update(BPy_BMEdge *self)
1794 {
1795  BPY_BM_CHECK_OBJ(self);
1796 
1798 
1799  Py_RETURN_NONE;
1800 }
1801 
1802 /* Face
1803  * ---- */
1804 
1806  bpy_bmface_copy_from_face_interp_doc,
1807  ".. method:: copy_from_face_interp(face, vert=True)\n"
1808  "\n"
1809  " Interpolate the customdata from another face onto this one (faces should overlap).\n"
1810  "\n"
1811  " :arg face: The face to interpolate data from.\n"
1812  " :type face: :class:`BMFace`\n"
1813  " :arg vert: When True, also copy vertex data.\n"
1814  " :type vert: boolean\n");
1815 static PyObject *bpy_bmface_copy_from_face_interp(BPy_BMFace *self, PyObject *args)
1816 {
1817  BPy_BMFace *py_face = NULL;
1818  bool do_vertex = true;
1819 
1820  BPY_BM_CHECK_OBJ(self);
1821 
1822  if (!PyArg_ParseTuple(args,
1823  "O!|O&:BMFace.copy_from_face_interp",
1824  &BPy_BMFace_Type,
1825  &py_face,
1826  PyC_ParseBool,
1827  &do_vertex)) {
1828  return NULL;
1829  }
1830 
1831  BMesh *bm = self->bm;
1832 
1833  BPY_BM_CHECK_SOURCE_OBJ(bm, "BMFace.copy_from_face_interp(face)", py_face);
1834 
1835  BM_face_interp_from_face(bm, self->f, py_face->f, do_vertex);
1836 
1837  Py_RETURN_NONE;
1838 }
1839 
1840 PyDoc_STRVAR(bpy_bmface_copy_doc,
1841  ".. method:: copy(verts=True, edges=True)\n"
1842  "\n"
1843  " Make a copy of this face.\n"
1844  "\n"
1845  " :arg verts: When set, the faces verts will be duplicated too.\n"
1846  " :type verts: boolean\n"
1847  " :arg edges: When set, the faces edges will be duplicated too.\n"
1848  " :type edges: boolean\n"
1849  " :return: The newly created face.\n"
1850  " :rtype: :class:`BMFace`\n");
1851 static PyObject *bpy_bmface_copy(BPy_BMFace *self, PyObject *args, PyObject *kw)
1852 {
1853  static const char *kwlist[] = {"verts", "edges", NULL};
1854 
1855  BMesh *bm = self->bm;
1856  bool do_verts = true;
1857  bool do_edges = true;
1858 
1859  BMFace *f_cpy;
1860  BPY_BM_CHECK_OBJ(self);
1861 
1862  if (!PyArg_ParseTupleAndKeywords(args,
1863  kw,
1864  "|O&O&:BMFace.copy",
1865  (char **)kwlist,
1866  PyC_ParseBool,
1867  &do_verts,
1868  PyC_ParseBool,
1869  &do_edges)) {
1870  return NULL;
1871  }
1872 
1873  f_cpy = BM_face_copy(bm, bm, self->f, do_verts, do_edges);
1874 
1875  if (f_cpy) {
1876  return BPy_BMFace_CreatePyObject(bm, f_cpy);
1877  }
1878 
1879  PyErr_SetString(PyExc_ValueError, "BMFace.copy(): couldn't create the new face, internal error");
1880  return NULL;
1881 }
1882 
1883 PyDoc_STRVAR(bpy_bmface_calc_area_doc,
1884  ".. method:: calc_area()\n"
1885  "\n"
1886  " Return the area of the face.\n"
1887  "\n"
1888  " :return: Return the area of the face.\n"
1889  " :rtype: float\n");
1890 static PyObject *bpy_bmface_calc_area(BPy_BMFace *self)
1891 {
1892  BPY_BM_CHECK_OBJ(self);
1893  return PyFloat_FromDouble(BM_face_calc_area(self->f));
1894 }
1895 
1896 PyDoc_STRVAR(bpy_bmface_calc_perimeter_doc,
1897  ".. method:: calc_perimeter()\n"
1898  "\n"
1899  " Return the perimeter of the face.\n"
1900  "\n"
1901  " :return: Return the perimeter of the face.\n"
1902  " :rtype: float\n");
1903 static PyObject *bpy_bmface_calc_perimeter(BPy_BMFace *self)
1904 {
1905  BPY_BM_CHECK_OBJ(self);
1906  return PyFloat_FromDouble(BM_face_calc_perimeter(self->f));
1907 }
1908 
1909 PyDoc_STRVAR(bpy_bmface_calc_tangent_edge_doc,
1910  ".. method:: calc_tangent_edge()\n"
1911  "\n"
1912  " Return face tangent based on longest edge.\n"
1913  "\n"
1914  " :return: a normalized vector.\n"
1915  " :rtype: :class:`mathutils.Vector`\n");
1917 {
1918  float tangent[3];
1919 
1920  BPY_BM_CHECK_OBJ(self);
1921  BM_face_calc_tangent_edge(self->f, tangent);
1922  return Vector_CreatePyObject(tangent, 3, NULL);
1923 }
1924 
1925 PyDoc_STRVAR(bpy_bmface_calc_tangent_edge_pair_doc,
1926  ".. method:: calc_tangent_edge_pair()\n"
1927  "\n"
1928  " Return face tangent based on the two longest disconnected edges.\n"
1929  "\n"
1930  " - Tris: Use the edge pair with the most similar lengths.\n"
1931  " - Quads: Use the longest edge pair.\n"
1932  " - NGons: Use the two longest disconnected edges.\n"
1933  "\n"
1934  " :return: a normalized vector.\n"
1935  " :rtype: :class:`mathutils.Vector`\n");
1937 {
1938  float tangent[3];
1939 
1940  BPY_BM_CHECK_OBJ(self);
1941  BM_face_calc_tangent_edge_pair(self->f, tangent);
1942  return Vector_CreatePyObject(tangent, 3, NULL);
1943 }
1944 
1945 PyDoc_STRVAR(bpy_bmface_calc_tangent_edge_diagonal_doc,
1946  ".. method:: calc_tangent_edge_diagonal()\n"
1947  "\n"
1948  " Return face tangent based on the edge farthest from any vertex.\n"
1949  "\n"
1950  " :return: a normalized vector.\n"
1951  " :rtype: :class:`mathutils.Vector`\n");
1953 {
1954  float tangent[3];
1955 
1956  BPY_BM_CHECK_OBJ(self);
1958  return Vector_CreatePyObject(tangent, 3, NULL);
1959 }
1960 
1961 PyDoc_STRVAR(bpy_bmface_calc_tangent_vert_diagonal_doc,
1962  ".. method:: calc_tangent_vert_diagonal()\n"
1963  "\n"
1964  " Return face tangent based on the two most distent vertices.\n"
1965  "\n"
1966  " :return: a normalized vector.\n"
1967  " :rtype: :class:`mathutils.Vector`\n");
1969 {
1970  float tangent[3];
1971 
1972  BPY_BM_CHECK_OBJ(self);
1974  return Vector_CreatePyObject(tangent, 3, NULL);
1975 }
1976 
1977 PyDoc_STRVAR(bpy_bmface_calc_center_median_doc,
1978  ".. method:: calc_center_median()\n"
1979  "\n"
1980  " Return median center of the face.\n"
1981  "\n"
1982  " :return: a 3D vector.\n"
1983  " :rtype: :class:`mathutils.Vector`\n");
1985 {
1986  float cent[3];
1987 
1988  BPY_BM_CHECK_OBJ(self);
1989  BM_face_calc_center_median(self->f, cent);
1990  return Vector_CreatePyObject(cent, 3, NULL);
1991 }
1992 
1993 PyDoc_STRVAR(bpy_bmface_calc_center_median_weighted_doc,
1994  ".. method:: calc_center_median_weighted()\n"
1995  "\n"
1996  " Return median center of the face weighted by edge lengths.\n"
1997  "\n"
1998  " :return: a 3D vector.\n"
1999  " :rtype: :class:`mathutils.Vector`\n");
2001 {
2002  float cent[3];
2003 
2004  BPY_BM_CHECK_OBJ(self);
2006  return Vector_CreatePyObject(cent, 3, NULL);
2007 }
2008 
2009 PyDoc_STRVAR(bpy_bmface_calc_center_bounds_doc,
2010  ".. method:: calc_center_bounds()\n"
2011  "\n"
2012  " Return bounds center of the face.\n"
2013  "\n"
2014  " :return: a 3D vector.\n"
2015  " :rtype: :class:`mathutils.Vector`\n");
2017 {
2018  float cent[3];
2019 
2020  BPY_BM_CHECK_OBJ(self);
2021  BM_face_calc_center_bounds(self->f, cent);
2022  return Vector_CreatePyObject(cent, 3, NULL);
2023 }
2024 
2025 PyDoc_STRVAR(bpy_bmface_normal_update_doc,
2026  ".. method:: normal_update()\n"
2027  "\n"
2028  " Update face's normal.\n");
2029 static PyObject *bpy_bmface_normal_update(BPy_BMFace *self)
2030 {
2031  BPY_BM_CHECK_OBJ(self);
2032 
2034 
2035  Py_RETURN_NONE;
2036 }
2037 
2038 PyDoc_STRVAR(bpy_bmface_normal_flip_doc,
2039  ".. method:: normal_flip()\n"
2040  "\n"
2041  " Reverses winding of a face, which flips its normal.\n");
2042 static PyObject *bpy_bmface_normal_flip(BPy_BMFace *self)
2043 {
2044  BPY_BM_CHECK_OBJ(self);
2045 
2046  BM_face_normal_flip(self->bm, self->f);
2047 
2048  Py_RETURN_NONE;
2049 }
2050 
2051 /* Loop
2052  * ---- */
2053 
2054 PyDoc_STRVAR(bpy_bmloop_copy_from_face_interp_doc,
2055  ".. method:: copy_from_face_interp(face, vert=True, multires=True)\n"
2056  "\n"
2057  " Interpolate the customdata from a face onto this loop (the loops vert should "
2058  "overlap the face).\n"
2059  "\n"
2060  " :arg face: The face to interpolate data from.\n"
2061  " :type face: :class:`BMFace`\n"
2062  " :arg vert: When enabled, interpolate the loops vertex data (optional).\n"
2063  " :type vert: boolean\n"
2064  " :arg multires: When enabled, interpolate the loops multires data (optional).\n"
2065  " :type multires: boolean\n");
2066 static PyObject *bpy_bmloop_copy_from_face_interp(BPy_BMLoop *self, PyObject *args)
2067 {
2068  BPy_BMFace *py_face = NULL;
2069  bool do_vertex = true;
2070  bool do_multires = true;
2071 
2072  BPY_BM_CHECK_OBJ(self);
2073 
2074  if (!PyArg_ParseTuple(args,
2075  "O!|O&O&:BMLoop.copy_from_face_interp",
2076  &BPy_BMFace_Type,
2077  &py_face,
2078  PyC_ParseBool,
2079  &do_vertex,
2080  PyC_ParseBool,
2081  &do_multires)) {
2082  return NULL;
2083  }
2084 
2085  BMesh *bm = self->bm;
2086 
2087  BPY_BM_CHECK_SOURCE_OBJ(bm, "BMLoop.copy_from_face_interp(face)", py_face);
2088 
2089  BM_loop_interp_from_face(bm, self->l, py_face->f, do_vertex, do_multires);
2090 
2091  Py_RETURN_NONE;
2092 }
2093 
2094 PyDoc_STRVAR(bpy_bmloop_calc_angle_doc,
2095  ".. method:: calc_angle()\n"
2096  "\n"
2097  " Return the angle at this loops corner of the face.\n"
2098  " This is calculated so sharper corners give lower angles.\n"
2099  "\n"
2100  " :return: The angle in radians.\n"
2101  " :rtype: float\n");
2102 static PyObject *bpy_bmloop_calc_angle(BPy_BMLoop *self)
2103 {
2104  BPY_BM_CHECK_OBJ(self);
2105  return PyFloat_FromDouble(BM_loop_calc_face_angle(self->l));
2106 }
2107 
2108 PyDoc_STRVAR(bpy_bmloop_calc_normal_doc,
2109  ".. method:: calc_normal()\n"
2110  "\n"
2111  " Return normal at this loops corner of the face.\n"
2112  " Falls back to the face normal for straight lines.\n"
2113  "\n"
2114  " :return: a normalized vector.\n"
2115  " :rtype: :class:`mathutils.Vector`\n");
2116 static PyObject *bpy_bmloop_calc_normal(BPy_BMLoop *self)
2117 {
2118  float vec[3];
2119  BPY_BM_CHECK_OBJ(self);
2120  BM_loop_calc_face_normal(self->l, vec);
2121  return Vector_CreatePyObject(vec, 3, NULL);
2122 }
2123 
2125  bpy_bmloop_calc_tangent_doc,
2126  ".. method:: calc_tangent()\n"
2127  "\n"
2128  " Return the tangent at this loops corner of the face (pointing inward into the face).\n"
2129  " Falls back to the face normal for straight lines.\n"
2130  "\n"
2131  " :return: a normalized vector.\n"
2132  " :rtype: :class:`mathutils.Vector`\n");
2133 static PyObject *bpy_bmloop_calc_tangent(BPy_BMLoop *self)
2134 {
2135  float vec[3];
2136  BPY_BM_CHECK_OBJ(self);
2138  return Vector_CreatePyObject(vec, 3, NULL);
2139 }
2140 
2141 /* Vert Seq
2142  * -------- */
2143 PyDoc_STRVAR(bpy_bmvertseq_new_doc,
2144  ".. method:: new(co=(0.0, 0.0, 0.0), example=None)\n"
2145  "\n"
2146  " Create a new vertex.\n"
2147  "\n"
2148  " :arg co: The initial location of the vertex (optional argument).\n"
2149  " :type co: float triplet\n"
2150  " :arg example: Existing vert to initialize settings.\n"
2151  " :type example: :class:`BMVert`\n"
2152  " :return: The newly created edge.\n"
2153  " :rtype: :class:`BMVert`\n");
2154 static PyObject *bpy_bmvertseq_new(BPy_BMElemSeq *self, PyObject *args)
2155 {
2156  PyObject *py_co = NULL;
2157  BPy_BMVert *py_vert_example = NULL; /* optional */
2158 
2159  BPY_BM_CHECK_OBJ(self);
2160 
2161  if (!PyArg_ParseTuple(args, "|OO!:verts.new", &py_co, &BPy_BMVert_Type, &py_vert_example)) {
2162  return NULL;
2163  }
2164 
2165  BMesh *bm = self->bm;
2166  BMVert *v;
2167  float co[3] = {0.0f, 0.0f, 0.0f};
2168 
2169  if (py_vert_example) {
2170  BPY_BM_CHECK_OBJ(py_vert_example);
2171  }
2172 
2173  if (py_co && mathutils_array_parse(co, 3, 3, py_co, "verts.new(co)") == -1) {
2174  return NULL;
2175  }
2176 
2178 
2179  if (v == NULL) {
2180  PyErr_SetString(PyExc_ValueError,
2181  "faces.new(verts): couldn't create the new face, internal error");
2182  return NULL;
2183  }
2184 
2185  if (py_vert_example) {
2186  BM_elem_attrs_copy(py_vert_example->bm, bm, py_vert_example->v, v);
2187  }
2188 
2189  return BPy_BMVert_CreatePyObject(bm, v);
2190 }
2191 
2192 /* Edge Seq
2193  * -------- */
2194 PyDoc_STRVAR(bpy_bmedgeseq_new_doc,
2195  ".. method:: new(verts, example=None)\n"
2196  "\n"
2197  " Create a new edge from a given pair of verts.\n"
2198  "\n"
2199  " :arg verts: Vertex pair.\n"
2200  " :type verts: pair of :class:`BMVert`\n"
2201  " :arg example: Existing edge to initialize settings (optional argument).\n"
2202  " :type example: :class:`BMEdge`\n"
2203  " :return: The newly created edge.\n"
2204  " :rtype: :class:`BMEdge`\n");
2205 static PyObject *bpy_bmedgeseq_new(BPy_BMElemSeq *self, PyObject *args)
2206 {
2207  PyObject *vert_seq;
2208  BPy_BMEdge *py_edge_example = NULL; /* optional */
2209 
2210  BPY_BM_CHECK_OBJ(self);
2211 
2212  if (!PyArg_ParseTuple(args, "O|O!:edges.new", &vert_seq, &BPy_BMEdge_Type, &py_edge_example)) {
2213  return NULL;
2214  }
2215 
2216  BMesh *bm = self->bm;
2217  BMEdge *e;
2218  BMVert **vert_array = NULL;
2219  Py_ssize_t vert_seq_len; /* always 2 */
2220  PyObject *ret = NULL;
2221 
2222  if (py_edge_example) {
2223  BPY_BM_CHECK_OBJ(py_edge_example);
2224  }
2225 
2226  vert_array = BPy_BMElem_PySeq_As_Array(
2227  &bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, true, true, "edges.new(...)");
2228 
2229  if (vert_array == NULL) {
2230  return NULL;
2231  }
2232 
2233  if (BM_edge_exists(vert_array[0], vert_array[1])) {
2234  PyErr_SetString(PyExc_ValueError, "edges.new(): this edge exists");
2235  goto cleanup;
2236  }
2237 
2238  e = BM_edge_create(bm, vert_array[0], vert_array[1], NULL, BM_CREATE_NOP);
2239 
2240  if (e == NULL) {
2241  PyErr_SetString(PyExc_ValueError,
2242  "faces.new(verts): couldn't create the new face, internal error");
2243  goto cleanup;
2244  }
2245 
2246  if (py_edge_example) {
2247  BM_elem_attrs_copy(py_edge_example->bm, bm, py_edge_example->e, e);
2248  }
2249 
2251 
2252 cleanup:
2253  if (vert_array) {
2254  PyMem_FREE(vert_array);
2255  }
2256  return ret;
2257 }
2258 
2259 /* Face Seq
2260  * -------- */
2261 PyDoc_STRVAR(bpy_bmfaceseq_new_doc,
2262  ".. method:: new(verts, example=None)\n"
2263  "\n"
2264  " Create a new face from a given set of verts.\n"
2265  "\n"
2266  " :arg verts: Sequence of 3 or more verts.\n"
2267  " :type verts: :class:`BMVert`\n"
2268  " :arg example: Existing face to initialize settings (optional argument).\n"
2269  " :type example: :class:`BMFace`\n"
2270  " :return: The newly created face.\n"
2271  " :rtype: :class:`BMFace`\n");
2272 static PyObject *bpy_bmfaceseq_new(BPy_BMElemSeq *self, PyObject *args)
2273 {
2274  PyObject *vert_seq;
2275  BPy_BMFace *py_face_example = NULL; /* optional */
2276 
2277  BPY_BM_CHECK_OBJ(self);
2278 
2279  if (!PyArg_ParseTuple(args, "O|O!:faces.new", &vert_seq, &BPy_BMFace_Type, &py_face_example)) {
2280  return NULL;
2281  }
2282 
2283  BMesh *bm = self->bm;
2284  Py_ssize_t vert_seq_len;
2285 
2286  BMVert **vert_array = NULL;
2287 
2288  PyObject *ret = NULL;
2289 
2290  BMFace *f_new;
2291 
2292  if (py_face_example) {
2293  BPY_BM_CHECK_OBJ(py_face_example);
2294  }
2295 
2296  vert_array = BPy_BMElem_PySeq_As_Array(
2297  &bm, vert_seq, 3, PY_SSIZE_T_MAX, &vert_seq_len, BM_VERT, true, true, "faces.new(...)");
2298 
2299  if (vert_array == NULL) {
2300  return NULL;
2301  }
2302 
2303  /* check if the face exists */
2304  if (BM_face_exists(vert_array, vert_seq_len) != NULL) {
2305  PyErr_SetString(PyExc_ValueError, "faces.new(verts): face already exists");
2306  goto cleanup;
2307  }
2308 
2309  /* Go ahead and make the face!
2310  * --------------------------- */
2311 
2312  f_new = BM_face_create_verts(bm,
2313  vert_array,
2314  vert_seq_len,
2315  py_face_example ? py_face_example->f : NULL,
2316  BM_CREATE_NOP,
2317  true);
2318 
2319  if (UNLIKELY(f_new == NULL)) {
2320  PyErr_SetString(PyExc_ValueError,
2321  "faces.new(verts): couldn't create the new face, internal error");
2322  goto cleanup;
2323  }
2324 
2325  ret = BPy_BMFace_CreatePyObject(bm, f_new);
2326 
2327  /* pass through */
2328 cleanup:
2329  if (vert_array) {
2330  PyMem_FREE(vert_array);
2331  }
2332  return ret;
2333 }
2334 
2335 /* Elem Seq
2336  * -------- */
2337 
2338 PyDoc_STRVAR(bpy_bmvertseq_remove_doc,
2339  ".. method:: remove(vert)\n"
2340  "\n"
2341  " Remove a vert.\n");
2342 static PyObject *bpy_bmvertseq_remove(BPy_BMElemSeq *self, BPy_BMVert *value)
2343 {
2344  BPY_BM_CHECK_OBJ(self);
2345 
2346  if (!BPy_BMVert_Check(value)) {
2347  return NULL;
2348  }
2349 
2350  BMesh *bm = self->bm;
2351 
2352  BPY_BM_CHECK_SOURCE_OBJ(bm, "verts.remove(vert)", value);
2353 
2354  BM_vert_kill(bm, value->v);
2356 
2357  Py_RETURN_NONE;
2358 }
2359 
2360 PyDoc_STRVAR(bpy_bmedgeseq_remove_doc,
2361  ".. method:: remove(edge)\n"
2362  "\n"
2363  " Remove an edge.\n");
2364 static PyObject *bpy_bmedgeseq_remove(BPy_BMElemSeq *self, BPy_BMEdge *value)
2365 {
2366  BPY_BM_CHECK_OBJ(self);
2367 
2368  if (!BPy_BMEdge_Check(value)) {
2369  return NULL;
2370  }
2371 
2372  BMesh *bm = self->bm;
2373 
2374  BPY_BM_CHECK_SOURCE_OBJ(bm, "edges.remove(edges)", value);
2375 
2376  BM_edge_kill(bm, value->e);
2378 
2379  Py_RETURN_NONE;
2380 }
2381 
2382 PyDoc_STRVAR(bpy_bmfaceseq_remove_doc,
2383  ".. method:: remove(face)\n"
2384  "\n"
2385  " Remove a face.\n");
2386 static PyObject *bpy_bmfaceseq_remove(BPy_BMElemSeq *self, BPy_BMFace *value)
2387 {
2388  BPY_BM_CHECK_OBJ(self);
2389 
2390  if (!BPy_BMFace_Check(value)) {
2391  return NULL;
2392  }
2393 
2394  BMesh *bm = self->bm;
2395 
2396  BPY_BM_CHECK_SOURCE_OBJ(bm, "faces.remove(face)", value);
2397 
2398  BM_face_kill(bm, value->f);
2400 
2401  Py_RETURN_NONE;
2402 }
2403 
2404 PyDoc_STRVAR(bpy_bmedgeseq_get__method_doc,
2405  ".. method:: get(verts, fallback=None)\n"
2406  "\n"
2407  " Return an edge which uses the **verts** passed.\n"
2408  "\n"
2409  " :arg verts: Sequence of verts.\n"
2410  " :type verts: :class:`BMVert`\n"
2411  " :arg fallback: Return this value if nothing is found.\n"
2412  " :return: The edge found or None\n"
2413  " :rtype: :class:`BMEdge`\n");
2414 static PyObject *bpy_bmedgeseq_get__method(BPy_BMElemSeq *self, PyObject *args)
2415 {
2416  PyObject *vert_seq;
2417  PyObject *fallback = Py_None; /* optional */
2418 
2419  BPY_BM_CHECK_OBJ(self);
2420 
2421  if (!PyArg_ParseTuple(args, "O|O:edges.get", &vert_seq, &fallback)) {
2422  return NULL;
2423  }
2424 
2425  BMesh *bm = self->bm;
2426  BMEdge *e;
2427  BMVert **vert_array = NULL;
2428  Py_ssize_t vert_seq_len; /* always 2 */
2429  PyObject *ret = NULL;
2430 
2431  vert_array = BPy_BMElem_PySeq_As_Array(
2432  &bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, true, true, "edges.get(...)");
2433 
2434  if (vert_array == NULL) {
2435  return NULL;
2436  }
2437 
2438  if ((e = BM_edge_exists(vert_array[0], vert_array[1]))) {
2440  }
2441  else {
2442  ret = fallback;
2443  Py_INCREF(ret);
2444  }
2445 
2446  PyMem_FREE(vert_array);
2447  return ret;
2448 }
2449 
2450 PyDoc_STRVAR(bpy_bmfaceseq_get__method_doc,
2451  ".. method:: get(verts, fallback=None)\n"
2452  "\n"
2453  " Return a face which uses the **verts** passed.\n"
2454  "\n"
2455  " :arg verts: Sequence of verts.\n"
2456  " :type verts: :class:`BMVert`\n"
2457  " :arg fallback: Return this value if nothing is found.\n"
2458  " :return: The face found or None\n"
2459  " :rtype: :class:`BMFace`\n");
2460 static PyObject *bpy_bmfaceseq_get__method(BPy_BMElemSeq *self, PyObject *args)
2461 {
2462  PyObject *vert_seq;
2463  PyObject *fallback = Py_None; /* optional */
2464 
2465  BPY_BM_CHECK_OBJ(self);
2466 
2467  if (!PyArg_ParseTuple(args, "O|O:faces.get", &vert_seq, &fallback)) {
2468  return NULL;
2469  }
2470 
2471  BMesh *bm = self->bm;
2472  BMFace *f = NULL;
2473  BMVert **vert_array = NULL;
2474  Py_ssize_t vert_seq_len;
2475  PyObject *ret = NULL;
2476 
2477  vert_array = BPy_BMElem_PySeq_As_Array(
2478  &bm, vert_seq, 1, PY_SSIZE_T_MAX, &vert_seq_len, BM_VERT, true, true, "faces.get(...)");
2479 
2480  if (vert_array == NULL) {
2481  return NULL;
2482  }
2483 
2484  f = BM_face_exists(vert_array, vert_seq_len);
2485  if (f != NULL) {
2487  }
2488  else {
2489  ret = fallback;
2490  Py_INCREF(ret);
2491  }
2492 
2493  PyMem_FREE(vert_array);
2494  return ret;
2495 }
2496 
2498  bpy_bmelemseq_index_update_doc,
2499  ".. method:: index_update()\n"
2500  "\n"
2501  " Initialize the index values of this sequence.\n"
2502  "\n"
2503  " This is the equivalent of looping over all elements and assigning the index values.\n"
2504  "\n"
2505  " .. code-block:: python\n"
2506  "\n"
2507  " for index, ele in enumerate(sequence):\n"
2508  " ele.index = index\n"
2509  "\n"
2510  " .. note::\n"
2511  "\n"
2512  " Running this on sequences besides :class:`BMesh.verts`, :class:`BMesh.edges`, "
2513  ":class:`BMesh.faces`\n"
2514  " works but wont result in each element having a valid index, instead its order in the "
2515  "sequence will be set.\n");
2517 {
2518  BMesh *bm = self->bm;
2519 
2520  BPY_BM_CHECK_OBJ(self);
2521 
2522  switch ((BMIterType)self->itype) {
2523  case BM_VERTS_OF_MESH:
2525  break;
2526  case BM_EDGES_OF_MESH:
2528  break;
2529  case BM_FACES_OF_MESH:
2531  break;
2532  default: {
2533  BMIter iter;
2534  BMElem *ele;
2535  int index = 0;
2536  const char htype = bm_iter_itype_htype_map[self->itype];
2537 
2538  BM_ITER_BPY_BM_SEQ (ele, &iter, self) {
2539  BM_elem_index_set(ele, index); /* set_dirty! */
2540  index++;
2541  }
2542 
2543  /* since this isn't the normal vert/edge/face loops,
2544  * we're setting dirty values here. so tag as dirty. */
2545  bm->elem_index_dirty |= htype;
2546 
2547  break;
2548  }
2549  }
2550 
2551  Py_RETURN_NONE;
2552 }
2553 
2554 PyDoc_STRVAR(bpy_bmelemseq_ensure_lookup_table_doc,
2555  ".. method:: ensure_lookup_table()\n"
2556  "\n"
2557  " Ensure internal data needed for int subscription is initialized with "
2558  "verts/edges/faces, eg ``bm.verts[index]``.\n"
2559  "\n"
2560  " This needs to be called again after adding/removing data in this sequence.");
2562 {
2563  BPY_BM_CHECK_OBJ(self);
2564 
2566 
2567  Py_RETURN_NONE;
2568 }
2569 
2571  bpy_bmelemseq_sort_doc,
2572  ".. method:: sort(key=None, reverse=False)\n"
2573  "\n"
2574  " Sort the elements of this sequence, using an optional custom sort key.\n"
2575  " Indices of elements are not changed, BMElemeSeq.index_update() can be used for that.\n"
2576  "\n"
2577  " :arg key: The key that sets the ordering of the elements.\n"
2578  " :type key: :function: returning a number\n"
2579  " :arg reverse: Reverse the order of the elements\n"
2580  " :type reverse: :boolean:\n"
2581  "\n"
2582  " .. note::\n"
2583  "\n"
2584  " When the 'key' argument is not provided, the elements are reordered following their "
2585  "current index value.\n"
2586  " In particular this can be used by setting indices manually before calling this "
2587  "method.\n"
2588  "\n"
2589  " .. warning::\n"
2590  "\n"
2591  " Existing references to the N'th element, will continue to point the data at that "
2592  "index.\n");
2593 
2594 /* Use a static variable here because there is the need to sort some array
2595  * doing comparisons on elements of another array, qsort_r would have been
2596  * wonderful to use here, but unfortunately it is not standard and it's not
2597  * portable across different platforms.
2598  *
2599  * If a portable alternative to qsort_r becomes available, remove this static
2600  * var hack!
2601  *
2602  * Note: the functions below assumes the keys array has been allocated and it
2603  * has enough elements to complete the task.
2604  */
2605 
2606 static int bpy_bmelemseq_sort_cmp_by_keys_ascending(const void *index1_v,
2607  const void *index2_v,
2608  void *keys_v)
2609 {
2610  const double *keys = keys_v;
2611  const int *index1 = (int *)index1_v;
2612  const int *index2 = (int *)index2_v;
2613 
2614  if (keys[*index1] < keys[*index2]) {
2615  return -1;
2616  }
2617  if (keys[*index1] > keys[*index2]) {
2618  return 1;
2619  }
2620 
2621  return 0;
2622 }
2623 
2624 static int bpy_bmelemseq_sort_cmp_by_keys_descending(const void *index1_v,
2625  const void *index2_v,
2626  void *keys_v)
2627 {
2628  return -bpy_bmelemseq_sort_cmp_by_keys_ascending(index1_v, index2_v, keys_v);
2629 }
2630 
2631 static PyObject *bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, PyObject *kw)
2632 {
2633  static const char *kwlist[] = {"key", "reverse", NULL};
2634  PyObject *keyfunc = NULL; /* optional */
2635  bool do_reverse = false; /* optional */
2636 
2637  const char htype = bm_iter_itype_htype_map[self->itype];
2638  int n_elem;
2639 
2640  BMIter iter;
2641  BMElem *ele;
2642 
2643  double *keys;
2644  int *elem_idx;
2645  uint *elem_map_idx;
2646  int (*elem_idx_compare_by_keys)(const void *, const void *, void *);
2647 
2648  uint *vert_idx = NULL;
2649  uint *edge_idx = NULL;
2650  uint *face_idx = NULL;
2651  int i;
2652 
2653  BMesh *bm = self->bm;
2654 
2655  BPY_BM_CHECK_OBJ(self);
2656 
2657  if (args != NULL) {
2658  if (!PyArg_ParseTupleAndKeywords(args,
2659  kw,
2660  "|OO&:BMElemSeq.sort",
2661  (char **)kwlist,
2662  &keyfunc,
2663  PyC_ParseBool,
2664  &do_reverse)) {
2665  return NULL;
2666  }
2667  }
2668 
2669  if (keyfunc != NULL && !PyCallable_Check(keyfunc)) {
2670  PyErr_SetString(PyExc_TypeError, "the 'key' argument is not a callable object");
2671  return NULL;
2672  }
2673 
2674  n_elem = BM_mesh_elem_count(bm, htype);
2675  if (n_elem <= 1) {
2676  /* 0 or 1 elements: sorted already */
2677  Py_RETURN_NONE;
2678  }
2679 
2680  keys = PyMem_MALLOC(sizeof(*keys) * n_elem);
2681  if (keys == NULL) {
2682  PyErr_NoMemory();
2683  return NULL;
2684  }
2685 
2686  i = 0;
2687  BM_ITER_BPY_BM_SEQ (ele, &iter, self) {
2688  if (keyfunc != NULL) {
2689  PyObject *py_elem;
2690  PyObject *index;
2691 
2692  py_elem = BPy_BMElem_CreatePyObject(self->bm, (BMHeader *)ele);
2693  index = PyObject_CallFunctionObjArgs(keyfunc, py_elem, NULL);
2694  Py_DECREF(py_elem);
2695  if (index == NULL) {
2696  /* No need to set the exception here,
2697  * PyObject_CallFunctionObjArgs() does that */
2698  PyMem_FREE(keys);
2699  return NULL;
2700  }
2701 
2702  if ((keys[i] = PyFloat_AsDouble(index)) == -1 && PyErr_Occurred()) {
2703  PyErr_SetString(PyExc_ValueError,
2704  "the value returned by the 'key' function is not a number");
2705  Py_DECREF(index);
2706  PyMem_FREE(keys);
2707  return NULL;
2708  }
2709 
2710  Py_DECREF(index);
2711  }
2712  else {
2713  /* If the 'key' function is not provided we sort
2714  * according to the current index values */
2715  keys[i] = ele->head.index;
2716  }
2717 
2718  i++;
2719  }
2720 
2721  elem_idx = PyMem_MALLOC(sizeof(*elem_idx) * n_elem);
2722  if (elem_idx == NULL) {
2723  PyErr_NoMemory();
2724  PyMem_FREE(keys);
2725  return NULL;
2726  }
2727 
2728  /* Initialize the element index array */
2729  range_vn_i(elem_idx, n_elem, 0);
2730 
2731  /* Sort the index array according to the order of the 'keys' array */
2732  if (do_reverse) {
2733  elem_idx_compare_by_keys = bpy_bmelemseq_sort_cmp_by_keys_descending;
2734  }
2735  else {
2736  elem_idx_compare_by_keys = bpy_bmelemseq_sort_cmp_by_keys_ascending;
2737  }
2738 
2739  BLI_qsort_r(elem_idx, n_elem, sizeof(*elem_idx), elem_idx_compare_by_keys, keys);
2740 
2741  elem_map_idx = PyMem_MALLOC(sizeof(*elem_map_idx) * n_elem);
2742  if (elem_map_idx == NULL) {
2743  PyErr_NoMemory();
2744  PyMem_FREE(elem_idx);
2745  PyMem_FREE(keys);
2746  return NULL;
2747  }
2748 
2749  /* Initialize the map array
2750  *
2751  * We need to know the index such that if used as the new_index in
2752  * BM_mesh_remap() will give the order of the sorted keys like in
2753  * elem_idx */
2754  for (i = 0; i < n_elem; i++) {
2755  elem_map_idx[elem_idx[i]] = i;
2756  }
2757 
2758  switch ((BMIterType)self->itype) {
2759  case BM_VERTS_OF_MESH:
2760  vert_idx = elem_map_idx;
2761  break;
2762  case BM_EDGES_OF_MESH:
2763  edge_idx = elem_map_idx;
2764  break;
2765  case BM_FACES_OF_MESH:
2766  face_idx = elem_map_idx;
2767  break;
2768  default:
2769  PyErr_Format(PyExc_TypeError, "element type %d not supported", self->itype);
2770  PyMem_FREE(elem_map_idx);
2771  PyMem_FREE(elem_idx);
2772  PyMem_FREE(keys);
2773  return NULL;
2774  }
2775 
2776  BM_mesh_remap(bm, vert_idx, edge_idx, face_idx);
2777 
2778  PyMem_FREE(elem_map_idx);
2779  PyMem_FREE(elem_idx);
2780  PyMem_FREE(keys);
2781 
2782  Py_RETURN_NONE;
2783 }
2784 
2785 static struct PyMethodDef bpy_bmesh_methods[] = {
2786  /* utility */
2787  {"copy", (PyCFunction)bpy_bmesh_copy, METH_NOARGS, bpy_bmesh_copy_doc},
2788  {"clear", (PyCFunction)bpy_bmesh_clear, METH_NOARGS, bpy_bmesh_clear_doc},
2789  {"free", (PyCFunction)bpy_bmesh_free, METH_NOARGS, bpy_bmesh_free_doc},
2790 
2791  /* conversion */
2792  {"from_object",
2793  (PyCFunction)bpy_bmesh_from_object,
2794  METH_VARARGS | METH_KEYWORDS,
2795  bpy_bmesh_from_object_doc},
2796  {"from_mesh",
2797  (PyCFunction)bpy_bmesh_from_mesh,
2798  METH_VARARGS | METH_KEYWORDS,
2799  bpy_bmesh_from_mesh_doc},
2800  {"to_mesh", (PyCFunction)bpy_bmesh_to_mesh, METH_VARARGS, bpy_bmesh_to_mesh_doc},
2801 
2802  /* meshdata */
2803  {"select_flush_mode",
2804  (PyCFunction)bpy_bmesh_select_flush_mode,
2805  METH_NOARGS,
2806  bpy_bmesh_select_flush_mode_doc},
2807  {"select_flush", (PyCFunction)bpy_bmesh_select_flush, METH_O, bpy_bmesh_select_flush_doc},
2808  {"normal_update",
2809  (PyCFunction)bpy_bmesh_normal_update,
2810  METH_NOARGS,
2811  bpy_bmesh_normal_update_doc},
2812  {"transform",
2813  (PyCFunction)bpy_bmesh_transform,
2814  METH_VARARGS | METH_KEYWORDS,
2815  bpy_bmesh_transform_doc},
2816 
2817  /* calculations */
2818  {"calc_volume",
2819  (PyCFunction)bpy_bmesh_calc_volume,
2820  METH_VARARGS | METH_KEYWORDS,
2821  bpy_bmesh_calc_volume_doc},
2822  {"calc_loop_triangles",
2823  (PyCFunction)bpy_bmesh_calc_loop_triangles,
2824  METH_NOARGS,
2825  bpy_bmesh_calc_loop_triangles_doc},
2826  {NULL, NULL, 0, NULL},
2827 };
2828 
2829 static struct PyMethodDef bpy_bmvert_methods[] = {
2830  {"select_set", (PyCFunction)bpy_bm_elem_select_set, METH_O, bpy_bm_elem_select_set_doc},
2831  {"hide_set", (PyCFunction)bpy_bm_elem_hide_set, METH_O, bpy_bm_elem_hide_set_doc},
2832  {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc},
2833  {"copy_from_face_interp",
2834  (PyCFunction)bpy_bmvert_copy_from_face_interp,
2835  METH_VARARGS,
2836  bpy_bmvert_copy_from_face_interp_doc},
2837  {"copy_from_vert_interp",
2838  (PyCFunction)bpy_bmvert_copy_from_vert_interp,
2839  METH_VARARGS,
2840  bpy_bmvert_copy_from_vert_interp_doc},
2841 
2842  {"calc_edge_angle",
2843  (PyCFunction)bpy_bmvert_calc_edge_angle,
2844  METH_VARARGS,
2845  bpy_bmvert_calc_edge_angle_doc},
2846  {"calc_shell_factor",
2847  (PyCFunction)bpy_bmvert_calc_shell_factor,
2848  METH_NOARGS,
2849  bpy_bmvert_calc_shell_factor_doc},
2850 
2851  {"normal_update",
2852  (PyCFunction)bpy_bmvert_normal_update,
2853  METH_NOARGS,
2854  bpy_bmvert_normal_update_doc},
2855 
2856  {NULL, NULL, 0, NULL},
2857 };
2858 
2859 static struct PyMethodDef bpy_bmedge_methods[] = {
2860  {"select_set", (PyCFunction)bpy_bm_elem_select_set, METH_O, bpy_bm_elem_select_set_doc},
2861  {"hide_set", (PyCFunction)bpy_bm_elem_hide_set, METH_O, bpy_bm_elem_hide_set_doc},
2862  {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc},
2863 
2864  {"other_vert", (PyCFunction)bpy_bmedge_other_vert, METH_O, bpy_bmedge_other_vert_doc},
2865 
2866  {"calc_length", (PyCFunction)bpy_bmedge_calc_length, METH_NOARGS, bpy_bmedge_calc_length_doc},
2867  {"calc_face_angle",
2868  (PyCFunction)bpy_bmedge_calc_face_angle,
2869  METH_VARARGS,
2870  bpy_bmedge_calc_face_angle_doc},
2871  {"calc_face_angle_signed",
2872  (PyCFunction)bpy_bmedge_calc_face_angle_signed,
2873  METH_VARARGS,
2874  bpy_bmedge_calc_face_angle_signed_doc},
2875  {"calc_tangent",
2876  (PyCFunction)bpy_bmedge_calc_tangent,
2877  METH_VARARGS,
2878  bpy_bmedge_calc_tangent_doc},
2879 
2880  {"normal_update",
2881  (PyCFunction)bpy_bmedge_normal_update,
2882  METH_NOARGS,
2883  bpy_bmedge_normal_update_doc},
2884 
2885  {NULL, NULL, 0, NULL},
2886 };
2887 
2888 static struct PyMethodDef bpy_bmface_methods[] = {
2889  {"select_set", (PyCFunction)bpy_bm_elem_select_set, METH_O, bpy_bm_elem_select_set_doc},
2890  {"hide_set", (PyCFunction)bpy_bm_elem_hide_set, METH_O, bpy_bm_elem_hide_set_doc},
2891 
2892  {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc},
2893  {"copy_from_face_interp",
2894  (PyCFunction)bpy_bmface_copy_from_face_interp,
2895  METH_O,
2896  bpy_bmface_copy_from_face_interp_doc},
2897 
2898  {"copy", (PyCFunction)bpy_bmface_copy, METH_VARARGS | METH_KEYWORDS, bpy_bmface_copy_doc},
2899 
2900  {"calc_area", (PyCFunction)bpy_bmface_calc_area, METH_NOARGS, bpy_bmface_calc_area_doc},
2901  {"calc_perimeter",
2902  (PyCFunction)bpy_bmface_calc_perimeter,
2903  METH_NOARGS,
2904  bpy_bmface_calc_perimeter_doc},
2905  {"calc_tangent_edge",
2906  (PyCFunction)bpy_bmface_calc_tangent_edge,
2907  METH_NOARGS,
2908  bpy_bmface_calc_tangent_edge_doc},
2909  {"calc_tangent_edge_pair",
2910  (PyCFunction)bpy_bmface_calc_tangent_edge_pair,
2911  METH_NOARGS,
2912  bpy_bmface_calc_tangent_edge_pair_doc},
2913  {"calc_tangent_edge_diagonal",
2915  METH_NOARGS,
2916  bpy_bmface_calc_tangent_edge_diagonal_doc},
2917  {"calc_tangent_vert_diagonal",
2919  METH_NOARGS,
2920  bpy_bmface_calc_tangent_vert_diagonal_doc},
2921  {"calc_center_median",
2922  (PyCFunction)bpy_bmface_calc_center_mean,
2923  METH_NOARGS,
2924  bpy_bmface_calc_center_median_doc},
2925  {"calc_center_median_weighted",
2927  METH_NOARGS,
2928  bpy_bmface_calc_center_median_weighted_doc},
2929  {"calc_center_bounds",
2930  (PyCFunction)bpy_bmface_calc_center_bounds,
2931  METH_NOARGS,
2932  bpy_bmface_calc_center_bounds_doc},
2933 
2934  {"normal_update",
2935  (PyCFunction)bpy_bmface_normal_update,
2936  METH_NOARGS,
2937  bpy_bmface_normal_update_doc},
2938  {"normal_flip", (PyCFunction)bpy_bmface_normal_flip, METH_NOARGS, bpy_bmface_normal_flip_doc},
2939 
2940  {NULL, NULL, 0, NULL},
2941 };
2942 
2943 static struct PyMethodDef bpy_bmloop_methods[] = {
2944  {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc},
2945  {"copy_from_face_interp",
2946  (PyCFunction)bpy_bmloop_copy_from_face_interp,
2947  METH_O,
2948  bpy_bmloop_copy_from_face_interp_doc},
2949 
2950  {"calc_angle", (PyCFunction)bpy_bmloop_calc_angle, METH_NOARGS, bpy_bmloop_calc_angle_doc},
2951  {"calc_normal", (PyCFunction)bpy_bmloop_calc_normal, METH_NOARGS, bpy_bmloop_calc_normal_doc},
2952  {"calc_tangent",
2953  (PyCFunction)bpy_bmloop_calc_tangent,
2954  METH_NOARGS,
2955  bpy_bmloop_calc_tangent_doc},
2956  {NULL, NULL, 0, NULL},
2957 };
2958 
2959 static struct PyMethodDef bpy_bmelemseq_methods[] = {
2960  /* odd function, initializes index values */
2961  {"index_update",
2962  (PyCFunction)bpy_bmelemseq_index_update,
2963  METH_NOARGS,
2964  bpy_bmelemseq_index_update_doc},
2965  {NULL, NULL, 0, NULL},
2966 };
2967 
2968 static struct PyMethodDef bpy_bmvertseq_methods[] = {
2969  {"new", (PyCFunction)bpy_bmvertseq_new, METH_VARARGS, bpy_bmvertseq_new_doc},
2970  {"remove", (PyCFunction)bpy_bmvertseq_remove, METH_O, bpy_bmvertseq_remove_doc},
2971 
2972  /* odd function, initializes index values */
2973  {"index_update",
2974  (PyCFunction)bpy_bmelemseq_index_update,
2975  METH_NOARGS,
2976  bpy_bmelemseq_index_update_doc},
2977  {"ensure_lookup_table",
2978  (PyCFunction)bpy_bmelemseq_ensure_lookup_table,
2979  METH_NOARGS,
2980  bpy_bmelemseq_ensure_lookup_table_doc},
2981  {"sort",
2982  (PyCFunction)bpy_bmelemseq_sort,
2983  METH_VARARGS | METH_KEYWORDS,
2984  bpy_bmelemseq_sort_doc},
2985  {NULL, NULL, 0, NULL},
2986 };
2987 
2988 static struct PyMethodDef bpy_bmedgeseq_methods[] = {
2989  {"new", (PyCFunction)bpy_bmedgeseq_new, METH_VARARGS, bpy_bmedgeseq_new_doc},
2990  {"remove", (PyCFunction)bpy_bmedgeseq_remove, METH_O, bpy_bmedgeseq_remove_doc},
2991  /* 'bpy_bmelemseq_get' for different purpose */
2992  {"get", (PyCFunction)bpy_bmedgeseq_get__method, METH_VARARGS, bpy_bmedgeseq_get__method_doc},
2993 
2994  /* odd function, initializes index values */
2995  {"index_update",
2996  (PyCFunction)bpy_bmelemseq_index_update,
2997  METH_NOARGS,
2998  bpy_bmelemseq_index_update_doc},
2999  {"ensure_lookup_table",
3000  (PyCFunction)bpy_bmelemseq_ensure_lookup_table,
3001  METH_NOARGS,
3002  bpy_bmelemseq_ensure_lookup_table_doc},
3003  {"sort",
3004  (PyCFunction)bpy_bmelemseq_sort,
3005  METH_VARARGS | METH_KEYWORDS,
3006  bpy_bmelemseq_sort_doc},
3007  {NULL, NULL, 0, NULL},
3008 };
3009 
3010 static struct PyMethodDef bpy_bmfaceseq_methods[] = {
3011  {"new", (PyCFunction)bpy_bmfaceseq_new, METH_VARARGS, bpy_bmfaceseq_new_doc},
3012  {"remove", (PyCFunction)bpy_bmfaceseq_remove, METH_O, bpy_bmfaceseq_remove_doc},
3013  /* 'bpy_bmelemseq_get' for different purpose */
3014  {"get", (PyCFunction)bpy_bmfaceseq_get__method, METH_VARARGS, bpy_bmfaceseq_get__method_doc},
3015 
3016  /* odd function, initializes index values */
3017  {"index_update",
3018  (PyCFunction)bpy_bmelemseq_index_update,
3019  METH_NOARGS,
3020  bpy_bmelemseq_index_update_doc},
3021  {"ensure_lookup_table",
3022  (PyCFunction)bpy_bmelemseq_ensure_lookup_table,
3023  METH_NOARGS,
3024  bpy_bmelemseq_ensure_lookup_table_doc},
3025  {"sort",
3026  (PyCFunction)bpy_bmelemseq_sort,
3027  METH_VARARGS | METH_KEYWORDS,
3028  bpy_bmelemseq_sort_doc},
3029  {NULL, NULL, 0, NULL},
3030 };
3031 
3032 static struct PyMethodDef bpy_bmloopseq_methods[] = {
3033  /* odd function, initializes index values */
3034  /* no: index_update() function since we cant iterate over loops */
3035  /* no: sort() function since we cant iterate over loops */
3036  {NULL, NULL, 0, NULL},
3037 };
3038 
3039 /* Sequences
3040  * ========= */
3041 
3042 /* BMElemSeq / Iter
3043  * ---------------- */
3044 
3045 static PyTypeObject *bpy_bm_itype_as_pytype(const char itype)
3046 {
3047  /* should cover all types */
3048  switch ((BMIterType)itype) {
3049  case BM_VERTS_OF_MESH:
3050  case BM_VERTS_OF_FACE:
3051  case BM_VERTS_OF_EDGE:
3052  return &BPy_BMVert_Type;
3053 
3054  case BM_EDGES_OF_MESH:
3055  case BM_EDGES_OF_FACE:
3056  case BM_EDGES_OF_VERT:
3057  return &BPy_BMEdge_Type;
3058 
3059  case BM_FACES_OF_MESH:
3060  case BM_FACES_OF_EDGE:
3061  case BM_FACES_OF_VERT:
3062  return &BPy_BMFace_Type;
3063 
3064  // case BM_ALL_LOOPS_OF_FACE:
3065  case BM_LOOPS_OF_FACE:
3066  case BM_LOOPS_OF_EDGE:
3067  case BM_LOOPS_OF_VERT:
3068  case BM_LOOPS_OF_LOOP:
3069  return &BPy_BMLoop_Type;
3070  }
3071 
3072  return NULL;
3073 }
3074 
3075 static Py_ssize_t bpy_bmelemseq_length(BPy_BMElemSeq *self)
3076 {
3077  BPY_BM_CHECK_INT(self);
3078 
3079  /* first check if the size is known */
3080  switch ((BMIterType)self->itype) {
3081  /* main-types */
3082  case BM_VERTS_OF_MESH:
3083  return self->bm->totvert;
3084  case BM_EDGES_OF_MESH:
3085  return self->bm->totedge;
3086  case BM_FACES_OF_MESH:
3087  return self->bm->totface;
3088 
3089  /* sub-types */
3090  case BM_VERTS_OF_FACE:
3091  case BM_EDGES_OF_FACE:
3092  case BM_LOOPS_OF_FACE:
3093  BPY_BM_CHECK_INT(self->py_ele);
3094  return ((BMFace *)self->py_ele->ele)->len;
3095 
3096  case BM_VERTS_OF_EDGE:
3097  return 2;
3098 
3099  default:
3100  /* quiet compiler */
3101  break;
3102  }
3103 
3104  /* loop over all items, avoid this if we can */
3105  {
3106  BMIter iter;
3107  BMHeader *ele;
3108  Py_ssize_t tot = 0;
3109 
3110  BM_ITER_BPY_BM_SEQ (ele, &iter, self) {
3111  tot++;
3112  }
3113  return tot;
3114  }
3115 }
3116 
3117 static PyObject *bpy_bmelemseq_subscript_int(BPy_BMElemSeq *self, int keynum)
3118 {
3119  BPY_BM_CHECK_OBJ(self);
3120 
3121  if (keynum < 0) {
3122  /* only get length on negative value, may loop entire seq */
3123  keynum += bpy_bmelemseq_length(self);
3124  }
3125  if (keynum >= 0) {
3126  if (self->itype <= BM_FACES_OF_MESH) {
3127  if ((self->bm->elem_table_dirty & bm_iter_itype_htype_map[self->itype]) == 0) {
3128  BMHeader *ele = NULL;
3129  switch (self->itype) {
3130  case BM_VERTS_OF_MESH:
3131  if (keynum < self->bm->totvert) {
3132  ele = (BMHeader *)self->bm->vtable[keynum];
3133  }
3134  break;
3135  case BM_EDGES_OF_MESH:
3136  if (keynum < self->bm->totedge) {
3137  ele = (BMHeader *)self->bm->etable[keynum];
3138  }
3139  break;
3140  case BM_FACES_OF_MESH:
3141  if (keynum < self->bm->totface) {
3142  ele = (BMHeader *)self->bm->ftable[keynum];
3143  }
3144  break;
3145  }
3146  if (ele) {
3147  return BPy_BMElem_CreatePyObject(self->bm, ele);
3148  }
3149  /* fall through to index error below */
3150  }
3151  else {
3152  PyErr_SetString(PyExc_IndexError,
3153  "BMElemSeq[index]: outdated internal index table, "
3154  "run ensure_lookup_table() first");
3155  return NULL;
3156  }
3157  }
3158  else {
3159  BMHeader *ele = BM_iter_at_index(
3160  self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL, keynum);
3161  if (ele) {
3162  return BPy_BMElem_CreatePyObject(self->bm, ele);
3163  }
3164  }
3165  }
3166 
3167  PyErr_Format(PyExc_IndexError, "BMElemSeq[index]: index %d out of range", keynum);
3168  return NULL;
3169 }
3170 
3172  Py_ssize_t start,
3173  Py_ssize_t stop)
3174 {
3175  BMIter iter;
3176  int count = 0;
3177  bool ok;
3178 
3179  PyObject *list;
3180  BMHeader *ele;
3181 
3182  BPY_BM_CHECK_OBJ(self);
3183 
3184  list = PyList_New(0);
3185 
3186  ok = BM_iter_init(&iter, self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL);
3187 
3188  BLI_assert(ok == true);
3189 
3190  if (UNLIKELY(ok == false)) {
3191  return list;
3192  }
3193 
3194  /* first loop up-until the start */
3195  for (ok = true; ok; ok = (BM_iter_step(&iter) != NULL)) {
3196  if (count == start) {
3197  break;
3198  }
3199  count++;
3200  }
3201 
3202  /* add items until stop */
3203  while ((ele = BM_iter_step(&iter))) {
3204  PyList_APPEND(list, BPy_BMElem_CreatePyObject(self->bm, ele));
3205 
3206  count++;
3207  if (count == stop) {
3208  break;
3209  }
3210  }
3211 
3212  return list;
3213 }
3214 
3215 static PyObject *bpy_bmelemseq_subscript(BPy_BMElemSeq *self, PyObject *key)
3216 {
3217  /* don't need error check here */
3218  if (PyIndex_Check(key)) {
3219  const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
3220  if (i == -1 && PyErr_Occurred()) {
3221  return NULL;
3222  }
3223  return bpy_bmelemseq_subscript_int(self, i);
3224  }
3225  if (PySlice_Check(key)) {
3226  PySliceObject *key_slice = (PySliceObject *)key;
3227  Py_ssize_t step = 1;
3228 
3229  if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
3230  return NULL;
3231  }
3232  if (step != 1) {
3233  PyErr_SetString(PyExc_TypeError, "BMElemSeq[slice]: slice steps not supported");
3234  return NULL;
3235  }
3236  if (key_slice->start == Py_None && key_slice->stop == Py_None) {
3237  return bpy_bmelemseq_subscript_slice(self, 0, PY_SSIZE_T_MAX);
3238  }
3239 
3240  Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
3241 
3242  /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
3243  if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
3244  return NULL;
3245  }
3246  if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
3247  return NULL;
3248  }
3249 
3250  if (start < 0 || stop < 0) {
3251  /* only get the length for negative values */
3252  const Py_ssize_t len = bpy_bmelemseq_length(self);
3253  if (start < 0) {
3254  start += len;
3255  CLAMP_MIN(start, 0);
3256  }
3257  if (stop < 0) {
3258  stop += len;
3259  CLAMP_MIN(stop, 0);
3260  }
3261  }
3262 
3263  if (stop - start <= 0) {
3264  return PyList_New(0);
3265  }
3266 
3267  return bpy_bmelemseq_subscript_slice(self, start, stop);
3268  }
3269 
3270  PyErr_SetString(PyExc_AttributeError, "BMElemSeq[key]: invalid key, key must be an int");
3271  return NULL;
3272 }
3273 
3274 static int bpy_bmelemseq_contains(BPy_BMElemSeq *self, PyObject *value)
3275 {
3276  BPY_BM_CHECK_INT(self);
3277 
3278  if (Py_TYPE(value) == bpy_bm_itype_as_pytype(self->itype)) {
3279  BPy_BMElem *value_bm_ele = (BPy_BMElem *)value;
3280  if (value_bm_ele->bm == self->bm) {
3281  BMElem *ele, *ele_test = value_bm_ele->ele;
3282  BMIter iter;
3283  BM_ITER_BPY_BM_SEQ (ele, &iter, self) {
3284  if (ele == ele_test) {
3285  return 1;
3286  }
3287  }
3288  }
3289  }
3290 
3291  return 0;
3292 }
3293 
3294 /* BMElem (customdata)
3295  * ------------------- */
3296 
3297 static PyObject *bpy_bmelem_subscript(BPy_BMElem *self, BPy_BMLayerItem *key)
3298 {
3299  BPY_BM_CHECK_OBJ(self);
3300 
3301  return BPy_BMLayerItem_GetItem(self, key);
3302 }
3303 
3304 static int bpy_bmelem_ass_subscript(BPy_BMElem *self, BPy_BMLayerItem *key, PyObject *value)
3305 {
3306  BPY_BM_CHECK_INT(self);
3307 
3308  return BPy_BMLayerItem_SetItem(self, key, value);
3309 }
3310 
3311 static PySequenceMethods bpy_bmelemseq_as_sequence = {
3312  (lenfunc)bpy_bmelemseq_length, /* sq_length */
3313  NULL, /* sq_concat */
3314  NULL, /* sq_repeat */
3315  (ssizeargfunc)bpy_bmelemseq_subscript_int,
3316  /* sq_item */ /* Only set this so PySequence_Check() returns True */
3317  NULL, /* sq_slice */
3318  (ssizeobjargproc)NULL, /* sq_ass_item */
3319  NULL, /* *was* sq_ass_slice */
3320  (objobjproc)bpy_bmelemseq_contains, /* sq_contains */
3321  (binaryfunc)NULL, /* sq_inplace_concat */
3322  (ssizeargfunc)NULL, /* sq_inplace_repeat */
3323 };
3324 
3325 static PyMappingMethods bpy_bmelemseq_as_mapping = {
3326  (lenfunc)bpy_bmelemseq_length, /* mp_length */
3327  (binaryfunc)bpy_bmelemseq_subscript, /* mp_subscript */
3328  (objobjargproc)NULL, /* mp_ass_subscript */
3329 };
3330 
3331 /* for customdata access */
3332 static PyMappingMethods bpy_bm_elem_as_mapping = {
3333  (lenfunc)NULL,
3334  /* mp_length */ /* keep this empty, messes up 'if elem: ...' test */
3335  (binaryfunc)bpy_bmelem_subscript, /* mp_subscript */
3336  (objobjargproc)bpy_bmelem_ass_subscript, /* mp_ass_subscript */
3337 };
3338 
3339 /* Iterator
3340  * -------- */
3341 
3342 static PyObject *bpy_bmelemseq_iter(BPy_BMElemSeq *self)
3343 {
3344  BPy_BMIter *py_iter;
3345 
3346  BPY_BM_CHECK_OBJ(self);
3347  py_iter = (BPy_BMIter *)BPy_BMIter_CreatePyObject(self->bm);
3348  BM_iter_init(&(py_iter->iter), self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL);
3349  return (PyObject *)py_iter;
3350 }
3351 
3352 static PyObject *bpy_bmiter_next(BPy_BMIter *self)
3353 {
3354  BMHeader *ele = BM_iter_step(&self->iter);
3355  if (ele == NULL) {
3356  PyErr_SetNone(PyExc_StopIteration);
3357  return NULL;
3358  }
3359 
3360  return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, ele);
3361 }
3362 
3363 /* Dealloc Functions
3364  * ================= */
3365 
3366 static void bpy_bmesh_dealloc(BPy_BMesh *self)
3367 {
3368  BMesh *bm = self->bm;
3369 
3370  /* have have been freed by bmesh */
3371  if (bm) {
3373 
3376  }
3379  }
3382  }
3385  }
3386 
3387  bm->py_handle = NULL;
3388 
3389  if ((self->flag & BPY_BMFLAG_IS_WRAPPED) == 0) {
3390  BM_mesh_free(bm);
3391  }
3392  }
3393 
3394  PyObject_DEL(self);
3395 }
3396 
3397 static void bpy_bmvert_dealloc(BPy_BMElem *self)
3398 {
3399  BMesh *bm = self->bm;
3400  if (bm) {
3401  void **ptr = CustomData_bmesh_get(&bm->vdata, self->ele->head.data, CD_BM_ELEM_PYPTR);
3402  if (ptr) {
3403  *ptr = NULL;
3404  }
3405  }
3406  PyObject_DEL(self);
3407 }
3408 
3409 static void bpy_bmedge_dealloc(BPy_BMElem *self)
3410 {
3411  BMesh *bm = self->bm;
3412  if (bm) {
3413  void **ptr = CustomData_bmesh_get(&bm->edata, self->ele->head.data, CD_BM_ELEM_PYPTR);
3414  if (ptr) {
3415  *ptr = NULL;
3416  }
3417  }
3418  PyObject_DEL(self);
3419 }
3420 
3421 static void bpy_bmface_dealloc(BPy_BMElem *self)
3422 {
3423  BMesh *bm = self->bm;
3424  if (bm) {
3425  void **ptr = CustomData_bmesh_get(&bm->pdata, self->ele->head.data, CD_BM_ELEM_PYPTR);
3426  if (ptr) {
3427  *ptr = NULL;
3428  }
3429  }
3430  PyObject_DEL(self);
3431 }
3432 
3433 static void bpy_bmloop_dealloc(BPy_BMElem *self)
3434 {
3435  BMesh *bm = self->bm;
3436  if (bm) {
3437  void **ptr = CustomData_bmesh_get(&bm->ldata, self->ele->head.data, CD_BM_ELEM_PYPTR);
3438  if (ptr) {
3439  *ptr = NULL;
3440  }
3441  }
3442  PyObject_DEL(self);
3443 }
3444 
3446 {
3447  Py_XDECREF(self->py_ele);
3448 
3449  PyObject_DEL(self);
3450 }
3451 
3452 /* not sure where this should go */
3453 static Py_hash_t bpy_bm_elem_hash(PyObject *self)
3454 {
3455  return _Py_HashPointer(((BPy_BMElem *)self)->ele);
3456 }
3457 
3458 static Py_hash_t bpy_bm_hash(PyObject *self)
3459 {
3460  return _Py_HashPointer(((BPy_BMesh *)self)->bm);
3461 }
3462 
3463 /* Type Docstrings
3464  * =============== */
3465 
3466 PyDoc_STRVAR(bpy_bmesh_doc, "The BMesh data structure\n");
3467 PyDoc_STRVAR(bpy_bmvert_doc, "The BMesh vertex type\n");
3468 PyDoc_STRVAR(bpy_bmedge_doc, "The BMesh edge connecting 2 verts\n");
3469 PyDoc_STRVAR(bpy_bmface_doc, "The BMesh face with 3 or more sides\n");
3470 PyDoc_STRVAR(bpy_bmloop_doc,
3471  "This is normally accessed from :class:`BMFace.loops` where each face loop "
3472  "represents a corner of the face.\n");
3473 PyDoc_STRVAR(bpy_bmelemseq_doc,
3474  "General sequence type used for accessing any sequence of\n"
3475  ":class:`BMVert`, :class:`BMEdge`, :class:`BMFace`, :class:`BMLoop`.\n"
3476  "\n"
3477  "When accessed via :class:`BMesh.verts`, :class:`BMesh.edges`, :class:`BMesh.faces`\n"
3478  "there are also functions to create/remomove items.\n");
3479 PyDoc_STRVAR(bpy_bmiter_doc,
3480  "Internal BMesh type for looping over verts/faces/edges,\n"
3481  "used for iterating over :class:`BMElemSeq` types.\n");
3482 
3483 static PyObject *bpy_bmesh_repr(BPy_BMesh *self)
3484 {
3485  BMesh *bm = self->bm;
3486 
3487  if (bm) {
3488  return PyUnicode_FromFormat("<BMesh(%p), totvert=%d, totedge=%d, totface=%d, totloop=%d>",
3489  bm,
3490  bm->totvert,
3491  bm->totedge,
3492  bm->totface,
3493  bm->totloop);
3494  }
3495 
3496  return PyUnicode_FromFormat("<BMesh dead at %p>", self);
3497 }
3498 
3499 static PyObject *bpy_bmvert_repr(BPy_BMVert *self)
3500 {
3501  BMesh *bm = self->bm;
3502 
3503  if (bm) {
3504  BMVert *v = self->v;
3505  return PyUnicode_FromFormat("<BMVert(%p), index=%d>", v, BM_elem_index_get(v));
3506  }
3507 
3508  return PyUnicode_FromFormat("<BMVert dead at %p>", self);
3509 }
3510 
3511 static PyObject *bpy_bmedge_repr(BPy_BMEdge *self)
3512 {
3513  BMesh *bm = self->bm;
3514 
3515  if (bm) {
3516  BMEdge *e = self->e;
3517  return PyUnicode_FromFormat("<BMEdge(%p), index=%d, verts=(%p/%d, %p/%d)>",
3518  e,
3520  e->v1,
3521  BM_elem_index_get(e->v1),
3522  e->v2,
3523  BM_elem_index_get(e->v2));
3524  }
3525 
3526  return PyUnicode_FromFormat("<BMEdge dead at %p>", self);
3527 }
3528 
3529 static PyObject *bpy_bmface_repr(BPy_BMFace *self)
3530 {
3531  BMesh *bm = self->bm;
3532 
3533  if (bm) {
3534  BMFace *f = self->f;
3535  return PyUnicode_FromFormat(
3536  "<BMFace(%p), index=%d, totverts=%d>", f, BM_elem_index_get(f), f->len);
3537  }
3538 
3539  return PyUnicode_FromFormat("<BMFace dead at %p>", self);
3540 }
3541 
3542 static PyObject *bpy_bmloop_repr(BPy_BMLoop *self)
3543 {
3544  BMesh *bm = self->bm;
3545 
3546  if (bm) {
3547  BMLoop *l = self->l;
3548  return PyUnicode_FromFormat("<BMLoop(%p), index=%d, vert=%p/%d, edge=%p/%d, face=%p/%d>",
3549  l,
3551  l->v,
3552  BM_elem_index_get(l->v),
3553  l->e,
3554  BM_elem_index_get(l->e),
3555  l->f,
3556  BM_elem_index_get(l->f));
3557  }
3558 
3559  return PyUnicode_FromFormat("<BMLoop dead at %p>", self);
3560 }
3561 
3562 /* Types
3563  * ===== */
3564 
3565 PyTypeObject BPy_BMesh_Type;
3566 PyTypeObject BPy_BMVert_Type;
3567 PyTypeObject BPy_BMEdge_Type;
3568 PyTypeObject BPy_BMFace_Type;
3569 PyTypeObject BPy_BMLoop_Type;
3570 PyTypeObject BPy_BMElemSeq_Type;
3571 PyTypeObject BPy_BMVertSeq_Type;
3572 PyTypeObject BPy_BMEdgeSeq_Type;
3573 PyTypeObject BPy_BMFaceSeq_Type;
3574 PyTypeObject BPy_BMLoopSeq_Type;
3575 PyTypeObject BPy_BMIter_Type;
3576 
3578 {
3579  BPy_BMesh_Type.tp_basicsize = sizeof(BPy_BMesh);
3580  BPy_BMVert_Type.tp_basicsize = sizeof(BPy_BMVert);
3581  BPy_BMEdge_Type.tp_basicsize = sizeof(BPy_BMEdge);
3582  BPy_BMFace_Type.tp_basicsize = sizeof(BPy_BMFace);
3583  BPy_BMLoop_Type.tp_basicsize = sizeof(BPy_BMLoop);
3584  BPy_BMElemSeq_Type.tp_basicsize = sizeof(BPy_BMElemSeq);
3585  BPy_BMVertSeq_Type.tp_basicsize = sizeof(BPy_BMElemSeq);
3586  BPy_BMEdgeSeq_Type.tp_basicsize = sizeof(BPy_BMElemSeq);
3587  BPy_BMFaceSeq_Type.tp_basicsize = sizeof(BPy_BMElemSeq);
3588  BPy_BMLoopSeq_Type.tp_basicsize = sizeof(BPy_BMElemSeq);
3589  BPy_BMIter_Type.tp_basicsize = sizeof(BPy_BMIter);
3590 
3591  BPy_BMesh_Type.tp_name = "BMesh";
3592  BPy_BMVert_Type.tp_name = "BMVert";
3593  BPy_BMEdge_Type.tp_name = "BMEdge";
3594  BPy_BMFace_Type.tp_name = "BMFace";
3595  BPy_BMLoop_Type.tp_name = "BMLoop";
3596  BPy_BMElemSeq_Type.tp_name = "BMElemSeq";
3597  BPy_BMVertSeq_Type.tp_name = "BMVertSeq";
3598  BPy_BMEdgeSeq_Type.tp_name = "BMEdgeSeq";
3599  BPy_BMFaceSeq_Type.tp_name = "BMFaceSeq";
3600  BPy_BMLoopSeq_Type.tp_name = "BMLoopSeq";
3601  BPy_BMIter_Type.tp_name = "BMIter";
3602 
3603  BPy_BMesh_Type.tp_doc = bpy_bmesh_doc;
3604  BPy_BMVert_Type.tp_doc = bpy_bmvert_doc;
3605  BPy_BMEdge_Type.tp_doc = bpy_bmedge_doc;
3606  BPy_BMFace_Type.tp_doc = bpy_bmface_doc;
3607  BPy_BMLoop_Type.tp_doc = bpy_bmloop_doc;
3608  BPy_BMElemSeq_Type.tp_doc = bpy_bmelemseq_doc;
3609  BPy_BMVertSeq_Type.tp_doc = NULL;
3610  BPy_BMEdgeSeq_Type.tp_doc = NULL;
3611  BPy_BMFaceSeq_Type.tp_doc = NULL;
3612  BPy_BMLoopSeq_Type.tp_doc = NULL;
3613  BPy_BMIter_Type.tp_doc = bpy_bmiter_doc;
3614 
3615  BPy_BMesh_Type.tp_repr = (reprfunc)bpy_bmesh_repr;
3616  BPy_BMVert_Type.tp_repr = (reprfunc)bpy_bmvert_repr;
3617  BPy_BMEdge_Type.tp_repr = (reprfunc)bpy_bmedge_repr;
3618  BPy_BMFace_Type.tp_repr = (reprfunc)bpy_bmface_repr;
3619  BPy_BMLoop_Type.tp_repr = (reprfunc)bpy_bmloop_repr;
3620  BPy_BMElemSeq_Type.tp_repr = NULL;
3621  BPy_BMVertSeq_Type.tp_repr = NULL;
3622  BPy_BMEdgeSeq_Type.tp_repr = NULL;
3623  BPy_BMFaceSeq_Type.tp_repr = NULL;
3624  BPy_BMLoopSeq_Type.tp_repr = NULL;
3625  BPy_BMIter_Type.tp_repr = NULL;
3626 
3627  BPy_BMesh_Type.tp_getset = bpy_bmesh_getseters;
3632  BPy_BMElemSeq_Type.tp_getset = NULL;
3637  BPy_BMIter_Type.tp_getset = NULL;
3638 
3639  BPy_BMesh_Type.tp_methods = bpy_bmesh_methods;
3640  BPy_BMVert_Type.tp_methods = bpy_bmvert_methods;
3641  BPy_BMEdge_Type.tp_methods = bpy_bmedge_methods;
3642  BPy_BMFace_Type.tp_methods = bpy_bmface_methods;
3643  BPy_BMLoop_Type.tp_methods = bpy_bmloop_methods;
3649  BPy_BMIter_Type.tp_methods = NULL;
3650 
3651  /*BPy_BMElem_Check() uses bpy_bm_elem_hash() to check types.
3652  * if this changes update the macro */
3653  BPy_BMesh_Type.tp_hash = bpy_bm_hash;
3658  BPy_BMElemSeq_Type.tp_hash = NULL;
3659  BPy_BMVertSeq_Type.tp_hash = NULL;
3660  BPy_BMEdgeSeq_Type.tp_hash = NULL;
3661  BPy_BMFaceSeq_Type.tp_hash = NULL;
3662  BPy_BMLoopSeq_Type.tp_hash = NULL;
3663  BPy_BMIter_Type.tp_hash = NULL;
3664 
3669  BPy_BMLoopSeq_Type.tp_as_sequence = NULL; /* this is not a seq really, only for layer access */
3670 
3675  BPy_BMLoopSeq_Type.tp_as_mapping = NULL; /* this is not a seq really, only for layer access */
3676 
3677  /* layer access */
3678  BPy_BMVert_Type.tp_as_mapping = &bpy_bm_elem_as_mapping;
3679  BPy_BMEdge_Type.tp_as_mapping = &bpy_bm_elem_as_mapping;
3680  BPy_BMFace_Type.tp_as_mapping = &bpy_bm_elem_as_mapping;
3681  BPy_BMLoop_Type.tp_as_mapping = &bpy_bm_elem_as_mapping;
3682 
3683  BPy_BMElemSeq_Type.tp_iter = (getiterfunc)bpy_bmelemseq_iter;
3684  BPy_BMVertSeq_Type.tp_iter = (getiterfunc)bpy_bmelemseq_iter;
3685  BPy_BMEdgeSeq_Type.tp_iter = (getiterfunc)bpy_bmelemseq_iter;
3686  BPy_BMFaceSeq_Type.tp_iter = (getiterfunc)bpy_bmelemseq_iter;
3687  BPy_BMLoopSeq_Type.tp_iter = NULL; /* no mapping */
3688 
3689  /* only 1 iteratir so far */
3690  BPy_BMIter_Type.tp_iternext = (iternextfunc)bpy_bmiter_next;
3691  BPy_BMIter_Type.tp_iter = PyObject_SelfIter;
3692 
3693  BPy_BMesh_Type.tp_dealloc = (destructor)bpy_bmesh_dealloc;
3694  BPy_BMVert_Type.tp_dealloc = (destructor)bpy_bmvert_dealloc;
3695  BPy_BMEdge_Type.tp_dealloc = (destructor)bpy_bmedge_dealloc;
3696  BPy_BMFace_Type.tp_dealloc = (destructor)bpy_bmface_dealloc;
3697  BPy_BMLoop_Type.tp_dealloc = (destructor)bpy_bmloop_dealloc;
3698  BPy_BMElemSeq_Type.tp_dealloc = (destructor)bpy_bmelemseq_dealloc;
3699  BPy_BMVertSeq_Type.tp_dealloc = (destructor)bpy_bmelemseq_dealloc;
3700  BPy_BMEdgeSeq_Type.tp_dealloc = (destructor)bpy_bmelemseq_dealloc;
3701  BPy_BMFaceSeq_Type.tp_dealloc = (destructor)bpy_bmelemseq_dealloc;
3702  BPy_BMLoopSeq_Type.tp_dealloc = (destructor)bpy_bmelemseq_dealloc;
3703  BPy_BMIter_Type.tp_dealloc = NULL;
3704 
3705  BPy_BMesh_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3706  BPy_BMVert_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3707  BPy_BMEdge_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3708  BPy_BMFace_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3709  BPy_BMLoop_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3710  BPy_BMElemSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3711  BPy_BMVertSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3712  BPy_BMEdgeSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3713  BPy_BMFaceSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3714  BPy_BMLoopSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3715  BPy_BMIter_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3716 
3717  PyType_Ready(&BPy_BMesh_Type);
3718  PyType_Ready(&BPy_BMVert_Type);
3719  PyType_Ready(&BPy_BMEdge_Type);
3720  PyType_Ready(&BPy_BMFace_Type);
3721  PyType_Ready(&BPy_BMLoop_Type);
3722  PyType_Ready(&BPy_BMElemSeq_Type);
3723  PyType_Ready(&BPy_BMVertSeq_Type);
3724  PyType_Ready(&BPy_BMEdgeSeq_Type);
3725  PyType_Ready(&BPy_BMFaceSeq_Type);
3726  PyType_Ready(&BPy_BMLoopSeq_Type);
3727  PyType_Ready(&BPy_BMIter_Type);
3728 }
3729 
3730 /* bmesh.types submodule
3731  * ********************* */
3732 
3733 static struct PyModuleDef BPy_BM_types_module_def = {
3734  PyModuleDef_HEAD_INIT,
3735  "bmesh.types", /* m_name */
3736  NULL, /* m_doc */
3737  0, /* m_size */
3738  NULL, /* m_methods */
3739  NULL, /* m_reload */
3740  NULL, /* m_traverse */
3741  NULL, /* m_clear */
3742  NULL, /* m_free */
3743 };
3744 
3745 PyObject *BPyInit_bmesh_types(void)
3746 {
3747  PyObject *submodule;
3748 
3749  submodule = PyModule_Create(&BPy_BM_types_module_def);
3750 
3751  /* bmesh_py_types.c */
3752  PyModule_AddType(submodule, &BPy_BMesh_Type);
3753  PyModule_AddType(submodule, &BPy_BMVert_Type);
3754  PyModule_AddType(submodule, &BPy_BMEdge_Type);
3755  PyModule_AddType(submodule, &BPy_BMFace_Type);
3756  PyModule_AddType(submodule, &BPy_BMLoop_Type);
3757  PyModule_AddType(submodule, &BPy_BMElemSeq_Type);
3758  PyModule_AddType(submodule, &BPy_BMVertSeq_Type);
3759  PyModule_AddType(submodule, &BPy_BMEdgeSeq_Type);
3760  PyModule_AddType(submodule, &BPy_BMFaceSeq_Type);
3761  PyModule_AddType(submodule, &BPy_BMLoopSeq_Type);
3762  PyModule_AddType(submodule, &BPy_BMIter_Type);
3763  /* bmesh_py_types_select.c */
3764  PyModule_AddType(submodule, &BPy_BMEditSelSeq_Type);
3765  PyModule_AddType(submodule, &BPy_BMEditSelIter_Type);
3766  /* bmesh_py_types_customdata.c */
3767  PyModule_AddType(submodule, &BPy_BMLayerAccessVert_Type);
3768  PyModule_AddType(submodule, &BPy_BMLayerAccessEdge_Type);
3769  PyModule_AddType(submodule, &BPy_BMLayerAccessFace_Type);
3770  PyModule_AddType(submodule, &BPy_BMLayerAccessLoop_Type);
3771  PyModule_AddType(submodule, &BPy_BMLayerCollection_Type);
3772  PyModule_AddType(submodule, &BPy_BMLayerItem_Type);
3773  /* bmesh_py_types_meshdata.c */
3774  PyModule_AddType(submodule, &BPy_BMLoopUV_Type);
3775  PyModule_AddType(submodule, &BPy_BMDeformVert_Type);
3776 
3777  return submodule;
3778 }
3779 
3780 /* Utility Functions
3781  * ***************** */
3782 
3783 PyObject *BPy_BMesh_CreatePyObject(BMesh *bm, int flag)
3784 {
3785  BPy_BMesh *self;
3786 
3787  if (bm->py_handle) {
3788  self = bm->py_handle;
3789  Py_INCREF(self);
3790  }
3791  else {
3792  self = PyObject_New(BPy_BMesh, &BPy_BMesh_Type);
3793  self->bm = bm;
3794  self->flag = flag;
3795 
3796  bm->py_handle = self; /* point back */
3797 
3798  /* avoid allocating layers when we don't have to */
3799 #if 0
3804 #endif
3805  }
3806 
3807  return (PyObject *)self;
3808 }
3809 
3811 {
3812  BPy_BMVert *self;
3813 
3815 
3816  /* bmesh may free layers, ensure we have one to store ourself */
3817  if (UNLIKELY(ptr == NULL)) {
3820  }
3821 
3822  if (*ptr != NULL) {
3823  self = *ptr;
3824  Py_INCREF(self);
3825  }
3826  else {
3827  self = PyObject_New(BPy_BMVert, &BPy_BMVert_Type);
3828  BLI_assert(v != NULL);
3829  self->bm = bm;
3830  self->v = v;
3831  *ptr = self;
3832  }
3833  return (PyObject *)self;
3834 }
3835 
3837 {
3838  BPy_BMEdge *self;
3839 
3841 
3842  /* bmesh may free layers, ensure we have one to store ourself */
3843  if (UNLIKELY(ptr == NULL)) {
3846  }
3847 
3848  if (*ptr != NULL) {
3849  self = *ptr;
3850  Py_INCREF(self);
3851  }
3852  else {
3853  self = PyObject_New(BPy_BMEdge, &BPy_BMEdge_Type);
3854  BLI_assert(e != NULL);
3855  self->bm = bm;
3856  self->e = e;
3857  *ptr = self;
3858  }
3859  return (PyObject *)self;
3860 }
3861 
3863 {
3864  BPy_BMFace *self;
3865 
3867 
3868  /* bmesh may free layers, ensure we have one to store ourself */
3869  if (UNLIKELY(ptr == NULL)) {
3872  }
3873 
3874  if (*ptr != NULL) {
3875  self = *ptr;
3876  Py_INCREF(self);
3877  }
3878  else {
3879  self = PyObject_New(BPy_BMFace, &BPy_BMFace_Type);
3880  BLI_assert(f != NULL);
3881  self->bm = bm;
3882  self->f = f;
3883  *ptr = self;
3884  }
3885  return (PyObject *)self;
3886 }
3887 
3889 {
3890  BPy_BMLoop *self;
3891 
3893 
3894  /* bmesh may free layers, ensure we have one to store ourself */
3895  if (UNLIKELY(ptr == NULL)) {
3898  }
3899 
3900  if (*ptr != NULL) {
3901  self = *ptr;
3902  Py_INCREF(self);
3903  }
3904  else {
3905  self = PyObject_New(BPy_BMLoop, &BPy_BMLoop_Type);
3906  BLI_assert(l != NULL);
3907  self->bm = bm;
3908  self->l = l;
3909  *ptr = self;
3910  }
3911  return (PyObject *)self;
3912 }
3913 
3914 PyObject *BPy_BMElemSeq_CreatePyObject(BMesh *bm, BPy_BMElem *py_ele, const char itype)
3915 {
3916  BPy_BMElemSeq *self = PyObject_New(BPy_BMElemSeq, &BPy_BMElemSeq_Type);
3917  self->bm = bm;
3918  self->py_ele = py_ele; /* can be NULL */
3919  self->itype = itype;
3920  Py_XINCREF(py_ele);
3921  return (PyObject *)self;
3922 }
3923 
3925 {
3926  BPy_BMElemSeq *self = PyObject_New(BPy_BMElemSeq, &BPy_BMVertSeq_Type);
3927  self->bm = bm;
3928  self->py_ele = NULL; /* unused */
3929  self->itype = BM_VERTS_OF_MESH;
3930  return (PyObject *)self;
3931 }
3932 
3934 {
3935  BPy_BMElemSeq *self = PyObject_New(BPy_BMElemSeq, &BPy_BMEdgeSeq_Type);
3936  self->bm = bm;
3937  self->py_ele = NULL; /* unused */
3938  self->itype = BM_EDGES_OF_MESH;
3939  return (PyObject *)self;
3940 }
3941 
3943 {
3944  BPy_BMElemSeq *self = PyObject_New(BPy_BMElemSeq, &BPy_BMFaceSeq_Type);
3945  self->bm = bm;
3946  self->py_ele = NULL; /* unused */
3947  self->itype = BM_FACES_OF_MESH;
3948  return (PyObject *)self;
3949 }
3950 
3952 {
3953  BPy_BMElemSeq *self = PyObject_New(BPy_BMElemSeq, &BPy_BMLoopSeq_Type);
3954  self->bm = bm;
3955  self->py_ele = NULL; /* unused */
3956  self->itype = 0; /* should never be passed to the iterator function */
3957  return (PyObject *)self;
3958 }
3959 
3961 {
3962  BPy_BMIter *self = PyObject_New(BPy_BMIter, &BPy_BMIter_Type);
3963  self->bm = bm;
3964  /* caller must initialize 'iter' member */
3965  return (PyObject *)self;
3966 }
3967 
3968 /* this is just a helper func */
3970 {
3971  switch (ele->htype) {
3972  case BM_VERT:
3973  return BPy_BMVert_CreatePyObject(bm, (BMVert *)ele);
3974  case BM_EDGE:
3975  return BPy_BMEdge_CreatePyObject(bm, (BMEdge *)ele);
3976  case BM_FACE:
3977  return BPy_BMFace_CreatePyObject(bm, (BMFace *)ele);
3978  case BM_LOOP:
3979  return BPy_BMLoop_CreatePyObject(bm, (BMLoop *)ele);
3980  default:
3982  PyErr_SetString(PyExc_SystemError, "internal error");
3983  return NULL;
3984  }
3985 }
3986 
3988 {
3989  if (LIKELY(self->bm)) {
3990 
3991  /* far too slow to enable by default but handy
3992  * to uncomment for debugging tricky errors,
3993  * note that this will throw error on entering a
3994  * function where the actual error will be caused by
3995  * the previous action. */
3996 #if 0
3997  if (BM_mesh_validate(self->bm) == false) {
3998  PyErr_Format(
3999  PyExc_ReferenceError, "BMesh used by %.200s has become invalid", Py_TYPE(self)->tp_name);
4000  return -1;
4001  }
4002 #endif
4003 
4004  return 0;
4005  }
4006 
4007  PyErr_Format(
4008  PyExc_ReferenceError, "BMesh data of type %.200s has been removed", Py_TYPE(self)->tp_name);
4009  return -1;
4010 }
4011 
4013  const char *error_prefix,
4014  void **args,
4015  uint args_tot)
4016 {
4017  int ret = 0;
4018 
4019  while (args_tot--) {
4020  BPy_BMGeneric *py_bm_elem = args[args_tot];
4021  if (py_bm_elem) {
4022 
4023  BLI_assert(BPy_BMesh_Check(py_bm_elem) || BPy_BMElem_Check(py_bm_elem));
4024 
4025  ret = bpy_bm_generic_valid_check(py_bm_elem);
4026  if (UNLIKELY(ret == -1)) {
4027  break;
4028  }
4029 
4030  if (UNLIKELY(py_bm_elem->bm != bm_source)) {
4031  /* could give more info here */
4032  PyErr_Format(PyExc_ValueError,
4033  "%.200s: BMesh data of type %.200s is from another mesh",
4034  error_prefix,
4035  Py_TYPE(py_bm_elem)->tp_name);
4036  ret = -1;
4037  break;
4038  }
4039  }
4040  }
4041 
4042  return ret;
4043 }
4044 
4046 {
4047  self->bm = NULL;
4048 }
4049 
4050 /* generic python seq as BMVert/Edge/Face array,
4051  * return value must be freed with PyMem_FREE(...);
4052  *
4053  * The 'bm_r' value is assigned when empty, and used when set.
4054  */
4056  PyObject *seq_fast,
4057  Py_ssize_t min,
4058  Py_ssize_t max,
4059  Py_ssize_t *r_size,
4060  const char htype,
4061  const bool do_unique_check,
4062  const bool do_bm_check,
4063  const char *error_prefix)
4064 {
4065  BMesh *bm = (r_bm && *r_bm) ? *r_bm : NULL;
4066  PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
4067  const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
4068  Py_ssize_t i, i_last_dirty = PY_SSIZE_T_MAX;
4069 
4070  BPy_BMElem *item;
4071  BMElem **alloc;
4072 
4073  *r_size = 0;
4074 
4075  if (seq_len < min || seq_len > max) {
4076  PyErr_Format(PyExc_TypeError,
4077  "%s: sequence incorrect size, expected [%d - %d], given %d",
4078  error_prefix,
4079  min,
4080  max,
4081  seq_len);
4082  return NULL;
4083  }
4084 
4085  /* from now on, use goto */
4086  alloc = PyMem_MALLOC(seq_len * sizeof(BPy_BMElem **));
4087 
4088  for (i = 0; i < seq_len; i++) {
4089  item = (BPy_BMElem *)seq_fast_items[i];
4090 
4091  if (!BPy_BMElem_CheckHType(Py_TYPE(item), htype)) {
4092  PyErr_Format(PyExc_TypeError,
4093  "%s: expected %.200s, not '%.200s'",
4094  error_prefix,
4096  Py_TYPE(item)->tp_name);
4097  goto err_cleanup;
4098  }
4099  else if (!BPY_BM_IS_VALID(item)) {
4100  PyErr_Format(
4101  PyExc_TypeError, "%s: %d %s has been removed", error_prefix, i, Py_TYPE(item)->tp_name);
4102  goto err_cleanup;
4103  }
4104  /* trick so we can ensure all items have the same mesh,
4105  * and allows us to pass the 'bm' as NULL. */
4106  else if (do_bm_check && (bm && bm != item->bm)) {
4107  PyErr_Format(PyExc_ValueError,
4108  "%s: %d %s is from another mesh",
4109  error_prefix,
4110  i,
4112  goto err_cleanup;
4113  }
4114 
4115  if (bm == NULL) {
4116  bm = item->bm;
4117  }
4118 
4119  alloc[i] = item->ele;
4120 
4121  if (do_unique_check) {
4123  i_last_dirty = i;
4124  }
4125  }
4126 
4127  if (do_unique_check) {
4128  /* check for double verts! */
4129  bool ok = true;
4130  for (i = 0; i < seq_len; i++) {
4131  if (UNLIKELY(BM_elem_flag_test(alloc[i], BM_ELEM_INTERNAL_TAG) == false)) {
4132  ok = false;
4133  }
4134 
4135  /* ensure we don't leave this enabled */
4137  }
4138 
4139  if (ok == false) {
4140  /* Cleared above. */
4141  i_last_dirty = PY_SSIZE_T_MAX;
4142  PyErr_Format(PyExc_ValueError,
4143  "%s: found the same %.200s used multiple times",
4144  error_prefix,
4146  goto err_cleanup;
4147  }
4148  }
4149 
4150  *r_size = seq_len;
4151  if (r_bm) {
4152  *r_bm = bm;
4153  }
4154  return alloc;
4155 
4156 err_cleanup:
4157  if (do_unique_check && (i_last_dirty != PY_SSIZE_T_MAX)) {
4158  for (i = 0; i <= i_last_dirty; i++) {
4160  }
4161  }
4162  PyMem_FREE(alloc);
4163  return NULL;
4164 }
4165 
4167  PyObject *seq,
4168  Py_ssize_t min,
4169  Py_ssize_t max,
4170  Py_ssize_t *r_size,
4171  const char htype,
4172  const bool do_unique_check,
4173  const bool do_bm_check,
4174  const char *error_prefix)
4175 {
4176  PyObject *seq_fast;
4177  PyObject *ret;
4178 
4179  if (!(seq_fast = PySequence_Fast(seq, error_prefix))) {
4180  return NULL;
4181  }
4182 
4184  r_bm, seq_fast, min, max, r_size, htype, do_unique_check, do_bm_check, error_prefix);
4185 
4186  Py_DECREF(seq_fast);
4187  return ret;
4188 }
4189 
4190 PyObject *BPy_BMElem_Array_As_Tuple(BMesh *bm, BMHeader **elem, Py_ssize_t elem_len)
4191 {
4192  Py_ssize_t i;
4193  PyObject *ret = PyTuple_New(elem_len);
4194  for (i = 0; i < elem_len; i++) {
4195  PyTuple_SET_ITEM(ret, i, BPy_BMElem_CreatePyObject(bm, elem[i]));
4196  }
4197  return ret;
4198 }
4199 PyObject *BPy_BMVert_Array_As_Tuple(BMesh *bm, BMVert **elem, Py_ssize_t elem_len)
4200 {
4201  Py_ssize_t i;
4202  PyObject *ret = PyTuple_New(elem_len);
4203  for (i = 0; i < elem_len; i++) {
4204  PyTuple_SET_ITEM(ret, i, BPy_BMVert_CreatePyObject(bm, elem[i]));
4205  }
4206  return ret;
4207 }
4208 PyObject *BPy_BMEdge_Array_As_Tuple(BMesh *bm, BMEdge **elem, Py_ssize_t elem_len)
4209 {
4210  Py_ssize_t i;
4211  PyObject *ret = PyTuple_New(elem_len);
4212  for (i = 0; i < elem_len; i++) {
4213  PyTuple_SET_ITEM(ret, i, BPy_BMEdge_CreatePyObject(bm, elem[i]));
4214  }
4215 
4216  return ret;
4217 }
4218 PyObject *BPy_BMFace_Array_As_Tuple(BMesh *bm, BMFace **elem, Py_ssize_t elem_len)
4219 {
4220  Py_ssize_t i;
4221  PyObject *ret = PyTuple_New(elem_len);
4222  for (i = 0; i < elem_len; i++) {
4223  PyTuple_SET_ITEM(ret, i, BPy_BMFace_CreatePyObject(bm, elem[i]));
4224  }
4225 
4226  return ret;
4227 }
4228 PyObject *BPy_BMLoop_Array_As_Tuple(BMesh *bm, BMLoop **elem, Py_ssize_t elem_len)
4229 {
4230  Py_ssize_t i;
4231  PyObject *ret = PyTuple_New(elem_len);
4232  for (i = 0; i < elem_len; i++) {
4233  PyTuple_SET_ITEM(ret, i, BPy_BMLoop_CreatePyObject(bm, elem[i]));
4234  }
4235 
4236  return ret;
4237 }
4238 
4239 int BPy_BMElem_CheckHType(PyTypeObject *type, const char htype)
4240 {
4241  return (((htype & BM_VERT) && (type == &BPy_BMVert_Type)) ||
4242  ((htype & BM_EDGE) && (type == &BPy_BMEdge_Type)) ||
4243  ((htype & BM_FACE) && (type == &BPy_BMFace_Type)) ||
4244  ((htype & BM_LOOP) && (type == &BPy_BMLoop_Type)));
4245 }
4246 
4252 char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32])
4253 {
4254  /* zero to ensure string is always NULL terminated */
4255  char *ret_ptr = ret;
4256  if (htype & BM_VERT) {
4257  ret_ptr += sprintf(ret_ptr, "/%s", BPy_BMVert_Type.tp_name);
4258  }
4259  if (htype & BM_EDGE) {
4260  ret_ptr += sprintf(ret_ptr, "/%s", BPy_BMEdge_Type.tp_name);
4261  }
4262  if (htype & BM_FACE) {
4263  ret_ptr += sprintf(ret_ptr, "/%s", BPy_BMFace_Type.tp_name);
4264  }
4265  if (htype & BM_LOOP) {
4266  ret_ptr += sprintf(ret_ptr, "/%s", BPy_BMLoop_Type.tp_name);
4267  }
4268  ret[0] = '(';
4269  *ret_ptr++ = ')';
4270  *ret_ptr = '\0';
4271  return ret;
4272 }
4273 char *BPy_BMElem_StringFromHType(const char htype)
4274 {
4275  /* zero to ensure string is always NULL terminated */
4276  static char ret[32];
4277  return BPy_BMElem_StringFromHType_ex(htype, ret);
4278 }
4279 
4280 /* -------------------------------------------------------------------- */
4281 /* keep at bottom */
4282 
4283 /* this function is called on free, it should stay quite fast */
4285 {
4286  if (self->flag & BPY_BMFLAG_IS_WRAPPED) {
4287  /* currently nop - this works without warnings now */
4288  }
4289 }
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_has_layer(const struct CustomData *data, int type)
const CustomData_MeshMasks CD_MASK_BMESH
Definition: customdata.c:1964
void * CustomData_bmesh_get(const struct CustomData *data, void *block, int type)
#define G_MAIN
Definition: BKE_global.h:232
void BKE_id_free(struct Main *bmain, void *idv)
bool BKE_id_is_in_global_main(struct ID *id)
Definition: lib_id.c:2287
struct Mesh * BKE_mesh_new_from_object(struct Depsgraph *depsgraph, struct Object *object, const bool preserve_all_data_layers, const bool preserve_origindex)
struct Mesh * mesh_get_eval_deform(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, const struct CustomData_MeshMasks *dataMask)
struct Mesh * mesh_get_eval_final(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, const struct CustomData_MeshMasks *dataMask)
#define BLI_assert_unreachable()
Definition: BLI_assert.h:96
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE float clamp_f(float value, float min, float max)
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count)
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void range_vn_i(int *array_tar, const int size, const int start)
Definition: math_vector.c:1172
void BLI_qsort_r(void *a, size_t n, size_t es, BLI_sort_cmp_t cmp, void *thunk)
Definition: sort.c:95
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
#define POINTER_AS_INT(i)
#define UNLIKELY(x)
#define CLAMP_MIN(a, b)
#define LIKELY(x)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:62
void DEG_id_tag_update(struct ID *id, int flag)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ LIB_TAG_NO_MAIN
Definition: DNA_ID.h:572
#define CD_MASK_BM_ELEM_PYPTR
@ CD_BM_ELEM_PYPTR
#define MAXMAT
Object is a sort of wrapper for general info.
@ OB_MESH
_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
@ BM_LOOP
Definition: bmesh_class.h:385
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
@ BM_ELEM_HIDDEN
Definition: bmesh_class.h:472
@ BM_ELEM_SEAM
Definition: bmesh_class.h:473
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
@ BM_ELEM_SMOOTH
Definition: bmesh_class.h:477
@ BM_ELEM_INTERNAL_TAG
Definition: bmesh_class.h:496
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v, const char hflag_mask, const uint64_t cd_mask_exclude)
void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src, void *ele_dst)
BMesh * BM_mesh_copy(BMesh *bm_old)
BMVert * BM_vert_create(BMesh *bm, const float co[3], const BMVert *v_example, const eBMCreateFlag create_flag)
Main function for creating a new vertex.
Definition: bmesh_core.c:58
BMFace * BM_face_create_verts(BMesh *bm, BMVert **vert_arr, const int len, const BMFace *f_example, const eBMCreateFlag create_flag, const bool create_edges)
Definition: bmesh_core.c:500
void BM_vert_kill(BMesh *bm, BMVert *v)
Definition: bmesh_core.c:1002
void BM_face_kill(BMesh *bm, BMFace *f)
Definition: bmesh_core.c:881
void BM_edge_kill(BMesh *bm, BMEdge *e)
Definition: bmesh_core.c:987
BMFace * BM_face_copy(BMesh *bm_dst, BMesh *bm_src, BMFace *f, const bool copy_verts, const bool copy_edges)
Definition: bmesh_core.c:303
BMEdge * BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag)
Main function for creating a new edge.
Definition: bmesh_core.c:147
@ BM_CREATE_NOP
Definition: bmesh_core.h:27
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:124
#define BM_elem_flag_disable(ele, hflag)
Definition: bmesh_inline.h:29
#define BM_elem_flag_set(ele, hflag, val)
Definition: bmesh_inline.h:30
#define BM_elem_index_set(ele, index)
Definition: bmesh_inline.h:125
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:26
#define BM_elem_flag_enable(ele, hflag)
Definition: bmesh_inline.h:28
void BM_data_layer_free(BMesh *bm, CustomData *data, int type)
Definition: bmesh_interp.c:930
void BM_vert_interp_from_face(BMesh *bm, BMVert *v_dst, const BMFace *f_src)
Definition: bmesh_interp.c:791
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
Definition: bmesh_interp.c:894
void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex)
Definition: bmesh_interp.c:213
void BM_loop_interp_from_face(BMesh *bm, BMLoop *l_dst, const BMFace *f_src, const bool do_vertex, const bool do_multires)
Definition: bmesh_interp.c:737
void BM_data_interp_from_verts(BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v_dst, const float fac)
Data, Interp From Verts.
Definition: bmesh_interp.c:91
const char bm_iter_itype_htype_map[BM_ITYPE_MAX]
void * BM_iter_at_index(BMesh *bm, const char itype, void *data, int index)
#define BM_ITER_MESH(ele, iter, bm, itype)
BMIterType
BMesh Iterators.
@ BM_LOOPS_OF_LOOP
@ BM_FACES_OF_EDGE
@ BM_FACES_OF_VERT
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
@ BM_VERTS_OF_EDGE
@ BM_VERTS_OF_FACE
@ BM_FACES_OF_MESH
@ BM_LOOPS_OF_VERT
@ BM_LOOPS_OF_EDGE
@ BM_EDGES_OF_VERT
@ BM_EDGES_OF_FACE
@ BM_LOOPS_OF_FACE
BLI_INLINE bool BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *data)
Iterator Init.
ATTR_WARN_UNUSED_RESULT BMesh const char itype
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_select_mode_flush(BMesh *bm)
void BM_elem_select_set(BMesh *bm, BMElem *ele, const bool select)
void BM_mesh_select_flush(BMesh *bm)
void BM_mesh_deselect_flush(BMesh *bm)
#define BM_elem_hide_set(bm, ele, hide)
Definition: bmesh_marking.h:30
void BM_mesh_remap(BMesh *bm, const uint *vert_idx, const uint *edge_idx, const uint *face_idx)
Definition: bmesh_mesh.c:2476
void BM_mesh_clear(BMesh *bm)
BMesh Clear Mesh.
Definition: bmesh_mesh.c:281
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
Definition: bmesh_mesh.c:307
void BM_mesh_normals_update(BMesh *bm)
BMesh Compute Normals.
Definition: bmesh_mesh.c:500
int BM_mesh_elem_count(BMesh *bm, const char htype)
Definition: bmesh_mesh.c:2444
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
Definition: bmesh_mesh.c:2276
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
Definition: bmesh_mesh.c:2152
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
Mesh -> BMesh.
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
bool BM_mesh_validate(BMesh *bm)
void BM_face_calc_tangent_edge_pair(const BMFace *f, float r_tangent[3])
void BM_face_calc_center_bounds(const BMFace *f, float r_cent[3])
void BM_vert_normal_update(BMVert *v)
void BM_face_calc_tangent_vert_diagonal(const BMFace *f, float r_tangent[3])
void BM_face_calc_tangent_edge_diagonal(const BMFace *f, float r_tangent[3])
void BM_face_normal_update(BMFace *f)
void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot)
BM_mesh_calc_tessellation get the looptris and its number from a certain bmesh.
void BM_face_normal_flip(BMesh *bm, BMFace *f)
void BM_face_calc_tangent_edge(const BMFace *f, float r_tangent[3])
float BM_face_calc_area(const BMFace *f)
void BM_face_calc_center_median(const BMFace *f, float r_cent[3])
void BM_face_calc_center_median_weighted(const BMFace *f, float r_cent[3])
float BM_face_calc_perimeter(const BMFace *f)
void BM_edge_normals_update(BMEdge *e)
static Py_hash_t bpy_bm_hash(PyObject *self)
static PyObject * bpy_bmesh_select_flush(BPy_BMesh *self, PyObject *value)
static void bpy_bmvert_dealloc(BPy_BMElem *self)
static PyObject * bpy_bmedge_is_contiguous_get(BPy_BMEdge *self)
static PyObject * bpy_bmedge_is_wire_get(BPy_BMEdge *self)
static Py_hash_t bpy_bm_elem_hash(PyObject *self)
PyC_FlagSet bpy_bm_htype_all_flags[]
static PyMappingMethods bpy_bmelemseq_as_mapping
static PyObject * bpy_bmesh_copy(BPy_BMesh *self)
static PyObject * bpy_bmesh_select_history_get(BPy_BMesh *self)
static PyObject * bpy_bmfaceseq_get__method(BPy_BMElemSeq *self, PyObject *args)
static PyObject * bpy_bmloop_calc_angle(BPy_BMLoop *self)
PyObject * BPy_BMIter_CreatePyObject(BMesh *bm)
static PyObject * bpy_bmface_repr(BPy_BMFace *self)
static PyObject * bpy_bmvert_normal_update(BPy_BMVert *self)
static PyObject * bpy_bmloopseq_get(BPy_BMesh *self, void *UNUSED(closure))
static PyGetSetDef bpy_bmvertseq_getseters[]
static PyObject * bpy_bmloop_link_loop_radial_next_get(BPy_BMLoop *self)
static PyObject * bpy_bmvertseq_get(BPy_BMesh *self, void *UNUSED(closure))
static PyObject * bpy_bmvert_copy_from_vert_interp(BPy_BMVert *self, PyObject *args)
static PyObject * bpy_bmvertseq_new(BPy_BMElemSeq *self, PyObject *args)
static PyGetSetDef bpy_bmloopseq_getseters[]
PyObject * BPy_BMEdge_Array_As_Tuple(BMesh *bm, BMEdge **elem, Py_ssize_t elem_len)
static PyObject * bpy_bm_elem_copy_from(BPy_BMElem *self, BPy_BMElem *value)
static PyObject * bpy_bmedge_repr(BPy_BMEdge *self)
PyTypeObject BPy_BMesh_Type
PyObject * BPy_BMEdge_CreatePyObject(BMesh *bm, BMEdge *e)
static PyObject * bpy_bmface_calc_perimeter(BPy_BMFace *self)
static PyObject * bpy_bmelemseq_layers_get(BPy_BMElemSeq *self, void *htype)
static PyObject * bpy_bmedge_calc_face_angle(BPy_BMEdge *self, PyObject *args)
PyC_FlagSet bpy_bm_htype_vert_edge_face_flags[]
PyObject * BPy_BMLoop_CreatePyObject(BMesh *bm, BMLoop *l)
PyObject * BPy_BMFace_Array_As_Tuple(BMesh *bm, BMFace **elem, Py_ssize_t elem_len)
PyObject * BPy_BMVert_Array_As_Tuple(BMesh *bm, BMVert **elem, Py_ssize_t elem_len)
static PyObject * bpy_bm_elem_hide_set(BPy_BMElem *self, PyObject *value)
static PyObject * bpy_bmface_calc_tangent_edge_pair(BPy_BMFace *self)
static PyMappingMethods bpy_bm_elem_as_mapping
static PyObject * bpy_bmiter_next(BPy_BMIter *self)
static PyObject * bpy_bmface_calc_center_mean(BPy_BMFace *self)
PyObject * BPyInit_bmesh_types(void)
PyObject * BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele)
static PyObject * bpy_bm_elem_index_get(BPy_BMElem *self, void *UNUSED(flag))
static PyObject * bpy_bm_elem_hflag_get(BPy_BMElem *self, void *flag)
void BPy_BM_init_types(void)
static int bpy_bmelem_ass_subscript(BPy_BMElem *self, BPy_BMLayerItem *key, PyObject *value)
static PyObject * bpy_bmelemseq_elem_get(BPy_BMElem *self, void *itype)
static struct PyMethodDef bpy_bmedge_methods[]
void * BPy_BMElem_PySeq_As_Array_FAST(BMesh **r_bm, PyObject *seq_fast, Py_ssize_t min, Py_ssize_t max, Py_ssize_t *r_size, const char htype, const bool do_unique_check, const bool do_bm_check, const char *error_prefix)
static PyObject * bpy_bmface_copy(BPy_BMFace *self, PyObject *args, PyObject *kw)
static void bm_dealloc_editmode_warn(BPy_BMesh *self)
PyTypeObject BPy_BMVertSeq_Type
PyTypeObject BPy_BMLoopSeq_Type
static PyObject * bpy_bmface_calc_center_bounds(BPy_BMFace *self)
static void bpy_bmedge_dealloc(BPy_BMElem *self)
static PyObject * bpy_bmesh_from_mesh(BPy_BMesh *self, PyObject *args, PyObject *kw)
static PyObject * bpy_bmvert_repr(BPy_BMVert *self)
static PyGetSetDef bpy_bmvert_getseters[]
static PyObject * bpy_bmedgeseq_get__method(BPy_BMElemSeq *self, PyObject *args)
static PyObject * bpy_bmfaceseq_remove(BPy_BMElemSeq *self, BPy_BMFace *value)
static PyObject * bpy_bmface_copy_from_face_interp(BPy_BMFace *self, PyObject *args)
static void bpy_bmloop_dealloc(BPy_BMElem *self)
static PyObject * bpy_bmesh_is_wrapped_get(BPy_BMesh *self)
static Py_ssize_t bpy_bmelemseq_length(BPy_BMElemSeq *self)
static PyObject * bpy_bmedge_normal_update(BPy_BMEdge *self)
PyObject * BPy_BMLoopSeq_CreatePyObject(BMesh *bm)
static struct PyMethodDef bpy_bmface_methods[]
static PyObject * bpy_bmedge_other_vert(BPy_BMEdge *self, BPy_BMVert *value)
static PyGetSetDef bpy_bmesh_getseters[]
PyObject * BPy_BMFace_CreatePyObject(BMesh *bm, BMFace *f)
static PyObject * bpy_bmelemseq_subscript_slice(BPy_BMElemSeq *self, Py_ssize_t start, Py_ssize_t stop)
void bpy_bm_generic_invalidate(BPy_BMGeneric *self)
static PyObject * bpy_bmloop_link_loop_next_get(BPy_BMLoop *self)
static PyObject * bpy_bmloop_face_get(BPy_BMLoop *self)
static PyObject * bpy_bmelemseq_ensure_lookup_table(BPy_BMElemSeq *self)
static int bpy_bmvert_co_set(BPy_BMVert *self, PyObject *value)
char * BPy_BMElem_StringFromHType_ex(const char htype, char ret[32])
static PyObject * bpy_bmelemseq_subscript(BPy_BMElemSeq *self, PyObject *key)
static PyObject * bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
static PyObject * bpy_bmesh_select_flush_mode(BPy_BMesh *self)
static PyTypeObject * bpy_bm_itype_as_pytype(const char itype)
PyTypeObject BPy_BMEdgeSeq_Type
static PyObject * bpy_bmedge_is_convex_get(BPy_BMEdge *self)
static PyObject * bpy_bmelem_subscript(BPy_BMElem *self, BPy_BMLayerItem *key)
PyTypeObject BPy_BMEdge_Type
static PyObject * bpy_bmface_calc_tangent_edge_diagonal(BPy_BMFace *self)
static PyObject * bpy_bmloop_repr(BPy_BMLoop *self)
static PyObject * bpy_bmedgeseq_get(BPy_BMesh *self, void *UNUSED(closure))
static int bpy_bmfaceseq_active_set(BPy_BMElem *self, PyObject *value, void *UNUSED(closure))
static PyObject * bpy_bmesh_transform(BPy_BMElem *self, PyObject *args, PyObject *kw)
static PyObject * bpy_bmesh_normal_update(BPy_BMesh *self)
static PyGetSetDef bpy_bmfaceseq_getseters[]
static PyObject * bpy_bmedge_calc_length(BPy_BMEdge *self)
static PyObject * bpy_bmloop_link_loop_prev_get(BPy_BMLoop *self)
static PyGetSetDef bpy_bmedge_getseters[]
static PyObject * bpy_bmedge_calc_face_angle_signed(BPy_BMEdge *self, PyObject *args)
static PyObject * bpy_bmface_calc_area(BPy_BMFace *self)
static PyObject * bpy_bmedgeseq_new(BPy_BMElemSeq *self, PyObject *args)
static PyObject * bpy_bmfaceseq_active_get(BPy_BMElemSeq *self, void *UNUSED(closure))
PyObject * BPy_BMFaceSeq_CreatePyObject(BMesh *bm)
static PyObject * bpy_bmesh_calc_volume(BPy_BMElem *self, PyObject *args, PyObject *kw)
static struct PyMethodDef bpy_bmvertseq_methods[]
static int bpy_bmesh_select_mode_set(BPy_BMesh *self, PyObject *value)
static struct PyMethodDef bpy_bmloopseq_methods[]
static int bpy_bmelemseq_sort_cmp_by_keys_descending(const void *index1_v, const void *index2_v, void *keys_v)
int bpy_bm_generic_valid_check_source(BMesh *bm_source, const char *error_prefix, void **args, uint args_tot)
static PyObject * bpy_bmloop_calc_normal(BPy_BMLoop *self)
static PyObject * bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject *kw)
static PyObject * bpy_bmelemseq_index_update(BPy_BMElemSeq *self)
PyObject * BPy_BMLoop_Array_As_Tuple(BMesh *bm, BMLoop **elem, Py_ssize_t elem_len)
PyObject * BPy_BMesh_CreatePyObject(BMesh *bm, int flag)
static int bpy_bmvert_normal_set(BPy_BMVert *self, PyObject *value)
static PyObject * bpy_bmvert_is_manifold_get(BPy_BMVert *self)
static PyGetSetDef bpy_bmedgeseq_getseters[]
static PyObject * bpy_bmesh_repr(BPy_BMesh *self)
static PyObject * bpy_bmedge_is_manifold_get(BPy_BMEdge *self)
static PyObject * bpy_bmvert_co_get(BPy_BMVert *self)
static void bpy_bmelemseq_dealloc(BPy_BMElemSeq *self)
int bpy_bm_generic_valid_check(BPy_BMGeneric *self)
static PyObject * bpy_bmedge_calc_tangent(BPy_BMEdge *self, PyObject *args)
static PyObject * bpy_bmloop_edge_get(BPy_BMLoop *self)
static PyObject * bpy_bmelemseq_subscript_int(BPy_BMElemSeq *self, int keynum)
static void bpy_bmface_dealloc(BPy_BMElem *self)
static PyObject * bpy_bmedge_is_boundary_get(BPy_BMEdge *self)
static PyObject * bpy_bmface_calc_tangent_edge(BPy_BMFace *self)
PyTypeObject BPy_BMFaceSeq_Type
PyTypeObject BPy_BMVert_Type
static PyObject * bpy_bmesh_calc_loop_triangles(BPy_BMElem *self)
PyTypeObject BPy_BMIter_Type
static PyObject * bpy_bmedgeseq_remove(BPy_BMElemSeq *self, BPy_BMEdge *value)
static PyObject * bpy_bmface_material_index_get(BPy_BMFace *self)
char * BPy_BMElem_StringFromHType(const char htype)
static struct PyMethodDef bpy_bmvert_methods[]
static int bpy_bm_elem_index_set(BPy_BMElem *self, PyObject *value, void *UNUSED(flag))
static PyObject * bpy_bmface_normal_get(BPy_BMFace *self)
static PyObject * bpy_bmelemseq_iter(BPy_BMElemSeq *self)
static PyObject * bpy_bmloop_copy_from_face_interp(BPy_BMLoop *self, PyObject *args)
static PyObject * bpy_bmvert_is_boundary_get(BPy_BMVert *self)
#define BPY_BM_HFLAG_ALL_STR
PyObject * BPy_BMVertSeq_CreatePyObject(BMesh *bm)
static int bpy_bmesh_select_history_set(BPy_BMesh *self, PyObject *value)
static PyObject * bpy_bmface_calc_center_median_weighted(BPy_BMFace *self)
static PyObject * bpy_bmvert_copy_from_face_interp(BPy_BMVert *self, PyObject *args)
static PyObject * bpy_bmesh_clear(BPy_BMesh *self)
static PyObject * bpy_bm_elem_select_set(BPy_BMElem *self, PyObject *value)
static PyObject * bpy_bmvert_normal_get(BPy_BMVert *self)
PyTypeObject BPy_BMElemSeq_Type
PyObject * BPy_BMElem_Array_As_Tuple(BMesh *bm, BMHeader **elem, Py_ssize_t elem_len)
static int bpy_bmface_material_index_set(BPy_BMFace *self, PyObject *value)
static PyGetSetDef bpy_bmface_getseters[]
PyDoc_STRVAR(bpy_bm_elem_select_doc, "Selected state of this element.\n\n:type: boolean")
static int bpy_bmface_normal_set(BPy_BMFace *self, PyObject *value)
static struct PyMethodDef bpy_bmelemseq_methods[]
static PyObject * bpy_bmface_calc_tangent_vert_diagonal(BPy_BMFace *self)
PyTypeObject BPy_BMFace_Type
static PyObject * bpy_bmesh_select_mode_get(BPy_BMesh *self)
static int bpy_bmelemseq_sort_cmp_by_keys_ascending(const void *index1_v, const void *index2_v, void *keys_v)
PyObject * BPy_BMVert_CreatePyObject(BMesh *bm, BMVert *v)
static struct PyMethodDef bpy_bmloop_methods[]
static struct PyMethodDef bpy_bmfaceseq_methods[]
static void bpy_bmesh_dealloc(BPy_BMesh *self)
static PyGetSetDef bpy_bmloop_getseters[]
static PyObject * bpy_bmfaceseq_get(BPy_BMesh *self, void *UNUSED(closure))
PyTypeObject BPy_BMLoop_Type
static PyObject * bpy_bmloop_vert_get(BPy_BMLoop *self)
static PyObject * bpy_bmface_normal_update(BPy_BMFace *self)
static int bpy_bmelemseq_contains(BPy_BMElemSeq *self, PyObject *value)
static PyObject * bpy_bmface_normal_flip(BPy_BMFace *self)
PyObject * BPy_BMElemSeq_CreatePyObject(BMesh *bm, BPy_BMElem *py_ele, const char itype)
PyC_FlagSet bpy_bm_hflag_all_flags[]
static struct PyMethodDef bpy_bmedgeseq_methods[]
PyC_FlagSet bpy_bm_scene_vert_edge_face_flags[]
int BPy_BMElem_CheckHType(PyTypeObject *type, const char htype)
static PyObject * bpy_bmvert_calc_edge_angle(BPy_BMVert *self, PyObject *args)
static PyObject * bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, PyObject *kw)
static PyObject * bpy_bm_is_valid_get(BPy_BMGeneric *self)
void * BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, Py_ssize_t *r_size, const char htype, const bool do_unique_check, const bool do_bm_check, const char *error_prefix)
static PySequenceMethods bpy_bmelemseq_as_sequence
static PyObject * bpy_bmvert_is_wire_get(BPy_BMVert *self)
static PyObject * bpy_bmloop_link_loop_radial_prev_get(BPy_BMLoop *self)
static PyObject * bpy_bmloop_is_convex_get(BPy_BMLoop *self)
static struct PyMethodDef bpy_bmesh_methods[]
static PyObject * bpy_bmloop_calc_tangent(BPy_BMLoop *self)
static PyObject * bpy_bmesh_free(BPy_BMesh *self)
static struct PyModuleDef BPy_BM_types_module_def
PyObject * BPy_BMEdgeSeq_CreatePyObject(BMesh *bm)
static int bpy_bm_elem_hflag_set(BPy_BMElem *self, PyObject *value, void *flag)
static PyObject * bpy_bmvertseq_remove(BPy_BMElemSeq *self, BPy_BMVert *value)
static PyObject * bpy_bmvert_calc_shell_factor(BPy_BMVert *self)
static PyObject * bpy_bmfaceseq_new(BPy_BMElemSeq *self, PyObject *args)
@ BPY_BMFLAG_IS_WRAPPED
@ BPY_BMFLAG_NOP
struct BPy_BMLoop BPy_BMLoop
#define BPy_BMFace_Check(v)
#define BPY_BM_CHECK_OBJ(obj)
struct BPy_BMVert BPy_BMVert
struct BPy_BMIter BPy_BMIter
#define BPY_BM_CHECK_SOURCE_INT(bm, errmsg,...)
#define BPy_BMVert_Check(v)
#define BPy_BMElem_Check(v)
struct BPy_BMEdge BPy_BMEdge
#define BPy_BMesh_Check(v)
struct BPy_BMFace BPy_BMFace
#define BPy_BMEdge_Check(v)
#define BPY_BM_CHECK_SOURCE_OBJ(bm, errmsg,...)
#define BPY_BM_IS_VALID(obj)
struct BPy_BMElemSeq BPy_BMElemSeq
#define BM_ITER_BPY_BM_SEQ(ele, iter, bpy_bmelemseq)
struct BPy_BMesh BPy_BMesh
#define BPY_BM_CHECK_INT(obj)
PyTypeObject BPy_BMLayerCollection_Type
PyTypeObject BPy_BMLayerItem_Type
PyObject * BPy_BMLayerAccess_CreatePyObject(BMesh *bm, const char htype)
PyTypeObject BPy_BMLayerAccessLoop_Type
PyTypeObject BPy_BMLayerAccessVert_Type
int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObject *py_value)
PyTypeObject BPy_BMLayerAccessFace_Type
PyTypeObject BPy_BMLayerAccessEdge_Type
PyObject * BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
BMElem.__getitem__()
PyTypeObject BPy_BMDeformVert_Type
PyTypeObject BPy_BMLoopUV_Type
int BPy_BMEditSel_Assign(BPy_BMesh *self, PyObject *value)
PyObject * BPy_BMEditSel_CreatePyObject(BMesh *bm)
PyTypeObject BPy_BMEditSelSeq_Type
PyTypeObject BPy_BMEditSelIter_Type
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
Definition: bmesh_query.c:1995
bool BM_vert_is_wire(const BMVert *v)
Definition: bmesh_query.c:919
void BM_loop_calc_face_tangent(const BMLoop *l, float r_tangent[3])
BM_loop_calc_face_tangent.
Definition: bmesh_query.c:1681
bool BM_vert_is_manifold(const BMVert *v)
Definition: bmesh_query.c:943
float BM_vert_calc_shell_factor(const BMVert *v)
Definition: bmesh_query.c:1850
float BM_vert_calc_edge_angle_ex(const BMVert *v, const float fallback)
BMESH VERT/EDGE ANGLE.
Definition: bmesh_query.c:1823
BMFace * BM_face_exists(BMVert **varr, int len)
Definition: bmesh_query.c:2070
float BM_edge_calc_face_angle_ex(const BMEdge *e, const float fallback)
BMESH EDGE/FACE ANGLE.
Definition: bmesh_query.c:1719
bool BM_loop_is_convex(const BMLoop *l)
Definition: bmesh_query.c:1513
double BM_mesh_calc_volume(BMesh *bm, bool is_signed)
Definition: bmesh_query.c:2576
float BM_loop_calc_face_angle(const BMLoop *l)
Definition: bmesh_query.c:1531
float BM_edge_calc_face_angle_signed_ex(const BMEdge *e, const float fallback)
BMESH EDGE/FACE ANGLE.
Definition: bmesh_query.c:1775
void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_tangent[3])
BMESH EDGE/FACE TANGENT.
Definition: bmesh_query.c:1803
float BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3])
BM_loop_calc_face_normal.
Definition: bmesh_query.c:1635
bool BM_vert_is_boundary(const BMVert *v)
Definition: bmesh_query.c:1168
bool BM_edge_is_convex(const BMEdge *e)
Definition: bmesh_query.c:1107
BLI_INLINE bool BM_edge_is_contiguous(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_edge_is_manifold(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE BMVert * BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_edge_is_wire(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
PyObject * self
Definition: bpy_driver.c:185
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
const Depsgraph * depsgraph
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
int count
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
Definition: mathutils.c:118
#define BaseMath_ReadCallback(_self)
Definition: mathutils.h:128
PyTypeObject matrix_Type
PyObject * Vector_CreatePyObject(const float *vec, const int size, PyTypeObject *base_type)
PyObject * Vector_CreatePyObject_wrap(float *vec, const int size, PyTypeObject *base_type)
PyObject * PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag)
int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, const char *error_prefix)
void * PyC_RNA_AsPointer(PyObject *value, const char *type_name)
int PyC_Long_AsBool(PyObject *value)
int PyC_ParseBool(PyObject *o, void *p)
return ret
#define min(a, b)
Definition: sort.c:51
BMHeader head
Definition: bmesh_class.h:255
int len
Definition: bmesh_class.h:279
BMHeader head
Definition: bmesh_class.h:267
char htype
Definition: bmesh_class.h:76
int index
Definition: bmesh_class.h:73
void * data
Definition: bmesh_class.h:63
BMHeader head
Definition: bmesh_class.h:157
struct BMVert * v
Definition: bmesh_class.h:165
struct BMEdge * e
Definition: bmesh_class.h:176
struct BMFace * f
Definition: bmesh_class.h:183
float co[3]
Definition: bmesh_class.h:99
struct BMEdge * e
Definition: bmesh_class.h:109
BMHeader head
Definition: bmesh_class.h:97
int totvert
Definition: bmesh_class.h:297
char elem_index_dirty
Definition: bmesh_class.h:305
CustomData vdata
Definition: bmesh_class.h:337
int totedge
Definition: bmesh_class.h:297
CustomData edata
Definition: bmesh_class.h:337
int totloop
Definition: bmesh_class.h:297
void * py_handle
Definition: bmesh_class.h:378
BMFace * act_face
Definition: bmesh_class.h:366
CustomData pdata
Definition: bmesh_class.h:337
CustomData ldata
Definition: bmesh_class.h:337
int totface
Definition: bmesh_class.h:297
PyObject_VAR_HEAD struct BMesh * bm
struct BMEdge * e
struct BMElem * ele
PyObject_VAR_HEAD struct BMesh * bm
struct BMFace * f
PyObject_VAR_HEAD struct BMesh * bm
struct BMLoop * l
PyObject_VAR_HEAD struct BMesh * bm
struct BMVert * v
int tag
Definition: DNA_ID.h:292
char name[66]
Definition: DNA_ID.h:283
Definition: BKE_main.h:116
struct BMEditMesh * edit_mesh
float max
uint len
PointerRNA * ptr
Definition: wm_files.c:3157