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