Blender  V2.93
bmesh_py_api.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2012 Blender Foundation.
17  * All rights reserved.
18  */
19 
26 #include <Python.h>
27 
28 #include "BLI_utildefines.h"
29 
30 #include "bmesh.h"
31 
32 #include "bmesh_py_types.h"
35 #include "bmesh_py_types_select.h"
36 
37 #include "bmesh_py_geometry.h"
38 #include "bmesh_py_ops.h"
39 #include "bmesh_py_utils.h"
40 
41 #include "BKE_editmesh.h"
42 
43 #include "DNA_mesh_types.h"
44 
45 #include "../generic/py_capi_utils.h"
46 
47 #include "bmesh_py_api.h" /* own include */
48 
49 PyDoc_STRVAR(bpy_bm_new_doc,
50  ".. method:: new(use_operators=True)\n"
51  "\n"
52  " :arg use_operators: Support calling operators in :mod:`bmesh.ops` (uses some "
53  "extra memory per vert/edge/face).\n"
54  " :type use_operators: bool\n"
55  " :return: Return a new, empty BMesh.\n"
56  " :rtype: :class:`bmesh.types.BMesh`\n");
57 
58 static PyObject *bpy_bm_new(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
59 {
60  static const char *kwlist[] = {"use_operators", NULL};
61  BMesh *bm;
62 
63  bool use_operators = true;
64 
65  if (!PyArg_ParseTupleAndKeywords(
66  args, kw, "|$O&:new", (char **)kwlist, PyC_ParseBool, &use_operators)) {
67  return NULL;
68  }
69 
71  &((struct BMeshCreateParams){
72  .use_toolflags = use_operators,
73  }));
74 
76 }
77 
78 PyDoc_STRVAR(bpy_bm_from_edit_mesh_doc,
79  ".. method:: from_edit_mesh(mesh)\n"
80  "\n"
81  " Return a BMesh from this mesh, currently the mesh must already be in editmode.\n"
82  "\n"
83  " :arg mesh: The editmode mesh.\n"
84  " :type mesh: :class:`bpy.types.Mesh`\n"
85  " :return: the BMesh associated with this mesh.\n"
86  " :rtype: :class:`bmesh.types.BMesh`\n");
87 static PyObject *bpy_bm_from_edit_mesh(PyObject *UNUSED(self), PyObject *value)
88 {
89  BMesh *bm;
90  Mesh *me = PyC_RNA_AsPointer(value, "Mesh");
91 
92  if (me == NULL) {
93  return NULL;
94  }
95 
96  if (me->edit_mesh == NULL) {
97  PyErr_SetString(PyExc_ValueError, "The mesh must be in editmode");
98  return NULL;
99  }
100 
101  bm = me->edit_mesh->bm;
102 
104 }
105 
106 PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc,
107  ".. method:: update_edit_mesh(mesh, loop_triangles=True, destructive=True)\n"
108  "\n"
109  " Update the mesh after changes to the BMesh in editmode,\n"
110  " optionally recalculating n-gon tessellation.\n"
111  "\n"
112  " :arg mesh: The editmode mesh.\n"
113  " :type mesh: :class:`bpy.types.Mesh`\n"
114  " :arg loop_triangles: Option to recalculate n-gon tessellation.\n"
115  " :type loop_triangles: boolean\n"
116  " :arg destructive: Use when geometry has been added or removed.\n"
117  " :type destructive: boolean\n");
118 static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
119 {
120  static const char *kwlist[] = {"mesh", "loop_triangles", "destructive", NULL};
121  PyObject *py_me;
122  Mesh *me;
123  bool do_loop_triangles = true;
124  bool is_destructive = true;
125 
126  if (!PyArg_ParseTupleAndKeywords(args,
127  kw,
128  "O|O&O&:update_edit_mesh",
129  (char **)kwlist,
130  &py_me,
132  &do_loop_triangles,
134  &is_destructive)) {
135  return NULL;
136  }
137 
138  me = PyC_RNA_AsPointer(py_me, "Mesh");
139 
140  if (me == NULL) {
141  return NULL;
142  }
143 
144  if (me->edit_mesh == NULL) {
145  PyErr_SetString(PyExc_ValueError, "The mesh must be in editmode");
146  return NULL;
147  }
148 
149  {
150  extern void EDBM_update_generic(
151  struct Mesh * me, const bool do_tessface, const bool is_destructive);
152 
153  EDBM_update_generic(me, do_loop_triangles, is_destructive);
154  }
155 
156  Py_RETURN_NONE;
157 }
158 
159 static struct PyMethodDef BPy_BM_methods[] = {
160  {"new", (PyCFunction)bpy_bm_new, METH_VARARGS | METH_KEYWORDS, bpy_bm_new_doc},
161  {"from_edit_mesh", (PyCFunction)bpy_bm_from_edit_mesh, METH_O, bpy_bm_from_edit_mesh_doc},
162  {"update_edit_mesh",
163  (PyCFunction)bpy_bm_update_edit_mesh,
164  METH_VARARGS | METH_KEYWORDS,
165  bpy_bm_update_edit_mesh_doc},
166  {NULL, NULL, 0, NULL},
167 };
168 
169 PyDoc_STRVAR(BPy_BM_doc,
170  "This module provides access to blenders bmesh data structures.\n"
171  "\n"
172  ".. include:: include__bmesh.rst\n");
173 static struct PyModuleDef BPy_BM_module_def = {
174  PyModuleDef_HEAD_INIT,
175  "bmesh", /* m_name */
176  BPy_BM_doc, /* m_doc */
177  0, /* m_size */
178  BPy_BM_methods, /* m_methods */
179  NULL, /* m_reload */
180  NULL, /* m_traverse */
181  NULL, /* m_clear */
182  NULL, /* m_free */
183 };
184 
185 PyObject *BPyInit_bmesh(void)
186 {
187  PyObject *mod;
188  PyObject *submodule;
189  PyObject *sys_modules = PyImport_GetModuleDict();
190 
195 
196  mod = PyModule_Create(&BPy_BM_module_def);
197 
198  /* bmesh.types */
199  PyModule_AddObject(mod, "types", (submodule = BPyInit_bmesh_types()));
200  PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
201 
202  /* bmesh.ops (not a real module, exposes module like access). */
203  PyModule_AddObject(mod, "ops", (submodule = BPyInit_bmesh_ops()));
204  PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
205 
206  PyModule_AddObject(mod, "utils", (submodule = BPyInit_bmesh_utils()));
207  PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
208 
209  PyModule_AddObject(mod, "geometry", (submodule = BPyInit_bmesh_geometry()));
210  PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
211 
212  return mod;
213 }
#define UNUSED(x)
void EDBM_update_generic(struct Mesh *me, const bool do_tessellation, const bool is_destructive)
ATTR_WARN_UNUSED_RESULT BMesh * bm
const BMAllocTemplate bm_mesh_allocsize_default
Definition: bmesh_mesh.c:46
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreateParams *params)
BMesh Make Mesh.
Definition: bmesh_mesh.c:157
static PyObject * bpy_bm_from_edit_mesh(PyObject *UNUSED(self), PyObject *value)
Definition: bmesh_py_api.c:87
PyDoc_STRVAR(bpy_bm_new_doc, ".. method:: new(use_operators=True)\n" "\n" " :arg use_operators: Support calling operators in :mod:`bmesh.ops` (uses some " "extra memory per vert/edge/face).\n" " :type use_operators: bool\n" " :return: Return a new, empty BMesh.\n" " :rtype: :class:`bmesh.types.BMesh`\n")
static struct PyMethodDef BPy_BM_methods[]
Definition: bmesh_py_api.c:159
static struct PyModuleDef BPy_BM_module_def
Definition: bmesh_py_api.c:173
PyObject * BPyInit_bmesh(void)
Definition: bmesh_py_api.c:185
static PyObject * bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
Definition: bmesh_py_api.c:118
static PyObject * bpy_bm_new(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
Definition: bmesh_py_api.c:58
PyObject * BPyInit_bmesh_geometry(void)
PyObject * BPyInit_bmesh_ops(void)
Definition: bmesh_py_ops.c:292
PyObject * BPyInit_bmesh_types(void)
void BPy_BM_init_types(void)
PyObject * BPy_BMesh_CreatePyObject(BMesh *bm, int flag)
@ BPY_BMFLAG_IS_WRAPPED
@ BPY_BMFLAG_NOP
void BPy_BM_init_types_customdata(void)
void BPy_BM_init_types_meshdata(void)
void BPy_BM_init_types_select(void)
PyObject * BPyInit_bmesh_utils(void)
void * PyC_RNA_AsPointer(PyObject *value, const char *type_name)
int PyC_ParseBool(PyObject *o, void *p)
struct BMesh * bm
Definition: BKE_editmesh.h:52
struct BMEditMesh * edit_mesh
ccl_device_inline int mod(int x, int m)
Definition: util_math.h:405