~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/python/bmesh/bmesh_py_types.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

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