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