Blender V5.0
bmesh_py_api.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2012 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include <Python.h>
12
13#include "bmesh.hh"
14
15#include "bmesh_py_types.hh"
19
20#include "bmesh_py_geometry.hh"
21#include "bmesh_py_ops.hh"
22#include "bmesh_py_utils.hh"
23
24#include "BKE_editmesh.hh"
25#include "BKE_mesh_types.hh"
26
27#include "DNA_mesh_types.h"
28#include "DNA_scene_types.h"
29
31
32#include "bmesh_py_api.hh" /* own include */
33
35 /* Wrap. */
36 bpy_bm_new_doc,
37 ".. method:: new(*, use_operators=True)\n"
38 "\n"
39 " :arg use_operators: Support calling operators in :mod:`bmesh.ops` (uses some "
40 "extra memory per vert/edge/face).\n"
41 " :type use_operators: bool\n"
42 " :return: Return a new, empty BMesh.\n"
43 " :rtype: :class:`bmesh.types.BMesh`\n");
44static PyObject *bpy_bm_new(PyObject * /*self*/, PyObject *args, PyObject *kw)
45{
46 static const char *kwlist[] = {"use_operators", nullptr};
47 BMesh *bm;
48
49 bool use_operators = true;
50
51 if (!PyArg_ParseTupleAndKeywords(
52 args, kw, "|$O&:new", (char **)kwlist, PyC_ParseBool, &use_operators))
53 {
54 return nullptr;
55 }
56
58 params.use_toolflags = use_operators;
60 bm->selectmode = SCE_SELECT_VERTEX;
61
63}
64
66 /* Wrap. */
67 bpy_bm_from_edit_mesh_doc,
68 ".. method:: from_edit_mesh(mesh)\n"
69 "\n"
70 " Return a BMesh from this mesh, currently the mesh must already be in editmode.\n"
71 "\n"
72 " :arg mesh: The editmode mesh.\n"
73 " :type mesh: :class:`bpy.types.Mesh`\n"
74 " :return: the BMesh associated with this mesh.\n"
75 " :rtype: :class:`bmesh.types.BMesh`\n");
76static PyObject *bpy_bm_from_edit_mesh(PyObject * /*self*/, PyObject *value)
77{
78 BMesh *bm;
79 Mesh *mesh = static_cast<Mesh *>(PyC_RNA_AsPointer(value, "Mesh"));
80
81 if (mesh == nullptr) {
82 return nullptr;
83 }
84
85 if (mesh->runtime->edit_mesh == nullptr) {
86 PyErr_SetString(PyExc_ValueError, "The mesh must be in editmode");
87 return nullptr;
88 }
89
90 bm = mesh->runtime->edit_mesh->bm;
91
93}
94
95void EDBM_update_extern(Mesh *mesh, const bool do_tessface, const bool is_destructive);
96
98 /* Wrap. */
99 bpy_bm_update_edit_mesh_doc,
100 ".. method:: update_edit_mesh(mesh, *, loop_triangles=True, destructive=True)\n"
101 "\n"
102 " Update the mesh after changes to the BMesh in editmode,\n"
103 " optionally recalculating n-gon tessellation.\n"
104 "\n"
105 " :arg mesh: The editmode mesh.\n"
106 " :type mesh: :class:`bpy.types.Mesh`\n"
107 " :arg loop_triangles: Option to recalculate n-gon tessellation.\n"
108 " :type loop_triangles: bool\n"
109 " :arg destructive: Use when geometry has been added or removed.\n"
110 " :type destructive: bool\n");
111static PyObject *bpy_bm_update_edit_mesh(PyObject * /*self*/, PyObject *args, PyObject *kw)
112{
113 static const char *kwlist[] = {"mesh", "loop_triangles", "destructive", nullptr};
114 PyObject *py_me;
115 Mesh *mesh;
116 bool do_loop_triangles = true;
117 bool is_destructive = true;
118
119 if (!PyArg_ParseTupleAndKeywords(args,
120 kw,
121 "O|$O&O&:update_edit_mesh",
122 (char **)kwlist,
123 &py_me,
125 &do_loop_triangles,
127 &is_destructive))
128 {
129 return nullptr;
130 }
131
132 mesh = static_cast<Mesh *>(PyC_RNA_AsPointer(py_me, "Mesh"));
133
134 if (mesh == nullptr) {
135 return nullptr;
136 }
137
138 if (mesh->runtime->edit_mesh == nullptr) {
139 PyErr_SetString(PyExc_ValueError, "The mesh must be in editmode");
140 return nullptr;
141 }
142
143 {
144 EDBM_update_extern(mesh, do_loop_triangles, is_destructive);
145 }
146
147 Py_RETURN_NONE;
148}
149
150#ifdef __GNUC__
151# ifdef __clang__
152# pragma clang diagnostic push
153# pragma clang diagnostic ignored "-Wcast-function-type"
154# else
155# pragma GCC diagnostic push
156# pragma GCC diagnostic ignored "-Wcast-function-type"
157# endif
158#endif
159
160static PyMethodDef BPy_BM_methods[] = {
161 {"new", (PyCFunction)bpy_bm_new, METH_VARARGS | METH_KEYWORDS, bpy_bm_new_doc},
162 {"from_edit_mesh", (PyCFunction)bpy_bm_from_edit_mesh, METH_O, bpy_bm_from_edit_mesh_doc},
163 {"update_edit_mesh",
164 (PyCFunction)bpy_bm_update_edit_mesh,
165 METH_VARARGS | METH_KEYWORDS,
166 bpy_bm_update_edit_mesh_doc},
167 {nullptr, nullptr, 0, nullptr},
168};
169
170#ifdef __GNUC__
171# ifdef __clang__
172# pragma clang diagnostic pop
173# else
174# pragma GCC diagnostic pop
175# endif
176#endif
177
179 /* Wrap. */
180 BPy_BM_doc,
181 "This module provides access to blenders bmesh data structures.\n"
182 "\n"
183 ".. include:: include__bmesh.rst\n");
184static PyModuleDef BPy_BM_module_def = {
185 /*m_base*/ PyModuleDef_HEAD_INIT,
186 /*m_name*/ "bmesh",
187 /*m_doc*/ BPy_BM_doc,
188 /*m_size*/ 0,
189 /*m_methods*/ BPy_BM_methods,
190 /*m_slots*/ nullptr,
191 /*m_traverse*/ nullptr,
192 /*m_clear*/ nullptr,
193 /*m_free*/ nullptr,
194};
195
196PyObject *BPyInit_bmesh()
197{
198 PyObject *mod;
199 PyObject *submodule;
200 PyObject *sys_modules = PyImport_GetModuleDict();
201
206
207 mod = PyModule_Create(&BPy_BM_module_def);
208
209 /* bmesh.types */
210 PyModule_AddObject(mod, "types", (submodule = BPyInit_bmesh_types()));
211 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
212
213 /* bmesh.ops (not a real module, exposes module like access). */
214 PyModule_AddObject(mod, "ops", (submodule = BPyInit_bmesh_ops()));
215 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
216
217 PyModule_AddObject(mod, "utils", (submodule = BPyInit_bmesh_utils()));
218 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
219
220 PyModule_AddObject(mod, "geometry", (submodule = BPyInit_bmesh_geometry()));
221 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
222
223 return mod;
224}
@ SCE_SELECT_VERTEX
BMesh * bm
const BMAllocTemplate bm_mesh_allocsize_default
Definition bmesh_mesh.cc:30
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const BMeshCreateParams *params)
BMesh Make Mesh.
static PyObject * bpy_bm_from_edit_mesh(PyObject *, PyObject *value)
static PyMethodDef BPy_BM_methods[]
static PyObject * bpy_bm_update_edit_mesh(PyObject *, PyObject *args, PyObject *kw)
static PyObject * bpy_bm_new(PyObject *, PyObject *args, PyObject *kw)
static PyModuleDef BPy_BM_module_def
PyObject * BPyInit_bmesh()
void EDBM_update_extern(Mesh *mesh, const bool do_tessface, const bool is_destructive)
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")
PyObject * BPyInit_bmesh_geometry()
PyObject * BPyInit_bmesh_ops()
PyObject * BPy_BMesh_CreatePyObject(BMesh *bm, int flag)
void BPy_BM_init_types()
PyObject * BPyInit_bmesh_types()
@ BPY_BMFLAG_IS_WRAPPED
@ BPY_BMFLAG_NOP
void BPy_BM_init_types_customdata()
void BPy_BM_init_types_meshdata()
void BPy_BM_init_types_select()
PyObject * BPyInit_bmesh_utils()
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * PyC_RNA_AsPointer(PyObject *value, const char *type_name)
int PyC_ParseBool(PyObject *o, void *p)
MeshRuntimeHandle * runtime