typo cleanup, no functional changes.
[blender-staging.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 "BKE_customdata.h"
35
36 #include "bmesh.h"
37
38 #include "../mathutils/mathutils.h"
39
40 #include "../generic/py_capi_utils.h"
41
42 #include "bmesh_py_types.h" /* own include */
43
44 /* Common Flags
45  * ************ */
46
47 /* scene does not use BM_* flags. */
48 PyC_FlagSet bpy_bm_scene_vert_edge_face_flags[] = {
49     {1, "VERT"},
50     {2, "EDGE"},
51     {4, "FACE"},
52     {0, NULL}
53 };
54
55 PyC_FlagSet bpy_bm_htype_vert_edge_face_flags[] = {
56     {BM_VERT, "VERT"},
57     {BM_EDGE, "EDGE"},
58     {BM_FACE, "FACE"},
59     {0, NULL}
60 };
61
62 PyC_FlagSet bpy_bm_htype_all_flags[] = {
63     {BM_VERT, "VERT"},
64     {BM_LOOP, "EDGE"},
65     {BM_FACE, "FACE"},
66     {BM_LOOP, "LOOP"},
67     {0, NULL}
68 };
69
70 PyC_FlagSet bpy_bm_hflag_all_flags[] = {
71     {BM_ELEM_SELECT,  "SELECT"},
72     {BM_ELEM_HIDDEN,  "HIDE"},
73     {BM_ELEM_SEAM,    "SEAM"},
74     {BM_ELEM_SMOOTH,  "SMOOTH"},
75     {BM_ELEM_TAG,     "TAG"},
76     {0, NULL}
77 };
78
79 /* py-type definitions
80  * ******************* */
81
82 /* getseters
83  * ========= */
84
85
86 /* bmesh elems
87  * ----------- */
88
89 PyDoc_STRVAR(bpy_bm_elem_select_doc,  "Selected state of this element.\n\n:type: boolean");
90 PyDoc_STRVAR(bpy_bm_elem_hide_doc,    "Hidden state of this element.\n\n:type: boolean");
91 PyDoc_STRVAR(bpy_bm_elem_tag_doc,     "Generic attribute scripts can use for own logic\n\n:type: boolean");
92 PyDoc_STRVAR(bpy_bm_elem_smooth_doc,  "Smooth state of this element.\n\n:type: boolean");
93
94
95 static PyObject *bpy_bm_elem_hflag_get(BPy_BMElem *self, void *flag)
96 {
97         const char hflag = (char)GET_INT_FROM_POINTER(flag);
98
99         BPY_BM_CHECK_OBJ(self);
100
101         return PyBool_FromLong(BM_elem_flag_test(self->ele, hflag));
102 }
103
104 static int bpy_bm_elem_hflag_set(BPy_BMElem *self, PyObject *value, void *flag)
105 {
106         const char hflag = (char)GET_INT_FROM_POINTER(flag);
107         int param;
108
109         BPY_BM_CHECK_INT(self);
110
111         param = PyLong_AsLong(value);
112
113         if (param == TRUE) {
114                 BM_elem_flag_enable(self->ele, hflag);
115                 return 0;
116         }
117         else if (param == FALSE) {
118                 BM_elem_flag_disable(self->ele, hflag);
119                 return 0;
120         }
121         else {
122                 PyErr_Format(PyExc_TypeError,
123                              "expected True/False or 0/1, not %.200s",
124                              Py_TYPE(value)->tp_name);
125                 return -1;
126         }
127 }
128
129 PyDoc_STRVAR(bpy_bm_elem_index_doc,
130 "Index of this element.\n"
131 "\n"
132 ":type: int\n"
133 "\n"
134 ".. note::\n"
135 "\n"
136 "   This value is not necessarily valid, while editing the mesh it can become *dirty*.\n"
137 "\n"
138 "   It's also possible to assign any number to this attribute for a scripts internal logic.\n"
139 "\n"
140 "   To ensure the value is up to date - see :class:`BMesh.update` **index** argument.\n"
141 );
142 static PyObject *bpy_bm_elem_index_get(BPy_BMElem *self, void *UNUSED(flag))
143 {
144         BPY_BM_CHECK_OBJ(self);
145
146         return PyLong_FromLong(BM_elem_index_get(self->ele));
147 }
148
149 static int bpy_bm_elem_index_set(BPy_BMElem *self, PyObject *value, void *UNUSED(flag))
150 {
151         int param;
152
153         BPY_BM_CHECK_INT(self);
154
155         param = PyLong_AsLong(value);
156
157         if (param == -1 && PyErr_Occurred()) {
158                 PyErr_SetString(PyExc_TypeError, "expected an int type");
159                 return -1;
160         }
161         else {
162                 BM_elem_index_set(self->ele, param); /* set_dirty! */
163
164                 /* when setting the index assume its set invalid */
165                 if (self->ele->htype & (BM_VERT | BM_EDGE | BM_FACE)) {
166                         self->bm->elem_index_dirty |= self->ele->htype;
167                 }
168
169                 return 0;
170         }
171 }
172
173 /* type spesific get/sets
174  * ---------------------- */
175
176
177 /* Mesh
178  * ^^^^ */
179
180 /* doc-strings for all uses of this funcion */
181 PyDoc_STRVAR(bpy_bmesh_verts_doc,
182 "This meshes vert sequence (read-only).\n\n:type: :class:`BMElemSeq`"
183 );
184 PyDoc_STRVAR(bpy_bmesh_edges_doc,
185 "This meshes edge sequence (read-only).\n\n:type: :class:`BMElemSeq`"
186 );
187 PyDoc_STRVAR(bpy_bmesh_faces_doc,
188 "This meshes face sequence (read-only).\n\n:type: :class:`BMElemSeq`"
189 );
190
191 static PyObject *bpy_bmelemseq_get(BPy_BMesh *self, void *itype)
192 {
193         BPY_BM_CHECK_OBJ(self);
194         return BPy_BMElemSeq_CreatePyObject(self->bm, NULL, GET_INT_FROM_POINTER(itype));
195 }
196
197 /* vert */
198 PyDoc_STRVAR(bpy_bmvert_link_edges_doc,
199 "Edges connected to this vertex (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMVert`"
200 );
201 PyDoc_STRVAR(bpy_bmvert_link_faces_doc,
202 "Faces connected to this vertex (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMFace`"
203 );
204 PyDoc_STRVAR(bpy_bmvert_link_loops_doc,
205 "Loops that use this vertex (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMLoop`"
206 );
207 /* edge */
208 PyDoc_STRVAR(bpy_bmedge_verts_doc,
209 "Verts this edge uses (always 2), (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMVert`"
210 );
211 PyDoc_STRVAR(bpy_bmedge_link_faces_doc,
212 "Faces connected to this edge, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMFace`"
213 );
214 PyDoc_STRVAR(bpy_bmedge_link_loops_doc,
215 "Loops connected to this edge, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMLoop`"
216 );
217 /* face */
218 PyDoc_STRVAR(bpy_bmface_verts_doc,
219 "Verts of this face, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMVert`"
220 );
221 PyDoc_STRVAR(bpy_bmface_edges_doc,
222 "Edges of this face, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMEdge`"
223 );
224 PyDoc_STRVAR(bpy_bmface_loops_doc,
225 "Loops of this face, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMLoop`"
226 );
227 /* loop */
228 PyDoc_STRVAR(bpy_bmloops_link_loops_doc,
229 "Loops connected to this loop, (read-only).\n\n:type: :class:`BMElemSeq` of :class:`BMLoop`"
230 );
231
232 static PyObject *bpy_bmelemseq_elem_get(BPy_BMElem *self, void *itype)
233 {
234         BPY_BM_CHECK_OBJ(self);
235         return BPy_BMElemSeq_CreatePyObject(self->bm, self, GET_INT_FROM_POINTER(itype));
236 }
237
238 PyDoc_STRVAR(bpy_bm_is_valid_doc,
239 "True when this element is valid (hasn't been removed).\n\n:type: boolean"
240 );
241 static PyObject *bpy_bm_is_valid_get(BPy_BMGeneric *self)
242 {
243         return PyBool_FromLong(self->bm != NULL);
244 }
245
246
247 PyDoc_STRVAR(bpy_bmesh_select_mode_doc,
248 "The selection mode, values can be {'VERT', 'EDGE', 'FACE'}, can't be assigned an empty set.\n\n:type: set"
249 );
250 static PyObject *bpy_bmesh_select_mode_get(BPy_BMesh *self)
251 {
252         BPY_BM_CHECK_OBJ(self);
253
254         return PyC_FlagSet_FromBitfield(bpy_bm_scene_vert_edge_face_flags, self->bm->selectmode);
255 }
256
257 static int bpy_bmesh_select_mode_set(BPy_BMesh *self, PyObject *value)
258 {
259         int flag = 0;
260         BPY_BM_CHECK_INT(self);
261
262         if (PyC_FlagSet_ToBitfield(bpy_bm_scene_vert_edge_face_flags, value, &flag, "bm.select_mode") == -1) {
263                 return -1;
264         }
265         else if (flag == 0) {
266                 PyErr_SetString(PyExc_TypeError, "bm.select_mode: cant assignt an empty value");
267                 return -1;
268         }
269         else {
270                 self->bm->selectmode = flag;
271                 return 0;
272         }
273 }
274
275
276 /* Vert
277  * ^^^^ */
278
279 PyDoc_STRVAR(bpy_bmvert_co_doc,
280 "The coordinates for this vertex as a 3D, wrapped vector.\n\n:type: :class:`mathutils.Vector`"
281 );
282 static PyObject *bpy_bmvert_co_get(BPy_BMVert *self)
283 {
284         BPY_BM_CHECK_OBJ(self);
285         return Vector_CreatePyObject(self->v->co, 3, Py_WRAP, NULL);
286 }
287
288 static int bpy_bmvert_co_set(BPy_BMVert *self, PyObject *value)
289 {
290         BPY_BM_CHECK_INT(self);
291
292         if (mathutils_array_parse(self->v->co, 3, 3, value, "BMVert.co") != -1) {
293                 return 0;
294         }
295         else {
296                 return -1;
297         }
298 }
299
300 PyDoc_STRVAR(bpy_bmvert_normal_doc,
301 "The normal for this vertex as a 3D, wrapped vector.\n\n:type: :class:`mathutils.Vector`"
302 );
303 static PyObject *bpy_bmvert_normal_get(BPy_BMVert *self)
304 {
305         BPY_BM_CHECK_OBJ(self);
306         return Vector_CreatePyObject(self->v->no, 3, Py_WRAP, NULL);
307 }
308
309 static int bpy_bmvert_normal_set(BPy_BMVert *self, PyObject *value)
310 {
311         BPY_BM_CHECK_INT(self);
312
313         if (mathutils_array_parse(self->v->no, 3, 3, value, "BMVert.normal") != -1) {
314                 return 0;
315         }
316         else {
317                 return -1;
318         }
319 }
320
321 PyDoc_STRVAR(bpy_bmvert_is_manifold_doc,
322 "True when this vertex is manifold (read-only).\n\n:type: boolean"
323 );
324 static PyObject *bpy_bmvert_is_manifold_get(BPy_BMVert *self)
325 {
326         BPY_BM_CHECK_OBJ(self);
327         return PyBool_FromLong(BM_vert_is_manifold(self->bm, self->v));
328 }
329
330 PyDoc_STRVAR(bpy_bmvert_is_wire_doc,
331 "True when this vertex is not connected to any faces (read-only).\n\n:type: boolean"
332 );
333 static PyObject *bpy_bmvert_is_wire_get(BPy_BMVert *self)
334 {
335         BPY_BM_CHECK_OBJ(self);
336         return PyBool_FromLong(BM_vert_is_wire(self->bm, self->v));
337 }
338
339 /* Edge
340  * ^^^^ */
341
342 PyDoc_STRVAR(bpy_bmedge_is_manifold_doc,
343 "True when this edge is manifold (read-only).\n\n:type: boolean"
344 );
345 static PyObject *bpy_bmedge_is_manifold_get(BPy_BMEdge *self)
346 {
347         BPY_BM_CHECK_OBJ(self);
348         return PyBool_FromLong(BM_edge_is_manifold(self->bm, self->e));
349 }
350
351 PyDoc_STRVAR(bpy_bmedge_is_wire_doc,
352 "True when this edge is not connected to any faces (read-only).\n\n:type: boolean"
353 );
354 static PyObject *bpy_bmedge_is_wire_get(BPy_BMEdge *self)
355 {
356         BPY_BM_CHECK_OBJ(self);
357         return PyBool_FromLong(BM_edge_is_wire(self->bm, self->e));
358 }
359
360 PyDoc_STRVAR(bpy_bmedge_is_boundary_doc,
361 "True when this edge is at the boundary of a face (read-only).\n\n:type: boolean"
362 );
363 static PyObject *bpy_bmedge_is_boundary_get(BPy_BMEdge *self)
364 {
365         BPY_BM_CHECK_OBJ(self);
366         return PyBool_FromLong(BM_edge_is_boundary(self->e));
367 }
368
369 /* Face
370  * ^^^^ */
371
372 PyDoc_STRVAR(bpy_bmface_normal_doc,
373 "The normal for this face as a 3D, wrapped vector.\n\n:type: boolean"
374 );
375 static PyObject *bpy_bmface_normal_get(BPy_BMFace *self)
376 {
377         BPY_BM_CHECK_OBJ(self);
378         return Vector_CreatePyObject(self->f->no, 3, Py_WRAP, NULL);
379 }
380
381 static int bpy_bmface_normal_set(BPy_BMFace *self, PyObject *value)
382 {
383         BPY_BM_CHECK_INT(self);
384
385         if (mathutils_array_parse(self->f->no, 3, 3, value, "BMFace.normal") != -1) {
386                 return 0;
387         }
388         else {
389                 return -1;
390         }
391 }
392
393 static PyGetSetDef bpy_bmesh_getseters[] = {
394     {(char *)"verts", (getter)bpy_bmelemseq_get, (setter)NULL, (char *)bpy_bmesh_verts_doc, (void *)BM_VERTS_OF_MESH},
395     {(char *)"edges", (getter)bpy_bmelemseq_get, (setter)NULL, (char *)bpy_bmesh_edges_doc, (void *)BM_EDGES_OF_MESH},
396     {(char *)"faces", (getter)bpy_bmelemseq_get, (setter)NULL, (char *)bpy_bmesh_faces_doc, (void *)BM_FACES_OF_MESH},
397     {(char *)"select_mode", (getter)bpy_bmesh_select_mode_get, (setter)bpy_bmesh_select_mode_set, (char *)bpy_bmesh_select_mode_doc, NULL},
398
399     /* readonly checks */
400     {(char *)"is_valid",   (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
401
402     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
403 };
404
405 static PyGetSetDef bpy_bmvert_getseters[] = {
406     /* generic */
407     {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT},
408     {(char *)"hide",   (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc,   (void *)BM_ELEM_SELECT},
409     {(char *)"tag",    (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_tag_doc,    (void *)BM_ELEM_TAG},
410     {(char *)"index",  (getter)bpy_bm_elem_index_get, (setter)bpy_bm_elem_index_set, (char *)bpy_bm_elem_index_doc,  NULL},
411
412     {(char *)"co",     (getter)bpy_bmvert_co_get,     (setter)bpy_bmvert_co_set,     (char *)bpy_bmvert_co_doc, NULL},
413     {(char *)"normal", (getter)bpy_bmvert_normal_get, (setter)bpy_bmvert_normal_set, (char *)bpy_bmvert_normal_doc, NULL},
414
415     /* connectivity data */
416     {(char *)"link_edges", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmvert_link_edges_doc, (void *)BM_EDGES_OF_VERT},
417     {(char *)"link_faces", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmvert_link_faces_doc, (void *)BM_FACES_OF_VERT},
418     {(char *)"link_loops", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmvert_link_loops_doc, (void *)BM_LOOPS_OF_VERT},
419
420     /* readonly checks */
421     {(char *)"is_manifold",  (getter)bpy_bmvert_is_manifold_get,  (setter)NULL, (char *)bpy_bmvert_is_manifold_doc, NULL},
422     {(char *)"is_wire",      (getter)bpy_bmvert_is_wire_get,      (setter)NULL, (char *)bpy_bmvert_is_wire_doc, NULL},
423     {(char *)"is_valid",     (getter)bpy_bm_is_valid_get,         (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
424
425     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
426 };
427
428 static PyGetSetDef bpy_bmedge_getseters[] = {
429     /* generic */
430     {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT},
431     {(char *)"hide",   (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc,   (void *)BM_ELEM_SELECT},
432     {(char *)"tag",    (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_tag_doc,    (void *)BM_ELEM_TAG},
433     {(char *)"index",  (getter)bpy_bm_elem_index_get, (setter)bpy_bm_elem_index_set, (char *)bpy_bm_elem_index_doc,  NULL},
434
435     {(char *)"smooth", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_smooth_doc, (void *)BM_ELEM_SMOOTH},
436     {(char *)"seam",   (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_smooth_doc, (void *)BM_ELEM_SEAM},
437
438     /* connectivity data */
439     {(char *)"verts", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmedge_verts_doc, (void *)BM_VERTS_OF_EDGE},
440
441     {(char *)"link_faces", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmedge_link_faces_doc, (void *)BM_FACES_OF_EDGE},
442     {(char *)"link_loops", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmedge_link_loops_doc, (void *)BM_LOOPS_OF_EDGE},
443
444     /* readonly checks */
445     {(char *)"is_manifold",  (getter)bpy_bmedge_is_manifold_get,  (setter)NULL, (char *)bpy_bmedge_is_manifold_doc, NULL},
446     {(char *)"is_wire",      (getter)bpy_bmedge_is_wire_get,      (setter)NULL, (char *)bpy_bmedge_is_wire_doc, NULL},
447     {(char *)"is_boundary",   (getter)bpy_bmedge_is_boundary_get,   (setter)NULL, (char *)bpy_bmedge_is_boundary_doc, NULL},
448     {(char *)"is_valid",     (getter)bpy_bm_is_valid_get,         (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
449
450     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
451 };
452
453 static PyGetSetDef bpy_bmface_getseters[] = {
454     /* generic */
455     {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT},
456     {(char *)"hide",   (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc,   (void *)BM_ELEM_SELECT},
457     {(char *)"tag",    (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_tag_doc,    (void *)BM_ELEM_TAG},
458     {(char *)"index",  (getter)bpy_bm_elem_index_get, (setter)bpy_bm_elem_index_set, (char *)bpy_bm_elem_index_doc,  NULL},
459
460     {(char *)"smooth", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_smooth_doc, (void *)BM_ELEM_SMOOTH},
461
462     {(char *)"normal", (getter)bpy_bmface_normal_get, (setter)bpy_bmface_normal_set, (char *)bpy_bmface_normal_doc, NULL},
463
464     /* connectivity data */
465     {(char *)"verts", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmface_verts_doc, (void *)BM_VERTS_OF_FACE},
466     {(char *)"edges", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmface_edges_doc, (void *)BM_EDGES_OF_FACE},
467     {(char *)"loops", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmface_loops_doc, (void *)BM_LOOPS_OF_FACE},
468
469     /* readonly checks */
470     {(char *)"is_valid",   (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
471
472     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
473 };
474
475 static PyGetSetDef bpy_bmloop_getseters[] = {
476     /* generic */
477     // flags are available but not used for loops.
478     // {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT},
479     // {(char *)"hide",   (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc,   (void *)BM_ELEM_SELECT},
480     {(char *)"tag",    (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_tag_doc,    (void *)BM_ELEM_TAG},
481     {(char *)"index",  (getter)bpy_bm_elem_index_get, (setter)bpy_bm_elem_index_set, (char *)bpy_bm_elem_index_doc,  NULL},
482
483     /* connectivity data */
484     {(char *)"link_loops", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmloops_link_loops_doc, (void *)BM_LOOPS_OF_LOOP},
485
486     /* readonly checks */
487     {(char *)"is_valid",   (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
488
489     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
490 };
491
492
493 /* Methods
494  * ======= */
495
496 /* Mesh
497  * ---- */
498
499 PyDoc_STRVAR(bpy_bmesh_select_flush_mode_doc,
500 ".. method:: select_flush_mode()\n"
501 "\n"
502 "   flush selection based on the current mode current :class:`BMesh.select_mode`.\n"
503 );
504 static PyObject *bpy_bmesh_select_flush_mode(BPy_BMesh *self)
505 {
506         BPY_BM_CHECK_OBJ(self);
507
508         BM_mesh_select_mode_flush(self->bm);
509
510         Py_RETURN_NONE;
511 }
512
513 PyDoc_STRVAR(bpy_bmesh_select_flush_doc,
514 ".. method:: select_flush(select)\n"
515 "\n"
516 "   Flush selection, independent of the current selection mode.\n"
517 "\n"
518 "   :arg select: flush selection or de-selected elements.\n"
519 "   :type select: boolean\n"
520 );
521 static PyObject *bpy_bmesh_select_flush(BPy_BMesh *self, PyObject *value)
522 {
523         int param;
524
525         BPY_BM_CHECK_OBJ(self);
526
527         param = PyLong_AsLong(value);
528         if (param != FALSE && param != TRUE) {
529                 PyErr_SetString(PyExc_TypeError, "expected a boolean type 0/1");
530                 return NULL;
531         }
532
533         if (param)  BM_mesh_select_flush(self->bm);
534         else        BM_mesh_deselect_flush(self->bm);
535
536         Py_RETURN_NONE;
537 }
538
539 PyDoc_STRVAR(bpy_bmesh_normal_update_doc,
540 ".. method:: normal_update(skip_hidden=False)\n"
541 "\n"
542 "   Update mesh normals.\n"
543 "\n"
544 "   :arg skip_hidden: When True hidden elements are ignored.\n"
545 "   :type skip_hidden: boolean\n"
546 );
547 static PyObject *bpy_bmesh_normal_update(BPy_BMElem *self, PyObject *args)
548 {
549
550         int skip_hidden = FALSE;
551
552         BPY_BM_CHECK_OBJ(self);
553
554         if (!PyArg_ParseTuple(args, "|i:normal_update", &skip_hidden)) {
555                 return NULL;
556         }
557
558         BM_mesh_normals_update(self->bm, skip_hidden);
559
560         Py_RETURN_NONE;
561 }
562
563
564 PyDoc_STRVAR(bpy_bmesh_transform_doc,
565 ".. method:: transform(matrix, filter=None)\n"
566 "\n"
567 "   Transform the mesh (optionally filtering flagged data only).\n"
568 "\n"
569 "   :arg matrix: transform matrix.\n"
570 "   :type matrix: 4x4 :class:`mathutils.Matrix`\n"
571 "   :arg filter: set of values in ('SELECT', 'HIDE', 'SEAM', 'SMOOTH', 'TAG').\n"
572 "   :type filter: set\n"
573 );
574 static PyObject *bpy_bmesh_transform(BPy_BMElem *self, PyObject *args, PyObject *kw)
575 {
576         static const char *kwlist[] = {"matrix", "filter", NULL};
577
578         MatrixObject *mat;
579         PyObject *filter = NULL;
580         int filter_flags = 0;
581
582         BPY_BM_CHECK_OBJ(self);
583
584         if (!PyArg_ParseTupleAndKeywords(args, kw,
585                                          "O!|O!:transform",
586                                          (char **)kwlist,
587                                          &matrix_Type, &mat,
588                                          &PySet_Type,  &filter))
589         {
590                 return NULL;
591         }
592         else {
593                 BMVert *eve;
594                 BMIter iter;
595                 void *mat_ptr;
596
597                 if (BaseMath_ReadCallback(mat) == -1) {
598                         return NULL;
599                 }
600                 else if (mat->num_col != 4 || mat->num_row != 4) {
601                         PyErr_SetString(PyExc_ValueError, "expected a 4x4 matrix");
602                         return NULL;
603                 }
604
605                 if (filter != NULL && PyC_FlagSet_ToBitfield(bpy_bm_hflag_all_flags, filter,
606                                                              &filter_flags, "bm.transform") == -1)
607                 {
608                         return NULL;
609                 }
610
611                 mat_ptr = mat->matrix;
612
613                 if (!filter_flags) {
614                         BM_ITER(eve, &iter, self->bm, BM_VERTS_OF_MESH, NULL) {
615                                 mul_m4_v3((float (*)[4])mat_ptr, eve->co);
616                         }
617                 }
618                 else {
619                         char filter_flags_ch = (char)filter_flags;
620                         BM_ITER(eve, &iter, self->bm, BM_VERTS_OF_MESH, NULL) {
621                                 if (eve->head.hflag & filter_flags_ch) {
622                                         mul_m4_v3((float (*)[4])mat_ptr, eve->co);
623                                 }
624                         }
625                 }
626         }
627
628         Py_RETURN_NONE;
629 }
630
631 /* Elem
632  * ---- */
633
634 PyDoc_STRVAR(bpy_bm_elem_select_set_doc,
635 ".. method:: select_set(select)\n"
636 "\n"
637 "   Set the selection.\n"
638 "   This is different from the *select* attribute because it updates the selection state of assosiated geometry.\n"
639 "\n"
640 "   :arg select: Select or de-select.\n"
641 "   :type select: boolean\n"
642 );
643 static PyObject *bpy_bm_elem_select_set(BPy_BMElem *self, PyObject *value)
644 {
645         int param;
646
647         BPY_BM_CHECK_OBJ(self);
648
649         param = PyLong_AsLong(value);
650         if (param != FALSE && param != TRUE) {
651                 PyErr_SetString(PyExc_TypeError, "expected a boolean type 0/1");
652                 return NULL;
653         }
654
655         BM_elem_select_set(self->bm, self->ele, param);
656
657         Py_RETURN_NONE;
658 }
659
660 PyDoc_STRVAR(bpy_bm_elem_copy_from_doc,
661 ".. method:: copy_from(select)\n"
662 "\n"
663 "   Copy values from another element.\n"
664 );
665 static PyObject *bpy_bm_elem_copy_from(BPy_BMElem *self, BPy_BMElem *value)
666 {
667         BPY_BM_CHECK_OBJ(self);
668
669         if (Py_TYPE(self) != Py_TYPE(value)) {
670                 PyErr_Format(PyExc_TypeError,
671                              "expected element of type '%.200s' not '%.200s'",
672                              Py_TYPE(self)->tp_name, Py_TYPE(value)->tp_name);
673                 return NULL;
674         }
675
676         BM_elem_attrs_copy(value->bm, self->bm, value->ele, self->ele);
677
678         Py_RETURN_NONE;
679 }
680
681
682 /* Vert
683  * ---- */
684
685 PyDoc_STRVAR(bpy_bmvert_calc_edge_angle_doc,
686 ".. method:: calc_edge_angle()\n"
687 "\n"
688 "   Return the angle between 2 connected edges.\n"
689 );
690 static PyObject *bpy_bmvert_calc_edge_angle(BPy_BMVert *self)
691 {
692         BPY_BM_CHECK_OBJ(self);
693         return PyFloat_FromDouble(BM_vert_edge_angle(self->bm, self->v));
694 }
695
696 /* Edge
697  * ---- */
698
699 PyDoc_STRVAR(bpy_bmedge_calc_face_angle_doc,
700 ".. method:: calc_face_angle()\n"
701 "\n"
702 "   Return the angle between 2 connected faces.\n"
703 "\n"
704 "   :return: The angle between both faces in radians.\n"
705 "   :rtype: float\n"
706 );
707 static PyObject *bpy_bmedge_calc_face_angle(BPy_BMEdge *self)
708 {
709         BPY_BM_CHECK_OBJ(self);
710         return PyFloat_FromDouble(BM_edge_face_angle(self->bm, self->e));
711 }
712
713 PyDoc_STRVAR(bpy_bmedge_other_vert_doc,
714 ".. method:: other_vert(vert)\n"
715 "\n"
716 "   Return the other vertex on this edge or None if the vertex is not used by this edge.\n"
717 "\n"
718 "   :arg vert: a vert in this edge.\n"
719 "   :type vert: :class:`BMVert`\n"
720 "   :return: The edges other vert.\n"
721 "   :rtype: :class:`BMVert` or None\n"
722 );
723 static PyObject *bpy_bmedge_other_vert(BPy_BMEdge *self, BPy_BMVert *value)
724 {
725         BMVert *other;
726         BPY_BM_CHECK_OBJ(self);
727
728         if (!BPy_BMVert_Check(value)) {
729                 PyErr_Format(PyExc_TypeError,
730                              "BMEdge.other_vert(vert): BMVert expected, not '%.200s'",
731                              Py_TYPE(value)->tp_name);
732                 return NULL;
733         }
734
735         BPY_BM_CHECK_OBJ(value);
736
737         if (self->bm != value->bm) {
738                 PyErr_SetString(PyExc_TypeError,
739                                 "BMEdge.other_vert(vert): vert is from another mesh");
740                 return NULL;
741         }
742
743         other = BM_edge_other_vert(self->e, value->v);
744
745         if (other) {
746                 return BPy_BMVert_CreatePyObject(self->bm, other);
747         }
748         else {
749                 /* could raise an exception here */
750                 Py_RETURN_NONE;
751         }
752 }
753
754 /* Face
755  * ---- */
756
757 PyDoc_STRVAR(bpy_bmface_copy_doc,
758 ".. method:: copy(verts=True, edges=True)\n"
759 "\n"
760 "   Make a copy of this face.\n"
761 "\n"
762 "   :arg verts: When set, the faces verts will be duplicated too.\n"
763 "   :type verts: boolean\n"
764 "   :arg edges: When set, the faces edges will be duplicated too.\n"
765 "   :type edges: boolean\n"
766 "   :return: The newly created face.\n"
767 "   :rtype: :class:`BMFace`\n"
768 );
769 static PyObject *bpy_bmface_copy(BPy_BMFace *self, PyObject *args, PyObject *kw)
770 {
771         static const char *kwlist[] = {"verts", "edges", NULL};
772
773         BMesh *bm = self->bm;
774         int do_verts = TRUE;
775         int do_edges = TRUE;
776
777         BMFace *f_cpy;
778         BPY_BM_CHECK_OBJ(self);
779
780         if (!PyArg_ParseTupleAndKeywords(args, kw,
781                                          "|ii:BMFace.copy",
782                                          (char **)kwlist,
783                                          &do_verts, &do_edges))
784         {
785                 return NULL;
786         }
787
788         f_cpy = BM_face_copy(bm, self->f, do_verts, do_edges);
789
790         if (f_cpy) {
791                 return BPy_BMFace_CreatePyObject(bm, f_cpy);
792         }
793         else {
794                 PyErr_SetString(PyExc_ValueError,
795                                 "BMFace.copy(): couldn't create the new face, internal error");
796                 return NULL;
797         }
798 }
799
800 PyDoc_STRVAR(bpy_bmface_calc_area_doc,
801 ".. method:: calc_area()\n"
802 "\n"
803 "   Return the area of the face.\n"
804 "\n"
805 "   :return: Return the area of the face.\n"
806 "   :rtype: float\n"
807 );
808 static PyObject *bpy_bmface_calc_area(BPy_BMFace *self)
809 {
810         BPY_BM_CHECK_OBJ(self);
811         return PyFloat_FromDouble(BM_face_area_calc(self->bm, self->f));
812 }
813
814 PyDoc_STRVAR(bpy_bmface_calc_center_mean_doc,
815 ".. method:: calc_center_median()\n"
816 "\n"
817 "   Return median center of the face.\n"
818 "\n"
819 "   :return: a 3D vector.\n"
820 "   :rtype: :class:`mathutils.Vector`\n"
821 );
822 static PyObject *bpy_bmface_calc_center_mean(BPy_BMFace *self)
823 {
824         float cent[3];
825
826         BPY_BM_CHECK_OBJ(self);
827         BM_face_center_mean_calc(self->bm, self->f, cent);
828         return Vector_CreatePyObject(cent, 3, Py_NEW, NULL);
829 }
830
831 PyDoc_STRVAR(bpy_bmface_calc_center_bounds_doc,
832 ".. method:: calc_center_bounds()\n"
833 "\n"
834 "   Return bounds center of the face.\n"
835 "\n"
836 "   :return: a 3D vector.\n"
837 "   :rtype: :class:`mathutils.Vector`\n"
838 );
839 static PyObject *bpy_bmface_calc_center_bounds(BPy_BMFace *self)
840 {
841         float cent[3];
842
843         BPY_BM_CHECK_OBJ(self);
844         BM_face_center_bounds_calc(self->bm, self->f, cent);
845         return Vector_CreatePyObject(cent, 3, Py_NEW, NULL);
846 }
847
848 /* Loop
849  * ---- */
850
851 PyDoc_STRVAR(bpy_bmloop_calc_face_angle_doc,
852 ".. method:: calc_face_angle()\n"
853 "\n"
854 "   Return angle at this loops corner of the face.\n"
855 "   This is calculated so sharper corners give lower angles.\n"
856 "\n"
857 "   :return: The angle in radians.\n"
858 "   :rtype: float\n"
859 );
860 static PyObject *bpy_bmloop_calc_face_angle(BPy_BMLoop *self)
861 {
862         BPY_BM_CHECK_OBJ(self);
863         return PyFloat_FromDouble(BM_loop_face_angle(self->bm, self->l));
864 }
865
866 /* Vert Seq
867  * -------- */
868
869 static PyObject *bpy_bmvert_seq_new(BPy_BMElemSeq *self, PyObject *args)
870 {
871         PyObject *py_co = NULL;
872         BPy_BMVert *py_vert_example = NULL; /* optional */
873
874         BPY_BM_CHECK_OBJ(self);
875
876         if (!PyArg_ParseTuple(args, "|OO!:verts.new",
877                               py_co,
878                               &BPy_BMVert_Type, &py_vert_example)) {
879                 return NULL;
880         }
881         else {
882                 BMesh *bm = self->bm;
883                 BMVert *v;
884                 float co[3] = {0.0f, 0.0f, 0.0f};
885
886                 if (py_vert_example) {
887                         BPY_BM_CHECK_OBJ(py_vert_example);
888                 }
889
890                 if (py_co && mathutils_array_parse(co, 3, 3, py_co, "verts.new(co)") != -1) {
891                         return NULL;
892                 }
893
894                 v = BM_vert_create(bm, co, NULL);
895
896                 if (v == NULL) {
897                         PyErr_SetString(PyExc_ValueError,
898                                         "faces.new(verts): couldn't create the new face, internal error");
899                         return NULL;
900                 }
901
902                 if (py_vert_example) {
903                         BM_elem_attrs_copy(py_vert_example->bm, bm, py_vert_example->v, v);
904                 }
905
906                 return BPy_BMVert_CreatePyObject(bm, v);
907         }
908 }
909
910
911 /* Edge Seq
912  * -------- */
913
914 static PyObject *bpy_bmedge_seq_new(BPy_BMElemSeq *self, PyObject *args)
915 {
916         BPy_BMVert *v1;
917         BPy_BMVert *v2;
918         BPy_BMEdge *py_edge_example = NULL; /* optional */
919
920         BPY_BM_CHECK_OBJ(self);
921
922         if (!PyArg_ParseTuple(args, "O!O!|O!:edges.new",
923                               &BPy_BMVert_Type, &v1,
924                               &BPy_BMVert_Type, &v2,
925                               &BPy_BMEdge_Type, &py_edge_example))
926         {
927                 return NULL;
928         }
929         else {
930                 BMesh *bm = self->bm;
931                 BMEdge *e;
932
933                 if (py_edge_example) {
934                         BPY_BM_CHECK_OBJ(py_edge_example);
935                 }
936
937                 if (v1->v == v2->v) {
938                         PyErr_SetString(PyExc_ValueError,
939                                         "edges.new(): both verts are the same");
940                 }
941
942                 if (!(bm == v1->bm && bm == v2->bm)) {
943                         PyErr_SetString(PyExc_ValueError,
944                                         "edges.new(): both verts must be from this mesh");
945                 }
946
947                 if (BM_edge_exists(v1->v, v2->v)) {
948                         PyErr_SetString(PyExc_ValueError,
949                                         "edges.new(): this edge exists");
950                 }
951
952                 e = BM_edge_create(bm, v1->v, v2->v, NULL, FALSE);
953
954                 if (e == NULL) {
955                         PyErr_SetString(PyExc_ValueError,
956                                         "faces.new(verts): couldn't create the new face, internal error");
957                         return NULL;
958                 }
959
960                 if (py_edge_example) {
961                         BM_elem_attrs_copy(py_edge_example->bm, bm, py_edge_example->e, e);
962                 }
963
964                 return BPy_BMEdge_CreatePyObject(bm, e);
965         }
966 }
967
968
969 /* Face Seq
970  * -------- */
971
972 static PyObject *bpy_bmface_seq_new(BPy_BMElemSeq *self, PyObject *args)
973 {
974         PyObject *vert_seq;
975         BPy_BMFace *py_face_example = NULL; /* optional */
976
977         BPY_BM_CHECK_OBJ(self);
978
979         if (!PyArg_ParseTuple(args, "O|O!:faces.new",
980                               &vert_seq,
981                               &BPy_BMFace_Type, &py_face_example)) {
982                 return NULL;
983         }
984         else {
985                 BMesh *bm = self->bm;
986                 Py_ssize_t vert_seq_len;
987                 Py_ssize_t i, i_prev;
988
989                 BMVert **vert_array = NULL;
990                 BMEdge **edge_array = NULL;
991
992                 PyObject *ret = NULL;
993
994                 BMFace *f_new;
995
996                 if (py_face_example) {
997                         BPY_BM_CHECK_OBJ(py_face_example);
998                 }
999
1000                 vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 3, PY_SSIZE_T_MAX,
1001                                                        &vert_seq_len, &BPy_BMVert_Type,
1002                                                        TRUE, TRUE, "faces.new(...)");
1003
1004                 /* check if the face exists */
1005                 if (BM_face_exists(bm, vert_array, vert_seq_len, NULL)) {
1006                         PyErr_SetString(PyExc_ValueError,
1007                                         "faces.new(verts): face already exists");
1008                         goto cleanup;
1009                 }
1010
1011                 /* Go ahead and make the face!
1012                  * --------------------------- */
1013
1014                 edge_array = (BMEdge **)PyMem_MALLOC(vert_seq_len * sizeof(BMEdge **));
1015
1016                 /* ensure edges */
1017                 for (i = 0, i_prev = vert_seq_len - 1; i < vert_seq_len; (i_prev=i++)) {
1018                         edge_array[i] = BM_edge_create(bm, vert_array[i], vert_array[i_prev], NULL, TRUE);
1019                 }
1020
1021                 f_new = BM_face_create(bm, vert_array, edge_array, vert_seq_len, FALSE);
1022
1023                 if (f_new == NULL) {
1024                         PyErr_SetString(PyExc_ValueError,
1025                                         "faces.new(verts): couldn't create the new face, internal error");
1026                         goto cleanup;
1027                 }
1028
1029                 if (py_face_example) {
1030                         BM_elem_attrs_copy(py_face_example->bm, bm, py_face_example->f, f_new);
1031                 }
1032
1033                 ret = BPy_BMFace_CreatePyObject(bm, f_new);
1034
1035                 /* pass through */
1036 cleanup:
1037                 if (vert_array) PyMem_FREE(vert_array);
1038                 if (edge_array) PyMem_FREE(edge_array);
1039                 return ret;
1040         }
1041 }
1042
1043 /* Elem Seq
1044  * -------- */
1045
1046 /* eek - 3 docstrings in 1!, we might need to split up this seq at some point */
1047 PyDoc_STRVAR(bpy_bmelemseq_new_doc,
1048 ".. method:: new(co=(0.0, 0.0, 0.0), example=None)\n"
1049 "\n"
1050 "   *Vertex Sequence*\n"
1051 "\n"
1052 "   :arg co: The initial location of the vertex (optional argument).\n"
1053 "   :type co: float triplet\n"
1054 "   :arg example: Existing vert to initialize settings.\n"
1055 "   :type example: :class:`BMVert`\n"
1056 "   :return: The newly created edge.\n"
1057 "   :rtype: :class:`BMVert`\n"
1058 "\n"
1059 "\n"
1060 ".. method:: new(v_a, v_b, example=None)\n"
1061 "\n"
1062 "   *Edge Sequence*\n"
1063 "\n"
1064 "   :arg v_a: Edge vertex.\n"
1065 "   :type v_a: :class:`BMEdge`\n"
1066 "   :arg v_b: Edge vertex.\n"
1067 "   :type v_b: :class:`BMEdge`\n"
1068 "   :arg example: Existing edge to initialize settings (optional argument).\n"
1069 "   :type example: :class:`BMEdge`\n"
1070 "   :return: The newly created edge.\n"
1071 "   :rtype: :class:`BMEdge`\n"
1072 "\n"
1073 ".. method:: new(verts, example=None)\n"
1074 "\n"
1075 "   *Face Sequence*\n"
1076 "\n"
1077 "   Create a new vert/edge/face.\n"
1078 "\n"
1079 "   :arg verts: Sequence of 3 or more verts.\n"
1080 "   :type verts: :class:`BMVert`\n"
1081 "   :arg example: Existing face to initialize settings (optional argument).\n"
1082 "   :type example: :class:`BMFace`\n"
1083 "   :return: The newly created face.\n"
1084 "   :rtype: :class:`BMFace`\n"
1085 );
1086 static PyObject *bpy_bmelemseq_new(BPy_BMElemSeq *self, PyObject *args)
1087 {
1088         switch ((BMIterType)self->itype) {
1089                 case BM_VERTS_OF_MESH:
1090                         return bpy_bmvert_seq_new(self, args);
1091                 case BM_EDGES_OF_MESH:
1092                         return bpy_bmedge_seq_new(self, args);
1093                 case BM_FACES_OF_MESH:
1094                         return bpy_bmface_seq_new(self, args);
1095                 default:
1096                         PyErr_SetString(PyExc_TypeError,
1097                                         ".new(...): function is not valid for this sequence");
1098                         return NULL;
1099         }
1100 }
1101
1102 static PyObject *bpy_bmvert_seq_remove(BPy_BMElemSeq *self, BPy_BMVert *value)
1103 {
1104         BPY_BM_CHECK_OBJ(self);
1105
1106         if (!BPy_BMVert_Check(value)) {
1107                 return NULL;
1108         }
1109         else {
1110                 BMesh *bm = self->bm;
1111
1112                 BPY_BM_CHECK_OBJ(value);
1113
1114                 if (value->bm != bm) {
1115                         PyErr_SetString(PyExc_TypeError,
1116                                         "faces.remove(vert): vertex is from another mesh");
1117                 }
1118
1119                 BM_vert_kill(bm, value->v);
1120                 bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
1121
1122                 Py_RETURN_NONE;;
1123         }
1124 }
1125
1126 static PyObject *bpy_bmedge_seq_remove(BPy_BMElemSeq *self, BPy_BMEdge *value)
1127 {
1128         BPY_BM_CHECK_OBJ(self);
1129
1130         if (!BPy_BMEdge_Check(value)) {
1131                 return NULL;
1132         }
1133         else {
1134                 BMesh *bm = self->bm;
1135
1136                 BPY_BM_CHECK_OBJ(value);
1137
1138                 if (value->bm != bm) {
1139                         PyErr_SetString(PyExc_TypeError,
1140                                         "faces.remove(vert): vertex is from another mesh");
1141                 }
1142
1143                 BM_edge_kill(bm, value->e);
1144                 bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
1145
1146                 Py_RETURN_NONE;;
1147         }
1148 }
1149
1150 static PyObject *bpy_bmface_seq_remove(BPy_BMElemSeq *self, BPy_BMFace *value)
1151 {
1152         BPY_BM_CHECK_OBJ(self);
1153
1154         if (!BPy_BMFace_Check(value)) {
1155                 return NULL;
1156         }
1157         else {
1158                 BMesh *bm = self->bm;
1159
1160                 BPY_BM_CHECK_OBJ(value);
1161
1162                 if (value->bm != bm) {
1163                         PyErr_SetString(PyExc_TypeError,
1164                                         "faces.remove(vert): vertex is from another mesh");
1165                 }
1166
1167                 BM_face_kill(bm, value->f);
1168                 bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
1169
1170                 Py_RETURN_NONE;;
1171         }
1172 }
1173
1174
1175 PyDoc_STRVAR(bpy_bmelemseq_remove_doc,
1176 ".. method:: remove(elem)\n"
1177 "\n"
1178 "   Remove a vert/edge/face.\n"
1179 );
1180 static PyObject *bpy_bmelemseq_remove(BPy_BMElemSeq *self, PyObject *value)
1181 {
1182         switch ((BMIterType)self->itype) {
1183                 case BM_VERTS_OF_MESH:
1184                         return bpy_bmvert_seq_remove(self, (BPy_BMVert *)value);
1185                 case BM_EDGES_OF_MESH:
1186                         return bpy_bmedge_seq_remove(self, (BPy_BMEdge *)value);
1187                 case BM_FACES_OF_MESH:
1188                         return bpy_bmface_seq_remove(self, (BPy_BMFace *)value);
1189                 default:
1190                         PyErr_SetString(PyExc_TypeError,
1191                                         ".remove(item): function is not valid for this sequence");
1192                         return NULL;
1193         }
1194 }
1195
1196 PyDoc_STRVAR(bpy_bmelemseq_index_update_doc,
1197 ".. method:: index_update()\n"
1198 "\n"
1199 "   Initialize the index values of this sequence.\n"
1200 "\n"
1201 "   This is the equivalent of looping over all elements and assigning the index values.\n"
1202 "\n"
1203 "   .. code-block:: python\n"
1204 "\n"
1205 "      for index, ele in enumerate(sequence):\n"
1206 "          ele.index = index\n"
1207 "\n"
1208 "   .. note::\n"
1209 "\n"
1210 "      Running this on sequences besides :class:`BMesh.verts`, :class:`BMesh.edges`, :class:`BMesh.faces`\n"
1211 "      works but wont result in each element having a valid index, insted its order in the sequence will be set.\n"
1212 );
1213 static PyObject *bpy_bmelemseq_index_update(BPy_BMElemSeq *self)
1214 {
1215         BMesh *bm = self->bm;
1216
1217         BPY_BM_CHECK_OBJ(self);
1218
1219         switch ((BMIterType)self->itype) {
1220                 case BM_VERTS_OF_MESH:
1221                         BM_mesh_elem_index_ensure(self->bm, BM_VERT);
1222                         break;
1223                 case BM_EDGES_OF_MESH:
1224                         BM_mesh_elem_index_ensure(self->bm, BM_EDGE);
1225                         break;
1226                 case BM_FACES_OF_MESH:
1227                         BM_mesh_elem_index_ensure(self->bm, BM_FACE);
1228                         break;
1229                 default:
1230                 {
1231                         BMIter iter;
1232                         BMHeader *ele;
1233                         int index = 0;
1234                         const char htype = bm_iter_itype_htype_map[self->itype];
1235
1236                         BM_ITER_BPY_BM_SEQ(ele, &iter, self) {
1237                                 BM_elem_index_set(ele, index); /* set_dirty! */
1238                                 index++;
1239                         }
1240
1241                         if (htype & (BM_VERT | BM_EDGE | BM_FACE)) {
1242                                 /* since this isnt the normal vert/edge/face loops,
1243                                  * we're setting dirty values here. so tag as dirty. */
1244                                 bm->elem_index_dirty |= htype;
1245                         }
1246
1247                         break;
1248                 }
1249         }
1250
1251         Py_RETURN_NONE;
1252 }
1253
1254
1255 static struct PyMethodDef bpy_bmesh_methods[] = {
1256     {"select_flush_mode", (PyCFunction)bpy_bmesh_select_flush_mode, METH_NOARGS, bpy_bmesh_select_flush_mode_doc},
1257     {"select_flush", (PyCFunction)bpy_bmesh_select_flush, METH_O, bpy_bmesh_select_flush_doc},
1258     {"normal_update", (PyCFunction)bpy_bmesh_normal_update, METH_VARARGS, bpy_bmesh_normal_update_doc},
1259     {"transform", (PyCFunction)bpy_bmesh_transform, METH_VARARGS|METH_KEYWORDS, bpy_bmesh_transform_doc},
1260     {NULL, NULL, 0, NULL}
1261 };
1262
1263 static struct PyMethodDef bpy_bmvert_methods[] = {
1264     {"select_set", (PyCFunction)bpy_bm_elem_select_set, METH_O, bpy_bm_elem_select_set_doc},
1265     {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc},
1266
1267     {"calc_vert_angle", (PyCFunction)bpy_bmvert_calc_edge_angle, METH_NOARGS, bpy_bmvert_calc_edge_angle_doc},
1268     {NULL, NULL, 0, NULL}
1269 };
1270
1271 static struct PyMethodDef bpy_bmedge_methods[] = {
1272     {"select_set", (PyCFunction)bpy_bm_elem_select_set, METH_O, bpy_bm_elem_select_set_doc},
1273     {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc},
1274
1275     {"other_vert", (PyCFunction)bpy_bmedge_other_vert, METH_O, bpy_bmedge_other_vert_doc},
1276
1277     {"calc_face_angle", (PyCFunction)bpy_bmedge_calc_face_angle, METH_NOARGS, bpy_bmedge_calc_face_angle_doc},
1278     {NULL, NULL, 0, NULL}
1279 };
1280
1281 static struct PyMethodDef bpy_bmface_methods[] = {
1282     {"select_set", (PyCFunction)bpy_bm_elem_select_set, METH_O, bpy_bm_elem_select_set_doc},
1283     {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc},
1284
1285     {"copy", (PyCFunction)bpy_bmface_copy, METH_VARARGS|METH_KEYWORDS, bpy_bmface_copy_doc},
1286
1287     {"calc_area",          (PyCFunction)bpy_bmface_calc_area,          METH_NOARGS, bpy_bmface_calc_area_doc},
1288     {"calc_center_median", (PyCFunction)bpy_bmface_calc_center_mean,   METH_NOARGS, bpy_bmface_calc_center_mean_doc},
1289     {"calc_center_bounds", (PyCFunction)bpy_bmface_calc_center_bounds, METH_NOARGS, bpy_bmface_calc_center_bounds_doc},
1290     {NULL, NULL, 0, NULL}
1291 };
1292
1293 static struct PyMethodDef bpy_bmloop_methods[] = {
1294     {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc},
1295
1296     {"calc_angle", (PyCFunction)bpy_bmloop_calc_face_angle, METH_NOARGS, bpy_bmloop_calc_face_angle_doc},
1297     {NULL, NULL, 0, NULL}
1298 };
1299
1300 static struct PyMethodDef bpy_bmelemseq_methods[] = {
1301     {"new", (PyCFunction)bpy_bmelemseq_new, METH_VARARGS, bpy_bmelemseq_new_doc},
1302     {"remove", (PyCFunction)bpy_bmelemseq_remove, METH_O, bpy_bmelemseq_remove_doc},
1303
1304     /* odd function, initializes index values */
1305     {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc},
1306     {NULL, NULL, 0, NULL}
1307 };
1308
1309 /* Sequences
1310  * ========= */
1311
1312 static PyTypeObject *bpy_bm_itype_as_pytype(const char itype)
1313 {
1314         /* should cover all types */
1315         switch ((BMIterType)itype) {
1316                 case BM_VERTS_OF_MESH:
1317                 case BM_VERTS_OF_FACE:
1318                 case BM_VERTS_OF_EDGE:
1319                         return &BPy_BMVert_Type;
1320
1321                 case BM_EDGES_OF_MESH:
1322                 case BM_EDGES_OF_FACE:
1323                 case BM_EDGES_OF_VERT:
1324                         return &BPy_BMEdge_Type;
1325
1326                 case BM_FACES_OF_MESH:
1327                 case BM_FACES_OF_EDGE:
1328                 case BM_FACES_OF_VERT:
1329                         return &BPy_BMFace_Type;
1330
1331                 case BM_ALL_LOOPS_OF_FACE:
1332                 case BM_LOOPS_OF_FACE:
1333                 case BM_LOOPS_OF_EDGE:
1334                 case BM_LOOPS_OF_VERT:
1335                 case BM_LOOPS_OF_LOOP:
1336                         return &BPy_BMLoop_Type;
1337         }
1338
1339         return NULL;
1340 }
1341
1342 static Py_ssize_t bpy_bmelemseq_length(BPy_BMElemSeq *self)
1343 {
1344         BPY_BM_CHECK_INT(self);
1345
1346         /* first check if the size is known */
1347         switch ((BMIterType)self->itype) {
1348                 /* main-types */
1349                 case BM_VERTS_OF_MESH:
1350                         return self->bm->totvert;
1351                 case BM_EDGES_OF_MESH:
1352                         return self->bm->totedge;
1353                 case BM_FACES_OF_MESH:
1354                         return self->bm->totface;
1355
1356                         /* sub-types */
1357                 case BM_VERTS_OF_FACE:
1358                 case BM_EDGES_OF_FACE:
1359                 case BM_LOOPS_OF_FACE:
1360                         BPY_BM_CHECK_INT(self->py_ele);
1361                         return ((BMFace *)self->py_ele->ele)->len;
1362
1363                 case BM_VERTS_OF_EDGE:
1364                         return 2;
1365
1366                 default:
1367                         /* quiet compiler */
1368                         break;
1369         }
1370
1371
1372         /* loop over all items, avoid this if we can */
1373         {
1374                 BMIter iter;
1375                 BMHeader *ele;
1376                 Py_ssize_t tot = 0;
1377
1378                 BM_ITER_BPY_BM_SEQ(ele, &iter, self) {
1379                         tot++;
1380                 }
1381                 return tot;
1382         }
1383 }
1384
1385 static PyObject *bpy_bmelemseq_subscript_int(BPy_BMElemSeq *self, int keynum)
1386 {
1387         BPY_BM_CHECK_OBJ(self);
1388
1389         if (keynum < 0) keynum += bpy_bmelemseq_length(self); /* only get length on negative value, may loop entire seq */
1390         if (keynum >= 0) {
1391                 BMHeader *ele = BM_iter_at_index(self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL, keynum);
1392                 if (ele) {
1393                         return BPy_BMElem_CreatePyObject(self->bm, ele);
1394                 }
1395         }
1396
1397         PyErr_Format(PyExc_IndexError,
1398                      "BMElemSeq[index]: index %d out of range", keynum);
1399         return NULL;
1400 }
1401
1402 static PyObject *bpy_bmelemseq_subscript_slice(BPy_BMElemSeq *self, Py_ssize_t start, Py_ssize_t stop)
1403 {
1404         BMIter iter;
1405         int count = 0;
1406         int ok;
1407
1408         PyObject *list;
1409         PyObject *item;
1410         BMHeader *ele;
1411
1412         BPY_BM_CHECK_OBJ(self);
1413
1414         list = PyList_New(0);
1415
1416         ok = BM_iter_init(&iter, self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL);
1417
1418         BLI_assert(ok == TRUE);
1419
1420         if (UNLIKELY(ok == FALSE)) {
1421                 return list;
1422         }
1423
1424         /* first loop up-until the start */
1425         for (ok = TRUE; ok; ok = (BM_iter_step(&iter) != NULL)) {
1426                 /* PointerRNA itemptr = rna_macro_iter.ptr; */
1427                 if (count == start) {
1428                         break;
1429                 }
1430                 count++;
1431         }
1432
1433         /* add items until stop */
1434         while ((ele = BM_iter_step(&iter))) {
1435                 item = BPy_BMElem_CreatePyObject(self->bm, ele);
1436                 PyList_Append(list, item);
1437                 Py_DECREF(item);
1438
1439                 count++;
1440                 if (count == stop) {
1441                         break;
1442                 }
1443         }
1444
1445         return list;
1446 }
1447
1448 static PyObject *bpy_bmelemseq_subscript(BPy_BMElemSeq *self, PyObject *key)
1449 {
1450         /* dont need error check here */
1451         if (PyIndex_Check(key)) {
1452                 Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
1453                 if (i == -1 && PyErr_Occurred())
1454                         return NULL;
1455                 return bpy_bmelemseq_subscript_int(self, i);
1456         }
1457         else if (PySlice_Check(key)) {
1458                 PySliceObject *key_slice = (PySliceObject *)key;
1459                 Py_ssize_t step = 1;
1460
1461                 if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
1462                         return NULL;
1463                 }
1464                 else if (step != 1) {
1465                         PyErr_SetString(PyExc_TypeError, "BMElemSeq[slice]: slice steps not supported");
1466                         return NULL;
1467                 }
1468                 else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
1469                         return bpy_bmelemseq_subscript_slice(self, 0, PY_SSIZE_T_MAX);
1470                 }
1471                 else {
1472                         Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
1473
1474                         /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
1475                         if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
1476                         if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop))    return NULL;
1477
1478                         if (start < 0 || stop < 0) {
1479                                 /* only get the length for negative values */
1480                                 Py_ssize_t len = bpy_bmelemseq_length(self);
1481                                 if (start < 0) start += len;
1482                                 if (stop < 0) start += len;
1483                         }
1484
1485                         if (stop - start <= 0) {
1486                                 return PyList_New(0);
1487                         }
1488                         else {
1489                                 return bpy_bmelemseq_subscript_slice(self, start, stop);
1490                         }
1491                 }
1492         }
1493         else {
1494                 PyErr_SetString(PyExc_AttributeError, "BMElemSeq[key]: invalid key, key must be an int");
1495                 return NULL;
1496         }
1497 }
1498
1499 static int bpy_bmelemseq_contains(BPy_BMElemSeq *self, PyObject *value)
1500 {
1501         BPY_BM_CHECK_INT(self);
1502
1503         if (Py_TYPE(value) == bpy_bm_itype_as_pytype(self->itype)) {
1504                 BPy_BMElem *value_bm_ele = (BPy_BMElem *)value;
1505                 if (value_bm_ele->bm == self->bm) {
1506                         BMHeader *ele, *ele_test = value_bm_ele->ele;
1507                         BMIter iter;
1508                         BM_ITER_BPY_BM_SEQ(ele, &iter, self) {
1509                                 if (ele == ele_test) {
1510                                         return 1;
1511                                 }
1512                         }
1513                 }
1514         }
1515
1516         return 0;
1517 }
1518
1519 static PySequenceMethods bpy_bmelemseq_as_sequence = {
1520     (lenfunc)bpy_bmelemseq_length,                  /* sq_length */
1521     NULL,                                        /* sq_concat */
1522     NULL,                                        /* sq_repeat */
1523     (ssizeargfunc)bpy_bmelemseq_subscript_int,      /* sq_item */ /* Only set this so PySequence_Check() returns True */
1524     NULL,                                        /* sq_slice */
1525     (ssizeobjargproc)NULL,                       /* sq_ass_item */
1526     NULL,                                        /* *was* sq_ass_slice */
1527     (objobjproc)bpy_bmelemseq_contains,             /* sq_contains */
1528     (binaryfunc) NULL,                           /* sq_inplace_concat */
1529     (ssizeargfunc) NULL,                         /* sq_inplace_repeat */
1530 };
1531
1532 static PyMappingMethods bpy_bmelemseq_as_mapping = {
1533     (lenfunc)bpy_bmelemseq_length,                  /* mp_length */
1534     (binaryfunc)bpy_bmelemseq_subscript,            /* mp_subscript */
1535     (objobjargproc)NULL,                         /* mp_ass_subscript */
1536 };
1537
1538 /* Iterator
1539  * -------- */
1540
1541 static PyObject *bpy_bmelemseq_iter(BPy_BMElemSeq *self)
1542 {
1543         BPy_BMIter *py_iter;
1544
1545         BPY_BM_CHECK_OBJ(self);
1546         py_iter = (BPy_BMIter *)BPy_BMIter_CreatePyObject(self->bm);
1547         BM_iter_init(&(py_iter->iter), self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL);
1548         return (PyObject *)py_iter;
1549 }
1550
1551 static PyObject *bpy_bmiter_next(BPy_BMIter *self)
1552 {
1553         BMHeader *ele = BM_iter_step(&self->iter);
1554         if (ele == NULL) {
1555                 PyErr_SetString(PyExc_StopIteration, "bpy_bmiter_next stop");
1556                 return NULL;
1557         }
1558         else {
1559                 return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, ele);
1560         }
1561 }
1562
1563
1564 /* Dealloc Functions
1565  * ================= */
1566
1567 static void bpy_bmesh_dealloc(BPy_BMesh *self)
1568 {
1569         BMesh *bm = self->bm;
1570
1571         BM_data_layer_free(bm, &bm->vdata, CD_BM_ELEM_PYPTR);
1572         BM_data_layer_free(bm, &bm->edata, CD_BM_ELEM_PYPTR);
1573         BM_data_layer_free(bm, &bm->pdata, CD_BM_ELEM_PYPTR);
1574         BM_data_layer_free(bm, &bm->ldata, CD_BM_ELEM_PYPTR);
1575
1576         bm->py_handle = NULL;
1577
1578         PyObject_DEL(self);
1579 }
1580
1581 static void bpy_bmvert_dealloc(BPy_BMElem *self)
1582 {
1583         BMesh *bm = self->bm;
1584         if (bm) {
1585                 void **ptr = CustomData_bmesh_get(&bm->vdata, self->ele->data, CD_BM_ELEM_PYPTR);
1586                 *ptr = NULL;
1587         }
1588         PyObject_DEL(self);
1589 }
1590
1591 static void bpy_bmedge_dealloc(BPy_BMElem *self)
1592 {
1593         BMesh *bm = self->bm;
1594         if (bm) {
1595                 void **ptr = CustomData_bmesh_get(&bm->edata, self->ele->data, CD_BM_ELEM_PYPTR);
1596                 *ptr = NULL;
1597         }
1598         PyObject_DEL(self);
1599 }
1600
1601 static void bpy_bmface_dealloc(BPy_BMElem *self)
1602 {
1603         BMesh *bm = self->bm;
1604         if (bm) {
1605                 void **ptr = CustomData_bmesh_get(&bm->pdata, self->ele->data, CD_BM_ELEM_PYPTR);
1606                 *ptr = NULL;
1607         }
1608         PyObject_DEL(self);
1609 }
1610
1611 static void bpy_bmloop_dealloc(BPy_BMElem *self)
1612 {
1613         BMesh *bm = self->bm;
1614         if (bm) {
1615                 void **ptr = CustomData_bmesh_get(&bm->ldata, self->ele->data, CD_BM_ELEM_PYPTR);
1616                 *ptr = NULL;
1617         }
1618         PyObject_DEL(self);
1619 }
1620
1621 static void bpy_bmelemseq_dealloc(BPy_BMElemSeq *self)
1622 {
1623         Py_XDECREF(self->py_ele);
1624
1625         PyObject_DEL(self);
1626 }
1627
1628 /* not sure where this should go */
1629 static long bpy_bm_elem_hash(PyObject *self)
1630 {
1631         return _Py_HashPointer(((BPy_BMElem *)self)->ele);
1632 }
1633
1634
1635 /* Type Docstrings
1636  * =============== */
1637
1638 PyDoc_STRVAR(bpy_bmesh_doc,
1639 "The BMesh data structure\n"
1640 );
1641 PyDoc_STRVAR(bpy_bmvert_doc,
1642 "The BMesh vertex type\n"
1643 );
1644 PyDoc_STRVAR(bpy_bmedge_doc,
1645 "The BMesh edge connecting 2 verts\n"
1646 );
1647 PyDoc_STRVAR(bpy_bmface_doc,
1648 "The BMesh face with 3 or more sides\n"
1649 );
1650 PyDoc_STRVAR(bpy_bmloop_doc,
1651 "This is normally accessed from :class:`BMFace.loops` where each face corner represents a corner of a face.\n"
1652 );
1653 PyDoc_STRVAR(bpy_bmelemseq_doc,
1654 "General sequence type used for accessing any sequence of \n"
1655 ":class:`BMVert`, :class:`BMEdge`, :class:`BMFace`, :class:`BMLoop`.\n"
1656 "\n"
1657 "When accessed via :class:`BMesh.verts`, :class:`BMesh.edges`, :class:`BMesh.faces` \n"
1658 "there are also functions to create/remomove items.\n"
1659 );
1660 PyDoc_STRVAR(bpy_bmiter_doc,
1661 "Internal BMesh type for looping over verts/faces/edges,\n"
1662 "used for iterating over :class:`BMElemSeq` types.\n"
1663 );
1664
1665 /* Types
1666  * ===== */
1667
1668 PyTypeObject BPy_BMesh_Type     = {{{0}}};
1669 PyTypeObject BPy_BMVert_Type    = {{{0}}};
1670 PyTypeObject BPy_BMEdge_Type    = {{{0}}};
1671 PyTypeObject BPy_BMFace_Type    = {{{0}}};
1672 PyTypeObject BPy_BMLoop_Type    = {{{0}}};
1673 PyTypeObject BPy_BMElemSeq_Type = {{{0}}};
1674 PyTypeObject BPy_BMIter_Type    = {{{0}}};
1675
1676
1677
1678 void BPy_BM_init_types(void)
1679 {
1680         BPy_BMesh_Type.tp_basicsize     = sizeof(BPy_BMesh);
1681         BPy_BMVert_Type.tp_basicsize    = sizeof(BPy_BMVert);
1682         BPy_BMEdge_Type.tp_basicsize    = sizeof(BPy_BMEdge);
1683         BPy_BMFace_Type.tp_basicsize    = sizeof(BPy_BMFace);
1684         BPy_BMLoop_Type.tp_basicsize    = sizeof(BPy_BMLoop);
1685         BPy_BMElemSeq_Type.tp_basicsize = sizeof(BPy_BMElemSeq);
1686         BPy_BMIter_Type.tp_basicsize    = sizeof(BPy_BMIter);
1687
1688
1689         BPy_BMesh_Type.tp_name     = "BMesh";
1690         BPy_BMVert_Type.tp_name    = "BMVert";
1691         BPy_BMEdge_Type.tp_name    = "BMEdge";
1692         BPy_BMFace_Type.tp_name    = "BMFace";
1693         BPy_BMLoop_Type.tp_name    = "BMLoop";
1694         BPy_BMElemSeq_Type.tp_name = "BMElemSeq";
1695         BPy_BMIter_Type.tp_name    = "BMIter";
1696
1697
1698         BPy_BMesh_Type.tp_doc     = bpy_bmesh_doc;
1699         BPy_BMVert_Type.tp_doc    = bpy_bmvert_doc;
1700         BPy_BMEdge_Type.tp_doc    = bpy_bmedge_doc;
1701         BPy_BMFace_Type.tp_doc    = bpy_bmface_doc;
1702         BPy_BMLoop_Type.tp_doc    = bpy_bmloop_doc;
1703         BPy_BMElemSeq_Type.tp_doc = bpy_bmelemseq_doc;
1704         BPy_BMIter_Type.tp_doc    = bpy_bmiter_doc;
1705
1706
1707         BPy_BMesh_Type.tp_getset     = bpy_bmesh_getseters;
1708         BPy_BMVert_Type.tp_getset    = bpy_bmvert_getseters;
1709         BPy_BMEdge_Type.tp_getset    = bpy_bmedge_getseters;
1710         BPy_BMFace_Type.tp_getset    = bpy_bmface_getseters;
1711         BPy_BMLoop_Type.tp_getset    = bpy_bmloop_getseters;
1712         BPy_BMElemSeq_Type.tp_getset = NULL;
1713         BPy_BMIter_Type.tp_getset    = NULL;
1714
1715
1716         BPy_BMesh_Type.tp_methods     = bpy_bmesh_methods;
1717         BPy_BMVert_Type.tp_methods    = bpy_bmvert_methods;
1718         BPy_BMEdge_Type.tp_methods    = bpy_bmedge_methods;
1719         BPy_BMFace_Type.tp_methods    = bpy_bmface_methods;
1720         BPy_BMLoop_Type.tp_methods    = bpy_bmloop_methods;
1721         BPy_BMElemSeq_Type.tp_methods = bpy_bmelemseq_methods;
1722         BPy_BMIter_Type.tp_methods    = NULL;
1723
1724
1725         BPy_BMesh_Type.tp_hash     = NULL;
1726         BPy_BMVert_Type.tp_hash    = bpy_bm_elem_hash;
1727         BPy_BMEdge_Type.tp_hash    = bpy_bm_elem_hash;
1728         BPy_BMFace_Type.tp_hash    = bpy_bm_elem_hash;
1729         BPy_BMLoop_Type.tp_hash    = bpy_bm_elem_hash;
1730         BPy_BMElemSeq_Type.tp_hash = NULL;
1731         BPy_BMIter_Type.tp_hash    = NULL;
1732
1733         BPy_BMElemSeq_Type.tp_as_sequence = &bpy_bmelemseq_as_sequence;
1734
1735         BPy_BMElemSeq_Type.tp_as_mapping = &bpy_bmelemseq_as_mapping;
1736
1737         BPy_BMElemSeq_Type.tp_iter = (getiterfunc)bpy_bmelemseq_iter;
1738
1739         /* only 1 iteratir so far */
1740         BPy_BMIter_Type.tp_iternext = (iternextfunc)bpy_bmiter_next;
1741
1742         BPy_BMesh_Type.tp_dealloc     = (destructor)bpy_bmesh_dealloc;
1743         BPy_BMVert_Type.tp_dealloc    = (destructor)bpy_bmvert_dealloc;
1744         BPy_BMEdge_Type.tp_dealloc    = (destructor)bpy_bmedge_dealloc;
1745         BPy_BMFace_Type.tp_dealloc    = (destructor)bpy_bmface_dealloc;
1746         BPy_BMLoop_Type.tp_dealloc    = (destructor)bpy_bmloop_dealloc;
1747         BPy_BMElemSeq_Type.tp_dealloc = (destructor)bpy_bmelemseq_dealloc;
1748         BPy_BMIter_Type.tp_dealloc    = NULL;
1749
1750         /*
1751         BPy_BMesh_Type.
1752         BPy_BMVert_Type.
1753         BPy_BMEdge_Type.
1754         BPy_BMFace_Type.
1755         BPy_BMLoop_Type.
1756         BPy_BMElemSeq_Type.
1757         BPy_BMIter_Type.
1758         */
1759
1760         BPy_BMesh_Type.tp_flags     = Py_TPFLAGS_DEFAULT;
1761         BPy_BMVert_Type.tp_flags    = Py_TPFLAGS_DEFAULT;
1762         BPy_BMEdge_Type.tp_flags    = Py_TPFLAGS_DEFAULT;
1763         BPy_BMFace_Type.tp_flags    = Py_TPFLAGS_DEFAULT;
1764         BPy_BMLoop_Type.tp_flags    = Py_TPFLAGS_DEFAULT;
1765         BPy_BMElemSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
1766         BPy_BMIter_Type.tp_flags    = Py_TPFLAGS_DEFAULT;
1767
1768
1769         PyType_Ready(&BPy_BMesh_Type);
1770         PyType_Ready(&BPy_BMVert_Type);
1771         PyType_Ready(&BPy_BMEdge_Type);
1772         PyType_Ready(&BPy_BMFace_Type);
1773         PyType_Ready(&BPy_BMLoop_Type);
1774         PyType_Ready(&BPy_BMElemSeq_Type);
1775         PyType_Ready(&BPy_BMIter_Type);
1776 }
1777
1778 /* bmesh.types submodule
1779  * ********************* */
1780
1781 static struct PyModuleDef BPy_BM_types_module_def = {
1782     PyModuleDef_HEAD_INIT,
1783     "bmesh.types",  /* m_name */
1784     NULL,  /* m_doc */
1785     0,  /* m_size */
1786     NULL,  /* m_methods */
1787     NULL,  /* m_reload */
1788     NULL,  /* m_traverse */
1789     NULL,  /* m_clear */
1790     NULL,  /* m_free */
1791 };
1792
1793 PyObject *BPyInit_bmesh_types(void)
1794 {
1795         PyObject *submodule;
1796
1797         submodule = PyModule_Create(&BPy_BM_types_module_def);
1798
1799 #define mod_type_add(s, t) \
1800         PyModule_AddObject(s, t.tp_name, (PyObject *)&t); Py_INCREF((PyObject *)&t)
1801
1802         mod_type_add(submodule, BPy_BMesh_Type);
1803         mod_type_add(submodule, BPy_BMVert_Type);
1804         mod_type_add(submodule, BPy_BMEdge_Type);
1805         mod_type_add(submodule, BPy_BMFace_Type);
1806         mod_type_add(submodule, BPy_BMLoop_Type);
1807         mod_type_add(submodule, BPy_BMElemSeq_Type);
1808         mod_type_add(submodule, BPy_BMIter_Type);
1809
1810 #undef mod_type_add
1811
1812         return submodule;
1813 }
1814
1815 /* Utility Functions
1816  * ***************** */
1817
1818 PyObject *BPy_BMesh_CreatePyObject(BMesh *bm)
1819 {
1820         BPy_BMesh *self;
1821
1822         if (bm->py_handle) {
1823                 self = bm->py_handle;
1824                 Py_INCREF(self);
1825         }
1826         else {
1827                 self = PyObject_New(BPy_BMesh, &BPy_BMesh_Type);
1828                 self->bm = bm;
1829
1830                 BM_data_layer_add(bm, &bm->vdata, CD_BM_ELEM_PYPTR);
1831                 BM_data_layer_add(bm, &bm->edata, CD_BM_ELEM_PYPTR);
1832                 BM_data_layer_add(bm, &bm->pdata, CD_BM_ELEM_PYPTR);
1833                 BM_data_layer_add(bm, &bm->ldata, CD_BM_ELEM_PYPTR);
1834         }
1835
1836         return (PyObject *)self;
1837 }
1838
1839
1840
1841 PyObject *BPy_BMVert_CreatePyObject(BMesh *bm, BMVert *v)
1842 {
1843         BPy_BMVert *self;
1844
1845         void **ptr = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_BM_ELEM_PYPTR);
1846
1847         /* bmesh may free layers, ensure we have one to store ourself */
1848         if (UNLIKELY(ptr == NULL)) {
1849                 BM_data_layer_add(bm, &bm->vdata, CD_BM_ELEM_PYPTR);
1850                 ptr = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_BM_ELEM_PYPTR);
1851         }
1852
1853         if (*ptr != NULL) {
1854                 self = *ptr;
1855                 Py_INCREF(self);
1856         }
1857         else {
1858                 self = PyObject_New(BPy_BMVert, &BPy_BMVert_Type);
1859                 BLI_assert(v != NULL);
1860                 self->bm = bm;
1861                 self->v  = v;
1862                 *ptr = self;
1863         }
1864         return (PyObject *)self;
1865 }
1866
1867 PyObject *BPy_BMEdge_CreatePyObject(BMesh *bm, BMEdge *e)
1868 {
1869         BPy_BMEdge *self;
1870
1871         void **ptr = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BM_ELEM_PYPTR);
1872
1873         /* bmesh may free layers, ensure we have one to store ourself */
1874         if (UNLIKELY(ptr == NULL)) {
1875                 BM_data_layer_add(bm, &bm->edata, CD_BM_ELEM_PYPTR);
1876                 ptr = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BM_ELEM_PYPTR);
1877         }
1878
1879         if (*ptr != NULL) {
1880                 self = *ptr;
1881                 Py_INCREF(self);
1882         }
1883         else {
1884                 self = PyObject_New(BPy_BMEdge, &BPy_BMEdge_Type);
1885                 BLI_assert(e != NULL);
1886                 self->bm = bm;
1887                 self->e  = e;
1888                 *ptr = self;
1889         }
1890         return (PyObject *)self;
1891 }
1892
1893 PyObject *BPy_BMFace_CreatePyObject(BMesh *bm, BMFace *f)
1894 {
1895         BPy_BMFace *self;
1896
1897         void **ptr = CustomData_bmesh_get(&bm->pdata, f->head.data, CD_BM_ELEM_PYPTR);
1898
1899         /* bmesh may free layers, ensure we have one to store ourself */
1900         if (UNLIKELY(ptr == NULL)) {
1901                 BM_data_layer_add(bm, &bm->pdata, CD_BM_ELEM_PYPTR);
1902                 ptr = CustomData_bmesh_get(&bm->pdata, f->head.data, CD_BM_ELEM_PYPTR);
1903         }
1904
1905         if (*ptr != NULL) {
1906                 self = *ptr;
1907                 Py_INCREF(self);
1908         }
1909         else {
1910                 self = PyObject_New(BPy_BMFace, &BPy_BMFace_Type);
1911                 BLI_assert(f != NULL);
1912                 self->bm = bm;
1913                 self->f  = f;
1914                 *ptr = self;
1915         }
1916         return (PyObject *)self;
1917 }
1918
1919 PyObject *BPy_BMLoop_CreatePyObject(BMesh *bm, BMLoop *l)
1920 {
1921         BPy_BMLoop *self;
1922
1923         void **ptr = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_BM_ELEM_PYPTR);
1924
1925         /* bmesh may free layers, ensure we have one to store ourself */
1926         if (UNLIKELY(ptr == NULL)) {
1927                 BM_data_layer_add(bm, &bm->ldata, CD_BM_ELEM_PYPTR);
1928                 ptr = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_BM_ELEM_PYPTR);
1929         }
1930
1931         if (*ptr != NULL) {
1932                 self = *ptr;
1933                 Py_INCREF(self);
1934         }
1935         else {
1936                 self = PyObject_New(BPy_BMLoop, &BPy_BMLoop_Type);
1937                 BLI_assert(l != NULL);
1938                 self->bm = bm;
1939                 self->l  = l;
1940                 *ptr = self;
1941         }
1942         return (PyObject *)self;
1943 }
1944
1945 PyObject *BPy_BMElemSeq_CreatePyObject(BMesh *bm, BPy_BMElem *py_ele, const char itype)
1946 {
1947         BPy_BMElemSeq *self = PyObject_New(BPy_BMElemSeq, &BPy_BMElemSeq_Type);
1948         self->bm = bm;
1949         self->py_ele = py_ele; /* can be NULL */
1950         self->itype = itype;
1951         Py_XINCREF(py_ele);
1952         return (PyObject *)self;
1953 }
1954
1955 PyObject *BPy_BMIter_CreatePyObject(BMesh *bm)
1956 {
1957         BPy_BMIter *self = PyObject_New(BPy_BMIter, &BPy_BMIter_Type);
1958         self->bm = bm;
1959         /* caller must initialize 'iter' member */
1960         return (PyObject *)self;
1961 }
1962
1963 /* this is just a helper func */
1964 PyObject *BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele)
1965 {
1966         switch (ele->htype) {
1967                 case BM_VERT:
1968                         return BPy_BMVert_CreatePyObject(bm, (BMVert *)ele);
1969                 case BM_EDGE:
1970                         return BPy_BMEdge_CreatePyObject(bm, (BMEdge *)ele);
1971                 case BM_FACE:
1972                         return BPy_BMFace_CreatePyObject(bm, (BMFace *)ele);
1973                 case BM_LOOP:
1974                         return BPy_BMLoop_CreatePyObject(bm, (BMLoop *)ele);
1975                 default:
1976                         PyErr_SetString(PyExc_SystemError, "internal error");
1977                         return NULL;
1978         }
1979 }
1980
1981 int bpy_bm_generic_valid_check(BPy_BMGeneric *self)
1982 {
1983         if (self->bm) {
1984                 return 0;
1985         }
1986         PyErr_Format(PyExc_ReferenceError,
1987                      "BMesh data of type %.200s has been removed",
1988                      Py_TYPE(self)->tp_name);
1989         return -1;
1990 }
1991
1992 void bpy_bm_generic_invalidate(BPy_BMGeneric *self)
1993 {
1994         self->bm = NULL;
1995 }
1996
1997 /* generic python seq as BMVert/Edge/Face array,
1998  * return value must be freed with PyMem_FREE(...);
1999  *
2000  * The 'bm_r' value is assigned when empty, and used when set.
2001  */
2002 void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, Py_ssize_t *r_size,
2003                                 PyTypeObject *type,
2004                                 const char do_unique_check, const char do_bm_check,
2005                                 const char *error_prefix)
2006 {
2007         BMesh *bm = (r_bm && *r_bm) ? *r_bm : NULL;
2008         PyObject *seq_fast;
2009         *r_size = 0;
2010
2011         if (!(seq_fast=PySequence_Fast(seq, error_prefix))) {
2012                 return NULL;
2013         }
2014         else {
2015                 Py_ssize_t seq_len;
2016                 Py_ssize_t i;
2017
2018                 BPy_BMElem *item;
2019                 BMHeader **alloc;
2020
2021                 seq_len = PySequence_Fast_GET_SIZE(seq_fast);
2022
2023                 if (seq_len < min || seq_len > max) {
2024                         PyErr_Format(PyExc_TypeError,
2025                                      "%s: sequence incorrect size, expected [%d - %d], given %d",
2026                                      error_prefix, min, max, seq_len);
2027                         return NULL;
2028                 }
2029
2030
2031                 /* from now on, use goto */
2032                 alloc = PyMem_MALLOC(seq_len * sizeof(BPy_BMElem **));
2033
2034                 for (i = 0; i < seq_len; i++) {
2035                         item = (BPy_BMElem *)PySequence_Fast_GET_ITEM(seq_fast, i);
2036
2037                         if (Py_TYPE(item) != type) {
2038                                 PyErr_Format(PyExc_TypeError,
2039                                              "%s: expected '%.200', not '%.200s'",
2040                                              error_prefix, type->tp_name, Py_TYPE(item)->tp_name);
2041                                 goto err_cleanup;
2042                         }
2043                         else if (item->bm == NULL) {
2044                                 PyErr_Format(PyExc_TypeError,
2045                                              "%s: %d %s has been removed",
2046                                              error_prefix, i, type->tp_name);
2047                                 goto err_cleanup;
2048                         }
2049                         /* trick so we can ensure all items have the same mesh,
2050                          * and allows us to pass the 'bm' as NULL. */
2051                         else if (do_bm_check && (bm  && bm != item->bm)) {
2052                                 PyErr_Format(PyExc_TypeError,
2053                                              "%s: %d %s is from another mesh",
2054                                              error_prefix, i, type->tp_name);
2055                                 goto err_cleanup;
2056                         }
2057
2058                         if (bm == NULL) {
2059                                 bm = item->bm;
2060                         }
2061
2062                         alloc[i] = item->ele;
2063
2064                         if (do_unique_check) {
2065                                 BM_elem_flag_enable(item->ele, BM_ELEM_TAG);
2066                         }
2067                 }
2068
2069                 if (do_unique_check) {
2070                         /* check for double verts! */
2071                         int ok = TRUE;
2072                         for (i = 0; i < seq_len; i++) {
2073                                 if (UNLIKELY(BM_elem_flag_test(alloc[i], BM_ELEM_TAG) == FALSE)) {
2074                                         ok = FALSE;
2075                                 }
2076
2077                                 /* ensure we dont leave this enabled */
2078                                 BM_elem_flag_disable(alloc[i], BM_ELEM_TAG);
2079                         }
2080
2081                         if (ok == FALSE) {
2082                                 PyErr_Format(PyExc_ValueError,
2083                                              "%s: found the same %s used multiple times",
2084                                              error_prefix, type->tp_name);
2085                                 goto err_cleanup;
2086                         }
2087                 }
2088
2089                 Py_DECREF(seq_fast);
2090                 *r_size = seq_len;
2091                 if (r_bm) *r_bm = bm;
2092                 return alloc;
2093
2094 err_cleanup:
2095                 Py_DECREF(seq_fast);
2096                 PyMem_FREE(alloc);
2097                 return NULL;
2098         }
2099 }