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