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