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