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