Blender  V2.93
bpy.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 
25 #include <Python.h>
26 
27 #include "BLI_string.h"
28 #include "BLI_utildefines.h"
29 
30 #include "BKE_appdir.h"
31 #include "BKE_blender_version.h"
32 #include "BKE_bpath.h"
33 #include "BKE_global.h" /* XXX, G_MAIN only */
34 
35 #include "RNA_access.h"
36 #include "RNA_types.h"
37 
38 #include "GPU_state.h"
39 
40 #include "bpy.h"
41 #include "bpy_app.h"
42 #include "bpy_capi_utils.h"
43 #include "bpy_library.h"
44 #include "bpy_operator.h"
45 #include "bpy_props.h"
46 #include "bpy_rna.h"
47 #include "bpy_rna_data.h"
48 #include "bpy_rna_gizmo.h"
49 #include "bpy_rna_id_collection.h"
50 #include "bpy_rna_types_capi.h"
51 #include "bpy_utils_previews.h"
52 #include "bpy_utils_units.h"
53 
54 #include "../generic/py_capi_utils.h"
55 #include "../generic/python_utildefines.h"
56 
57 /* external util modules */
58 #include "../generic/idprop_py_api.h"
59 #include "bpy_msgbus.h"
60 
61 #ifdef WITH_FREESTYLE
62 # include "BPy_Freestyle.h"
63 #endif
64 
65 PyObject *bpy_package_py = NULL;
66 
67 PyDoc_STRVAR(bpy_script_paths_doc,
68  ".. function:: script_paths()\n"
69  "\n"
70  " Return 2 paths to blender scripts directories.\n"
71  "\n"
72  " :return: (system, user) strings will be empty when not found.\n"
73  " :rtype: tuple of strings\n");
74 static PyObject *bpy_script_paths(PyObject *UNUSED(self))
75 {
76  PyObject *ret = PyTuple_New(2);
77  PyObject *item;
78  const char *path;
79 
81  item = PyC_UnicodeFromByte(path ? path : "");
82  BLI_assert(item != NULL);
83  PyTuple_SET_ITEM(ret, 0, item);
85  item = PyC_UnicodeFromByte(path ? path : "");
86  BLI_assert(item != NULL);
87  PyTuple_SET_ITEM(ret, 1, item);
88 
89  return ret;
90 }
91 
92 static bool bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src)
93 {
94  PyList_APPEND((PyObject *)userdata, PyC_UnicodeFromByte(path_src));
95  return false; /* never edits the path */
96 }
97 
98 PyDoc_STRVAR(bpy_blend_paths_doc,
99  ".. function:: blend_paths(absolute=False, packed=False, local=False)\n"
100  "\n"
101  " Returns a list of paths to external files referenced by the loaded .blend file.\n"
102  "\n"
103  " :arg absolute: When true the paths returned are made absolute.\n"
104  " :type absolute: boolean\n"
105  " :arg packed: When true skip file paths for packed data.\n"
106  " :type packed: boolean\n"
107  " :arg local: When true skip linked library paths.\n"
108  " :type local: boolean\n"
109  " :return: path list.\n"
110  " :rtype: list of strings\n");
111 static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
112 {
113  int flag = 0;
114  PyObject *list;
115 
116  bool absolute = false;
117  bool packed = false;
118  bool local = false;
119 
120  static const char *_keywords[] = {"absolute", "packed", "local", NULL};
121  static _PyArg_Parser _parser = {"|O&O&O&:blend_paths", _keywords, 0};
122  if (!_PyArg_ParseTupleAndKeywordsFast(args,
123  kw,
124  &_parser,
126  &absolute,
128  &packed,
130  &local)) {
131  return NULL;
132  }
133 
134  if (absolute) {
135  flag |= BKE_BPATH_TRAVERSE_ABS;
136  }
137  if (!packed) {
139  }
140  if (local) {
142  }
143 
144  list = PyList_New(0);
145 
147 
148  return list;
149 }
150 
151 // PyDoc_STRVAR(bpy_user_resource_doc[] = /* now in bpy/utils.py */
152 static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
153 {
154  const struct PyC_StringEnumItems type_items[] = {
155  {BLENDER_USER_DATAFILES, "DATAFILES"},
156  {BLENDER_USER_CONFIG, "CONFIG"},
157  {BLENDER_USER_SCRIPTS, "SCRIPTS"},
158  {BLENDER_USER_AUTOSAVE, "AUTOSAVE"},
159  {0, NULL},
160  };
161  struct PyC_StringEnum type = {type_items};
162 
163  const char *subdir = NULL;
164 
165  const char *path;
166 
167  static const char *_keywords[] = {"type", "subdir", NULL};
168  static _PyArg_Parser _parser = {"O&|s:user_resource", _keywords, 0};
169  if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, PyC_ParseStringEnum, &type, &subdir)) {
170  return NULL;
171  }
172 
173  /* same logic as BKE_appdir_folder_id_create(),
174  * but best leave it up to the script author to create */
175  path = BKE_appdir_folder_id_user_notest(type.value_found, subdir);
176 
177  return PyC_UnicodeFromByte(path ? path : "");
178 }
179 
180 PyDoc_STRVAR(bpy_system_resource_doc,
181  ".. function:: system_resource(type, path=\"\")\n"
182  "\n"
183  " Return a system resource path.\n"
184  "\n"
185  " :arg type: string in ['DATAFILES', 'SCRIPTS', 'PYTHON'].\n"
186  " :type type: string\n"
187  " :arg path: Optional subdirectory.\n"
188  " :type path: string\n");
189 static PyObject *bpy_system_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
190 {
191  const struct PyC_StringEnumItems type_items[] = {
192  {BLENDER_SYSTEM_DATAFILES, "DATAFILES"},
193  {BLENDER_SYSTEM_SCRIPTS, "SCRIPTS"},
194  {BLENDER_SYSTEM_PYTHON, "PYTHON"},
195  {0, NULL},
196  };
197  struct PyC_StringEnum type = {type_items};
198 
199  const char *subdir = NULL;
200 
201  const char *path;
202 
203  static const char *_keywords[] = {"type", "path", NULL};
204  static _PyArg_Parser _parser = {"O&|s:system_resource", _keywords, 0};
205  if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, PyC_ParseStringEnum, &type, &subdir)) {
206  return NULL;
207  }
208 
209  path = BKE_appdir_folder_id(type.value_found, subdir);
210 
211  return PyC_UnicodeFromByte(path ? path : "");
212 }
213 
215  bpy_resource_path_doc,
216  ".. function:: resource_path(type, major=bpy.app.version[0], minor=bpy.app.version[1])\n"
217  "\n"
218  " Return the base path for storing system files.\n"
219  "\n"
220  " :arg type: string in ['USER', 'LOCAL', 'SYSTEM'].\n"
221  " :type type: string\n"
222  " :arg major: major version, defaults to current.\n"
223  " :type major: int\n"
224  " :arg minor: minor version, defaults to current.\n"
225  " :type minor: string\n"
226  " :return: the resource path (not necessarily existing).\n"
227  " :rtype: string\n");
228 static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
229 {
230  const struct PyC_StringEnumItems type_items[] = {
231  {BLENDER_RESOURCE_PATH_USER, "USER"},
232  {BLENDER_RESOURCE_PATH_LOCAL, "LOCAL"},
233  {BLENDER_RESOURCE_PATH_SYSTEM, "SYSTEM"},
234  {0, NULL},
235  };
236  struct PyC_StringEnum type = {type_items};
237 
238  int major = BLENDER_VERSION / 100, minor = BLENDER_VERSION % 100;
239  const char *path;
240 
241  static const char *_keywords[] = {"type", "major", "minor", NULL};
242  static _PyArg_Parser _parser = {"O&|ii:resource_path", _keywords, 0};
243  if (!_PyArg_ParseTupleAndKeywordsFast(
244  args, kw, &_parser, PyC_ParseStringEnum, &type, &major, &minor)) {
245  return NULL;
246  }
247 
248  path = BKE_appdir_folder_id_version(type.value_found, (major * 100) + minor, false);
249 
250  return PyC_UnicodeFromByte(path ? path : "");
251 }
252 
253 PyDoc_STRVAR(bpy_escape_identifier_doc,
254  ".. function:: escape_identifier(string)\n"
255  "\n"
256  " Simple string escaping function used for animation paths.\n"
257  "\n"
258  " :arg string: text\n"
259  " :type string: string\n"
260  " :return: The escaped string.\n"
261  " :rtype: string\n");
262 static PyObject *bpy_escape_identifier(PyObject *UNUSED(self), PyObject *value)
263 {
264  Py_ssize_t value_str_len;
265  const char *value_str = PyUnicode_AsUTF8AndSize(value, &value_str_len);
266 
267  if (value_str == NULL) {
268  PyErr_SetString(PyExc_TypeError, "expected a string");
269  return NULL;
270  }
271 
272  const size_t size = (value_str_len * 2) + 1;
273  char *value_escape_str = PyMem_MALLOC(size);
274  const Py_ssize_t value_escape_str_len = BLI_str_escape(value_escape_str, value_str, size);
275 
276  PyObject *value_escape;
277  if (value_escape_str_len == value_str_len) {
278  Py_INCREF(value);
279  value_escape = value;
280  }
281  else {
282  value_escape = PyUnicode_FromStringAndSize(value_escape_str, value_escape_str_len);
283  }
284 
285  PyMem_FREE(value_escape_str);
286 
287  return value_escape;
288 }
289 
290 PyDoc_STRVAR(bpy_unescape_identifier_doc,
291  ".. function:: unescape_identifier(string)\n"
292  "\n"
293  " Simple string un-escape function used for animation paths.\n"
294  " This performs the reverse of `escape_identifier`.\n"
295  "\n"
296  " :arg string: text\n"
297  " :type string: string\n"
298  " :return: The un-escaped string.\n"
299  " :rtype: string\n");
300 static PyObject *bpy_unescape_identifier(PyObject *UNUSED(self), PyObject *value)
301 {
302  Py_ssize_t value_str_len;
303  const char *value_str = PyUnicode_AsUTF8AndSize(value, &value_str_len);
304 
305  if (value_str == NULL) {
306  PyErr_SetString(PyExc_TypeError, "expected a string");
307  return NULL;
308  }
309 
310  const size_t size = value_str_len + 1;
311  char *value_unescape_str = PyMem_MALLOC(size);
312  const Py_ssize_t value_unescape_str_len = BLI_str_unescape(value_unescape_str, value_str, size);
313 
314  PyObject *value_unescape;
315  if (value_unescape_str_len == value_str_len) {
316  Py_INCREF(value);
317  value_unescape = value;
318  }
319  else {
320  value_unescape = PyUnicode_FromStringAndSize(value_unescape_str, value_unescape_str_len);
321  }
322 
323  PyMem_FREE(value_unescape_str);
324 
325  return value_unescape;
326 }
327 
328 static PyMethodDef meth_bpy_script_paths = {
329  "script_paths",
330  (PyCFunction)bpy_script_paths,
331  METH_NOARGS,
332  bpy_script_paths_doc,
333 };
334 static PyMethodDef meth_bpy_blend_paths = {
335  "blend_paths",
336  (PyCFunction)bpy_blend_paths,
337  METH_VARARGS | METH_KEYWORDS,
338  bpy_blend_paths_doc,
339 };
340 static PyMethodDef meth_bpy_user_resource = {
341  "user_resource",
342  (PyCFunction)bpy_user_resource,
343  METH_VARARGS | METH_KEYWORDS,
344  NULL,
345 };
346 static PyMethodDef meth_bpy_system_resource = {
347  "system_resource",
348  (PyCFunction)bpy_system_resource,
349  METH_VARARGS | METH_KEYWORDS,
350  bpy_system_resource_doc,
351 };
352 static PyMethodDef meth_bpy_resource_path = {
353  "resource_path",
354  (PyCFunction)bpy_resource_path,
355  METH_VARARGS | METH_KEYWORDS,
356  bpy_resource_path_doc,
357 };
358 static PyMethodDef meth_bpy_escape_identifier = {
359  "escape_identifier",
360  (PyCFunction)bpy_escape_identifier,
361  METH_O,
362  bpy_escape_identifier_doc,
363 };
364 static PyMethodDef meth_bpy_unescape_identifier = {
365  "unescape_identifier",
366  (PyCFunction)bpy_unescape_identifier,
367  METH_O,
368  bpy_unescape_identifier_doc,
369 };
370 
371 static PyObject *bpy_import_test(const char *modname)
372 {
373  PyObject *mod = PyImport_ImportModuleLevel(modname, NULL, NULL, NULL, 0);
374 
375  GPU_bgl_end();
376 
377  if (mod) {
378  Py_DECREF(mod);
379  }
380  else {
381  PyErr_Print();
382  PyErr_Clear();
383  }
384 
385  return mod;
386 }
387 
388 /******************************************************************************
389  * Description: Creates the bpy module and adds it to sys.modules for importing
390  ******************************************************************************/
392 {
393  PointerRNA ctx_ptr;
394  PyObject *mod;
395 
396  /* Needs to be first since this dir is needed for future modules */
397  const char *const modpath = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, "modules");
398  if (modpath) {
399  // printf("bpy: found module path '%s'.\n", modpath);
400  PyObject *sys_path = PySys_GetObject("path"); /* borrow */
401  PyObject *py_modpath = PyUnicode_FromString(modpath);
402  PyList_Insert(sys_path, 0, py_modpath); /* add first */
403  Py_DECREF(py_modpath);
404  }
405  else {
406  printf("bpy: couldn't find 'scripts/modules', blender probably wont start.\n");
407  }
408  /* stand alone utility modules not related to blender directly */
409  IDProp_Init_Types(); /* not actually a submodule, just types */
410 #ifdef WITH_FREESTYLE
411  Freestyle_Init();
412 #endif
413 
414  mod = PyModule_New("_bpy");
415 
416  /* add the module so we can import it */
417  PyDict_SetItemString(PyImport_GetModuleDict(), "_bpy", mod);
418  Py_DECREF(mod);
419 
420  /* run first, initializes rna types */
421  BPY_rna_init();
422 
423  /* needs to be first so bpy_types can run */
424  PyModule_AddObject(mod, "types", BPY_rna_types());
425 
426  /* needs to be first so bpy_types can run */
428 
430 
432 
433  bpy_import_test("bpy_types");
434  PyModule_AddObject(mod, "data", BPY_rna_module()); /* imports bpy_types by running this */
435  bpy_import_test("bpy_types");
436  PyModule_AddObject(mod, "props", BPY_rna_props());
437  /* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
438  PyModule_AddObject(mod, "ops", BPY_operator_module());
439  PyModule_AddObject(mod, "app", BPY_app_struct());
440  PyModule_AddObject(mod, "_utils_units", BPY_utils_units());
441  PyModule_AddObject(mod, "_utils_previews", BPY_utils_previews_module());
442  PyModule_AddObject(mod, "msgbus", BPY_msgbus_module());
443 
444  RNA_pointer_create(NULL, &RNA_Context, C, &ctx_ptr);
446  /* odd that this is needed, 1 ref on creation and another for the module
447  * but without we get a crash on exit */
448  Py_INCREF(bpy_context_module);
449 
450  PyModule_AddObject(mod, "context", (PyObject *)bpy_context_module);
451 
452  /* Register methods and property get/set for RNA types. */
454 
455  /* utility func's that have nowhere else to go */
456  PyModule_AddObject(mod,
457  meth_bpy_script_paths.ml_name,
458  (PyObject *)PyCFunction_New(&meth_bpy_script_paths, NULL));
459  PyModule_AddObject(
460  mod, meth_bpy_blend_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_blend_paths, NULL));
461  PyModule_AddObject(mod,
462  meth_bpy_user_resource.ml_name,
463  (PyObject *)PyCFunction_New(&meth_bpy_user_resource, NULL));
464  PyModule_AddObject(mod,
465  meth_bpy_system_resource.ml_name,
466  (PyObject *)PyCFunction_New(&meth_bpy_system_resource, NULL));
467  PyModule_AddObject(mod,
468  meth_bpy_resource_path.ml_name,
469  (PyObject *)PyCFunction_New(&meth_bpy_resource_path, NULL));
470  PyModule_AddObject(mod,
472  (PyObject *)PyCFunction_New(&meth_bpy_escape_identifier, NULL));
473  PyModule_AddObject(mod,
475  (PyObject *)PyCFunction_New(&meth_bpy_unescape_identifier, NULL));
476 
477  /* register funcs (bpy_rna.c) */
478  PyModule_AddObject(mod,
479  meth_bpy_register_class.ml_name,
480  (PyObject *)PyCFunction_New(&meth_bpy_register_class, NULL));
481  PyModule_AddObject(mod,
483  (PyObject *)PyCFunction_New(&meth_bpy_unregister_class, NULL));
484 
485  PyModule_AddObject(mod,
486  meth_bpy_owner_id_get.ml_name,
487  (PyObject *)PyCFunction_New(&meth_bpy_owner_id_get, NULL));
488  PyModule_AddObject(mod,
489  meth_bpy_owner_id_set.ml_name,
490  (PyObject *)PyCFunction_New(&meth_bpy_owner_id_set, NULL));
491 
492  /* add our own modules dir, this is a python package */
494 }
@ BLENDER_USER_DATAFILES
Definition: BKE_appdir.h:82
@ BLENDER_SYSTEM_DATAFILES
Definition: BKE_appdir.h:87
@ BLENDER_SYSTEM_PYTHON
Definition: BKE_appdir.h:89
@ BLENDER_SYSTEM_SCRIPTS
Definition: BKE_appdir.h:88
@ BLENDER_USER_AUTOSAVE
Definition: BKE_appdir.h:84
@ BLENDER_USER_CONFIG
Definition: BKE_appdir.h:81
@ BLENDER_USER_SCRIPTS
Definition: BKE_appdir.h:83
const char * BKE_appdir_folder_id_version(const int folder_id, const int version, const bool check_is_dir)
Definition: appdir.c:764
const char * BKE_appdir_folder_id(const int folder_id, const char *subfolder)
Definition: appdir.c:674
@ BLENDER_RESOURCE_PATH_SYSTEM
Definition: BKE_appdir.h:96
@ BLENDER_RESOURCE_PATH_LOCAL
Definition: BKE_appdir.h:95
@ BLENDER_RESOURCE_PATH_USER
Definition: BKE_appdir.h:94
const char * BKE_appdir_folder_id_user_notest(const int folder_id, const char *subfolder)
Definition: appdir.c:686
#define BLENDER_VERSION
void BKE_bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
Definition: bpath.c:781
@ BKE_BPATH_TRAVERSE_SKIP_LIBRARY
Definition: BKE_bpath.h:63
@ BKE_BPATH_TRAVERSE_ABS
Definition: BKE_bpath.h:61
@ BKE_BPATH_TRAVERSE_SKIP_PACKED
Definition: BKE_bpath.h:65
#define G_MAIN
Definition: BKE_global.h:232
#define BLI_assert(a)
Definition: BLI_assert.h:58
size_t size_t char size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy) ATTR_NONNULL()
Definition: string.c:333
size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy) ATTR_NONNULL()
Definition: string.c:375
#define UNUSED(x)
PyObject * Freestyle_Init(void)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
void GPU_bgl_end(void)
Definition: gpu_state.cc:367
StructRNA RNA_Context
#define C
Definition: RandGen.cpp:39
static bool bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src)
Definition: bpy.c:92
static PyObject * bpy_import_test(const char *modname)
Definition: bpy.c:371
PyDoc_STRVAR(bpy_script_paths_doc, ".. function:: script_paths()\n" "\n" " Return 2 paths to blender scripts directories.\n" "\n" " :return: (system, user) strings will be empty when not found.\n" " :rtype: tuple of strings\n")
void BPy_init_modules(struct bContext *C)
Definition: bpy.c:391
static PyMethodDef meth_bpy_resource_path
Definition: bpy.c:352
static PyObject * bpy_escape_identifier(PyObject *UNUSED(self), PyObject *value)
Definition: bpy.c:262
static PyObject * bpy_script_paths(PyObject *UNUSED(self))
Definition: bpy.c:74
static PyMethodDef meth_bpy_blend_paths
Definition: bpy.c:334
PyObject * bpy_package_py
Definition: bpy.c:65
static PyMethodDef meth_bpy_script_paths
Definition: bpy.c:328
static PyObject * bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
Definition: bpy.c:228
static PyObject * bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
Definition: bpy.c:111
static PyMethodDef meth_bpy_unescape_identifier
Definition: bpy.c:364
static PyObject * bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
Definition: bpy.c:152
static PyObject * bpy_system_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
Definition: bpy.c:189
static PyMethodDef meth_bpy_escape_identifier
Definition: bpy.c:358
static PyObject * bpy_unescape_identifier(PyObject *UNUSED(self), PyObject *value)
Definition: bpy.c:300
static PyMethodDef meth_bpy_user_resource
Definition: bpy.c:340
static PyMethodDef meth_bpy_system_resource
Definition: bpy.c:346
PyObject * BPY_app_struct(void)
Definition: bpy_app.c:488
int BPY_library_load_type_ready(void)
PyObject * BPY_msgbus_module(void)
Definition: bpy_msgbus.c:390
PyObject * BPY_operator_module(void)
Definition: bpy_operator.c:484
PyObject * BPY_rna_props(void)
Definition: bpy_props.c:3927
void BPY_rna_init(void)
Definition: bpy_rna.c:7638
PyMethodDef meth_bpy_owner_id_set
Definition: bpy_rna.c:9200
PyMethodDef meth_bpy_owner_id_get
Definition: bpy_rna.c:9194
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
Definition: bpy_rna.c:7469
PyObject * BPY_rna_module(void)
Definition: bpy_rna.c:7688
PyMethodDef meth_bpy_unregister_class
Definition: bpy_rna.c:9001
PyMethodDef meth_bpy_register_class
Definition: bpy_rna.c:8827
PyObject * BPY_rna_types(void)
Definition: bpy_rna.c:7819
BPy_StructRNA * bpy_context_module
Definition: bpy_rna.c:97
int BPY_rna_data_context_type_ready(void)
Definition: bpy_rna_data.c:212
bool BPY_rna_gizmo_module(PyObject *mod_par)
void BPY_rna_types_extend_capi(void)
PyObject * BPY_utils_previews_module(void)
PyObject * BPY_utils_units(void)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
btMatrix3x3 absolute() const
Return the matrix with all values non negative.
Definition: btMatrix3x3.h:1028
void IDProp_Init_Types(void)
int PyC_ParseStringEnum(PyObject *o, void *p)
PyObject * PyC_UnicodeFromByte(const char *str)
int PyC_ParseBool(PyObject *o, void *p)
return ret
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
ccl_device_inline int mod(int x, int m)
Definition: util_math.h:405