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