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