py/bmesh api: add radial prev/next attributes to the loop
[blender.git] / source / blender / python / bmesh / bmesh_py_types.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2012 Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Campbell Barton
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/python/bmesh/bmesh_py_types.c
27  *  \ingroup pybmesh
28  */
29
30 #include <Python.h>
31
32 #include "BLI_math.h"
33
34 #include "DNA_mesh_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_material_types.h"
37
38 #include "BKE_depsgraph.h"
39 #include "BKE_customdata.h"
40 #include "BKE_DerivedMesh.h"
41
42 #include "bmesh.h"
43
44 #include "../mathutils/mathutils.h"
45
46 #include "../generic/py_capi_utils.h"
47
48 #include "bmesh_py_types.h" /* own include */
49 #include "bmesh_py_types_select.h"
50 #include "bmesh_py_types_customdata.h"
51 #include "bmesh_py_types_meshdata.h"
52
53 /* Common Flags
54  * ************ */
55
56 /* scene does not use BM_* flags. */
57 PyC_FlagSet bpy_bm_scene_vert_edge_face_flags[] = {
58         {1, "VERT"},
59         {2, "EDGE"},
60         {4, "FACE"},
61         {0, NULL}
62 };
63
64 PyC_FlagSet bpy_bm_htype_vert_edge_face_flags[] = {
65         {BM_VERT, "VERT"},
66         {BM_EDGE, "EDGE"},
67         {BM_FACE, "FACE"},
68                 {0, NULL}
69 };
70
71 PyC_FlagSet bpy_bm_htype_all_flags[] = {
72         {BM_VERT, "VERT"},
73         {BM_LOOP, "EDGE"},
74         {BM_FACE, "FACE"},
75         {BM_LOOP, "LOOP"},
76         {0, NULL}
77 };
78
79 PyC_FlagSet bpy_bm_hflag_all_flags[] = {
80         {BM_ELEM_SELECT,  "SELECT"},
81         {BM_ELEM_HIDDEN,  "HIDE"},
82         {BM_ELEM_SEAM,    "SEAM"},
83         {BM_ELEM_SMOOTH,  "SMOOTH"},
84         {BM_ELEM_TAG,     "TAG"},
85         {0, NULL}
86 };
87
88 /* py-type definitions
89  * ******************* */
90
91 /* getseters
92  * ========= */
93
94
95 /* bmesh elems
96  * ----------- */
97
98 PyDoc_STRVAR(bpy_bm_elem_select_doc,  "Selected state of this element.\n\n:type: boolean");
99 PyDoc_STRVAR(bpy_bm_elem_hide_doc,    "Hidden state of this element.\n\n:type: boolean");
100 PyDoc_STRVAR(bpy_bm_elem_tag_doc,     "Generic attribute scripts can use for own logic\n\n:type: boolean");
101 PyDoc_STRVAR(bpy_bm_elem_smooth_doc,  "Smooth state of this element.\n\n:type: boolean");
102 PyDoc_STRVAR(bpy_bm_elem_seam_doc,    "Seam for UV unwrapping.\n\n:type: boolean");
103
104
105 static PyObject *bpy_bm_elem_hflag_get(BPy_BMElem *self, void *flag)
106 {
107         const char hflag = (char)GET_INT_FROM_POINTER(flag);
108
109         BPY_BM_CHECK_OBJ(self);
110
111         return PyBool_FromLong(BM_elem_flag_test(self->ele, hflag));
112 }
113
114 static int bpy_bm_elem_hflag_set(BPy_BMElem *self, PyObject *value, void *flag)
115 {
116         const char hflag = (char)GET_INT_FROM_POINTER(flag);
117         int param;
118
119         BPY_BM_CHECK_INT(self);
120
121         param = PyLong_AsLong(value);
122
123         if (param == TRUE) {
124                 BM_elem_flag_enable(self->ele, hflag);
125                 return 0;
126         }
127         else if (param == FALSE) {
128                 BM_elem_flag_disable(self->ele, hflag);
129                 return 0;
130         }
131         else {
132                 PyErr_Format(PyExc_TypeError,
133                              "expected True/False or 0/1, not %.200s",
134                              Py_TYPE(value)->tp_name);
135                 return -1;
136         }
137 }
138
139
140 PyDoc_STRVAR(bpy_bm_elem_index_doc,
141 "Index of this element.\n"
142 "\n"
143 ":type: int\n"
144 "\n"
145 ".. note::\n"
146 "\n"
147 "   This value is not necessarily valid, while editing the mesh it can become *dirty*.\n"
148 "\n"
149 "   It's also possible to assign any number to this attribute for a scripts internal logic.\n"
150 "\n"
151 "   To ensure the value is up to date - see :class:`BMElemSeq.index_update`.\n"
152 );
153 static PyObject *bpy_bm_elem_index_get(BPy_BMElem *self, void *UNUSED(flag))
154 {
155         BPY_BM_CHECK_OBJ(self);
156
157         return PyLong_FromLong(BM_elem_index_get(self->ele));
158 }
159
160 static int bpy_bm_elem_index_set(BPy_BMElem *self, PyObject *value, void *UNUSED(flag))
161 {
162         int param;
163
164         BPY_BM_CHECK_INT(self);
165
166         param = PyLong_AsLong(value);
167
168         if (param == -1 && PyErr_Occurred()) {
169                 PyErr_SetString(PyExc_TypeError,
170                                 "expected an int type");
171                 return -1;
172         }
173         else {
174                 BM_elem_index_set(self->ele, param); /* set_dirty! */
175
176                 /* when setting the index assume its set invalid */
177                 if (self->ele->head.htype & (BM_VERT | BM_EDGE | BM_FACE)) {
178                         self->bm->elem_index_dirty |= self->ele->head.htype;
179                 }
180
181                 return 0;
182         }
183 }
184
185 /* type specific get/sets
186  * ---------------------- */
187
188
189 /* Mesh
190  * ^^^^ */
191
192 /* doc-strings for all uses of this function */
193
194 PyDoc_STRVAR(bpy_bmvertseq_doc,
195 "This meshes vert sequence (read-only).\n\n:type: :class:`BMVertSeq`"
196 );
197 static PyObject *bpy_bmvertseq_get(BPy_BMesh *self, void *UNUSED(closure))
198 {
199         BPY_BM_CHECK_OBJ(self);
200         return BPy_BMVertSeq_CreatePyObject(self->bm);
201 }
202
203 PyDoc_STRVAR(bpy_bmedgeseq_doc,
204 "This meshes edge sequence (read-only).\n\n:type: :class:`BMEdgeSeq`"
205 );
206 static PyObject *bpy_bmedgeseq_get(BPy_BMesh *self, void *UNUSED(closure))
207 {
208         BPY_BM_CHECK_OBJ(self);
209         return BPy_BMEdgeSeq_CreatePyObject(self->bm);
210 }
211
212 PyDoc_STRVAR(bpy_bmfaceseq_doc,
213 "This meshes face sequence (read-only).\n\n:type: :class:`BMFaceSeq`"
214 );
215 static PyObject *bpy_bmfaceseq_get(BPy_BMesh *self, void *UNUSED(closure))
216 {
217         BPY_BM_CHECK_OBJ(self);
218         return BPy_BMFaceSeq_CreatePyObject(self->bm);
219 }
220
221 PyDoc_STRVAR(bpy_bmloopseq_doc,
222 "This meshes face sequence (read-only).\n\n:type: :class:`BMLoopSeq`"
223 );
224 static PyObject *bpy_bmloopseq_get(BPy_BMesh *self, void *UNUSED(closure))
225 {
226         BPY_BM_CHECK_OBJ(self);
227         return BPy_BMLoopSeq_CreatePyObject(self->bm);
228 }
229
230 /* vert */
231 PyDoc_STRVAR(bpy_bmvert_link_edges_doc,
232 "Edges connected to this vertex (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMVert`"
233 );
234 PyDoc_STRVAR(bpy_bmvert_link_faces_doc,
235 "Faces connected to this vertex (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMFace`"
236 );
237 PyDoc_STRVAR(bpy_bmvert_link_loops_doc,
238 "Loops that use this vertex (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMLoop`"
239 );
240 /* edge */
241 PyDoc_STRVAR(bpy_bmedge_verts_doc,
242 "Verts this edge uses (always 2), (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMVert`"
243 );
244 PyDoc_STRVAR(bpy_bmedge_link_faces_doc,
245 "Faces connected to this edge, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMFace`"
246 );
247 PyDoc_STRVAR(bpy_bmedge_link_loops_doc,
248 "Loops connected to this edge, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMLoop`"
249 );
250 /* face */
251 PyDoc_STRVAR(bpy_bmface_verts_doc,
252 "Verts of this face, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMVert`"
253 );
254 PyDoc_STRVAR(bpy_bmface_edges_doc,
255 "Edges of this face, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMEdge`"
256 );
257 PyDoc_STRVAR(bpy_bmface_loops_doc,
258 "Loops of this face, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMLoop`"
259 );
260 /* loop */
261 PyDoc_STRVAR(bpy_bmloops_link_loops_doc,
262 "Loops connected to this loop, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMLoop`"
263 );
264
265 static PyObject *bpy_bmelemseq_elem_get(BPy_BMElem *self, void *itype)
266 {
267         BPY_BM_CHECK_OBJ(self);
268         return BPy_BMElemSeq_CreatePyObject(self->bm, self, GET_INT_FROM_POINTER(itype));
269 }
270
271
272 PyDoc_STRVAR(bpy_bm_is_valid_doc,
273 "True when this element is valid (hasn't been removed).\n\n:type: boolean"
274 );
275 static PyObject *bpy_bm_is_valid_get(BPy_BMGeneric *self)
276 {
277         return PyBool_FromLong(BPY_BM_IS_VALID(self));
278 }
279
280 PyDoc_STRVAR(bpy_bmesh_is_wrapped_doc,
281 "True when this mesh is owned by blender (typically the editmode BMesh).\n\n:type: boolean"
282 );
283 static PyObject *bpy_bmesh_is_wrapped_get(BPy_BMesh *self)
284 {
285         BPY_BM_CHECK_OBJ(self);
286
287         return PyBool_FromLong(self->flag & BPY_BMFLAG_IS_WRAPPED);
288 }
289
290 PyDoc_STRVAR(bpy_bmesh_select_mode_doc,
291 "The selection mode, values can be {'VERT', 'EDGE', 'FACE'}, can't be assigned an empty set.\n\n:type: set"
292 );
293 static PyObject *bpy_bmesh_select_mode_get(BPy_BMesh *self)
294 {
295         BPY_BM_CHECK_OBJ(self);
296
297         return PyC_FlagSet_FromBitfield(bpy_bm_scene_vert_edge_face_flags, self->bm->selectmode);
298 }
299
300 static int bpy_bmesh_select_mode_set(BPy_BMesh *self, PyObject *value)
301 {
302         int flag = 0;
303         BPY_BM_CHECK_INT(self);
304
305         if (PyC_FlagSet_ToBitfield(bpy_bm_scene_vert_edge_face_flags, value, &flag, "bm.select_mode") == -1) {
306                 return -1;
307         }
308         else if (flag == 0) {
309                 PyErr_SetString(PyExc_TypeError,
310                                 "bm.select_mode: cant assignt an empty value");
311                 return -1;
312         }
313         else {
314                 self->bm->selectmode = flag;
315                 return 0;
316         }
317 }
318
319 PyDoc_STRVAR(bpy_bmesh_select_history_doc,
320 "Sequence of selected items (the last is displayed as active).\n\n:type: :class:`BMEditSelSeq`"
321 );
322 static PyObject *bpy_bmesh_select_history_get(BPy_BMesh *self)
323 {
324         BPY_BM_CHECK_OBJ(self);
325
326         return BPy_BMEditSel_CreatePyObject(self->bm);
327 }
328
329 static int bpy_bmesh_select_history_set(BPy_BMesh *self, PyObject *value)
330 {
331         BPY_BM_CHECK_INT(self);
332
333         return BPy_BMEditSel_Assign(self, value);
334 }
335
336 /* Vert
337  * ^^^^ */
338
339 PyDoc_STRVAR(bpy_bmvert_co_doc,
340 "The coordinates for this vertex as a 3D, wrapped vector.\n\n:type: :class:`mathutils.Vector`"
341 );
342 static PyObject *bpy_bmvert_co_get(BPy_BMVert *self)
343 {
344         BPY_BM_CHECK_OBJ(self);
345         return Vector_CreatePyObject(self->v->co, 3, Py_WRAP, NULL);
346 }
347
348 static int bpy_bmvert_co_set(BPy_BMVert *self, PyObject *value)
349 {
350         BPY_BM_CHECK_INT(self);
351
352         if (mathutils_array_parse(self->v->co, 3, 3, value, "BMVert.co") != -1) {
353                 return 0;
354         }
355         else {
356                 return -1;
357         }
358 }
359
360
361 PyDoc_STRVAR(bpy_bmvert_normal_doc,
362 "The normal for this vertex as a 3D, wrapped vector.\n\n:type: :class:`mathutils.Vector`"
363 );
364 static PyObject *bpy_bmvert_normal_get(BPy_BMVert *self)
365 {
366         BPY_BM_CHECK_OBJ(self);
367         return Vector_CreatePyObject(self->v->no, 3, Py_WRAP, NULL);
368 }
369
370 static int bpy_bmvert_normal_set(BPy_BMVert *self, PyObject *value)
371 {
372         BPY_BM_CHECK_INT(self);
373
374         if (mathutils_array_parse(self->v->no, 3, 3, value, "BMVert.normal") != -1) {
375                 return 0;
376         }
377         else {
378                 return -1;
379         }
380 }
381
382
383 PyDoc_STRVAR(bpy_bmvert_is_manifold_doc,
384 "True when this vertex is manifold (read-only).\n\n:type: boolean"
385 );
386 static PyObject *bpy_bmvert_is_manifold_get(BPy_BMVert *self)
387 {
388         BPY_BM_CHECK_OBJ(self);
389         return PyBool_FromLong(BM_vert_is_manifold(self->v));
390 }
391
392
393 PyDoc_STRVAR(bpy_bmvert_is_wire_doc,
394 "True when this vertex is not connected to any faces (read-only).\n\n:type: boolean"
395 );
396 static PyObject *bpy_bmvert_is_wire_get(BPy_BMVert *self)
397 {
398         BPY_BM_CHECK_OBJ(self);
399         return PyBool_FromLong(BM_vert_is_wire(self->v));
400 }
401
402
403 /* Edge
404  * ^^^^ */
405
406 PyDoc_STRVAR(bpy_bmedge_is_manifold_doc,
407 "True when this edge is manifold (read-only).\n\n:type: boolean"
408 );
409 static PyObject *bpy_bmedge_is_manifold_get(BPy_BMEdge *self)
410 {
411         BPY_BM_CHECK_OBJ(self);
412         return PyBool_FromLong(BM_edge_is_manifold(self->e));
413 }
414
415
416 PyDoc_STRVAR(bpy_bmedge_is_wire_doc,
417 "True when this edge is not connected to any faces (read-only).\n\n:type: boolean"
418 );
419 static PyObject *bpy_bmedge_is_wire_get(BPy_BMEdge *self)
420 {
421         BPY_BM_CHECK_OBJ(self);
422         return PyBool_FromLong(BM_edge_is_wire(self->e));
423 }
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 );
429 static PyObject *bpy_bmedge_is_boundary_get(BPy_BMEdge *self)
430 {
431         BPY_BM_CHECK_OBJ(self);
432         return PyBool_FromLong(BM_edge_is_boundary(self->e));
433 }
434
435
436 /* Face
437  * ^^^^ */
438
439 PyDoc_STRVAR(bpy_bmface_normal_doc,
440 "The normal for this face as a 3D, wrapped vector.\n\n:type: :class:`mathutils.Vector`"
441 );
442 static PyObject *bpy_bmface_normal_get(BPy_BMFace *self)
443 {
444         BPY_BM_CHECK_OBJ(self);
445         return Vector_CreatePyObject(self->f->no, 3, Py_WRAP, NULL);
446 }
447
448 static int bpy_bmface_normal_set(BPy_BMFace *self, PyObject *value)
449 {
450         BPY_BM_CHECK_INT(self);
451
452         if (mathutils_array_parse(self->f->no, 3, 3, value, "BMFace.normal") != -1) {
453                 return 0;
454         }
455         else {
456                 return -1;
457         }
458 }
459
460 PyDoc_STRVAR(bpy_bmface_material_index_doc,
461 "The faces material index.\n\n:type: int"
462 );
463 static PyObject *bpy_bmface_material_index_get(BPy_BMFace *self)
464 {
465         BPY_BM_CHECK_OBJ(self);
466         return PyLong_FromLong(self->f->mat_nr);
467 }
468
469 static int bpy_bmface_material_index_set(BPy_BMFace *self, PyObject *value)
470 {
471         int param;
472
473         BPY_BM_CHECK_INT(self);
474
475         param = PyLong_AsLong(value);
476
477         if (param == -1 && PyErr_Occurred()) {
478                 PyErr_SetString(PyExc_TypeError,
479                                 "expected an int type");
480                 return -1;
481         }
482         else if ((param < 0) || (param > MAXMAT)) {
483                 /* normally we clamp but in this case raise an error */
484                 PyErr_SetString(PyExc_ValueError,
485                                 "material index outside of usable range (0 - 32766)");
486                 return -1;
487         }
488         else {
489                 self->f->mat_nr = (short)param;
490                 return 0;
491         }
492 }
493
494 /* Loop
495  * ^^^^ */
496
497 PyDoc_STRVAR(bpy_bmloop_vert_doc,
498 "The loops vertex (read-only).\n\n:type: :class:`BMVert`"
499 );
500 static PyObject *bpy_bmloop_vert_get(BPy_BMLoop *self)
501 {
502         BPY_BM_CHECK_OBJ(self);
503         return BPy_BMVert_CreatePyObject(self->bm, self->l->v);
504 }
505
506
507 PyDoc_STRVAR(bpy_bmloop_edge_doc,
508 "The loops edge (between this loop and the next), (read-only).\n\n:type: :class:`BMEdge`"
509 );
510 static PyObject *bpy_bmloop_edge_get(BPy_BMLoop *self)
511 {
512         BPY_BM_CHECK_OBJ(self);
513         return BPy_BMEdge_CreatePyObject(self->bm, self->l->e);
514 }
515
516
517 PyDoc_STRVAR(bpy_bmloop_face_doc,
518 "The face this loop makes (read-only).\n\n:type: :class:`BMFace`"
519 );
520 static PyObject *bpy_bmloop_face_get(BPy_BMLoop *self)
521 {
522         BPY_BM_CHECK_OBJ(self);
523         return BPy_BMFace_CreatePyObject(self->bm, self->l->f);
524 }
525
526 PyDoc_STRVAR(bpy_bmloop_link_loop_next_doc,
527 "The next face corner (read-only).\n\n:type: :class:`BMLoop`"
528 );
529 static PyObject *bpy_bmloop_link_loop_next_get(BPy_BMLoop *self)
530 {
531         BPY_BM_CHECK_OBJ(self);
532         return BPy_BMLoop_CreatePyObject(self->bm, self->l->next);
533 }
534
535 PyDoc_STRVAR(bpy_bmloop_link_loop_prev_doc,
536 "The previous face corner (read-only).\n\n:type: :class:`BMLoop`"
537 );
538 static PyObject *bpy_bmloop_link_loop_prev_get(BPy_BMLoop *self)
539 {
540         BPY_BM_CHECK_OBJ(self);
541         return BPy_BMLoop_CreatePyObject(self->bm, self->l->prev);
542 }
543
544 PyDoc_STRVAR(bpy_bmloop_link_loop_radial_next_doc,
545 "The next loop around the edge (read-only).\n\n:type: :class:`BMLoop`"
546 );
547 static PyObject *bpy_bmloop_link_loop_radial_next_get(BPy_BMLoop *self)
548 {
549         BPY_BM_CHECK_OBJ(self);
550         return BPy_BMLoop_CreatePyObject(self->bm, self->l->radial_next);
551 }
552
553 PyDoc_STRVAR(bpy_bmloop_link_loop_radial_prev_doc,
554 "The previous loop around the edge (read-only).\n\n:type: :class:`BMLoop`"
555 );
556 static PyObject *bpy_bmloop_link_loop_radial_prev_get(BPy_BMLoop *self)
557 {
558         BPY_BM_CHECK_OBJ(self);
559         return BPy_BMLoop_CreatePyObject(self->bm, self->l->radial_prev);
560 }
561
562 /* ElemSeq
563  * ^^^^^^^ */
564
565 /* note: use for bmvert/edge/face/loop seq's use these, not bmelemseq directly */
566 PyDoc_STRVAR(bpy_bmelemseq_layers_doc,
567 "custom-data layers (read-only).\n\n:type: :class:`BMLayerAccess`"
568 );
569 static PyObject *bpy_bmelemseq_layers_get(BPy_BMElemSeq *self, void *htype)
570 {
571         BPY_BM_CHECK_OBJ(self);
572
573         return BPy_BMLayerAccess_CreatePyObject(self->bm, GET_INT_FROM_POINTER(htype));
574 }
575
576 /* FaceSeq
577  * ^^^^^^^ */
578
579 PyDoc_STRVAR(bpy_bmfaceseq_active_doc,
580 "active face.\n\n:type: :class:`BMFace` or None"
581 );
582 static PyObject *bpy_bmfaceseq_active_get(BPy_BMElemSeq *self, void *UNUSED(closure))
583 {
584         BMesh *bm = self->bm;
585         BPY_BM_CHECK_OBJ(self);
586
587         if (bm->act_face) {
588                 return BPy_BMElem_CreatePyObject(bm, (BMHeader *)bm->act_face);
589         }
590         else {
591                 Py_RETURN_NONE;
592         }
593 }
594
595 static int bpy_bmfaceseq_active_set(BPy_BMElem *self, PyObject *value, void *UNUSED(closure))
596 {
597         BMesh *bm = self->bm;
598         if (value == Py_None) {
599                 bm->act_face = NULL;
600                 return 0;
601         }
602         else if (BPy_BMFace_Check(value)) {
603                 BPY_BM_CHECK_SOURCE_INT(value, bm, "faces.active = f");
604
605                 bm->act_face = ((BPy_BMFace *)value)->f;
606                 return 0;
607         }
608         else {
609                 PyErr_Format(PyExc_TypeError,
610                              "faces.active = f: expected BMFace or None, not %.200s",
611                              Py_TYPE(value)->tp_name);
612                 return -1;
613         }
614 }
615
616 static PyGetSetDef bpy_bmesh_getseters[] = {
617         {(char *)"verts", (getter)bpy_bmvertseq_get, (setter)NULL, (char *)bpy_bmvertseq_doc, NULL},
618         {(char *)"edges", (getter)bpy_bmedgeseq_get, (setter)NULL, (char *)bpy_bmedgeseq_doc, NULL},
619         {(char *)"faces", (getter)bpy_bmfaceseq_get, (setter)NULL, (char *)bpy_bmfaceseq_doc, NULL},
620         {(char *)"loops", (getter)bpy_bmloopseq_get, (setter)NULL, (char *)bpy_bmloopseq_doc, NULL},
621         {(char *)"select_mode", (getter)bpy_bmesh_select_mode_get, (setter)bpy_bmesh_select_mode_set, (char *)bpy_bmesh_select_mode_doc, NULL},
622
623         {(char *)"select_history", (getter)bpy_bmesh_select_history_get, (setter)bpy_bmesh_select_history_set, (char *)bpy_bmesh_select_history_doc, NULL},
624
625         /* readonly checks */
626         {(char *)"is_wrapped", (getter)bpy_bmesh_is_wrapped_get, (setter)NULL, (char *)bpy_bmesh_is_wrapped_doc, NULL}, /* as with mathutils */
627         {(char *)"is_valid",   (getter)bpy_bm_is_valid_get,   (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
628
629         {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
630 };
631
632 static PyGetSetDef bpy_bmvert_getseters[] = {
633         /* generic */
634         {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT},
635         {(char *)"hide",   (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc,   (void *)BM_ELEM_HIDDEN},
636         {(char *)"tag",    (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_tag_doc,    (void *)BM_ELEM_TAG},
637         {(char *)"index",  (getter)bpy_bm_elem_index_get, (setter)bpy_bm_elem_index_set, (char *)bpy_bm_elem_index_doc,  NULL},
638
639         {(char *)"co",     (getter)bpy_bmvert_co_get,     (setter)bpy_bmvert_co_set,     (char *)bpy_bmvert_co_doc, NULL},
640         {(char *)"normal", (getter)bpy_bmvert_normal_get, (setter)bpy_bmvert_normal_set, (char *)bpy_bmvert_normal_doc, NULL},
641
642         /* connectivity data */
643         {(char *)"link_edges", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmvert_link_edges_doc, (void *)BM_EDGES_OF_VERT},
644         {(char *)"link_faces", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmvert_link_faces_doc, (void *)BM_FACES_OF_VERT},
645         {(char *)"link_loops", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmvert_link_loops_doc, (void *)BM_LOOPS_OF_VERT},
646
647         /* readonly checks */
648         {(char *)"is_manifold",  (getter)bpy_bmvert_is_manifold_get,  (setter)NULL, (char *)bpy_bmvert_is_manifold_doc, NULL},
649         {(char *)"is_wire",      (getter)bpy_bmvert_is_wire_get,      (setter)NULL, (char *)bpy_bmvert_is_wire_doc, NULL},
650         {(char *)"is_valid",     (getter)bpy_bm_is_valid_get,         (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
651
652         {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
653 };
654
655 static PyGetSetDef bpy_bmedge_getseters[] = {
656         /* generic */
657         {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT},
658         {(char *)"hide",   (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc,   (void *)BM_ELEM_HIDDEN},
659         {(char *)"tag",    (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_tag_doc,    (void *)BM_ELEM_TAG},
660         {(char *)"index",  (getter)bpy_bm_elem_index_get, (setter)bpy_bm_elem_index_set, (char *)bpy_bm_elem_index_doc,  NULL},
661
662         {(char *)"smooth", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_smooth_doc, (void *)BM_ELEM_SMOOTH},
663         {(char *)"seam",   (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_seam_doc, (void *)BM_ELEM_SEAM},
664
665         /* connectivity data */
666         {(char *)"verts", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmedge_verts_doc, (void *)BM_VERTS_OF_EDGE},
667
668         {(char *)"link_faces", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmedge_link_faces_doc, (void *)BM_FACES_OF_EDGE},
669         {(char *)"link_loops", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmedge_link_loops_doc, (void *)BM_LOOPS_OF_EDGE},
670
671         /* readonly checks */
672         {(char *)"is_manifold",  (getter)bpy_bmedge_is_manifold_get,  (setter)NULL, (char *)bpy_bmedge_is_manifold_doc, NULL},
673         {(char *)"is_wire",      (getter)bpy_bmedge_is_wire_get,      (setter)NULL, (char *)bpy_bmedge_is_wire_doc, NULL},
674         {(char *)"is_boundary",   (getter)bpy_bmedge_is_boundary_get,   (setter)NULL, (char *)bpy_bmedge_is_boundary_doc, NULL},
675         {(char *)"is_valid",     (getter)bpy_bm_is_valid_get,         (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
676
677         {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
678 };
679
680 static PyGetSetDef bpy_bmface_getseters[] = {
681         /* generic */
682         {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT},
683         {(char *)"hide",   (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc,   (void *)BM_ELEM_HIDDEN},
684         {(char *)"tag",    (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_tag_doc,    (void *)BM_ELEM_TAG},
685         {(char *)"index",  (getter)bpy_bm_elem_index_get, (setter)bpy_bm_elem_index_set, (char *)bpy_bm_elem_index_doc,  NULL},
686
687         {(char *)"smooth", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_smooth_doc, (void *)BM_ELEM_SMOOTH},
688
689         {(char *)"normal", (getter)bpy_bmface_normal_get, (setter)bpy_bmface_normal_set, (char *)bpy_bmface_normal_doc, NULL},
690
691         {(char *)"material_index",  (getter)bpy_bmface_material_index_get, (setter)bpy_bmface_material_index_set, (char *)bpy_bmface_material_index_doc,  NULL},
692
693         /* connectivity data */
694         {(char *)"verts", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmface_verts_doc, (void *)BM_VERTS_OF_FACE},
695         {(char *)"edges", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmface_edges_doc, (void *)BM_EDGES_OF_FACE},
696         {(char *)"loops", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmface_loops_doc, (void *)BM_LOOPS_OF_FACE},
697
698         /* readonly checks */
699         {(char *)"is_valid",   (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
700
701         {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
702 };
703
704 static PyGetSetDef bpy_bmloop_getseters[] = {
705         /* generic */
706         /* flags are available but not used for loops. */
707         // {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT},
708         // {(char *)"hide",   (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc,   (void *)BM_ELEM_HIDDEN},
709         {(char *)"tag",    (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_tag_doc,    (void *)BM_ELEM_TAG},
710         {(char *)"index",  (getter)bpy_bm_elem_index_get, (setter)bpy_bm_elem_index_set, (char *)bpy_bm_elem_index_doc,  NULL},
711
712         {(char *)"vert", (getter)bpy_bmloop_vert_get, (setter)NULL, (char *)bpy_bmloop_vert_doc, NULL},
713         {(char *)"edge", (getter)bpy_bmloop_edge_get, (setter)NULL, (char *)bpy_bmloop_edge_doc, NULL},
714         {(char *)"face", (getter)bpy_bmloop_face_get, (setter)NULL, (char *)bpy_bmloop_face_doc, NULL},
715
716         /* connectivity data */
717         {(char *)"link_loops", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmloops_link_loops_doc, (void *)BM_LOOPS_OF_LOOP},
718         {(char *)"link_loop_next", (getter)bpy_bmloop_link_loop_next_get, (setter)NULL, (char *)bpy_bmloop_link_loop_next_doc, NULL},
719         {(char *)"link_loop_prev", (getter)bpy_bmloop_link_loop_prev_get, (setter)NULL, (char *)bpy_bmloop_link_loop_prev_doc, NULL},
720         {(char *)"link_loop_radial_next", (getter)bpy_bmloop_link_loop_radial_next_get, (setter)NULL, (char *)bpy_bmloop_link_loop_radial_next_doc, NULL},
721         {(char *)"link_loop_radial_prev", (getter)bpy_bmloop_link_loop_radial_prev_get, (setter)NULL, (char *)bpy_bmloop_link_loop_radial_prev_doc, NULL},
722
723         /* readonly checks */
724         {(char *)"is_valid",   (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
725
726         {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
727 };
728
729 static PyGetSetDef bpy_bmvertseq_getseters[] = {
730         {(char *)"layers",    (getter)bpy_bmelemseq_layers_get, (setter)NULL, (char *)bpy_bmelemseq_layers_doc, (void *)BM_VERT},
731                 {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
732 };
733 static PyGetSetDef bpy_bmedgeseq_getseters[] = {
734         {(char *)"layers",    (getter)bpy_bmelemseq_layers_get, (setter)NULL, (char *)bpy_bmelemseq_layers_doc, (void *)BM_EDGE},
735         {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
736 };
737 static PyGetSetDef bpy_bmfaceseq_getseters[] = {
738         {(char *)"layers",    (getter)bpy_bmelemseq_layers_get, (setter)NULL, (char *)bpy_bmelemseq_layers_doc, (void *)BM_FACE},
739         /* face only */
740         {(char *)"active",    (getter)bpy_bmfaceseq_active_get, (setter)bpy_bmfaceseq_active_set, (char *)bpy_bmfaceseq_active_doc, NULL},
741         {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
742 };
743 static PyGetSetDef bpy_bmloopseq_getseters[] = {
744         {(char *)"layers",    (getter)bpy_bmelemseq_layers_get, (setter)NULL, (char *)bpy_bmelemseq_layers_doc, (void *)BM_LOOP},
745         {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
746 };
747
748
749 /* Methods
750  * ======= */
751
752
753 /* Mesh
754  * ---- */
755
756 PyDoc_STRVAR(bpy_bmesh_copy_doc,
757 ".. method:: copy()\n"
758 "\n"
759 "   :return: A copy of this BMesh.\n"
760 "   :rtype: :class:`BMesh`\n"
761 );
762 static PyObject *bpy_bmesh_copy(BPy_BMesh *self)
763 {
764         BMesh *bm;
765         BMesh *bm_copy;
766
767         BPY_BM_CHECK_OBJ(self);
768
769         bm = self->bm;
770
771         bm_copy = BM_mesh_copy(bm);
772
773         if (bm_copy) {
774                 return BPy_BMesh_CreatePyObject(bm_copy, BPY_BMFLAG_NOP);
775         }
776         else {
777                 PyErr_SetString(PyExc_SystemError, "Unable to copy BMesh, internal error");
778                 return NULL;
779         }
780 }
781
782 PyDoc_STRVAR(bpy_bmesh_clear_doc,
783 ".. method:: clear()\n"
784 "\n"
785 "   Clear all mesh data.\n"
786 );
787 static PyObject *bpy_bmesh_clear(BPy_BMesh *self)
788 {
789         BMesh *bm;
790
791         BPY_BM_CHECK_OBJ(self);
792
793         bm = self->bm;
794
795         BM_mesh_clear(bm);
796
797         Py_RETURN_NONE;
798 }
799
800 PyDoc_STRVAR(bpy_bmesh_free_doc,
801 ".. method:: free()\n"
802 "\n"
803 "   Explicitly free the BMesh data from memory, causing exceptions on further access.\n"
804 "\n"
805 "   .. note::\n"
806 "\n"
807 "      The BMesh is freed automatically, typically when the script finishes executing.\n"
808 "      However in some cases its hard to predict when this will be and its useful to\n"
809 "      explicitly free the data.\n"
810 );
811 static PyObject *bpy_bmesh_free(BPy_BMesh *self)
812 {
813         if (self->bm) {
814                 BMesh *bm = self->bm;
815
816                 if ((self->flag & BPY_BMFLAG_IS_WRAPPED) == 0) {
817                         BM_mesh_free(bm);
818                 }
819
820                 bpy_bm_generic_invalidate((BPy_BMGeneric *)self);
821         }
822
823         Py_RETURN_NONE;
824 }
825
826 PyDoc_STRVAR(bpy_bmesh_to_mesh_doc,
827 ".. method:: to_mesh(mesh)\n"
828 "\n"
829 "   Writes this BMesh data into an existing Mesh datablock.\n"
830 "\n"
831 "   :arg mesh: The mesh data to write into.\n"
832 "   :type mesh: :class:`Mesh`\n"
833 );
834 static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
835 {
836         PyObject *py_mesh;
837         Mesh *me;
838         BMesh *bm;
839
840         BPY_BM_CHECK_OBJ(self);
841
842         if (!PyArg_ParseTuple(args, "O:to_mesh", &py_mesh) ||
843             !(me = PyC_RNA_AsPointer(py_mesh, "Mesh")))
844         {
845                 return NULL;
846         }
847
848         /* we could allow this but its almost certainly _not_ what script authors want */
849         if (me->edit_btmesh) {
850                 PyErr_Format(PyExc_ValueError,
851                              "to_mesh(): Mesh '%s' is in editmode", me->id.name + 2);
852                 return NULL;
853         }
854
855         bm = self->bm;
856
857         BM_mesh_bm_to_me(bm, me, FALSE);
858
859         /* we could have the user do this but if they forget blender can easy crash
860          * since the references arrays for the objects derived meshes are now invalid */
861         DAG_id_tag_update(&me->id, OB_RECALC_DATA);
862
863         Py_RETURN_NONE;
864 }
865
866 PyDoc_STRVAR(bpy_bmesh_from_object_doc,
867 ".. method:: from_object(object, scene, deform=True, render=False, cage=False)\n"
868 "\n"
869 "   Initialize this bmesh from existing object datablock (currently only meshes are supported).\n"
870 "\n"
871 "   :arg object: The object data to load.\n"
872 "   :type object: :class:`Object`\n"
873 "   :arg deform: Apply deformation modifiers.\n"
874 "   :type deform: boolean\n"
875 "   :arg render: Use render settings.\n"
876 "   :type render: boolean\n"
877 "   :arg cage: Get the mesh as a deformed cage.\n"
878 "   :type cage: boolean\n"
879 );
880 static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args)
881 {
882         PyObject *py_object;
883         PyObject *py_scene;
884         Object *ob;
885         struct Scene *scene;
886         BMesh *bm;
887         int use_deform = TRUE;
888         int use_render = FALSE;
889         int use_cage   = FALSE;
890         DerivedMesh *dm;
891         const int mask = CD_MASK_BMESH;
892
893         BPY_BM_CHECK_OBJ(self);
894
895         if (!PyArg_ParseTuple(args, "OO|iii:from_object", &py_object, &py_scene, &use_render, &use_cage) ||
896             !(ob    = PyC_RNA_AsPointer(py_object, "Object")) ||
897             !(scene = PyC_RNA_AsPointer(py_scene,  "Scene")))
898         {
899                 return NULL;
900         }
901
902         if (ob->type != OB_MESH) {
903                 PyErr_SetString(PyExc_ValueError,
904                                 "from_object(...): currently only mesh objects are supported");
905                 return NULL;
906         }
907
908         /* Write the display mesh into the dummy mesh */
909         if (use_deform) {
910                 if (use_render) {
911                         if (use_cage) {
912                                 PyErr_SetString(PyExc_ValueError,
913                                                 "from_object(...): cage arg is unsupported when (render=True)");
914                                 return NULL;
915                         }
916                         else {
917                                 dm = mesh_create_derived_render(scene, ob, mask);
918                         }
919                 }
920                 else {
921                         if (use_cage) {
922                                 dm = mesh_get_derived_deform(scene, ob, mask);  /* ob->derivedDeform */
923                         }
924                         else {
925                                 dm = mesh_get_derived_final(scene, ob, mask);  /* ob->derivedFinal */
926                         }
927                 }
928         }
929         else {
930                 /* !use_deform */
931                 if (use_render) {
932                         if (use_cage) {
933                                 PyErr_SetString(PyExc_ValueError,
934                                                 "from_object(...): cage arg is unsupported when (render=True)");
935                                 return NULL;
936                         }
937                         else {
938                                 dm = mesh_create_derived_no_deform_render(scene, ob, NULL, mask);
939                         }
940                 }
941                 else {
942                         if (use_cage) {
943                                 PyErr_SetString(PyExc_ValueError,
944                                                 "from_object(...): cage arg is unsupported when (deform=False, render=False)");
945                                 return NULL;
946                         }
947                         else {
948                                 dm = mesh_create_derived_no_deform(scene, ob, NULL, mask);
949                         }
950                 }
951         }
952
953         if (dm == NULL) {
954                 PyErr_Format(PyExc_ValueError,
955                              "from_object(...): Object '%s' has no usable mesh data", ob->id.name + 2);
956                 return NULL;
957         }
958
959         bm = self->bm;
960
961         DM_to_bmesh_ex(dm, bm);
962
963         dm->release(dm);
964
965         Py_RETURN_NONE;
966 }
967
968
969 PyDoc_STRVAR(bpy_bmesh_from_mesh_doc,
970 ".. method:: from_mesh(mesh, use_shape_key=False, shape_key_index=0)\n"
971 "\n"
972 "   Initialize this bmesh from existing mesh datablock.\n"
973 "\n"
974 "   :arg mesh: The mesh data to load.\n"
975 "   :type mesh: :class:`Mesh`\n"
976 "   :arg use_shape_key: Use the locations from a shape key.\n"
977 "   :type use_shape_key: boolean\n"
978 "   :arg shape_key_index: The shape key index to use.\n"
979 "   :type shape_key_index: int\n"
980 );
981 static PyObject *bpy_bmesh_from_mesh(BPy_BMesh *self, PyObject *args, PyObject *kw)
982 {
983         static const char *kwlist[] = {"mesh", "use_shape_key", "shape_key_index", NULL};
984         BMesh *bm;
985         PyObject *py_mesh;
986         Mesh *me;
987         int use_shape_key = FALSE;
988         int shape_key_index = 0;
989
990         if (!PyArg_ParseTupleAndKeywords(args, kw, "O|ii:from_mesh", (char **)kwlist,
991                                          &py_mesh, &use_shape_key, &shape_key_index) ||
992             !(me = PyC_RNA_AsPointer(py_mesh, "Mesh")))
993         {
994                 return NULL;
995         }
996
997         bm = self->bm;
998
999         BM_mesh_bm_from_me(bm, me, use_shape_key, shape_key_index + 1);
1000
1001         Py_RETURN_NONE;
1002 }
1003
1004
1005 PyDoc_STRVAR(bpy_bmesh_select_flush_mode_doc,
1006 ".. method:: select_flush_mode()\n"
1007 "\n"
1008 "   flush selection based on the current mode current :class:`BMesh.select_mode`.\n"
1009 );
1010 static PyObject *bpy_bmesh_select_flush_mode(BPy_BMesh *self)
1011 {
1012         BPY_BM_CHECK_OBJ(self);
1013
1014         BM_mesh_select_mode_flush(self->bm);
1015
1016         Py_RETURN_NONE;
1017 }
1018
1019
1020 PyDoc_STRVAR(bpy_bmesh_select_flush_doc,
1021 ".. method:: select_flush(select)\n"
1022 "\n"
1023 "   Flush selection, independent of the current selection mode.\n"
1024 "\n"
1025 "   :arg select: flush selection or de-selected elements.\n"
1026 "   :type select: boolean\n"
1027 );
1028 static PyObject *bpy_bmesh_select_flush(BPy_BMesh *self, PyObject *value)
1029 {
1030         int param;
1031
1032         BPY_BM_CHECK_OBJ(self);
1033
1034         param = PyLong_AsLong(value);
1035         if (param != FALSE && param != TRUE) {
1036                 PyErr_SetString(PyExc_TypeError,
1037                                 "expected a boolean type 0/1");
1038                 return NULL;
1039         }
1040
1041         if (param)  BM_mesh_select_flush(self->bm);
1042         else        BM_mesh_deselect_flush(self->bm);
1043
1044         Py_RETURN_NONE;
1045 }
1046
1047
1048 PyDoc_STRVAR(bpy_bmesh_normal_update_doc,
1049 ".. method:: normal_update(skip_hidden=False)\n"
1050 "\n"
1051 "   Update mesh normals.\n"
1052 "\n"
1053 "   :arg skip_hidden: When True hidden elements are ignored.\n"
1054 "   :type skip_hidden: boolean\n"
1055 );
1056 static PyObject *bpy_bmesh_normal_update(BPy_BMesh *self, PyObject *args)
1057 {
1058
1059         int skip_hidden = FALSE;
1060
1061         BPY_BM_CHECK_OBJ(self);
1062
1063         if (!PyArg_ParseTuple(args, "|i:normal_update", &skip_hidden)) {
1064                 return NULL;
1065         }
1066
1067         BM_mesh_normals_update(self->bm, skip_hidden);
1068
1069         Py_RETURN_NONE;
1070 }
1071
1072
1073 PyDoc_STRVAR(bpy_bmesh_transform_doc,
1074 ".. method:: transform(matrix, filter=None)\n"
1075 "\n"
1076 "   Transform the mesh (optionally filtering flagged data only).\n"
1077 "\n"
1078 "   :arg matrix: transform matrix.\n"
1079 "   :type matrix: 4x4 :class:`mathutils.Matrix`\n"
1080 "   :arg filter: set of values in ('SELECT', 'HIDE', 'SEAM', 'SMOOTH', 'TAG').\n"
1081 "   :type filter: set\n"
1082 );
1083 static PyObject *bpy_bmesh_transform(BPy_BMElem *self, PyObject *args, PyObject *kw)
1084 {
1085         static const char *kwlist[] = {"matrix", "filter", NULL};
1086
1087         MatrixObject *mat;
1088         PyObject *filter = NULL;
1089         int filter_flags = 0;
1090
1091         BPY_BM_CHECK_OBJ(self);
1092
1093         if (!PyArg_ParseTupleAndKeywords(args, kw,
1094                                          "O!|O!:transform",
1095                                          (char **)kwlist,
1096                                          &matrix_Type, &mat,
1097                                          &PySet_Type,  &filter))
1098         {
1099                 return NULL;
1100         }
1101         else {
1102                 BMVert *eve;
1103                 BMIter iter;
1104                 void *mat_ptr;
1105
1106                 if (BaseMath_ReadCallback(mat) == -1) {
1107                         return NULL;
1108                 }
1109                 else if (mat->num_col != 4 || mat->num_row != 4) {
1110                         PyErr_SetString(PyExc_ValueError,
1111                                         "expected a 4x4 matrix");
1112                         return NULL;
1113                 }
1114
1115                 if (filter != NULL && PyC_FlagSet_ToBitfield(bpy_bm_hflag_all_flags, filter,
1116                                                              &filter_flags, "bm.transform") == -1)
1117                 {
1118                         return NULL;
1119                 }
1120
1121                 mat_ptr = mat->matrix;
1122
1123                 if (!filter_flags) {
1124                         BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) {
1125                                 mul_m4_v3((float (*)[4])mat_ptr, eve->co);
1126                         }
1127                 }
1128                 else {
1129                         char filter_flags_ch = (char)filter_flags;
1130                         BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) {
1131                                 if (eve->head.hflag & filter_flags_ch) {
1132                                         mul_m4_v3((float (*)[4])mat_ptr, eve->co);
1133                                 }
1134                         }
1135                 }
1136         }
1137
1138         Py_RETURN_NONE;
1139 }
1140
1141
1142 /* Elem
1143  * ---- */
1144
1145 PyDoc_STRVAR(bpy_bm_elem_select_set_doc,
1146 ".. method:: select_set(select)\n"
1147 "\n"
1148 "   Set the selection.\n"
1149 "   This is different from the *select* attribute because it updates the selection state of associated geometry.\n"
1150 "\n"
1151 "   :arg select: Select or de-select.\n"
1152 "   :type select: boolean\n"
1153 "\n"
1154 "   .. note::\n"
1155 "\n"
1156 "      Currently this only flushes down, so selecting a face will select all its vertices but de-selecting a vertex "
1157 "      won't de-select all the faces that use it, before finishing with a mesh typically flushing is still needed.\n"
1158 );
1159 static PyObject *bpy_bm_elem_select_set(BPy_BMElem *self, PyObject *value)
1160 {
1161         int param;
1162
1163         BPY_BM_CHECK_OBJ(self);
1164
1165         param = PyLong_AsLong(value);
1166         if (param != FALSE && param != TRUE) {
1167                 PyErr_SetString(PyExc_TypeError,
1168                                 "expected a boolean type 0/1");
1169                 return NULL;
1170         }
1171
1172         BM_elem_select_set(self->bm, self->ele, param);
1173
1174         Py_RETURN_NONE;
1175 }
1176
1177
1178 PyDoc_STRVAR(bpy_bm_elem_hide_set_doc,
1179 ".. method:: hide_set(hide)\n"
1180 "\n"
1181 "   Set the hide state.\n"
1182 "   This is different from the *hide* attribute because it updates the selection and hide state of associated geometry.\n"
1183 "\n"
1184 "   :arg hide: Hidden or visible.\n"
1185 "   :type hide: boolean\n"
1186 );
1187 static PyObject *bpy_bm_elem_hide_set(BPy_BMElem *self, PyObject *value)
1188 {
1189         int param;
1190
1191         BPY_BM_CHECK_OBJ(self);
1192
1193         param = PyLong_AsLong(value);
1194         if (param != FALSE && param != TRUE) {
1195                 PyErr_SetString(PyExc_TypeError,
1196                                 "expected a boolean type 0/1");
1197                 return NULL;
1198         }
1199
1200         BM_elem_hide_set(self->bm, self->ele, param);
1201
1202         Py_RETURN_NONE;
1203 }
1204
1205
1206 PyDoc_STRVAR(bpy_bm_elem_copy_from_doc,
1207 ".. method:: copy_from(other)\n"
1208 "\n"
1209 "   Copy values from another element of matching type.\n"
1210 );
1211 static PyObject *bpy_bm_elem_copy_from(BPy_BMElem *self, BPy_BMElem *value)
1212 {
1213         BPY_BM_CHECK_OBJ(self);
1214
1215         if (Py_TYPE(self) != Py_TYPE(value)) {
1216                 PyErr_Format(PyExc_TypeError,
1217                              "expected element of type '%.200s' not '%.200s'",
1218                              Py_TYPE(self)->tp_name, Py_TYPE(value)->tp_name);
1219                 return NULL;
1220         }
1221
1222         if (value->ele != self->ele) {
1223                 BM_elem_attrs_copy(value->bm, self->bm, value->ele, self->ele);
1224         }
1225
1226         Py_RETURN_NONE;
1227 }
1228
1229
1230 /* Vert
1231  * ---- */
1232
1233
1234 PyDoc_STRVAR(bpy_bmvert_copy_from_vert_interp_doc,
1235 ".. method:: copy_from_vert_interp(vert_pair, fac)\n"
1236 "\n"
1237 "   Interpolate the customdata from a vert between 2 other verts.\n"
1238 "\n"
1239 "   :arg vert_pair: The vert to interpolate data from.\n"
1240 "   :type vert_pair: :class:`BMVert`\n"
1241 );
1242 static PyObject *bpy_bmvert_copy_from_vert_interp(BPy_BMVert *self, PyObject *args)
1243 {
1244         PyObject *vert_seq;
1245         float fac;
1246
1247         BPY_BM_CHECK_OBJ(self);
1248
1249         if (!PyArg_ParseTuple(args, "Of:BMVert.copy_from_vert_interp",
1250                               &vert_seq, &fac))
1251         {
1252                 return NULL;
1253         }
1254         else {
1255                 BMesh *bm = self->bm;
1256                 BMVert **vert_array = NULL;
1257                 Py_ssize_t vert_seq_len; /* always 2 */
1258
1259                 vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 2, 2,
1260                                                        &vert_seq_len, BM_VERT,
1261                                                        TRUE, TRUE, "BMVert.copy_from_vert_interp(...)");
1262
1263                 if (vert_array == NULL) {
1264                         return NULL;
1265                 }
1266
1267                 BM_data_interp_from_verts(bm, vert_array[0], vert_array[1], self->v, CLAMPIS(fac, 0.0f, 1.0f));
1268
1269                 PyMem_FREE(vert_array);
1270                 Py_RETURN_NONE;
1271         }
1272 }
1273
1274
1275 PyDoc_STRVAR(bpy_bmvert_copy_from_face_interp_doc,
1276 ".. method:: copy_from_face_interp(face)\n"
1277 "\n"
1278 "   Interpolate the customdata from a face onto this loop (the loops vert should overlap the face).\n"
1279 "\n"
1280 "   :arg face: The face to interpolate data from.\n"
1281 "   :type face: :class:`BMFace`\n"
1282 );
1283 static PyObject *bpy_bmvert_copy_from_face_interp(BPy_BMVert *self, PyObject *args)
1284 {
1285         BPy_BMFace *py_face = NULL;
1286
1287         BPY_BM_CHECK_OBJ(self);
1288
1289         if (!PyArg_ParseTuple(args, "O!:BMVert.copy_from_face_interp",
1290                               &BPy_BMFace_Type, &py_face))
1291         {
1292                 return NULL;
1293         }
1294         else {
1295                 BMesh *bm = self->bm;
1296
1297                 BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "copy_from_face_interp()");
1298
1299                 BM_vert_interp_from_face(bm, self->v, py_face->f);
1300
1301                 Py_RETURN_NONE;
1302         }
1303 }
1304
1305
1306 PyDoc_STRVAR(bpy_bmvert_calc_edge_angle_doc,
1307 ".. method:: calc_edge_angle()\n"
1308 "\n"
1309 "   Return the angle between this verts 2 connected edges.\n"
1310 "\n"
1311 "   :return: Angle between edges in radians.\n"
1312 "   :rtype: float\n"
1313 );
1314 static PyObject *bpy_bmvert_calc_edge_angle(BPy_BMVert *self)
1315 {
1316         BPY_BM_CHECK_OBJ(self);
1317         return PyFloat_FromDouble(BM_vert_calc_edge_angle(self->v));
1318 }
1319
1320 PyDoc_STRVAR(bpy_bmvert_calc_shell_factor_doc,
1321 ".. method:: calc_shell_factor()\n"
1322 "\n"
1323 "   Return a multiplier calculated based on the sharpness of the vertex.\n"
1324 "   Where a flat surface gives 1.0, and higher values sharper edges.\n"
1325 "   This is used to maintain shell thickness when offsetting verts along their normals.\n"
1326 "\n"
1327 "   :return: offset multiplier\n"
1328 "   :rtype: float\n"
1329 );
1330 static PyObject *bpy_bmvert_calc_shell_factor(BPy_BMVert *self)
1331 {
1332         BPY_BM_CHECK_OBJ(self);
1333         return PyFloat_FromDouble(BM_vert_calc_shell_factor(self->v));
1334 }
1335
1336 PyDoc_STRVAR(bpy_bmvert_normal_update_doc,
1337 ".. method:: normal_update()\n"
1338 "\n"
1339 "   Update vertex normal.\n"
1340 );
1341 static PyObject *bpy_bmvert_normal_update(BPy_BMVert *self)
1342 {
1343         BPY_BM_CHECK_OBJ(self);
1344
1345         BM_vert_normal_update(self->v);
1346
1347         Py_RETURN_NONE;
1348 }
1349
1350
1351 /* Edge
1352  * ---- */
1353
1354 PyDoc_STRVAR(bpy_bmedge_calc_length_doc,
1355 ".. method:: calc_length()\n"
1356 "\n"
1357 "   :return: The length between both verts.\n"
1358 "   :rtype: float\n"
1359 );
1360 static PyObject *bpy_bmedge_calc_length(BPy_BMEdge *self)
1361 {
1362         BPY_BM_CHECK_OBJ(self);
1363         return PyFloat_FromDouble(len_v3v3(self->e->v1->co, self->e->v2->co));
1364 }
1365
1366 PyDoc_STRVAR(bpy_bmedge_calc_face_angle_doc,
1367 ".. method:: calc_face_angle()\n"
1368 "\n"
1369 "   :return: The angle between 2 connected faces in radians.\n"
1370 "   :rtype: float\n"
1371 );
1372 static PyObject *bpy_bmedge_calc_face_angle(BPy_BMEdge *self)
1373 {
1374         BPY_BM_CHECK_OBJ(self);
1375         return PyFloat_FromDouble(BM_edge_calc_face_angle(self->e));
1376 }
1377
1378 PyDoc_STRVAR(bpy_bmedge_calc_tangent_doc,
1379 ".. method:: calc_tangent(loop)\n"
1380 "\n"
1381 "   Return the tangent at this edge relative to a face (pointing inward into the face).\n"
1382 "   This uses the face normal for calculation.\n"
1383 "\n"
1384 "   :arg loop: The loop used for tangent calculation.\n"
1385 "   :type loop: :class:`BMLoop`\n"
1386 "   :return: a normalized vector.\n"
1387 "   :rtype: :class:`mathutils.Vector`\n"
1388 );
1389 static PyObject *bpy_bmedge_calc_tangent(BPy_BMEdge *self, PyObject *args)
1390 {
1391         BPy_BMLoop *py_loop;
1392         BPY_BM_CHECK_OBJ(self);
1393
1394         if (!PyArg_ParseTuple(args, "O!:BMEdge.calc_face_tangent",
1395                               &BPy_BMLoop_Type, &py_loop))
1396         {
1397                 return NULL;
1398         }
1399         else {
1400                 float vec[3];
1401                 BPY_BM_CHECK_OBJ(py_loop);
1402                 /* no need to check if they are from the same mesh or even connected */
1403                 BM_edge_calc_face_tangent(self->e, py_loop->l, vec);
1404                 return Vector_CreatePyObject(vec, 3, Py_NEW, NULL);
1405         }
1406 }
1407
1408
1409 PyDoc_STRVAR(bpy_bmedge_other_vert_doc,
1410 ".. method:: other_vert(vert)\n"
1411 "\n"
1412 "   Return the other vertex on this edge or None if the vertex is not used by this edge.\n"
1413 "\n"
1414 "   :arg vert: a vert in this edge.\n"
1415 "   :type vert: :class:`BMVert`\n"
1416 "   :return: The edges other vert.\n"
1417 "   :rtype: :class:`BMVert` or None\n"
1418 );
1419 static PyObject *bpy_bmedge_other_vert(BPy_BMEdge *self, BPy_BMVert *value)
1420 {
1421         BMVert *other;
1422         BPY_BM_CHECK_OBJ(self);
1423
1424         if (!BPy_BMVert_Check(value)) {
1425                 PyErr_Format(PyExc_TypeError,
1426                              "BMEdge.other_vert(vert): BMVert expected, not '%.200s'",
1427                              Py_TYPE(value)->tp_name);
1428                 return NULL;
1429         }
1430
1431         BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "BMEdge.other_vert(vert)");
1432
1433         other = BM_edge_other_vert(self->e, value->v);
1434
1435         if (other) {
1436                 return BPy_BMVert_CreatePyObject(self->bm, other);
1437         }
1438         else {
1439                 /* could raise an exception here */
1440                 Py_RETURN_NONE;
1441         }
1442 }
1443
1444
1445 PyDoc_STRVAR(bpy_bmedge_normal_update_doc,
1446 ".. method:: normal_update()\n"
1447 "\n"
1448 "   Update edges vertex normals.\n"
1449 );
1450 static PyObject *bpy_bmedge_normal_update(BPy_BMEdge *self)
1451 {
1452         BPY_BM_CHECK_OBJ(self);
1453
1454         BM_edge_normals_update(self->e);
1455
1456         Py_RETURN_NONE;
1457 }
1458
1459
1460 /* Face
1461  * ---- */
1462
1463 PyDoc_STRVAR(bpy_bmface_copy_from_face_interp_doc,
1464 ".. method:: copy_from_face_interp(face)\n"
1465 "\n"
1466 "   Interpolate the customdata from another face onto this one (faces should overlap).\n"
1467 "\n"
1468 "   :arg face: The face to interpolate data from.\n"
1469 "   :type face: :class:`BMFace`\n"
1470 );
1471 static PyObject *bpy_bmface_copy_from_face_interp(BPy_BMFace *self, PyObject *args)
1472 {
1473         BPy_BMFace *py_face = NULL;
1474
1475         BPY_BM_CHECK_OBJ(self);
1476
1477         if (!PyArg_ParseTuple(args, "O!:BMFace.copy_from_face_interp",
1478                               &BPy_BMFace_Type, &py_face))
1479         {
1480                 return NULL;
1481         }
1482         else {
1483                 BMesh *bm = self->bm;
1484
1485                 BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "BMFace.copy_from_face_interp(face)");
1486
1487                 BM_face_interp_from_face(bm, self->f, py_face->f);
1488
1489                 Py_RETURN_NONE;
1490         }
1491 }
1492
1493
1494 PyDoc_STRVAR(bpy_bmface_copy_doc,
1495 ".. method:: copy(verts=True, edges=True)\n"
1496 "\n"
1497 "   Make a copy of this face.\n"
1498 "\n"
1499 "   :arg verts: When set, the faces verts will be duplicated too.\n"
1500 "   :type verts: boolean\n"
1501 "   :arg edges: When set, the faces edges will be duplicated too.\n"
1502 "   :type edges: boolean\n"
1503 "   :return: The newly created face.\n"
1504 "   :rtype: :class:`BMFace`\n"
1505 );
1506 static PyObject *bpy_bmface_copy(BPy_BMFace *self, PyObject *args, PyObject *kw)
1507 {
1508         static const char *kwlist[] = {"verts", "edges", NULL};
1509
1510         BMesh *bm = self->bm;
1511         int do_verts = TRUE;
1512         int do_edges = TRUE;
1513
1514         BMFace *f_cpy;
1515         BPY_BM_CHECK_OBJ(self);
1516
1517         if (!PyArg_ParseTupleAndKeywords(args, kw,
1518                                          "|ii:BMFace.copy",
1519                                          (char **)kwlist,
1520                                          &do_verts, &do_edges))
1521         {
1522                 return NULL;
1523         }
1524
1525         f_cpy = BM_face_copy(bm, self->f, do_verts, do_edges);
1526
1527         if (f_cpy) {
1528                 return BPy_BMFace_CreatePyObject(bm, f_cpy);
1529         }
1530         else {
1531                 PyErr_SetString(PyExc_ValueError,
1532                                 "BMFace.copy(): couldn't create the new face, internal error");
1533                 return NULL;
1534         }
1535 }
1536
1537
1538 PyDoc_STRVAR(bpy_bmface_calc_area_doc,
1539 ".. method:: calc_area()\n"
1540 "\n"
1541 "   Return the area of the face.\n"
1542 "\n"
1543 "   :return: Return the area of the face.\n"
1544 "   :rtype: float\n"
1545 );
1546 static PyObject *bpy_bmface_calc_area(BPy_BMFace *self)
1547 {
1548         BPY_BM_CHECK_OBJ(self);
1549         return PyFloat_FromDouble(BM_face_calc_area(self->f));
1550 }
1551
1552
1553 PyDoc_STRVAR(bpy_bmface_calc_perimeter_doc,
1554 ".. method:: calc_perimeter()\n"
1555 "\n"
1556 "   Return the perimeter of the face.\n"
1557 "\n"
1558 "   :return: Return the perimeter of the face.\n"
1559 "   :rtype: float\n"
1560 );
1561 static PyObject *bpy_bmface_calc_perimeter(BPy_BMFace *self)
1562 {
1563         BPY_BM_CHECK_OBJ(self);
1564         return PyFloat_FromDouble(BM_face_calc_perimeter(self->f));
1565 }
1566
1567
1568 PyDoc_STRVAR(bpy_bmface_calc_center_mean_doc,
1569 ".. method:: calc_center_median()\n"
1570 "\n"
1571 "   Return median center of the face.\n"
1572 "\n"
1573 "   :return: a 3D vector.\n"
1574 "   :rtype: :class:`mathutils.Vector`\n"
1575 );
1576 static PyObject *bpy_bmface_calc_center_mean(BPy_BMFace *self)
1577 {
1578         float cent[3];
1579
1580         BPY_BM_CHECK_OBJ(self);
1581         BM_face_calc_center_mean(self->f, cent);
1582         return Vector_CreatePyObject(cent, 3, Py_NEW, NULL);
1583 }
1584
1585
1586 PyDoc_STRVAR(bpy_bmface_calc_center_bounds_doc,
1587 ".. method:: calc_center_bounds()\n"
1588 "\n"
1589 "   Return bounds center of the face.\n"
1590 "\n"
1591 "   :return: a 3D vector.\n"
1592 "   :rtype: :class:`mathutils.Vector`\n"
1593 );
1594 static PyObject *bpy_bmface_calc_center_bounds(BPy_BMFace *self)
1595 {
1596         float cent[3];
1597
1598         BPY_BM_CHECK_OBJ(self);
1599         BM_face_calc_center_bounds(self->f, cent);
1600         return Vector_CreatePyObject(cent, 3, Py_NEW, NULL);
1601 }
1602
1603
1604 PyDoc_STRVAR(bpy_bmface_normal_update_doc,
1605 ".. method:: normal_update()\n"
1606 "\n"
1607 "   Update faces normal.\n"
1608 );
1609 static PyObject *bpy_bmface_normal_update(BPy_BMFace *self)
1610 {
1611         BPY_BM_CHECK_OBJ(self);
1612
1613         BM_face_normal_update(self->f);
1614
1615         Py_RETURN_NONE;
1616 }
1617
1618
1619 /* Loop
1620  * ---- */
1621
1622 PyDoc_STRVAR(bpy_bmloop_copy_from_face_interp_doc,
1623 ".. method:: copy_from_face_interp(face, vert=True, multires=True)\n"
1624 "\n"
1625 "   Interpolate the customdata from a face onto this loop (the loops vert should overlap the face).\n"
1626 "\n"
1627 "   :arg face: The face to interpolate data from.\n"
1628 "   :type face: :class:`BMFace`\n"
1629 "   :arg vert: When enabled, interpolate the loops vertex data (optional).\n"
1630 "   :type vert: boolean\n"
1631 "   :arg multires: When enabled, interpolate the loops multires data (optional).\n"
1632 "   :type multires: boolean\n"
1633 );
1634 static PyObject *bpy_bmloop_copy_from_face_interp(BPy_BMLoop *self, PyObject *args)
1635 {
1636         BPy_BMFace *py_face = NULL;
1637         int do_vertex   = TRUE;
1638         int do_multires = TRUE;
1639
1640         BPY_BM_CHECK_OBJ(self);
1641
1642         if (!PyArg_ParseTuple(args, "O!|ii:BMLoop.copy_from_face_interp",
1643                               &BPy_BMFace_Type, &py_face,
1644                               &do_vertex, &do_multires))
1645         {
1646                 return NULL;
1647         }
1648         else {
1649                 BMesh *bm = self->bm;
1650
1651                 BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "BMLoop.copy_from_face_interp(face)");
1652
1653                 BM_loop_interp_from_face(bm, self->l, py_face->f, do_vertex, do_multires);
1654
1655                 Py_RETURN_NONE;
1656         }
1657 }
1658
1659
1660 PyDoc_STRVAR(bpy_bmloop_calc_angle_doc,
1661 ".. method:: calc_angle()\n"
1662 "\n"
1663 "   Return the angle at this loops corner of the face.\n"
1664 "   This is calculated so sharper corners give lower angles.\n"
1665 "\n"
1666 "   :return: The angle in radians.\n"
1667 "   :rtype: float\n"
1668 );
1669 static PyObject *bpy_bmloop_calc_angle(BPy_BMLoop *self)
1670 {
1671         BPY_BM_CHECK_OBJ(self);
1672         return PyFloat_FromDouble(BM_loop_calc_face_angle(self->l));
1673 }
1674
1675 PyDoc_STRVAR(bpy_bmloop_calc_normal_doc,
1676 ".. method:: calc_normal()\n"
1677 "\n"
1678 "   Return normal at this loops corner of the face.\n"
1679 "   Falls back to the face normal for straight lines.\n"
1680 "\n"
1681 "   :return: a normalized vector.\n"
1682 "   :rtype: :class:`mathutils.Vector`\n"
1683 );
1684 static PyObject *bpy_bmloop_calc_normal(BPy_BMLoop *self)
1685 {
1686         float vec[3];
1687         BPY_BM_CHECK_OBJ(self);
1688         BM_loop_calc_face_normal(self->l, vec);
1689         return Vector_CreatePyObject(vec, 3, Py_NEW, NULL);
1690 }
1691
1692 PyDoc_STRVAR(bpy_bmloop_calc_tangent_doc,
1693 ".. method:: calc_tangent()\n"
1694 "\n"
1695 "   Return the tangent at this loops corner of the face (pointing inward into the face).\n"
1696 "   Falls back to the face normal for straight lines.\n"
1697 "\n"
1698 "   :return: a normalized vector.\n"
1699 "   :rtype: :class:`mathutils.Vector`\n"
1700 );
1701 static PyObject *bpy_bmloop_calc_tangent(BPy_BMLoop *self)
1702 {
1703         float vec[3];
1704         BPY_BM_CHECK_OBJ(self);
1705         BM_loop_calc_face_tangent(self->l, vec);
1706         return Vector_CreatePyObject(vec, 3, Py_NEW, NULL);
1707 }
1708
1709 /* Vert Seq
1710  * -------- */
1711 PyDoc_STRVAR(bpy_bmvertseq_new_doc,
1712 ".. method:: new(co=(0.0, 0.0, 0.0), example=None)\n"
1713 "\n"
1714 "   Create a new vertex.\n"
1715 "\n"
1716 "   :arg co: The initial location of the vertex (optional argument).\n"
1717 "   :type co: float triplet\n"
1718 "   :arg example: Existing vert to initialize settings.\n"
1719 "   :type example: :class:`BMVert`\n"
1720 "   :return: The newly created edge.\n"
1721 "   :rtype: :class:`BMVert`\n"
1722 );
1723 static PyObject *bpy_bmvertseq_new(BPy_BMElemSeq *self, PyObject *args)
1724 {
1725         PyObject *py_co = NULL;
1726         BPy_BMVert *py_vert_example = NULL; /* optional */
1727
1728         BPY_BM_CHECK_OBJ(self);
1729
1730         if (!PyArg_ParseTuple(args, "|OO!:verts.new",
1731                               &py_co,
1732                               &BPy_BMVert_Type, &py_vert_example))
1733         {
1734                 return NULL;
1735         }
1736         else {
1737                 BMesh *bm = self->bm;
1738                 BMVert *v;
1739                 float co[3] = {0.0f, 0.0f, 0.0f};
1740
1741                 if (py_vert_example) {
1742                         BPY_BM_CHECK_OBJ(py_vert_example);
1743                 }
1744
1745                 if (py_co && mathutils_array_parse(co, 3, 3, py_co, "verts.new(co)") == -1) {
1746                         return NULL;
1747                 }
1748
1749                 v = BM_vert_create(bm, co, NULL);
1750
1751                 if (v == NULL) {
1752                         PyErr_SetString(PyExc_ValueError,
1753                                         "faces.new(verts): couldn't create the new face, internal error");
1754                         return NULL;
1755                 }
1756
1757                 if (py_vert_example) {
1758                         BM_elem_attrs_copy(py_vert_example->bm, bm, py_vert_example->v, v);
1759                 }
1760
1761                 return BPy_BMVert_CreatePyObject(bm, v);
1762         }
1763 }
1764
1765
1766 /* Edge Seq
1767  * -------- */
1768 PyDoc_STRVAR(bpy_bmedgeseq_new_doc,
1769 ".. method:: new(verts, example=None)\n"
1770 "\n"
1771 "   Create a new edge from a given pair of verts.\n"
1772 "\n"
1773 "   :arg verts: Vertex pair.\n"
1774 "   :type verts: pair of :class:`BMVert`\n"
1775 "   :arg example: Existing edge to initialize settings (optional argument).\n"
1776 "   :type example: :class:`BMEdge`\n"
1777 "   :return: The newly created edge.\n"
1778 "   :rtype: :class:`BMEdge`\n"
1779 );
1780 static PyObject *bpy_bmedgeseq_new(BPy_BMElemSeq *self, PyObject *args)
1781 {
1782         PyObject *vert_seq;
1783         BPy_BMEdge *py_edge_example = NULL; /* optional */
1784
1785         BPY_BM_CHECK_OBJ(self);
1786
1787         if (!PyArg_ParseTuple(args, "O|O!:edges.new",
1788                               &vert_seq,
1789                               &BPy_BMEdge_Type, &py_edge_example))
1790         {
1791                 return NULL;
1792         }
1793         else {
1794                 BMesh *bm = self->bm;
1795                 BMEdge *e;
1796                 BMVert **vert_array = NULL;
1797                 Py_ssize_t vert_seq_len; /* always 2 */
1798                 PyObject *ret = NULL;
1799
1800                 if (py_edge_example) {
1801                         BPY_BM_CHECK_OBJ(py_edge_example);
1802                 }
1803
1804                 vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 2, 2,
1805                                                        &vert_seq_len, BM_VERT,
1806                                                        TRUE, TRUE, "edges.new(...)");
1807
1808                 if (vert_array == NULL) {
1809                         return NULL;
1810                 }
1811                 
1812                 if (BM_edge_exists(vert_array[0], vert_array[1])) {
1813                         PyErr_SetString(PyExc_ValueError,
1814                                         "edges.new(): this edge exists");
1815                         goto cleanup;
1816                 }
1817
1818                 e = BM_edge_create(bm, vert_array[0], vert_array[1], NULL, FALSE);
1819
1820                 if (e == NULL) {
1821                         PyErr_SetString(PyExc_ValueError,
1822                                         "faces.new(verts): couldn't create the new face, internal error");
1823                         goto cleanup;
1824                 }
1825
1826                 if (py_edge_example) {
1827                         BM_elem_attrs_copy(py_edge_example->bm, bm, py_edge_example->e, e);
1828                 }
1829
1830                 ret = BPy_BMEdge_CreatePyObject(bm, e);
1831
1832 cleanup:
1833                 if (vert_array) PyMem_FREE(vert_array);
1834                 return ret;
1835         }
1836 }
1837
1838
1839 /* Face Seq
1840  * -------- */
1841 PyDoc_STRVAR(bpy_bmfaceseq_new_doc,
1842 ".. method:: new(verts, example=None)\n"
1843 "\n"
1844 "   Create a new face from a given set of verts.\n"
1845 "\n"
1846 "   :arg verts: Sequence of 3 or more verts.\n"
1847 "   :type verts: :class:`BMVert`\n"
1848 "   :arg example: Existing face to initialize settings (optional argument).\n"
1849 "   :type example: :class:`BMFace`\n"
1850 "   :return: The newly created face.\n"
1851 "   :rtype: :class:`BMFace`\n"
1852 );
1853 static PyObject *bpy_bmfaceseq_new(BPy_BMElemSeq *self, PyObject *args)
1854 {
1855         PyObject *vert_seq;
1856         BPy_BMFace *py_face_example = NULL; /* optional */
1857
1858         BPY_BM_CHECK_OBJ(self);
1859
1860         if (!PyArg_ParseTuple(args, "O|O!:faces.new",
1861                               &vert_seq,
1862                               &BPy_BMFace_Type, &py_face_example))
1863         {
1864                 return NULL;
1865         }
1866         else {
1867                 BMesh *bm = self->bm;
1868                 Py_ssize_t vert_seq_len;
1869                 Py_ssize_t i, i_next;
1870
1871                 BMVert **vert_array = NULL;
1872                 BMEdge **edge_array = NULL;
1873
1874                 PyObject *ret = NULL;
1875
1876                 BMFace *f_new;
1877
1878                 if (py_face_example) {
1879                         BPY_BM_CHECK_OBJ(py_face_example);
1880                 }
1881
1882                 vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 3, PY_SSIZE_T_MAX,
1883                                                        &vert_seq_len, BM_VERT,
1884                                                        TRUE, TRUE, "faces.new(...)");
1885
1886                 if (vert_array == NULL) {
1887                         return NULL;
1888                 }
1889
1890                 /* check if the face exists */
1891                 if (BM_face_exists(vert_array, vert_seq_len, NULL)) {
1892                         PyErr_SetString(PyExc_ValueError,
1893                                         "faces.new(verts): face already exists");
1894                         goto cleanup;
1895                 }
1896
1897                 /* Go ahead and make the face!
1898                  * --------------------------- */
1899
1900                 edge_array = (BMEdge **)PyMem_MALLOC(vert_seq_len * sizeof(BMEdge **));
1901
1902                 /* ensure edges */
1903                 for (i = vert_seq_len - 1, i_next = 0; i_next < vert_seq_len; (i = i_next++)) {
1904                         edge_array[i] = BM_edge_create(bm, vert_array[i], vert_array[i_next], NULL, TRUE);
1905                 }
1906
1907                 f_new = BM_face_create(bm, vert_array, edge_array, vert_seq_len, FALSE);
1908
1909                 if (UNLIKELY(f_new == NULL)) {
1910                         PyErr_SetString(PyExc_ValueError,
1911                                         "faces.new(verts): couldn't create the new face, internal error");
1912                         goto cleanup;
1913                 }
1914
1915                 if (py_face_example) {
1916                         BM_elem_attrs_copy(py_face_example->bm, bm, py_face_example->f, f_new);
1917                 }
1918
1919                 ret = BPy_BMFace_CreatePyObject(bm, f_new);
1920
1921                 /* pass through */
1922 cleanup:
1923                 if (vert_array) PyMem_FREE(vert_array);
1924                 if (edge_array) PyMem_FREE(edge_array);
1925                 return ret;
1926         }
1927 }
1928
1929 /* Elem Seq
1930  * -------- */
1931
1932 PyDoc_STRVAR(bpy_bmvertseq_remove_doc,
1933 ".. method:: remove(vert)\n"
1934 "\n"
1935 "   Remove a vert.\n"
1936 );
1937 static PyObject *bpy_bmvertseq_remove(BPy_BMElemSeq *self, BPy_BMVert *value)
1938 {
1939         BPY_BM_CHECK_OBJ(self);
1940
1941         if (!BPy_BMVert_Check(value)) {
1942                 return NULL;
1943         }
1944         else {
1945                 BMesh *bm = self->bm;
1946
1947                 BPY_BM_CHECK_SOURCE_OBJ(value, bm, "verts.remove(vert)");
1948
1949                 BM_vert_kill(bm, value->v);
1950                 bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
1951
1952                 Py_RETURN_NONE;
1953         }
1954 }
1955
1956 PyDoc_STRVAR(bpy_bmedgeseq_remove_doc,
1957 ".. method:: remove(edge)\n"
1958 "\n"
1959 "   Remove a edge.\n"
1960 );
1961 static PyObject *bpy_bmedgeseq_remove(BPy_BMElemSeq *self, BPy_BMEdge *value)
1962 {
1963         BPY_BM_CHECK_OBJ(self);
1964
1965         if (!BPy_BMEdge_Check(value)) {
1966                 return NULL;
1967         }
1968         else {
1969                 BMesh *bm = self->bm;
1970
1971                 BPY_BM_CHECK_SOURCE_OBJ(value, bm, "edges.remove(edges)");
1972
1973                 BM_edge_kill(bm, value->e);
1974                 bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
1975
1976                 Py_RETURN_NONE;
1977         }
1978 }
1979
1980 PyDoc_STRVAR(bpy_bmfaceseq_remove_doc,
1981 ".. method:: remove(face)\n"
1982 "\n"
1983 "   Remove a face.\n"
1984 );
1985 static PyObject *bpy_bmfaceseq_remove(BPy_BMElemSeq *self, BPy_BMFace *value)
1986 {
1987         BPY_BM_CHECK_OBJ(self);
1988
1989         if (!BPy_BMFace_Check(value)) {
1990                 return NULL;
1991         }
1992         else {
1993                 BMesh *bm = self->bm;
1994
1995                 BPY_BM_CHECK_SOURCE_OBJ(value, bm, "faces.remove(face)");
1996
1997                 BM_face_kill(bm, value->f);
1998                 bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
1999
2000                 Py_RETURN_NONE;
2001         }
2002 }
2003
2004 PyDoc_STRVAR(bpy_bmedgeseq_get__method_doc,
2005 ".. method:: get(verts, fallback=None)\n"
2006 "\n"
2007 "   Return a edge which uses the **verts** passed.\n"
2008 "\n"
2009 "   :arg verts: Sequence of verts.\n"
2010 "   :type verts: :class:`BMVert`\n"
2011 "   :arg fallback: Return this value if nothing is found.\n"
2012 "   :return: The edge found or None\n"
2013 "   :rtype: :class:`BMEdge`\n"
2014 );
2015 static PyObject *bpy_bmedgeseq_get__method(BPy_BMElemSeq *self, PyObject *args)
2016 {
2017         PyObject *vert_seq;
2018         PyObject *fallback = Py_None; /* optional */
2019
2020         BPY_BM_CHECK_OBJ(self);
2021
2022         if (!PyArg_ParseTuple(args, "O|O:edges.get",
2023                               &vert_seq,
2024                               &fallback))
2025         {
2026                 return NULL;
2027         }
2028         else {
2029                 BMesh *bm = self->bm;
2030                 BMEdge *e;
2031                 BMVert **vert_array = NULL;
2032                 Py_ssize_t vert_seq_len; /* always 2 */
2033                 PyObject *ret = NULL;
2034
2035                 vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 2, 2,
2036                                                        &vert_seq_len, BM_VERT,
2037                                                        TRUE, TRUE, "edges.get(...)");
2038
2039                 if (vert_array == NULL) {
2040                         return NULL;
2041                 }
2042
2043                 if ((e = BM_edge_exists(vert_array[0], vert_array[1]))) {
2044                         ret = BPy_BMEdge_CreatePyObject(bm, e);
2045                 }
2046                 else {
2047                         ret = fallback;
2048                         Py_INCREF(ret);
2049                 }
2050
2051                 PyMem_FREE(vert_array);
2052                 return ret;
2053         }
2054 }
2055
2056 PyDoc_STRVAR(bpy_bmfaceseq_get__method_doc,
2057 ".. method:: get(verts, fallback=None)\n"
2058 "\n"
2059 "   Return a face which uses the **verts** passed.\n"
2060 "\n"
2061 "   :arg verts: Sequence of verts.\n"
2062 "   :type verts: :class:`BMVert`\n"
2063 "   :arg fallback: Return this value if nothing is found.\n"
2064 "   :return: The face found or None\n"
2065 "   :rtype: :class:`BMFace`\n"
2066 );
2067 static PyObject *bpy_bmfaceseq_get__method(BPy_BMElemSeq *self, PyObject *args)
2068 {
2069         PyObject *vert_seq;
2070         PyObject *fallback = Py_None; /* optional */
2071
2072         BPY_BM_CHECK_OBJ(self);
2073
2074         if (!PyArg_ParseTuple(args, "O|O:faces.get",
2075                               &vert_seq,
2076                               &fallback))
2077         {
2078                 return NULL;
2079         }
2080         else {
2081                 BMesh *bm = self->bm;
2082                 BMFace *f = NULL;
2083                 BMVert **vert_array = NULL;
2084                 Py_ssize_t vert_seq_len;
2085                 PyObject *ret = NULL;
2086
2087                 vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 1, PY_SSIZE_T_MAX,
2088                                                        &vert_seq_len, BM_VERT,
2089                                                        TRUE, TRUE, "faces.get(...)");
2090
2091                 if (vert_array == NULL) {
2092                         return NULL;
2093                 }
2094
2095                 if (BM_face_exists(vert_array, vert_seq_len, &f)) {
2096                         ret = BPy_BMFace_CreatePyObject(bm, f);
2097                 }
2098                 else {
2099                         ret = fallback;
2100                         Py_INCREF(ret);
2101                 }
2102
2103                 PyMem_FREE(vert_array);
2104                 return ret;
2105         }
2106 }
2107
2108 PyDoc_STRVAR(bpy_bmelemseq_index_update_doc,
2109 ".. method:: index_update()\n"
2110 "\n"
2111 "   Initialize the index values of this sequence.\n"
2112 "\n"
2113 "   This is the equivalent of looping over all elements and assigning the index values.\n"
2114 "\n"
2115 "   .. code-block:: python\n"
2116 "\n"
2117 "      for index, ele in enumerate(sequence):\n"
2118 "          ele.index = index\n"
2119 "\n"
2120 "   .. note::\n"
2121 "\n"
2122 "      Running this on sequences besides :class:`BMesh.verts`, :class:`BMesh.edges`, :class:`BMesh.faces`\n"
2123 "      works but wont result in each element having a valid index, insted its order in the sequence will be set.\n"
2124 );
2125 static PyObject *bpy_bmelemseq_index_update(BPy_BMElemSeq *self)
2126 {
2127         BMesh *bm = self->bm;
2128
2129         BPY_BM_CHECK_OBJ(self);
2130
2131         switch ((BMIterType)self->itype) {
2132                 case BM_VERTS_OF_MESH:
2133                         BM_mesh_elem_index_ensure(self->bm, BM_VERT);
2134                         break;
2135                 case BM_EDGES_OF_MESH:
2136                         BM_mesh_elem_index_ensure(self->bm, BM_EDGE);
2137                         break;
2138                 case BM_FACES_OF_MESH:
2139                         BM_mesh_elem_index_ensure(self->bm, BM_FACE);
2140                         break;
2141                 default:
2142                 {
2143                         BMIter iter;
2144                         BMElem *ele;
2145                         int index = 0;
2146                         const char htype = bm_iter_itype_htype_map[self->itype];
2147
2148                         BM_ITER_BPY_BM_SEQ (ele, &iter, self) {
2149                                 BM_elem_index_set(ele, index); /* set_dirty! */
2150                                 index++;
2151                         }
2152
2153                         if (htype & (BM_VERT | BM_EDGE | BM_FACE)) {
2154                                 /* since this isn't the normal vert/edge/face loops,
2155                                  * we're setting dirty values here. so tag as dirty. */
2156                                 bm->elem_index_dirty |= htype;
2157                         }
2158
2159                         break;
2160                 }
2161         }
2162
2163         Py_RETURN_NONE;
2164 }
2165
2166 PyDoc_STRVAR(bpy_bmelemseq_sort_doc,
2167 ".. method:: sort(key=None, reverse=False)\n"
2168 "\n"
2169 "   Sort the elements of this sequence, using an optional custom sort key.\n"
2170 "   Indices of elements are not changed, BMElemeSeq.index_update() can be used for that.\n"
2171 "\n"
2172 "   :arg key: The key that sets the ordering of the elements.\n"
2173 "   :type key: :function: returning a number\n"
2174 "   :arg reverse: Reverse the order of the elements\n"
2175 "   :type reverse: :boolean:\n"
2176 "\n"
2177 "   .. note::\n"
2178 "\n"
2179 "      When the 'key' argument is not provided, the elements are reordered following their current index value.\n"
2180 "      In particular this can be used by setting indices manually before calling this method.\n"
2181 "\n"
2182 );
2183
2184 /* Use a static variable here because there is the need to sort some array
2185  * doing comparisons on elements of another array, qsort_r would have been
2186  * wonderful to use here, but unfortunately it is not standard and it's not
2187  * portable across different platforms.
2188  *
2189  * If a portable alternative to qsort_r becomes available, remove this static
2190  * var hack!
2191  *
2192  * Note: the functions below assumes the keys array has been allocated and it
2193  * has enough elements to complete the task.
2194  */
2195 static double *keys = NULL;
2196
2197 static int bpy_bmelemseq_sort_cmp_by_keys_ascending(const void *index1_v, const void *index2_v)
2198 {
2199         const int *index1 = (int *)index1_v;
2200         const int *index2 = (int *)index2_v;
2201
2202         if      (keys[*index1] < keys[*index2]) return -1;
2203         else if (keys[*index1] > keys[*index2]) return 1;
2204         else                                    return 0;
2205 }
2206
2207 static int bpy_bmelemseq_sort_cmp_by_keys_descending(const void *index1_v, const void *index2_v)
2208 {
2209         return -bpy_bmelemseq_sort_cmp_by_keys_ascending(index1_v, index2_v);
2210 }
2211
2212 static PyObject *bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, PyObject *kw)
2213 {
2214         static const char *kwlist[] = {"key", "reverse", NULL};
2215         PyObject *keyfunc = NULL; /* optional */
2216         int reverse = FALSE; /* optional */
2217
2218         const char htype = bm_iter_itype_htype_map[self->itype];
2219         int n_elem;
2220
2221         BMIter iter;
2222         BMElem *ele;
2223
2224         int *elem_idx;
2225         int *elem_map_idx;
2226         int (*elem_idx_compare_by_keys)(const void *, const void *);
2227
2228         int *vert_idx = NULL;
2229         int *edge_idx = NULL;
2230         int *face_idx = NULL;
2231         int i;
2232
2233         BMesh *bm = self->bm;
2234
2235         BPY_BM_CHECK_OBJ(self);
2236
2237         if (args != NULL) {
2238                 if (!PyArg_ParseTupleAndKeywords(args, kw,
2239                                                  "|Oi:BMElemSeq.sort",
2240                                                  (char **)kwlist,
2241                                                  &keyfunc, &reverse))
2242                 {
2243                         return NULL;
2244                 }
2245         }
2246
2247         if (keyfunc != NULL && !PyCallable_Check(keyfunc)) {
2248                 PyErr_SetString(PyExc_TypeError,
2249                                 "the 'key' argument is not a callable object");
2250                 return NULL;
2251         }
2252
2253         n_elem = BM_mesh_elem_count(bm, htype);
2254         if (n_elem <= 1) {
2255                 /* 0 or 1 elements: sorted already */
2256                 Py_RETURN_NONE;
2257         }
2258
2259         keys = PyMem_MALLOC(sizeof(*keys) * n_elem);
2260         if (keys == NULL) {
2261                 PyErr_NoMemory();
2262                 return NULL;
2263         }
2264
2265         i = 0;
2266         BM_ITER_BPY_BM_SEQ (ele, &iter, self) {
2267                 if (keyfunc != NULL) {
2268                         PyObject *py_elem;
2269                         PyObject *index;
2270
2271                         py_elem = BPy_BMElem_CreatePyObject(self->bm, (BMHeader *)ele);
2272                         index = PyObject_CallFunctionObjArgs(keyfunc, py_elem, NULL);
2273                         Py_DECREF(py_elem);
2274                         if (index == NULL) {
2275                                 /* No need to set the exception here,
2276                                  * PyObject_CallFunctionObjArgs() does that */
2277                                 PyMem_FREE(keys);
2278                                 return NULL;
2279                         }
2280
2281                         if ((keys[i] = PyFloat_AsDouble(index)) == -1 && PyErr_Occurred()) {
2282                                 PyErr_SetString(PyExc_ValueError,
2283                                                 "the value returned by the 'key' function is not a number");
2284                                 Py_DECREF(index);
2285                                 PyMem_FREE(keys);
2286                                 return NULL;
2287                         }
2288
2289                         Py_DECREF(index);
2290                 }
2291                 else {
2292                         /* If the 'key' function is not provided we sort
2293                          * according to the current index values */
2294                         keys[i] = ele->head.index;
2295                 }
2296
2297                 i++;
2298         }
2299
2300         elem_idx = PyMem_MALLOC(sizeof(*elem_idx) * n_elem);
2301         if (elem_idx == NULL) {
2302                 PyErr_NoMemory();
2303                 PyMem_FREE(keys);
2304                 return NULL;
2305         }
2306
2307         /* Initialize the element index array */
2308         range_vn_i(elem_idx, n_elem, 0);
2309
2310         /* Sort the index array according to the order of the 'keys' array */
2311         if (reverse)
2312                 elem_idx_compare_by_keys = bpy_bmelemseq_sort_cmp_by_keys_descending;
2313         else
2314                 elem_idx_compare_by_keys = bpy_bmelemseq_sort_cmp_by_keys_ascending;
2315
2316         qsort(elem_idx, n_elem, sizeof(*elem_idx), elem_idx_compare_by_keys);
2317
2318         elem_map_idx = PyMem_MALLOC(sizeof(*elem_map_idx) * n_elem);
2319         if (elem_map_idx == NULL) {
2320                 PyErr_NoMemory();
2321                 PyMem_FREE(elem_idx);
2322                 PyMem_FREE(keys);
2323                 return NULL;
2324         }
2325
2326         /* Initialize the map array
2327          *
2328          * We need to know the index such that if used as the new_index in
2329          * BM_mesh_remap() will give the order of the sorted keys like in
2330          * elem_idx */
2331         for (i = 0; i < n_elem; i++) {
2332                 elem_map_idx[elem_idx[i]] = i;
2333         }
2334
2335         switch ((BMIterType)self->itype) {
2336                 case BM_VERTS_OF_MESH:
2337                         vert_idx = elem_map_idx;
2338                         break;
2339                 case BM_EDGES_OF_MESH:
2340                         edge_idx = elem_map_idx;
2341                         break;
2342                 case BM_FACES_OF_MESH:
2343                         face_idx = elem_map_idx;
2344                         break;
2345                 default:
2346                         PyErr_Format(PyExc_TypeError, "element type %d not supported", self->itype);
2347                         PyMem_FREE(elem_map_idx);
2348                         PyMem_FREE(elem_idx);
2349                         PyMem_FREE(keys);
2350                         return NULL;
2351         }
2352
2353         BM_mesh_remap(bm, vert_idx, edge_idx, face_idx);
2354
2355         PyMem_FREE(elem_map_idx);
2356         PyMem_FREE(elem_idx);
2357         PyMem_FREE(keys);
2358
2359         Py_RETURN_NONE;
2360 }
2361
2362 static struct PyMethodDef bpy_bmesh_methods[] = {
2363         /* utility */
2364         {"copy",  (PyCFunction)bpy_bmesh_copy,  METH_NOARGS, bpy_bmesh_copy_doc},
2365         {"clear", (PyCFunction)bpy_bmesh_clear, METH_NOARGS, bpy_bmesh_clear_doc},
2366         {"free",  (PyCFunction)bpy_bmesh_free,  METH_NOARGS, bpy_bmesh_free_doc},
2367
2368         /* conversion */
2369         {"from_object", (PyCFunction)bpy_bmesh_from_object, METH_VARARGS | METH_KEYWORDS, bpy_bmesh_from_object_doc},
2370         {"from_mesh",   (PyCFunction)bpy_bmesh_from_mesh,   METH_VARARGS | METH_KEYWORDS, bpy_bmesh_from_mesh_doc},
2371         {"to_mesh",     (PyCFunction)bpy_bmesh_to_mesh,     METH_VARARGS,                 bpy_bmesh_to_mesh_doc},
2372
2373         /* meshdata */
2374         {"select_flush_mode", (PyCFunction)bpy_bmesh_select_flush_mode, METH_NOARGS, bpy_bmesh_select_flush_mode_doc},
2375         {"select_flush", (PyCFunction)bpy_bmesh_select_flush, METH_O, bpy_bmesh_select_flush_doc},
2376         {"normal_update", (PyCFunction)bpy_bmesh_normal_update, METH_VARARGS, bpy_bmesh_normal_update_doc},
2377         {"transform", (PyCFunction)bpy_bmesh_transform, METH_VARARGS | METH_KEYWORDS, bpy_bmesh_transform_doc},
2378         {NULL, NULL, 0, NULL}
2379 };
2380
2381 static struct PyMethodDef bpy_bmvert_methods[] = {
2382         {"select_set", (PyCFunction)bpy_bm_elem_select_set, METH_O, bpy_bm_elem_select_set_doc},
2383         {"hide_set", (PyCFunction)bpy_bm_elem_hide_set, METH_O, bpy_bm_elem_hide_set_doc},
2384         {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc},
2385         {"copy_from_face_interp", (PyCFunction)bpy_bmvert_copy_from_face_interp, METH_VARARGS, bpy_bmvert_copy_from_face_interp_doc},
2386         {"copy_from_vert_interp", (PyCFunction)bpy_bmvert_copy_from_vert_interp, METH_VARARGS, bpy_bmvert_copy_from_vert_interp_doc},
2387
2388         {"calc_vert_angle",   (PyCFunction)bpy_bmvert_calc_edge_angle,   METH_NOARGS, bpy_bmvert_calc_edge_angle_doc},
2389         {"calc_shell_factor", (PyCFunction)bpy_bmvert_calc_shell_factor, METH_NOARGS, bpy_bmvert_calc_shell_factor_doc},
2390
2391         {"normal_update",  (PyCFunction)bpy_bmvert_normal_update,  METH_NOARGS,  bpy_bmvert_normal_update_doc},
2392
2393         {NULL, NULL, 0, NULL}
2394 };
2395
2396 static struct PyMethodDef bpy_bmedge_methods[] = {
2397         {"select_set", (PyCFunction)bpy_bm_elem_select_set, METH_O, bpy_bm_elem_select_set_doc},
2398         {"hide_set", (PyCFunction)bpy_bm_elem_hide_set, METH_O, bpy_bm_elem_hide_set_doc},
2399         {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc},
2400
2401         {"other_vert", (PyCFunction)bpy_bmedge_other_vert, METH_O, bpy_bmedge_other_vert_doc},
2402
2403         {"calc_length",     (PyCFunction)bpy_bmedge_calc_length,     METH_NOARGS,  bpy_bmedge_calc_length_doc},
2404         {"calc_face_angle", (PyCFunction)bpy_bmedge_calc_face_angle, METH_NOARGS,  bpy_bmedge_calc_face_angle_doc},
2405         {"calc_tangent",    (PyCFunction)bpy_bmedge_calc_tangent,    METH_VARARGS, bpy_bmedge_calc_tangent_doc},
2406
2407         {"normal_update",  (PyCFunction)bpy_bmedge_normal_update,  METH_NOARGS,  bpy_bmedge_normal_update_doc},
2408
2409         {NULL, NULL, 0, NULL}
2410 };
2411
2412 static struct PyMethodDef bpy_bmface_methods[] = {
2413         {"select_set", (PyCFunction)bpy_bm_elem_select_set, METH_O, bpy_bm_elem_select_set_doc},
2414         {"hide_set", (PyCFunction)bpy_bm_elem_hide_set, METH_O, bpy_bm_elem_hide_set_doc},
2415
2416         {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc},
2417         {"copy_from_face_interp", (PyCFunction)bpy_bmface_copy_from_face_interp, METH_O, bpy_bmface_copy_from_face_interp_doc},
2418
2419         {"copy", (PyCFunction)bpy_bmface_copy, METH_VARARGS | METH_KEYWORDS, bpy_bmface_copy_doc},
2420
2421         {"calc_area",          (PyCFunction)bpy_bmface_calc_area,          METH_NOARGS, bpy_bmface_calc_area_doc},
2422         {"calc_perimeter",     (PyCFunction)bpy_bmface_calc_perimeter,     METH_NOARGS, bpy_bmface_calc_perimeter_doc},
2423         {"calc_center_median", (PyCFunction)bpy_bmface_calc_center_mean,   METH_NOARGS, bpy_bmface_calc_center_mean_doc},
2424         {"calc_center_bounds", (PyCFunction)bpy_bmface_calc_center_bounds, METH_NOARGS, bpy_bmface_calc_center_bounds_doc},
2425
2426         {"normal_update",  (PyCFunction)bpy_bmface_normal_update,  METH_NOARGS,  bpy_bmface_normal_update_doc},
2427
2428                 {NULL, NULL, 0, NULL}
2429 };
2430
2431 static struct PyMethodDef bpy_bmloop_methods[] = {
2432         {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc},
2433         {"copy_from_face_interp", (PyCFunction)bpy_bmloop_copy_from_face_interp, METH_O, bpy_bmloop_copy_from_face_interp_doc},
2434
2435         {"calc_angle",   (PyCFunction)bpy_bmloop_calc_angle,   METH_NOARGS, bpy_bmloop_calc_angle_doc},
2436         {"calc_normal",  (PyCFunction)bpy_bmloop_calc_normal,  METH_NOARGS, bpy_bmloop_calc_normal_doc},
2437         {"calc_tangent", (PyCFunction)bpy_bmloop_calc_tangent, METH_NOARGS, bpy_bmloop_calc_tangent_doc},
2438         {NULL, NULL, 0, NULL}
2439 };
2440
2441 static struct PyMethodDef bpy_bmelemseq_methods[] = {
2442         /* odd function, initializes index values */
2443         {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc},
2444         {NULL, NULL, 0, NULL}
2445 };
2446
2447 static struct PyMethodDef bpy_bmvertseq_methods[] = {
2448         {"new",     (PyCFunction)bpy_bmvertseq_new,         METH_VARARGS, bpy_bmvertseq_new_doc},
2449         {"remove",  (PyCFunction)bpy_bmvertseq_remove,      METH_O,       bpy_bmvertseq_remove_doc},
2450
2451         /* odd function, initializes index values */
2452         {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc},
2453         {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc},
2454         {NULL, NULL, 0, NULL}
2455 };
2456
2457 static struct PyMethodDef bpy_bmedgeseq_methods[] = {
2458         {"new",     (PyCFunction)bpy_bmedgeseq_new,         METH_VARARGS, bpy_bmedgeseq_new_doc},
2459         {"remove",  (PyCFunction)bpy_bmedgeseq_remove,      METH_O,       bpy_bmedgeseq_remove_doc},
2460         /* 'bpy_bmelemseq_get' for different purpose */
2461         {"get",     (PyCFunction)bpy_bmedgeseq_get__method, METH_VARARGS, bpy_bmedgeseq_get__method_doc},
2462
2463         /* odd function, initializes index values */
2464         {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc},
2465         {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc},
2466         {NULL, NULL, 0, NULL}
2467 };
2468
2469 static struct PyMethodDef bpy_bmfaceseq_methods[] = {
2470         {"new",     (PyCFunction)bpy_bmfaceseq_new,         METH_VARARGS, bpy_bmfaceseq_new_doc},
2471         {"remove",  (PyCFunction)bpy_bmfaceseq_remove,      METH_O,       bpy_bmfaceseq_remove_doc},
2472         /* 'bpy_bmelemseq_get' for different purpose */
2473         {"get",     (PyCFunction)bpy_bmfaceseq_get__method, METH_VARARGS, bpy_bmfaceseq_get__method_doc},
2474
2475         /* odd function, initializes index values */
2476         {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc},
2477         {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc},
2478         {NULL, NULL, 0, NULL}
2479 };
2480
2481 static struct PyMethodDef bpy_bmloopseq_methods[] = {
2482         /* odd function, initializes index values */
2483         /* no: index_update() function since we cant iterate over loops */
2484         /* no: sort() function since we cant iterate over loops */
2485         {NULL, NULL, 0, NULL}
2486 };
2487
2488 /* Sequences
2489  * ========= */
2490
2491 /* BMElemSeq / Iter
2492  * ---------------- */
2493
2494 static PyTypeObject *bpy_bm_itype_as_pytype(const char itype)
2495 {
2496         /* should cover all types */
2497         switch ((BMIterType)itype) {
2498                 case BM_VERTS_OF_MESH:
2499                 case BM_VERTS_OF_FACE:
2500                 case BM_VERTS_OF_EDGE:
2501                         return &BPy_BMVert_Type;
2502
2503                 case BM_EDGES_OF_MESH:
2504                 case BM_EDGES_OF_FACE:
2505                 case BM_EDGES_OF_VERT:
2506                         return &BPy_BMEdge_Type;
2507
2508                 case BM_FACES_OF_MESH:
2509                 case BM_FACES_OF_EDGE:
2510                 case BM_FACES_OF_VERT:
2511                         return &BPy_BMFace_Type;
2512
2513                 case BM_ALL_LOOPS_OF_FACE:
2514                 case BM_LOOPS_OF_FACE:
2515                 case BM_LOOPS_OF_EDGE:
2516                 case BM_LOOPS_OF_VERT:
2517                 case BM_LOOPS_OF_LOOP:
2518                         return &BPy_BMLoop_Type;
2519         }
2520
2521         return NULL;
2522 }
2523
2524 static Py_ssize_t bpy_bmelemseq_length(BPy_BMElemSeq *self)
2525 {
2526         BPY_BM_CHECK_INT(self);
2527
2528         /* first check if the size is known */
2529         switch ((BMIterType)self->itype) {
2530                 /* main-types */
2531                 case BM_VERTS_OF_MESH:
2532                         return self->bm->totvert;
2533                 case BM_EDGES_OF_MESH:
2534                         return self->bm->totedge;
2535                 case BM_FACES_OF_MESH:
2536                         return self->bm->totface;
2537
2538                         /* sub-types */
2539                 case BM_VERTS_OF_FACE:
2540                 case BM_EDGES_OF_FACE:
2541                 case BM_LOOPS_OF_FACE:
2542                         BPY_BM_CHECK_INT(self->py_ele);
2543                         return ((BMFace *)self->py_ele->ele)->len;
2544
2545                 case BM_VERTS_OF_EDGE:
2546                         return 2;
2547
2548                 default:
2549                         /* quiet compiler */
2550                         break;
2551         }
2552
2553
2554         /* loop over all items, avoid this if we can */
2555         {
2556                 BMIter iter;
2557                 BMHeader *ele;
2558                 Py_ssize_t tot = 0;
2559
2560                 BM_ITER_BPY_BM_SEQ (ele, &iter, self) {
2561                         tot++;
2562                 }
2563                 return tot;
2564         }
2565 }
2566
2567 static PyObject *bpy_bmelemseq_subscript_int(BPy_BMElemSeq *self, int keynum)
2568 {
2569         BPY_BM_CHECK_OBJ(self);
2570
2571         if (keynum < 0) keynum += bpy_bmelemseq_length(self); /* only get length on negative value, may loop entire seq */
2572         if (keynum >= 0) {
2573                 BMHeader *ele = BM_iter_at_index(self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL, keynum);
2574                 if (ele) {
2575                         return BPy_BMElem_CreatePyObject(self->bm, ele);
2576                 }
2577         }
2578
2579         PyErr_Format(PyExc_IndexError,
2580                      "BMElemSeq[index]: index %d out of range", keynum);
2581         return NULL;
2582 }
2583
2584 static PyObject *bpy_bmelemseq_subscript_slice(BPy_BMElemSeq *self, Py_ssize_t start, Py_ssize_t stop)
2585 {
2586         BMIter iter;
2587         int count = 0;
2588         int ok;
2589
2590         PyObject *list;
2591         PyObject *item;
2592         BMHeader *ele;
2593
2594         BPY_BM_CHECK_OBJ(self);
2595
2596         list = PyList_New(0);
2597
2598         ok = BM_iter_init(&iter, self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL);
2599
2600         BLI_assert(ok == TRUE);
2601
2602         if (UNLIKELY(ok == FALSE)) {
2603                 return list;
2604         }
2605
2606         /* first loop up-until the start */
2607         for (ok = TRUE; ok; ok = (BM_iter_step(&iter) != NULL)) {
2608                 if (count == start) {
2609                         break;
2610                 }
2611                 count++;
2612         }
2613
2614         /* add items until stop */
2615         while ((ele = BM_iter_step(&iter))) {
2616                 item = BPy_BMElem_CreatePyObject(self->bm, ele);
2617                 PyList_Append(list, item);
2618                 Py_DECREF(item);
2619
2620                 count++;
2621                 if (count == stop) {
2622                         break;
2623                 }
2624         }
2625
2626         return list;
2627 }
2628
2629 static PyObject *bpy_bmelemseq_subscript(BPy_BMElemSeq *self, PyObject *key)
2630 {
2631         /* don't need error check here */
2632         if (PyIndex_Check(key)) {
2633                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
2634                 if (i == -1 && PyErr_Occurred())
2635                         return NULL;
2636                 return bpy_bmelemseq_subscript_int(self, i);
2637         }
2638         else if (PySlice_Check(key)) {
2639                 PySliceObject *key_slice = (PySliceObject *)key;
2640                 Py_ssize_t step = 1;
2641
2642                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
2643                         return NULL;
2644                 }
2645                 else if (step != 1) {
2646                         PyErr_SetString(PyExc_TypeError,
2647                                         "BMElemSeq[slice]: slice steps not supported");
2648                         return NULL;
2649                 }
2650                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
2651                         return bpy_bmelemseq_subscript_slice(self, 0, PY_SSIZE_T_MAX);
2652                 }
2653                 else {
2654                         Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
2655
2656                         /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
2657                         if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
2658                         if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop))    return NULL;
2659
2660                         if (start < 0 || stop < 0) {
2661                                 /* only get the length for negative values */
2662                                 Py_ssize_t len = bpy_bmelemseq_length(self);
2663                                 if (start < 0) start += len;
2664                                 if (stop  < 0) stop  += len;
2665                         }
2666
2667                         if (stop - start <= 0) {
2668                                 return PyList_New(0);
2669                         }
2670                         else {
2671                                 return bpy_bmelemseq_subscript_slice(self, start, stop);
2672                         }
2673                 }
2674         }
2675         else {
2676                 PyErr_SetString(PyExc_AttributeError,
2677                                 "BMElemSeq[key]: invalid key, key must be an int");
2678                 return NULL;
2679         }
2680 }
2681
2682 static int bpy_bmelemseq_contains(BPy_BMElemSeq *self, PyObject *value)
2683 {
2684         BPY_BM_CHECK_INT(self);
2685
2686         if (Py_TYPE(value) == bpy_bm_itype_as_pytype(self->itype)) {
2687                 BPy_BMElem *value_bm_ele = (BPy_BMElem *)value;
2688                 if (value_bm_ele->bm == self->bm) {
2689                         BMElem *ele, *ele_test = value_bm_ele->ele;
2690                         BMIter iter;
2691                         BM_ITER_BPY_BM_SEQ (ele, &iter, self) {
2692                                 if (ele == ele_test) {
2693                                         return 1;
2694                                 }
2695                         }
2696                 }
2697         }
2698
2699         return 0;
2700 }
2701
2702 /* BMElem (customdata)
2703  * ------------------- */
2704
2705 static PyObject *bpy_bmelem_subscript(BPy_BMElem *self, BPy_BMLayerItem *key)
2706 {
2707         BPY_BM_CHECK_OBJ(self);
2708
2709         return BPy_BMLayerItem_GetItem(self, key);
2710 }
2711
2712 static int bpy_bmelem_ass_subscript(BPy_BMElem *self, BPy_BMLayerItem *key, PyObject *value)
2713 {
2714         BPY_BM_CHECK_INT(self);
2715
2716         return BPy_BMLayerItem_SetItem(self, key, value);
2717 }
2718
2719 static PySequenceMethods bpy_bmelemseq_as_sequence = {
2720         (lenfunc)bpy_bmelemseq_length,               /* sq_length */
2721         NULL,                                        /* sq_concat */
2722         NULL,                                        /* sq_repeat */
2723         (ssizeargfunc)bpy_bmelemseq_subscript_int,   /* sq_item */ /* Only set this so PySequence_Check() returns True */
2724         NULL,                                        /* sq_slice */
2725         (ssizeobjargproc)NULL,                       /* sq_ass_item */
2726         NULL,                                        /* *was* sq_ass_slice */
2727         (objobjproc)bpy_bmelemseq_contains,          /* sq_contains */
2728         (binaryfunc) NULL,                           /* sq_inplace_concat */
2729         (ssizeargfunc) NULL,                         /* sq_inplace_repeat */
2730 };
2731
2732 static PyMappingMethods bpy_bmelemseq_as_mapping = {
2733         (lenfunc)bpy_bmelemseq_length,               /* mp_length */
2734         (binaryfunc)bpy_bmelemseq_subscript,         /* mp_subscript */
2735         (objobjargproc)NULL,                         /* mp_ass_subscript */
2736 };
2737
2738 /* for customdata access */
2739 static PyMappingMethods bpy_bm_elem_as_mapping = {
2740         (lenfunc)NULL,                           /* mp_length */ /* keep this empty, messes up 'if elem: ...' test */
2741         (binaryfunc)bpy_bmelem_subscript,        /* mp_subscript */
2742         (objobjargproc)bpy_bmelem_ass_subscript, /* mp_ass_subscript */
2743 };
2744
2745 /* Iterator
2746  * -------- */
2747
2748 static PyObject *bpy_bmelemseq_iter(BPy_BMElemSeq *self)
2749 {
2750         BPy_BMIter *py_iter;
2751
2752         BPY_BM_CHECK_OBJ(self);
2753         py_iter = (BPy_BMIter *)BPy_BMIter_CreatePyObject(self->bm);
2754         BM_iter_init(&(py_iter->iter), self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL);
2755         return (PyObject *)py_iter;
2756 }
2757
2758 static PyObject *bpy_bmiter_next(BPy_BMIter *self)
2759 {
2760         BMHeader *ele = BM_iter_step(&self->iter);
2761         if (ele == NULL) {
2762                 PyErr_SetString(PyExc_StopIteration,
2763                                 "bpy_bmiter_next stop");
2764                 return NULL;
2765         }
2766         else {
2767                 return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, ele);
2768         }
2769 }
2770
2771
2772 /* Dealloc Functions
2773  * ================= */
2774
2775 static void bpy_bmesh_dealloc(BPy_BMesh *self)
2776 {
2777         BMesh *bm = self->bm;
2778
2779         /* have have been freed by bmesh */
2780         if (bm) {
2781                 BM_data_layer_free(bm, &bm->vdata, CD_BM_ELEM_PYPTR);
2782                 BM_data_layer_free(bm, &bm->edata, CD_BM_ELEM_PYPTR);
2783                 BM_data_layer_free(bm, &bm->pdata, CD_BM_ELEM_PYPTR);
2784                 BM_data_layer_free(bm, &bm->ldata, CD_BM_ELEM_PYPTR);
2785
2786                 bm->py_handle = NULL;
2787
2788                 if ((self->flag & BPY_BMFLAG_IS_WRAPPED) == 0) {
2789                         BM_mesh_free(bm);
2790                 }
2791         }
2792
2793         PyObject_DEL(self);
2794 }
2795
2796 static void bpy_bmvert_dealloc(BPy_BMElem *self)
2797 {
2798         BMesh *bm = self->bm;
2799         if (bm) {
2800                 void **ptr = CustomData_bmesh_get(&bm->vdata, self->ele->head.data, CD_BM_ELEM_PYPTR);
2801                 *ptr = NULL;
2802         }
2803         PyObject_DEL(self);
2804 }
2805
2806 static void bpy_bmedge_dealloc(BPy_BMElem *self)
2807 {
2808         BMesh *bm = self->bm;
2809         if (bm) {
2810                 void **ptr = CustomData_bmesh_get(&bm->edata, self->ele->head.data, CD_BM_ELEM_PYPTR);
2811                 *ptr = NULL;
2812         }
2813         PyObject_DEL(self);
2814 }
2815
2816 static void bpy_bmface_dealloc(BPy_BMElem *self)
2817 {
2818         BMesh *bm = self->bm;
2819         if (bm) {
2820                 void **ptr = CustomData_bmesh_get(&bm->pdata, self->ele->head.data, CD_BM_ELEM_PYPTR);
2821                 *ptr = NULL;
2822         }
2823         PyObject_DEL(self);
2824 }
2825
2826 static void bpy_bmloop_dealloc(BPy_BMElem *self)
2827 {
2828         BMesh *bm = self->bm;
2829         if (bm) {
2830                 void **ptr = CustomData_bmesh_get(&bm->ldata, self->ele->head.data, CD_BM_ELEM_PYPTR);
2831                 *ptr = NULL;
2832         }
2833         PyObject_DEL(self);
2834 }
2835
2836 static void bpy_bmelemseq_dealloc(BPy_BMElemSeq *self)
2837 {
2838         Py_XDECREF(self->py_ele);
2839
2840         PyObject_DEL(self);
2841 }
2842
2843 /* not sure where this should go */
2844 static Py_hash_t bpy_bm_elem_hash(PyObject *self)
2845 {
2846         return _Py_HashPointer(((BPy_BMElem *)self)->ele);
2847 }
2848
2849 static Py_hash_t bpy_bm_hash(PyObject *self)
2850 {
2851         return _Py_HashPointer(((BPy_BMesh *)self)->bm);
2852 }
2853
2854 /* Type Docstrings
2855  * =============== */
2856
2857 PyDoc_STRVAR(bpy_bmesh_doc,
2858 "The BMesh data structure\n"
2859 );
2860 PyDoc_STRVAR(bpy_bmvert_doc,
2861 "The BMesh vertex type\n"
2862 );
2863 PyDoc_STRVAR(bpy_bmedge_doc,
2864 "The BMesh edge connecting 2 verts\n"
2865 );
2866 PyDoc_STRVAR(bpy_bmface_doc,
2867 "The BMesh face with 3 or more sides\n"
2868 );
2869 PyDoc_STRVAR(bpy_bmloop_doc,
2870 "This is normally accessed from :class:`BMFace.loops` where each face corner represents a corner of a face.\n"
2871 );
2872 PyDoc_STRVAR(bpy_bmelemseq_doc,
2873 "General sequence type used for accessing any sequence of \n"
2874 ":class:`BMVert`, :class:`BMEdge`, :class:`BMFace`, :class:`BMLoop`.\n"
2875 "\n"
2876 "When accessed via :class:`BMesh.verts`, :class:`BMesh.edges`, :class:`BMesh.faces` \n"
2877 "there are also functions to create/remomove items.\n"
2878 );
2879 PyDoc_STRVAR(bpy_bmiter_doc,
2880 "Internal BMesh type for looping over verts/faces/edges,\n"
2881 "used for iterating over :class:`BMElemSeq` types.\n"
2882 );
2883
2884 static PyObject *bpy_bmesh_repr(BPy_BMesh *self)
2885 {
2886         BMesh *bm = self->bm;
2887
2888         if (bm) {
2889                 return PyUnicode_FromFormat("<BMesh(%p), totvert=%d, totedge=%d, totface=%d, totloop=%d>",
2890                                             bm, bm->totvert, bm->totedge, bm->totface, bm->totloop);
2891         }
2892         else {
2893                 return PyUnicode_FromFormat("<BMesh dead at %p>", self);
2894         }
2895 }
2896
2897 static PyObject *bpy_bmvert_repr(BPy_BMVert *self)
2898 {
2899         BMesh *bm = self->bm;
2900
2901         if (bm) {
2902                 BMVert *v = self->v;
2903                 return PyUnicode_FromFormat("<BMVert(%p), index=%d>",
2904                                             v, BM_elem_index_get(v));
2905         }
2906         else {
2907                 return PyUnicode_FromFormat("<BMVert dead at %p>", self);
2908         }
2909 }
2910
2911 static PyObject *bpy_bmedge_repr(BPy_BMEdge *self)
2912 {
2913         BMesh *bm = self->bm;
2914
2915         if (bm) {
2916                 BMEdge *e = self->e;
2917                 return PyUnicode_FromFormat("<BMEdge(%p), index=%d, verts=(%p/%d, %p/%d)>",
2918                                             e, BM_elem_index_get(e),
2919                                             e->v1, BM_elem_index_get(e->v1),
2920                                             e->v2, BM_elem_index_get(e->v2));
2921         }
2922         else {
2923                 return PyUnicode_FromFormat("<BMEdge dead at %p>", self);
2924         }
2925 }
2926
2927 static PyObject *bpy_bmface_repr(BPy_BMFace *self)
2928 {
2929         BMesh *bm = self->bm;
2930
2931         if (bm) {
2932                 BMFace *f = self->f;
2933                 return PyUnicode_FromFormat("<BMFace(%p), index=%d, totverts=%d>",
2934                                             f, BM_elem_index_get(f),
2935                                             f->len);
2936         }
2937         else {
2938                 return PyUnicode_FromFormat("<BMFace dead at %p>", self);
2939         }
2940 }
2941
2942 static PyObject *bpy_bmloop_repr(BPy_BMLoop *self)
2943 {
2944         BMesh *bm = self->bm;
2945
2946         if (bm) {
2947                 BMLoop *l = self->l;
2948                 return PyUnicode_FromFormat("<BMLoop(%p), index=%d, vert=%p/%d, edge=%p/%d, face=%p/%d>",
2949                                             l, BM_elem_index_get(l),
2950                                             l->v, BM_elem_index_get(l->v),
2951                                             l->e, BM_elem_index_get(l->e),
2952                                             l->f, BM_elem_index_get(l->f));
2953         }
2954         else {
2955                 return PyUnicode_FromFormat("<BMLoop dead at %p>", self);
2956         }
2957 }
2958
2959 /* Types
2960  * ===== */
2961
2962 PyTypeObject BPy_BMesh_Type     = {{{0}}};
2963 PyTypeObject BPy_BMVert_Type    = {{{0}}};
2964 PyTypeObject BPy_BMEdge_Type    = {{{0}}};
2965 PyTypeObject BPy_BMFace_Type    = {{{0}}};
2966 PyTypeObject BPy_BMLoop_Type    = {{{0}}};
2967 PyTypeObject BPy_BMElemSeq_Type = {{{0}}};
2968 PyTypeObject BPy_BMVertSeq_Type = {{{0}}};
2969 PyTypeObject BPy_BMEdgeSeq_Type = {{{0}}};
2970 PyTypeObject BPy_BMFaceSeq_Type = {{{0}}};
2971 PyTypeObject BPy_BMLoopSeq_Type = {{{0}}};
2972 PyTypeObject BPy_BMIter_Type    = {{{0}}};
2973
2974
2975
2976 void BPy_BM_init_types(void)
2977 {
2978         BPy_BMesh_Type.tp_basicsize     = sizeof(BPy_BMesh);
2979         BPy_BMVert_Type.tp_basicsize    = sizeof(BPy_BMVert);
2980         BPy_BMEdge_Type.tp_basicsize    = sizeof(BPy_BMEdge);
2981         BPy_BMFace_Type.tp_basicsize    = sizeof(BPy_BMFace);
2982         BPy_BMLoop_Type.tp_basicsize    = sizeof(BPy_BMLoop);
2983         BPy_BMElemSeq_Type.tp_basicsize = sizeof(BPy_BMElemSeq);
2984         BPy_BMVertSeq_Type.tp_basicsize = sizeof(BPy_BMElemSeq);
2985         BPy_BMEdgeSeq_Type.tp_basicsize = sizeof(BPy_BMElemSeq);
2986         BPy_BMFaceSeq_Type.tp_basicsize = sizeof(BPy_BMElemSeq);
2987         BPy_BMLoopSeq_Type.tp_basicsize = sizeof(BPy_BMElemSeq);
2988         BPy_BMIter_Type.tp_basicsize    = sizeof(BPy_BMIter);
2989
2990
2991         BPy_BMesh_Type.tp_name     = "BMesh";
2992         BPy_BMVert_Type.tp_name    = "BMVert";
2993         BPy_BMEdge_Type.tp_name    = "BMEdge";
2994         BPy_BMFace_Type.tp_name    = "BMFace";
2995         BPy_BMLoop_Type.tp_name    = "BMLoop";
2996         BPy_BMElemSeq_Type.tp_name = "BMElemSeq";
2997         BPy_BMVertSeq_Type.tp_name = "BMVertSeq";
2998         BPy_BMEdgeSeq_Type.tp_name = "BMEdgeSeq";
2999         BPy_BMFaceSeq_Type.tp_name = "BMFaceSeq";
3000         BPy_BMLoopSeq_Type.tp_name = "BMLoopSeq";
3001         BPy_BMIter_Type.tp_name    = "BMIter";
3002
3003
3004         BPy_BMesh_Type.tp_doc     = bpy_bmesh_doc;
3005         BPy_BMVert_Type.tp_doc    = bpy_bmvert_doc;
3006         BPy_BMEdge_Type.tp_doc    = bpy_bmedge_doc;
3007         BPy_BMFace_Type.tp_doc    = bpy_bmface_doc;
3008         BPy_BMLoop_Type.tp_doc    = bpy_bmloop_doc;
3009         BPy_BMElemSeq_Type.tp_doc = bpy_bmelemseq_doc;
3010         BPy_BMVertSeq_Type.tp_doc = NULL;
3011         BPy_BMEdgeSeq_Type.tp_doc = NULL;
3012         BPy_BMFaceSeq_Type.tp_doc = NULL;
3013         BPy_BMLoopSeq_Type.tp_doc = NULL;
3014         BPy_BMIter_Type.tp_doc    = bpy_bmiter_doc;
3015
3016
3017         BPy_BMesh_Type.tp_repr     = (reprfunc)bpy_bmesh_repr;
3018         BPy_BMVert_Type.tp_repr    = (reprfunc)bpy_bmvert_repr;
3019         BPy_BMEdge_Type.tp_repr    = (reprfunc)bpy_bmedge_repr;
3020         BPy_BMFace_Type.tp_repr    = (reprfunc)bpy_bmface_repr;
3021         BPy_BMLoop_Type.tp_repr    = (reprfunc)bpy_bmloop_repr;
3022         BPy_BMElemSeq_Type.tp_repr = NULL;
3023         BPy_BMVertSeq_Type.tp_repr = NULL;
3024         BPy_BMEdgeSeq_Type.tp_repr = NULL;
3025         BPy_BMFaceSeq_Type.tp_repr = NULL;
3026         BPy_BMLoopSeq_Type.tp_repr = NULL;
3027         BPy_BMIter_Type.tp_repr    = NULL;
3028
3029
3030         BPy_BMesh_Type.tp_getset     = bpy_bmesh_getseters;
3031         BPy_BMVert_Type.tp_getset    = bpy_bmvert_getseters;
3032         BPy_BMEdge_Type.tp_getset    = bpy_bmedge_getseters;
3033         BPy_BMFace_Type.tp_getset    = bpy_bmface_getseters;
3034         BPy_BMLoop_Type.tp_getset    = bpy_bmloop_getseters;
3035         BPy_BMElemSeq_Type.tp_getset = NULL;
3036         BPy_BMVertSeq_Type.tp_getset = bpy_bmvertseq_getseters;
3037         BPy_BMEdgeSeq_Type.tp_getset = bpy_bmedgeseq_getseters;
3038         BPy_BMFaceSeq_Type.tp_getset = bpy_bmfaceseq_getseters;
3039         BPy_BMLoopSeq_Type.tp_getset = bpy_bmloopseq_getseters;
3040         BPy_BMIter_Type.tp_getset    = NULL;
3041
3042
3043         BPy_BMesh_Type.tp_methods     = bpy_bmesh_methods;
3044         BPy_BMVert_Type.tp_methods    = bpy_bmvert_methods;
3045         BPy_BMEdge_Type.tp_methods    = bpy_bmedge_methods;
3046         BPy_BMFace_Type.tp_methods    = bpy_bmface_methods;
3047         BPy_BMLoop_Type.tp_methods    = bpy_bmloop_methods;
3048         BPy_BMElemSeq_Type.tp_methods = bpy_bmelemseq_methods;
3049         BPy_BMVertSeq_Type.tp_methods = bpy_bmvertseq_methods;
3050         BPy_BMEdgeSeq_Type.tp_methods = bpy_bmedgeseq_methods;
3051         BPy_BMFaceSeq_Type.tp_methods = bpy_bmfaceseq_methods;
3052         BPy_BMLoopSeq_Type.tp_methods = bpy_bmloopseq_methods;
3053         BPy_BMIter_Type.tp_methods    = NULL;
3054
3055         /*BPy_BMElem_Check() uses bpy_bm_elem_hash() to check types.
3056          * if this changes update the macro */
3057         BPy_BMesh_Type.tp_hash     = bpy_bm_hash;
3058         BPy_BMVert_Type.tp_hash    = bpy_bm_elem_hash;
3059         BPy_BMEdge_Type.tp_hash    = bpy_bm_elem_hash;
3060         BPy_BMFace_Type.tp_hash    = bpy_bm_elem_hash;
3061         BPy_BMLoop_Type.tp_hash    = bpy_bm_elem_hash;
3062         BPy_BMElemSeq_Type.tp_hash = NULL;
3063         BPy_BMVertSeq_Type.tp_hash = NULL;
3064         BPy_BMEdgeSeq_Type.tp_hash = NULL;
3065         BPy_BMFaceSeq_Type.tp_hash = NULL;
3066         BPy_BMLoopSeq_Type.tp_hash = NULL;
3067         BPy_BMIter_Type.tp_hash    = NULL;
3068
3069         BPy_BMElemSeq_Type.tp_as_sequence = &bpy_bmelemseq_as_sequence;
3070         BPy_BMVertSeq_Type.tp_as_sequence = &bpy_bmelemseq_as_sequence;
3071         BPy_BMEdgeSeq_Type.tp_as_sequence = &bpy_bmelemseq_as_sequence;
3072         BPy_BMFaceSeq_Type.tp_as_sequence = &bpy_bmelemseq_as_sequence;
3073         BPy_BMLoopSeq_Type.tp_as_sequence = NULL; /* this is not a seq really, only for layer access */
3074
3075         BPy_BMElemSeq_Type.tp_as_mapping = &bpy_bmelemseq_as_mapping;
3076         BPy_BMVertSeq_Type.tp_as_mapping = &bpy_bmelemseq_as_mapping;
3077         BPy_BMEdgeSeq_Type.tp_as_mapping = &bpy_bmelemseq_as_mapping;
3078         BPy_BMFaceSeq_Type.tp_as_mapping = &bpy_bmelemseq_as_mapping;
3079         BPy_BMLoopSeq_Type.tp_as_mapping = NULL; /* this is not a seq really, only for layer access */
3080
3081         /* layer access */
3082         BPy_BMVert_Type.tp_as_mapping    = &bpy_bm_elem_as_mapping;
3083         BPy_BMEdge_Type.tp_as_mapping    = &bpy_bm_elem_as_mapping;
3084         BPy_BMFace_Type.tp_as_mapping    = &bpy_bm_elem_as_mapping;
3085         BPy_BMLoop_Type.tp_as_mapping    = &bpy_bm_elem_as_mapping;
3086
3087         BPy_BMElemSeq_Type.tp_iter = (getiterfunc)bpy_bmelemseq_iter;
3088         BPy_BMVertSeq_Type.tp_iter = (getiterfunc)bpy_bmelemseq_iter;
3089         BPy_BMEdgeSeq_Type.tp_iter = (getiterfunc)bpy_bmelemseq_iter;
3090         BPy_BMFaceSeq_Type.tp_iter = (getiterfunc)bpy_bmelemseq_iter;
3091         BPy_BMLoopSeq_Type.tp_iter = NULL; /* no mapping */
3092
3093         /* only 1 iteratir so far */
3094         BPy_BMIter_Type.tp_iternext = (iternextfunc)bpy_bmiter_next;
3095         BPy_BMIter_Type.tp_iter     = PyObject_SelfIter;
3096
3097         BPy_BMesh_Type.tp_dealloc     = (destructor)bpy_bmesh_dealloc;
3098         BPy_BMVert_Type.tp_dealloc    = (destructor)bpy_bmvert_dealloc;
3099         BPy_BMEdge_Type.tp_dealloc    = (destructor)bpy_bmedge_dealloc;
3100         BPy_BMFace_Type.tp_dealloc    = (destructor)bpy_bmface_dealloc;
3101         BPy_BMLoop_Type.tp_dealloc    = (destructor)bpy_bmloop_dealloc;
3102         BPy_BMElemSeq_Type.tp_dealloc = (destructor)bpy_bmelemseq_dealloc;
3103         BPy_BMVertSeq_Type.tp_dealloc = (destructor)bpy_bmelemseq_dealloc;
3104         BPy_BMEdgeSeq_Type.tp_dealloc = (destructor)bpy_bmelemseq_dealloc;
3105         BPy_BMFaceSeq_Type.tp_dealloc = (destructor)bpy_bmelemseq_dealloc;
3106         BPy_BMLoopSeq_Type.tp_dealloc = (destructor)bpy_bmelemseq_dealloc;
3107         BPy_BMIter_Type.tp_dealloc    = NULL;
3108
3109         BPy_BMesh_Type.tp_flags     = Py_TPFLAGS_DEFAULT;
3110         BPy_BMVert_Type.tp_flags    = Py_TPFLAGS_DEFAULT;
3111         BPy_BMEdge_Type.tp_flags    = Py_TPFLAGS_DEFAULT;
3112         BPy_BMFace_Type.tp_flags    = Py_TPFLAGS_DEFAULT;
3113         BPy_BMLoop_Type.tp_flags    = Py_TPFLAGS_DEFAULT;
3114         BPy_BMElemSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3115         BPy_BMVertSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3116         BPy_BMEdgeSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3117         BPy_BMFaceSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3118         BPy_BMLoopSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
3119         BPy_BMIter_Type.tp_flags    = Py_TPFLAGS_DEFAULT;
3120
3121
3122         PyType_Ready(&BPy_BMesh_Type);
3123         PyType_Ready(&BPy_BMVert_Type);
3124         PyType_Ready(&BPy_BMEdge_Type);
3125         PyType_Ready(&BPy_BMFace_Type);
3126         PyType_Ready(&BPy_BMLoop_Type);
3127         PyType_Ready(&BPy_BMElemSeq_Type);
3128         PyType_Ready(&BPy_BMVertSeq_Type);
3129         PyType_Ready(&BPy_BMEdgeSeq_Type);
3130         PyType_Ready(&BPy_BMFaceSeq_Type);
3131         PyType_Ready(&BPy_BMLoopSeq_Type);
3132         PyType_Ready(&BPy_BMIter_Type);
3133 }
3134
3135 /* bmesh.types submodule
3136  * ********************* */
3137
3138 static struct PyModuleDef BPy_BM_types_module_def = {
3139         PyModuleDef_HEAD_INIT,
3140         "bmesh.types",  /* m_name */
3141         NULL,  /* m_doc */
3142         0,     /* m_size */
3143         NULL,  /* m_methods */
3144         NULL,  /* m_reload */
3145         NULL,  /* m_traverse */
3146         NULL,  /* m_clear */
3147         NULL,  /* m_free */
3148 };
3149
3150 PyObject *BPyInit_bmesh_types(void)
3151 {
3152         PyObject *submodule;
3153
3154         submodule = PyModule_Create(&BPy_BM_types_module_def);
3155
3156 #define MODULE_TYPE_ADD(s, t) \
3157         PyModule_AddObject(s, t.tp_name, (PyObject *)&t); Py_INCREF((PyObject *)&t)
3158
3159         /* bmesh_py_types.c */
3160         MODULE_TYPE_ADD(submodule, BPy_BMesh_Type);
3161         MODULE_TYPE_ADD(submodule, BPy_BMVert_Type);
3162         MODULE_TYPE_ADD(submodule, BPy_BMEdge_Type);
3163         MODULE_TYPE_ADD(submodule, BPy_BMFace_Type);
3164         MODULE_TYPE_ADD(submodule, BPy_BMLoop_Type);
3165         MODULE_TYPE_ADD(submodule, BPy_BMElemSeq_Type);
3166         MODULE_TYPE_ADD(submodule, BPy_BMVertSeq_Type);
3167         MODULE_TYPE_ADD(submodule, BPy_BMEdgeSeq_Type);
3168         MODULE_TYPE_ADD(submodule, BPy_BMFaceSeq_Type);
3169         MODULE_TYPE_ADD(submodule, BPy_BMLoopSeq_Type);
3170         MODULE_TYPE_ADD(submodule, BPy_BMIter_Type);
3171         /* bmesh_py_types_select.c */
3172         MODULE_TYPE_ADD(submodule, BPy_BMEditSelSeq_Type);
3173         MODULE_TYPE_ADD(submodule, BPy_BMEditSelIter_Type);
3174         /* bmesh_py_types_customdata.c */
3175         MODULE_TYPE_ADD(submodule, BPy_BMLayerAccessVert_Type);
3176         MODULE_TYPE_ADD(submodule, BPy_BMLayerAccessEdge_Type);
3177         MODULE_TYPE_ADD(submodule, BPy_BMLayerAccessFace_Type);
3178         MODULE_TYPE_ADD(submodule, BPy_BMLayerAccessLoop_Type);
3179         MODULE_TYPE_ADD(submodule, BPy_BMLayerCollection_Type);
3180         MODULE_TYPE_ADD(submodule, BPy_BMLayerItem_Type);
3181         /* bmesh_py_types_meshdata.c */
3182         MODULE_TYPE_ADD(submodule, BPy_BMLoopUV_Type);
3183         MODULE_TYPE_ADD(submodule, BPy_BMDeformVert_Type);
3184
3185 #undef MODULE_TYPE_ADD
3186
3187         return submodule;
3188 }
3189
3190 /* Utility Functions
3191  * ***************** */
3192
3193 PyObject *BPy_BMesh_CreatePyObject(BMesh *bm, int flag)
3194 {
3195         BPy_BMesh *self;
3196
3197         if (bm->py_handle) {
3198                 self = bm->py_handle;
3199                 Py_INCREF(self);
3200         }
3201         else {
3202                 self = PyObject_New(BPy_BMesh, &BPy_BMesh_Type);
3203                 self->bm = bm;
3204                 self->flag = flag;
3205
3206                 bm->py_handle = self; /* point back */
3207
3208                 BM_data_layer_add(bm, &bm->vdata, CD_BM_ELEM_PYPTR);
3209                 BM_data_layer_add(bm, &bm->edata, CD_BM_ELEM_PYPTR);
3210                 BM_data_layer_add(bm, &bm->pdata, CD_BM_ELEM_PYPTR);
3211                 BM_data_layer_add(bm, &bm->ldata, CD_BM_ELEM_PYPTR);
3212         }
3213
3214         return (PyObject *)self;
3215 }
3216
3217
3218
3219 PyObject *BPy_BMVert_CreatePyObject(BMesh *bm, BMVert *v)
3220 {
3221         BPy_BMVert *self;
3222
3223         void **ptr = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_BM_ELEM_PYPTR);
3224
3225         /* bmesh may free layers, ensure we have one to store ourself */
3226         if (UNLIKELY(ptr == NULL)) {
3227                 BM_data_layer_add(bm, &bm->vdata, CD_BM_ELEM_PYPTR);
3228                 ptr = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_BM_ELEM_PYPTR);
3229         }
3230
3231         if (*ptr != NULL) {
3232                 self = *ptr;
3233                 Py_INCREF(self);
3234         }
3235         else {
3236                 self = PyObject_New(BPy_BMVert, &BPy_BMVert_Type);
3237                 BLI_assert(v != NULL);
3238                 self->bm = bm;
3239                 self->v  = v;
3240                 *ptr = self;
3241         }
3242         return (PyObject *)self;
3243 }
3244
3245 PyObject *BPy_BMEdge_CreatePyObject(BMesh *bm, BMEdge *e)
3246 {
3247         BPy_BMEdge *self;
3248
3249         void **ptr = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BM_ELEM_PYPTR);
3250
3251         /* bmesh may free layers, ensure we have one to store ourself */
3252         if (UNLIKELY(ptr == NULL)) {
3253                 BM_data_layer_add(bm, &bm->edata, CD_BM_ELEM_PYPTR);
3254                 ptr = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BM_ELEM_PYPTR);
3255         }
3256
3257         if (*ptr != NULL) {
3258                 self = *ptr;
3259                 Py_INCREF(self);
3260         }
3261         else {
3262                 self = PyObject_New(BPy_BMEdge, &BPy_BMEdge_Type);
3263                 BLI_assert(e != NULL);
3264                 self->bm = bm;
3265                 self->e  = e;
3266                 *ptr = self;
3267         }
3268         return (PyObject *)self;
3269 }
3270
3271 PyObject *BPy_BMFace_CreatePyObject(BMesh *bm, BMFace *f)
3272 {
3273         BPy_BMFace *self;
3274
3275         void **ptr = CustomData_bmesh_get(&bm->pdata, f->head.data, CD_BM_ELEM_PYPTR);
3276
3277         /* bmesh may free layers, ensure we have one to store ourself */
3278         if (UNLIKELY(ptr == NULL)) {
3279                 BM_data_layer_add(bm, &bm->pdata, CD_BM_ELEM_PYPTR);
3280                 ptr = CustomData_bmesh_get(&bm->pdata, f->head.data, CD_BM_ELEM_PYPTR);
3281         }
3282
3283         if (*ptr != NULL) {
3284                 self = *ptr;
3285                 Py_INCREF(self);
3286         }
3287         else {
3288                 self = PyObject_New(BPy_BMFace, &BPy_BMFace_Type);
3289                 BLI_assert(f != NULL);
3290                 self->bm = bm;
3291                 self->f  = f;
3292                 *ptr = self;
3293         }
3294         return (PyObject *)self;
3295 }
3296
3297 PyObject *BPy_BMLoop_CreatePyObject(BMesh *bm, BMLoop *l)
3298 {
3299         BPy_BMLoop *self;
3300
3301         void **ptr = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_BM_ELEM_PYPTR);
3302
3303         /* bmesh may free layers, ensure we have one to store ourself */
3304         if (UNLIKELY(ptr == NULL)) {
3305                 BM_data_layer_add(bm, &bm->ldata, CD_BM_ELEM_PYPTR);
3306                 ptr = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_BM_ELEM_PYPTR);
3307         }
3308
3309         if (*ptr != NULL) {
3310                 self = *ptr;
3311                 Py_INCREF(self);
3312         }
3313         else {
3314                 self = PyObject_New(BPy_BMLoop, &BPy_BMLoop_Type);
3315                 BLI_assert(l != NULL);
3316                 self->bm = bm;
3317                 self->l  = l;
3318                 *ptr = self;
3319         }
3320         return (PyObject *)self;
3321 }
3322
3323 PyObject *BPy_BMElemSeq_CreatePyObject(BMesh *bm, BPy_BMElem *py_ele, const char itype)
3324 {
3325         BPy_BMElemSeq *self = PyObject_New(BPy_BMElemSeq, &BPy_BMElemSeq_Type);
3326         self->bm = bm;
3327         self->py_ele = py_ele; /* can be NULL */
3328         self->itype = itype;
3329         Py_XINCREF(py_ele);
3330         return (PyObject *)self;
3331 }
3332
3333 PyObject *BPy_BMVertSeq_CreatePyObject(BMesh *bm)
3334 {
3335         BPy_BMElemSeq *self = PyObject_New(BPy_BMElemSeq, &BPy_BMVertSeq_Type);
3336         self->bm = bm;
3337         self->py_ele = NULL; /* unused */
3338         self->itype = BM_VERTS_OF_MESH;
3339         return (PyObject *)self;
3340 }
3341
3342 PyObject *BPy_BMEdgeSeq_CreatePyObject(BMesh *bm)
3343 {
3344         BPy_BMElemSeq *self = PyObject_New(BPy_BMElemSeq, &BPy_BMEdgeSeq_Type);
3345         self->bm = bm;
3346         self->py_ele = NULL; /* unused */
3347         self->itype = BM_EDGES_OF_MESH;
3348         return (PyObject *)self;
3349 }
3350
3351 PyObject *BPy_BMFaceSeq_CreatePyObject(BMesh *bm)
3352 {
3353         BPy_BMElemSeq *self = PyObject_New(BPy_BMElemSeq, &BPy_BMFaceSeq_Type);
3354         self->bm = bm;
3355         self->py_ele = NULL; /* unused */
3356         self->itype = BM_FACES_OF_MESH;
3357         return (PyObject *)self;
3358 }
3359
3360 PyObject *BPy_BMLoopSeq_CreatePyObject(BMesh *bm)
3361 {
3362         BPy_BMElemSeq *self = PyObject_New(BPy_BMElemSeq, &BPy_BMLoopSeq_Type);
3363         self->bm = bm;
3364         self->py_ele = NULL; /* unused */
3365         self->itype = 0; /* should never be passed to the iterator function */
3366         return (PyObject *)self;
3367 }
3368
3369 PyObject *BPy_BMIter_CreatePyObject(BMesh *bm)
3370 {
3371         BPy_BMIter *self = PyObject_New(BPy_BMIter, &BPy_BMIter_Type);
3372         self->bm = bm;
3373         /* caller must initialize 'iter' member */
3374         return (PyObject *)self;
3375 }
3376
3377 /* this is just a helper func */
3378 PyObject *BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele)
3379 {
3380         switch (ele->htype) {
3381                 case BM_VERT:
3382                         return BPy_BMVert_CreatePyObject(bm, (BMVert *)ele);
3383                 case BM_EDGE:
3384                         return BPy_BMEdge_CreatePyObject(bm, (BMEdge *)ele);
3385                 case BM_FACE:
3386                         return BPy_BMFace_CreatePyObject(bm, (BMFace *)ele);
3387                 case BM_LOOP:
3388                         return BPy_BMLoop_CreatePyObject(bm, (BMLoop *)ele);
3389                 default:
3390                         BLI_assert(0);
3391                         PyErr_SetString(PyExc_SystemError, "internal error");
3392                         return NULL;
3393         }
3394 }
3395
3396 int bpy_bm_generic_valid_check(BPy_BMGeneric *self)
3397 {
3398         if (LIKELY(self->bm)) {
3399
3400                 /* far too slow to enable by default but handy
3401                  * to uncomment for debugging tricky errors,
3402                  * note that this will throw error on entering a
3403                  * function where the actual error will be caused by
3404                  * the previous action. */
3405 #if 0
3406                 if (BM_mesh_validate(self->bm) == FALSE) {
3407                         PyErr_Format(PyExc_ReferenceError,
3408                                      "BMesh used by %.200s has become invalid",
3409                                      Py_TYPE(self)->tp_name);
3410                         return -1;
3411                 }
3412 #endif
3413
3414                 return 0;
3415         }
3416         else {
3417                 PyErr_Format(PyExc_ReferenceError,
3418                              "BMesh data of type %.200s has been removed",
3419                              Py_TYPE(self)->tp_name);
3420                 return -1;
3421         }
3422 }
3423
3424 int bpy_bm_generic_valid_check_source(BPy_BMGeneric *self, BMesh *bm_source, const char *error_prefix)
3425 {
3426         int ret = bpy_bm_generic_valid_check(self);
3427         if (LIKELY(ret == 0)) {
3428                 if (UNLIKELY(self->bm != bm_source)) {
3429                         /* could give more info here */
3430                         PyErr_Format(PyExc_ValueError,
3431                                      "%.200s: BMesh data of type %.200s is from another mesh",
3432                                      error_prefix, Py_TYPE(self)->tp_name);
3433                         ret = -1;
3434                 }
3435         }
3436         return ret;
3437 }
3438
3439 void bpy_bm_generic_invalidate(BPy_BMGeneric *self)
3440 {
3441         self->bm = NULL;
3442 }
3443
3444 /* generic python seq as BMVert/Edge/Face array,
3445  * return value must be freed with PyMem_FREE(...);
3446  *
3447  * The 'bm_r' value is assigned when empty, and used when set.
3448  */
3449 void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, Py_ssize_t *r_size,
3450                                 const char htype,
3451                                 const char do_unique_check, const char do_bm_check,
3452                                 const char *error_prefix)
3453 {
3454         BMesh *bm = (r_bm && *r_bm) ? *r_bm : NULL;
3455         PyObject *seq_fast;
3456         *r_size = 0;
3457
3458         if (!(seq_fast = PySequence_Fast(seq, error_prefix))) {
3459                 return NULL;
3460  &nbs