ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
This commit is contained in:
@@ -18,20 +18,18 @@
|
||||
* \ingroup python
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __BPY_EXTERN_H__
|
||||
#define __BPY_EXTERN_H__
|
||||
|
||||
struct ChannelDriver; /* DNA_anim_types.h */
|
||||
struct ID; /* DNA_ID.h */
|
||||
struct ListBase; /* DNA_listBase.h */
|
||||
struct Object; /* DNA_object_types.h */
|
||||
struct ID; /* DNA_ID.h */
|
||||
struct ListBase; /* DNA_listBase.h */
|
||||
struct Object; /* DNA_object_types.h */
|
||||
struct PathResolvedRNA;
|
||||
struct ReportList;
|
||||
struct Text; /* defined in DNA_text_types.h */
|
||||
struct bConstraint; /* DNA_constraint_types.h */
|
||||
struct bConstraintOb; /* DNA_constraint_types.h */
|
||||
struct Text; /* defined in DNA_text_types.h */
|
||||
struct bConstraint; /* DNA_constraint_types.h */
|
||||
struct bConstraintOb; /* DNA_constraint_types.h */
|
||||
struct bConstraintTarget; /* DNA_constraint_types.h*/
|
||||
struct bContext;
|
||||
struct bContextDataResult;
|
||||
@@ -41,18 +39,19 @@ struct bPythonConstraint; /* DNA_constraint_types.h */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void BPY_pyconstraint_exec(struct bPythonConstraint *con, struct bConstraintOb *cob, struct ListBase *targets);
|
||||
// void BPY_pyconstraint_settings(void *arg1, void *arg2);
|
||||
void BPY_pyconstraint_exec(struct bPythonConstraint *con,
|
||||
struct bConstraintOb *cob,
|
||||
struct ListBase *targets);
|
||||
// void BPY_pyconstraint_settings(void *arg1, void *arg2);
|
||||
void BPY_pyconstraint_target(struct bPythonConstraint *con, struct bConstraintTarget *ct);
|
||||
void BPY_pyconstraint_update(struct Object *owner, struct bConstraint *con);
|
||||
int BPY_is_pyconstraint(struct Text *text);
|
||||
// void BPY_free_pyconstraint_links(struct Text *text);
|
||||
// void BPY_free_pyconstraint_links(struct Text *text);
|
||||
|
||||
void BPY_python_start(int argc, const char **argv);
|
||||
void BPY_python_end(void);
|
||||
void BPY_python_reset(struct bContext *C);
|
||||
|
||||
|
||||
/* global interpreter lock */
|
||||
|
||||
typedef void *BPy_ThreadStatePtr;
|
||||
@@ -61,38 +60,67 @@ BPy_ThreadStatePtr BPY_thread_save(void);
|
||||
void BPY_thread_restore(BPy_ThreadStatePtr tstate);
|
||||
|
||||
/* our own wrappers to Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS */
|
||||
#define BPy_BEGIN_ALLOW_THREADS { BPy_ThreadStatePtr _bpy_saved_tstate = BPY_thread_save(); (void)0
|
||||
#define BPy_END_ALLOW_THREADS BPY_thread_restore(_bpy_saved_tstate); } (void)0
|
||||
#define BPy_BEGIN_ALLOW_THREADS \
|
||||
{ \
|
||||
BPy_ThreadStatePtr _bpy_saved_tstate = BPY_thread_save(); \
|
||||
(void)0
|
||||
#define BPy_END_ALLOW_THREADS \
|
||||
BPY_thread_restore(_bpy_saved_tstate); \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
bool BPY_execute_filepath(struct bContext *C, const char *filepath, struct ReportList *reports);
|
||||
bool BPY_execute_text(struct bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump);
|
||||
bool BPY_execute_filepath(struct bContext *C, const char *filepath, struct ReportList *reports);
|
||||
bool BPY_execute_text(struct bContext *C,
|
||||
struct Text *text,
|
||||
struct ReportList *reports,
|
||||
const bool do_jump);
|
||||
|
||||
bool BPY_execute_string_as_number(struct bContext *C, const char *imports[], const char *expr, const bool verbose, double *r_value);
|
||||
bool BPY_execute_string_as_intptr(struct bContext *C, const char *imports[], const char *expr, const bool verbose, intptr_t *r_value);
|
||||
bool BPY_execute_string_as_string(struct bContext *C, const char *imports[], const char *expr, const bool verbose, char **r_value);
|
||||
bool BPY_execute_string_as_number(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const bool verbose,
|
||||
double *r_value);
|
||||
bool BPY_execute_string_as_intptr(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const bool verbose,
|
||||
intptr_t *r_value);
|
||||
bool BPY_execute_string_as_string(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const bool verbose,
|
||||
char **r_value);
|
||||
|
||||
bool BPY_execute_string_ex(struct bContext *C, const char *imports[], const char *expr, bool use_eval);
|
||||
bool BPY_execute_string(struct bContext *C, const char *imports[], const char *expr);
|
||||
bool BPY_execute_string_ex(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
bool use_eval);
|
||||
bool BPY_execute_string(struct bContext *C, const char *imports[], const char *expr);
|
||||
|
||||
void BPY_text_free_code(struct Text *text);
|
||||
void BPY_modules_update(struct bContext *C); // XXX - annoying, need this for pointers that get out of date
|
||||
void BPY_modules_load_user(struct bContext *C);
|
||||
void BPY_text_free_code(struct Text *text);
|
||||
void BPY_modules_update(
|
||||
struct bContext *C); // XXX - annoying, need this for pointers that get out of date
|
||||
void BPY_modules_load_user(struct bContext *C);
|
||||
|
||||
void BPY_app_handlers_reset(const short do_all);
|
||||
void BPY_app_handlers_reset(const short do_all);
|
||||
|
||||
void BPY_driver_reset(void);
|
||||
float BPY_driver_exec(struct PathResolvedRNA *anim_rna, struct ChannelDriver *driver,
|
||||
struct ChannelDriver *driver_orig, const float evaltime);
|
||||
void BPY_driver_reset(void);
|
||||
float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
|
||||
struct ChannelDriver *driver,
|
||||
struct ChannelDriver *driver_orig,
|
||||
const float evaltime);
|
||||
|
||||
void BPY_DECREF(void *pyob_ptr); /* Py_DECREF() */
|
||||
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr);
|
||||
int BPY_context_member_get(struct bContext *C, const char *member, struct bContextDataResult *result);
|
||||
void BPY_context_set(struct bContext *C);
|
||||
void BPY_context_update(struct bContext *C);
|
||||
void BPY_DECREF(void *pyob_ptr); /* Py_DECREF() */
|
||||
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr);
|
||||
int BPY_context_member_get(struct bContext *C,
|
||||
const char *member,
|
||||
struct bContextDataResult *result);
|
||||
void BPY_context_set(struct bContext *C);
|
||||
void BPY_context_update(struct bContext *C);
|
||||
|
||||
void BPY_id_release(struct ID *id);
|
||||
void BPY_id_release(struct ID *id);
|
||||
|
||||
bool BPY_string_is_keyword(const char *str);
|
||||
bool BPY_string_is_keyword(const char *str);
|
||||
|
||||
/* I18n for addons */
|
||||
#ifdef WITH_INTERNATIONAL
|
||||
@@ -100,7 +128,7 @@ const char *BPY_app_translations_py_pgettext(const char *msgctxt, const char *ms
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __BPY_EXTERN_H__ */
|
||||
#endif /* __BPY_EXTERN_H__ */
|
||||
|
||||
@@ -23,9 +23,8 @@
|
||||
#ifndef __BPY_EXTERN_CLOG_H__
|
||||
#define __BPY_EXTERN_CLOG_H__
|
||||
|
||||
|
||||
/* bpy_interface.c */
|
||||
extern struct CLG_LogRef *BPY_LOG_RNA;
|
||||
extern struct CLG_LogRef *BPY_LOG_CONTEXT;
|
||||
|
||||
#endif /* __BPY_EXTERN_CLOG_H__ */
|
||||
#endif /* __BPY_EXTERN_CLOG_H__ */
|
||||
|
||||
@@ -16,49 +16,49 @@
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
.
|
||||
../../bmesh
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../depsgraph
|
||||
../../makesdna
|
||||
../../../../intern/guardedalloc
|
||||
.
|
||||
../../bmesh
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../depsgraph
|
||||
../../makesdna
|
||||
../../../../intern/guardedalloc
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
bmesh_py_api.c
|
||||
bmesh_py_geometry.c
|
||||
bmesh_py_ops.c
|
||||
bmesh_py_ops_call.c
|
||||
bmesh_py_types.c
|
||||
bmesh_py_types_customdata.c
|
||||
bmesh_py_types_meshdata.c
|
||||
bmesh_py_types_select.c
|
||||
bmesh_py_utils.c
|
||||
bmesh_py_api.c
|
||||
bmesh_py_geometry.c
|
||||
bmesh_py_ops.c
|
||||
bmesh_py_ops_call.c
|
||||
bmesh_py_types.c
|
||||
bmesh_py_types_customdata.c
|
||||
bmesh_py_types_meshdata.c
|
||||
bmesh_py_types_select.c
|
||||
bmesh_py_utils.c
|
||||
|
||||
bmesh_py_api.h
|
||||
bmesh_py_geometry.h
|
||||
bmesh_py_ops.h
|
||||
bmesh_py_ops_call.h
|
||||
bmesh_py_types.h
|
||||
bmesh_py_types_customdata.h
|
||||
bmesh_py_types_meshdata.h
|
||||
bmesh_py_types_select.h
|
||||
bmesh_py_utils.h
|
||||
bmesh_py_api.h
|
||||
bmesh_py_geometry.h
|
||||
bmesh_py_ops.h
|
||||
bmesh_py_ops_call.h
|
||||
bmesh_py_types.h
|
||||
bmesh_py_types_customdata.h
|
||||
bmesh_py_types_meshdata.h
|
||||
bmesh_py_types_select.h
|
||||
bmesh_py_utils.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
bf_blenkernel
|
||||
bf_blenlib
|
||||
bf_python_mathutils
|
||||
bf_blenkernel
|
||||
bf_blenlib
|
||||
bf_python_mathutils
|
||||
)
|
||||
|
||||
if(WITH_FREESTYLE)
|
||||
add_definitions(-DWITH_FREESTYLE)
|
||||
add_definitions(-DWITH_FREESTYLE)
|
||||
endif()
|
||||
|
||||
blender_add_lib(bf_python_bmesh "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
||||
@@ -47,167 +47,168 @@
|
||||
#include "bmesh_py_api.h" /* own include */
|
||||
|
||||
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"
|
||||
);
|
||||
".. 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 PyObject *bpy_bm_new(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
static const char *kwlist[] = {"use_operators", NULL};
|
||||
BMesh *bm;
|
||||
static const char *kwlist[] = {"use_operators", NULL};
|
||||
BMesh *bm;
|
||||
|
||||
bool use_operators = true;
|
||||
bool use_operators = true;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kw, "|$O&:new", (char **)kwlist,
|
||||
PyC_ParseBool, &use_operators))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kw, "|$O&:new", (char **)kwlist, PyC_ParseBool, &use_operators)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bm = BM_mesh_create(
|
||||
&bm_mesh_allocsize_default,
|
||||
&((struct BMeshCreateParams){.use_toolflags = use_operators,}));
|
||||
bm = BM_mesh_create(&bm_mesh_allocsize_default,
|
||||
&((struct BMeshCreateParams){
|
||||
.use_toolflags = use_operators,
|
||||
}));
|
||||
|
||||
return BPy_BMesh_CreatePyObject(bm, BPY_BMFLAG_NOP);
|
||||
return BPy_BMesh_CreatePyObject(bm, BPY_BMFLAG_NOP);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_bm_from_edit_mesh_doc,
|
||||
".. method:: from_edit_mesh(mesh)\n"
|
||||
"\n"
|
||||
" Return a BMesh from this mesh, currently the mesh must already be in editmode.\n"
|
||||
"\n"
|
||||
" :arg mesh: The editmode mesh.\n"
|
||||
" :type mesh: :class:`bpy.types.Mesh`\n"
|
||||
" :return: the BMesh associated with this mesh.\n"
|
||||
" :rtype: :class:`bmesh.types.BMesh`\n"
|
||||
);
|
||||
".. method:: from_edit_mesh(mesh)\n"
|
||||
"\n"
|
||||
" Return a BMesh from this mesh, currently the mesh must already be in editmode.\n"
|
||||
"\n"
|
||||
" :arg mesh: The editmode mesh.\n"
|
||||
" :type mesh: :class:`bpy.types.Mesh`\n"
|
||||
" :return: the BMesh associated with this mesh.\n"
|
||||
" :rtype: :class:`bmesh.types.BMesh`\n");
|
||||
static PyObject *bpy_bm_from_edit_mesh(PyObject *UNUSED(self), PyObject *value)
|
||||
{
|
||||
BMesh *bm;
|
||||
Mesh *me = PyC_RNA_AsPointer(value, "Mesh");
|
||||
BMesh *bm;
|
||||
Mesh *me = PyC_RNA_AsPointer(value, "Mesh");
|
||||
|
||||
if (me == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (me == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (me->edit_mesh == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"The mesh must be in editmode");
|
||||
return NULL;
|
||||
}
|
||||
if (me->edit_mesh == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "The mesh must be in editmode");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bm = me->edit_mesh->bm;
|
||||
bm = me->edit_mesh->bm;
|
||||
|
||||
return BPy_BMesh_CreatePyObject(bm, BPY_BMFLAG_IS_WRAPPED);
|
||||
return BPy_BMesh_CreatePyObject(bm, BPY_BMFLAG_IS_WRAPPED);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc,
|
||||
".. method:: update_edit_mesh(mesh, loop_triangles=True, destructive=True)\n"
|
||||
"\n"
|
||||
" Update the mesh after changes to the BMesh in editmode,\n"
|
||||
" optionally recalculating n-gon tessellation.\n"
|
||||
"\n"
|
||||
" :arg mesh: The editmode mesh.\n"
|
||||
" :type mesh: :class:`bpy.types.Mesh`\n"
|
||||
" :arg loop_triangles: Option to recalculate n-gon tessellation.\n"
|
||||
" :type loop_triangles: boolean\n"
|
||||
" :arg destructive: Use when geometry has been added or removed.\n"
|
||||
" :type destructive: boolean\n"
|
||||
);
|
||||
".. method:: update_edit_mesh(mesh, loop_triangles=True, destructive=True)\n"
|
||||
"\n"
|
||||
" Update the mesh after changes to the BMesh in editmode,\n"
|
||||
" optionally recalculating n-gon tessellation.\n"
|
||||
"\n"
|
||||
" :arg mesh: The editmode mesh.\n"
|
||||
" :type mesh: :class:`bpy.types.Mesh`\n"
|
||||
" :arg loop_triangles: Option to recalculate n-gon tessellation.\n"
|
||||
" :type loop_triangles: boolean\n"
|
||||
" :arg destructive: Use when geometry has been added or removed.\n"
|
||||
" :type destructive: boolean\n");
|
||||
static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
static const char *kwlist[] = {"mesh", "loop_triangles", "destructive", NULL};
|
||||
PyObject *py_me;
|
||||
Mesh *me;
|
||||
bool do_loop_triangles = true;
|
||||
bool is_destructive = true;
|
||||
static const char *kwlist[] = {"mesh", "loop_triangles", "destructive", NULL};
|
||||
PyObject *py_me;
|
||||
Mesh *me;
|
||||
bool do_loop_triangles = true;
|
||||
bool is_destructive = true;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kw, "O|O&O&:update_edit_mesh", (char **)kwlist,
|
||||
&py_me,
|
||||
PyC_ParseBool, &do_loop_triangles,
|
||||
PyC_ParseBool, &is_destructive))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTupleAndKeywords(args,
|
||||
kw,
|
||||
"O|O&O&:update_edit_mesh",
|
||||
(char **)kwlist,
|
||||
&py_me,
|
||||
PyC_ParseBool,
|
||||
&do_loop_triangles,
|
||||
PyC_ParseBool,
|
||||
&is_destructive)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
me = PyC_RNA_AsPointer(py_me, "Mesh");
|
||||
me = PyC_RNA_AsPointer(py_me, "Mesh");
|
||||
|
||||
if (me == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (me == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (me->edit_mesh == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"The mesh must be in editmode");
|
||||
return NULL;
|
||||
}
|
||||
if (me->edit_mesh == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "The mesh must be in editmode");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
extern void EDBM_update_generic(BMEditMesh *em, const bool do_tessface, const bool is_destructive);
|
||||
{
|
||||
extern void EDBM_update_generic(
|
||||
BMEditMesh * em, const bool do_tessface, const bool is_destructive);
|
||||
|
||||
EDBM_update_generic(me->edit_mesh, do_loop_triangles, is_destructive);
|
||||
}
|
||||
EDBM_update_generic(me->edit_mesh, do_loop_triangles, is_destructive);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static struct PyMethodDef BPy_BM_methods[] = {
|
||||
{"new", (PyCFunction)bpy_bm_new, METH_VARARGS | METH_KEYWORDS, bpy_bm_new_doc},
|
||||
{"from_edit_mesh", (PyCFunction)bpy_bm_from_edit_mesh, METH_O, bpy_bm_from_edit_mesh_doc},
|
||||
{"update_edit_mesh", (PyCFunction)bpy_bm_update_edit_mesh, METH_VARARGS | METH_KEYWORDS, bpy_bm_update_edit_mesh_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"new", (PyCFunction)bpy_bm_new, METH_VARARGS | METH_KEYWORDS, bpy_bm_new_doc},
|
||||
{"from_edit_mesh", (PyCFunction)bpy_bm_from_edit_mesh, METH_O, bpy_bm_from_edit_mesh_doc},
|
||||
{"update_edit_mesh",
|
||||
(PyCFunction)bpy_bm_update_edit_mesh,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_bm_update_edit_mesh_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(BPy_BM_doc,
|
||||
"This module provides access to blenders bmesh data structures.\n"
|
||||
"\n"
|
||||
".. include:: include__bmesh.rst\n"
|
||||
);
|
||||
"This module provides access to blenders bmesh data structures.\n"
|
||||
"\n"
|
||||
".. include:: include__bmesh.rst\n");
|
||||
static struct PyModuleDef BPy_BM_module_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"bmesh", /* m_name */
|
||||
BPy_BM_doc, /* m_doc */
|
||||
0, /* m_size */
|
||||
BPy_BM_methods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"bmesh", /* m_name */
|
||||
BPy_BM_doc, /* m_doc */
|
||||
0, /* m_size */
|
||||
BPy_BM_methods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
};
|
||||
|
||||
PyObject *BPyInit_bmesh(void)
|
||||
{
|
||||
PyObject *mod;
|
||||
PyObject *submodule;
|
||||
PyObject *sys_modules = PyImport_GetModuleDict();
|
||||
PyObject *mod;
|
||||
PyObject *submodule;
|
||||
PyObject *sys_modules = PyImport_GetModuleDict();
|
||||
|
||||
BPy_BM_init_types();
|
||||
BPy_BM_init_types_select();
|
||||
BPy_BM_init_types_customdata();
|
||||
BPy_BM_init_types_meshdata();
|
||||
BPy_BM_init_types();
|
||||
BPy_BM_init_types_select();
|
||||
BPy_BM_init_types_customdata();
|
||||
BPy_BM_init_types_meshdata();
|
||||
|
||||
mod = PyModule_Create(&BPy_BM_module_def);
|
||||
mod = PyModule_Create(&BPy_BM_module_def);
|
||||
|
||||
/* bmesh.types */
|
||||
PyModule_AddObject(mod, "types", (submodule = BPyInit_bmesh_types()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
/* bmesh.types */
|
||||
PyModule_AddObject(mod, "types", (submodule = BPyInit_bmesh_types()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
|
||||
/* bmesh.ops (not a real module, exposes module like access). */
|
||||
PyModule_AddObject(mod, "ops", (submodule = BPyInit_bmesh_ops()));
|
||||
/* PyDict_SetItemString(sys_modules, PyModule_GetNameObject(submodule), submodule); */
|
||||
PyDict_SetItemString(sys_modules, "bmesh.ops", submodule); /* fake module */
|
||||
/* bmesh.ops (not a real module, exposes module like access). */
|
||||
PyModule_AddObject(mod, "ops", (submodule = BPyInit_bmesh_ops()));
|
||||
/* PyDict_SetItemString(sys_modules, PyModule_GetNameObject(submodule), submodule); */
|
||||
PyDict_SetItemString(sys_modules, "bmesh.ops", submodule); /* fake module */
|
||||
|
||||
PyModule_AddObject(mod, "utils", (submodule = BPyInit_bmesh_utils()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
PyModule_AddObject(mod, "utils", (submodule = BPyInit_bmesh_utils()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
|
||||
PyModule_AddObject(mod, "geometry", (submodule = BPyInit_bmesh_geometry()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
PyModule_AddObject(mod, "geometry", (submodule = BPyInit_bmesh_geometry()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
|
||||
return mod;
|
||||
return mod;
|
||||
}
|
||||
|
||||
@@ -35,70 +35,64 @@
|
||||
#include "bmesh_py_geometry.h" /* own include */
|
||||
|
||||
PyDoc_STRVAR(bpy_bm_geometry_intersect_face_point_doc,
|
||||
".. method:: intersect_face_point(face, point)\n"
|
||||
"\n"
|
||||
" Tests if the projection of a point is inside a face (using the face's normal).\n"
|
||||
"\n"
|
||||
" :arg face: The face to test.\n"
|
||||
" :type face: :class:`bmesh.types.BMFace`\n"
|
||||
" :arg point: The point to test.\n"
|
||||
" :type point: float triplet\n"
|
||||
" :return: True when the projection of the point is in the face.\n"
|
||||
" :rtype: bool\n"
|
||||
);
|
||||
".. method:: intersect_face_point(face, point)\n"
|
||||
"\n"
|
||||
" Tests if the projection of a point is inside a face (using the face's normal).\n"
|
||||
"\n"
|
||||
" :arg face: The face to test.\n"
|
||||
" :type face: :class:`bmesh.types.BMFace`\n"
|
||||
" :arg point: The point to test.\n"
|
||||
" :type point: float triplet\n"
|
||||
" :return: True when the projection of the point is in the face.\n"
|
||||
" :rtype: bool\n");
|
||||
static PyObject *bpy_bm_geometry_intersect_face_point(BPy_BMFace *UNUSED(self), PyObject *args)
|
||||
{
|
||||
BPy_BMFace *py_face;
|
||||
PyObject *py_point;
|
||||
float point[3];
|
||||
bool ret;
|
||||
BPy_BMFace *py_face;
|
||||
PyObject *py_point;
|
||||
float point[3];
|
||||
bool ret;
|
||||
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"O!O:intersect_face_point",
|
||||
&BPy_BMFace_Type, &py_face,
|
||||
&py_point))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "O!O:intersect_face_point", &BPy_BMFace_Type, &py_face, &py_point)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_BM_CHECK_OBJ(py_face);
|
||||
if (mathutils_array_parse(point, 3, 3, py_point, "intersect_face_point") == -1) {
|
||||
return NULL;
|
||||
}
|
||||
BPY_BM_CHECK_OBJ(py_face);
|
||||
if (mathutils_array_parse(point, 3, 3, py_point, "intersect_face_point") == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = BM_face_point_inside_test(py_face->f, point);
|
||||
ret = BM_face_point_inside_test(py_face->f, point);
|
||||
|
||||
return PyBool_FromLong(ret);
|
||||
return PyBool_FromLong(ret);
|
||||
}
|
||||
|
||||
|
||||
static struct PyMethodDef BPy_BM_geometry_methods[] = {
|
||||
{"intersect_face_point", (PyCFunction)bpy_bm_geometry_intersect_face_point, METH_VARARGS, bpy_bm_geometry_intersect_face_point_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"intersect_face_point",
|
||||
(PyCFunction)bpy_bm_geometry_intersect_face_point,
|
||||
METH_VARARGS,
|
||||
bpy_bm_geometry_intersect_face_point_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
|
||||
PyDoc_STRVAR(BPy_BM_utils_doc,
|
||||
"This module provides access to bmesh geometry evaluation functions."
|
||||
);
|
||||
"This module provides access to bmesh geometry evaluation functions.");
|
||||
static struct PyModuleDef BPy_BM_geometry_module_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"bmesh.geometry", /* m_name */
|
||||
BPy_BM_utils_doc, /* m_doc */
|
||||
0, /* m_size */
|
||||
BPy_BM_geometry_methods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"bmesh.geometry", /* m_name */
|
||||
BPy_BM_utils_doc, /* m_doc */
|
||||
0, /* m_size */
|
||||
BPy_BM_geometry_methods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
};
|
||||
|
||||
|
||||
PyObject *BPyInit_bmesh_geometry(void)
|
||||
{
|
||||
PyObject *submodule;
|
||||
PyObject *submodule;
|
||||
|
||||
submodule = PyModule_Create(&BPy_BM_geometry_module_def);
|
||||
submodule = PyModule_Create(&BPy_BM_geometry_module_def);
|
||||
|
||||
return submodule;
|
||||
return submodule;
|
||||
}
|
||||
|
||||
@@ -31,11 +31,10 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
#include "bmesh_py_ops_call.h"
|
||||
#include "bmesh_py_ops.h" /* own include */
|
||||
#include "bmesh_py_ops.h" /* own include */
|
||||
|
||||
/* bmesh operator 'bmesh.ops.*' callable types
|
||||
* ******************************************* */
|
||||
@@ -43,327 +42,337 @@ static PyTypeObject bmesh_op_Type;
|
||||
|
||||
static PyObject *bpy_bmesh_op_CreatePyObject(const char *opname)
|
||||
{
|
||||
BPy_BMeshOpFunc *self = PyObject_New(BPy_BMeshOpFunc, &bmesh_op_Type);
|
||||
BPy_BMeshOpFunc *self = PyObject_New(BPy_BMeshOpFunc, &bmesh_op_Type);
|
||||
|
||||
self->opname = opname;
|
||||
self->opname = opname;
|
||||
|
||||
return (PyObject *)self;
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
static PyObject *bpy_bmesh_op_repr(BPy_BMeshOpFunc *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("<%.200s bmesh.ops.%.200s()>",
|
||||
Py_TYPE(self)->tp_name,
|
||||
self->opname);
|
||||
return PyUnicode_FromFormat("<%.200s bmesh.ops.%.200s()>", Py_TYPE(self)->tp_name, self->opname);
|
||||
}
|
||||
|
||||
|
||||
/* methods
|
||||
* ======= */
|
||||
|
||||
|
||||
/* __doc__
|
||||
* ------- */
|
||||
|
||||
static char *bmp_slots_as_args(const BMOSlotType slot_types[BMO_OP_MAX_SLOTS], const bool is_out)
|
||||
{
|
||||
DynStr *dyn_str = BLI_dynstr_new();
|
||||
char *ret;
|
||||
bool quoted;
|
||||
bool set;
|
||||
DynStr *dyn_str = BLI_dynstr_new();
|
||||
char *ret;
|
||||
bool quoted;
|
||||
bool set;
|
||||
|
||||
int i = 0;
|
||||
int i = 0;
|
||||
|
||||
while (*slot_types[i].name) {
|
||||
quoted = false;
|
||||
set = false;
|
||||
/* cut off '.out' by using a string size arg */
|
||||
const int name_len = is_out ?
|
||||
(strchr(slot_types[i].name, '.') - slot_types[i].name) :
|
||||
sizeof(slot_types[i].name);
|
||||
const char *value = "<Unknown>";
|
||||
switch (slot_types[i].type) {
|
||||
case BMO_OP_SLOT_BOOL: value = "False"; break;
|
||||
case BMO_OP_SLOT_INT:
|
||||
if (slot_types[i].subtype.intg == BMO_OP_SLOT_SUBTYPE_INT_ENUM) {
|
||||
value = slot_types[i].enum_flags[0].identifier;
|
||||
quoted = true;
|
||||
}
|
||||
else if (slot_types[i].subtype.intg == BMO_OP_SLOT_SUBTYPE_INT_FLAG) {
|
||||
value = "";
|
||||
set = true;
|
||||
}
|
||||
else {
|
||||
value = "0";
|
||||
}
|
||||
break;
|
||||
case BMO_OP_SLOT_FLT: value = "0.0"; break;
|
||||
case BMO_OP_SLOT_PTR: value = "None"; break;
|
||||
case BMO_OP_SLOT_MAT: value = "Matrix()"; break;
|
||||
case BMO_OP_SLOT_VEC: value = "Vector()"; break;
|
||||
case BMO_OP_SLOT_ELEMENT_BUF: value =
|
||||
(slot_types[i].subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) ? "None" : "[]"; break;
|
||||
case BMO_OP_SLOT_MAPPING: value = "{}"; break;
|
||||
}
|
||||
BLI_dynstr_appendf(
|
||||
dyn_str, i ? ", %.*s=%s%s%s%s%s" : "%.*s=%s%s%s%s%s",
|
||||
name_len, slot_types[i].name,
|
||||
set ? "{" : "", quoted ? "'" : "",
|
||||
value,
|
||||
quoted ? "'" : "", set ? "}" : "");
|
||||
i++;
|
||||
}
|
||||
while (*slot_types[i].name) {
|
||||
quoted = false;
|
||||
set = false;
|
||||
/* cut off '.out' by using a string size arg */
|
||||
const int name_len = is_out ? (strchr(slot_types[i].name, '.') - slot_types[i].name) :
|
||||
sizeof(slot_types[i].name);
|
||||
const char *value = "<Unknown>";
|
||||
switch (slot_types[i].type) {
|
||||
case BMO_OP_SLOT_BOOL:
|
||||
value = "False";
|
||||
break;
|
||||
case BMO_OP_SLOT_INT:
|
||||
if (slot_types[i].subtype.intg == BMO_OP_SLOT_SUBTYPE_INT_ENUM) {
|
||||
value = slot_types[i].enum_flags[0].identifier;
|
||||
quoted = true;
|
||||
}
|
||||
else if (slot_types[i].subtype.intg == BMO_OP_SLOT_SUBTYPE_INT_FLAG) {
|
||||
value = "";
|
||||
set = true;
|
||||
}
|
||||
else {
|
||||
value = "0";
|
||||
}
|
||||
break;
|
||||
case BMO_OP_SLOT_FLT:
|
||||
value = "0.0";
|
||||
break;
|
||||
case BMO_OP_SLOT_PTR:
|
||||
value = "None";
|
||||
break;
|
||||
case BMO_OP_SLOT_MAT:
|
||||
value = "Matrix()";
|
||||
break;
|
||||
case BMO_OP_SLOT_VEC:
|
||||
value = "Vector()";
|
||||
break;
|
||||
case BMO_OP_SLOT_ELEMENT_BUF:
|
||||
value = (slot_types[i].subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) ? "None" : "[]";
|
||||
break;
|
||||
case BMO_OP_SLOT_MAPPING:
|
||||
value = "{}";
|
||||
break;
|
||||
}
|
||||
BLI_dynstr_appendf(dyn_str,
|
||||
i ? ", %.*s=%s%s%s%s%s" : "%.*s=%s%s%s%s%s",
|
||||
name_len,
|
||||
slot_types[i].name,
|
||||
set ? "{" : "",
|
||||
quoted ? "'" : "",
|
||||
value,
|
||||
quoted ? "'" : "",
|
||||
set ? "}" : "");
|
||||
i++;
|
||||
}
|
||||
|
||||
ret = BLI_dynstr_get_cstring(dyn_str);
|
||||
BLI_dynstr_free(dyn_str);
|
||||
return ret;
|
||||
ret = BLI_dynstr_get_cstring(dyn_str);
|
||||
BLI_dynstr_free(dyn_str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PyObject *bpy_bmesh_op_doc_get(BPy_BMeshOpFunc *self, void *UNUSED(closure))
|
||||
{
|
||||
PyObject *ret;
|
||||
char *slot_in;
|
||||
char *slot_out;
|
||||
int i;
|
||||
PyObject *ret;
|
||||
char *slot_in;
|
||||
char *slot_out;
|
||||
int i;
|
||||
|
||||
i = BMO_opcode_from_opname(self->opname);
|
||||
i = BMO_opcode_from_opname(self->opname);
|
||||
|
||||
slot_in = bmp_slots_as_args(bmo_opdefines[i]->slot_types_in, false);
|
||||
slot_out = bmp_slots_as_args(bmo_opdefines[i]->slot_types_out, true);
|
||||
slot_in = bmp_slots_as_args(bmo_opdefines[i]->slot_types_in, false);
|
||||
slot_out = bmp_slots_as_args(bmo_opdefines[i]->slot_types_out, true);
|
||||
|
||||
ret = PyUnicode_FromFormat("%.200s bmesh.ops.%.200s(bmesh, %s)\n -> dict(%s)",
|
||||
Py_TYPE(self)->tp_name,
|
||||
self->opname, slot_in, slot_out);
|
||||
ret = PyUnicode_FromFormat("%.200s bmesh.ops.%.200s(bmesh, %s)\n -> dict(%s)",
|
||||
Py_TYPE(self)->tp_name,
|
||||
self->opname,
|
||||
slot_in,
|
||||
slot_out);
|
||||
|
||||
MEM_freeN(slot_in);
|
||||
MEM_freeN(slot_out);
|
||||
MEM_freeN(slot_in);
|
||||
MEM_freeN(slot_out);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PyGetSetDef bpy_bmesh_op_getseters[] = {
|
||||
{(char *)"__doc__", (getter)bpy_bmesh_op_doc_get, (setter)NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
|
||||
{(char *)"__doc__", (getter)bpy_bmesh_op_doc_get, (setter)NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
/* Types
|
||||
* ===== */
|
||||
|
||||
static PyTypeObject bmesh_op_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"BMeshOpFunc", /* tp_name */
|
||||
sizeof(BPy_BMeshOpFunc), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
/* methods */
|
||||
NULL, /* tp_dealloc */
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
|
||||
(reprfunc) bpy_bmesh_op_repr, /* tp_repr */
|
||||
PyVarObject_HEAD_INIT(NULL, 0) "BMeshOpFunc", /* tp_name */
|
||||
sizeof(BPy_BMeshOpFunc), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
/* methods */
|
||||
NULL, /* tp_dealloc */
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
NULL,
|
||||
/* tp_compare */ /* DEPRECATED in python 3.0! */
|
||||
(reprfunc)bpy_bmesh_op_repr, /* tp_repr */
|
||||
|
||||
/* Method suites for standard classes */
|
||||
/* Method suites for standard classes */
|
||||
|
||||
NULL, /* PyNumberMethods *tp_as_number; */
|
||||
NULL, /* PySequenceMethods *tp_as_sequence; */
|
||||
NULL, /* PyMappingMethods *tp_as_mapping; */
|
||||
NULL, /* PyNumberMethods *tp_as_number; */
|
||||
NULL, /* PySequenceMethods *tp_as_sequence; */
|
||||
NULL, /* PyMappingMethods *tp_as_mapping; */
|
||||
|
||||
/* More standard operations (here for binary compatibility) */
|
||||
/* More standard operations (here for binary compatibility) */
|
||||
|
||||
NULL, /* hashfunc tp_hash; */
|
||||
(ternaryfunc)BPy_BMO_call, /* ternaryfunc tp_call; */
|
||||
NULL, /* reprfunc tp_str; */
|
||||
NULL, /* hashfunc tp_hash; */
|
||||
(ternaryfunc)BPy_BMO_call, /* ternaryfunc tp_call; */
|
||||
NULL, /* reprfunc tp_str; */
|
||||
|
||||
/* will only use these if this is a subtype of a py class */
|
||||
NULL, /* getattrofunc tp_getattro; */
|
||||
NULL, /* setattrofunc tp_setattro; */
|
||||
/* will only use these if this is a subtype of a py class */
|
||||
NULL, /* getattrofunc tp_getattro; */
|
||||
NULL, /* setattrofunc tp_setattro; */
|
||||
|
||||
/* Functions to access object as input/output buffer */
|
||||
NULL, /* PyBufferProcs *tp_as_buffer; */
|
||||
/* Functions to access object as input/output buffer */
|
||||
NULL, /* PyBufferProcs *tp_as_buffer; */
|
||||
|
||||
/*** Flags to define presence of optional/expanded features ***/
|
||||
Py_TPFLAGS_DEFAULT, /* long tp_flags; */
|
||||
/*** Flags to define presence of optional/expanded features ***/
|
||||
Py_TPFLAGS_DEFAULT, /* long tp_flags; */
|
||||
|
||||
NULL, /* char *tp_doc; Documentation string */
|
||||
/*** Assigned meaning in release 2.0 ***/
|
||||
/* call function for all accessible objects */
|
||||
NULL, /* traverseproc tp_traverse; */
|
||||
NULL, /* char *tp_doc; Documentation string */
|
||||
/*** Assigned meaning in release 2.0 ***/
|
||||
/* call function for all accessible objects */
|
||||
NULL, /* traverseproc tp_traverse; */
|
||||
|
||||
/* delete references to contained objects */
|
||||
NULL, /* inquiry tp_clear; */
|
||||
/* delete references to contained objects */
|
||||
NULL, /* inquiry tp_clear; */
|
||||
|
||||
/*** Assigned meaning in release 2.1 ***/
|
||||
/*** rich comparisons ***/
|
||||
NULL, /* richcmpfunc tp_richcompare; */
|
||||
/*** Assigned meaning in release 2.1 ***/
|
||||
/*** rich comparisons ***/
|
||||
NULL, /* richcmpfunc tp_richcompare; */
|
||||
|
||||
/*** weak reference enabler ***/
|
||||
0,
|
||||
/*** Added in release 2.2 ***/
|
||||
/* Iterators */
|
||||
NULL, /* getiterfunc tp_iter; */
|
||||
NULL, /* iternextfunc tp_iternext; */
|
||||
/*** weak reference enabler ***/
|
||||
0,
|
||||
/*** Added in release 2.2 ***/
|
||||
/* Iterators */
|
||||
NULL, /* getiterfunc tp_iter; */
|
||||
NULL, /* iternextfunc tp_iternext; */
|
||||
|
||||
/*** Attribute descriptor and subclassing stuff ***/
|
||||
NULL, /* struct PyMethodDef *tp_methods; */
|
||||
NULL, /* struct PyMemberDef *tp_members; */
|
||||
bpy_bmesh_op_getseters, /* struct PyGetSetDef *tp_getset; */
|
||||
NULL, /* struct _typeobject *tp_base; */
|
||||
NULL, /* PyObject *tp_dict; */
|
||||
NULL, /* descrgetfunc tp_descr_get; */
|
||||
NULL, /* descrsetfunc tp_descr_set; */
|
||||
0, /* long tp_dictoffset; */
|
||||
NULL, /* initproc tp_init; */
|
||||
NULL, /* allocfunc tp_alloc; */
|
||||
NULL, /* newfunc tp_new; */
|
||||
/* Low-level free-memory routine */
|
||||
NULL, /* freefunc tp_free; */
|
||||
/* For PyObject_IS_GC */
|
||||
NULL, /* inquiry tp_is_gc; */
|
||||
NULL, /* PyObject *tp_bases; */
|
||||
/* method resolution order */
|
||||
NULL, /* PyObject *tp_mro; */
|
||||
NULL, /* PyObject *tp_cache; */
|
||||
NULL, /* PyObject *tp_subclasses; */
|
||||
NULL, /* PyObject *tp_weaklist; */
|
||||
NULL,
|
||||
/*** Attribute descriptor and subclassing stuff ***/
|
||||
NULL, /* struct PyMethodDef *tp_methods; */
|
||||
NULL, /* struct PyMemberDef *tp_members; */
|
||||
bpy_bmesh_op_getseters, /* struct PyGetSetDef *tp_getset; */
|
||||
NULL, /* struct _typeobject *tp_base; */
|
||||
NULL, /* PyObject *tp_dict; */
|
||||
NULL, /* descrgetfunc tp_descr_get; */
|
||||
NULL, /* descrsetfunc tp_descr_set; */
|
||||
0, /* long tp_dictoffset; */
|
||||
NULL, /* initproc tp_init; */
|
||||
NULL, /* allocfunc tp_alloc; */
|
||||
NULL, /* newfunc tp_new; */
|
||||
/* Low-level free-memory routine */
|
||||
NULL, /* freefunc tp_free; */
|
||||
/* For PyObject_IS_GC */
|
||||
NULL, /* inquiry tp_is_gc; */
|
||||
NULL, /* PyObject *tp_bases; */
|
||||
/* method resolution order */
|
||||
NULL, /* PyObject *tp_mro; */
|
||||
NULL, /* PyObject *tp_cache; */
|
||||
NULL, /* PyObject *tp_subclasses; */
|
||||
NULL, /* PyObject *tp_weaklist; */
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
/* bmesh fake module 'bmesh.ops'
|
||||
* ***************************** */
|
||||
|
||||
static PyObject *bpy_bmesh_ops_fakemod_getattro(PyObject *UNUSED(self), PyObject *pyname)
|
||||
{
|
||||
const char *opname = _PyUnicode_AsString(pyname);
|
||||
const char *opname = _PyUnicode_AsString(pyname);
|
||||
|
||||
if (BMO_opcode_from_opname(opname) != -1) {
|
||||
return bpy_bmesh_op_CreatePyObject(opname);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"BMeshOpsModule: operator \"%.200s\" doesn't exist",
|
||||
opname);
|
||||
return NULL;
|
||||
}
|
||||
if (BMO_opcode_from_opname(opname) != -1) {
|
||||
return bpy_bmesh_op_CreatePyObject(opname);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(
|
||||
PyExc_AttributeError, "BMeshOpsModule: operator \"%.200s\" doesn't exist", opname);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *bpy_bmesh_ops_fakemod_dir(PyObject *UNUSED(self))
|
||||
{
|
||||
const unsigned int tot = bmo_opdefines_total;
|
||||
unsigned int i;
|
||||
PyObject *ret;
|
||||
const unsigned int tot = bmo_opdefines_total;
|
||||
unsigned int i;
|
||||
PyObject *ret;
|
||||
|
||||
ret = PyList_New(bmo_opdefines_total);
|
||||
ret = PyList_New(bmo_opdefines_total);
|
||||
|
||||
for (i = 0; i < tot; i++) {
|
||||
PyList_SET_ITEM(ret, i, PyUnicode_FromString(bmo_opdefines[i]->opname));
|
||||
}
|
||||
for (i = 0; i < tot; i++) {
|
||||
PyList_SET_ITEM(ret, i, PyUnicode_FromString(bmo_opdefines[i]->opname));
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct PyMethodDef bpy_bmesh_ops_fakemod_methods[] = {
|
||||
{"__dir__", (PyCFunction)bpy_bmesh_ops_fakemod_dir, METH_NOARGS, NULL},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"__dir__", (PyCFunction)bpy_bmesh_ops_fakemod_dir, METH_NOARGS, NULL},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
static PyTypeObject bmesh_ops_fakemod_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"BMeshOpsModule", /* tp_name */
|
||||
0, /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
/* methods */
|
||||
NULL, /* tp_dealloc */
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
|
||||
NULL, /* tp_repr */
|
||||
PyVarObject_HEAD_INIT(NULL, 0) "BMeshOpsModule", /* tp_name */
|
||||
0, /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
/* methods */
|
||||
NULL, /* tp_dealloc */
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
NULL,
|
||||
/* tp_compare */ /* DEPRECATED in python 3.0! */
|
||||
NULL, /* tp_repr */
|
||||
|
||||
/* Method suites for standard classes */
|
||||
/* Method suites for standard classes */
|
||||
|
||||
NULL, /* PyNumberMethods *tp_as_number; */
|
||||
NULL, /* PySequenceMethods *tp_as_sequence; */
|
||||
NULL, /* PyMappingMethods *tp_as_mapping; */
|
||||
NULL, /* PyNumberMethods *tp_as_number; */
|
||||
NULL, /* PySequenceMethods *tp_as_sequence; */
|
||||
NULL, /* PyMappingMethods *tp_as_mapping; */
|
||||
|
||||
/* More standard operations (here for binary compatibility) */
|
||||
/* More standard operations (here for binary compatibility) */
|
||||
|
||||
NULL, /* hashfunc tp_hash; */
|
||||
NULL, /* ternaryfunc tp_call; */
|
||||
NULL, /* reprfunc tp_str; */
|
||||
NULL, /* hashfunc tp_hash; */
|
||||
NULL, /* ternaryfunc tp_call; */
|
||||
NULL, /* reprfunc tp_str; */
|
||||
|
||||
/* will only use these if this is a subtype of a py class */
|
||||
bpy_bmesh_ops_fakemod_getattro, /* getattrofunc tp_getattro; */
|
||||
NULL, /* setattrofunc tp_setattro; */
|
||||
/* will only use these if this is a subtype of a py class */
|
||||
bpy_bmesh_ops_fakemod_getattro, /* getattrofunc tp_getattro; */
|
||||
NULL, /* setattrofunc tp_setattro; */
|
||||
|
||||
/* Functions to access object as input/output buffer */
|
||||
NULL, /* PyBufferProcs *tp_as_buffer; */
|
||||
/* Functions to access object as input/output buffer */
|
||||
NULL, /* PyBufferProcs *tp_as_buffer; */
|
||||
|
||||
/*** Flags to define presence of optional/expanded features ***/
|
||||
Py_TPFLAGS_DEFAULT, /* long tp_flags; */
|
||||
/*** Flags to define presence of optional/expanded features ***/
|
||||
Py_TPFLAGS_DEFAULT, /* long tp_flags; */
|
||||
|
||||
NULL, /* char *tp_doc; Documentation string */
|
||||
/*** Assigned meaning in release 2.0 ***/
|
||||
/* call function for all accessible objects */
|
||||
NULL, /* traverseproc tp_traverse; */
|
||||
NULL, /* char *tp_doc; Documentation string */
|
||||
/*** Assigned meaning in release 2.0 ***/
|
||||
/* call function for all accessible objects */
|
||||
NULL, /* traverseproc tp_traverse; */
|
||||
|
||||
/* delete references to contained objects */
|
||||
NULL, /* inquiry tp_clear; */
|
||||
/* delete references to contained objects */
|
||||
NULL, /* inquiry tp_clear; */
|
||||
|
||||
/*** Assigned meaning in release 2.1 ***/
|
||||
/*** rich comparisons (subclassed) ***/
|
||||
NULL, /* richcmpfunc tp_richcompare; */
|
||||
/*** Assigned meaning in release 2.1 ***/
|
||||
/*** rich comparisons (subclassed) ***/
|
||||
NULL, /* richcmpfunc tp_richcompare; */
|
||||
|
||||
/*** weak reference enabler ***/
|
||||
0,
|
||||
/*** Added in release 2.2 ***/
|
||||
/* Iterators */
|
||||
NULL, /* getiterfunc tp_iter; */
|
||||
NULL, /* iternextfunc tp_iternext; */
|
||||
/*** weak reference enabler ***/
|
||||
0,
|
||||
/*** Added in release 2.2 ***/
|
||||
/* Iterators */
|
||||
NULL, /* getiterfunc tp_iter; */
|
||||
NULL, /* iternextfunc tp_iternext; */
|
||||
|
||||
/*** Attribute descriptor and subclassing stuff ***/
|
||||
bpy_bmesh_ops_fakemod_methods, /* struct PyMethodDef *tp_methods; */
|
||||
NULL, /* struct PyMemberDef *tp_members; */
|
||||
NULL, /* struct PyGetSetDef *tp_getset; */
|
||||
NULL, /* struct _typeobject *tp_base; */
|
||||
NULL, /* PyObject *tp_dict; */
|
||||
NULL, /* descrgetfunc tp_descr_get; */
|
||||
NULL, /* descrsetfunc tp_descr_set; */
|
||||
0, /* long tp_dictoffset; */
|
||||
NULL, /* initproc tp_init; */
|
||||
NULL, /* allocfunc tp_alloc; */
|
||||
NULL, /* newfunc tp_new; */
|
||||
/* Low-level free-memory routine */
|
||||
NULL, /* freefunc tp_free; */
|
||||
/* For PyObject_IS_GC */
|
||||
NULL, /* inquiry tp_is_gc; */
|
||||
NULL, /* PyObject *tp_bases; */
|
||||
/* method resolution order */
|
||||
NULL, /* PyObject *tp_mro; */
|
||||
NULL, /* PyObject *tp_cache; */
|
||||
NULL, /* PyObject *tp_subclasses; */
|
||||
NULL, /* PyObject *tp_weaklist; */
|
||||
NULL,
|
||||
/*** Attribute descriptor and subclassing stuff ***/
|
||||
bpy_bmesh_ops_fakemod_methods, /* struct PyMethodDef *tp_methods; */
|
||||
NULL, /* struct PyMemberDef *tp_members; */
|
||||
NULL, /* struct PyGetSetDef *tp_getset; */
|
||||
NULL, /* struct _typeobject *tp_base; */
|
||||
NULL, /* PyObject *tp_dict; */
|
||||
NULL, /* descrgetfunc tp_descr_get; */
|
||||
NULL, /* descrsetfunc tp_descr_set; */
|
||||
0, /* long tp_dictoffset; */
|
||||
NULL, /* initproc tp_init; */
|
||||
NULL, /* allocfunc tp_alloc; */
|
||||
NULL, /* newfunc tp_new; */
|
||||
/* Low-level free-memory routine */
|
||||
NULL, /* freefunc tp_free; */
|
||||
/* For PyObject_IS_GC */
|
||||
NULL, /* inquiry tp_is_gc; */
|
||||
NULL, /* PyObject *tp_bases; */
|
||||
/* method resolution order */
|
||||
NULL, /* PyObject *tp_mro; */
|
||||
NULL, /* PyObject *tp_cache; */
|
||||
NULL, /* PyObject *tp_subclasses; */
|
||||
NULL, /* PyObject *tp_weaklist; */
|
||||
NULL,
|
||||
};
|
||||
|
||||
PyObject *BPyInit_bmesh_ops(void)
|
||||
{
|
||||
PyObject *submodule;
|
||||
PyObject *submodule;
|
||||
|
||||
if (PyType_Ready(&bmesh_ops_fakemod_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&bmesh_ops_fakemod_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&bmesh_op_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&bmesh_op_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
submodule = PyObject_New(PyObject, &bmesh_ops_fakemod_Type);
|
||||
submodule = PyObject_New(PyObject, &bmesh_ops_fakemod_Type);
|
||||
|
||||
/* prevent further creation of instances */
|
||||
bmesh_ops_fakemod_Type.tp_init = NULL;
|
||||
bmesh_ops_fakemod_Type.tp_new = NULL;
|
||||
/* prevent further creation of instances */
|
||||
bmesh_ops_fakemod_Type.tp_init = NULL;
|
||||
bmesh_ops_fakemod_Type.tp_new = NULL;
|
||||
|
||||
return submodule;
|
||||
return submodule;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,11 +25,10 @@
|
||||
#define __BMESH_PY_OPS_CALL_H__
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD /* required python macro */
|
||||
const char *opname;
|
||||
PyObject_HEAD /* required python macro */
|
||||
const char *opname;
|
||||
} BPy_BMeshOpFunc;
|
||||
|
||||
|
||||
PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw);
|
||||
|
||||
#endif /* __BMESH_PY_OPS_CALL_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -38,65 +38,57 @@ extern PyTypeObject BPy_BMLoopSeq_Type;
|
||||
|
||||
extern PyTypeObject BPy_BMIter_Type;
|
||||
|
||||
#define BPy_BMesh_Check(v) (Py_TYPE(v) == &BPy_BMesh_Type)
|
||||
#define BPy_BMVert_Check(v) (Py_TYPE(v) == &BPy_BMVert_Type)
|
||||
#define BPy_BMEdge_Check(v) (Py_TYPE(v) == &BPy_BMEdge_Type)
|
||||
#define BPy_BMFace_Check(v) (Py_TYPE(v) == &BPy_BMFace_Type)
|
||||
#define BPy_BMLoop_Check(v) (Py_TYPE(v) == &BPy_BMLoop_Type)
|
||||
#define BPy_BMElemSeq_Check(v) (Py_TYPE(v) == &BPy_BMElemSeq_Type)
|
||||
#define BPy_BMVertSeq_Check(v) (Py_TYPE(v) == &BPy_BMVertSeq_Type)
|
||||
#define BPy_BMEdgeSeq_Check(v) (Py_TYPE(v) == &BPy_BMEdgeSeq_Type)
|
||||
#define BPy_BMFaceSeq_Check(v) (Py_TYPE(v) == &BPy_BMFaceSeq_Type)
|
||||
#define BPy_BMLoopSeq_Check(v) (Py_TYPE(v) == &BPy_BMLoopSeq_Type)
|
||||
#define BPy_BMIter_Check(v) (Py_TYPE(v) == &BPy_BMIter_Type)
|
||||
#define BPy_BMesh_Check(v) (Py_TYPE(v) == &BPy_BMesh_Type)
|
||||
#define BPy_BMVert_Check(v) (Py_TYPE(v) == &BPy_BMVert_Type)
|
||||
#define BPy_BMEdge_Check(v) (Py_TYPE(v) == &BPy_BMEdge_Type)
|
||||
#define BPy_BMFace_Check(v) (Py_TYPE(v) == &BPy_BMFace_Type)
|
||||
#define BPy_BMLoop_Check(v) (Py_TYPE(v) == &BPy_BMLoop_Type)
|
||||
#define BPy_BMElemSeq_Check(v) (Py_TYPE(v) == &BPy_BMElemSeq_Type)
|
||||
#define BPy_BMVertSeq_Check(v) (Py_TYPE(v) == &BPy_BMVertSeq_Type)
|
||||
#define BPy_BMEdgeSeq_Check(v) (Py_TYPE(v) == &BPy_BMEdgeSeq_Type)
|
||||
#define BPy_BMFaceSeq_Check(v) (Py_TYPE(v) == &BPy_BMFaceSeq_Type)
|
||||
#define BPy_BMLoopSeq_Check(v) (Py_TYPE(v) == &BPy_BMLoopSeq_Type)
|
||||
#define BPy_BMIter_Check(v) (Py_TYPE(v) == &BPy_BMIter_Type)
|
||||
/* trick since we know they share a hash function */
|
||||
#define BPy_BMElem_Check(v) (Py_TYPE(v)->tp_hash == BPy_BMVert_Type.tp_hash)
|
||||
#define BPy_BMElem_Check(v) (Py_TYPE(v)->tp_hash == BPy_BMVert_Type.tp_hash)
|
||||
|
||||
/* cast from _any_ bmesh type - they all have BMesh first */
|
||||
typedef struct BPy_BMGeneric {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
} BPy_BMGeneric;
|
||||
|
||||
/* BPy_BMVert/BPy_BMEdge/BPy_BMFace/BPy_BMLoop can cast to this */
|
||||
typedef struct BPy_BMElem {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
struct BMElem *ele;
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
struct BMElem *ele;
|
||||
} BPy_BMElem;
|
||||
|
||||
typedef struct BPy_BMesh {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
int flag;
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
int flag;
|
||||
} BPy_BMesh;
|
||||
|
||||
/* element types */
|
||||
typedef struct BPy_BMVert {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
struct BMVert *v;
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
struct BMVert *v;
|
||||
} BPy_BMVert;
|
||||
|
||||
typedef struct BPy_BMEdge {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
struct BMEdge *e;
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
struct BMEdge *e;
|
||||
} BPy_BMEdge;
|
||||
|
||||
typedef struct BPy_BMFace {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
struct BMFace *f;
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
struct BMFace *f;
|
||||
} BPy_BMFace;
|
||||
|
||||
typedef struct BPy_BMLoop {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
struct BMLoop *l;
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
struct BMLoop *l;
|
||||
} BPy_BMLoop;
|
||||
|
||||
|
||||
/* iterators */
|
||||
|
||||
/* used for ...
|
||||
@@ -107,26 +99,24 @@ typedef struct BPy_BMLoop {
|
||||
* - BPy_BMLoopSeq_Type
|
||||
*/
|
||||
typedef struct BPy_BMElemSeq {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
|
||||
/* if this is a sequence on an existing element,
|
||||
* loops of faces for eg.
|
||||
* If this variable is set, it will be used */
|
||||
/* if this is a sequence on an existing element,
|
||||
* loops of faces for eg.
|
||||
* If this variable is set, it will be used */
|
||||
|
||||
/* we hold a reference to this.
|
||||
* check in case the owner becomes invalid on access */
|
||||
/* TODO - make this a GC'd object!, will function OK without this though */
|
||||
BPy_BMElem *py_ele;
|
||||
/* we hold a reference to this.
|
||||
* check in case the owner becomes invalid on access */
|
||||
/* TODO - make this a GC'd object!, will function OK without this though */
|
||||
BPy_BMElem *py_ele;
|
||||
|
||||
/* iterator type */
|
||||
short itype;
|
||||
/* iterator type */
|
||||
short itype;
|
||||
} BPy_BMElemSeq;
|
||||
|
||||
typedef struct BPy_BMIter {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
BMIter iter;
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
BMIter iter;
|
||||
} BPy_BMIter;
|
||||
|
||||
void BPy_BM_init_types(void);
|
||||
@@ -134,8 +124,8 @@ void BPy_BM_init_types(void);
|
||||
PyObject *BPyInit_bmesh_types(void);
|
||||
|
||||
enum {
|
||||
BPY_BMFLAG_NOP = 0, /* do nothing */
|
||||
BPY_BMFLAG_IS_WRAPPED = 1, /* the mesh is owned by editmode */
|
||||
BPY_BMFLAG_NOP = 0, /* do nothing */
|
||||
BPY_BMFLAG_IS_WRAPPED = 1, /* the mesh is owned by editmode */
|
||||
};
|
||||
|
||||
PyObject *BPy_BMesh_CreatePyObject(BMesh *bm, int flag);
|
||||
@@ -150,18 +140,27 @@ PyObject *BPy_BMFaceSeq_CreatePyObject(BMesh *bm);
|
||||
PyObject *BPy_BMLoopSeq_CreatePyObject(BMesh *bm);
|
||||
PyObject *BPy_BMIter_CreatePyObject(BMesh *bm);
|
||||
|
||||
PyObject *BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele); /* just checks type and creates v/e/f/l */
|
||||
PyObject *BPy_BMElem_CreatePyObject(BMesh *bm,
|
||||
BMHeader *ele); /* just checks type and creates v/e/f/l */
|
||||
|
||||
void *BPy_BMElem_PySeq_As_Array_FAST(
|
||||
BMesh **r_bm, PyObject *seq_fast, Py_ssize_t min, Py_ssize_t max, Py_ssize_t *r_size,
|
||||
const char htype,
|
||||
const bool do_unique_check, const bool do_bm_check,
|
||||
const char *error_prefix);
|
||||
void *BPy_BMElem_PySeq_As_Array(
|
||||
BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, Py_ssize_t *r_size,
|
||||
const char htype,
|
||||
const bool do_unique_check, const bool do_bm_check,
|
||||
const char *error_prefix);
|
||||
void *BPy_BMElem_PySeq_As_Array_FAST(BMesh **r_bm,
|
||||
PyObject *seq_fast,
|
||||
Py_ssize_t min,
|
||||
Py_ssize_t max,
|
||||
Py_ssize_t *r_size,
|
||||
const char htype,
|
||||
const bool do_unique_check,
|
||||
const bool do_bm_check,
|
||||
const char *error_prefix);
|
||||
void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm,
|
||||
PyObject *seq,
|
||||
Py_ssize_t min,
|
||||
Py_ssize_t max,
|
||||
Py_ssize_t *r_size,
|
||||
const char htype,
|
||||
const bool do_unique_check,
|
||||
const bool do_bm_check,
|
||||
const char *error_prefix);
|
||||
|
||||
PyObject *BPy_BMElem_Array_As_Tuple(BMesh *bm, BMHeader **elem, Py_ssize_t elem_len);
|
||||
PyObject *BPy_BMVert_Array_As_Tuple(BMesh *bm, BMVert **elem, Py_ssize_t elem_len);
|
||||
@@ -169,47 +168,58 @@ PyObject *BPy_BMEdge_Array_As_Tuple(BMesh *bm, BMEdge **elem, Py_ssize_t elem_le
|
||||
PyObject *BPy_BMFace_Array_As_Tuple(BMesh *bm, BMFace **elem, Py_ssize_t elem_len);
|
||||
PyObject *BPy_BMLoop_Array_As_Tuple(BMesh *bm, BMLoop **elem, Py_ssize_t elem_len);
|
||||
|
||||
int BPy_BMElem_CheckHType(PyTypeObject *type, const char htype);
|
||||
char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32]);
|
||||
char *BPy_BMElem_StringFromHType(const char htype);
|
||||
int BPy_BMElem_CheckHType(PyTypeObject *type, const char htype);
|
||||
char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32]);
|
||||
char *BPy_BMElem_StringFromHType(const char htype);
|
||||
|
||||
// void bpy_bm_generic_invalidate(BPy_BMGeneric *self);
|
||||
int bpy_bm_generic_valid_check(BPy_BMGeneric *self);
|
||||
int bpy_bm_generic_valid_check_source(BMesh *bm_source, const char *error_prefix, void **args, unsigned int args_n) ATTR_NONNULL(1, 2);
|
||||
int bpy_bm_generic_valid_check(BPy_BMGeneric *self);
|
||||
int bpy_bm_generic_valid_check_source(BMesh *bm_source,
|
||||
const char *error_prefix,
|
||||
void **args,
|
||||
unsigned int args_n) ATTR_NONNULL(1, 2);
|
||||
|
||||
#define BPY_BM_CHECK_OBJ(obj) \
|
||||
if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return NULL; } (void)0
|
||||
if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
(void)0
|
||||
#define BPY_BM_CHECK_INT(obj) \
|
||||
if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return -1; } (void)0
|
||||
if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { \
|
||||
return -1; \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
/* macros like BPY_BM_CHECK_OBJ/BPY_BM_CHECK_INT that ensure we're from the right BMesh */
|
||||
#define BPY_BM_CHECK_SOURCE_OBJ(bm, errmsg, ...) { \
|
||||
void *_args[] = {__VA_ARGS__}; \
|
||||
if (UNLIKELY(bpy_bm_generic_valid_check_source(bm, errmsg, _args, ARRAY_SIZE(_args)) == -1)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
} (void)0
|
||||
#define BPY_BM_CHECK_SOURCE_INT(bm, errmsg, ...) { \
|
||||
void *_args[] = {__VA_ARGS__}; \
|
||||
if (UNLIKELY(bpy_bm_generic_valid_check_source(bm, errmsg, _args, ARRAY_SIZE(_args)) == -1)) { \
|
||||
return -1; \
|
||||
} \
|
||||
} (void)0
|
||||
#define BPY_BM_CHECK_SOURCE_OBJ(bm, errmsg, ...) \
|
||||
{ \
|
||||
void *_args[] = {__VA_ARGS__}; \
|
||||
if (UNLIKELY(bpy_bm_generic_valid_check_source(bm, errmsg, _args, ARRAY_SIZE(_args)) == \
|
||||
-1)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
} \
|
||||
(void)0
|
||||
#define BPY_BM_CHECK_SOURCE_INT(bm, errmsg, ...) \
|
||||
{ \
|
||||
void *_args[] = {__VA_ARGS__}; \
|
||||
if (UNLIKELY(bpy_bm_generic_valid_check_source(bm, errmsg, _args, ARRAY_SIZE(_args)) == \
|
||||
-1)) { \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
#define BPY_BM_IS_VALID(obj) (LIKELY((obj)->bm != NULL))
|
||||
|
||||
#define BM_ITER_BPY_BM_SEQ(ele, iter, bpy_bmelemseq) \
|
||||
for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new( \
|
||||
iter, \
|
||||
(bpy_bmelemseq)->bm, \
|
||||
(bpy_bmelemseq)->itype, \
|
||||
(bpy_bmelemseq)->py_ele ? \
|
||||
((BPy_BMElem *)(bpy_bmelemseq)->py_ele)->ele : \
|
||||
NULL \
|
||||
); \
|
||||
ele; \
|
||||
BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
|
||||
|
||||
#define BM_ITER_BPY_BM_SEQ(ele, iter, bpy_bmelemseq) \
|
||||
for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new( \
|
||||
iter, \
|
||||
(bpy_bmelemseq)->bm, \
|
||||
(bpy_bmelemseq)->itype, \
|
||||
(bpy_bmelemseq)->py_ele ? ((BPy_BMElem *)(bpy_bmelemseq)->py_ele)->ele : NULL); \
|
||||
ele; \
|
||||
BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
|
||||
|
||||
#ifdef __PY_CAPI_UTILS_H__
|
||||
struct PyC_FlagSet;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,32 +33,29 @@ extern PyTypeObject BPy_BMLayerAccessLoop_Type;
|
||||
extern PyTypeObject BPy_BMLayerCollection_Type;
|
||||
extern PyTypeObject BPy_BMLayerItem_Type;
|
||||
|
||||
#define BPy_BMLayerAccess_Check(v) (Py_TYPE(v) == &BPy_BMLayerAccess_Type)
|
||||
#define BPy_BMLayerCollection_Check(v) (Py_TYPE(v) == &BPy_BMLayerCollection_Type)
|
||||
#define BPy_BMLayerItem_Check(v) (Py_TYPE(v) == &BPy_BMLayerItem_Type)
|
||||
#define BPy_BMLayerAccess_Check(v) (Py_TYPE(v) == &BPy_BMLayerAccess_Type)
|
||||
#define BPy_BMLayerCollection_Check(v) (Py_TYPE(v) == &BPy_BMLayerCollection_Type)
|
||||
#define BPy_BMLayerItem_Check(v) (Py_TYPE(v) == &BPy_BMLayerItem_Type)
|
||||
|
||||
/* all layers for vert/edge/face/loop */
|
||||
typedef struct BPy_BMLayerAccess {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
char htype;
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
char htype;
|
||||
} BPy_BMLayerAccess;
|
||||
|
||||
/* access different layer types deform/uv/vertexcolor */
|
||||
typedef struct BPy_BMLayerCollection {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
char htype;
|
||||
int type; /* customdata type - CD_XXX */
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
char htype;
|
||||
int type; /* customdata type - CD_XXX */
|
||||
} BPy_BMLayerCollection;
|
||||
|
||||
/* access a specific layer directly */
|
||||
typedef struct BPy_BMLayerItem {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
char htype;
|
||||
int type; /* customdata type - CD_XXX */
|
||||
int index; /* index of this layer type */
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
char htype;
|
||||
int type; /* customdata type - CD_XXX */
|
||||
int index; /* index of this layer type */
|
||||
} BPy_BMLayerItem;
|
||||
|
||||
PyObject *BPy_BMLayerAccess_CreatePyObject(BMesh *bm, const char htype);
|
||||
@@ -69,7 +66,6 @@ void BPy_BM_init_types_customdata(void);
|
||||
|
||||
/* __getitem__ / __setitem__ */
|
||||
PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer);
|
||||
int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObject *value);
|
||||
|
||||
int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObject *value);
|
||||
|
||||
#endif /* __BMESH_PY_TYPES_CUSTOMDATA_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,11 +27,10 @@
|
||||
extern PyTypeObject BPy_BMLoopUV_Type;
|
||||
extern PyTypeObject BPy_BMDeformVert_Type;
|
||||
|
||||
#define BPy_BMLoopUV_Check(v) (Py_TYPE(v) == &BPy_BMLoopUV_Type)
|
||||
#define BPy_BMLoopUV_Check(v) (Py_TYPE(v) == &BPy_BMLoopUV_Type)
|
||||
|
||||
typedef struct BPy_BMGenericMeshData {
|
||||
PyObject_VAR_HEAD
|
||||
void *data;
|
||||
PyObject_VAR_HEAD void *data;
|
||||
} BPy_BMGenericMeshData;
|
||||
|
||||
struct MDeformVert;
|
||||
@@ -39,19 +38,18 @@ struct MLoopCol;
|
||||
struct MLoopUV;
|
||||
struct MVertSkin;
|
||||
|
||||
int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *data, PyObject *value);
|
||||
int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *data, PyObject *value);
|
||||
PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *data);
|
||||
|
||||
int BPy_BMVertSkin_AssignPyObject(struct MVertSkin *data, PyObject *value);
|
||||
int BPy_BMVertSkin_AssignPyObject(struct MVertSkin *data, PyObject *value);
|
||||
PyObject *BPy_BMVertSkin_CreatePyObject(struct MVertSkin *data);
|
||||
|
||||
int BPy_BMLoopColor_AssignPyObject(struct MLoopCol *data, PyObject *value);
|
||||
int BPy_BMLoopColor_AssignPyObject(struct MLoopCol *data, PyObject *value);
|
||||
PyObject *BPy_BMLoopColor_CreatePyObject(struct MLoopCol *data);
|
||||
|
||||
int BPy_BMDeformVert_AssignPyObject(struct MDeformVert *dvert, PyObject *value);
|
||||
int BPy_BMDeformVert_AssignPyObject(struct MDeformVert *dvert, PyObject *value);
|
||||
PyObject *BPy_BMDeformVert_CreatePyObject(struct MDeformVert *dvert);
|
||||
|
||||
|
||||
void BPy_BM_init_types_meshdata(void);
|
||||
|
||||
#endif /* __BMESH_PY_TYPES_MESHDATA_H__ */
|
||||
|
||||
@@ -41,397 +41,387 @@
|
||||
#include "../generic/python_utildefines.h"
|
||||
|
||||
PyDoc_STRVAR(bpy_bmeditselseq_active_doc,
|
||||
"The last selected element or None (read-only).\n\n:type: :class:`BMVert`, :class:`BMEdge` or :class:`BMFace`"
|
||||
);
|
||||
"The last selected element or None (read-only).\n\n:type: :class:`BMVert`, "
|
||||
":class:`BMEdge` or :class:`BMFace`");
|
||||
static PyObject *bpy_bmeditselseq_active_get(BPy_BMEditSelSeq *self, void *UNUSED(closure))
|
||||
{
|
||||
BMEditSelection *ese;
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
BMEditSelection *ese;
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
|
||||
if ((ese = self->bm->selected.last)) {
|
||||
return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
|
||||
}
|
||||
else {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
if ((ese = self->bm->selected.last)) {
|
||||
return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
|
||||
}
|
||||
else {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static PyGetSetDef bpy_bmeditselseq_getseters[] = {
|
||||
{(char *)"active", (getter)bpy_bmeditselseq_active_get, (setter)NULL, (char *)bpy_bmeditselseq_active_doc, NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
|
||||
{(char *)"active",
|
||||
(getter)bpy_bmeditselseq_active_get,
|
||||
(setter)NULL,
|
||||
(char *)bpy_bmeditselseq_active_doc,
|
||||
NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(bpy_bmeditselseq_validate_doc,
|
||||
".. method:: validate()\n"
|
||||
"\n"
|
||||
" Ensures all elements in the selection history are selected.\n"
|
||||
);
|
||||
".. method:: validate()\n"
|
||||
"\n"
|
||||
" Ensures all elements in the selection history are selected.\n");
|
||||
static PyObject *bpy_bmeditselseq_validate(BPy_BMEditSelSeq *self)
|
||||
{
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
BM_select_history_validate(self->bm);
|
||||
Py_RETURN_NONE;
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
BM_select_history_validate(self->bm);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_bmeditselseq_clear_doc,
|
||||
".. method:: clear()\n"
|
||||
"\n"
|
||||
" Empties the selection history.\n"
|
||||
);
|
||||
".. method:: clear()\n"
|
||||
"\n"
|
||||
" Empties the selection history.\n");
|
||||
static PyObject *bpy_bmeditselseq_clear(BPy_BMEditSelSeq *self)
|
||||
{
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
BM_select_history_clear(self->bm);
|
||||
Py_RETURN_NONE;
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
BM_select_history_clear(self->bm);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_bmeditselseq_add_doc,
|
||||
".. method:: add(element)\n"
|
||||
"\n"
|
||||
" Add an element to the selection history (no action taken if its already added).\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpy_bmeditselseq_add_doc,
|
||||
".. method:: add(element)\n"
|
||||
"\n"
|
||||
" Add an element to the selection history (no action taken if its already added).\n");
|
||||
static PyObject *bpy_bmeditselseq_add(BPy_BMEditSelSeq *self, BPy_BMElem *value)
|
||||
{
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
|
||||
if ((BPy_BMVert_Check(value) ||
|
||||
BPy_BMEdge_Check(value) ||
|
||||
BPy_BMFace_Check(value)) == false)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Expected a BMVert/BMedge/BMFace not a %.200s", Py_TYPE(value)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
if ((BPy_BMVert_Check(value) || BPy_BMEdge_Check(value) || BPy_BMFace_Check(value)) == false) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError, "Expected a BMVert/BMedge/BMFace not a %.200s", Py_TYPE(value)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_BM_CHECK_SOURCE_OBJ(self->bm, "select_history.add()", value);
|
||||
BPY_BM_CHECK_SOURCE_OBJ(self->bm, "select_history.add()", value);
|
||||
|
||||
BM_select_history_store(self->bm, value->ele);
|
||||
BM_select_history_store(self->bm, value->ele);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_bmeditselseq_remove_doc,
|
||||
".. method:: remove(element)\n"
|
||||
"\n"
|
||||
" Remove an element from the selection history.\n"
|
||||
);
|
||||
".. method:: remove(element)\n"
|
||||
"\n"
|
||||
" Remove an element from the selection history.\n");
|
||||
static PyObject *bpy_bmeditselseq_remove(BPy_BMEditSelSeq *self, BPy_BMElem *value)
|
||||
{
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
|
||||
if ((BPy_BMVert_Check(value) ||
|
||||
BPy_BMEdge_Check(value) ||
|
||||
BPy_BMFace_Check(value)) == false)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Expected a BMVert/BMedge/BMFace not a %.200s", Py_TYPE(value)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
if ((BPy_BMVert_Check(value) || BPy_BMEdge_Check(value) || BPy_BMFace_Check(value)) == false) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError, "Expected a BMVert/BMedge/BMFace not a %.200s", Py_TYPE(value)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_BM_CHECK_SOURCE_OBJ(self->bm, "select_history.remove()", value);
|
||||
BPY_BM_CHECK_SOURCE_OBJ(self->bm, "select_history.remove()", value);
|
||||
|
||||
if (BM_select_history_remove(self->bm, value->ele) == false) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Element not found in selection history");
|
||||
return NULL;
|
||||
}
|
||||
if (BM_select_history_remove(self->bm, value->ele) == false) {
|
||||
PyErr_SetString(PyExc_ValueError, "Element not found in selection history");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_bmeditselseq_discard_doc,
|
||||
".. method:: discard(element)\n"
|
||||
"\n"
|
||||
" Discard an element from the selection history.\n"
|
||||
"\n"
|
||||
" Like remove but doesn't raise an error when the elements not in the selection list.\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpy_bmeditselseq_discard_doc,
|
||||
".. method:: discard(element)\n"
|
||||
"\n"
|
||||
" Discard an element from the selection history.\n"
|
||||
"\n"
|
||||
" Like remove but doesn't raise an error when the elements not in the selection list.\n");
|
||||
static PyObject *bpy_bmeditselseq_discard(BPy_BMEditSelSeq *self, BPy_BMElem *value)
|
||||
{
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
|
||||
if ((BPy_BMVert_Check(value) ||
|
||||
BPy_BMEdge_Check(value) ||
|
||||
BPy_BMFace_Check(value)) == false)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Expected a BMVert/BMedge/BMFace not a %.200s", Py_TYPE(value)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
if ((BPy_BMVert_Check(value) || BPy_BMEdge_Check(value) || BPy_BMFace_Check(value)) == false) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError, "Expected a BMVert/BMedge/BMFace not a %.200s", Py_TYPE(value)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_BM_CHECK_SOURCE_OBJ(self->bm, "select_history.discard()", value);
|
||||
BPY_BM_CHECK_SOURCE_OBJ(self->bm, "select_history.discard()", value);
|
||||
|
||||
BM_select_history_remove(self->bm, value->ele);
|
||||
BM_select_history_remove(self->bm, value->ele);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static struct PyMethodDef bpy_bmeditselseq_methods[] = {
|
||||
{"validate", (PyCFunction)bpy_bmeditselseq_validate, METH_NOARGS, bpy_bmeditselseq_validate_doc},
|
||||
{"clear", (PyCFunction)bpy_bmeditselseq_clear, METH_NOARGS, bpy_bmeditselseq_clear_doc},
|
||||
{"validate",
|
||||
(PyCFunction)bpy_bmeditselseq_validate,
|
||||
METH_NOARGS,
|
||||
bpy_bmeditselseq_validate_doc},
|
||||
{"clear", (PyCFunction)bpy_bmeditselseq_clear, METH_NOARGS, bpy_bmeditselseq_clear_doc},
|
||||
|
||||
{"add", (PyCFunction)bpy_bmeditselseq_add, METH_O, bpy_bmeditselseq_add_doc},
|
||||
{"remove", (PyCFunction)bpy_bmeditselseq_remove, METH_O, bpy_bmeditselseq_remove_doc},
|
||||
{"discard", (PyCFunction)bpy_bmeditselseq_discard, METH_O, bpy_bmeditselseq_discard_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"add", (PyCFunction)bpy_bmeditselseq_add, METH_O, bpy_bmeditselseq_add_doc},
|
||||
{"remove", (PyCFunction)bpy_bmeditselseq_remove, METH_O, bpy_bmeditselseq_remove_doc},
|
||||
{"discard", (PyCFunction)bpy_bmeditselseq_discard, METH_O, bpy_bmeditselseq_discard_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
|
||||
/* Sequences
|
||||
* ========= */
|
||||
|
||||
static Py_ssize_t bpy_bmeditselseq_length(BPy_BMEditSelSeq *self)
|
||||
{
|
||||
BPY_BM_CHECK_INT(self);
|
||||
BPY_BM_CHECK_INT(self);
|
||||
|
||||
return BLI_listbase_count(&self->bm->selected);
|
||||
return BLI_listbase_count(&self->bm->selected);
|
||||
}
|
||||
|
||||
static PyObject *bpy_bmeditselseq_subscript_int(BPy_BMEditSelSeq *self, int keynum)
|
||||
{
|
||||
BMEditSelection *ese;
|
||||
BMEditSelection *ese;
|
||||
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
|
||||
if (keynum < 0) {
|
||||
ese = BLI_rfindlink(&self->bm->selected, -1 - keynum);
|
||||
}
|
||||
else {
|
||||
ese = BLI_findlink(&self->bm->selected, keynum);
|
||||
}
|
||||
if (keynum < 0) {
|
||||
ese = BLI_rfindlink(&self->bm->selected, -1 - keynum);
|
||||
}
|
||||
else {
|
||||
ese = BLI_findlink(&self->bm->selected, keynum);
|
||||
}
|
||||
|
||||
if (ese) {
|
||||
return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_IndexError,
|
||||
"BMElemSeq[index]: index %d out of range", keynum);
|
||||
return NULL;
|
||||
}
|
||||
if (ese) {
|
||||
return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_IndexError, "BMElemSeq[index]: index %d out of range", keynum);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self, Py_ssize_t start, Py_ssize_t stop)
|
||||
static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self,
|
||||
Py_ssize_t start,
|
||||
Py_ssize_t stop)
|
||||
{
|
||||
int count = 0;
|
||||
bool ok;
|
||||
int count = 0;
|
||||
bool ok;
|
||||
|
||||
PyObject *list;
|
||||
BMEditSelection *ese;
|
||||
PyObject *list;
|
||||
BMEditSelection *ese;
|
||||
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
|
||||
list = PyList_New(0);
|
||||
list = PyList_New(0);
|
||||
|
||||
ese = self->bm->selected.first;
|
||||
ese = self->bm->selected.first;
|
||||
|
||||
ok = (ese != NULL);
|
||||
ok = (ese != NULL);
|
||||
|
||||
if (UNLIKELY(ok == false)) {
|
||||
return list;
|
||||
}
|
||||
if (UNLIKELY(ok == false)) {
|
||||
return list;
|
||||
}
|
||||
|
||||
/* first loop up-until the start */
|
||||
for (ok = true; ok; ok = ((ese = ese->next) != NULL)) {
|
||||
if (count == start) {
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
/* first loop up-until the start */
|
||||
for (ok = true; ok; ok = ((ese = ese->next) != NULL)) {
|
||||
if (count == start) {
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
/* add items until stop */
|
||||
do {
|
||||
PyList_APPEND(list, BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head));
|
||||
count++;
|
||||
if (count == stop) {
|
||||
break;
|
||||
}
|
||||
} while ((ese = ese->next));
|
||||
/* add items until stop */
|
||||
do {
|
||||
PyList_APPEND(list, BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head));
|
||||
count++;
|
||||
if (count == stop) {
|
||||
break;
|
||||
}
|
||||
} while ((ese = ese->next));
|
||||
|
||||
return list;
|
||||
return list;
|
||||
}
|
||||
|
||||
static PyObject *bpy_bmeditselseq_subscript(BPy_BMEditSelSeq *self, PyObject *key)
|
||||
{
|
||||
/* don't need error check here */
|
||||
if (PyIndex_Check(key)) {
|
||||
Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
|
||||
if (i == -1 && PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
return bpy_bmeditselseq_subscript_int(self, i);
|
||||
}
|
||||
else if (PySlice_Check(key)) {
|
||||
PySliceObject *key_slice = (PySliceObject *)key;
|
||||
Py_ssize_t step = 1;
|
||||
/* don't need error check here */
|
||||
if (PyIndex_Check(key)) {
|
||||
Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
|
||||
if (i == -1 && PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
return bpy_bmeditselseq_subscript_int(self, i);
|
||||
}
|
||||
else if (PySlice_Check(key)) {
|
||||
PySliceObject *key_slice = (PySliceObject *)key;
|
||||
Py_ssize_t step = 1;
|
||||
|
||||
if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
|
||||
return NULL;
|
||||
}
|
||||
else if (step != 1) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"BMElemSeq[slice]: slice steps not supported");
|
||||
return NULL;
|
||||
}
|
||||
else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
|
||||
return bpy_bmeditselseq_subscript_slice(self, 0, PY_SSIZE_T_MAX);
|
||||
}
|
||||
else {
|
||||
Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
|
||||
if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
|
||||
return NULL;
|
||||
}
|
||||
else if (step != 1) {
|
||||
PyErr_SetString(PyExc_TypeError, "BMElemSeq[slice]: slice steps not supported");
|
||||
return NULL;
|
||||
}
|
||||
else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
|
||||
return bpy_bmeditselseq_subscript_slice(self, 0, PY_SSIZE_T_MAX);
|
||||
}
|
||||
else {
|
||||
Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
|
||||
|
||||
/* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
|
||||
if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
|
||||
return NULL;
|
||||
}
|
||||
if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
|
||||
return NULL;
|
||||
}
|
||||
/* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
|
||||
if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
|
||||
return NULL;
|
||||
}
|
||||
if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (start < 0 || stop < 0) {
|
||||
/* only get the length for negative values */
|
||||
Py_ssize_t len = bpy_bmeditselseq_length(self);
|
||||
if (start < 0) {
|
||||
start += len;
|
||||
}
|
||||
if (stop < 0) {
|
||||
stop += len;
|
||||
}
|
||||
}
|
||||
if (start < 0 || stop < 0) {
|
||||
/* only get the length for negative values */
|
||||
Py_ssize_t len = bpy_bmeditselseq_length(self);
|
||||
if (start < 0) {
|
||||
start += len;
|
||||
}
|
||||
if (stop < 0) {
|
||||
stop += len;
|
||||
}
|
||||
}
|
||||
|
||||
if (stop - start <= 0) {
|
||||
return PyList_New(0);
|
||||
}
|
||||
else {
|
||||
return bpy_bmeditselseq_subscript_slice(self, start, stop);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
"BMElemSeq[key]: invalid key, key must be an int");
|
||||
return NULL;
|
||||
}
|
||||
if (stop - start <= 0) {
|
||||
return PyList_New(0);
|
||||
}
|
||||
else {
|
||||
return bpy_bmeditselseq_subscript_slice(self, start, stop);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_AttributeError, "BMElemSeq[key]: invalid key, key must be an int");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int bpy_bmeditselseq_contains(BPy_BMEditSelSeq *self, PyObject *value)
|
||||
{
|
||||
BPy_BMElem *value_bm_ele;
|
||||
BPy_BMElem *value_bm_ele;
|
||||
|
||||
BPY_BM_CHECK_INT(self);
|
||||
BPY_BM_CHECK_INT(self);
|
||||
|
||||
value_bm_ele = (BPy_BMElem *)value;
|
||||
if (value_bm_ele->bm == self->bm) {
|
||||
return BM_select_history_check(self->bm, value_bm_ele->ele);
|
||||
}
|
||||
value_bm_ele = (BPy_BMElem *)value;
|
||||
if (value_bm_ele->bm == self->bm) {
|
||||
return BM_select_history_check(self->bm, value_bm_ele->ele);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PySequenceMethods bpy_bmeditselseq_as_sequence = {
|
||||
(lenfunc)bpy_bmeditselseq_length, /* sq_length */
|
||||
NULL, /* sq_concat */
|
||||
NULL, /* sq_repeat */
|
||||
(ssizeargfunc)bpy_bmeditselseq_subscript_int,/* sq_item */ /* Only set this so PySequence_Check() returns True */
|
||||
NULL, /* sq_slice */
|
||||
(ssizeobjargproc)NULL, /* sq_ass_item */
|
||||
NULL, /* *was* sq_ass_slice */
|
||||
(objobjproc)bpy_bmeditselseq_contains, /* sq_contains */
|
||||
(binaryfunc) NULL, /* sq_inplace_concat */
|
||||
(ssizeargfunc) NULL, /* sq_inplace_repeat */
|
||||
(lenfunc)bpy_bmeditselseq_length, /* sq_length */
|
||||
NULL, /* sq_concat */
|
||||
NULL, /* sq_repeat */
|
||||
(ssizeargfunc)bpy_bmeditselseq_subscript_int,
|
||||
/* sq_item */ /* Only set this so PySequence_Check() returns True */
|
||||
NULL, /* sq_slice */
|
||||
(ssizeobjargproc)NULL, /* sq_ass_item */
|
||||
NULL, /* *was* sq_ass_slice */
|
||||
(objobjproc)bpy_bmeditselseq_contains, /* sq_contains */
|
||||
(binaryfunc)NULL, /* sq_inplace_concat */
|
||||
(ssizeargfunc)NULL, /* sq_inplace_repeat */
|
||||
};
|
||||
|
||||
static PyMappingMethods bpy_bmeditselseq_as_mapping = {
|
||||
(lenfunc)bpy_bmeditselseq_length, /* mp_length */
|
||||
(binaryfunc)bpy_bmeditselseq_subscript, /* mp_subscript */
|
||||
(objobjargproc)NULL, /* mp_ass_subscript */
|
||||
(lenfunc)bpy_bmeditselseq_length, /* mp_length */
|
||||
(binaryfunc)bpy_bmeditselseq_subscript, /* mp_subscript */
|
||||
(objobjargproc)NULL, /* mp_ass_subscript */
|
||||
};
|
||||
|
||||
|
||||
/* Iterator
|
||||
* -------- */
|
||||
|
||||
static PyObject *bpy_bmeditselseq_iter(BPy_BMEditSelSeq *self)
|
||||
{
|
||||
BPy_BMEditSelIter *py_iter;
|
||||
BPy_BMEditSelIter *py_iter;
|
||||
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
py_iter = (BPy_BMEditSelIter *)BPy_BMEditSelIter_CreatePyObject(self->bm);
|
||||
py_iter->ese = self->bm->selected.first;
|
||||
return (PyObject *)py_iter;
|
||||
BPY_BM_CHECK_OBJ(self);
|
||||
py_iter = (BPy_BMEditSelIter *)BPy_BMEditSelIter_CreatePyObject(self->bm);
|
||||
py_iter->ese = self->bm->selected.first;
|
||||
return (PyObject *)py_iter;
|
||||
}
|
||||
|
||||
static PyObject *bpy_bmeditseliter_next(BPy_BMEditSelIter *self)
|
||||
{
|
||||
BMEditSelection *ese = self->ese;
|
||||
if (ese == NULL) {
|
||||
PyErr_SetNone(PyExc_StopIteration);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
self->ese = ese->next;
|
||||
return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
|
||||
}
|
||||
BMEditSelection *ese = self->ese;
|
||||
if (ese == NULL) {
|
||||
PyErr_SetNone(PyExc_StopIteration);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
self->ese = ese->next;
|
||||
return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
|
||||
}
|
||||
}
|
||||
|
||||
PyTypeObject BPy_BMEditSelSeq_Type;
|
||||
PyTypeObject BPy_BMEditSelIter_Type;
|
||||
|
||||
|
||||
PyObject *BPy_BMEditSel_CreatePyObject(BMesh *bm)
|
||||
{
|
||||
BPy_BMEditSelSeq *self = PyObject_New(BPy_BMEditSelSeq, &BPy_BMEditSelSeq_Type);
|
||||
self->bm = bm;
|
||||
/* caller must initialize 'iter' member */
|
||||
return (PyObject *)self;
|
||||
BPy_BMEditSelSeq *self = PyObject_New(BPy_BMEditSelSeq, &BPy_BMEditSelSeq_Type);
|
||||
self->bm = bm;
|
||||
/* caller must initialize 'iter' member */
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
PyObject *BPy_BMEditSelIter_CreatePyObject(BMesh *bm)
|
||||
{
|
||||
BPy_BMEditSelIter *self = PyObject_New(BPy_BMEditSelIter, &BPy_BMEditSelIter_Type);
|
||||
self->bm = bm;
|
||||
/* caller must initialize 'iter' member */
|
||||
return (PyObject *)self;
|
||||
BPy_BMEditSelIter *self = PyObject_New(BPy_BMEditSelIter, &BPy_BMEditSelIter_Type);
|
||||
self->bm = bm;
|
||||
/* caller must initialize 'iter' member */
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
void BPy_BM_init_types_select(void)
|
||||
{
|
||||
BPy_BMEditSelSeq_Type.tp_basicsize = sizeof(BPy_BMEditSelSeq);
|
||||
BPy_BMEditSelIter_Type.tp_basicsize = sizeof(BPy_BMEditSelIter);
|
||||
BPy_BMEditSelSeq_Type.tp_basicsize = sizeof(BPy_BMEditSelSeq);
|
||||
BPy_BMEditSelIter_Type.tp_basicsize = sizeof(BPy_BMEditSelIter);
|
||||
|
||||
BPy_BMEditSelSeq_Type.tp_name = "BMEditSelSeq";
|
||||
BPy_BMEditSelIter_Type.tp_name = "BMEditSelIter";
|
||||
BPy_BMEditSelSeq_Type.tp_name = "BMEditSelSeq";
|
||||
BPy_BMEditSelIter_Type.tp_name = "BMEditSelIter";
|
||||
|
||||
BPy_BMEditSelSeq_Type.tp_doc = NULL; /* todo */
|
||||
BPy_BMEditSelIter_Type.tp_doc = NULL;
|
||||
BPy_BMEditSelSeq_Type.tp_doc = NULL; /* todo */
|
||||
BPy_BMEditSelIter_Type.tp_doc = NULL;
|
||||
|
||||
BPy_BMEditSelSeq_Type.tp_repr = (reprfunc)NULL;
|
||||
BPy_BMEditSelIter_Type.tp_repr = (reprfunc)NULL;
|
||||
BPy_BMEditSelSeq_Type.tp_repr = (reprfunc)NULL;
|
||||
BPy_BMEditSelIter_Type.tp_repr = (reprfunc)NULL;
|
||||
|
||||
BPy_BMEditSelSeq_Type.tp_getset = bpy_bmeditselseq_getseters;
|
||||
BPy_BMEditSelIter_Type.tp_getset = NULL;
|
||||
BPy_BMEditSelSeq_Type.tp_getset = bpy_bmeditselseq_getseters;
|
||||
BPy_BMEditSelIter_Type.tp_getset = NULL;
|
||||
|
||||
BPy_BMEditSelSeq_Type.tp_methods = bpy_bmeditselseq_methods;
|
||||
BPy_BMEditSelIter_Type.tp_methods = NULL;
|
||||
BPy_BMEditSelSeq_Type.tp_methods = bpy_bmeditselseq_methods;
|
||||
BPy_BMEditSelIter_Type.tp_methods = NULL;
|
||||
|
||||
BPy_BMEditSelSeq_Type.tp_as_sequence = &bpy_bmeditselseq_as_sequence;
|
||||
BPy_BMEditSelSeq_Type.tp_as_sequence = &bpy_bmeditselseq_as_sequence;
|
||||
|
||||
BPy_BMEditSelSeq_Type.tp_as_mapping = &bpy_bmeditselseq_as_mapping;
|
||||
BPy_BMEditSelSeq_Type.tp_as_mapping = &bpy_bmeditselseq_as_mapping;
|
||||
|
||||
BPy_BMEditSelSeq_Type.tp_iter = (getiterfunc)bpy_bmeditselseq_iter;
|
||||
BPy_BMEditSelSeq_Type.tp_iter = (getiterfunc)bpy_bmeditselseq_iter;
|
||||
|
||||
/* only 1 iteratir so far */
|
||||
BPy_BMEditSelIter_Type.tp_iternext = (iternextfunc)bpy_bmeditseliter_next;
|
||||
/* only 1 iteratir so far */
|
||||
BPy_BMEditSelIter_Type.tp_iternext = (iternextfunc)bpy_bmeditseliter_next;
|
||||
|
||||
BPy_BMEditSelSeq_Type.tp_dealloc = NULL; //(destructor)bpy_bmeditselseq_dealloc;
|
||||
BPy_BMEditSelIter_Type.tp_dealloc = NULL; //(destructor)bpy_bmvert_dealloc;
|
||||
BPy_BMEditSelSeq_Type.tp_dealloc = NULL; //(destructor)bpy_bmeditselseq_dealloc;
|
||||
BPy_BMEditSelIter_Type.tp_dealloc = NULL; //(destructor)bpy_bmvert_dealloc;
|
||||
|
||||
BPy_BMEditSelSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||
BPy_BMEditSelIter_Type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||
BPy_BMEditSelSeq_Type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||
BPy_BMEditSelIter_Type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||
|
||||
PyType_Ready(&BPy_BMEditSelSeq_Type);
|
||||
PyType_Ready(&BPy_BMEditSelIter_Type);
|
||||
PyType_Ready(&BPy_BMEditSelSeq_Type);
|
||||
PyType_Ready(&BPy_BMEditSelIter_Type);
|
||||
}
|
||||
|
||||
|
||||
/* utility function */
|
||||
|
||||
/**
|
||||
@@ -439,29 +429,35 @@ void BPy_BM_init_types_select(void)
|
||||
*/
|
||||
int BPy_BMEditSel_Assign(BPy_BMesh *self, PyObject *value)
|
||||
{
|
||||
BMesh *bm;
|
||||
Py_ssize_t value_len;
|
||||
Py_ssize_t i;
|
||||
BMElem **value_array = NULL;
|
||||
BMesh *bm;
|
||||
Py_ssize_t value_len;
|
||||
Py_ssize_t i;
|
||||
BMElem **value_array = NULL;
|
||||
|
||||
BPY_BM_CHECK_INT(self);
|
||||
BPY_BM_CHECK_INT(self);
|
||||
|
||||
bm = self->bm;
|
||||
bm = self->bm;
|
||||
|
||||
value_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX,
|
||||
&value_len, BM_VERT | BM_EDGE | BM_FACE,
|
||||
true, true, "BMesh.select_history = value");
|
||||
value_array = BPy_BMElem_PySeq_As_Array(&bm,
|
||||
value,
|
||||
0,
|
||||
PY_SSIZE_T_MAX,
|
||||
&value_len,
|
||||
BM_VERT | BM_EDGE | BM_FACE,
|
||||
true,
|
||||
true,
|
||||
"BMesh.select_history = value");
|
||||
|
||||
if (value_array == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (value_array == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
BM_select_history_clear(bm);
|
||||
BM_select_history_clear(bm);
|
||||
|
||||
for (i = 0; i < value_len; i++) {
|
||||
BM_select_history_store_notest(bm, value_array[i]);
|
||||
}
|
||||
for (i = 0; i < value_len; i++) {
|
||||
BM_select_history_store_notest(bm, value_array[i]);
|
||||
}
|
||||
|
||||
PyMem_FREE(value_array);
|
||||
return 0;
|
||||
PyMem_FREE(value_array);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -29,24 +29,22 @@ struct BPy_BMesh;
|
||||
extern PyTypeObject BPy_BMEditSelSeq_Type;
|
||||
extern PyTypeObject BPy_BMEditSelIter_Type;
|
||||
|
||||
#define BPy_BMSelectHistory_Check(v) (Py_TYPE(v) == &BPy_BMEditSelSeq_Type)
|
||||
#define BPy_BMSelectHistoryIter_Check(v) (Py_TYPE(v) == &BPy_BMEditSelIter_Type)
|
||||
#define BPy_BMSelectHistory_Check(v) (Py_TYPE(v) == &BPy_BMEditSelSeq_Type)
|
||||
#define BPy_BMSelectHistoryIter_Check(v) (Py_TYPE(v) == &BPy_BMEditSelIter_Type)
|
||||
|
||||
typedef struct BPy_BMEditSelSeq {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
} BPy_BMEditSelSeq;
|
||||
|
||||
typedef struct BPy_BMEditSelIter {
|
||||
PyObject_VAR_HEAD
|
||||
struct BMesh *bm; /* keep first */
|
||||
struct BMEditSelection *ese;
|
||||
PyObject_VAR_HEAD struct BMesh *bm; /* keep first */
|
||||
struct BMEditSelection *ese;
|
||||
} BPy_BMEditSelIter;
|
||||
|
||||
void BPy_BM_init_types_select(void);
|
||||
|
||||
PyObject *BPy_BMEditSel_CreatePyObject(BMesh *bm);
|
||||
PyObject *BPy_BMEditSelIter_CreatePyObject(BMesh *bm);
|
||||
int BPy_BMEditSel_Assign(struct BPy_BMesh *self, PyObject *value);
|
||||
int BPy_BMEditSel_Assign(struct BPy_BMesh *self, PyObject *value);
|
||||
|
||||
#endif /* __BMESH_PY_SELECT_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,42 +16,42 @@
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
.
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../gpu
|
||||
../../makesdna
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
.
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../gpu
|
||||
../../makesdna
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${GLEW_INCLUDE_PATH}
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
${GLEW_INCLUDE_PATH}
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
bgl.c
|
||||
blf_py_api.c
|
||||
bpy_internal_import.c
|
||||
bpy_threads.c
|
||||
idprop_py_api.c
|
||||
imbuf_py_api.c
|
||||
py_capi_utils.c
|
||||
bgl.c
|
||||
blf_py_api.c
|
||||
bpy_internal_import.c
|
||||
bpy_threads.c
|
||||
idprop_py_api.c
|
||||
imbuf_py_api.c
|
||||
py_capi_utils.c
|
||||
|
||||
bgl.h
|
||||
blf_py_api.h
|
||||
bpy_internal_import.h
|
||||
idprop_py_api.h
|
||||
imbuf_py_api.h
|
||||
py_capi_utils.h
|
||||
bgl.h
|
||||
blf_py_api.h
|
||||
bpy_internal_import.h
|
||||
idprop_py_api.h
|
||||
imbuf_py_api.h
|
||||
py_capi_utils.h
|
||||
|
||||
# header-only
|
||||
python_utildefines.h
|
||||
# header-only
|
||||
python_utildefines.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
${GLEW_LIBRARY}
|
||||
${GLEW_LIBRARY}
|
||||
)
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,22 +33,21 @@ int BGL_typeSize(int type);
|
||||
* For Python access to OpenGL functions requiring a pointer.
|
||||
*/
|
||||
typedef struct _Buffer {
|
||||
PyObject_VAR_HEAD
|
||||
PyObject *parent;
|
||||
PyObject_VAR_HEAD PyObject *parent;
|
||||
|
||||
int type; /* GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT */
|
||||
int ndimensions;
|
||||
int *dimensions;
|
||||
int type; /* GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT */
|
||||
int ndimensions;
|
||||
int *dimensions;
|
||||
|
||||
union {
|
||||
char *asbyte;
|
||||
short *asshort;
|
||||
int *asint;
|
||||
float *asfloat;
|
||||
double *asdouble;
|
||||
union {
|
||||
char *asbyte;
|
||||
short *asshort;
|
||||
int *asint;
|
||||
float *asfloat;
|
||||
double *asdouble;
|
||||
|
||||
void *asvoid;
|
||||
} buf;
|
||||
void *asvoid;
|
||||
} buf;
|
||||
} Buffer;
|
||||
|
||||
/** The type object */
|
||||
|
||||
@@ -29,486 +29,470 @@
|
||||
|
||||
#include "python_utildefines.h"
|
||||
|
||||
|
||||
PyDoc_STRVAR(py_blf_position_doc,
|
||||
".. function:: position(fontid, x, y, z)\n"
|
||||
"\n"
|
||||
" Set the position for drawing text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg x: X axis position to draw the text.\n"
|
||||
" :type x: float\n"
|
||||
" :arg y: Y axis position to draw the text.\n"
|
||||
" :type y: float\n"
|
||||
" :arg z: Z axis position to draw the text.\n"
|
||||
" :type z: float\n"
|
||||
);
|
||||
".. function:: position(fontid, x, y, z)\n"
|
||||
"\n"
|
||||
" Set the position for drawing text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg x: X axis position to draw the text.\n"
|
||||
" :type x: float\n"
|
||||
" :arg y: Y axis position to draw the text.\n"
|
||||
" :type y: float\n"
|
||||
" :arg z: Z axis position to draw the text.\n"
|
||||
" :type z: float\n");
|
||||
|
||||
static PyObject *py_blf_position(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
int fontid;
|
||||
float x, y, z;
|
||||
int fontid;
|
||||
float x, y, z;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ifff:blf.position", &fontid, &x, &y, &z)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "ifff:blf.position", &fontid, &x, &y, &z)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_position(fontid, x, y, z);
|
||||
BLF_position(fontid, x, y, z);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(py_blf_size_doc,
|
||||
".. function:: size(fontid, size, dpi)\n"
|
||||
"\n"
|
||||
" Set the size and dpi for drawing text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg size: Point size of the font.\n"
|
||||
" :type size: int\n"
|
||||
" :arg dpi: dots per inch value to use for drawing.\n"
|
||||
" :type dpi: int\n"
|
||||
);
|
||||
".. function:: size(fontid, size, dpi)\n"
|
||||
"\n"
|
||||
" Set the size and dpi for drawing text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg size: Point size of the font.\n"
|
||||
" :type size: int\n"
|
||||
" :arg dpi: dots per inch value to use for drawing.\n"
|
||||
" :type dpi: int\n");
|
||||
static PyObject *py_blf_size(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
int fontid, size, dpi;
|
||||
int fontid, size, dpi;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iii:blf.size", &fontid, &size, &dpi)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "iii:blf.size", &fontid, &size, &dpi)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_size(fontid, size, dpi);
|
||||
BLF_size(fontid, size, dpi);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(py_blf_aspect_doc,
|
||||
".. function:: aspect(fontid, aspect)\n"
|
||||
"\n"
|
||||
" Set the aspect for drawing text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg aspect: The aspect ratio for text drawing to use.\n"
|
||||
" :type aspect: float\n"
|
||||
);
|
||||
".. function:: aspect(fontid, aspect)\n"
|
||||
"\n"
|
||||
" Set the aspect for drawing text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg aspect: The aspect ratio for text drawing to use.\n"
|
||||
" :type aspect: float\n");
|
||||
static PyObject *py_blf_aspect(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
float aspect;
|
||||
int fontid;
|
||||
float aspect;
|
||||
int fontid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "if:blf.aspect", &fontid, &aspect)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "if:blf.aspect", &fontid, &aspect)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_aspect(fontid, aspect, aspect, 1.0);
|
||||
BLF_aspect(fontid, aspect, aspect, 1.0);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(py_blf_color_doc,
|
||||
".. function:: color(fontid, r, g, b, a)\n"
|
||||
"\n"
|
||||
" Set the color for drawing text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg r: red channel 0.0 - 1.0.\n"
|
||||
" :type r: float\n"
|
||||
" :arg g: green channel 0.0 - 1.0.\n"
|
||||
" :type g: float\n"
|
||||
" :arg b: blue channel 0.0 - 1.0.\n"
|
||||
" :type b: float\n"
|
||||
" :arg a: alpha channel 0.0 - 1.0.\n"
|
||||
" :type a: float\n"
|
||||
);
|
||||
".. function:: color(fontid, r, g, b, a)\n"
|
||||
"\n"
|
||||
" Set the color for drawing text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg r: red channel 0.0 - 1.0.\n"
|
||||
" :type r: float\n"
|
||||
" :arg g: green channel 0.0 - 1.0.\n"
|
||||
" :type g: float\n"
|
||||
" :arg b: blue channel 0.0 - 1.0.\n"
|
||||
" :type b: float\n"
|
||||
" :arg a: alpha channel 0.0 - 1.0.\n"
|
||||
" :type a: float\n");
|
||||
static PyObject *py_blf_color(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
int fontid;
|
||||
float rgba[4];
|
||||
int fontid;
|
||||
float rgba[4];
|
||||
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "iffff:blf.color",
|
||||
&fontid, &rgba[0], &rgba[1], &rgba[2], &rgba[3]))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "iffff:blf.color", &fontid, &rgba[0], &rgba[1], &rgba[2], &rgba[3])) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_color4fv(fontid, rgba);
|
||||
BLF_color4fv(fontid, rgba);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
#if BLF_BLUR_ENABLE
|
||||
PyDoc_STRVAR(py_blf_blur_doc,
|
||||
".. function:: blur(fontid, radius)\n"
|
||||
"\n"
|
||||
" Set the blur radius for drawing text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg radius: The radius for blurring text (in pixels).\n"
|
||||
" :type radius: int\n"
|
||||
);
|
||||
".. function:: blur(fontid, radius)\n"
|
||||
"\n"
|
||||
" Set the blur radius for drawing text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg radius: The radius for blurring text (in pixels).\n"
|
||||
" :type radius: int\n");
|
||||
static PyObject *py_blf_blur(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
int blur, fontid;
|
||||
int blur, fontid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ii:blf.blur", &fontid, &blur)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "ii:blf.blur", &fontid, &blur)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_blur(fontid, blur);
|
||||
BLF_blur(fontid, blur);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
PyDoc_STRVAR(py_blf_draw_doc,
|
||||
".. function:: draw(fontid, text)\n"
|
||||
"\n"
|
||||
" Draw text in the current context.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg text: the text to draw.\n"
|
||||
" :type text: string\n"
|
||||
);
|
||||
".. function:: draw(fontid, text)\n"
|
||||
"\n"
|
||||
" Draw text in the current context.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg text: the text to draw.\n"
|
||||
" :type text: string\n");
|
||||
static PyObject *py_blf_draw(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
const char *text;
|
||||
int text_length;
|
||||
int fontid;
|
||||
const char *text;
|
||||
int text_length;
|
||||
int fontid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "is#:blf.draw", &fontid, &text, &text_length)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "is#:blf.draw", &fontid, &text, &text_length)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_draw(fontid, text, (unsigned int)text_length);
|
||||
BLF_draw(fontid, text, (unsigned int)text_length);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_blf_dimensions_doc,
|
||||
".. function:: dimensions(fontid, text)\n"
|
||||
"\n"
|
||||
" Return the width and height of the text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg text: the text to draw.\n"
|
||||
" :type text: string\n"
|
||||
" :return: the width and height of the text.\n"
|
||||
" :rtype: tuple of 2 floats\n"
|
||||
);
|
||||
".. function:: dimensions(fontid, text)\n"
|
||||
"\n"
|
||||
" Return the width and height of the text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg text: the text to draw.\n"
|
||||
" :type text: string\n"
|
||||
" :return: the width and height of the text.\n"
|
||||
" :rtype: tuple of 2 floats\n");
|
||||
static PyObject *py_blf_dimensions(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
const char *text;
|
||||
float r_width, r_height;
|
||||
PyObject *ret;
|
||||
int fontid;
|
||||
const char *text;
|
||||
float r_width, r_height;
|
||||
PyObject *ret;
|
||||
int fontid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "is:blf.dimensions", &fontid, &text)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "is:blf.dimensions", &fontid, &text)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_width_and_height(fontid, text, INT_MAX, &r_width, &r_height);
|
||||
BLF_width_and_height(fontid, text, INT_MAX, &r_width, &r_height);
|
||||
|
||||
ret = PyTuple_New(2);
|
||||
PyTuple_SET_ITEMS(ret,
|
||||
PyFloat_FromDouble(r_width),
|
||||
PyFloat_FromDouble(r_height));
|
||||
return ret;
|
||||
ret = PyTuple_New(2);
|
||||
PyTuple_SET_ITEMS(ret, PyFloat_FromDouble(r_width), PyFloat_FromDouble(r_height));
|
||||
return ret;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_blf_clipping_doc,
|
||||
".. function:: clipping(fontid, xmin, ymin, xmax, ymax)\n"
|
||||
"\n"
|
||||
" Set the clipping, enable/disable using CLIPPING.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg xmin: Clip the drawing area by these bounds.\n"
|
||||
" :type xmin: float\n"
|
||||
" :arg ymin: Clip the drawing area by these bounds.\n"
|
||||
" :type ymin: float\n"
|
||||
" :arg xmax: Clip the drawing area by these bounds.\n"
|
||||
" :type xmax: float\n"
|
||||
" :arg ymax: Clip the drawing area by these bounds.\n"
|
||||
" :type ymax: float\n"
|
||||
);
|
||||
".. function:: clipping(fontid, xmin, ymin, xmax, ymax)\n"
|
||||
"\n"
|
||||
" Set the clipping, enable/disable using CLIPPING.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg xmin: Clip the drawing area by these bounds.\n"
|
||||
" :type xmin: float\n"
|
||||
" :arg ymin: Clip the drawing area by these bounds.\n"
|
||||
" :type ymin: float\n"
|
||||
" :arg xmax: Clip the drawing area by these bounds.\n"
|
||||
" :type xmax: float\n"
|
||||
" :arg ymax: Clip the drawing area by these bounds.\n"
|
||||
" :type ymax: float\n");
|
||||
static PyObject *py_blf_clipping(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
float xmin, ymin, xmax, ymax;
|
||||
int fontid;
|
||||
float xmin, ymin, xmax, ymax;
|
||||
int fontid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iffff:blf.clipping", &fontid, &xmin, &ymin, &xmax, &ymax)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "iffff:blf.clipping", &fontid, &xmin, &ymin, &xmax, &ymax)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_clipping(fontid, xmin, ymin, xmax, ymax);
|
||||
BLF_clipping(fontid, xmin, ymin, xmax, ymax);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_blf_word_wrap_doc,
|
||||
".. function:: word_wrap(fontid, wrap_width)\n"
|
||||
"\n"
|
||||
" Set the wrap width, enable/disable using WORD_WRAP.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg wrap_width: The width (in pixels) to wrap words at.\n"
|
||||
" :type wrap_width: int\n"
|
||||
);
|
||||
".. function:: word_wrap(fontid, wrap_width)\n"
|
||||
"\n"
|
||||
" Set the wrap width, enable/disable using WORD_WRAP.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg wrap_width: The width (in pixels) to wrap words at.\n"
|
||||
" :type wrap_width: int\n");
|
||||
static PyObject *py_blf_word_wrap(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
int wrap_width;
|
||||
int fontid;
|
||||
int wrap_width;
|
||||
int fontid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ii:blf.word_wrap", &fontid, &wrap_width)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "ii:blf.word_wrap", &fontid, &wrap_width)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_wordwrap(fontid, wrap_width);
|
||||
BLF_wordwrap(fontid, wrap_width);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_blf_disable_doc,
|
||||
".. function:: disable(fontid, option)\n"
|
||||
"\n"
|
||||
" Disable option.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg option: One of ROTATION, CLIPPING, SHADOW or KERNING_DEFAULT.\n"
|
||||
" :type option: int\n"
|
||||
);
|
||||
".. function:: disable(fontid, option)\n"
|
||||
"\n"
|
||||
" Disable option.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg option: One of ROTATION, CLIPPING, SHADOW or KERNING_DEFAULT.\n"
|
||||
" :type option: int\n");
|
||||
static PyObject *py_blf_disable(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
int option, fontid;
|
||||
int option, fontid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ii:blf.disable", &fontid, &option)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "ii:blf.disable", &fontid, &option)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_disable(fontid, option);
|
||||
BLF_disable(fontid, option);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_blf_enable_doc,
|
||||
".. function:: enable(fontid, option)\n"
|
||||
"\n"
|
||||
" Enable option.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg option: One of ROTATION, CLIPPING, SHADOW or KERNING_DEFAULT.\n"
|
||||
" :type option: int\n"
|
||||
);
|
||||
".. function:: enable(fontid, option)\n"
|
||||
"\n"
|
||||
" Enable option.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg option: One of ROTATION, CLIPPING, SHADOW or KERNING_DEFAULT.\n"
|
||||
" :type option: int\n");
|
||||
static PyObject *py_blf_enable(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
int option, fontid;
|
||||
int option, fontid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ii:blf.enable", &fontid, &option)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "ii:blf.enable", &fontid, &option)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_enable(fontid, option);
|
||||
BLF_enable(fontid, option);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_blf_rotation_doc,
|
||||
".. function:: rotation(fontid, angle)\n"
|
||||
"\n"
|
||||
" Set the text rotation angle, enable/disable using ROTATION.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg angle: The angle for text drawing to use.\n"
|
||||
" :type angle: float\n"
|
||||
);
|
||||
".. function:: rotation(fontid, angle)\n"
|
||||
"\n"
|
||||
" Set the text rotation angle, enable/disable using ROTATION.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg angle: The angle for text drawing to use.\n"
|
||||
" :type angle: float\n");
|
||||
static PyObject *py_blf_rotation(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
float angle;
|
||||
int fontid;
|
||||
float angle;
|
||||
int fontid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "if:blf.rotation", &fontid, &angle)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "if:blf.rotation", &fontid, &angle)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_rotation(fontid, angle);
|
||||
BLF_rotation(fontid, angle);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_blf_shadow_doc,
|
||||
".. function:: shadow(fontid, level, r, g, b, a)\n"
|
||||
"\n"
|
||||
" Shadow options, enable/disable using SHADOW .\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg level: The blur level, can be 3, 5 or 0.\n"
|
||||
" :type level: int\n"
|
||||
" :arg r: Shadow color (red channel 0.0 - 1.0).\n"
|
||||
" :type r: float\n"
|
||||
" :arg g: Shadow color (green channel 0.0 - 1.0).\n"
|
||||
" :type g: float\n"
|
||||
" :arg b: Shadow color (blue channel 0.0 - 1.0).\n"
|
||||
" :type b: float\n"
|
||||
" :arg a: Shadow color (alpha channel 0.0 - 1.0).\n"
|
||||
" :type a: float\n"
|
||||
);
|
||||
".. function:: shadow(fontid, level, r, g, b, a)\n"
|
||||
"\n"
|
||||
" Shadow options, enable/disable using SHADOW .\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg level: The blur level, can be 3, 5 or 0.\n"
|
||||
" :type level: int\n"
|
||||
" :arg r: Shadow color (red channel 0.0 - 1.0).\n"
|
||||
" :type r: float\n"
|
||||
" :arg g: Shadow color (green channel 0.0 - 1.0).\n"
|
||||
" :type g: float\n"
|
||||
" :arg b: Shadow color (blue channel 0.0 - 1.0).\n"
|
||||
" :type b: float\n"
|
||||
" :arg a: Shadow color (alpha channel 0.0 - 1.0).\n"
|
||||
" :type a: float\n");
|
||||
static PyObject *py_blf_shadow(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
int level, fontid;
|
||||
float rgba[4];
|
||||
int level, fontid;
|
||||
float rgba[4];
|
||||
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "iiffff:blf.shadow",
|
||||
&fontid, &level, &rgba[0], &rgba[1], &rgba[2], &rgba[3]))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "iiffff:blf.shadow", &fontid, &level, &rgba[0], &rgba[1], &rgba[2], &rgba[3])) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (level != 0 && level != 3 && level != 5) {
|
||||
PyErr_SetString(PyExc_TypeError, "blf.shadow expected arg to be in (0, 3, 5)");
|
||||
return NULL;
|
||||
}
|
||||
if (level != 0 && level != 3 && level != 5) {
|
||||
PyErr_SetString(PyExc_TypeError, "blf.shadow expected arg to be in (0, 3, 5)");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_shadow(fontid, level, rgba);
|
||||
BLF_shadow(fontid, level, rgba);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_blf_shadow_offset_doc,
|
||||
".. function:: shadow_offset(fontid, x, y)\n"
|
||||
"\n"
|
||||
" Set the offset for shadow text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg x: Vertical shadow offset value in pixels.\n"
|
||||
" :type x: float\n"
|
||||
" :arg y: Horizontal shadow offset value in pixels.\n"
|
||||
" :type y: float\n"
|
||||
);
|
||||
".. function:: shadow_offset(fontid, x, y)\n"
|
||||
"\n"
|
||||
" Set the offset for shadow text.\n"
|
||||
"\n"
|
||||
" :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
|
||||
"font use 0.\n"
|
||||
" :type fontid: int\n"
|
||||
" :arg x: Vertical shadow offset value in pixels.\n"
|
||||
" :type x: float\n"
|
||||
" :arg y: Horizontal shadow offset value in pixels.\n"
|
||||
" :type y: float\n");
|
||||
static PyObject *py_blf_shadow_offset(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
int x, y, fontid;
|
||||
int x, y, fontid;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iii:blf.shadow_offset", &fontid, &x, &y)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "iii:blf.shadow_offset", &fontid, &x, &y)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_shadow_offset(fontid, x, y);
|
||||
BLF_shadow_offset(fontid, x, y);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_blf_load_doc,
|
||||
".. function:: load(filename)\n"
|
||||
"\n"
|
||||
" Load a new font.\n"
|
||||
"\n"
|
||||
" :arg filename: the filename of the font.\n"
|
||||
" :type filename: string\n"
|
||||
" :return: the new font's fontid or -1 if there was an error.\n"
|
||||
" :rtype: integer\n"
|
||||
);
|
||||
".. function:: load(filename)\n"
|
||||
"\n"
|
||||
" Load a new font.\n"
|
||||
"\n"
|
||||
" :arg filename: the filename of the font.\n"
|
||||
" :type filename: string\n"
|
||||
" :return: the new font's fontid or -1 if there was an error.\n"
|
||||
" :rtype: integer\n");
|
||||
static PyObject *py_blf_load(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
const char *filename;
|
||||
const char *filename;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:blf.load", &filename)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "s:blf.load", &filename)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return PyLong_FromLong(BLF_load(filename));
|
||||
return PyLong_FromLong(BLF_load(filename));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_blf_unload_doc,
|
||||
".. function:: unload(filename)\n"
|
||||
"\n"
|
||||
" Unload an existing font.\n"
|
||||
"\n"
|
||||
" :arg filename: the filename of the font.\n"
|
||||
" :type filename: string\n"
|
||||
);
|
||||
".. function:: unload(filename)\n"
|
||||
"\n"
|
||||
" Unload an existing font.\n"
|
||||
"\n"
|
||||
" :arg filename: the filename of the font.\n"
|
||||
" :type filename: string\n");
|
||||
static PyObject *py_blf_unload(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
const char *filename;
|
||||
const char *filename;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:blf.unload", &filename)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "s:blf.unload", &filename)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLF_unload(filename);
|
||||
BLF_unload(filename);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*----------------------------MODULE INIT-------------------------*/
|
||||
static PyMethodDef BLF_methods[] = {
|
||||
{"aspect", (PyCFunction) py_blf_aspect, METH_VARARGS, py_blf_aspect_doc},
|
||||
{"aspect", (PyCFunction)py_blf_aspect, METH_VARARGS, py_blf_aspect_doc},
|
||||
#if BLF_BLUR_ENABLE
|
||||
{"blur", (PyCFunction) py_blf_blur, METH_VARARGS, py_blf_blur_doc},
|
||||
{"blur", (PyCFunction)py_blf_blur, METH_VARARGS, py_blf_blur_doc},
|
||||
#endif
|
||||
{"clipping", (PyCFunction) py_blf_clipping, METH_VARARGS, py_blf_clipping_doc},
|
||||
{"word_wrap", (PyCFunction) py_blf_word_wrap, METH_VARARGS, py_blf_word_wrap_doc},
|
||||
{"disable", (PyCFunction) py_blf_disable, METH_VARARGS, py_blf_disable_doc},
|
||||
{"dimensions", (PyCFunction) py_blf_dimensions, METH_VARARGS, py_blf_dimensions_doc},
|
||||
{"draw", (PyCFunction) py_blf_draw, METH_VARARGS, py_blf_draw_doc},
|
||||
{"enable", (PyCFunction) py_blf_enable, METH_VARARGS, py_blf_enable_doc},
|
||||
{"position", (PyCFunction) py_blf_position, METH_VARARGS, py_blf_position_doc},
|
||||
{"rotation", (PyCFunction) py_blf_rotation, METH_VARARGS, py_blf_rotation_doc},
|
||||
{"shadow", (PyCFunction) py_blf_shadow, METH_VARARGS, py_blf_shadow_doc},
|
||||
{"shadow_offset", (PyCFunction) py_blf_shadow_offset, METH_VARARGS, py_blf_shadow_offset_doc},
|
||||
{"size", (PyCFunction) py_blf_size, METH_VARARGS, py_blf_size_doc},
|
||||
{"color", (PyCFunction) py_blf_color, METH_VARARGS, py_blf_color_doc},
|
||||
{"load", (PyCFunction) py_blf_load, METH_VARARGS, py_blf_load_doc},
|
||||
{"unload", (PyCFunction) py_blf_unload, METH_VARARGS, py_blf_unload_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"clipping", (PyCFunction)py_blf_clipping, METH_VARARGS, py_blf_clipping_doc},
|
||||
{"word_wrap", (PyCFunction)py_blf_word_wrap, METH_VARARGS, py_blf_word_wrap_doc},
|
||||
{"disable", (PyCFunction)py_blf_disable, METH_VARARGS, py_blf_disable_doc},
|
||||
{"dimensions", (PyCFunction)py_blf_dimensions, METH_VARARGS, py_blf_dimensions_doc},
|
||||
{"draw", (PyCFunction)py_blf_draw, METH_VARARGS, py_blf_draw_doc},
|
||||
{"enable", (PyCFunction)py_blf_enable, METH_VARARGS, py_blf_enable_doc},
|
||||
{"position", (PyCFunction)py_blf_position, METH_VARARGS, py_blf_position_doc},
|
||||
{"rotation", (PyCFunction)py_blf_rotation, METH_VARARGS, py_blf_rotation_doc},
|
||||
{"shadow", (PyCFunction)py_blf_shadow, METH_VARARGS, py_blf_shadow_doc},
|
||||
{"shadow_offset", (PyCFunction)py_blf_shadow_offset, METH_VARARGS, py_blf_shadow_offset_doc},
|
||||
{"size", (PyCFunction)py_blf_size, METH_VARARGS, py_blf_size_doc},
|
||||
{"color", (PyCFunction)py_blf_color, METH_VARARGS, py_blf_color_doc},
|
||||
{"load", (PyCFunction)py_blf_load, METH_VARARGS, py_blf_load_doc},
|
||||
{"unload", (PyCFunction)py_blf_unload, METH_VARARGS, py_blf_unload_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(BLF_doc,
|
||||
"This module provides access to blenders text drawing functions."
|
||||
);
|
||||
PyDoc_STRVAR(BLF_doc, "This module provides access to blenders text drawing functions.");
|
||||
static struct PyModuleDef BLF_module_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"blf", /* m_name */
|
||||
BLF_doc, /* m_doc */
|
||||
0, /* m_size */
|
||||
BLF_methods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"blf", /* m_name */
|
||||
BLF_doc, /* m_doc */
|
||||
0, /* m_size */
|
||||
BLF_methods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
};
|
||||
|
||||
PyObject *BPyInit_blf(void)
|
||||
{
|
||||
PyObject *submodule;
|
||||
PyObject *submodule;
|
||||
|
||||
submodule = PyModule_Create(&BLF_module_def);
|
||||
submodule = PyModule_Create(&BLF_module_def);
|
||||
|
||||
PyModule_AddIntConstant(submodule, "ROTATION", BLF_ROTATION);
|
||||
PyModule_AddIntConstant(submodule, "CLIPPING", BLF_CLIPPING);
|
||||
PyModule_AddIntConstant(submodule, "SHADOW", BLF_SHADOW);
|
||||
PyModule_AddIntConstant(submodule, "KERNING_DEFAULT", BLF_KERNING_DEFAULT);
|
||||
PyModule_AddIntConstant(submodule, "WORD_WRAP", BLF_WORD_WRAP);
|
||||
PyModule_AddIntConstant(submodule, "MONOCHROME", BLF_MONOCHROME);
|
||||
PyModule_AddIntConstant(submodule, "ROTATION", BLF_ROTATION);
|
||||
PyModule_AddIntConstant(submodule, "CLIPPING", BLF_CLIPPING);
|
||||
PyModule_AddIntConstant(submodule, "SHADOW", BLF_SHADOW);
|
||||
PyModule_AddIntConstant(submodule, "KERNING_DEFAULT", BLF_KERNING_DEFAULT);
|
||||
PyModule_AddIntConstant(submodule, "WORD_WRAP", BLF_WORD_WRAP);
|
||||
PyModule_AddIntConstant(submodule, "MONOCHROME", BLF_MONOCHROME);
|
||||
|
||||
return submodule;
|
||||
return submodule;
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
|
||||
PyObject *BPyInit_blf(void);
|
||||
|
||||
#endif /* __BLF_PY_API_H__ */
|
||||
#endif /* __BLF_PY_API_H__ */
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
* This should eventually be replaced by import hooks (pep 302).
|
||||
*/
|
||||
|
||||
|
||||
#include <Python.h>
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -39,18 +38,18 @@
|
||||
|
||||
#include "BKE_main.h"
|
||||
/* UNUSED */
|
||||
#include "BKE_text.h" /* txt_to_buf */
|
||||
#include "BKE_text.h" /* txt_to_buf */
|
||||
|
||||
#include "py_capi_utils.h"
|
||||
|
||||
#include "bpy_internal_import.h" /* own include */
|
||||
#include "bpy_internal_import.h" /* own include */
|
||||
|
||||
static Main *bpy_import_main = NULL;
|
||||
static ListBase bpy_import_main_list;
|
||||
|
||||
static PyMethodDef bpy_import_meth;
|
||||
static PyMethodDef bpy_reload_meth;
|
||||
static PyObject *imp_reload_orig = NULL;
|
||||
static PyObject *imp_reload_orig = NULL;
|
||||
|
||||
/* 'builtins' is most likely PyEval_GetBuiltins() */
|
||||
|
||||
@@ -68,304 +67,309 @@ static PyObject *imp_reload_orig = NULL;
|
||||
*/
|
||||
void bpy_import_init(PyObject *builtins)
|
||||
{
|
||||
PyObject *item;
|
||||
PyObject *mod;
|
||||
PyObject *item;
|
||||
PyObject *mod;
|
||||
|
||||
PyDict_SetItemString(builtins, "__import__", item = PyCFunction_New(&bpy_import_meth, NULL)); Py_DECREF(item);
|
||||
PyDict_SetItemString(builtins, "__import__", item = PyCFunction_New(&bpy_import_meth, NULL));
|
||||
Py_DECREF(item);
|
||||
|
||||
/* move reload here
|
||||
* XXX, use import hooks */
|
||||
mod = PyImport_ImportModuleLevel("importlib", NULL, NULL, NULL, 0);
|
||||
if (mod) {
|
||||
PyObject *mod_dict = PyModule_GetDict(mod);
|
||||
/* move reload here
|
||||
* XXX, use import hooks */
|
||||
mod = PyImport_ImportModuleLevel("importlib", NULL, NULL, NULL, 0);
|
||||
if (mod) {
|
||||
PyObject *mod_dict = PyModule_GetDict(mod);
|
||||
|
||||
/* blender owns the function */
|
||||
imp_reload_orig = PyDict_GetItemString(mod_dict, "reload");
|
||||
Py_INCREF(imp_reload_orig);
|
||||
/* blender owns the function */
|
||||
imp_reload_orig = PyDict_GetItemString(mod_dict, "reload");
|
||||
Py_INCREF(imp_reload_orig);
|
||||
|
||||
PyDict_SetItemString(mod_dict, "reload", item = PyCFunction_New(&bpy_reload_meth, NULL)); Py_DECREF(item);
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
else {
|
||||
BLI_assert(!"unable to load 'importlib' module.");
|
||||
}
|
||||
PyDict_SetItemString(mod_dict, "reload", item = PyCFunction_New(&bpy_reload_meth, NULL));
|
||||
Py_DECREF(item);
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
else {
|
||||
BLI_assert(!"unable to load 'importlib' module.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void free_compiled_text(Text *text)
|
||||
{
|
||||
if (text->compiled) {
|
||||
Py_DECREF((PyObject *)text->compiled);
|
||||
}
|
||||
text->compiled = NULL;
|
||||
if (text->compiled) {
|
||||
Py_DECREF((PyObject *)text->compiled);
|
||||
}
|
||||
text->compiled = NULL;
|
||||
}
|
||||
|
||||
struct Main *bpy_import_main_get(void)
|
||||
{
|
||||
return bpy_import_main;
|
||||
return bpy_import_main;
|
||||
}
|
||||
|
||||
void bpy_import_main_set(struct Main *maggie)
|
||||
{
|
||||
bpy_import_main = maggie;
|
||||
bpy_import_main = maggie;
|
||||
}
|
||||
|
||||
/* returns a dummy filename for a textblock so we can tell what file a text block comes from */
|
||||
void bpy_text_filename_get(char *fn, size_t fn_len, Text *text)
|
||||
{
|
||||
BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bpy_import_main, &text->id), SEP, text->id.name + 2);
|
||||
BLI_snprintf(
|
||||
fn, fn_len, "%s%c%s", ID_BLEND_PATH(bpy_import_main, &text->id), SEP, text->id.name + 2);
|
||||
}
|
||||
|
||||
bool bpy_text_compile(Text *text)
|
||||
{
|
||||
char fn_dummy[FILE_MAX];
|
||||
PyObject *fn_dummy_py;
|
||||
char *buf;
|
||||
char fn_dummy[FILE_MAX];
|
||||
PyObject *fn_dummy_py;
|
||||
char *buf;
|
||||
|
||||
bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text);
|
||||
bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text);
|
||||
|
||||
/* if previously compiled, free the object */
|
||||
free_compiled_text(text);
|
||||
/* if previously compiled, free the object */
|
||||
free_compiled_text(text);
|
||||
|
||||
fn_dummy_py = PyC_UnicodeFromByte(fn_dummy);
|
||||
fn_dummy_py = PyC_UnicodeFromByte(fn_dummy);
|
||||
|
||||
buf = txt_to_buf(text);
|
||||
text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1);
|
||||
MEM_freeN(buf);
|
||||
buf = txt_to_buf(text);
|
||||
text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1);
|
||||
MEM_freeN(buf);
|
||||
|
||||
Py_DECREF(fn_dummy_py);
|
||||
Py_DECREF(fn_dummy_py);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
PySys_SetObject("last_traceback", NULL);
|
||||
free_compiled_text(text);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
PySys_SetObject("last_traceback", NULL);
|
||||
free_compiled_text(text);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *bpy_text_import(Text *text)
|
||||
{
|
||||
char modulename[MAX_ID_NAME + 2];
|
||||
int len;
|
||||
char modulename[MAX_ID_NAME + 2];
|
||||
int len;
|
||||
|
||||
if (!text->compiled) {
|
||||
if (bpy_text_compile(text) == false) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!text->compiled) {
|
||||
if (bpy_text_compile(text) == false) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
len = strlen(text->id.name + 2);
|
||||
BLI_strncpy(modulename, text->id.name + 2, len);
|
||||
modulename[len - 3] = '\0'; /* remove .py */
|
||||
return PyImport_ExecCodeModule(modulename, text->compiled);
|
||||
len = strlen(text->id.name + 2);
|
||||
BLI_strncpy(modulename, text->id.name + 2, len);
|
||||
modulename[len - 3] = '\0'; /* remove .py */
|
||||
return PyImport_ExecCodeModule(modulename, text->compiled);
|
||||
}
|
||||
|
||||
PyObject *bpy_text_import_name(const char *name, int *found)
|
||||
{
|
||||
Text *text;
|
||||
char txtname[MAX_ID_NAME - 2];
|
||||
int namelen = strlen(name);
|
||||
//XXX Main *maggie = bpy_import_main ? bpy_import_main : G_MAIN;
|
||||
Main *maggie = bpy_import_main;
|
||||
Text *text;
|
||||
char txtname[MAX_ID_NAME - 2];
|
||||
int namelen = strlen(name);
|
||||
//XXX Main *maggie = bpy_import_main ? bpy_import_main : G_MAIN;
|
||||
Main *maggie = bpy_import_main;
|
||||
|
||||
*found = 0;
|
||||
*found = 0;
|
||||
|
||||
if (!maggie) {
|
||||
printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!maggie) {
|
||||
printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* we know this cant be importable, the name is too long for blender! */
|
||||
if (namelen >= (MAX_ID_NAME - 2) - 3) {
|
||||
return NULL;
|
||||
}
|
||||
/* we know this cant be importable, the name is too long for blender! */
|
||||
if (namelen >= (MAX_ID_NAME - 2) - 3) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(txtname, name, namelen);
|
||||
memcpy(&txtname[namelen], ".py", 4);
|
||||
memcpy(txtname, name, namelen);
|
||||
memcpy(&txtname[namelen], ".py", 4);
|
||||
|
||||
text = BLI_findstring(&maggie->texts, txtname, offsetof(ID, name) + 2);
|
||||
text = BLI_findstring(&maggie->texts, txtname, offsetof(ID, name) + 2);
|
||||
|
||||
if (text) {
|
||||
*found = 1;
|
||||
return bpy_text_import(text);
|
||||
}
|
||||
if (text) {
|
||||
*found = 1;
|
||||
return bpy_text_import(text);
|
||||
}
|
||||
|
||||
/* If we still haven't found the module try additional modules form bpy_import_main_list */
|
||||
maggie = bpy_import_main_list.first;
|
||||
while (maggie && !text) {
|
||||
text = BLI_findstring(&maggie->texts, txtname, offsetof(ID, name) + 2);
|
||||
maggie = maggie->next;
|
||||
}
|
||||
/* If we still haven't found the module try additional modules form bpy_import_main_list */
|
||||
maggie = bpy_import_main_list.first;
|
||||
while (maggie && !text) {
|
||||
text = BLI_findstring(&maggie->texts, txtname, offsetof(ID, name) + 2);
|
||||
maggie = maggie->next;
|
||||
}
|
||||
|
||||
if (!text) {
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
*found = 1;
|
||||
}
|
||||
if (!text) {
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
*found = 1;
|
||||
}
|
||||
|
||||
return bpy_text_import(text);
|
||||
return bpy_text_import(text);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* find in-memory module and recompile
|
||||
*/
|
||||
|
||||
PyObject *bpy_text_reimport(PyObject *module, int *found)
|
||||
{
|
||||
Text *text;
|
||||
const char *name;
|
||||
const char *filepath;
|
||||
//XXX Main *maggie = bpy_import_main ? bpy_import_main : G_MAIN;
|
||||
Main *maggie = bpy_import_main;
|
||||
Text *text;
|
||||
const char *name;
|
||||
const char *filepath;
|
||||
//XXX Main *maggie = bpy_import_main ? bpy_import_main : G_MAIN;
|
||||
Main *maggie = bpy_import_main;
|
||||
|
||||
if (!maggie) {
|
||||
printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!maggie) {
|
||||
printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*found = 0;
|
||||
*found = 0;
|
||||
|
||||
/* get name, filename from the module itself */
|
||||
if ((name = PyModule_GetName(module)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
/* get name, filename from the module itself */
|
||||
if ((name = PyModule_GetName(module)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
PyObject *module_file = PyModule_GetFilenameObject(module);
|
||||
if (module_file == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
filepath = _PyUnicode_AsString(module_file);
|
||||
Py_DECREF(module_file);
|
||||
if (filepath == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
{
|
||||
PyObject *module_file = PyModule_GetFilenameObject(module);
|
||||
if (module_file == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
filepath = _PyUnicode_AsString(module_file);
|
||||
Py_DECREF(module_file);
|
||||
if (filepath == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* look up the text object */
|
||||
text = BLI_findstring(&maggie->texts, BLI_path_basename(filepath), offsetof(ID, name) + 2);
|
||||
/* look up the text object */
|
||||
text = BLI_findstring(&maggie->texts, BLI_path_basename(filepath), offsetof(ID, name) + 2);
|
||||
|
||||
/* uh-oh.... didn't find it */
|
||||
if (!text) {
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
*found = 1;
|
||||
}
|
||||
/* uh-oh.... didn't find it */
|
||||
if (!text) {
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
*found = 1;
|
||||
}
|
||||
|
||||
if (bpy_text_compile(text) == false) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_text_compile(text) == false) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make into a module */
|
||||
return PyImport_ExecCodeModule(name, text->compiled);
|
||||
/* make into a module */
|
||||
return PyImport_ExecCodeModule(name, text->compiled);
|
||||
}
|
||||
|
||||
|
||||
static PyObject *blender_import(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
PyObject *exception, *err, *tb;
|
||||
const char *name;
|
||||
int found = 0;
|
||||
PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
|
||||
int level = 0; /* relative imports */
|
||||
PyObject *newmodule;
|
||||
PyObject *exception, *err, *tb;
|
||||
const char *name;
|
||||
int found = 0;
|
||||
PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
|
||||
int level = 0; /* relative imports */
|
||||
PyObject *newmodule;
|
||||
|
||||
static const char *_keywords[] = {"name", "globals", "locals", "fromlist", "level", NULL};
|
||||
static _PyArg_Parser _parser = {"s|OOOi:bpy_import_meth", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&name, &globals, &locals, &fromlist, &level))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"name", "globals", "locals", "fromlist", "level", NULL};
|
||||
static _PyArg_Parser _parser = {"s|OOOi:bpy_import_meth", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser, &name, &globals, &locals, &fromlist, &level)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* import existing builtin modules or modules that have been imported already */
|
||||
newmodule = PyImport_ImportModuleLevel(name, globals, locals, fromlist, level);
|
||||
/* import existing builtin modules or modules that have been imported already */
|
||||
newmodule = PyImport_ImportModuleLevel(name, globals, locals, fromlist, level);
|
||||
|
||||
if (newmodule) {
|
||||
return newmodule;
|
||||
}
|
||||
if (newmodule) {
|
||||
return newmodule;
|
||||
}
|
||||
|
||||
PyErr_Fetch(&exception, &err, &tb); /* get the python error in case we cant import as blender text either */
|
||||
PyErr_Fetch(&exception,
|
||||
&err,
|
||||
&tb); /* get the python error in case we cant import as blender text either */
|
||||
|
||||
/* importing from existing modules failed, see if we have this module as blender text */
|
||||
newmodule = bpy_text_import_name(name, &found);
|
||||
/* importing from existing modules failed, see if we have this module as blender text */
|
||||
newmodule = bpy_text_import_name(name, &found);
|
||||
|
||||
if (newmodule) { /* found module as blender text, ignore above exception */
|
||||
PyErr_Clear();
|
||||
Py_XDECREF(exception);
|
||||
Py_XDECREF(err);
|
||||
Py_XDECREF(tb);
|
||||
/* printf("imported from text buffer...\n"); */
|
||||
}
|
||||
else if (found == 1) { /* blender text module failed to execute but was found, use its error message */
|
||||
Py_XDECREF(exception);
|
||||
Py_XDECREF(err);
|
||||
Py_XDECREF(tb);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
/* no blender text was found that could import the module
|
||||
* reuse the original error from PyImport_ImportModuleEx */
|
||||
PyErr_Restore(exception, err, tb);
|
||||
}
|
||||
return newmodule;
|
||||
if (newmodule) { /* found module as blender text, ignore above exception */
|
||||
PyErr_Clear();
|
||||
Py_XDECREF(exception);
|
||||
Py_XDECREF(err);
|
||||
Py_XDECREF(tb);
|
||||
/* printf("imported from text buffer...\n"); */
|
||||
}
|
||||
else if (found ==
|
||||
1) { /* blender text module failed to execute but was found, use its error message */
|
||||
Py_XDECREF(exception);
|
||||
Py_XDECREF(err);
|
||||
Py_XDECREF(tb);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
/* no blender text was found that could import the module
|
||||
* reuse the original error from PyImport_ImportModuleEx */
|
||||
PyErr_Restore(exception, err, tb);
|
||||
}
|
||||
return newmodule;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* our reload() module, to handle reloading in-memory scripts
|
||||
*/
|
||||
|
||||
static PyObject *blender_reload(PyObject *UNUSED(self), PyObject *module)
|
||||
{
|
||||
PyObject *exception, *err, *tb;
|
||||
PyObject *newmodule = NULL;
|
||||
int found = 0;
|
||||
PyObject *exception, *err, *tb;
|
||||
PyObject *newmodule = NULL;
|
||||
int found = 0;
|
||||
|
||||
/* try reimporting from file */
|
||||
/* try reimporting from file */
|
||||
|
||||
/* in Py3.3 this just calls imp.reload() which we overwrite, causing recursive calls */
|
||||
//newmodule = PyImport_ReloadModule(module);
|
||||
/* in Py3.3 this just calls imp.reload() which we overwrite, causing recursive calls */
|
||||
//newmodule = PyImport_ReloadModule(module);
|
||||
|
||||
newmodule = PyObject_CallFunctionObjArgs(imp_reload_orig, module, NULL);
|
||||
newmodule = PyObject_CallFunctionObjArgs(imp_reload_orig, module, NULL);
|
||||
|
||||
if (newmodule) {
|
||||
return newmodule;
|
||||
}
|
||||
if (newmodule) {
|
||||
return newmodule;
|
||||
}
|
||||
|
||||
/* no file, try importing from memory */
|
||||
PyErr_Fetch(&exception, &err, &tb); /*restore for probable later use */
|
||||
/* no file, try importing from memory */
|
||||
PyErr_Fetch(&exception, &err, &tb); /*restore for probable later use */
|
||||
|
||||
newmodule = bpy_text_reimport(module, &found);
|
||||
if (newmodule) { /* found module as blender text, ignore above exception */
|
||||
PyErr_Clear();
|
||||
Py_XDECREF(exception);
|
||||
Py_XDECREF(err);
|
||||
Py_XDECREF(tb);
|
||||
/* printf("imported from text buffer...\n"); */
|
||||
}
|
||||
else if (found == 1) { /* blender text module failed to execute but was found, use its error message */
|
||||
Py_XDECREF(exception);
|
||||
Py_XDECREF(err);
|
||||
Py_XDECREF(tb);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
/* no blender text was found that could import the module
|
||||
* reuse the original error from PyImport_ImportModuleEx */
|
||||
PyErr_Restore(exception, err, tb);
|
||||
}
|
||||
newmodule = bpy_text_reimport(module, &found);
|
||||
if (newmodule) { /* found module as blender text, ignore above exception */
|
||||
PyErr_Clear();
|
||||
Py_XDECREF(exception);
|
||||
Py_XDECREF(err);
|
||||
Py_XDECREF(tb);
|
||||
/* printf("imported from text buffer...\n"); */
|
||||
}
|
||||
else if (found ==
|
||||
1) { /* blender text module failed to execute but was found, use its error message */
|
||||
Py_XDECREF(exception);
|
||||
Py_XDECREF(err);
|
||||
Py_XDECREF(tb);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
/* no blender text was found that could import the module
|
||||
* reuse the original error from PyImport_ImportModuleEx */
|
||||
PyErr_Restore(exception, err, tb);
|
||||
}
|
||||
|
||||
return newmodule;
|
||||
return newmodule;
|
||||
}
|
||||
|
||||
static PyMethodDef bpy_import_meth = {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"};
|
||||
static PyMethodDef bpy_reload_meth = {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"};
|
||||
static PyMethodDef bpy_import_meth = {"bpy_import_meth",
|
||||
(PyCFunction)blender_import,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
"blenders import"};
|
||||
static PyMethodDef bpy_reload_meth = {
|
||||
"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"};
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
* \ingroup pygen
|
||||
*/
|
||||
|
||||
|
||||
/* Note, the BGE needs to use this too, keep it minimal */
|
||||
|
||||
#ifndef __BPY_INTERNAL_IMPORT_H__
|
||||
@@ -26,26 +25,26 @@
|
||||
|
||||
/* python redefines :/ */
|
||||
#ifdef _POSIX_C_SOURCE
|
||||
#undef _POSIX_C_SOURCE
|
||||
# undef _POSIX_C_SOURCE
|
||||
#endif
|
||||
|
||||
#ifdef _XOPEN_SOURCE
|
||||
#undef _XOPEN_SOURCE
|
||||
# undef _XOPEN_SOURCE
|
||||
#endif
|
||||
|
||||
struct Text;
|
||||
|
||||
void bpy_import_init(PyObject *builtins);
|
||||
|
||||
bool bpy_text_compile(struct Text *text);
|
||||
PyObject *bpy_text_import(struct Text *text);
|
||||
PyObject *bpy_text_import_name(const char *name, int *found);
|
||||
PyObject *bpy_text_reimport(PyObject *module, int *found);
|
||||
/* void bpy_text_clear_modules(int clear_all);*/ /* Clear user modules */
|
||||
bool bpy_text_compile(struct Text *text);
|
||||
PyObject *bpy_text_import(struct Text *text);
|
||||
PyObject *bpy_text_import_name(const char *name, int *found);
|
||||
PyObject *bpy_text_reimport(PyObject *module, int *found);
|
||||
/* void bpy_text_clear_modules(int clear_all);*/ /* Clear user modules */
|
||||
|
||||
void bpy_text_filename_get(char *fn, size_t fn_len, struct Text *text);
|
||||
|
||||
struct Main *bpy_import_main_get(void);
|
||||
void bpy_import_main_set(struct Main *maggie);
|
||||
|
||||
#endif /* __BPY_INTERNAL_IMPORT_H__ */
|
||||
#endif /* __BPY_INTERNAL_IMPORT_H__ */
|
||||
|
||||
@@ -29,20 +29,20 @@
|
||||
/* analogue of PyEval_SaveThread() */
|
||||
BPy_ThreadStatePtr BPY_thread_save(void)
|
||||
{
|
||||
PyThreadState *tstate = PyThreadState_Swap(NULL);
|
||||
/* note: tstate can be NULL when quitting Blender */
|
||||
PyThreadState *tstate = PyThreadState_Swap(NULL);
|
||||
/* note: tstate can be NULL when quitting Blender */
|
||||
|
||||
if (tstate && PyEval_ThreadsInitialized()) {
|
||||
PyEval_ReleaseLock();
|
||||
}
|
||||
if (tstate && PyEval_ThreadsInitialized()) {
|
||||
PyEval_ReleaseLock();
|
||||
}
|
||||
|
||||
return (BPy_ThreadStatePtr)tstate;
|
||||
return (BPy_ThreadStatePtr)tstate;
|
||||
}
|
||||
|
||||
/* analogue of PyEval_RestoreThread() */
|
||||
void BPY_thread_restore(BPy_ThreadStatePtr tstate)
|
||||
{
|
||||
if (tstate) {
|
||||
PyEval_RestoreThread((PyThreadState *)tstate);
|
||||
}
|
||||
if (tstate) {
|
||||
PyEval_RestoreThread((PyThreadState *)tstate);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,6 @@
|
||||
* \ingroup pygen
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __IDPROP_PY_API_H__
|
||||
#define __IDPROP_PY_API_H__
|
||||
|
||||
@@ -30,32 +29,29 @@ extern PyTypeObject BPy_IDArray_Type;
|
||||
extern PyTypeObject BPy_IDGroup_Iter_Type;
|
||||
extern PyTypeObject BPy_IDGroup_Type;
|
||||
|
||||
#define BPy_IDArray_Check(v) (PyObject_TypeCheck(v, &BPy_IDArray_Type))
|
||||
#define BPy_IDArray_CheckExact(v) (Py_TYPE(v) == &BPy_IDArray_Type)
|
||||
#define BPy_IDGroup_Iter_Check(v) (PyObject_TypeCheck(v, &BPy_IDGroup_Iter_Type))
|
||||
#define BPy_IDGroup_Iter_CheckExact(v) (Py_TYPE(v) == &BPy_IDGroup_Iter_Type)
|
||||
#define BPy_IDGroup_Check(v) (PyObject_TypeCheck(v, &BPy_IDGroup_Type))
|
||||
#define BPy_IDGroup_CheckExact(v) (Py_TYPE(v) == &BPy_IDGroup_Type)
|
||||
#define BPy_IDArray_Check(v) (PyObject_TypeCheck(v, &BPy_IDArray_Type))
|
||||
#define BPy_IDArray_CheckExact(v) (Py_TYPE(v) == &BPy_IDArray_Type)
|
||||
#define BPy_IDGroup_Iter_Check(v) (PyObject_TypeCheck(v, &BPy_IDGroup_Iter_Type))
|
||||
#define BPy_IDGroup_Iter_CheckExact(v) (Py_TYPE(v) == &BPy_IDGroup_Iter_Type)
|
||||
#define BPy_IDGroup_Check(v) (PyObject_TypeCheck(v, &BPy_IDGroup_Type))
|
||||
#define BPy_IDGroup_CheckExact(v) (Py_TYPE(v) == &BPy_IDGroup_Type)
|
||||
|
||||
typedef struct BPy_IDProperty {
|
||||
PyObject_VAR_HEAD
|
||||
struct ID *id; /* can be NULL */
|
||||
struct IDProperty *prop; /* must be second member */
|
||||
struct IDProperty *parent;
|
||||
PyObject *data_wrap;
|
||||
PyObject_VAR_HEAD struct ID *id; /* can be NULL */
|
||||
struct IDProperty *prop; /* must be second member */
|
||||
struct IDProperty *parent;
|
||||
PyObject *data_wrap;
|
||||
} BPy_IDProperty;
|
||||
|
||||
typedef struct BPy_IDArray {
|
||||
PyObject_VAR_HEAD
|
||||
struct ID *id; /* can be NULL */
|
||||
struct IDProperty *prop; /* must be second member */
|
||||
PyObject_VAR_HEAD struct ID *id; /* can be NULL */
|
||||
struct IDProperty *prop; /* must be second member */
|
||||
} BPy_IDArray;
|
||||
|
||||
typedef struct BPy_IDGroup_Iter {
|
||||
PyObject_VAR_HEAD
|
||||
BPy_IDProperty *group;
|
||||
struct IDProperty *cur;
|
||||
int mode;
|
||||
PyObject_VAR_HEAD BPy_IDProperty *group;
|
||||
struct IDProperty *cur;
|
||||
int mode;
|
||||
} BPy_IDGroup_Iter;
|
||||
|
||||
PyObject *BPy_Wrap_GetKeys(struct IDProperty *prop);
|
||||
@@ -63,7 +59,6 @@ PyObject *BPy_Wrap_GetValues(struct ID *id, struct IDProperty *prop);
|
||||
PyObject *BPy_Wrap_GetItems(struct ID *id, struct IDProperty *prop);
|
||||
int BPy_Wrap_SetMapItem(struct IDProperty *prop, PyObject *key, PyObject *val);
|
||||
|
||||
|
||||
PyObject *BPy_IDGroup_WrapData(struct ID *id, struct IDProperty *prop, struct IDProperty *parent);
|
||||
bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *key, struct IDProperty *group, PyObject *ob);
|
||||
|
||||
@@ -71,7 +66,7 @@ void IDProp_Init_Types(void);
|
||||
|
||||
PyObject *BPyInit_idprop(void);
|
||||
|
||||
#define IDPROP_ITER_KEYS 0
|
||||
#define IDPROP_ITER_ITEMS 1
|
||||
#define IDPROP_ITER_KEYS 0
|
||||
#define IDPROP_ITER_ITEMS 1
|
||||
|
||||
#endif /* __IDPROP_PY_API_H__ */
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "python_utildefines.h"
|
||||
|
||||
#include "imbuf_py_api.h" /* own include */
|
||||
#include "imbuf_py_api.h" /* own include */
|
||||
|
||||
#include "../../imbuf/IMB_imbuf.h"
|
||||
#include "../../imbuf/IMB_imbuf_types.h"
|
||||
@@ -46,28 +46,33 @@ static PyObject *Py_ImBuf_CreatePyObject(ImBuf *ibuf);
|
||||
* \{ */
|
||||
|
||||
typedef struct Py_ImBuf {
|
||||
PyObject_VAR_HEAD
|
||||
/* can be NULL */
|
||||
ImBuf *ibuf;
|
||||
PyObject_VAR_HEAD
|
||||
/* can be NULL */
|
||||
ImBuf *ibuf;
|
||||
} Py_ImBuf;
|
||||
|
||||
static int py_imbuf_valid_check(Py_ImBuf *self)
|
||||
{
|
||||
if (LIKELY(self->ibuf)) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_ReferenceError,
|
||||
"ImBuf data of type %.200s has been freed",
|
||||
Py_TYPE(self)->tp_name);
|
||||
return -1;
|
||||
}
|
||||
if (LIKELY(self->ibuf)) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(
|
||||
PyExc_ReferenceError, "ImBuf data of type %.200s has been freed", Py_TYPE(self)->tp_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#define PY_IMBUF_CHECK_OBJ(obj) \
|
||||
if (UNLIKELY(py_imbuf_valid_check(obj) == -1)) { return NULL; } ((void)0)
|
||||
if (UNLIKELY(py_imbuf_valid_check(obj) == -1)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
((void)0)
|
||||
#define PY_IMBUF_CHECK_INT(obj) \
|
||||
if (UNLIKELY(py_imbuf_valid_check(obj) == -1)) { return -1; } ((void)0)
|
||||
if (UNLIKELY(py_imbuf_valid_check(obj) == -1)) { \
|
||||
return -1; \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -76,77 +81,72 @@ static int py_imbuf_valid_check(Py_ImBuf *self)
|
||||
* \{ */
|
||||
|
||||
PyDoc_STRVAR(py_imbuf_resize_doc,
|
||||
".. method:: resize(size, method='FAST')\n"
|
||||
"\n"
|
||||
" Resize the image.\n"
|
||||
"\n"
|
||||
" :arg size: New size.\n"
|
||||
" :type size: pair of ints\n"
|
||||
" :arg method: Method of resizing (TODO)\n"
|
||||
" :type method: str\n"
|
||||
);
|
||||
".. method:: resize(size, method='FAST')\n"
|
||||
"\n"
|
||||
" Resize the image.\n"
|
||||
"\n"
|
||||
" :arg size: New size.\n"
|
||||
" :type size: pair of ints\n"
|
||||
" :arg method: Method of resizing (TODO)\n"
|
||||
" :type method: str\n");
|
||||
static PyObject *py_imbuf_resize(Py_ImBuf *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
PY_IMBUF_CHECK_OBJ(self);
|
||||
PY_IMBUF_CHECK_OBJ(self);
|
||||
|
||||
uint size[2];
|
||||
char *method = NULL;
|
||||
uint size[2];
|
||||
char *method = NULL;
|
||||
|
||||
static const char *_keywords[] = {"size", "method", NULL};
|
||||
static _PyArg_Parser _parser = {"(II)|s:resize", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&size[0], &size[1],
|
||||
&method))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
IMB_scaleImBuf(self->ibuf, UNPACK2(size));
|
||||
Py_RETURN_NONE;
|
||||
static const char *_keywords[] = {"size", "method", NULL};
|
||||
static _PyArg_Parser _parser = {"(II)|s:resize", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &size[0], &size[1], &method)) {
|
||||
return NULL;
|
||||
}
|
||||
IMB_scaleImBuf(self->ibuf, UNPACK2(size));
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_imbuf_copy_doc,
|
||||
".. method:: copy()\n"
|
||||
"\n"
|
||||
" :return: A copy of the image.\n"
|
||||
" :rtype: :class:`ImBuf`\n"
|
||||
);
|
||||
".. method:: copy()\n"
|
||||
"\n"
|
||||
" :return: A copy of the image.\n"
|
||||
" :rtype: :class:`ImBuf`\n");
|
||||
static PyObject *py_imbuf_copy(Py_ImBuf *self)
|
||||
{
|
||||
PY_IMBUF_CHECK_OBJ(self);
|
||||
return Py_ImBuf_CreatePyObject(self->ibuf);
|
||||
PY_IMBUF_CHECK_OBJ(self);
|
||||
return Py_ImBuf_CreatePyObject(self->ibuf);
|
||||
}
|
||||
|
||||
static PyObject *py_imbuf_deepcopy(Py_ImBuf *self, PyObject *args)
|
||||
{
|
||||
if (!PyC_CheckArgs_DeepCopy(args)) {
|
||||
return NULL;
|
||||
}
|
||||
return py_imbuf_copy(self);
|
||||
if (!PyC_CheckArgs_DeepCopy(args)) {
|
||||
return NULL;
|
||||
}
|
||||
return py_imbuf_copy(self);
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(py_imbuf_free_doc,
|
||||
".. method:: free()\n"
|
||||
"\n"
|
||||
" Clear image data immediately (causing an error on re-use).\n"
|
||||
);
|
||||
".. method:: free()\n"
|
||||
"\n"
|
||||
" Clear image data immediately (causing an error on re-use).\n");
|
||||
static PyObject *py_imbuf_free(Py_ImBuf *self)
|
||||
{
|
||||
if (self->ibuf) {
|
||||
IMB_freeImBuf(self->ibuf);
|
||||
self->ibuf = NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
if (self->ibuf) {
|
||||
IMB_freeImBuf(self->ibuf);
|
||||
self->ibuf = NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static struct PyMethodDef Py_ImBuf_methods[] = {
|
||||
{"resize", (PyCFunction)py_imbuf_resize, METH_VARARGS | METH_KEYWORDS, (char *)py_imbuf_resize_doc},
|
||||
{"free", (PyCFunction)py_imbuf_free, METH_NOARGS, (char *)py_imbuf_free_doc},
|
||||
{"copy", (PyCFunction)py_imbuf_copy, METH_NOARGS, (char *)py_imbuf_copy_doc},
|
||||
{"__copy__", (PyCFunction)py_imbuf_copy, METH_NOARGS, (char *)py_imbuf_copy_doc},
|
||||
{"__deepcopy__", (PyCFunction)py_imbuf_deepcopy, METH_VARARGS, (char *)py_imbuf_copy_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"resize",
|
||||
(PyCFunction)py_imbuf_resize,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
(char *)py_imbuf_resize_doc},
|
||||
{"free", (PyCFunction)py_imbuf_free, METH_NOARGS, (char *)py_imbuf_free_doc},
|
||||
{"copy", (PyCFunction)py_imbuf_copy, METH_NOARGS, (char *)py_imbuf_copy_doc},
|
||||
{"__copy__", (PyCFunction)py_imbuf_copy, METH_NOARGS, (char *)py_imbuf_copy_doc},
|
||||
{"__deepcopy__", (PyCFunction)py_imbuf_deepcopy, METH_VARARGS, (char *)py_imbuf_copy_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
/** \} */
|
||||
@@ -155,50 +155,50 @@ static struct PyMethodDef Py_ImBuf_methods[] = {
|
||||
/** \name Attributes
|
||||
* \{ */
|
||||
|
||||
PyDoc_STRVAR(py_imbuf_size_doc,
|
||||
"size of the image in pixels.\n\n:type: pair of ints"
|
||||
);
|
||||
PyDoc_STRVAR(py_imbuf_size_doc, "size of the image in pixels.\n\n:type: pair of ints");
|
||||
static PyObject *py_imbuf_size_get(Py_ImBuf *self, void *UNUSED(closure))
|
||||
{
|
||||
PY_IMBUF_CHECK_OBJ(self);
|
||||
ImBuf *ibuf = self->ibuf;
|
||||
return PyC_Tuple_Pack_I32(ibuf->x, ibuf->y);
|
||||
PY_IMBUF_CHECK_OBJ(self);
|
||||
ImBuf *ibuf = self->ibuf;
|
||||
return PyC_Tuple_Pack_I32(ibuf->x, ibuf->y);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_imbuf_ppm_doc,
|
||||
"pixels per meter.\n\n:type: pair of floats"
|
||||
);
|
||||
PyDoc_STRVAR(py_imbuf_ppm_doc, "pixels per meter.\n\n:type: pair of floats");
|
||||
static PyObject *py_imbuf_ppm_get(Py_ImBuf *self, void *UNUSED(closure))
|
||||
{
|
||||
PY_IMBUF_CHECK_OBJ(self);
|
||||
ImBuf *ibuf = self->ibuf;
|
||||
return PyC_Tuple_Pack_F64(ibuf->ppm[0], ibuf->ppm[1]);
|
||||
PY_IMBUF_CHECK_OBJ(self);
|
||||
ImBuf *ibuf = self->ibuf;
|
||||
return PyC_Tuple_Pack_F64(ibuf->ppm[0], ibuf->ppm[1]);
|
||||
}
|
||||
|
||||
static int py_imbuf_ppm_set(Py_ImBuf *self, PyObject *value, void *UNUSED(closure))
|
||||
{
|
||||
PY_IMBUF_CHECK_INT(self);
|
||||
double ppm[2];
|
||||
PY_IMBUF_CHECK_INT(self);
|
||||
double ppm[2];
|
||||
|
||||
if (PyC_AsArray(ppm, value, 2, &PyFloat_Type, true, "ppm") == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (PyC_AsArray(ppm, value, 2, &PyFloat_Type, true, "ppm") == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ppm[0] <= 0.0 || ppm[1] <= 0.0) {
|
||||
PyErr_SetString(PyExc_ValueError, "invalid ppm value");
|
||||
return -1;
|
||||
}
|
||||
if (ppm[0] <= 0.0 || ppm[1] <= 0.0) {
|
||||
PyErr_SetString(PyExc_ValueError, "invalid ppm value");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ImBuf *ibuf = self->ibuf;
|
||||
ibuf->ppm[0] = ppm[0];
|
||||
ibuf->ppm[1] = ppm[1];
|
||||
return 0;
|
||||
ImBuf *ibuf = self->ibuf;
|
||||
ibuf->ppm[0] = ppm[0];
|
||||
ibuf->ppm[1] = ppm[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef Py_ImBuf_getseters[] = {
|
||||
{(char *)"size", (getter)py_imbuf_size_get, (setter)NULL, (char *)py_imbuf_size_doc, NULL},
|
||||
{(char *)"ppm", (getter)py_imbuf_ppm_get, (setter)py_imbuf_ppm_set, (char *)py_imbuf_ppm_doc, NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
|
||||
{(char *)"size", (getter)py_imbuf_size_get, (setter)NULL, (char *)py_imbuf_size_doc, NULL},
|
||||
{(char *)"ppm",
|
||||
(getter)py_imbuf_ppm_get,
|
||||
(setter)py_imbuf_ppm_set,
|
||||
(char *)py_imbuf_ppm_doc,
|
||||
NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
/** \} */
|
||||
@@ -209,99 +209,97 @@ static PyGetSetDef Py_ImBuf_getseters[] = {
|
||||
|
||||
static void py_imbuf_dealloc(Py_ImBuf *self)
|
||||
{
|
||||
ImBuf *ibuf = self->ibuf;
|
||||
if (ibuf != NULL) {
|
||||
IMB_freeImBuf(self->ibuf);
|
||||
self->ibuf = NULL;
|
||||
}
|
||||
PyObject_DEL(self);
|
||||
ImBuf *ibuf = self->ibuf;
|
||||
if (ibuf != NULL) {
|
||||
IMB_freeImBuf(self->ibuf);
|
||||
self->ibuf = NULL;
|
||||
}
|
||||
PyObject_DEL(self);
|
||||
}
|
||||
|
||||
static PyObject *py_imbuf_repr(Py_ImBuf *self)
|
||||
{
|
||||
const ImBuf *ibuf = self->ibuf;
|
||||
if (ibuf != NULL) {
|
||||
return PyUnicode_FromFormat(
|
||||
"<imbuf: address=%p, filename='%s', size=(%d, %d)>",
|
||||
ibuf, ibuf->name, ibuf->x, ibuf->y);
|
||||
}
|
||||
else {
|
||||
return PyUnicode_FromString(
|
||||
"<imbuf: address=0x0>");
|
||||
}
|
||||
const ImBuf *ibuf = self->ibuf;
|
||||
if (ibuf != NULL) {
|
||||
return PyUnicode_FromFormat(
|
||||
"<imbuf: address=%p, filename='%s', size=(%d, %d)>", ibuf, ibuf->name, ibuf->x, ibuf->y);
|
||||
}
|
||||
else {
|
||||
return PyUnicode_FromString("<imbuf: address=0x0>");
|
||||
}
|
||||
}
|
||||
|
||||
static Py_hash_t py_imbuf_hash(Py_ImBuf *self)
|
||||
{
|
||||
return _Py_HashPointer(self->ibuf);
|
||||
return _Py_HashPointer(self->ibuf);
|
||||
}
|
||||
|
||||
PyTypeObject Py_ImBuf_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
/* For printing, in format "<module>.<name>" */
|
||||
"ImBuf", /* tp_name */
|
||||
sizeof(Py_ImBuf), /* int tp_basicsize; */
|
||||
0, /* tp_itemsize; For allocation */
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
/* For printing, in format "<module>.<name>" */
|
||||
"ImBuf", /* tp_name */
|
||||
sizeof(Py_ImBuf), /* int tp_basicsize; */
|
||||
0, /* tp_itemsize; For allocation */
|
||||
|
||||
/* Methods to implement standard operations */
|
||||
/* Methods to implement standard operations */
|
||||
|
||||
(destructor)py_imbuf_dealloc, /* destructor tp_dealloc; */
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
NULL, /* cmpfunc tp_compare; */
|
||||
(reprfunc)py_imbuf_repr, /* reprfunc tp_repr; */
|
||||
(destructor)py_imbuf_dealloc, /* destructor tp_dealloc; */
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
NULL, /* cmpfunc tp_compare; */
|
||||
(reprfunc)py_imbuf_repr, /* reprfunc tp_repr; */
|
||||
|
||||
/* Method suites for standard classes */
|
||||
/* Method suites for standard classes */
|
||||
|
||||
NULL, /* PyNumberMethods *tp_as_number; */
|
||||
NULL, /* PySequenceMethods *tp_as_sequence; */
|
||||
NULL, /* PyMappingMethods *tp_as_mapping; */
|
||||
NULL, /* PyNumberMethods *tp_as_number; */
|
||||
NULL, /* PySequenceMethods *tp_as_sequence; */
|
||||
NULL, /* PyMappingMethods *tp_as_mapping; */
|
||||
|
||||
/* More standard operations (here for binary compatibility) */
|
||||
/* More standard operations (here for binary compatibility) */
|
||||
|
||||
(hashfunc)py_imbuf_hash, /* hashfunc tp_hash; */
|
||||
NULL, /* ternaryfunc tp_call; */
|
||||
NULL, /* reprfunc tp_str; */
|
||||
NULL, /* getattrofunc tp_getattro; */
|
||||
NULL, /* setattrofunc tp_setattro; */
|
||||
(hashfunc)py_imbuf_hash, /* hashfunc tp_hash; */
|
||||
NULL, /* ternaryfunc tp_call; */
|
||||
NULL, /* reprfunc tp_str; */
|
||||
NULL, /* getattrofunc tp_getattro; */
|
||||
NULL, /* setattrofunc tp_setattro; */
|
||||
|
||||
/* Functions to access object as input/output buffer */
|
||||
NULL, /* PyBufferProcs *tp_as_buffer; */
|
||||
/* Functions to access object as input/output buffer */
|
||||
NULL, /* PyBufferProcs *tp_as_buffer; */
|
||||
|
||||
/*** Flags to define presence of optional/expanded features ***/
|
||||
Py_TPFLAGS_DEFAULT, /* long tp_flags; */
|
||||
/*** Flags to define presence of optional/expanded features ***/
|
||||
Py_TPFLAGS_DEFAULT, /* long tp_flags; */
|
||||
|
||||
NULL, /* char *tp_doc; Documentation string */
|
||||
/*** Assigned meaning in release 2.0 ***/
|
||||
/* call function for all accessible objects */
|
||||
NULL, /* traverseproc tp_traverse; */
|
||||
NULL, /* char *tp_doc; Documentation string */
|
||||
/*** Assigned meaning in release 2.0 ***/
|
||||
/* call function for all accessible objects */
|
||||
NULL, /* traverseproc tp_traverse; */
|
||||
|
||||
/* delete references to contained objects */
|
||||
NULL, /* inquiry tp_clear; */
|
||||
/* delete references to contained objects */
|
||||
NULL, /* inquiry tp_clear; */
|
||||
|
||||
/*** Assigned meaning in release 2.1 ***/
|
||||
/*** rich comparisons ***/
|
||||
NULL, /* richcmpfunc tp_richcompare; */
|
||||
/*** Assigned meaning in release 2.1 ***/
|
||||
/*** rich comparisons ***/
|
||||
NULL, /* richcmpfunc tp_richcompare; */
|
||||
|
||||
/*** weak reference enabler ***/
|
||||
0, /* long tp_weaklistoffset; */
|
||||
/*** weak reference enabler ***/
|
||||
0, /* long tp_weaklistoffset; */
|
||||
|
||||
/*** Added in release 2.2 ***/
|
||||
/* Iterators */
|
||||
NULL, /* getiterfunc tp_iter; */
|
||||
NULL, /* iternextfunc tp_iternext; */
|
||||
/*** Attribute descriptor and subclassing stuff ***/
|
||||
Py_ImBuf_methods, /* struct PyMethodDef *tp_methods; */
|
||||
NULL, /* struct PyMemberDef *tp_members; */
|
||||
Py_ImBuf_getseters, /* struct PyGetSetDef *tp_getset; */
|
||||
/*** Added in release 2.2 ***/
|
||||
/* Iterators */
|
||||
NULL, /* getiterfunc tp_iter; */
|
||||
NULL, /* iternextfunc tp_iternext; */
|
||||
/*** Attribute descriptor and subclassing stuff ***/
|
||||
Py_ImBuf_methods, /* struct PyMethodDef *tp_methods; */
|
||||
NULL, /* struct PyMemberDef *tp_members; */
|
||||
Py_ImBuf_getseters, /* struct PyGetSetDef *tp_getset; */
|
||||
};
|
||||
|
||||
static PyObject *Py_ImBuf_CreatePyObject(ImBuf *ibuf)
|
||||
{
|
||||
Py_ImBuf *self = PyObject_New(Py_ImBuf, &Py_ImBuf_Type);
|
||||
self->ibuf = ibuf;
|
||||
return (PyObject *)self;
|
||||
Py_ImBuf *self = PyObject_New(Py_ImBuf, &Py_ImBuf_Type);
|
||||
self->ibuf = ibuf;
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -311,118 +309,107 @@ static PyObject *Py_ImBuf_CreatePyObject(ImBuf *ibuf)
|
||||
* \{ */
|
||||
|
||||
PyDoc_STRVAR(M_imbuf_new_doc,
|
||||
".. function:: new(size)\n"
|
||||
"\n"
|
||||
" Load a new image.\n"
|
||||
"\n"
|
||||
" :arg size: The size of the image in pixels.\n"
|
||||
" :type size: pair of ints\n"
|
||||
" :return: the newly loaded image.\n"
|
||||
" :rtype: :class:`ImBuf`\n"
|
||||
);
|
||||
".. function:: new(size)\n"
|
||||
"\n"
|
||||
" Load a new image.\n"
|
||||
"\n"
|
||||
" :arg size: The size of the image in pixels.\n"
|
||||
" :type size: pair of ints\n"
|
||||
" :return: the newly loaded image.\n"
|
||||
" :rtype: :class:`ImBuf`\n");
|
||||
static PyObject *M_imbuf_new(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
int size[2];
|
||||
static const char *_keywords[] = {"size", NULL};
|
||||
static _PyArg_Parser _parser = {"(ii)|i:new", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&size[0], &size[1]))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
int size[2];
|
||||
static const char *_keywords[] = {"size", NULL};
|
||||
static _PyArg_Parser _parser = {"(ii)|i:new", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &size[0], &size[1])) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* TODO, make options */
|
||||
uchar planes = 4;
|
||||
uint flags = IB_rect;
|
||||
/* TODO, make options */
|
||||
uchar planes = 4;
|
||||
uint flags = IB_rect;
|
||||
|
||||
ImBuf *ibuf = IMB_allocImBuf(UNPACK2(size), planes, flags);
|
||||
if (ibuf == NULL) {
|
||||
PyErr_Format(PyExc_ValueError, "new: Unable to create image (%d, %d)", UNPACK2(size));
|
||||
return NULL;
|
||||
}
|
||||
return Py_ImBuf_CreatePyObject(ibuf);
|
||||
ImBuf *ibuf = IMB_allocImBuf(UNPACK2(size), planes, flags);
|
||||
if (ibuf == NULL) {
|
||||
PyErr_Format(PyExc_ValueError, "new: Unable to create image (%d, %d)", UNPACK2(size));
|
||||
return NULL;
|
||||
}
|
||||
return Py_ImBuf_CreatePyObject(ibuf);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(M_imbuf_load_doc,
|
||||
".. function:: load(filename)\n"
|
||||
"\n"
|
||||
" Load an image from a file.\n"
|
||||
"\n"
|
||||
" :arg filename: the filename of the image.\n"
|
||||
" :type filename: string\n"
|
||||
" :return: the newly loaded image.\n"
|
||||
" :rtype: :class:`ImBuf`\n"
|
||||
);
|
||||
".. function:: load(filename)\n"
|
||||
"\n"
|
||||
" Load an image from a file.\n"
|
||||
"\n"
|
||||
" :arg filename: the filename of the image.\n"
|
||||
" :type filename: string\n"
|
||||
" :return: the newly loaded image.\n"
|
||||
" :rtype: :class:`ImBuf`\n");
|
||||
static PyObject *M_imbuf_load(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
const char *filename;
|
||||
const char *filename;
|
||||
|
||||
static const char *_keywords[] = {"filename", NULL};
|
||||
static _PyArg_Parser _parser = {"s:load", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&filename))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"filename", NULL};
|
||||
static _PyArg_Parser _parser = {"s:load", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &filename)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int file = BLI_open(filename, O_BINARY | O_RDONLY, 0);
|
||||
if (file == -1) {
|
||||
PyErr_Format(PyExc_IOError, "load: %s, failed to open file '%s'", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
const int file = BLI_open(filename, O_BINARY | O_RDONLY, 0);
|
||||
if (file == -1) {
|
||||
PyErr_Format(PyExc_IOError, "load: %s, failed to open file '%s'", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ImBuf *ibuf = IMB_loadifffile(file, filename, IB_rect, NULL, filename);
|
||||
ImBuf *ibuf = IMB_loadifffile(file, filename, IB_rect, NULL, filename);
|
||||
|
||||
close(file);
|
||||
close(file);
|
||||
|
||||
if (ibuf == NULL) {
|
||||
PyErr_Format(PyExc_ValueError, "load: Unable to recognize image format for file '%s'", filename);
|
||||
return NULL;
|
||||
}
|
||||
if (ibuf == NULL) {
|
||||
PyErr_Format(
|
||||
PyExc_ValueError, "load: Unable to recognize image format for file '%s'", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLI_strncpy(ibuf->name, filename, sizeof(ibuf->name));
|
||||
BLI_strncpy(ibuf->name, filename, sizeof(ibuf->name));
|
||||
|
||||
return Py_ImBuf_CreatePyObject(ibuf);
|
||||
return Py_ImBuf_CreatePyObject(ibuf);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(M_imbuf_write_doc,
|
||||
".. function:: write(image, filename)\n"
|
||||
"\n"
|
||||
" Write an image.\n"
|
||||
"\n"
|
||||
" :arg image: the image to write.\n"
|
||||
" :type image: :class:`ImBuf`\n"
|
||||
" :arg filename: the filename of the image.\n"
|
||||
" :type filename: string\n"
|
||||
);
|
||||
".. function:: write(image, filename)\n"
|
||||
"\n"
|
||||
" Write an image.\n"
|
||||
"\n"
|
||||
" :arg image: the image to write.\n"
|
||||
" :type image: :class:`ImBuf`\n"
|
||||
" :arg filename: the filename of the image.\n"
|
||||
" :type filename: string\n");
|
||||
static PyObject *M_imbuf_write(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
Py_ImBuf *py_imb;
|
||||
const char *filename = NULL;
|
||||
Py_ImBuf *py_imb;
|
||||
const char *filename = NULL;
|
||||
|
||||
static const char *_keywords[] = {"image", "filename", NULL};
|
||||
static _PyArg_Parser _parser = {"O!|s:write", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&Py_ImBuf_Type, &py_imb,
|
||||
&filename))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"image", "filename", NULL};
|
||||
static _PyArg_Parser _parser = {"O!|s:write", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &Py_ImBuf_Type, &py_imb, &filename)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (filename == NULL) {
|
||||
filename = py_imb->ibuf->name;
|
||||
}
|
||||
if (filename == NULL) {
|
||||
filename = py_imb->ibuf->name;
|
||||
}
|
||||
|
||||
bool ok = IMB_saveiff(py_imb->ibuf, filename, IB_rect);
|
||||
if (ok == false) {
|
||||
PyErr_Format(PyExc_IOError, "write: Unable to write image file (%s) '%s'", strerror(errno), filename);
|
||||
return NULL;
|
||||
}
|
||||
bool ok = IMB_saveiff(py_imb->ibuf, filename, IB_rect);
|
||||
if (ok == false) {
|
||||
PyErr_Format(
|
||||
PyExc_IOError, "write: Unable to write image file (%s) '%s'", strerror(errno), filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -432,36 +419,34 @@ static PyObject *M_imbuf_write(PyObject *UNUSED(self), PyObject *args, PyObject
|
||||
* \{ */
|
||||
|
||||
static PyMethodDef IMB_methods[] = {
|
||||
{"new", (PyCFunction) M_imbuf_new, METH_VARARGS | METH_KEYWORDS, M_imbuf_new_doc},
|
||||
{"load", (PyCFunction) M_imbuf_load, METH_VARARGS | METH_KEYWORDS, M_imbuf_load_doc},
|
||||
{"write", (PyCFunction) M_imbuf_write, METH_VARARGS | METH_KEYWORDS, M_imbuf_write_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"new", (PyCFunction)M_imbuf_new, METH_VARARGS | METH_KEYWORDS, M_imbuf_new_doc},
|
||||
{"load", (PyCFunction)M_imbuf_load, METH_VARARGS | METH_KEYWORDS, M_imbuf_load_doc},
|
||||
{"write", (PyCFunction)M_imbuf_write, METH_VARARGS | METH_KEYWORDS, M_imbuf_write_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(IMB_doc,
|
||||
"This module provides access to Blender's image manipulation API."
|
||||
);
|
||||
PyDoc_STRVAR(IMB_doc, "This module provides access to Blender's image manipulation API.");
|
||||
static struct PyModuleDef IMB_module_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"imbuf", /* m_name */
|
||||
IMB_doc, /* m_doc */
|
||||
0, /* m_size */
|
||||
IMB_methods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"imbuf", /* m_name */
|
||||
IMB_doc, /* m_doc */
|
||||
0, /* m_size */
|
||||
IMB_methods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
};
|
||||
|
||||
PyObject *BPyInit_imbuf(void)
|
||||
{
|
||||
PyObject *submodule;
|
||||
PyObject *submodule;
|
||||
|
||||
submodule = PyModule_Create(&IMB_module_def);
|
||||
submodule = PyModule_Create(&IMB_module_def);
|
||||
|
||||
PyType_Ready(&Py_ImBuf_Type);
|
||||
PyType_Ready(&Py_ImBuf_Type);
|
||||
|
||||
return submodule;
|
||||
return submodule;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -25,4 +25,4 @@ PyObject *BPyInit_imbuf(void);
|
||||
|
||||
extern PyTypeObject Py_ImBuf_Type;
|
||||
|
||||
#endif /* __IMBUF_PY_API_H__ */
|
||||
#endif /* __IMBUF_PY_API_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,10 +24,10 @@
|
||||
#include "BLI_sys_types.h"
|
||||
#include "BLI_utildefines_variadic.h"
|
||||
|
||||
void PyC_ObSpit(const char *name, PyObject *var);
|
||||
void PyC_ObSpitStr(char *result, size_t result_len, PyObject *var);
|
||||
void PyC_LineSpit(void);
|
||||
void PyC_StackSpit(void);
|
||||
void PyC_ObSpit(const char *name, PyObject *var);
|
||||
void PyC_ObSpitStr(char *result, size_t result_len, PyObject *var);
|
||||
void PyC_LineSpit(void);
|
||||
void PyC_StackSpit(void);
|
||||
PyObject *PyC_ExceptionBuffer(void);
|
||||
PyObject *PyC_ExceptionBuffer_Simple(void);
|
||||
PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...);
|
||||
@@ -36,40 +36,46 @@ PyObject *PyC_FrozenSetFromStrings(const char **strings);
|
||||
PyObject *PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...);
|
||||
PyObject *PyC_Err_SetString_Prefix(PyObject *exception_type_prefix, const char *str);
|
||||
|
||||
void PyC_Err_PrintWithFunc(PyObject *py_func);
|
||||
void PyC_Err_PrintWithFunc(PyObject *py_func);
|
||||
|
||||
void PyC_FileAndNum(const char **filename, int *lineno);
|
||||
void PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python is running */
|
||||
int PyC_AsArray_FAST(
|
||||
void *array, PyObject *value_fast, const Py_ssize_t length,
|
||||
const PyTypeObject *type, const bool is_double, const char *error_prefix);
|
||||
int PyC_AsArray(
|
||||
void *array, PyObject *value, const Py_ssize_t length,
|
||||
const PyTypeObject *type, const bool is_double, const char *error_prefix);
|
||||
void PyC_FileAndNum(const char **filename, int *lineno);
|
||||
void PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python is running */
|
||||
int PyC_AsArray_FAST(void *array,
|
||||
PyObject *value_fast,
|
||||
const Py_ssize_t length,
|
||||
const PyTypeObject *type,
|
||||
const bool is_double,
|
||||
const char *error_prefix);
|
||||
int PyC_AsArray(void *array,
|
||||
PyObject *value,
|
||||
const Py_ssize_t length,
|
||||
const PyTypeObject *type,
|
||||
const bool is_double,
|
||||
const char *error_prefix);
|
||||
|
||||
PyObject *PyC_Tuple_PackArray_F32(const float *array, uint len);
|
||||
PyObject *PyC_Tuple_PackArray_F64(const double *array, uint len);
|
||||
PyObject *PyC_Tuple_PackArray_I32(const int *array, uint len);
|
||||
PyObject *PyC_Tuple_PackArray_I32FromBool(const int *array, uint len);
|
||||
PyObject *PyC_Tuple_PackArray_Bool(const bool *array, uint len);
|
||||
PyObject *PyC_Tuple_PackArray_F32(const float *array, uint len);
|
||||
PyObject *PyC_Tuple_PackArray_F64(const double *array, uint len);
|
||||
PyObject *PyC_Tuple_PackArray_I32(const int *array, uint len);
|
||||
PyObject *PyC_Tuple_PackArray_I32FromBool(const int *array, uint len);
|
||||
PyObject *PyC_Tuple_PackArray_Bool(const bool *array, uint len);
|
||||
|
||||
#define PyC_Tuple_Pack_F32(...) \
|
||||
PyC_Tuple_PackArray_F32(((const float []){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
|
||||
PyC_Tuple_PackArray_F32(((const float[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
|
||||
#define PyC_Tuple_Pack_F64(...) \
|
||||
PyC_Tuple_PackArray_F64(((const double []){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
|
||||
PyC_Tuple_PackArray_F64(((const double[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
|
||||
#define PyC_Tuple_Pack_I32(...) \
|
||||
PyC_Tuple_PackArray_I32(((const int []){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
|
||||
PyC_Tuple_PackArray_I32(((const int[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
|
||||
#define PyC_Tuple_Pack_I32FromBool(...) \
|
||||
PyC_Tuple_PackArray_I32FromBool(((const int []){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
|
||||
PyC_Tuple_PackArray_I32FromBool(((const int[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
|
||||
#define PyC_Tuple_Pack_Bool(...) \
|
||||
PyC_Tuple_PackArray_Bool(((const bool []){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
|
||||
PyC_Tuple_PackArray_Bool(((const bool[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__))
|
||||
|
||||
void PyC_Tuple_Fill(PyObject *tuple, PyObject *value);
|
||||
void PyC_List_Fill(PyObject *list, PyObject *value);
|
||||
void PyC_Tuple_Fill(PyObject *tuple, PyObject *value);
|
||||
void PyC_List_Fill(PyObject *list, PyObject *value);
|
||||
|
||||
/* follow http://www.python.org/dev/peps/pep-0383/ */
|
||||
PyObject *PyC_UnicodeFromByte(const char *str);
|
||||
PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size);
|
||||
PyObject *PyC_UnicodeFromByte(const char *str);
|
||||
PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size);
|
||||
const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce); /* coerce must be NULL */
|
||||
const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObject **coerce);
|
||||
|
||||
@@ -89,34 +95,49 @@ void *PyC_RNA_AsPointer(PyObject *value, const char *type_name);
|
||||
|
||||
/* flag / set --- interchange */
|
||||
typedef struct PyC_FlagSet {
|
||||
int value;
|
||||
const char *identifier;
|
||||
int value;
|
||||
const char *identifier;
|
||||
} PyC_FlagSet;
|
||||
|
||||
char *PyC_FlagSet_AsString(PyC_FlagSet *item);
|
||||
int PyC_FlagSet_ValueFromID_int(PyC_FlagSet *item, const char *identifier, int *r_value);
|
||||
int PyC_FlagSet_ValueFromID(PyC_FlagSet *item, const char *identifier, int *r_value, const char *error_prefix);
|
||||
int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, const char *error_prefix);
|
||||
char *PyC_FlagSet_AsString(PyC_FlagSet *item);
|
||||
int PyC_FlagSet_ValueFromID_int(PyC_FlagSet *item, const char *identifier, int *r_value);
|
||||
int PyC_FlagSet_ValueFromID(PyC_FlagSet *item,
|
||||
const char *identifier,
|
||||
int *r_value,
|
||||
const char *error_prefix);
|
||||
int PyC_FlagSet_ToBitfield(PyC_FlagSet *items,
|
||||
PyObject *value,
|
||||
int *r_value,
|
||||
const char *error_prefix);
|
||||
PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag);
|
||||
|
||||
bool PyC_RunString_AsNumber(const char **imports, const char *expr, const char *filename, double *r_value);
|
||||
bool PyC_RunString_AsIntPtr(const char **imports, const char *expr, const char *filename, intptr_t *r_value);
|
||||
bool PyC_RunString_AsString(const char **imports, const char *expr, const char *filename, char **r_value);
|
||||
bool PyC_RunString_AsNumber(const char **imports,
|
||||
const char *expr,
|
||||
const char *filename,
|
||||
double *r_value);
|
||||
bool PyC_RunString_AsIntPtr(const char **imports,
|
||||
const char *expr,
|
||||
const char *filename,
|
||||
intptr_t *r_value);
|
||||
bool PyC_RunString_AsString(const char **imports,
|
||||
const char *expr,
|
||||
const char *filename,
|
||||
char **r_value);
|
||||
|
||||
int PyC_ParseBool(PyObject *o, void *p);
|
||||
|
||||
int PyC_CheckArgs_DeepCopy(PyObject *args);
|
||||
|
||||
/* Integer parsing (with overflow checks), -1 on error. */
|
||||
int PyC_Long_AsBool(PyObject *value);
|
||||
int8_t PyC_Long_AsI8(PyObject *value);
|
||||
int PyC_Long_AsBool(PyObject *value);
|
||||
int8_t PyC_Long_AsI8(PyObject *value);
|
||||
int16_t PyC_Long_AsI16(PyObject *value);
|
||||
#if 0 /* inline */
|
||||
int32_t PyC_Long_AsI32(PyObject *value);
|
||||
int64_t PyC_Long_AsI64(PyObject *value);
|
||||
#endif
|
||||
|
||||
uint8_t PyC_Long_AsU8(PyObject *value);
|
||||
uint8_t PyC_Long_AsU8(PyObject *value);
|
||||
uint16_t PyC_Long_AsU16(PyObject *value);
|
||||
uint32_t PyC_Long_AsU32(PyObject *value);
|
||||
#if 0 /* inline */
|
||||
@@ -124,9 +145,18 @@ uint64_t PyC_Long_AsU64(PyObject *value);
|
||||
#endif
|
||||
|
||||
/* inline so type signatures match as expected */
|
||||
Py_LOCAL_INLINE(int32_t) PyC_Long_AsI32(PyObject *value) { return (int32_t)_PyLong_AsInt(value); }
|
||||
Py_LOCAL_INLINE(int64_t) PyC_Long_AsI64(PyObject *value) { return (int64_t)PyLong_AsLongLong(value); }
|
||||
Py_LOCAL_INLINE(uint64_t) PyC_Long_AsU64(PyObject *value) { return (uint64_t)PyLong_AsUnsignedLongLong(value); }
|
||||
Py_LOCAL_INLINE(int32_t) PyC_Long_AsI32(PyObject *value)
|
||||
{
|
||||
return (int32_t)_PyLong_AsInt(value);
|
||||
}
|
||||
Py_LOCAL_INLINE(int64_t) PyC_Long_AsI64(PyObject *value)
|
||||
{
|
||||
return (int64_t)PyLong_AsLongLong(value);
|
||||
}
|
||||
Py_LOCAL_INLINE(uint64_t) PyC_Long_AsU64(PyObject *value)
|
||||
{
|
||||
return (uint64_t)PyLong_AsUnsignedLongLong(value);
|
||||
}
|
||||
|
||||
/* utils for format string in `struct` module style syntax */
|
||||
char PyC_StructFmt_type_from_str(const char *typestr);
|
||||
@@ -135,4 +165,4 @@ bool PyC_StructFmt_type_is_int_any(char format);
|
||||
bool PyC_StructFmt_type_is_byte(char format);
|
||||
bool PyC_StructFmt_type_is_bool(char format);
|
||||
|
||||
#endif /* __PY_CAPI_UTILS_H__ */
|
||||
#endif /* __PY_CAPI_UTILS_H__ */
|
||||
|
||||
@@ -28,28 +28,33 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define PyTuple_SET_ITEMS(op_arg, ...) \
|
||||
{ \
|
||||
PyTupleObject *op = (PyTupleObject *)op_arg; \
|
||||
PyObject **ob_items = op->ob_item; \
|
||||
CHECK_TYPE_ANY(op_arg, PyObject *, PyTupleObject *); \
|
||||
BLI_assert(VA_NARGS_COUNT(__VA_ARGS__) == PyTuple_GET_SIZE(op)); \
|
||||
ARRAY_SET_ITEMS(ob_items, __VA_ARGS__); \
|
||||
} (void)0
|
||||
{ \
|
||||
PyTupleObject *op = (PyTupleObject *)op_arg; \
|
||||
PyObject **ob_items = op->ob_item; \
|
||||
CHECK_TYPE_ANY(op_arg, PyObject *, PyTupleObject *); \
|
||||
BLI_assert(VA_NARGS_COUNT(__VA_ARGS__) == PyTuple_GET_SIZE(op)); \
|
||||
ARRAY_SET_ITEMS(ob_items, __VA_ARGS__); \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
/* wrap Py_INCREF & return the result,
|
||||
* use sparingly to avoid comma operator or temp var assignment */
|
||||
Py_LOCAL_INLINE(PyObject *)Py_INCREF_RET(PyObject *op) { Py_INCREF(op); return op; }
|
||||
Py_LOCAL_INLINE(PyObject *) Py_INCREF_RET(PyObject *op)
|
||||
{
|
||||
Py_INCREF(op);
|
||||
return op;
|
||||
}
|
||||
|
||||
/* append & transfer ownership to the list, avoids inline Py_DECREF all over (which is quite a large macro) */
|
||||
Py_LOCAL_INLINE(int) PyList_APPEND(PyObject *op, PyObject *v)
|
||||
{
|
||||
int ret = PyList_Append(op, v);
|
||||
Py_DecRef(v);
|
||||
return ret;
|
||||
int ret = PyList_Append(op, v);
|
||||
Py_DecRef(v);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PYTHON_UTILDEFINES_H__ */
|
||||
#endif /* __PYTHON_UTILDEFINES_H__ */
|
||||
|
||||
@@ -16,42 +16,42 @@
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
.
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../gpu
|
||||
../../makesdna
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
.
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../gpu
|
||||
../../makesdna
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${GLEW_INCLUDE_PATH}
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
${GLEW_INCLUDE_PATH}
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
gpu_py_api.c
|
||||
gpu_py_batch.c
|
||||
gpu_py_element.c
|
||||
gpu_py_matrix.c
|
||||
gpu_py_offscreen.c
|
||||
gpu_py_select.c
|
||||
gpu_py_shader.c
|
||||
gpu_py_types.c
|
||||
gpu_py_vertex_buffer.c
|
||||
gpu_py_vertex_format.c
|
||||
gpu_py_api.c
|
||||
gpu_py_batch.c
|
||||
gpu_py_element.c
|
||||
gpu_py_matrix.c
|
||||
gpu_py_offscreen.c
|
||||
gpu_py_select.c
|
||||
gpu_py_shader.c
|
||||
gpu_py_types.c
|
||||
gpu_py_vertex_buffer.c
|
||||
gpu_py_vertex_format.c
|
||||
|
||||
gpu_py_api.h
|
||||
gpu_py_batch.h
|
||||
gpu_py_element.h
|
||||
gpu_py_matrix.h
|
||||
gpu_py_offscreen.h
|
||||
gpu_py_select.h
|
||||
gpu_py_shader.h
|
||||
gpu_py_types.h
|
||||
gpu_py_vertex_buffer.h
|
||||
gpu_py_vertex_format.h
|
||||
gpu_py_api.h
|
||||
gpu_py_batch.h
|
||||
gpu_py_element.h
|
||||
gpu_py_matrix.h
|
||||
gpu_py_offscreen.h
|
||||
gpu_py_select.h
|
||||
gpu_py_shader.h
|
||||
gpu_py_types.h
|
||||
gpu_py_vertex_buffer.h
|
||||
gpu_py_vertex_format.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
|
||||
@@ -39,120 +39,111 @@
|
||||
|
||||
#include "gpu_py_api.h" /* own include */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Utils to invalidate functions
|
||||
* \{ */
|
||||
|
||||
bool bpygpu_is_initialized_or_error(void)
|
||||
{
|
||||
if (!GPU_is_initialized()) {
|
||||
PyErr_SetString(
|
||||
PyExc_SystemError,
|
||||
"GPU functions for drawing are not available in background mode");
|
||||
if (!GPU_is_initialized()) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"GPU functions for drawing are not available in background mode");
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Primitive Type Utils
|
||||
* \{ */
|
||||
|
||||
int bpygpu_ParsePrimType(PyObject *o, void *p)
|
||||
{
|
||||
Py_ssize_t mode_id_len;
|
||||
const char *mode_id = _PyUnicode_AsStringAndSize(o, &mode_id_len);
|
||||
if (mode_id == NULL) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"expected a string, got %s",
|
||||
Py_TYPE(o)->tp_name);
|
||||
return 0;
|
||||
}
|
||||
Py_ssize_t mode_id_len;
|
||||
const char *mode_id = _PyUnicode_AsStringAndSize(o, &mode_id_len);
|
||||
if (mode_id == NULL) {
|
||||
PyErr_Format(PyExc_ValueError, "expected a string, got %s", Py_TYPE(o)->tp_name);
|
||||
return 0;
|
||||
}
|
||||
#define MATCH_ID(id) \
|
||||
if (mode_id_len == strlen(STRINGIFY(id))) { \
|
||||
if (STREQ(mode_id, STRINGIFY(id))) { \
|
||||
mode = GPU_PRIM_##id; \
|
||||
goto success; \
|
||||
} \
|
||||
} ((void)0)
|
||||
if (mode_id_len == strlen(STRINGIFY(id))) { \
|
||||
if (STREQ(mode_id, STRINGIFY(id))) { \
|
||||
mode = GPU_PRIM_##id; \
|
||||
goto success; \
|
||||
} \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
GPUPrimType mode;
|
||||
MATCH_ID(POINTS);
|
||||
MATCH_ID(LINES);
|
||||
MATCH_ID(TRIS);
|
||||
MATCH_ID(LINE_STRIP);
|
||||
MATCH_ID(LINE_LOOP);
|
||||
MATCH_ID(TRI_STRIP);
|
||||
MATCH_ID(TRI_FAN);
|
||||
MATCH_ID(LINE_STRIP_ADJ);
|
||||
GPUPrimType mode;
|
||||
MATCH_ID(POINTS);
|
||||
MATCH_ID(LINES);
|
||||
MATCH_ID(TRIS);
|
||||
MATCH_ID(LINE_STRIP);
|
||||
MATCH_ID(LINE_LOOP);
|
||||
MATCH_ID(TRI_STRIP);
|
||||
MATCH_ID(TRI_FAN);
|
||||
MATCH_ID(LINE_STRIP_ADJ);
|
||||
|
||||
#undef MATCH_ID
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"unknown type literal: '%s'",
|
||||
mode_id);
|
||||
return 0;
|
||||
PyErr_Format(PyExc_ValueError, "unknown type literal: '%s'", mode_id);
|
||||
return 0;
|
||||
|
||||
success:
|
||||
(*(GPUPrimType *)p) = mode;
|
||||
return 1;
|
||||
(*(GPUPrimType *)p) = mode;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name GPU Module
|
||||
* \{ */
|
||||
|
||||
|
||||
PyDoc_STRVAR(GPU_doc,
|
||||
"This module provides Python wrappers for the GPU implementation in Blender. "
|
||||
"Some higher level functions can be found in the `gpu_extras` module. "
|
||||
"\n\n"
|
||||
"Submodules:\n"
|
||||
"\n"
|
||||
".. toctree::\n"
|
||||
" :maxdepth: 1\n"
|
||||
"\n"
|
||||
" gpu.types.rst\n"
|
||||
" gpu.shader.rst\n"
|
||||
" gpu.matrix.rst\n"
|
||||
" gpu.select.rst\n"
|
||||
"\n"
|
||||
);
|
||||
"This module provides Python wrappers for the GPU implementation in Blender. "
|
||||
"Some higher level functions can be found in the `gpu_extras` module. "
|
||||
"\n\n"
|
||||
"Submodules:\n"
|
||||
"\n"
|
||||
".. toctree::\n"
|
||||
" :maxdepth: 1\n"
|
||||
"\n"
|
||||
" gpu.types.rst\n"
|
||||
" gpu.shader.rst\n"
|
||||
" gpu.matrix.rst\n"
|
||||
" gpu.select.rst\n"
|
||||
"\n");
|
||||
static struct PyModuleDef GPU_module_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "gpu",
|
||||
.m_doc = GPU_doc,
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "gpu",
|
||||
.m_doc = GPU_doc,
|
||||
};
|
||||
|
||||
PyObject *BPyInit_gpu(void)
|
||||
{
|
||||
PyObject *sys_modules = PyImport_GetModuleDict();
|
||||
PyObject *submodule;
|
||||
PyObject *mod;
|
||||
PyObject *sys_modules = PyImport_GetModuleDict();
|
||||
PyObject *submodule;
|
||||
PyObject *mod;
|
||||
|
||||
mod = PyModule_Create(&GPU_module_def);
|
||||
mod = PyModule_Create(&GPU_module_def);
|
||||
|
||||
PyModule_AddObject(mod, "types", (submodule = BPyInit_gpu_types()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
PyModule_AddObject(mod, "types", (submodule = BPyInit_gpu_types()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
|
||||
PyModule_AddObject(mod, "matrix", (submodule = BPyInit_gpu_matrix()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
PyModule_AddObject(mod, "matrix", (submodule = BPyInit_gpu_matrix()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
|
||||
PyModule_AddObject(mod, "select", (submodule = BPyInit_gpu_select()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
PyModule_AddObject(mod, "select", (submodule = BPyInit_gpu_select()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
|
||||
PyModule_AddObject(mod, "shader", (submodule = BPyInit_gpu_shader()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
PyModule_AddObject(mod, "shader", (submodule = BPyInit_gpu_shader()));
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
|
||||
|
||||
return mod;
|
||||
return mod;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -21,13 +21,20 @@
|
||||
#ifndef __GPU_PY_API_H__
|
||||
#define __GPU_PY_API_H__
|
||||
|
||||
|
||||
int bpygpu_ParsePrimType(PyObject *o, void *p);
|
||||
|
||||
PyObject *BPyInit_gpu(void);
|
||||
|
||||
bool bpygpu_is_initialized_or_error(void);
|
||||
#define BPYGPU_IS_INIT_OR_ERROR_OBJ if (UNLIKELY(!bpygpu_is_initialized_or_error())) { return NULL; } ((void)0)
|
||||
#define BPYGPU_IS_INIT_OR_ERROR_INT if (UNLIKELY(!bpygpu_is_initialized_or_error())) { return -1; } ((void)0)
|
||||
#define BPYGPU_IS_INIT_OR_ERROR_OBJ \
|
||||
if (UNLIKELY(!bpygpu_is_initialized_or_error())) { \
|
||||
return NULL; \
|
||||
} \
|
||||
((void)0)
|
||||
#define BPYGPU_IS_INIT_OR_ERROR_INT \
|
||||
if (UNLIKELY(!bpygpu_is_initialized_or_error())) { \
|
||||
return -1; \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
#endif /* __GPU_PY_API_H__ */
|
||||
#endif /* __GPU_PY_API_H__ */
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
|
||||
#include "GPU_batch.h"
|
||||
|
||||
#include "../mathutils/mathutils.h"
|
||||
@@ -45,85 +44,81 @@
|
||||
#include "gpu_py_element.h"
|
||||
#include "gpu_py_batch.h" /* own include */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Utility Functions
|
||||
* \{ */
|
||||
|
||||
static bool bpygpu_batch_is_program_or_error(BPyGPUBatch *self)
|
||||
{
|
||||
if (!glIsProgram(self->batch->program)) {
|
||||
PyErr_SetString(
|
||||
PyExc_RuntimeError,
|
||||
"batch does not have any program assigned to it");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (!glIsProgram(self->batch->program)) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "batch does not have any program assigned to it");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name GPUBatch Type
|
||||
* \{ */
|
||||
|
||||
static PyObject *bpygpu_Batch_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
|
||||
{
|
||||
BPYGPU_IS_INIT_OR_ERROR_OBJ;
|
||||
BPYGPU_IS_INIT_OR_ERROR_OBJ;
|
||||
|
||||
const char *exc_str_missing_arg = "GPUBatch.__new__() missing required argument '%s' (pos %d)";
|
||||
const char *exc_str_missing_arg = "GPUBatch.__new__() missing required argument '%s' (pos %d)";
|
||||
|
||||
struct {
|
||||
GPUPrimType type_id;
|
||||
BPyGPUVertBuf *py_vertbuf;
|
||||
BPyGPUIndexBuf *py_indexbuf;
|
||||
} params = {GPU_PRIM_NONE, NULL, NULL};
|
||||
struct {
|
||||
GPUPrimType type_id;
|
||||
BPyGPUVertBuf *py_vertbuf;
|
||||
BPyGPUIndexBuf *py_indexbuf;
|
||||
} params = {GPU_PRIM_NONE, NULL, NULL};
|
||||
|
||||
static const char *_keywords[] = {"type", "buf", "elem", NULL};
|
||||
static _PyArg_Parser _parser = {"|$O&O!O!:GPUBatch.__new__", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kwds, &_parser,
|
||||
bpygpu_ParsePrimType, ¶ms.type_id,
|
||||
&BPyGPUVertBuf_Type, ¶ms.py_vertbuf,
|
||||
&BPyGPUIndexBuf_Type, ¶ms.py_indexbuf))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"type", "buf", "elem", NULL};
|
||||
static _PyArg_Parser _parser = {"|$O&O!O!:GPUBatch.__new__", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args,
|
||||
kwds,
|
||||
&_parser,
|
||||
bpygpu_ParsePrimType,
|
||||
¶ms.type_id,
|
||||
&BPyGPUVertBuf_Type,
|
||||
¶ms.py_vertbuf,
|
||||
&BPyGPUIndexBuf_Type,
|
||||
¶ms.py_indexbuf)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (params.type_id == GPU_PRIM_NONE) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
exc_str_missing_arg, _keywords[0], 1);
|
||||
return NULL;
|
||||
}
|
||||
if (params.type_id == GPU_PRIM_NONE) {
|
||||
PyErr_Format(PyExc_TypeError, exc_str_missing_arg, _keywords[0], 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (params.py_vertbuf == NULL) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
exc_str_missing_arg, _keywords[1], 2);
|
||||
return NULL;
|
||||
}
|
||||
if (params.py_vertbuf == NULL) {
|
||||
PyErr_Format(PyExc_TypeError, exc_str_missing_arg, _keywords[1], 2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GPUBatch *batch = GPU_batch_create(
|
||||
params.type_id,
|
||||
params.py_vertbuf->buf,
|
||||
params.py_indexbuf ? params.py_indexbuf->elem : NULL);
|
||||
GPUBatch *batch = GPU_batch_create(params.type_id,
|
||||
params.py_vertbuf->buf,
|
||||
params.py_indexbuf ? params.py_indexbuf->elem : NULL);
|
||||
|
||||
BPyGPUBatch *ret = (BPyGPUBatch *)BPyGPUBatch_CreatePyObject(batch);
|
||||
BPyGPUBatch *ret = (BPyGPUBatch *)BPyGPUBatch_CreatePyObject(batch);
|
||||
|
||||
#ifdef USE_GPU_PY_REFERENCES
|
||||
ret->references = PyList_New(params.py_indexbuf ? 2 : 1);
|
||||
PyList_SET_ITEM(ret->references, 0, (PyObject *)params.py_vertbuf);
|
||||
Py_INCREF(params.py_vertbuf);
|
||||
ret->references = PyList_New(params.py_indexbuf ? 2 : 1);
|
||||
PyList_SET_ITEM(ret->references, 0, (PyObject *)params.py_vertbuf);
|
||||
Py_INCREF(params.py_vertbuf);
|
||||
|
||||
if (params.py_indexbuf != NULL) {
|
||||
PyList_SET_ITEM(ret->references, 1, (PyObject *)params.py_indexbuf);
|
||||
Py_INCREF(params.py_indexbuf);
|
||||
}
|
||||
if (params.py_indexbuf != NULL) {
|
||||
PyList_SET_ITEM(ret->references, 1, (PyObject *)params.py_indexbuf);
|
||||
Py_INCREF(params.py_indexbuf);
|
||||
}
|
||||
|
||||
PyObject_GC_Track(ret);
|
||||
PyObject_GC_Track(ret);
|
||||
#endif
|
||||
|
||||
return (PyObject *)ret;
|
||||
return (PyObject *)ret;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_Batch_vertbuf_add_doc,
|
||||
@@ -140,240 +135,224 @@ PyDoc_STRVAR(bpygpu_Batch_vertbuf_add_doc,
|
||||
);
|
||||
static PyObject *bpygpu_Batch_vertbuf_add(BPyGPUBatch *self, BPyGPUVertBuf *py_buf)
|
||||
{
|
||||
if (!BPyGPUVertBuf_Check(py_buf)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Expected a GPUVertBuf, got %s",
|
||||
Py_TYPE(py_buf)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
if (!BPyGPUVertBuf_Check(py_buf)) {
|
||||
PyErr_Format(PyExc_TypeError, "Expected a GPUVertBuf, got %s", Py_TYPE(py_buf)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (self->batch->verts[0]->vertex_len != py_buf->buf->vertex_len) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Expected %d length, got %d",
|
||||
self->batch->verts[0]->vertex_len, py_buf->buf->vertex_len);
|
||||
return NULL;
|
||||
}
|
||||
if (self->batch->verts[0]->vertex_len != py_buf->buf->vertex_len) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Expected %d length, got %d",
|
||||
self->batch->verts[0]->vertex_len,
|
||||
py_buf->buf->vertex_len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (self->batch->verts[GPU_BATCH_VBO_MAX_LEN - 1] != NULL) {
|
||||
PyErr_SetString(
|
||||
PyExc_RuntimeError,
|
||||
"Maximum number of vertex buffers exceeded: " STRINGIFY(GPU_BATCH_VBO_MAX_LEN));
|
||||
return NULL;
|
||||
}
|
||||
if (self->batch->verts[GPU_BATCH_VBO_MAX_LEN - 1] != NULL) {
|
||||
PyErr_SetString(
|
||||
PyExc_RuntimeError,
|
||||
"Maximum number of vertex buffers exceeded: " STRINGIFY(GPU_BATCH_VBO_MAX_LEN));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef USE_GPU_PY_REFERENCES
|
||||
/* Hold user */
|
||||
PyList_Append(self->references, (PyObject *)py_buf);
|
||||
/* Hold user */
|
||||
PyList_Append(self->references, (PyObject *)py_buf);
|
||||
#endif
|
||||
|
||||
GPU_batch_vertbuf_add(self->batch, py_buf->buf);
|
||||
Py_RETURN_NONE;
|
||||
GPU_batch_vertbuf_add(self->batch, py_buf->buf);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_Batch_program_set_doc,
|
||||
".. method:: program_set(program)\n"
|
||||
"\n"
|
||||
" Assign a shader to this batch that will be used for drawing when not overwritten later.\n"
|
||||
" Note: This method has to be called in the draw context that the batch will be drawn in.\n"
|
||||
" This function does not need to be called when you always set the shader when calling `batch.draw`.\n"
|
||||
"\n"
|
||||
" :param program: The program/shader the batch will use in future draw calls.\n"
|
||||
" :type program: :class:`gpu.types.GPUShader`\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpygpu_Batch_program_set_doc,
|
||||
".. method:: program_set(program)\n"
|
||||
"\n"
|
||||
" Assign a shader to this batch that will be used for drawing when not overwritten later.\n"
|
||||
" Note: This method has to be called in the draw context that the batch will be drawn in.\n"
|
||||
" This function does not need to be called when you always set the shader when calling "
|
||||
"`batch.draw`.\n"
|
||||
"\n"
|
||||
" :param program: The program/shader the batch will use in future draw calls.\n"
|
||||
" :type program: :class:`gpu.types.GPUShader`\n");
|
||||
static PyObject *bpygpu_Batch_program_set(BPyGPUBatch *self, BPyGPUShader *py_shader)
|
||||
{
|
||||
if (!BPyGPUShader_Check(py_shader)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Expected a GPUShader, got %s",
|
||||
Py_TYPE(py_shader)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
if (!BPyGPUShader_Check(py_shader)) {
|
||||
PyErr_Format(PyExc_TypeError, "Expected a GPUShader, got %s", Py_TYPE(py_shader)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GPUShader *shader = py_shader->shader;
|
||||
GPU_batch_program_set(
|
||||
self->batch,
|
||||
GPU_shader_get_program(shader),
|
||||
GPU_shader_get_interface(shader));
|
||||
GPUShader *shader = py_shader->shader;
|
||||
GPU_batch_program_set(
|
||||
self->batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader));
|
||||
|
||||
#ifdef USE_GPU_PY_REFERENCES
|
||||
/* Remove existing user (if any), hold new user. */
|
||||
int i = PyList_GET_SIZE(self->references);
|
||||
while (--i != -1) {
|
||||
PyObject *py_shader_test = PyList_GET_ITEM(self->references, i);
|
||||
if (BPyGPUShader_Check(py_shader_test)) {
|
||||
PyList_SET_ITEM(self->references, i, (PyObject *)py_shader);
|
||||
Py_INCREF(py_shader);
|
||||
Py_DECREF(py_shader_test);
|
||||
/* Only ever reference one shader. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i != -1) {
|
||||
PyList_Append(self->references, (PyObject *)py_shader);
|
||||
}
|
||||
/* Remove existing user (if any), hold new user. */
|
||||
int i = PyList_GET_SIZE(self->references);
|
||||
while (--i != -1) {
|
||||
PyObject *py_shader_test = PyList_GET_ITEM(self->references, i);
|
||||
if (BPyGPUShader_Check(py_shader_test)) {
|
||||
PyList_SET_ITEM(self->references, i, (PyObject *)py_shader);
|
||||
Py_INCREF(py_shader);
|
||||
Py_DECREF(py_shader_test);
|
||||
/* Only ever reference one shader. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i != -1) {
|
||||
PyList_Append(self->references, (PyObject *)py_shader);
|
||||
}
|
||||
#endif
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_Batch_draw_doc,
|
||||
".. method:: draw(program=None)\n"
|
||||
"\n"
|
||||
" Run the drawing program with the parameters assigned to the batch.\n"
|
||||
"\n"
|
||||
" :param program: Program that performs the drawing operations.\n"
|
||||
" If ``None`` is passed, the last program setted to this batch will run.\n"
|
||||
" :type program: :class:`gpu.types.GPUShader`\n"
|
||||
);
|
||||
".. method:: draw(program=None)\n"
|
||||
"\n"
|
||||
" Run the drawing program with the parameters assigned to the batch.\n"
|
||||
"\n"
|
||||
" :param program: Program that performs the drawing operations.\n"
|
||||
" If ``None`` is passed, the last program setted to this batch will run.\n"
|
||||
" :type program: :class:`gpu.types.GPUShader`\n");
|
||||
static PyObject *bpygpu_Batch_draw(BPyGPUBatch *self, PyObject *args)
|
||||
{
|
||||
BPyGPUShader *py_program = NULL;
|
||||
BPyGPUShader *py_program = NULL;
|
||||
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "|O!:GPUBatch.draw",
|
||||
&BPyGPUShader_Type, &py_program))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else if (py_program == NULL) {
|
||||
if (!bpygpu_batch_is_program_or_error(self)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (self->batch->program != GPU_shader_get_program(py_program->shader)) {
|
||||
GPU_batch_program_set(
|
||||
self->batch,
|
||||
GPU_shader_get_program(py_program->shader),
|
||||
GPU_shader_get_interface(py_program->shader));
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "|O!:GPUBatch.draw", &BPyGPUShader_Type, &py_program)) {
|
||||
return NULL;
|
||||
}
|
||||
else if (py_program == NULL) {
|
||||
if (!bpygpu_batch_is_program_or_error(self)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (self->batch->program != GPU_shader_get_program(py_program->shader)) {
|
||||
GPU_batch_program_set(self->batch,
|
||||
GPU_shader_get_program(py_program->shader),
|
||||
GPU_shader_get_interface(py_program->shader));
|
||||
}
|
||||
|
||||
GPU_batch_draw(self->batch);
|
||||
Py_RETURN_NONE;
|
||||
GPU_batch_draw(self->batch);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *bpygpu_Batch_program_use_begin(BPyGPUBatch *self)
|
||||
{
|
||||
if (!bpygpu_batch_is_program_or_error(self)) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_batch_program_use_begin(self->batch);
|
||||
Py_RETURN_NONE;
|
||||
if (!bpygpu_batch_is_program_or_error(self)) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_batch_program_use_begin(self->batch);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *bpygpu_Batch_program_use_end(BPyGPUBatch *self)
|
||||
{
|
||||
if (!bpygpu_batch_is_program_or_error(self)) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_batch_program_use_end(self->batch);
|
||||
Py_RETURN_NONE;
|
||||
if (!bpygpu_batch_is_program_or_error(self)) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_batch_program_use_end(self->batch);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static struct PyMethodDef bpygpu_Batch_methods[] = {
|
||||
{"vertbuf_add", (PyCFunction)bpygpu_Batch_vertbuf_add,
|
||||
METH_O, bpygpu_Batch_vertbuf_add_doc},
|
||||
{"program_set", (PyCFunction)bpygpu_Batch_program_set,
|
||||
METH_O, bpygpu_Batch_program_set_doc},
|
||||
{"draw", (PyCFunction) bpygpu_Batch_draw,
|
||||
METH_VARARGS, bpygpu_Batch_draw_doc},
|
||||
{"_program_use_begin", (PyCFunction)bpygpu_Batch_program_use_begin,
|
||||
METH_NOARGS, ""},
|
||||
{"_program_use_end", (PyCFunction)bpygpu_Batch_program_use_end,
|
||||
METH_NOARGS, ""},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"vertbuf_add", (PyCFunction)bpygpu_Batch_vertbuf_add, METH_O, bpygpu_Batch_vertbuf_add_doc},
|
||||
{"program_set", (PyCFunction)bpygpu_Batch_program_set, METH_O, bpygpu_Batch_program_set_doc},
|
||||
{"draw", (PyCFunction)bpygpu_Batch_draw, METH_VARARGS, bpygpu_Batch_draw_doc},
|
||||
{"_program_use_begin", (PyCFunction)bpygpu_Batch_program_use_begin, METH_NOARGS, ""},
|
||||
{"_program_use_end", (PyCFunction)bpygpu_Batch_program_use_end, METH_NOARGS, ""},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
#ifdef USE_GPU_PY_REFERENCES
|
||||
|
||||
static int bpygpu_Batch_traverse(BPyGPUBatch *self, visitproc visit, void *arg)
|
||||
{
|
||||
Py_VISIT(self->references);
|
||||
return 0;
|
||||
Py_VISIT(self->references);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bpygpu_Batch_clear(BPyGPUBatch *self)
|
||||
{
|
||||
Py_CLEAR(self->references);
|
||||
return 0;
|
||||
Py_CLEAR(self->references);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void bpygpu_Batch_dealloc(BPyGPUBatch *self)
|
||||
{
|
||||
GPU_batch_discard(self->batch);
|
||||
GPU_batch_discard(self->batch);
|
||||
|
||||
#ifdef USE_GPU_PY_REFERENCES
|
||||
if (self->references) {
|
||||
PyObject_GC_UnTrack(self);
|
||||
bpygpu_Batch_clear(self);
|
||||
Py_XDECREF(self->references);
|
||||
}
|
||||
if (self->references) {
|
||||
PyObject_GC_UnTrack(self);
|
||||
bpygpu_Batch_clear(self);
|
||||
Py_XDECREF(self->references);
|
||||
}
|
||||
#endif
|
||||
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_gpu_batch_doc,
|
||||
".. class:: GPUBatch(type, buf, elem=None)\n"
|
||||
"\n"
|
||||
" Reusable container for drawable geometry.\n"
|
||||
"\n"
|
||||
" :arg type: One of these primitive types: {\n"
|
||||
" `POINTS`,\n"
|
||||
" `LINES`,\n"
|
||||
" `TRIS`,\n"
|
||||
" `LINE_STRIP`,\n"
|
||||
" `LINE_LOOP`,\n"
|
||||
" `TRI_STRIP`,\n"
|
||||
" `TRI_FAN`,\n"
|
||||
" `LINES_ADJ`,\n"
|
||||
" `TRIS_ADJ`,\n"
|
||||
" `LINE_STRIP_ADJ` }\n"
|
||||
" :type type: `str`\n"
|
||||
" :arg buf: Vertex buffer containing all or some of the attributes required for drawing.\n"
|
||||
" :type buf: :class:`gpu.types.GPUVertBuf`\n"
|
||||
" :arg elem: An optional index buffer.\n"
|
||||
" :type elem: :class:`gpu.types.GPUIndexBuf`\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
py_gpu_batch_doc,
|
||||
".. class:: GPUBatch(type, buf, elem=None)\n"
|
||||
"\n"
|
||||
" Reusable container for drawable geometry.\n"
|
||||
"\n"
|
||||
" :arg type: One of these primitive types: {\n"
|
||||
" `POINTS`,\n"
|
||||
" `LINES`,\n"
|
||||
" `TRIS`,\n"
|
||||
" `LINE_STRIP`,\n"
|
||||
" `LINE_LOOP`,\n"
|
||||
" `TRI_STRIP`,\n"
|
||||
" `TRI_FAN`,\n"
|
||||
" `LINES_ADJ`,\n"
|
||||
" `TRIS_ADJ`,\n"
|
||||
" `LINE_STRIP_ADJ` }\n"
|
||||
" :type type: `str`\n"
|
||||
" :arg buf: Vertex buffer containing all or some of the attributes required for drawing.\n"
|
||||
" :type buf: :class:`gpu.types.GPUVertBuf`\n"
|
||||
" :arg elem: An optional index buffer.\n"
|
||||
" :type elem: :class:`gpu.types.GPUIndexBuf`\n");
|
||||
PyTypeObject BPyGPUBatch_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "GPUBatch",
|
||||
.tp_basicsize = sizeof(BPyGPUBatch),
|
||||
.tp_dealloc = (destructor)bpygpu_Batch_dealloc,
|
||||
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "GPUBatch",
|
||||
.tp_basicsize = sizeof(BPyGPUBatch),
|
||||
.tp_dealloc = (destructor)bpygpu_Batch_dealloc,
|
||||
#ifdef USE_GPU_PY_REFERENCES
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
|
||||
.tp_doc = py_gpu_batch_doc,
|
||||
.tp_traverse = (traverseproc)bpygpu_Batch_traverse,
|
||||
.tp_clear = (inquiry)bpygpu_Batch_clear,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
|
||||
.tp_doc = py_gpu_batch_doc,
|
||||
.tp_traverse = (traverseproc)bpygpu_Batch_traverse,
|
||||
.tp_clear = (inquiry)bpygpu_Batch_clear,
|
||||
#else
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
#endif
|
||||
.tp_methods = bpygpu_Batch_methods,
|
||||
.tp_new = bpygpu_Batch_new,
|
||||
.tp_methods = bpygpu_Batch_methods,
|
||||
.tp_new = bpygpu_Batch_new,
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public API
|
||||
* \{ */
|
||||
|
||||
PyObject *BPyGPUBatch_CreatePyObject(GPUBatch *batch)
|
||||
{
|
||||
BPyGPUBatch *self;
|
||||
BPyGPUBatch *self;
|
||||
|
||||
#ifdef USE_GPU_PY_REFERENCES
|
||||
self = (BPyGPUBatch *)_PyObject_GC_New(&BPyGPUBatch_Type);
|
||||
self->references = NULL;
|
||||
self = (BPyGPUBatch *)_PyObject_GC_New(&BPyGPUBatch_Type);
|
||||
self->references = NULL;
|
||||
#else
|
||||
self = PyObject_New(BPyGPUBatch, &BPyGPUBatch_Type);
|
||||
self = PyObject_New(BPyGPUBatch, &BPyGPUBatch_Type);
|
||||
#endif
|
||||
|
||||
self->batch = batch;
|
||||
self->batch = batch;
|
||||
|
||||
return (PyObject *)self;
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -27,15 +27,15 @@
|
||||
|
||||
extern PyTypeObject BPyGPUBatch_Type;
|
||||
|
||||
#define BPyGPUBatch_Check(v) (Py_TYPE(v) == &BPyGPUBatch_Type)
|
||||
#define BPyGPUBatch_Check(v) (Py_TYPE(v) == &BPyGPUBatch_Type)
|
||||
|
||||
typedef struct BPyGPUBatch {
|
||||
PyObject_VAR_HEAD
|
||||
/* The batch is owned, we may support thin wrapped batches later. */
|
||||
struct GPUBatch *batch;
|
||||
PyObject_VAR_HEAD
|
||||
/* The batch is owned, we may support thin wrapped batches later. */
|
||||
struct GPUBatch *batch;
|
||||
#ifdef USE_GPU_PY_REFERENCES
|
||||
/* Just to keep a user to prevent freeing buf's we're using */
|
||||
PyObject *references;
|
||||
/* Just to keep a user to prevent freeing buf's we're using */
|
||||
PyObject *references;
|
||||
#endif
|
||||
} BPyGPUBatch;
|
||||
|
||||
|
||||
@@ -35,204 +35,190 @@
|
||||
#include "gpu_py_api.h"
|
||||
#include "gpu_py_element.h" /* own include */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name IndexBuf Type
|
||||
* \{ */
|
||||
|
||||
static PyObject *bpygpu_IndexBuf_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
|
||||
{
|
||||
BPYGPU_IS_INIT_OR_ERROR_OBJ;
|
||||
BPYGPU_IS_INIT_OR_ERROR_OBJ;
|
||||
|
||||
const char *error_prefix = "IndexBuf.__new__";
|
||||
bool ok = true;
|
||||
const char *error_prefix = "IndexBuf.__new__";
|
||||
bool ok = true;
|
||||
|
||||
struct {
|
||||
GPUPrimType type_id;
|
||||
PyObject *seq;
|
||||
} params;
|
||||
struct {
|
||||
GPUPrimType type_id;
|
||||
PyObject *seq;
|
||||
} params;
|
||||
|
||||
uint verts_per_prim;
|
||||
uint index_len;
|
||||
GPUIndexBufBuilder builder;
|
||||
uint verts_per_prim;
|
||||
uint index_len;
|
||||
GPUIndexBufBuilder builder;
|
||||
|
||||
static const char *_keywords[] = {"type", "seq", NULL};
|
||||
static _PyArg_Parser _parser = {"$O&O:IndexBuf.__new__", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kwds, &_parser,
|
||||
bpygpu_ParsePrimType, ¶ms.type_id,
|
||||
¶ms.seq))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"type", "seq", NULL};
|
||||
static _PyArg_Parser _parser = {"$O&O:IndexBuf.__new__", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kwds, &_parser, bpygpu_ParsePrimType, ¶ms.type_id, ¶ms.seq)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
verts_per_prim = GPU_indexbuf_primitive_len(params.type_id);
|
||||
if (verts_per_prim == -1) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"The argument 'type' must be "
|
||||
"'POINTS', 'LINES', 'TRIS' or 'LINES_ADJ'");
|
||||
return NULL;
|
||||
}
|
||||
verts_per_prim = GPU_indexbuf_primitive_len(params.type_id);
|
||||
if (verts_per_prim == -1) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"The argument 'type' must be "
|
||||
"'POINTS', 'LINES', 'TRIS' or 'LINES_ADJ'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyObject_CheckBuffer(params.seq)) {
|
||||
Py_buffer pybuffer;
|
||||
if (PyObject_CheckBuffer(params.seq)) {
|
||||
Py_buffer pybuffer;
|
||||
|
||||
if (PyObject_GetBuffer(params.seq, &pybuffer, PyBUF_FORMAT | PyBUF_ND) == -1) {
|
||||
/* PyObject_GetBuffer already handles error messages. */
|
||||
return NULL;
|
||||
}
|
||||
if (PyObject_GetBuffer(params.seq, &pybuffer, PyBUF_FORMAT | PyBUF_ND) == -1) {
|
||||
/* PyObject_GetBuffer already handles error messages. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pybuffer.ndim != 1 && pybuffer.shape[1] != verts_per_prim) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"Each primitive must exactly %d indices",
|
||||
verts_per_prim);
|
||||
return NULL;
|
||||
}
|
||||
if (pybuffer.ndim != 1 && pybuffer.shape[1] != verts_per_prim) {
|
||||
PyErr_Format(PyExc_ValueError, "Each primitive must exactly %d indices", verts_per_prim);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pybuffer.itemsize != 4 ||
|
||||
PyC_StructFmt_type_is_float_any(PyC_StructFmt_type_from_str(pybuffer.format)))
|
||||
{
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"Each index must be an 4-bytes integer value");
|
||||
return NULL;
|
||||
}
|
||||
if (pybuffer.itemsize != 4 ||
|
||||
PyC_StructFmt_type_is_float_any(PyC_StructFmt_type_from_str(pybuffer.format))) {
|
||||
PyErr_Format(PyExc_ValueError, "Each index must be an 4-bytes integer value");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
index_len = pybuffer.shape[0];
|
||||
if (pybuffer.ndim != 1) {
|
||||
index_len *= pybuffer.shape[1];
|
||||
}
|
||||
index_len = pybuffer.shape[0];
|
||||
if (pybuffer.ndim != 1) {
|
||||
index_len *= pybuffer.shape[1];
|
||||
}
|
||||
|
||||
/* The `vertex_len` parameter is only used for asserts in the Debug build. */
|
||||
/* Not very useful in python since scripts are often tested in Release build. */
|
||||
/* Use `INT_MAX` instead of the actual number of vertices. */
|
||||
GPU_indexbuf_init(
|
||||
&builder, params.type_id, index_len, INT_MAX);
|
||||
/* The `vertex_len` parameter is only used for asserts in the Debug build. */
|
||||
/* Not very useful in python since scripts are often tested in Release build. */
|
||||
/* Use `INT_MAX` instead of the actual number of vertices. */
|
||||
GPU_indexbuf_init(&builder, params.type_id, index_len, INT_MAX);
|
||||
|
||||
#if 0
|
||||
uint *buf = pybuffer.buf;
|
||||
for (uint i = index_len; i--; buf++) {
|
||||
GPU_indexbuf_add_generic_vert(&builder, *buf);
|
||||
}
|
||||
uint *buf = pybuffer.buf;
|
||||
for (uint i = index_len; i--; buf++) {
|
||||
GPU_indexbuf_add_generic_vert(&builder, *buf);
|
||||
}
|
||||
#else
|
||||
memcpy(builder.data, pybuffer.buf, index_len * sizeof(*builder.data));
|
||||
builder.index_len = index_len;
|
||||
memcpy(builder.data, pybuffer.buf, index_len * sizeof(*builder.data));
|
||||
builder.index_len = index_len;
|
||||
#endif
|
||||
PyBuffer_Release(&pybuffer);
|
||||
}
|
||||
else {
|
||||
PyObject *seq_fast = PySequence_Fast(params.seq, error_prefix);
|
||||
PyBuffer_Release(&pybuffer);
|
||||
}
|
||||
else {
|
||||
PyObject *seq_fast = PySequence_Fast(params.seq, error_prefix);
|
||||
|
||||
if (seq_fast == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (seq_fast == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast);
|
||||
const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast);
|
||||
|
||||
PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
|
||||
PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
|
||||
|
||||
index_len = seq_len * verts_per_prim;
|
||||
index_len = seq_len * verts_per_prim;
|
||||
|
||||
/* The `vertex_len` parameter is only used for asserts in the Debug build. */
|
||||
/* Not very useful in python since scripts are often tested in Release build. */
|
||||
/* Use `INT_MAX` instead of the actual number of vertices. */
|
||||
GPU_indexbuf_init(
|
||||
&builder, params.type_id, index_len, INT_MAX);
|
||||
/* The `vertex_len` parameter is only used for asserts in the Debug build. */
|
||||
/* Not very useful in python since scripts are often tested in Release build. */
|
||||
/* Use `INT_MAX` instead of the actual number of vertices. */
|
||||
GPU_indexbuf_init(&builder, params.type_id, index_len, INT_MAX);
|
||||
|
||||
if (verts_per_prim == 1) {
|
||||
for (uint i = 0; i < seq_len; i++) {
|
||||
GPU_indexbuf_add_generic_vert(
|
||||
&builder, PyC_Long_AsU32(seq_items[i]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
int values[4];
|
||||
for (uint i = 0; i < seq_len; i++) {
|
||||
PyObject *seq_fast_item = PySequence_Fast(seq_items[i], error_prefix);
|
||||
if (seq_fast_item == NULL) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%s: expected a sequence, got %s",
|
||||
error_prefix, Py_TYPE(seq_items[i])->tp_name);
|
||||
ok = false;
|
||||
goto finally;
|
||||
}
|
||||
if (verts_per_prim == 1) {
|
||||
for (uint i = 0; i < seq_len; i++) {
|
||||
GPU_indexbuf_add_generic_vert(&builder, PyC_Long_AsU32(seq_items[i]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
int values[4];
|
||||
for (uint i = 0; i < seq_len; i++) {
|
||||
PyObject *seq_fast_item = PySequence_Fast(seq_items[i], error_prefix);
|
||||
if (seq_fast_item == NULL) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%s: expected a sequence, got %s",
|
||||
error_prefix,
|
||||
Py_TYPE(seq_items[i])->tp_name);
|
||||
ok = false;
|
||||
goto finally;
|
||||
}
|
||||
|
||||
ok = PyC_AsArray_FAST(
|
||||
values, seq_fast_item, verts_per_prim,
|
||||
&PyLong_Type, false, error_prefix) == 0;
|
||||
ok = PyC_AsArray_FAST(
|
||||
values, seq_fast_item, verts_per_prim, &PyLong_Type, false, error_prefix) == 0;
|
||||
|
||||
if (ok) {
|
||||
for (uint j = 0; j < verts_per_prim; j++) {
|
||||
GPU_indexbuf_add_generic_vert(&builder, values[j]);
|
||||
}
|
||||
}
|
||||
Py_DECREF(seq_fast_item);
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
for (uint j = 0; j < verts_per_prim; j++) {
|
||||
GPU_indexbuf_add_generic_vert(&builder, values[j]);
|
||||
}
|
||||
}
|
||||
Py_DECREF(seq_fast_item);
|
||||
}
|
||||
}
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
ok = false;
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
ok = false;
|
||||
}
|
||||
|
||||
finally:
|
||||
finally:
|
||||
|
||||
Py_DECREF(seq_fast);
|
||||
}
|
||||
Py_DECREF(seq_fast);
|
||||
}
|
||||
|
||||
if (ok == false) {
|
||||
MEM_freeN(builder.data);
|
||||
return NULL;
|
||||
}
|
||||
if (ok == false) {
|
||||
MEM_freeN(builder.data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return BPyGPUIndexBuf_CreatePyObject(GPU_indexbuf_build(&builder));
|
||||
return BPyGPUIndexBuf_CreatePyObject(GPU_indexbuf_build(&builder));
|
||||
}
|
||||
|
||||
static void bpygpu_IndexBuf_dealloc(BPyGPUIndexBuf *self)
|
||||
{
|
||||
GPU_indexbuf_discard(self->elem);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
GPU_indexbuf_discard(self->elem);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_gpu_element_doc,
|
||||
".. class:: GPUIndexBuf(type, seq)\n"
|
||||
"\n"
|
||||
" Contains an index buffer.\n"
|
||||
"\n"
|
||||
" :param type: One of these primitive types: {\n"
|
||||
" `POINTS`,\n"
|
||||
" `LINES`,\n"
|
||||
" `TRIS`,\n"
|
||||
" `LINE_STRIP_ADJ` }\n"
|
||||
" :type type: `str`\n"
|
||||
" :param seq: Indices this index buffer will contain.\n"
|
||||
" Whether a 1D or 2D sequence is required depends on the type.\n"
|
||||
" Optionally the sequence can support the buffer protocol.\n"
|
||||
" :type seq: 1D or 2D sequence\n"
|
||||
);
|
||||
".. class:: GPUIndexBuf(type, seq)\n"
|
||||
"\n"
|
||||
" Contains an index buffer.\n"
|
||||
"\n"
|
||||
" :param type: One of these primitive types: {\n"
|
||||
" `POINTS`,\n"
|
||||
" `LINES`,\n"
|
||||
" `TRIS`,\n"
|
||||
" `LINE_STRIP_ADJ` }\n"
|
||||
" :type type: `str`\n"
|
||||
" :param seq: Indices this index buffer will contain.\n"
|
||||
" Whether a 1D or 2D sequence is required depends on the type.\n"
|
||||
" Optionally the sequence can support the buffer protocol.\n"
|
||||
" :type seq: 1D or 2D sequence\n");
|
||||
PyTypeObject BPyGPUIndexBuf_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "GPUIndexBuf",
|
||||
.tp_basicsize = sizeof(BPyGPUIndexBuf),
|
||||
.tp_dealloc = (destructor)bpygpu_IndexBuf_dealloc,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_doc = py_gpu_element_doc,
|
||||
.tp_new = bpygpu_IndexBuf_new,
|
||||
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "GPUIndexBuf",
|
||||
.tp_basicsize = sizeof(BPyGPUIndexBuf),
|
||||
.tp_dealloc = (destructor)bpygpu_IndexBuf_dealloc,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_doc = py_gpu_element_doc,
|
||||
.tp_new = bpygpu_IndexBuf_new,
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public API
|
||||
* \{ */
|
||||
|
||||
PyObject *BPyGPUIndexBuf_CreatePyObject(GPUIndexBuf *elem)
|
||||
{
|
||||
BPyGPUIndexBuf *self;
|
||||
BPyGPUIndexBuf *self;
|
||||
|
||||
self = PyObject_New(BPyGPUIndexBuf, &BPyGPUIndexBuf_Type);
|
||||
self->elem = elem;
|
||||
self = PyObject_New(BPyGPUIndexBuf, &BPyGPUIndexBuf_Type);
|
||||
self->elem = elem;
|
||||
|
||||
return (PyObject *)self;
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -23,11 +23,10 @@
|
||||
|
||||
extern PyTypeObject BPyGPUIndexBuf_Type;
|
||||
|
||||
#define BPyGPUIndexBuf_Check(v) (Py_TYPE(v) == &BPyGPUIndexBuf_Type)
|
||||
#define BPyGPUIndexBuf_Check(v) (Py_TYPE(v) == &BPyGPUIndexBuf_Type)
|
||||
|
||||
typedef struct BPyGPUIndexBuf {
|
||||
PyObject_VAR_HEAD
|
||||
struct GPUIndexBuf *elem;
|
||||
PyObject_VAR_HEAD struct GPUIndexBuf *elem;
|
||||
} BPyGPUIndexBuf;
|
||||
|
||||
PyObject *BPyGPUIndexBuf_CreatePyObject(struct GPUIndexBuf *elem);
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "../mathutils/mathutils.h"
|
||||
@@ -47,42 +46,42 @@
|
||||
|
||||
static bool bpygpu_stack_is_push_model_view_ok_or_error(void)
|
||||
{
|
||||
if (GPU_matrix_stack_level_get_model_view() >= GPU_PY_MATRIX_STACK_LEN) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Maximum model-view stack depth " STRINGIFY(GPU_PY_MATRIX_STACK_DEPTH) " reached");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (GPU_matrix_stack_level_get_model_view() >= GPU_PY_MATRIX_STACK_LEN) {
|
||||
PyErr_SetString(
|
||||
PyExc_RuntimeError,
|
||||
"Maximum model-view stack depth " STRINGIFY(GPU_PY_MATRIX_STACK_DEPTH) " reached");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool bpygpu_stack_is_push_projection_ok_or_error(void)
|
||||
{
|
||||
if (GPU_matrix_stack_level_get_projection() >= GPU_PY_MATRIX_STACK_LEN) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Maximum projection stack depth " STRINGIFY(GPU_PY_MATRIX_STACK_DEPTH) " reached");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (GPU_matrix_stack_level_get_projection() >= GPU_PY_MATRIX_STACK_LEN) {
|
||||
PyErr_SetString(
|
||||
PyExc_RuntimeError,
|
||||
"Maximum projection stack depth " STRINGIFY(GPU_PY_MATRIX_STACK_DEPTH) " reached");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool bpygpu_stack_is_pop_model_view_ok_or_error(void)
|
||||
{
|
||||
if (GPU_matrix_stack_level_get_model_view() == 0) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Minimum model-view stack depth reached");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (GPU_matrix_stack_level_get_model_view() == 0) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Minimum model-view stack depth reached");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool bpygpu_stack_is_pop_projection_ok_or_error(void)
|
||||
{
|
||||
if (GPU_matrix_stack_level_get_projection() == 0) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Minimum projection stack depth reached");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (GPU_matrix_stack_level_get_projection() == 0) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Minimum projection stack depth reached");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -92,59 +91,55 @@ static bool bpygpu_stack_is_pop_projection_ok_or_error(void)
|
||||
* \{ */
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_push_doc,
|
||||
".. function:: push()\n"
|
||||
"\n"
|
||||
" Add to the model-view matrix stack.\n"
|
||||
);
|
||||
".. function:: push()\n"
|
||||
"\n"
|
||||
" Add to the model-view matrix stack.\n");
|
||||
static PyObject *bpygpu_matrix_push(PyObject *UNUSED(self))
|
||||
{
|
||||
if (!bpygpu_stack_is_push_model_view_ok_or_error()) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_push();
|
||||
Py_RETURN_NONE;
|
||||
if (!bpygpu_stack_is_push_model_view_ok_or_error()) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_push();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_pop_doc,
|
||||
".. function:: pop()\n"
|
||||
"\n"
|
||||
" Remove the last model-view matrix from the stack.\n"
|
||||
);
|
||||
".. function:: pop()\n"
|
||||
"\n"
|
||||
" Remove the last model-view matrix from the stack.\n");
|
||||
static PyObject *bpygpu_matrix_pop(PyObject *UNUSED(self))
|
||||
{
|
||||
if (!bpygpu_stack_is_pop_model_view_ok_or_error()) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_pop();
|
||||
Py_RETURN_NONE;
|
||||
if (!bpygpu_stack_is_pop_model_view_ok_or_error()) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_pop();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_push_projection_doc,
|
||||
".. function:: push_projection()\n"
|
||||
"\n"
|
||||
" Add to the projection matrix stack.\n"
|
||||
);
|
||||
".. function:: push_projection()\n"
|
||||
"\n"
|
||||
" Add to the projection matrix stack.\n");
|
||||
static PyObject *bpygpu_matrix_push_projection(PyObject *UNUSED(self))
|
||||
{
|
||||
if (!bpygpu_stack_is_push_projection_ok_or_error()) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_push_projection();
|
||||
Py_RETURN_NONE;
|
||||
if (!bpygpu_stack_is_push_projection_ok_or_error()) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_push_projection();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_pop_projection_doc,
|
||||
".. function:: pop_projection()\n"
|
||||
"\n"
|
||||
" Remove the last projection matrix from the stack.\n"
|
||||
);
|
||||
".. function:: pop_projection()\n"
|
||||
"\n"
|
||||
" Remove the last projection matrix from the stack.\n");
|
||||
static PyObject *bpygpu_matrix_pop_projection(PyObject *UNUSED(self))
|
||||
{
|
||||
if (!bpygpu_stack_is_pop_projection_ok_or_error()) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_pop_projection();
|
||||
Py_RETURN_NONE;
|
||||
if (!bpygpu_stack_is_pop_projection_ok_or_error()) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_pop_projection();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -157,120 +152,121 @@ static PyObject *bpygpu_matrix_pop_projection(PyObject *UNUSED(self))
|
||||
* \{ */
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD /* required python macro */
|
||||
int type;
|
||||
int level;
|
||||
PyObject_HEAD /* required python macro */
|
||||
int type;
|
||||
int level;
|
||||
} BPyGPU_MatrixStackContext;
|
||||
|
||||
enum {
|
||||
PYGPU_MATRIX_TYPE_MODEL_VIEW = 1,
|
||||
PYGPU_MATRIX_TYPE_PROJECTION = 2,
|
||||
PYGPU_MATRIX_TYPE_MODEL_VIEW = 1,
|
||||
PYGPU_MATRIX_TYPE_PROJECTION = 2,
|
||||
};
|
||||
|
||||
static PyObject *bpygpu_matrix_stack_context_enter(BPyGPU_MatrixStackContext *self);
|
||||
static PyObject *bpygpu_matrix_stack_context_exit(BPyGPU_MatrixStackContext *self, PyObject *args);
|
||||
|
||||
static PyMethodDef bpygpu_matrix_stack_context_methods[] = {
|
||||
{"__enter__", (PyCFunction)bpygpu_matrix_stack_context_enter, METH_NOARGS},
|
||||
{"__exit__", (PyCFunction)bpygpu_matrix_stack_context_exit, METH_VARARGS},
|
||||
{NULL},
|
||||
{"__enter__", (PyCFunction)bpygpu_matrix_stack_context_enter, METH_NOARGS},
|
||||
{"__exit__", (PyCFunction)bpygpu_matrix_stack_context_exit, METH_VARARGS},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static PyTypeObject BPyGPU_matrix_stack_context_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "GPUMatrixStackContext",
|
||||
.tp_basicsize = sizeof(BPyGPU_MatrixStackContext),
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_methods = bpygpu_matrix_stack_context_methods,
|
||||
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "GPUMatrixStackContext",
|
||||
.tp_basicsize = sizeof(BPyGPU_MatrixStackContext),
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_methods = bpygpu_matrix_stack_context_methods,
|
||||
};
|
||||
|
||||
static PyObject *bpygpu_matrix_stack_context_enter(BPyGPU_MatrixStackContext *self)
|
||||
{
|
||||
/* sanity - should never happen */
|
||||
if (self->level != -1) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Already in use");
|
||||
return NULL;
|
||||
}
|
||||
/* sanity - should never happen */
|
||||
if (self->level != -1) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Already in use");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (self->type == PYGPU_MATRIX_TYPE_MODEL_VIEW) {
|
||||
if (!bpygpu_stack_is_push_model_view_ok_or_error()) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_push();
|
||||
self->level = GPU_matrix_stack_level_get_model_view();
|
||||
}
|
||||
else if (self->type == PYGPU_MATRIX_TYPE_PROJECTION) {
|
||||
if (!bpygpu_stack_is_push_projection_ok_or_error()) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_push_projection();
|
||||
self->level = GPU_matrix_stack_level_get_projection();
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
if (self->type == PYGPU_MATRIX_TYPE_MODEL_VIEW) {
|
||||
if (!bpygpu_stack_is_push_model_view_ok_or_error()) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_push();
|
||||
self->level = GPU_matrix_stack_level_get_model_view();
|
||||
}
|
||||
else if (self->type == PYGPU_MATRIX_TYPE_PROJECTION) {
|
||||
if (!bpygpu_stack_is_push_projection_ok_or_error()) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_push_projection();
|
||||
self->level = GPU_matrix_stack_level_get_projection();
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *bpygpu_matrix_stack_context_exit(BPyGPU_MatrixStackContext *self, PyObject *UNUSED(args))
|
||||
static PyObject *bpygpu_matrix_stack_context_exit(BPyGPU_MatrixStackContext *self,
|
||||
PyObject *UNUSED(args))
|
||||
{
|
||||
/* sanity - should never happen */
|
||||
if (self->level == -1) {
|
||||
fprintf(stderr, "Not yet in use\n");
|
||||
goto finally;
|
||||
}
|
||||
/* sanity - should never happen */
|
||||
if (self->level == -1) {
|
||||
fprintf(stderr, "Not yet in use\n");
|
||||
goto finally;
|
||||
}
|
||||
|
||||
if (self->type == PYGPU_MATRIX_TYPE_MODEL_VIEW) {
|
||||
const int level = GPU_matrix_stack_level_get_model_view();
|
||||
if (level != self->level) {
|
||||
fprintf(stderr, "Level push/pop mismatch, expected %d, got %d\n", self->level, level);
|
||||
}
|
||||
if (level != 0) {
|
||||
GPU_matrix_pop();
|
||||
}
|
||||
}
|
||||
else if (self->type == PYGPU_MATRIX_TYPE_PROJECTION) {
|
||||
const int level = GPU_matrix_stack_level_get_projection();
|
||||
if (level != self->level) {
|
||||
fprintf(stderr, "Level push/pop mismatch, expected %d, got %d", self->level, level);
|
||||
}
|
||||
if (level != 0) {
|
||||
GPU_matrix_pop_projection();
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
}
|
||||
if (self->type == PYGPU_MATRIX_TYPE_MODEL_VIEW) {
|
||||
const int level = GPU_matrix_stack_level_get_model_view();
|
||||
if (level != self->level) {
|
||||
fprintf(stderr, "Level push/pop mismatch, expected %d, got %d\n", self->level, level);
|
||||
}
|
||||
if (level != 0) {
|
||||
GPU_matrix_pop();
|
||||
}
|
||||
}
|
||||
else if (self->type == PYGPU_MATRIX_TYPE_PROJECTION) {
|
||||
const int level = GPU_matrix_stack_level_get_projection();
|
||||
if (level != self->level) {
|
||||
fprintf(stderr, "Level push/pop mismatch, expected %d, got %d", self->level, level);
|
||||
}
|
||||
if (level != 0) {
|
||||
GPU_matrix_pop_projection();
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
}
|
||||
finally:
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *bpygpu_matrix_push_pop_impl(int type)
|
||||
{
|
||||
BPyGPU_MatrixStackContext *ret = PyObject_New(BPyGPU_MatrixStackContext, &BPyGPU_matrix_stack_context_Type);
|
||||
ret->type = type;
|
||||
ret->level = -1;
|
||||
return (PyObject *)ret;
|
||||
BPyGPU_MatrixStackContext *ret = PyObject_New(BPyGPU_MatrixStackContext,
|
||||
&BPyGPU_matrix_stack_context_Type);
|
||||
ret->type = type;
|
||||
ret->level = -1;
|
||||
return (PyObject *)ret;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_push_pop_doc,
|
||||
".. function:: push_pop()\n"
|
||||
"\n"
|
||||
" Context manager to ensure balanced push/pop calls, even in the case of an error.\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpygpu_matrix_push_pop_doc,
|
||||
".. function:: push_pop()\n"
|
||||
"\n"
|
||||
" Context manager to ensure balanced push/pop calls, even in the case of an error.\n");
|
||||
static PyObject *bpygpu_matrix_push_pop(PyObject *UNUSED(self))
|
||||
{
|
||||
return bpygpu_matrix_push_pop_impl(PYGPU_MATRIX_TYPE_MODEL_VIEW);
|
||||
return bpygpu_matrix_push_pop_impl(PYGPU_MATRIX_TYPE_MODEL_VIEW);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_push_pop_projection_doc,
|
||||
".. function:: push_pop_projection()\n"
|
||||
"\n"
|
||||
" Context manager to ensure balanced push/pop calls, even in the case of an error.\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpygpu_matrix_push_pop_projection_doc,
|
||||
".. function:: push_pop_projection()\n"
|
||||
"\n"
|
||||
" Context manager to ensure balanced push/pop calls, even in the case of an error.\n");
|
||||
static PyObject *bpygpu_matrix_push_pop_projection(PyObject *UNUSED(self))
|
||||
{
|
||||
return bpygpu_matrix_push_pop_impl(PYGPU_MATRIX_TYPE_PROJECTION);
|
||||
return bpygpu_matrix_push_pop_impl(PYGPU_MATRIX_TYPE_PROJECTION);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -280,88 +276,84 @@ static PyObject *bpygpu_matrix_push_pop_projection(PyObject *UNUSED(self))
|
||||
* \{ */
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_multiply_matrix_doc,
|
||||
".. function:: multiply_matrix(matrix)\n"
|
||||
"\n"
|
||||
" Multiply the current stack matrix.\n"
|
||||
"\n"
|
||||
" :param matrix: A 4x4 matrix.\n"
|
||||
" :type matrix: :class:`mathutils.Matrix`\n"
|
||||
);
|
||||
".. function:: multiply_matrix(matrix)\n"
|
||||
"\n"
|
||||
" Multiply the current stack matrix.\n"
|
||||
"\n"
|
||||
" :param matrix: A 4x4 matrix.\n"
|
||||
" :type matrix: :class:`mathutils.Matrix`\n");
|
||||
static PyObject *bpygpu_matrix_multiply_matrix(PyObject *UNUSED(self), PyObject *value)
|
||||
{
|
||||
MatrixObject *pymat;
|
||||
if (!Matrix_Parse4x4(value, &pymat)) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_mul(pymat->matrix);
|
||||
Py_RETURN_NONE;
|
||||
MatrixObject *pymat;
|
||||
if (!Matrix_Parse4x4(value, &pymat)) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_mul(pymat->matrix);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_scale_doc,
|
||||
".. function:: scale(scale)\n"
|
||||
"\n"
|
||||
" Scale the current stack matrix.\n"
|
||||
"\n"
|
||||
" :param scale: Scale the current stack matrix.\n"
|
||||
" :type scale: sequence of 2 or 3 floats\n"
|
||||
);
|
||||
".. function:: scale(scale)\n"
|
||||
"\n"
|
||||
" Scale the current stack matrix.\n"
|
||||
"\n"
|
||||
" :param scale: Scale the current stack matrix.\n"
|
||||
" :type scale: sequence of 2 or 3 floats\n");
|
||||
static PyObject *bpygpu_matrix_scale(PyObject *UNUSED(self), PyObject *value)
|
||||
{
|
||||
float scale[3];
|
||||
int len;
|
||||
if ((len = mathutils_array_parse(scale, 2, 3, value, "gpu.matrix.scale(): invalid vector arg")) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (len == 2) {
|
||||
GPU_matrix_scale_2fv(scale);
|
||||
}
|
||||
else {
|
||||
GPU_matrix_scale_3fv(scale);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
float scale[3];
|
||||
int len;
|
||||
if ((len = mathutils_array_parse(
|
||||
scale, 2, 3, value, "gpu.matrix.scale(): invalid vector arg")) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (len == 2) {
|
||||
GPU_matrix_scale_2fv(scale);
|
||||
}
|
||||
else {
|
||||
GPU_matrix_scale_3fv(scale);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_scale_uniform_doc,
|
||||
".. function:: scale_uniform(scale)\n"
|
||||
"\n"
|
||||
" :param scale: Scale the current stack matrix.\n"
|
||||
" :type scale: float\n"
|
||||
);
|
||||
".. function:: scale_uniform(scale)\n"
|
||||
"\n"
|
||||
" :param scale: Scale the current stack matrix.\n"
|
||||
" :type scale: float\n");
|
||||
static PyObject *bpygpu_matrix_scale_uniform(PyObject *UNUSED(self), PyObject *value)
|
||||
{
|
||||
float scalar;
|
||||
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"expected a number, not %.200s",
|
||||
Py_TYPE(value)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_scale_1f(scalar);
|
||||
Py_RETURN_NONE;
|
||||
float scalar;
|
||||
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
|
||||
PyErr_Format(PyExc_TypeError, "expected a number, not %.200s", Py_TYPE(value)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_scale_1f(scalar);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_translate_doc,
|
||||
".. function:: translate(offset)\n"
|
||||
"\n"
|
||||
" Scale the current stack matrix.\n"
|
||||
"\n"
|
||||
" :param offset: Translate the current stack matrix.\n"
|
||||
" :type offset: sequence of 2 or 3 floats\n"
|
||||
);
|
||||
".. function:: translate(offset)\n"
|
||||
"\n"
|
||||
" Scale the current stack matrix.\n"
|
||||
"\n"
|
||||
" :param offset: Translate the current stack matrix.\n"
|
||||
" :type offset: sequence of 2 or 3 floats\n");
|
||||
static PyObject *bpygpu_matrix_translate(PyObject *UNUSED(self), PyObject *value)
|
||||
{
|
||||
float offset[3];
|
||||
int len;
|
||||
if ((len = mathutils_array_parse(offset, 2, 3, value, "gpu.matrix.translate(): invalid vector arg")) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (len == 2) {
|
||||
GPU_matrix_translate_2fv(offset);
|
||||
}
|
||||
else {
|
||||
GPU_matrix_translate_3fv(offset);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
float offset[3];
|
||||
int len;
|
||||
if ((len = mathutils_array_parse(
|
||||
offset, 2, 3, value, "gpu.matrix.translate(): invalid vector arg")) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (len == 2) {
|
||||
GPU_matrix_translate_2fv(offset);
|
||||
}
|
||||
else {
|
||||
GPU_matrix_translate_3fv(offset);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -371,61 +363,57 @@ static PyObject *bpygpu_matrix_translate(PyObject *UNUSED(self), PyObject *value
|
||||
* \{ */
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_reset_doc,
|
||||
".. function:: reset()\n"
|
||||
"\n"
|
||||
" Empty stack and set to identity.\n"
|
||||
);
|
||||
".. function:: reset()\n"
|
||||
"\n"
|
||||
" Empty stack and set to identity.\n");
|
||||
static PyObject *bpygpu_matrix_reset(PyObject *UNUSED(self))
|
||||
{
|
||||
GPU_matrix_reset();
|
||||
Py_RETURN_NONE;
|
||||
GPU_matrix_reset();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_load_identity_doc,
|
||||
".. function:: load_identity()\n"
|
||||
"\n"
|
||||
" Empty stack and set to identity.\n"
|
||||
);
|
||||
".. function:: load_identity()\n"
|
||||
"\n"
|
||||
" Empty stack and set to identity.\n");
|
||||
static PyObject *bpygpu_matrix_load_identity(PyObject *UNUSED(self))
|
||||
{
|
||||
GPU_matrix_identity_set();
|
||||
Py_RETURN_NONE;
|
||||
GPU_matrix_identity_set();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_load_matrix_doc,
|
||||
".. function:: load_matrix(matrix)\n"
|
||||
"\n"
|
||||
" Load a matrix into the stack.\n"
|
||||
"\n"
|
||||
" :param matrix: A 4x4 matrix.\n"
|
||||
" :type matrix: :class:`mathutils.Matrix`\n"
|
||||
);
|
||||
".. function:: load_matrix(matrix)\n"
|
||||
"\n"
|
||||
" Load a matrix into the stack.\n"
|
||||
"\n"
|
||||
" :param matrix: A 4x4 matrix.\n"
|
||||
" :type matrix: :class:`mathutils.Matrix`\n");
|
||||
static PyObject *bpygpu_matrix_load_matrix(PyObject *UNUSED(self), PyObject *value)
|
||||
{
|
||||
MatrixObject *pymat;
|
||||
if (!Matrix_Parse4x4(value, &pymat)) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_set(pymat->matrix);
|
||||
Py_RETURN_NONE;
|
||||
MatrixObject *pymat;
|
||||
if (!Matrix_Parse4x4(value, &pymat)) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_set(pymat->matrix);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_load_projection_matrix_doc,
|
||||
".. function:: load_projection_matrix(matrix)\n"
|
||||
"\n"
|
||||
" Load a projection matrix into the stack.\n"
|
||||
"\n"
|
||||
" :param matrix: A 4x4 matrix.\n"
|
||||
" :type matrix: :class:`mathutils.Matrix`\n"
|
||||
);
|
||||
".. function:: load_projection_matrix(matrix)\n"
|
||||
"\n"
|
||||
" Load a projection matrix into the stack.\n"
|
||||
"\n"
|
||||
" :param matrix: A 4x4 matrix.\n"
|
||||
" :type matrix: :class:`mathutils.Matrix`\n");
|
||||
static PyObject *bpygpu_matrix_load_projection_matrix(PyObject *UNUSED(self), PyObject *value)
|
||||
{
|
||||
MatrixObject *pymat;
|
||||
if (!Matrix_Parse4x4(value, &pymat)) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_projection_set(pymat->matrix);
|
||||
Py_RETURN_NONE;
|
||||
MatrixObject *pymat;
|
||||
if (!Matrix_Parse4x4(value, &pymat)) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_matrix_projection_set(pymat->matrix);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -435,49 +423,45 @@ static PyObject *bpygpu_matrix_load_projection_matrix(PyObject *UNUSED(self), Py
|
||||
* \{ */
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_get_projection_matrix_doc,
|
||||
".. function:: get_projection_matrix()\n"
|
||||
"\n"
|
||||
" Return a copy of the projection matrix.\n"
|
||||
"\n"
|
||||
" :return: A 4x4 projection matrix.\n"
|
||||
" :rtype: :class:`mathutils.Matrix`\n"
|
||||
);
|
||||
".. function:: get_projection_matrix()\n"
|
||||
"\n"
|
||||
" Return a copy of the projection matrix.\n"
|
||||
"\n"
|
||||
" :return: A 4x4 projection matrix.\n"
|
||||
" :rtype: :class:`mathutils.Matrix`\n");
|
||||
static PyObject *bpygpu_matrix_get_projection_matrix(PyObject *UNUSED(self))
|
||||
{
|
||||
float matrix[4][4];
|
||||
GPU_matrix_projection_get(matrix);
|
||||
return Matrix_CreatePyObject(&matrix[0][0], 4, 4, NULL);
|
||||
float matrix[4][4];
|
||||
GPU_matrix_projection_get(matrix);
|
||||
return Matrix_CreatePyObject(&matrix[0][0], 4, 4, NULL);
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_get_model_view_matrix_doc,
|
||||
".. function:: get_model_view_matrix()\n"
|
||||
"\n"
|
||||
" Return a copy of the model-view matrix.\n"
|
||||
"\n"
|
||||
" :return: A 4x4 view matrix.\n"
|
||||
" :rtype: :class:`mathutils.Matrix`\n"
|
||||
);
|
||||
".. function:: get_model_view_matrix()\n"
|
||||
"\n"
|
||||
" Return a copy of the model-view matrix.\n"
|
||||
"\n"
|
||||
" :return: A 4x4 view matrix.\n"
|
||||
" :rtype: :class:`mathutils.Matrix`\n");
|
||||
static PyObject *bpygpu_matrix_get_model_view_matrix(PyObject *UNUSED(self))
|
||||
{
|
||||
float matrix[4][4];
|
||||
GPU_matrix_model_view_get(matrix);
|
||||
return Matrix_CreatePyObject(&matrix[0][0], 4, 4, NULL);
|
||||
float matrix[4][4];
|
||||
GPU_matrix_model_view_get(matrix);
|
||||
return Matrix_CreatePyObject(&matrix[0][0], 4, 4, NULL);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_get_normal_matrix_doc,
|
||||
".. function:: get_normal_matrix()\n"
|
||||
"\n"
|
||||
" Return a copy of the normal matrix.\n"
|
||||
"\n"
|
||||
" :return: A 3x3 normal matrix.\n"
|
||||
" :rtype: :class:`mathutils.Matrix`\n"
|
||||
);
|
||||
".. function:: get_normal_matrix()\n"
|
||||
"\n"
|
||||
" Return a copy of the normal matrix.\n"
|
||||
"\n"
|
||||
" :return: A 3x3 normal matrix.\n"
|
||||
" :rtype: :class:`mathutils.Matrix`\n");
|
||||
static PyObject *bpygpu_matrix_get_normal_matrix(PyObject *UNUSED(self))
|
||||
{
|
||||
float matrix[3][3];
|
||||
GPU_matrix_normal_get(matrix);
|
||||
return Matrix_CreatePyObject(&matrix[0][0], 3, 3, NULL);
|
||||
float matrix[3][3];
|
||||
GPU_matrix_normal_get(matrix);
|
||||
return Matrix_CreatePyObject(&matrix[0][0], 3, 3, NULL);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -487,85 +471,96 @@ static PyObject *bpygpu_matrix_get_normal_matrix(PyObject *UNUSED(self))
|
||||
* \{ */
|
||||
|
||||
static struct PyMethodDef bpygpu_matrix_methods[] = {
|
||||
/* Manage Stack */
|
||||
{"push", (PyCFunction)bpygpu_matrix_push,
|
||||
METH_NOARGS, bpygpu_matrix_push_doc},
|
||||
{"pop", (PyCFunction)bpygpu_matrix_pop,
|
||||
METH_NOARGS, bpygpu_matrix_pop_doc},
|
||||
/* Manage Stack */
|
||||
{"push", (PyCFunction)bpygpu_matrix_push, METH_NOARGS, bpygpu_matrix_push_doc},
|
||||
{"pop", (PyCFunction)bpygpu_matrix_pop, METH_NOARGS, bpygpu_matrix_pop_doc},
|
||||
|
||||
{"push_projection", (PyCFunction)bpygpu_matrix_push_projection,
|
||||
METH_NOARGS, bpygpu_matrix_push_projection_doc},
|
||||
{"pop_projection", (PyCFunction)bpygpu_matrix_pop_projection,
|
||||
METH_NOARGS, bpygpu_matrix_pop_projection_doc},
|
||||
{"push_projection",
|
||||
(PyCFunction)bpygpu_matrix_push_projection,
|
||||
METH_NOARGS,
|
||||
bpygpu_matrix_push_projection_doc},
|
||||
{"pop_projection",
|
||||
(PyCFunction)bpygpu_matrix_pop_projection,
|
||||
METH_NOARGS,
|
||||
bpygpu_matrix_pop_projection_doc},
|
||||
|
||||
/* Stack (Context Manager) */
|
||||
{"push_pop", (PyCFunction)bpygpu_matrix_push_pop,
|
||||
METH_NOARGS, bpygpu_matrix_push_pop_doc},
|
||||
{"push_pop_projection", (PyCFunction)bpygpu_matrix_push_pop_projection,
|
||||
METH_NOARGS, bpygpu_matrix_push_pop_projection_doc},
|
||||
/* Stack (Context Manager) */
|
||||
{"push_pop", (PyCFunction)bpygpu_matrix_push_pop, METH_NOARGS, bpygpu_matrix_push_pop_doc},
|
||||
{"push_pop_projection",
|
||||
(PyCFunction)bpygpu_matrix_push_pop_projection,
|
||||
METH_NOARGS,
|
||||
bpygpu_matrix_push_pop_projection_doc},
|
||||
|
||||
/* Manipulate State */
|
||||
{"multiply_matrix", (PyCFunction)bpygpu_matrix_multiply_matrix,
|
||||
METH_O, bpygpu_matrix_multiply_matrix_doc},
|
||||
{"scale", (PyCFunction)bpygpu_matrix_scale,
|
||||
METH_O, bpygpu_matrix_scale_doc},
|
||||
{"scale_uniform", (PyCFunction)bpygpu_matrix_scale_uniform,
|
||||
METH_O, bpygpu_matrix_scale_uniform_doc},
|
||||
{"translate", (PyCFunction)bpygpu_matrix_translate,
|
||||
METH_O, bpygpu_matrix_translate_doc},
|
||||
/* Manipulate State */
|
||||
{"multiply_matrix",
|
||||
(PyCFunction)bpygpu_matrix_multiply_matrix,
|
||||
METH_O,
|
||||
bpygpu_matrix_multiply_matrix_doc},
|
||||
{"scale", (PyCFunction)bpygpu_matrix_scale, METH_O, bpygpu_matrix_scale_doc},
|
||||
{"scale_uniform",
|
||||
(PyCFunction)bpygpu_matrix_scale_uniform,
|
||||
METH_O,
|
||||
bpygpu_matrix_scale_uniform_doc},
|
||||
{"translate", (PyCFunction)bpygpu_matrix_translate, METH_O, bpygpu_matrix_translate_doc},
|
||||
|
||||
/* TODO */
|
||||
/* TODO */
|
||||
#if 0
|
||||
{"rotate", (PyCFunction)bpygpu_matrix_rotate,
|
||||
METH_O, bpygpu_matrix_rotate_doc},
|
||||
{"rotate_axis", (PyCFunction)bpygpu_matrix_rotate_axis,
|
||||
METH_O, bpygpu_matrix_rotate_axis_doc},
|
||||
{"look_at", (PyCFunction)bpygpu_matrix_look_at,
|
||||
METH_O, bpygpu_matrix_look_at_doc},
|
||||
{"rotate", (PyCFunction)bpygpu_matrix_rotate,
|
||||
METH_O, bpygpu_matrix_rotate_doc},
|
||||
{"rotate_axis", (PyCFunction)bpygpu_matrix_rotate_axis,
|
||||
METH_O, bpygpu_matrix_rotate_axis_doc},
|
||||
{"look_at", (PyCFunction)bpygpu_matrix_look_at,
|
||||
METH_O, bpygpu_matrix_look_at_doc},
|
||||
#endif
|
||||
|
||||
/* Write State */
|
||||
{"reset", (PyCFunction)bpygpu_matrix_reset,
|
||||
METH_NOARGS, bpygpu_matrix_reset_doc},
|
||||
{"load_identity", (PyCFunction)bpygpu_matrix_load_identity,
|
||||
METH_NOARGS, bpygpu_matrix_load_identity_doc},
|
||||
{"load_matrix", (PyCFunction)bpygpu_matrix_load_matrix,
|
||||
METH_O, bpygpu_matrix_load_matrix_doc},
|
||||
{"load_projection_matrix", (PyCFunction)bpygpu_matrix_load_projection_matrix,
|
||||
METH_O, bpygpu_matrix_load_projection_matrix_doc},
|
||||
/* Write State */
|
||||
{"reset", (PyCFunction)bpygpu_matrix_reset, METH_NOARGS, bpygpu_matrix_reset_doc},
|
||||
{"load_identity",
|
||||
(PyCFunction)bpygpu_matrix_load_identity,
|
||||
METH_NOARGS,
|
||||
bpygpu_matrix_load_identity_doc},
|
||||
{"load_matrix", (PyCFunction)bpygpu_matrix_load_matrix, METH_O, bpygpu_matrix_load_matrix_doc},
|
||||
{"load_projection_matrix",
|
||||
(PyCFunction)bpygpu_matrix_load_projection_matrix,
|
||||
METH_O,
|
||||
bpygpu_matrix_load_projection_matrix_doc},
|
||||
|
||||
/* Read State */
|
||||
{"get_projection_matrix", (PyCFunction)bpygpu_matrix_get_projection_matrix,
|
||||
METH_NOARGS, bpygpu_matrix_get_projection_matrix_doc},
|
||||
{"get_model_view_matrix", (PyCFunction)bpygpu_matrix_get_model_view_matrix,
|
||||
METH_NOARGS, bpygpu_matrix_get_model_view_matrix_doc},
|
||||
{"get_normal_matrix", (PyCFunction)bpygpu_matrix_get_normal_matrix,
|
||||
METH_NOARGS, bpygpu_matrix_get_normal_matrix_doc},
|
||||
/* Read State */
|
||||
{"get_projection_matrix",
|
||||
(PyCFunction)bpygpu_matrix_get_projection_matrix,
|
||||
METH_NOARGS,
|
||||
bpygpu_matrix_get_projection_matrix_doc},
|
||||
{"get_model_view_matrix",
|
||||
(PyCFunction)bpygpu_matrix_get_model_view_matrix,
|
||||
METH_NOARGS,
|
||||
bpygpu_matrix_get_model_view_matrix_doc},
|
||||
{"get_normal_matrix",
|
||||
(PyCFunction)bpygpu_matrix_get_normal_matrix,
|
||||
METH_NOARGS,
|
||||
bpygpu_matrix_get_normal_matrix_doc},
|
||||
|
||||
{NULL, NULL, 0, NULL},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(bpygpu_matrix_doc,
|
||||
"This module provides access to the matrix stack."
|
||||
);
|
||||
PyDoc_STRVAR(bpygpu_matrix_doc, "This module provides access to the matrix stack.");
|
||||
static PyModuleDef BPyGPU_matrix_module_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "gpu.matrix",
|
||||
.m_doc = bpygpu_matrix_doc,
|
||||
.m_methods = bpygpu_matrix_methods,
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "gpu.matrix",
|
||||
.m_doc = bpygpu_matrix_doc,
|
||||
.m_methods = bpygpu_matrix_methods,
|
||||
};
|
||||
|
||||
PyObject *BPyInit_gpu_matrix(void)
|
||||
{
|
||||
PyObject *submodule;
|
||||
PyObject *submodule;
|
||||
|
||||
submodule = PyModule_Create(&BPyGPU_matrix_module_def);
|
||||
submodule = PyModule_Create(&BPyGPU_matrix_module_def);
|
||||
|
||||
if (PyType_Ready(&BPyGPU_matrix_stack_context_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&BPyGPU_matrix_stack_context_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return submodule;
|
||||
return submodule;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
|
||||
PyObject *BPyInit_gpu_matrix(void);
|
||||
|
||||
#endif /* __GPU_PY_MATRIX_H__ */
|
||||
#endif /* __GPU_PY_MATRIX_H__ */
|
||||
|
||||
@@ -51,316 +51,331 @@
|
||||
#include "gpu_py_api.h"
|
||||
#include "gpu_py_offscreen.h" /* own include */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name GPUOffScreen Common Utilities
|
||||
* \{ */
|
||||
|
||||
static int bpygpu_offscreen_valid_check(BPyGPUOffScreen *bpygpu_ofs)
|
||||
{
|
||||
if (UNLIKELY(bpygpu_ofs->ofs == NULL)) {
|
||||
PyErr_SetString(PyExc_ReferenceError, "GPU offscreen was freed, no further access is valid");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
if (UNLIKELY(bpygpu_ofs->ofs == NULL)) {
|
||||
PyErr_SetString(PyExc_ReferenceError, "GPU offscreen was freed, no further access is valid");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BPY_GPU_OFFSCREEN_CHECK_OBJ(bpygpu) { \
|
||||
if (UNLIKELY(bpygpu_offscreen_valid_check(bpygpu) == -1)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
} ((void)0)
|
||||
#define BPY_GPU_OFFSCREEN_CHECK_OBJ(bpygpu) \
|
||||
{ \
|
||||
if (UNLIKELY(bpygpu_offscreen_valid_check(bpygpu) == -1)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name GPUOffscreen Type
|
||||
* \{ */
|
||||
|
||||
|
||||
static PyObject *bpygpu_offscreen_new(PyTypeObject *UNUSED(self), PyObject *args, PyObject *kwds)
|
||||
{
|
||||
BPYGPU_IS_INIT_OR_ERROR_OBJ;
|
||||
BPYGPU_IS_INIT_OR_ERROR_OBJ;
|
||||
|
||||
GPUOffScreen *ofs;
|
||||
int width, height, samples = 0;
|
||||
char err_out[256];
|
||||
GPUOffScreen *ofs;
|
||||
int width, height, samples = 0;
|
||||
char err_out[256];
|
||||
|
||||
static const char *_keywords[] = {"width", "height", "samples", NULL};
|
||||
static _PyArg_Parser _parser = {"ii|i:GPUOffScreen.__new__", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kwds, &_parser,
|
||||
&width, &height, &samples))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"width", "height", "samples", NULL};
|
||||
static _PyArg_Parser _parser = {"ii|i:GPUOffScreen.__new__", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, &width, &height, &samples)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ofs = GPU_offscreen_create(width, height, samples, true, false, err_out);
|
||||
ofs = GPU_offscreen_create(width, height, samples, true, false, err_out);
|
||||
|
||||
if (ofs == NULL) {
|
||||
PyErr_Format(PyExc_RuntimeError,
|
||||
"gpu.offscreen.new(...) failed with '%s'",
|
||||
err_out[0] ? err_out : "unknown error");
|
||||
return NULL;
|
||||
}
|
||||
if (ofs == NULL) {
|
||||
PyErr_Format(PyExc_RuntimeError,
|
||||
"gpu.offscreen.new(...) failed with '%s'",
|
||||
err_out[0] ? err_out : "unknown error");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return BPyGPUOffScreen_CreatePyObject(ofs);
|
||||
return BPyGPUOffScreen_CreatePyObject(ofs);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_offscreen_width_doc, "Width of the texture.\n\n:type: `int`");
|
||||
static PyObject *bpygpu_offscreen_width_get(BPyGPUOffScreen *self, void *UNUSED(type))
|
||||
{
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
return PyLong_FromLong(GPU_offscreen_width(self->ofs));
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
return PyLong_FromLong(GPU_offscreen_width(self->ofs));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_offscreen_height_doc, "Height of the texture.\n\n:type: `int`");
|
||||
static PyObject *bpygpu_offscreen_height_get(BPyGPUOffScreen *self, void *UNUSED(type))
|
||||
{
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
return PyLong_FromLong(GPU_offscreen_height(self->ofs));
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
return PyLong_FromLong(GPU_offscreen_height(self->ofs));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_offscreen_color_texture_doc, "OpenGL bindcode for the color texture.\n\n:type: `int`");
|
||||
PyDoc_STRVAR(bpygpu_offscreen_color_texture_doc,
|
||||
"OpenGL bindcode for the color texture.\n\n:type: `int`");
|
||||
static PyObject *bpygpu_offscreen_color_texture_get(BPyGPUOffScreen *self, void *UNUSED(type))
|
||||
{
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
GPUTexture *texture = GPU_offscreen_color_texture(self->ofs);
|
||||
return PyLong_FromLong(GPU_texture_opengl_bindcode(texture));
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
GPUTexture *texture = GPU_offscreen_color_texture(self->ofs);
|
||||
return PyLong_FromLong(GPU_texture_opengl_bindcode(texture));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_offscreen_bind_doc,
|
||||
".. method:: bind(save=True)\n"
|
||||
"\n"
|
||||
" Bind the offscreen object.\n"
|
||||
" To make sure that the offscreen gets unbind whether an exception occurs or not, pack it into a `with` statement.\n"
|
||||
"\n"
|
||||
" :arg save: Save the current OpenGL state, so that it can be restored when unbinding.\n"
|
||||
" :type save: `bool`\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpygpu_offscreen_bind_doc,
|
||||
".. method:: bind(save=True)\n"
|
||||
"\n"
|
||||
" Bind the offscreen object.\n"
|
||||
" To make sure that the offscreen gets unbind whether an exception occurs or not, pack it "
|
||||
"into a `with` statement.\n"
|
||||
"\n"
|
||||
" :arg save: Save the current OpenGL state, so that it can be restored when unbinding.\n"
|
||||
" :type save: `bool`\n");
|
||||
static PyObject *bpygpu_offscreen_bind(BPyGPUOffScreen *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
bool save = true;
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
bool save = true;
|
||||
|
||||
static const char *_keywords[] = {"save", NULL};
|
||||
static _PyArg_Parser _parser = {"|O&:bind", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kwds, &_parser,
|
||||
PyC_ParseBool, &save))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"save", NULL};
|
||||
static _PyArg_Parser _parser = {"|O&:bind", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, PyC_ParseBool, &save)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GPU_offscreen_bind(self->ofs, save);
|
||||
GPU_offscreen_bind(self->ofs, save);
|
||||
|
||||
self->is_saved = save;
|
||||
Py_INCREF(self);
|
||||
self->is_saved = save;
|
||||
Py_INCREF(self);
|
||||
|
||||
return (PyObject *)self;
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_offscreen_unbind_doc,
|
||||
".. method:: unbind(restore=True)\n"
|
||||
"\n"
|
||||
" Unbind the offscreen object.\n"
|
||||
"\n"
|
||||
" :arg restore: Restore the OpenGL state, can only be used when the state has been saved before.\n"
|
||||
" :type restore: `bool`\n"
|
||||
);
|
||||
".. method:: unbind(restore=True)\n"
|
||||
"\n"
|
||||
" Unbind the offscreen object.\n"
|
||||
"\n"
|
||||
" :arg restore: Restore the OpenGL state, can only be used when the state has been "
|
||||
"saved before.\n"
|
||||
" :type restore: `bool`\n");
|
||||
static PyObject *bpygpu_offscreen_unbind(BPyGPUOffScreen *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
bool restore = true;
|
||||
bool restore = true;
|
||||
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
|
||||
static const char *_keywords[] = {"restore", NULL};
|
||||
static _PyArg_Parser _parser = {"|O&:unbind", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kwds, &_parser,
|
||||
PyC_ParseBool, &restore))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"restore", NULL};
|
||||
static _PyArg_Parser _parser = {"|O&:unbind", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, PyC_ParseBool, &restore)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GPU_offscreen_unbind(self->ofs, restore);
|
||||
Py_RETURN_NONE;
|
||||
GPU_offscreen_unbind(self->ofs, restore);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_offscreen_draw_view3d_doc,
|
||||
".. method:: draw_view3d(scene, view3d, region, view_matrix, projection_matrix)\n"
|
||||
"\n"
|
||||
" Draw the 3d viewport in the offscreen object.\n"
|
||||
"\n"
|
||||
" :arg scene: Scene to draw.\n"
|
||||
" :type scene: :class:`bpy.types.Scene`\n"
|
||||
" :arg view_layer: View layer to draw.\n"
|
||||
" :type view_layer: :class:`bpy.types.ViewLayer`\n"
|
||||
" :arg view3d: 3D View to get the drawing settings from.\n"
|
||||
" :type view3d: :class:`bpy.types.SpaceView3D`\n"
|
||||
" :arg region: Region of the 3D View (required as temporary draw target).\n"
|
||||
" :type region: :class:`bpy.types.Region`\n"
|
||||
" :arg view_matrix: View Matrix (e.g. ``camera.matrix_world.inverted()``).\n"
|
||||
" :type view_matrix: :class:`mathutils.Matrix`\n"
|
||||
" :arg projection_matrix: Projection Matrix (e.g. ``camera.calc_matrix_camera(...)``).\n"
|
||||
" :type projection_matrix: :class:`mathutils.Matrix`\n"
|
||||
);
|
||||
static PyObject *bpygpu_offscreen_draw_view3d(BPyGPUOffScreen *self, PyObject *args, PyObject *kwds)
|
||||
PyDoc_STRVAR(
|
||||
bpygpu_offscreen_draw_view3d_doc,
|
||||
".. method:: draw_view3d(scene, view3d, region, view_matrix, projection_matrix)\n"
|
||||
"\n"
|
||||
" Draw the 3d viewport in the offscreen object.\n"
|
||||
"\n"
|
||||
" :arg scene: Scene to draw.\n"
|
||||
" :type scene: :class:`bpy.types.Scene`\n"
|
||||
" :arg view_layer: View layer to draw.\n"
|
||||
" :type view_layer: :class:`bpy.types.ViewLayer`\n"
|
||||
" :arg view3d: 3D View to get the drawing settings from.\n"
|
||||
" :type view3d: :class:`bpy.types.SpaceView3D`\n"
|
||||
" :arg region: Region of the 3D View (required as temporary draw target).\n"
|
||||
" :type region: :class:`bpy.types.Region`\n"
|
||||
" :arg view_matrix: View Matrix (e.g. ``camera.matrix_world.inverted()``).\n"
|
||||
" :type view_matrix: :class:`mathutils.Matrix`\n"
|
||||
" :arg projection_matrix: Projection Matrix (e.g. ``camera.calc_matrix_camera(...)``).\n"
|
||||
" :type projection_matrix: :class:`mathutils.Matrix`\n");
|
||||
static PyObject *bpygpu_offscreen_draw_view3d(BPyGPUOffScreen *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
MatrixObject *py_mat_view, *py_mat_projection;
|
||||
PyObject *py_scene, *py_view_layer, *py_region, *py_view3d;
|
||||
MatrixObject *py_mat_view, *py_mat_projection;
|
||||
PyObject *py_scene, *py_view_layer, *py_region, *py_view3d;
|
||||
|
||||
struct Depsgraph *depsgraph;
|
||||
struct Scene *scene;
|
||||
struct ViewLayer *view_layer;
|
||||
View3D *v3d;
|
||||
ARegion *ar;
|
||||
struct RV3DMatrixStore *rv3d_mats;
|
||||
struct Depsgraph *depsgraph;
|
||||
struct Scene *scene;
|
||||
struct ViewLayer *view_layer;
|
||||
View3D *v3d;
|
||||
ARegion *ar;
|
||||
struct RV3DMatrixStore *rv3d_mats;
|
||||
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
|
||||
static const char *_keywords[] = {
|
||||
"scene", "view_layer", "view3d", "region",
|
||||
"view_matrix", "projection_matrix", NULL};
|
||||
static const char *_keywords[] = {
|
||||
"scene", "view_layer", "view3d", "region", "view_matrix", "projection_matrix", NULL};
|
||||
|
||||
static _PyArg_Parser _parser = {"OOOOO&O&:draw_view3d", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kwds, &_parser,
|
||||
&py_scene, &py_view_layer, &py_view3d, &py_region,
|
||||
Matrix_Parse4x4, &py_mat_view,
|
||||
Matrix_Parse4x4, &py_mat_projection) ||
|
||||
(!(scene = PyC_RNA_AsPointer(py_scene, "Scene")) ||
|
||||
!(view_layer = PyC_RNA_AsPointer(py_view_layer, "ViewLayer")) ||
|
||||
!(v3d = PyC_RNA_AsPointer(py_view3d, "SpaceView3D")) ||
|
||||
!(ar = PyC_RNA_AsPointer(py_region, "Region"))))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static _PyArg_Parser _parser = {"OOOOO&O&:draw_view3d", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args,
|
||||
kwds,
|
||||
&_parser,
|
||||
&py_scene,
|
||||
&py_view_layer,
|
||||
&py_view3d,
|
||||
&py_region,
|
||||
Matrix_Parse4x4,
|
||||
&py_mat_view,
|
||||
Matrix_Parse4x4,
|
||||
&py_mat_projection) ||
|
||||
(!(scene = PyC_RNA_AsPointer(py_scene, "Scene")) ||
|
||||
!(view_layer = PyC_RNA_AsPointer(py_view_layer, "ViewLayer")) ||
|
||||
!(v3d = PyC_RNA_AsPointer(py_view3d, "SpaceView3D")) ||
|
||||
!(ar = PyC_RNA_AsPointer(py_region, "Region")))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLI_assert(BKE_id_is_in_global_main(&scene->id));
|
||||
BLI_assert(BKE_id_is_in_global_main(&scene->id));
|
||||
|
||||
depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
|
||||
depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
|
||||
|
||||
rv3d_mats = ED_view3d_mats_rv3d_backup(ar->regiondata);
|
||||
rv3d_mats = ED_view3d_mats_rv3d_backup(ar->regiondata);
|
||||
|
||||
GPU_offscreen_bind(self->ofs, true);
|
||||
GPU_offscreen_bind(self->ofs, true);
|
||||
|
||||
ED_view3d_draw_offscreen(depsgraph,
|
||||
scene,
|
||||
v3d->shading.type,
|
||||
v3d,
|
||||
ar,
|
||||
GPU_offscreen_width(self->ofs),
|
||||
GPU_offscreen_height(self->ofs),
|
||||
(float(*)[4])py_mat_view->matrix,
|
||||
(float(*)[4])py_mat_projection->matrix,
|
||||
false,
|
||||
true,
|
||||
"",
|
||||
NULL,
|
||||
true,
|
||||
self->ofs,
|
||||
NULL);
|
||||
ED_view3d_draw_offscreen(depsgraph,
|
||||
scene,
|
||||
v3d->shading.type,
|
||||
v3d,
|
||||
ar,
|
||||
GPU_offscreen_width(self->ofs),
|
||||
GPU_offscreen_height(self->ofs),
|
||||
(float(*)[4])py_mat_view->matrix,
|
||||
(float(*)[4])py_mat_projection->matrix,
|
||||
false,
|
||||
true,
|
||||
"",
|
||||
NULL,
|
||||
true,
|
||||
self->ofs,
|
||||
NULL);
|
||||
|
||||
GPU_offscreen_unbind(self->ofs, true);
|
||||
GPU_offscreen_unbind(self->ofs, true);
|
||||
|
||||
ED_view3d_mats_rv3d_restore(ar->regiondata, rv3d_mats);
|
||||
MEM_freeN(rv3d_mats);
|
||||
ED_view3d_mats_rv3d_restore(ar->regiondata, rv3d_mats);
|
||||
MEM_freeN(rv3d_mats);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_offscreen_free_doc,
|
||||
".. method:: free()\n"
|
||||
"\n"
|
||||
" Free the offscreen object.\n"
|
||||
" The framebuffer, texture and render objects will no longer be accessible.\n"
|
||||
);
|
||||
".. method:: free()\n"
|
||||
"\n"
|
||||
" Free the offscreen object.\n"
|
||||
" The framebuffer, texture and render objects will no longer be accessible.\n");
|
||||
static PyObject *bpygpu_offscreen_free(BPyGPUOffScreen *self)
|
||||
{
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
|
||||
GPU_offscreen_free(self->ofs);
|
||||
self->ofs = NULL;
|
||||
Py_RETURN_NONE;
|
||||
GPU_offscreen_free(self->ofs);
|
||||
self->ofs = NULL;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *bpygpu_offscreen_bind_context_enter(BPyGPUOffScreen *UNUSED(self))
|
||||
{
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *bpygpu_offscreen_bind_context_exit(BPyGPUOffScreen *self, PyObject *UNUSED(args))
|
||||
{
|
||||
GPU_offscreen_unbind(self->ofs, self->is_saved);
|
||||
Py_RETURN_NONE;
|
||||
GPU_offscreen_unbind(self->ofs, self->is_saved);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static void BPyGPUOffScreen__tp_dealloc(BPyGPUOffScreen *self)
|
||||
{
|
||||
if (self->ofs) {
|
||||
GPU_offscreen_free(self->ofs);
|
||||
}
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
if (self->ofs) {
|
||||
GPU_offscreen_free(self->ofs);
|
||||
}
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyGetSetDef bpygpu_offscreen_getseters[] = {
|
||||
{(char *)"color_texture", (getter)bpygpu_offscreen_color_texture_get, (setter)NULL, bpygpu_offscreen_color_texture_doc, NULL},
|
||||
{(char *)"width", (getter)bpygpu_offscreen_width_get, (setter)NULL, bpygpu_offscreen_width_doc, NULL},
|
||||
{(char *)"height", (getter)bpygpu_offscreen_height_get, (setter)NULL, bpygpu_offscreen_height_doc, NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
|
||||
{(char *)"color_texture",
|
||||
(getter)bpygpu_offscreen_color_texture_get,
|
||||
(setter)NULL,
|
||||
bpygpu_offscreen_color_texture_doc,
|
||||
NULL},
|
||||
{(char *)"width",
|
||||
(getter)bpygpu_offscreen_width_get,
|
||||
(setter)NULL,
|
||||
bpygpu_offscreen_width_doc,
|
||||
NULL},
|
||||
{(char *)"height",
|
||||
(getter)bpygpu_offscreen_height_get,
|
||||
(setter)NULL,
|
||||
bpygpu_offscreen_height_doc,
|
||||
NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static struct PyMethodDef bpygpu_offscreen_methods[] = {
|
||||
{"bind", (PyCFunction)bpygpu_offscreen_bind, METH_VARARGS | METH_KEYWORDS, bpygpu_offscreen_bind_doc},
|
||||
{"unbind", (PyCFunction)bpygpu_offscreen_unbind, METH_VARARGS | METH_KEYWORDS, bpygpu_offscreen_unbind_doc},
|
||||
{"draw_view3d", (PyCFunction)bpygpu_offscreen_draw_view3d, METH_VARARGS | METH_KEYWORDS, bpygpu_offscreen_draw_view3d_doc},
|
||||
{"free", (PyCFunction)bpygpu_offscreen_free, METH_NOARGS, bpygpu_offscreen_free_doc},
|
||||
{"__enter__", (PyCFunction)bpygpu_offscreen_bind_context_enter, METH_NOARGS},
|
||||
{"__exit__", (PyCFunction)bpygpu_offscreen_bind_context_exit, METH_VARARGS},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"bind",
|
||||
(PyCFunction)bpygpu_offscreen_bind,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpygpu_offscreen_bind_doc},
|
||||
{"unbind",
|
||||
(PyCFunction)bpygpu_offscreen_unbind,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpygpu_offscreen_unbind_doc},
|
||||
{"draw_view3d",
|
||||
(PyCFunction)bpygpu_offscreen_draw_view3d,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpygpu_offscreen_draw_view3d_doc},
|
||||
{"free", (PyCFunction)bpygpu_offscreen_free, METH_NOARGS, bpygpu_offscreen_free_doc},
|
||||
{"__enter__", (PyCFunction)bpygpu_offscreen_bind_context_enter, METH_NOARGS},
|
||||
{"__exit__", (PyCFunction)bpygpu_offscreen_bind_context_exit, METH_VARARGS},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(bpygpu_offscreen_doc,
|
||||
".. class:: GPUOffScreen(width, height, samples=0)\n"
|
||||
"\n"
|
||||
" This object gives access to off screen buffers.\n"
|
||||
"\n"
|
||||
" :arg width: Horizontal dimension of the buffer.\n"
|
||||
" :type width: `int`\n"
|
||||
" :arg height: Vertical dimension of the buffer.\n"
|
||||
" :type height: `int`\n"
|
||||
" :arg samples: OpenGL samples to use for MSAA or zero to disable.\n"
|
||||
" :type samples: `int`\n"
|
||||
);
|
||||
".. class:: GPUOffScreen(width, height, samples=0)\n"
|
||||
"\n"
|
||||
" This object gives access to off screen buffers.\n"
|
||||
"\n"
|
||||
" :arg width: Horizontal dimension of the buffer.\n"
|
||||
" :type width: `int`\n"
|
||||
" :arg height: Vertical dimension of the buffer.\n"
|
||||
" :type height: `int`\n"
|
||||
" :arg samples: OpenGL samples to use for MSAA or zero to disable.\n"
|
||||
" :type samples: `int`\n");
|
||||
PyTypeObject BPyGPUOffScreen_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "GPUOffScreen",
|
||||
.tp_basicsize = sizeof(BPyGPUOffScreen),
|
||||
.tp_dealloc = (destructor)BPyGPUOffScreen__tp_dealloc,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_doc = bpygpu_offscreen_doc,
|
||||
.tp_methods = bpygpu_offscreen_methods,
|
||||
.tp_getset = bpygpu_offscreen_getseters,
|
||||
.tp_new = bpygpu_offscreen_new,
|
||||
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "GPUOffScreen",
|
||||
.tp_basicsize = sizeof(BPyGPUOffScreen),
|
||||
.tp_dealloc = (destructor)BPyGPUOffScreen__tp_dealloc,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_doc = bpygpu_offscreen_doc,
|
||||
.tp_methods = bpygpu_offscreen_methods,
|
||||
.tp_getset = bpygpu_offscreen_getseters,
|
||||
.tp_new = bpygpu_offscreen_new,
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public API
|
||||
* \{ */
|
||||
|
||||
PyObject *BPyGPUOffScreen_CreatePyObject(GPUOffScreen *ofs)
|
||||
{
|
||||
BPyGPUOffScreen *self;
|
||||
BPyGPUOffScreen *self;
|
||||
|
||||
self = PyObject_New(BPyGPUOffScreen, &BPyGPUOffScreen_Type);
|
||||
self->ofs = ofs;
|
||||
self = PyObject_New(BPyGPUOffScreen, &BPyGPUOffScreen_Type);
|
||||
self->ofs = ofs;
|
||||
|
||||
return (PyObject *)self;
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -25,12 +25,11 @@
|
||||
|
||||
extern PyTypeObject BPyGPUOffScreen_Type;
|
||||
|
||||
#define BPyGPUOffScreen_Check(v) (Py_TYPE(v) == &BPyGPUOffScreen_Type)
|
||||
#define BPyGPUOffScreen_Check(v) (Py_TYPE(v) == &BPyGPUOffScreen_Type)
|
||||
|
||||
typedef struct BPyGPUOffScreen {
|
||||
PyObject_HEAD
|
||||
struct GPUOffScreen *ofs;
|
||||
bool is_saved;
|
||||
PyObject_HEAD struct GPUOffScreen *ofs;
|
||||
bool is_saved;
|
||||
} BPyGPUOffScreen;
|
||||
|
||||
PyObject *BPyGPUOffScreen_CreatePyObject(struct GPUOffScreen *ofs) ATTR_NONNULL(1);
|
||||
|
||||
@@ -41,21 +41,20 @@
|
||||
* \{ */
|
||||
|
||||
PyDoc_STRVAR(bpygpu_select_load_id_doc,
|
||||
"load_id(id)\n"
|
||||
"\n"
|
||||
" Set the selection ID.\n"
|
||||
"\n"
|
||||
" :param id: Number (32-bit unsigned int).\n"
|
||||
" :type select: int\n"
|
||||
);
|
||||
"load_id(id)\n"
|
||||
"\n"
|
||||
" Set the selection ID.\n"
|
||||
"\n"
|
||||
" :param id: Number (32-bit unsigned int).\n"
|
||||
" :type select: int\n");
|
||||
static PyObject *bpygpu_select_load_id(PyObject *UNUSED(self), PyObject *value)
|
||||
{
|
||||
uint id;
|
||||
if ((id = PyC_Long_AsU32(value)) == (uint)-1) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_select_load_id(id);
|
||||
Py_RETURN_NONE;
|
||||
uint id;
|
||||
if ((id = PyC_Long_AsU32(value)) == (uint)-1) {
|
||||
return NULL;
|
||||
}
|
||||
GPU_select_load_id(id);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
/** \} */
|
||||
|
||||
@@ -64,28 +63,26 @@ static PyObject *bpygpu_select_load_id(PyObject *UNUSED(self), PyObject *value)
|
||||
* \{ */
|
||||
|
||||
static struct PyMethodDef bpygpu_select_methods[] = {
|
||||
/* Manage Stack */
|
||||
{"load_id", (PyCFunction)bpygpu_select_load_id, METH_O, bpygpu_select_load_id_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
/* Manage Stack */
|
||||
{"load_id", (PyCFunction)bpygpu_select_load_id, METH_O, bpygpu_select_load_id_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(bpygpu_select_doc,
|
||||
"This module provides access to selection."
|
||||
);
|
||||
PyDoc_STRVAR(bpygpu_select_doc, "This module provides access to selection.");
|
||||
static PyModuleDef BPyGPU_select_module_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "gpu.select",
|
||||
.m_doc = bpygpu_select_doc,
|
||||
.m_methods = bpygpu_select_methods,
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "gpu.select",
|
||||
.m_doc = bpygpu_select_doc,
|
||||
.m_methods = bpygpu_select_methods,
|
||||
};
|
||||
|
||||
PyObject *BPyInit_gpu_select(void)
|
||||
{
|
||||
PyObject *submodule;
|
||||
PyObject *submodule;
|
||||
|
||||
submodule = PyModule_Create(&BPyGPU_select_module_def);
|
||||
submodule = PyModule_Create(&BPyGPU_select_module_def);
|
||||
|
||||
return submodule;
|
||||
return submodule;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
|
||||
PyObject *BPyInit_gpu_select(void);
|
||||
|
||||
#endif /* __GPU_PY_SELECT_H__ */
|
||||
#endif /* __GPU_PY_SELECT_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,12 +23,11 @@
|
||||
|
||||
extern PyTypeObject BPyGPUShader_Type;
|
||||
|
||||
#define BPyGPUShader_Check(v) (Py_TYPE(v) == &BPyGPUShader_Type)
|
||||
#define BPyGPUShader_Check(v) (Py_TYPE(v) == &BPyGPUShader_Type)
|
||||
|
||||
typedef struct BPyGPUShader {
|
||||
PyObject_VAR_HEAD
|
||||
struct GPUShader *shader;
|
||||
bool is_builtin;
|
||||
PyObject_VAR_HEAD struct GPUShader *shader;
|
||||
bool is_builtin;
|
||||
} BPyGPUShader;
|
||||
|
||||
PyObject *BPyGPUShader_CreatePyObject(struct GPUShader *shader, bool is_builtin);
|
||||
|
||||
@@ -30,53 +30,53 @@
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/** \name GPU Types Module
|
||||
* \{ */
|
||||
|
||||
static struct PyModuleDef BPyGPU_types_module_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "gpu.types",
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "gpu.types",
|
||||
};
|
||||
|
||||
PyObject *BPyInit_gpu_types(void)
|
||||
{
|
||||
PyObject *submodule;
|
||||
PyObject *submodule;
|
||||
|
||||
submodule = PyModule_Create(&BPyGPU_types_module_def);
|
||||
submodule = PyModule_Create(&BPyGPU_types_module_def);
|
||||
|
||||
if (PyType_Ready(&BPyGPUVertFormat_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&BPyGPUVertBuf_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&BPyGPUIndexBuf_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&BPyGPUBatch_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&BPyGPUOffScreen_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&BPyGPUShader_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&BPyGPUVertFormat_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&BPyGPUVertBuf_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&BPyGPUIndexBuf_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&BPyGPUBatch_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&BPyGPUOffScreen_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyType_Ready(&BPyGPUShader_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define MODULE_TYPE_ADD(s, t) \
|
||||
PyModule_AddObject(s, t.tp_name, (PyObject *)&t); Py_INCREF((PyObject *)&t)
|
||||
PyModule_AddObject(s, t.tp_name, (PyObject *)&t); \
|
||||
Py_INCREF((PyObject *)&t)
|
||||
|
||||
MODULE_TYPE_ADD(submodule, BPyGPUVertFormat_Type);
|
||||
MODULE_TYPE_ADD(submodule, BPyGPUVertBuf_Type);
|
||||
MODULE_TYPE_ADD(submodule, BPyGPUIndexBuf_Type);
|
||||
MODULE_TYPE_ADD(submodule, BPyGPUBatch_Type);
|
||||
MODULE_TYPE_ADD(submodule, BPyGPUOffScreen_Type);
|
||||
MODULE_TYPE_ADD(submodule, BPyGPUShader_Type);
|
||||
MODULE_TYPE_ADD(submodule, BPyGPUVertFormat_Type);
|
||||
MODULE_TYPE_ADD(submodule, BPyGPUVertBuf_Type);
|
||||
MODULE_TYPE_ADD(submodule, BPyGPUIndexBuf_Type);
|
||||
MODULE_TYPE_ADD(submodule, BPyGPUBatch_Type);
|
||||
MODULE_TYPE_ADD(submodule, BPyGPUOffScreen_Type);
|
||||
MODULE_TYPE_ADD(submodule, BPyGPUShader_Type);
|
||||
|
||||
#undef MODULE_TYPE_ADD
|
||||
|
||||
return submodule;
|
||||
return submodule;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -40,48 +40,74 @@
|
||||
* \{ */
|
||||
|
||||
#define PY_AS_NATIVE_SWITCH(attr) \
|
||||
switch (attr->comp_type) { \
|
||||
case GPU_COMP_I8: { PY_AS_NATIVE(int8_t, PyC_Long_AsI8); break; } \
|
||||
case GPU_COMP_U8: { PY_AS_NATIVE(uint8_t, PyC_Long_AsU8); break; } \
|
||||
case GPU_COMP_I16: { PY_AS_NATIVE(int16_t, PyC_Long_AsI16); break; } \
|
||||
case GPU_COMP_U16: { PY_AS_NATIVE(uint16_t, PyC_Long_AsU16); break; } \
|
||||
case GPU_COMP_I32: { PY_AS_NATIVE(int32_t, PyC_Long_AsI32); break; } \
|
||||
case GPU_COMP_U32: { PY_AS_NATIVE(uint32_t, PyC_Long_AsU32); break; } \
|
||||
case GPU_COMP_F32: { PY_AS_NATIVE(float, PyFloat_AsDouble); break; } \
|
||||
default: \
|
||||
BLI_assert(0); \
|
||||
} ((void)0)
|
||||
switch (attr->comp_type) { \
|
||||
case GPU_COMP_I8: { \
|
||||
PY_AS_NATIVE(int8_t, PyC_Long_AsI8); \
|
||||
break; \
|
||||
} \
|
||||
case GPU_COMP_U8: { \
|
||||
PY_AS_NATIVE(uint8_t, PyC_Long_AsU8); \
|
||||
break; \
|
||||
} \
|
||||
case GPU_COMP_I16: { \
|
||||
PY_AS_NATIVE(int16_t, PyC_Long_AsI16); \
|
||||
break; \
|
||||
} \
|
||||
case GPU_COMP_U16: { \
|
||||
PY_AS_NATIVE(uint16_t, PyC_Long_AsU16); \
|
||||
break; \
|
||||
} \
|
||||
case GPU_COMP_I32: { \
|
||||
PY_AS_NATIVE(int32_t, PyC_Long_AsI32); \
|
||||
break; \
|
||||
} \
|
||||
case GPU_COMP_U32: { \
|
||||
PY_AS_NATIVE(uint32_t, PyC_Long_AsU32); \
|
||||
break; \
|
||||
} \
|
||||
case GPU_COMP_F32: { \
|
||||
PY_AS_NATIVE(float, PyFloat_AsDouble); \
|
||||
break; \
|
||||
} \
|
||||
default: \
|
||||
BLI_assert(0); \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
/* No error checking, callers must run PyErr_Occurred */
|
||||
static void fill_format_elem(void *data_dst_void, PyObject *py_src, const GPUVertAttr *attr)
|
||||
{
|
||||
#define PY_AS_NATIVE(ty_dst, py_as_native) \
|
||||
{ \
|
||||
ty_dst *data_dst = data_dst_void; \
|
||||
*data_dst = py_as_native(py_src); \
|
||||
} ((void)0)
|
||||
{ \
|
||||
ty_dst *data_dst = data_dst_void; \
|
||||
*data_dst = py_as_native(py_src); \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
PY_AS_NATIVE_SWITCH(attr);
|
||||
PY_AS_NATIVE_SWITCH(attr);
|
||||
|
||||
#undef PY_AS_NATIVE
|
||||
}
|
||||
|
||||
/* No error checking, callers must run PyErr_Occurred */
|
||||
static void fill_format_sequence(void *data_dst_void, PyObject *py_seq_fast, const GPUVertAttr *attr)
|
||||
static void fill_format_sequence(void *data_dst_void,
|
||||
PyObject *py_seq_fast,
|
||||
const GPUVertAttr *attr)
|
||||
{
|
||||
const uint len = attr->comp_len;
|
||||
PyObject **value_fast_items = PySequence_Fast_ITEMS(py_seq_fast);
|
||||
const uint len = attr->comp_len;
|
||||
PyObject **value_fast_items = PySequence_Fast_ITEMS(py_seq_fast);
|
||||
|
||||
/**
|
||||
* Args are constants, so range checks will be optimized out if they're nop's.
|
||||
*/
|
||||
#define PY_AS_NATIVE(ty_dst, py_as_native) \
|
||||
ty_dst *data_dst = data_dst_void; \
|
||||
for (uint i = 0; i < len; i++) { \
|
||||
data_dst[i] = py_as_native(value_fast_items[i]); \
|
||||
} ((void)0)
|
||||
ty_dst *data_dst = data_dst_void; \
|
||||
for (uint i = 0; i < len; i++) { \
|
||||
data_dst[i] = py_as_native(value_fast_items[i]); \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
PY_AS_NATIVE_SWITCH(attr);
|
||||
PY_AS_NATIVE_SWITCH(attr);
|
||||
|
||||
#undef PY_AS_NATIVE
|
||||
}
|
||||
@@ -90,256 +116,244 @@ static void fill_format_sequence(void *data_dst_void, PyObject *py_seq_fast, con
|
||||
#undef WARN_TYPE_LIMIT_PUSH
|
||||
#undef WARN_TYPE_LIMIT_POP
|
||||
|
||||
static bool bpygpu_vertbuf_fill_impl(
|
||||
GPUVertBuf *vbo,
|
||||
uint data_id, PyObject *seq, const char *error_prefix)
|
||||
static bool bpygpu_vertbuf_fill_impl(GPUVertBuf *vbo,
|
||||
uint data_id,
|
||||
PyObject *seq,
|
||||
const char *error_prefix)
|
||||
{
|
||||
const char *exc_str_size_mismatch = "Expected a %s of size %d, got %u";
|
||||
const char *exc_str_size_mismatch = "Expected a %s of size %d, got %u";
|
||||
|
||||
bool ok = true;
|
||||
const GPUVertAttr *attr = &vbo->format.attrs[data_id];
|
||||
bool ok = true;
|
||||
const GPUVertAttr *attr = &vbo->format.attrs[data_id];
|
||||
|
||||
if (PyObject_CheckBuffer(seq)) {
|
||||
Py_buffer pybuffer;
|
||||
if (PyObject_CheckBuffer(seq)) {
|
||||
Py_buffer pybuffer;
|
||||
|
||||
if (PyObject_GetBuffer(seq, &pybuffer, PyBUF_STRIDES | PyBUF_ND) == -1) {
|
||||
/* PyObject_GetBuffer raise a PyExc_BufferError */
|
||||
return false;
|
||||
}
|
||||
if (PyObject_GetBuffer(seq, &pybuffer, PyBUF_STRIDES | PyBUF_ND) == -1) {
|
||||
/* PyObject_GetBuffer raise a PyExc_BufferError */
|
||||
return false;
|
||||
}
|
||||
|
||||
uint comp_len = pybuffer.ndim == 1 ? 1 : (uint)pybuffer.shape[1];
|
||||
uint comp_len = pybuffer.ndim == 1 ? 1 : (uint)pybuffer.shape[1];
|
||||
|
||||
if (pybuffer.shape[0] != vbo->vertex_len) {
|
||||
PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
|
||||
"sequence", vbo->vertex_len, pybuffer.shape[0]);
|
||||
ok = false;
|
||||
}
|
||||
else if (comp_len != attr->comp_len) {
|
||||
PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
|
||||
"component", attr->comp_len, comp_len);
|
||||
ok = false;
|
||||
}
|
||||
else {
|
||||
GPU_vertbuf_attr_fill_stride(vbo, data_id, pybuffer.strides[0], pybuffer.buf);
|
||||
}
|
||||
if (pybuffer.shape[0] != vbo->vertex_len) {
|
||||
PyErr_Format(
|
||||
PyExc_ValueError, exc_str_size_mismatch, "sequence", vbo->vertex_len, pybuffer.shape[0]);
|
||||
ok = false;
|
||||
}
|
||||
else if (comp_len != attr->comp_len) {
|
||||
PyErr_Format(PyExc_ValueError, exc_str_size_mismatch, "component", attr->comp_len, comp_len);
|
||||
ok = false;
|
||||
}
|
||||
else {
|
||||
GPU_vertbuf_attr_fill_stride(vbo, data_id, pybuffer.strides[0], pybuffer.buf);
|
||||
}
|
||||
|
||||
PyBuffer_Release(&pybuffer);
|
||||
}
|
||||
else {
|
||||
GPUVertBufRaw data_step;
|
||||
GPU_vertbuf_attr_get_raw_data(vbo, data_id, &data_step);
|
||||
PyBuffer_Release(&pybuffer);
|
||||
}
|
||||
else {
|
||||
GPUVertBufRaw data_step;
|
||||
GPU_vertbuf_attr_get_raw_data(vbo, data_id, &data_step);
|
||||
|
||||
PyObject *seq_fast = PySequence_Fast(seq, "Vertex buffer fill");
|
||||
if (seq_fast == NULL) {
|
||||
return false;
|
||||
}
|
||||
PyObject *seq_fast = PySequence_Fast(seq, "Vertex buffer fill");
|
||||
if (seq_fast == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast);
|
||||
const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast);
|
||||
|
||||
if (seq_len != vbo->vertex_len) {
|
||||
PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
|
||||
"sequence", vbo->vertex_len, seq_len);
|
||||
}
|
||||
if (seq_len != vbo->vertex_len) {
|
||||
PyErr_Format(PyExc_ValueError, exc_str_size_mismatch, "sequence", vbo->vertex_len, seq_len);
|
||||
}
|
||||
|
||||
PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
|
||||
PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
|
||||
|
||||
if (attr->comp_len == 1) {
|
||||
for (uint i = 0; i < seq_len; i++) {
|
||||
uchar *data = (uchar *)GPU_vertbuf_raw_step(&data_step);
|
||||
PyObject *item = seq_items[i];
|
||||
fill_format_elem(data, item, attr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (uint i = 0; i < seq_len; i++) {
|
||||
uchar *data = (uchar *)GPU_vertbuf_raw_step(&data_step);
|
||||
PyObject *seq_fast_item = PySequence_Fast(seq_items[i], error_prefix);
|
||||
if (attr->comp_len == 1) {
|
||||
for (uint i = 0; i < seq_len; i++) {
|
||||
uchar *data = (uchar *)GPU_vertbuf_raw_step(&data_step);
|
||||
PyObject *item = seq_items[i];
|
||||
fill_format_elem(data, item, attr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (uint i = 0; i < seq_len; i++) {
|
||||
uchar *data = (uchar *)GPU_vertbuf_raw_step(&data_step);
|
||||
PyObject *seq_fast_item = PySequence_Fast(seq_items[i], error_prefix);
|
||||
|
||||
if (seq_fast_item == NULL) {
|
||||
ok = false;
|
||||
goto finally;
|
||||
}
|
||||
if (PySequence_Fast_GET_SIZE(seq_fast_item) != attr->comp_len) {
|
||||
PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
|
||||
"sequence", attr->comp_len, PySequence_Fast_GET_SIZE(seq_fast_item));
|
||||
ok = false;
|
||||
Py_DECREF(seq_fast_item);
|
||||
goto finally;
|
||||
}
|
||||
if (seq_fast_item == NULL) {
|
||||
ok = false;
|
||||
goto finally;
|
||||
}
|
||||
if (PySequence_Fast_GET_SIZE(seq_fast_item) != attr->comp_len) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
exc_str_size_mismatch,
|
||||
"sequence",
|
||||
attr->comp_len,
|
||||
PySequence_Fast_GET_SIZE(seq_fast_item));
|
||||
ok = false;
|
||||
Py_DECREF(seq_fast_item);
|
||||
goto finally;
|
||||
}
|
||||
|
||||
/* May trigger error, check below */
|
||||
fill_format_sequence(data, seq_fast_item, attr);
|
||||
Py_DECREF(seq_fast_item);
|
||||
}
|
||||
}
|
||||
/* May trigger error, check below */
|
||||
fill_format_sequence(data, seq_fast_item, attr);
|
||||
Py_DECREF(seq_fast_item);
|
||||
}
|
||||
}
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
ok = false;
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
ok = false;
|
||||
}
|
||||
|
||||
finally:
|
||||
finally:
|
||||
|
||||
Py_DECREF(seq_fast);
|
||||
}
|
||||
return ok;
|
||||
Py_DECREF(seq_fast);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int bpygpu_attr_fill(GPUVertBuf *buf, int id, PyObject *py_seq_data, const char *error_prefix)
|
||||
static int bpygpu_attr_fill(GPUVertBuf *buf,
|
||||
int id,
|
||||
PyObject *py_seq_data,
|
||||
const char *error_prefix)
|
||||
{
|
||||
if (id < 0 || id >= buf->format.attr_len) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"Format id %d out of range",
|
||||
id);
|
||||
return 0;
|
||||
}
|
||||
if (id < 0 || id >= buf->format.attr_len) {
|
||||
PyErr_Format(PyExc_ValueError, "Format id %d out of range", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (buf->data == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Can't fill, static buffer already in use");
|
||||
return 0;
|
||||
}
|
||||
if (buf->data == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "Can't fill, static buffer already in use");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!bpygpu_vertbuf_fill_impl(buf, (uint)id, py_seq_data, error_prefix)) {
|
||||
return 0;
|
||||
}
|
||||
if (!bpygpu_vertbuf_fill_impl(buf, (uint)id, py_seq_data, error_prefix)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name VertBuf Type
|
||||
* \{ */
|
||||
|
||||
static PyObject *bpygpu_VertBuf_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
|
||||
{
|
||||
struct {
|
||||
PyObject *py_fmt;
|
||||
uint len;
|
||||
} params;
|
||||
struct {
|
||||
PyObject *py_fmt;
|
||||
uint len;
|
||||
} params;
|
||||
|
||||
static const char *_keywords[] = {"format", "len", NULL};
|
||||
static _PyArg_Parser _parser = {"O!I:GPUVertBuf.__new__", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kwds, &_parser,
|
||||
&BPyGPUVertFormat_Type, ¶ms.py_fmt,
|
||||
¶ms.len))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"format", "len", NULL};
|
||||
static _PyArg_Parser _parser = {"O!I:GPUVertBuf.__new__", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kwds, &_parser, &BPyGPUVertFormat_Type, ¶ms.py_fmt, ¶ms.len)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const GPUVertFormat *fmt = &((BPyGPUVertFormat *)params.py_fmt)->fmt;
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(fmt);
|
||||
const GPUVertFormat *fmt = &((BPyGPUVertFormat *)params.py_fmt)->fmt;
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(fmt);
|
||||
|
||||
GPU_vertbuf_data_alloc(vbo, params.len);
|
||||
GPU_vertbuf_data_alloc(vbo, params.len);
|
||||
|
||||
return BPyGPUVertBuf_CreatePyObject(vbo);
|
||||
return BPyGPUVertBuf_CreatePyObject(vbo);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_VertBuf_attr_fill_doc,
|
||||
".. method:: attr_fill(id, data)\n"
|
||||
"\n"
|
||||
" Insert data into the buffer for a single attribute.\n"
|
||||
"\n"
|
||||
" :param id: Either the name or the id of the attribute.\n"
|
||||
" :type id: int or str\n"
|
||||
" :param data: Sequence of data that should be stored in the buffer\n"
|
||||
" :type data: sequence of values or tuples\n"
|
||||
);
|
||||
".. method:: attr_fill(id, data)\n"
|
||||
"\n"
|
||||
" Insert data into the buffer for a single attribute.\n"
|
||||
"\n"
|
||||
" :param id: Either the name or the id of the attribute.\n"
|
||||
" :type id: int or str\n"
|
||||
" :param data: Sequence of data that should be stored in the buffer\n"
|
||||
" :type data: sequence of values or tuples\n");
|
||||
static PyObject *bpygpu_VertBuf_attr_fill(BPyGPUVertBuf *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *data;
|
||||
PyObject *identifier;
|
||||
PyObject *data;
|
||||
PyObject *identifier;
|
||||
|
||||
static const char *_keywords[] = {"id", "data", NULL};
|
||||
static _PyArg_Parser _parser = {"OO:attr_fill", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kwds, &_parser,
|
||||
&identifier, &data))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"id", "data", NULL};
|
||||
static _PyArg_Parser _parser = {"OO:attr_fill", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, &identifier, &data)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int id;
|
||||
int id;
|
||||
|
||||
if (PyLong_Check(identifier)) {
|
||||
id = PyLong_AsLong(identifier);
|
||||
}
|
||||
else if (PyUnicode_Check(identifier)) {
|
||||
const char *name = PyUnicode_AsUTF8(identifier);
|
||||
id = GPU_vertformat_attr_id_get(&self->buf->format, name);
|
||||
if (id == -1) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Unknown attribute name");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"expected int or str type as identifier");
|
||||
return NULL;
|
||||
}
|
||||
if (PyLong_Check(identifier)) {
|
||||
id = PyLong_AsLong(identifier);
|
||||
}
|
||||
else if (PyUnicode_Check(identifier)) {
|
||||
const char *name = PyUnicode_AsUTF8(identifier);
|
||||
id = GPU_vertformat_attr_id_get(&self->buf->format, name);
|
||||
if (id == -1) {
|
||||
PyErr_SetString(PyExc_ValueError, "Unknown attribute name");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "expected int or str type as identifier");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!bpygpu_attr_fill(self->buf, id, data, "GPUVertBuf.attr_fill")) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!bpygpu_attr_fill(self->buf, id, data, "GPUVertBuf.attr_fill")) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
static struct PyMethodDef bpygpu_VertBuf_methods[] = {
|
||||
{"attr_fill", (PyCFunction) bpygpu_VertBuf_attr_fill,
|
||||
METH_VARARGS | METH_KEYWORDS, bpygpu_VertBuf_attr_fill_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"attr_fill",
|
||||
(PyCFunction)bpygpu_VertBuf_attr_fill,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpygpu_VertBuf_attr_fill_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
static void bpygpu_VertBuf_dealloc(BPyGPUVertBuf *self)
|
||||
{
|
||||
GPU_vertbuf_discard(self->buf);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
GPU_vertbuf_discard(self->buf);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(py_gpu_vertex_buffer_doc,
|
||||
".. class:: GPUVertBuf(len, format)\n"
|
||||
"\n"
|
||||
" Contains a VBO.\n"
|
||||
"\n"
|
||||
" :param len: Amount of vertices that will fit into this buffer.\n"
|
||||
" :type type: `int`\n"
|
||||
" :param format: Vertex format.\n"
|
||||
" :type buf: :class:`gpu.types.GPUVertFormat`\n"
|
||||
);
|
||||
".. class:: GPUVertBuf(len, format)\n"
|
||||
"\n"
|
||||
" Contains a VBO.\n"
|
||||
"\n"
|
||||
" :param len: Amount of vertices that will fit into this buffer.\n"
|
||||
" :type type: `int`\n"
|
||||
" :param format: Vertex format.\n"
|
||||
" :type buf: :class:`gpu.types.GPUVertFormat`\n");
|
||||
PyTypeObject BPyGPUVertBuf_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "GPUVertBuf",
|
||||
.tp_basicsize = sizeof(BPyGPUVertBuf),
|
||||
.tp_dealloc = (destructor)bpygpu_VertBuf_dealloc,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_doc = py_gpu_vertex_buffer_doc,
|
||||
.tp_methods = bpygpu_VertBuf_methods,
|
||||
.tp_new = bpygpu_VertBuf_new,
|
||||
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "GPUVertBuf",
|
||||
.tp_basicsize = sizeof(BPyGPUVertBuf),
|
||||
.tp_dealloc = (destructor)bpygpu_VertBuf_dealloc,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_doc = py_gpu_vertex_buffer_doc,
|
||||
.tp_methods = bpygpu_VertBuf_methods,
|
||||
.tp_new = bpygpu_VertBuf_new,
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public API
|
||||
* \{ */
|
||||
|
||||
PyObject *BPyGPUVertBuf_CreatePyObject(GPUVertBuf *buf)
|
||||
{
|
||||
BPyGPUVertBuf *self;
|
||||
BPyGPUVertBuf *self;
|
||||
|
||||
self = PyObject_New(BPyGPUVertBuf, &BPyGPUVertBuf_Type);
|
||||
self->buf = buf;
|
||||
self = PyObject_New(BPyGPUVertBuf, &BPyGPUVertBuf_Type);
|
||||
self->buf = buf;
|
||||
|
||||
return (PyObject *)self;
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
|
||||
extern PyTypeObject BPyGPUVertBuf_Type;
|
||||
|
||||
#define BPyGPUVertBuf_Check(v) (Py_TYPE(v) == &BPyGPUVertBuf_Type)
|
||||
#define BPyGPUVertBuf_Check(v) (Py_TYPE(v) == &BPyGPUVertBuf_Type)
|
||||
|
||||
typedef struct BPyGPUVertBuf {
|
||||
PyObject_VAR_HEAD
|
||||
/* The buf is owned, we may support thin wrapped batches later. */
|
||||
struct GPUVertBuf *buf;
|
||||
PyObject_VAR_HEAD
|
||||
/* The buf is owned, we may support thin wrapped batches later. */
|
||||
struct GPUVertBuf *buf;
|
||||
} BPyGPUVertBuf;
|
||||
|
||||
PyObject *BPyGPUVertBuf_CreatePyObject(struct GPUVertBuf *vbo) ATTR_NONNULL(1);
|
||||
|
||||
@@ -33,15 +33,15 @@
|
||||
#include "gpu_py_vertex_format.h" /* own include */
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
/* big endian */
|
||||
# define MAKE_ID2(c, d) ((c) << 8 | (d))
|
||||
# define MAKE_ID3(a, b, c) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 )
|
||||
# define MAKE_ID4(a, b, c, d) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d) )
|
||||
/* big endian */
|
||||
# define MAKE_ID2(c, d) ((c) << 8 | (d))
|
||||
# define MAKE_ID3(a, b, c) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8)
|
||||
# define MAKE_ID4(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d))
|
||||
#else
|
||||
/* little endian */
|
||||
# define MAKE_ID2(c, d) ((d) << 8 | (c))
|
||||
# define MAKE_ID3(a, b, c) ( (int)(c) << 16 | (b) << 8 | (a) )
|
||||
# define MAKE_ID4(a, b, c, d) ( (int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a) )
|
||||
/* little endian */
|
||||
# define MAKE_ID2(c, d) ((d) << 8 | (c))
|
||||
# define MAKE_ID3(a, b, c) ((int)(c) << 16 | (b) << 8 | (a))
|
||||
# define MAKE_ID4(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -52,205 +52,211 @@
|
||||
|
||||
static int bpygpu_parse_component_type(const char *str, int length)
|
||||
{
|
||||
if (length == 2) {
|
||||
switch (*((ushort *)str)) {
|
||||
case MAKE_ID2('I', '8'): return GPU_COMP_I8;
|
||||
case MAKE_ID2('U', '8'): return GPU_COMP_U8;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else if (length == 3) {
|
||||
switch (*((uint *)str)) {
|
||||
case MAKE_ID3('I', '1', '6'): return GPU_COMP_I16;
|
||||
case MAKE_ID3('U', '1', '6'): return GPU_COMP_U16;
|
||||
case MAKE_ID3('I', '3', '2'): return GPU_COMP_I32;
|
||||
case MAKE_ID3('U', '3', '2'): return GPU_COMP_U32;
|
||||
case MAKE_ID3('F', '3', '2'): return GPU_COMP_F32;
|
||||
case MAKE_ID3('I', '1', '0'): return GPU_COMP_I10;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
if (length == 2) {
|
||||
switch (*((ushort *)str)) {
|
||||
case MAKE_ID2('I', '8'):
|
||||
return GPU_COMP_I8;
|
||||
case MAKE_ID2('U', '8'):
|
||||
return GPU_COMP_U8;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (length == 3) {
|
||||
switch (*((uint *)str)) {
|
||||
case MAKE_ID3('I', '1', '6'):
|
||||
return GPU_COMP_I16;
|
||||
case MAKE_ID3('U', '1', '6'):
|
||||
return GPU_COMP_U16;
|
||||
case MAKE_ID3('I', '3', '2'):
|
||||
return GPU_COMP_I32;
|
||||
case MAKE_ID3('U', '3', '2'):
|
||||
return GPU_COMP_U32;
|
||||
case MAKE_ID3('F', '3', '2'):
|
||||
return GPU_COMP_F32;
|
||||
case MAKE_ID3('I', '1', '0'):
|
||||
return GPU_COMP_I10;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int bpygpu_parse_fetch_mode(const char *str, int length)
|
||||
{
|
||||
#define MATCH_ID(id) \
|
||||
if (length == strlen(STRINGIFY(id))) { \
|
||||
if (STREQ(str, STRINGIFY(id))) { \
|
||||
return GPU_FETCH_##id; \
|
||||
} \
|
||||
} ((void)0)
|
||||
if (length == strlen(STRINGIFY(id))) { \
|
||||
if (STREQ(str, STRINGIFY(id))) { \
|
||||
return GPU_FETCH_##id; \
|
||||
} \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
MATCH_ID(FLOAT);
|
||||
MATCH_ID(INT);
|
||||
MATCH_ID(INT_TO_FLOAT_UNIT);
|
||||
MATCH_ID(INT_TO_FLOAT);
|
||||
MATCH_ID(FLOAT);
|
||||
MATCH_ID(INT);
|
||||
MATCH_ID(INT_TO_FLOAT_UNIT);
|
||||
MATCH_ID(INT_TO_FLOAT);
|
||||
#undef MATCH_ID
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int bpygpu_ParseVertCompType(PyObject *o, void *p)
|
||||
{
|
||||
Py_ssize_t length;
|
||||
const char *str = _PyUnicode_AsStringAndSize(o, &length);
|
||||
Py_ssize_t length;
|
||||
const char *str = _PyUnicode_AsStringAndSize(o, &length);
|
||||
|
||||
if (str == NULL) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"expected a string, got %s",
|
||||
Py_TYPE(o)->tp_name);
|
||||
return 0;
|
||||
}
|
||||
if (str == NULL) {
|
||||
PyErr_Format(PyExc_ValueError, "expected a string, got %s", Py_TYPE(o)->tp_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int comp_type = bpygpu_parse_component_type(str, length);
|
||||
if (comp_type == -1) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"unkown component type: '%s",
|
||||
str);
|
||||
return 0;
|
||||
}
|
||||
int comp_type = bpygpu_parse_component_type(str, length);
|
||||
if (comp_type == -1) {
|
||||
PyErr_Format(PyExc_ValueError, "unkown component type: '%s", str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*((GPUVertCompType *)p) = comp_type;
|
||||
return 1;
|
||||
*((GPUVertCompType *)p) = comp_type;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bpygpu_ParseVertFetchMode(PyObject *o, void *p)
|
||||
{
|
||||
Py_ssize_t length;
|
||||
const char *str = _PyUnicode_AsStringAndSize(o, &length);
|
||||
Py_ssize_t length;
|
||||
const char *str = _PyUnicode_AsStringAndSize(o, &length);
|
||||
|
||||
if (str == NULL) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"expected a string, got %s",
|
||||
Py_TYPE(o)->tp_name);
|
||||
return 0;
|
||||
}
|
||||
if (str == NULL) {
|
||||
PyErr_Format(PyExc_ValueError, "expected a string, got %s", Py_TYPE(o)->tp_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fetch_mode = bpygpu_parse_fetch_mode(str, length);
|
||||
if (fetch_mode == -1) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"unknown type literal: '%s'",
|
||||
str);
|
||||
return 0;
|
||||
}
|
||||
int fetch_mode = bpygpu_parse_fetch_mode(str, length);
|
||||
if (fetch_mode == -1) {
|
||||
PyErr_Format(PyExc_ValueError, "unknown type literal: '%s'", str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
(*(GPUVertFetchMode *)p) = fetch_mode;
|
||||
return 1;
|
||||
(*(GPUVertFetchMode *)p) = fetch_mode;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name VertFormat Type
|
||||
* \{ */
|
||||
|
||||
static PyObject *bpygpu_VertFormat_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
|
||||
{
|
||||
if (PyTuple_GET_SIZE(args) || (kwds && PyDict_Size(kwds))) {
|
||||
PyErr_SetString(PyExc_ValueError, "This function takes no arguments");
|
||||
return NULL;
|
||||
}
|
||||
return BPyGPUVertFormat_CreatePyObject(NULL);
|
||||
if (PyTuple_GET_SIZE(args) || (kwds && PyDict_Size(kwds))) {
|
||||
PyErr_SetString(PyExc_ValueError, "This function takes no arguments");
|
||||
return NULL;
|
||||
}
|
||||
return BPyGPUVertFormat_CreatePyObject(NULL);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_VertFormat_attr_add_doc,
|
||||
".. method:: attr_add(id, comp_type, len, fetch_mode)\n"
|
||||
"\n"
|
||||
" Add a new attribute to the format.\n"
|
||||
"\n"
|
||||
" :param id: Name the attribute. Often `position`, `normal`, ...\n"
|
||||
" :type id: str\n"
|
||||
" :param comp_type: The data type that will be used store the value in memory.\n"
|
||||
" Possible values are `I8`, `U8`, `I16`, `U16`, `I32`, `U32`, `F32` and `I10`.\n"
|
||||
" :type comp_type: `str`\n"
|
||||
" :param len: How many individual values the attribute consists of (e.g. 2 for uv coordinates).\n"
|
||||
" :type len: int\n"
|
||||
" :param fetch_mode: How values from memory will be converted when used in the shader.\n"
|
||||
" This is mainly useful for memory optimizations when you want to store values with reduced precision.\n"
|
||||
" E.g. you can store a float in only 1 byte but it will be converted to a normal 4 byte float when used.\n"
|
||||
" Possible values are `FLOAT`, `INT`, `INT_TO_FLOAT_UNIT` and `INT_TO_FLOAT`.\n"
|
||||
" :type fetch_mode: `str`\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpygpu_VertFormat_attr_add_doc,
|
||||
".. method:: attr_add(id, comp_type, len, fetch_mode)\n"
|
||||
"\n"
|
||||
" Add a new attribute to the format.\n"
|
||||
"\n"
|
||||
" :param id: Name the attribute. Often `position`, `normal`, ...\n"
|
||||
" :type id: str\n"
|
||||
" :param comp_type: The data type that will be used store the value in memory.\n"
|
||||
" Possible values are `I8`, `U8`, `I16`, `U16`, `I32`, `U32`, `F32` and `I10`.\n"
|
||||
" :type comp_type: `str`\n"
|
||||
" :param len: How many individual values the attribute consists of (e.g. 2 for uv "
|
||||
"coordinates).\n"
|
||||
" :type len: int\n"
|
||||
" :param fetch_mode: How values from memory will be converted when used in the shader.\n"
|
||||
" This is mainly useful for memory optimizations when you want to store values with "
|
||||
"reduced precision.\n"
|
||||
" E.g. you can store a float in only 1 byte but it will be converted to a normal 4 byte "
|
||||
"float when used.\n"
|
||||
" Possible values are `FLOAT`, `INT`, `INT_TO_FLOAT_UNIT` and `INT_TO_FLOAT`.\n"
|
||||
" :type fetch_mode: `str`\n");
|
||||
static PyObject *bpygpu_VertFormat_attr_add(BPyGPUVertFormat *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
struct {
|
||||
const char *id;
|
||||
GPUVertCompType comp_type;
|
||||
uint len;
|
||||
GPUVertFetchMode fetch_mode;
|
||||
} params;
|
||||
struct {
|
||||
const char *id;
|
||||
GPUVertCompType comp_type;
|
||||
uint len;
|
||||
GPUVertFetchMode fetch_mode;
|
||||
} params;
|
||||
|
||||
if (self->fmt.attr_len == GPU_VERT_ATTR_MAX_LEN) {
|
||||
PyErr_SetString(PyExc_ValueError, "Maxumum attr reached " STRINGIFY(GPU_VERT_ATTR_MAX_LEN));
|
||||
return NULL;
|
||||
}
|
||||
if (self->fmt.attr_len == GPU_VERT_ATTR_MAX_LEN) {
|
||||
PyErr_SetString(PyExc_ValueError, "Maxumum attr reached " STRINGIFY(GPU_VERT_ATTR_MAX_LEN));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *_keywords[] = {"id", "comp_type", "len", "fetch_mode", NULL};
|
||||
static _PyArg_Parser _parser = {"$sO&IO&:attr_add", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kwds, &_parser,
|
||||
¶ms.id,
|
||||
bpygpu_ParseVertCompType, ¶ms.comp_type,
|
||||
¶ms.len,
|
||||
bpygpu_ParseVertFetchMode, ¶ms.fetch_mode))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"id", "comp_type", "len", "fetch_mode", NULL};
|
||||
static _PyArg_Parser _parser = {"$sO&IO&:attr_add", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args,
|
||||
kwds,
|
||||
&_parser,
|
||||
¶ms.id,
|
||||
bpygpu_ParseVertCompType,
|
||||
¶ms.comp_type,
|
||||
¶ms.len,
|
||||
bpygpu_ParseVertFetchMode,
|
||||
¶ms.fetch_mode)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint attr_id = GPU_vertformat_attr_add(&self->fmt, params.id, params.comp_type, params.len, params.fetch_mode);
|
||||
return PyLong_FromLong(attr_id);
|
||||
uint attr_id = GPU_vertformat_attr_add(
|
||||
&self->fmt, params.id, params.comp_type, params.len, params.fetch_mode);
|
||||
return PyLong_FromLong(attr_id);
|
||||
}
|
||||
|
||||
static struct PyMethodDef bpygpu_VertFormat_methods[] = {
|
||||
{"attr_add", (PyCFunction)bpygpu_VertFormat_attr_add,
|
||||
METH_VARARGS | METH_KEYWORDS, bpygpu_VertFormat_attr_add_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"attr_add",
|
||||
(PyCFunction)bpygpu_VertFormat_attr_add,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpygpu_VertFormat_attr_add_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
|
||||
static void bpygpu_VertFormat_dealloc(BPyGPUVertFormat *self)
|
||||
{
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpygpu_VertFormat_doc,
|
||||
".. class:: GPUVertFormat()\n"
|
||||
"\n"
|
||||
" This object contains information about the structure of a vertex buffer.\n"
|
||||
);
|
||||
".. class:: GPUVertFormat()\n"
|
||||
"\n"
|
||||
" This object contains information about the structure of a vertex buffer.\n");
|
||||
PyTypeObject BPyGPUVertFormat_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "GPUVertFormat",
|
||||
.tp_basicsize = sizeof(BPyGPUVertFormat),
|
||||
.tp_dealloc = (destructor)bpygpu_VertFormat_dealloc,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_doc = bpygpu_VertFormat_doc,
|
||||
.tp_methods = bpygpu_VertFormat_methods,
|
||||
.tp_new = bpygpu_VertFormat_new,
|
||||
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "GPUVertFormat",
|
||||
.tp_basicsize = sizeof(BPyGPUVertFormat),
|
||||
.tp_dealloc = (destructor)bpygpu_VertFormat_dealloc,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_doc = bpygpu_VertFormat_doc,
|
||||
.tp_methods = bpygpu_VertFormat_methods,
|
||||
.tp_new = bpygpu_VertFormat_new,
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public API
|
||||
* \{ */
|
||||
|
||||
PyObject *BPyGPUVertFormat_CreatePyObject(GPUVertFormat *fmt)
|
||||
{
|
||||
BPyGPUVertFormat *self;
|
||||
BPyGPUVertFormat *self;
|
||||
|
||||
self = PyObject_New(BPyGPUVertFormat, &BPyGPUVertFormat_Type);
|
||||
if (fmt) {
|
||||
self->fmt = *fmt;
|
||||
}
|
||||
else {
|
||||
memset(&self->fmt, 0, sizeof(self->fmt));
|
||||
}
|
||||
self = PyObject_New(BPyGPUVertFormat, &BPyGPUVertFormat_Type);
|
||||
if (fmt) {
|
||||
self->fmt = *fmt;
|
||||
}
|
||||
else {
|
||||
memset(&self->fmt, 0, sizeof(self->fmt));
|
||||
}
|
||||
|
||||
return (PyObject *)self;
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -25,11 +25,10 @@
|
||||
|
||||
extern PyTypeObject BPyGPUVertFormat_Type;
|
||||
|
||||
#define BPyGPUVertFormat_Check(v) (Py_TYPE(v) == &BPyGPUVertFormat_Type)
|
||||
#define BPyGPUVertFormat_Check(v) (Py_TYPE(v) == &BPyGPUVertFormat_Type)
|
||||
|
||||
typedef struct BPyGPUVertFormat {
|
||||
PyObject_VAR_HEAD
|
||||
struct GPUVertFormat fmt;
|
||||
PyObject_VAR_HEAD struct GPUVertFormat fmt;
|
||||
} BPyGPUVertFormat;
|
||||
|
||||
PyObject *BPyGPUVertFormat_CreatePyObject(struct GPUVertFormat *fmt);
|
||||
|
||||
@@ -19,293 +19,293 @@
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
..
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../blenloader
|
||||
../../blentranslation
|
||||
../../editors/include
|
||||
../../gpu
|
||||
../../imbuf
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../../../intern/clog
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/opencolorio
|
||||
..
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../blenloader
|
||||
../../blentranslation
|
||||
../../editors/include
|
||||
../../gpu
|
||||
../../imbuf
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../../../intern/clog
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/opencolorio
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
bpy.c
|
||||
bpy_app.c
|
||||
bpy_app_alembic.c
|
||||
bpy_app_build_options.c
|
||||
bpy_app_ffmpeg.c
|
||||
bpy_app_handlers.c
|
||||
bpy_app_icons.c
|
||||
bpy_app_ocio.c
|
||||
bpy_app_oiio.c
|
||||
bpy_app_opensubdiv.c
|
||||
bpy_app_openvdb.c
|
||||
bpy_app_sdl.c
|
||||
bpy_app_timers.c
|
||||
bpy_app_translations.c
|
||||
bpy_capi_utils.c
|
||||
bpy_driver.c
|
||||
bpy_gizmo_wrap.c
|
||||
bpy_interface.c
|
||||
bpy_interface_atexit.c
|
||||
bpy_intern_string.c
|
||||
bpy_library_load.c
|
||||
bpy_library_write.c
|
||||
bpy_msgbus.c
|
||||
bpy_operator.c
|
||||
bpy_operator_wrap.c
|
||||
bpy_path.c
|
||||
bpy_props.c
|
||||
bpy_rna.c
|
||||
bpy_rna_anim.c
|
||||
bpy_rna_array.c
|
||||
bpy_rna_callback.c
|
||||
bpy_rna_driver.c
|
||||
bpy_rna_gizmo.c
|
||||
bpy_rna_id_collection.c
|
||||
bpy_traceback.c
|
||||
bpy_utils_previews.c
|
||||
bpy_utils_units.c
|
||||
stubs.c
|
||||
bpy.c
|
||||
bpy_app.c
|
||||
bpy_app_alembic.c
|
||||
bpy_app_build_options.c
|
||||
bpy_app_ffmpeg.c
|
||||
bpy_app_handlers.c
|
||||
bpy_app_icons.c
|
||||
bpy_app_ocio.c
|
||||
bpy_app_oiio.c
|
||||
bpy_app_opensubdiv.c
|
||||
bpy_app_openvdb.c
|
||||
bpy_app_sdl.c
|
||||
bpy_app_timers.c
|
||||
bpy_app_translations.c
|
||||
bpy_capi_utils.c
|
||||
bpy_driver.c
|
||||
bpy_gizmo_wrap.c
|
||||
bpy_interface.c
|
||||
bpy_interface_atexit.c
|
||||
bpy_intern_string.c
|
||||
bpy_library_load.c
|
||||
bpy_library_write.c
|
||||
bpy_msgbus.c
|
||||
bpy_operator.c
|
||||
bpy_operator_wrap.c
|
||||
bpy_path.c
|
||||
bpy_props.c
|
||||
bpy_rna.c
|
||||
bpy_rna_anim.c
|
||||
bpy_rna_array.c
|
||||
bpy_rna_callback.c
|
||||
bpy_rna_driver.c
|
||||
bpy_rna_gizmo.c
|
||||
bpy_rna_id_collection.c
|
||||
bpy_traceback.c
|
||||
bpy_utils_previews.c
|
||||
bpy_utils_units.c
|
||||
stubs.c
|
||||
|
||||
bpy.h
|
||||
bpy_app.h
|
||||
bpy_app_alembic.h
|
||||
bpy_app_build_options.h
|
||||
bpy_app_ffmpeg.h
|
||||
bpy_app_handlers.h
|
||||
bpy_app_icons.h
|
||||
bpy_app_ocio.h
|
||||
bpy_app_oiio.h
|
||||
bpy_app_opensubdiv.h
|
||||
bpy_app_openvdb.h
|
||||
bpy_app_sdl.h
|
||||
bpy_app_timers.h
|
||||
bpy_app_translations.h
|
||||
bpy_capi_utils.h
|
||||
bpy_driver.h
|
||||
bpy_gizmo_wrap.h
|
||||
bpy_intern_string.h
|
||||
bpy_library.h
|
||||
bpy_msgbus.h
|
||||
bpy_operator.h
|
||||
bpy_operator_wrap.h
|
||||
bpy_path.h
|
||||
bpy_props.h
|
||||
bpy_rna.h
|
||||
bpy_rna_anim.h
|
||||
bpy_rna_callback.h
|
||||
bpy_rna_driver.h
|
||||
bpy_rna_gizmo.h
|
||||
bpy_rna_id_collection.h
|
||||
bpy_traceback.h
|
||||
bpy_utils_previews.h
|
||||
bpy_utils_units.h
|
||||
../BPY_extern.h
|
||||
../BPY_extern_clog.h
|
||||
bpy.h
|
||||
bpy_app.h
|
||||
bpy_app_alembic.h
|
||||
bpy_app_build_options.h
|
||||
bpy_app_ffmpeg.h
|
||||
bpy_app_handlers.h
|
||||
bpy_app_icons.h
|
||||
bpy_app_ocio.h
|
||||
bpy_app_oiio.h
|
||||
bpy_app_opensubdiv.h
|
||||
bpy_app_openvdb.h
|
||||
bpy_app_sdl.h
|
||||
bpy_app_timers.h
|
||||
bpy_app_translations.h
|
||||
bpy_capi_utils.h
|
||||
bpy_driver.h
|
||||
bpy_gizmo_wrap.h
|
||||
bpy_intern_string.h
|
||||
bpy_library.h
|
||||
bpy_msgbus.h
|
||||
bpy_operator.h
|
||||
bpy_operator_wrap.h
|
||||
bpy_path.h
|
||||
bpy_props.h
|
||||
bpy_rna.h
|
||||
bpy_rna_anim.h
|
||||
bpy_rna_callback.h
|
||||
bpy_rna_driver.h
|
||||
bpy_rna_gizmo.h
|
||||
bpy_rna_id_collection.h
|
||||
bpy_traceback.h
|
||||
bpy_utils_previews.h
|
||||
bpy_utils_units.h
|
||||
../BPY_extern.h
|
||||
../BPY_extern_clog.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
bf_editor_animation
|
||||
bf_editor_interface
|
||||
bf_editor_space_api
|
||||
bf_python_gpu
|
||||
bf_editor_animation
|
||||
bf_editor_interface
|
||||
bf_editor_space_api
|
||||
bf_python_gpu
|
||||
)
|
||||
|
||||
# only to check if buildinfo is available
|
||||
if(WITH_BUILDINFO)
|
||||
add_definitions(-DBUILD_DATE)
|
||||
add_definitions(-DBUILD_DATE)
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON_MODULE)
|
||||
add_definitions(-DWITH_PYTHON_MODULE)
|
||||
add_definitions(-DWITH_PYTHON_MODULE)
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON_SAFETY)
|
||||
add_definitions(-DWITH_PYTHON_SAFETY)
|
||||
add_definitions(-DWITH_PYTHON_SAFETY)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
if(WITH_AUDASPACE)
|
||||
add_definitions(-DWITH_AUDASPACE)
|
||||
add_definitions(-DWITH_AUDASPACE)
|
||||
endif()
|
||||
|
||||
if(WITH_BULLET)
|
||||
add_definitions(-DWITH_BULLET)
|
||||
add_definitions(-DWITH_BULLET)
|
||||
endif()
|
||||
|
||||
if(WITH_CODEC_AVI)
|
||||
add_definitions(-DWITH_AVI)
|
||||
add_definitions(-DWITH_AVI)
|
||||
endif()
|
||||
|
||||
if(WITH_CODEC_FFMPEG)
|
||||
list(APPEND INC_SYS
|
||||
${FFMPEG_INCLUDE_DIRS}
|
||||
)
|
||||
add_definitions(-DWITH_FFMPEG)
|
||||
list(APPEND INC_SYS
|
||||
${FFMPEG_INCLUDE_DIRS}
|
||||
)
|
||||
add_definitions(-DWITH_FFMPEG)
|
||||
endif()
|
||||
|
||||
if(WITH_CODEC_SNDFILE)
|
||||
add_definitions(-DWITH_SNDFILE)
|
||||
add_definitions(-DWITH_SNDFILE)
|
||||
endif()
|
||||
|
||||
if(WITH_COMPOSITOR)
|
||||
add_definitions(-DWITH_COMPOSITOR)
|
||||
add_definitions(-DWITH_COMPOSITOR)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES)
|
||||
list(APPEND INC
|
||||
../../../../intern/cycles/blender
|
||||
)
|
||||
list(APPEND LIB
|
||||
bf_intern_cycles
|
||||
)
|
||||
add_definitions(-DWITH_CYCLES)
|
||||
list(APPEND INC
|
||||
../../../../intern/cycles/blender
|
||||
)
|
||||
list(APPEND LIB
|
||||
bf_intern_cycles
|
||||
)
|
||||
add_definitions(-DWITH_CYCLES)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_OSL)
|
||||
add_definitions(-DWITH_CYCLES_OSL)
|
||||
add_definitions(-DWITH_CYCLES_OSL)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_EMBREE)
|
||||
add_definitions(-DWITH_CYCLES_EMBREE)
|
||||
add_definitions(-DWITH_CYCLES_EMBREE)
|
||||
endif()
|
||||
|
||||
if(WITH_FREESTYLE)
|
||||
list(APPEND INC
|
||||
../../freestyle/intern/python
|
||||
)
|
||||
add_definitions(-DWITH_FREESTYLE)
|
||||
list(APPEND INC
|
||||
../../freestyle/intern/python
|
||||
)
|
||||
add_definitions(-DWITH_FREESTYLE)
|
||||
endif()
|
||||
|
||||
if(WITH_IMAGE_CINEON)
|
||||
add_definitions(-DWITH_CINEON)
|
||||
add_definitions(-DWITH_CINEON)
|
||||
endif()
|
||||
|
||||
if(WITH_IMAGE_DDS)
|
||||
add_definitions(-DWITH_DDS)
|
||||
add_definitions(-DWITH_DDS)
|
||||
endif()
|
||||
|
||||
if(WITH_IMAGE_HDR)
|
||||
add_definitions(-DWITH_HDR)
|
||||
add_definitions(-DWITH_HDR)
|
||||
endif()
|
||||
|
||||
if(WITH_IMAGE_OPENEXR)
|
||||
add_definitions(-DWITH_OPENEXR)
|
||||
add_definitions(-DWITH_OPENEXR)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENIMAGEIO)
|
||||
add_definitions(-DWITH_OPENIMAGEIO)
|
||||
add_definitions(-DWITH_OPENIMAGEIO)
|
||||
endif()
|
||||
|
||||
if(WITH_IMAGE_OPENJPEG)
|
||||
add_definitions(-DWITH_OPENJPEG)
|
||||
add_definitions(-DWITH_OPENJPEG)
|
||||
endif()
|
||||
|
||||
if(WITH_IMAGE_TIFF)
|
||||
add_definitions(-DWITH_TIFF)
|
||||
add_definitions(-DWITH_TIFF)
|
||||
endif()
|
||||
|
||||
if(WITH_INPUT_NDOF)
|
||||
add_definitions(-DWITH_INPUT_NDOF)
|
||||
add_definitions(-DWITH_INPUT_NDOF)
|
||||
endif()
|
||||
|
||||
if(WITH_INTERNATIONAL)
|
||||
add_definitions(-DWITH_INTERNATIONAL)
|
||||
add_definitions(-DWITH_INTERNATIONAL)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENAL)
|
||||
add_definitions(-DWITH_OPENAL)
|
||||
add_definitions(-DWITH_OPENAL)
|
||||
endif()
|
||||
|
||||
if(WITH_SDL)
|
||||
list(APPEND INC_SYS
|
||||
${SDL_INCLUDE_DIR}
|
||||
)
|
||||
add_definitions(-DWITH_SDL)
|
||||
list(APPEND INC_SYS
|
||||
${SDL_INCLUDE_DIR}
|
||||
)
|
||||
add_definitions(-DWITH_SDL)
|
||||
endif()
|
||||
|
||||
if(WITH_SDL_DYNLOAD)
|
||||
list(APPEND INC
|
||||
../../../../extern/sdlew/include
|
||||
)
|
||||
add_definitions(-DWITH_SDL_DYNLOAD)
|
||||
list(APPEND INC
|
||||
../../../../extern/sdlew/include
|
||||
)
|
||||
add_definitions(-DWITH_SDL_DYNLOAD)
|
||||
endif()
|
||||
|
||||
if(WITH_JACK)
|
||||
add_definitions(-DWITH_JACK)
|
||||
add_definitions(-DWITH_JACK)
|
||||
endif()
|
||||
|
||||
if(WITH_LIBMV)
|
||||
add_definitions(-DWITH_LIBMV)
|
||||
add_definitions(-DWITH_LIBMV)
|
||||
endif()
|
||||
|
||||
if(WITH_MOD_FLUID)
|
||||
add_definitions(-DWITH_MOD_FLUID)
|
||||
add_definitions(-DWITH_MOD_FLUID)
|
||||
endif()
|
||||
|
||||
if(WITH_MOD_OCEANSIM)
|
||||
add_definitions(-DWITH_OCEANSIM)
|
||||
add_definitions(-DWITH_OCEANSIM)
|
||||
endif()
|
||||
|
||||
if(WITH_MOD_REMESH)
|
||||
add_definitions(-DWITH_MOD_REMESH)
|
||||
add_definitions(-DWITH_MOD_REMESH)
|
||||
endif()
|
||||
|
||||
if(WITH_MOD_SMOKE)
|
||||
add_definitions(-DWITH_SMOKE)
|
||||
add_definitions(-DWITH_SMOKE)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLLADA)
|
||||
add_definitions(-DWITH_COLLADA)
|
||||
add_definitions(-DWITH_COLLADA)
|
||||
endif()
|
||||
|
||||
if(WITH_ALEMBIC)
|
||||
add_definitions(-DWITH_ALEMBIC)
|
||||
add_definitions(-DWITH_ALEMBIC)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
add_definitions(-DWITH_OCIO)
|
||||
add_definitions(-DWITH_OCIO)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENVDB)
|
||||
add_definitions(-DWITH_OPENVDB)
|
||||
list(APPEND INC
|
||||
../../../../intern/openvdb
|
||||
)
|
||||
add_definitions(-DWITH_OPENVDB)
|
||||
list(APPEND INC
|
||||
../../../../intern/openvdb
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_ALEMBIC)
|
||||
add_definitions(-DWITH_ALEMBIC)
|
||||
list(APPEND INC
|
||||
../../alembic
|
||||
)
|
||||
add_definitions(-DWITH_ALEMBIC)
|
||||
list(APPEND INC
|
||||
../../alembic
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENIMAGEIO)
|
||||
add_definitions(-DWITH_OPENIMAGEIO)
|
||||
list(APPEND INC
|
||||
../../imbuf/intern/oiio
|
||||
)
|
||||
add_definitions(-DWITH_OPENIMAGEIO)
|
||||
list(APPEND INC
|
||||
../../imbuf/intern/oiio
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV)
|
||||
add_definitions(-DWITH_OPENSUBDIV)
|
||||
list(APPEND INC
|
||||
../../../../intern/opensubdiv
|
||||
)
|
||||
add_definitions(-DWITH_OPENSUBDIV)
|
||||
list(APPEND INC
|
||||
../../../../intern/opensubdiv
|
||||
)
|
||||
endif()
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
@@ -61,320 +61,347 @@
|
||||
PyObject *bpy_package_py = NULL;
|
||||
|
||||
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"
|
||||
);
|
||||
".. 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");
|
||||
static PyObject *bpy_script_paths(PyObject *UNUSED(self))
|
||||
{
|
||||
PyObject *ret = PyTuple_New(2);
|
||||
PyObject *item;
|
||||
const char *path;
|
||||
PyObject *ret = PyTuple_New(2);
|
||||
PyObject *item;
|
||||
const char *path;
|
||||
|
||||
path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, NULL);
|
||||
item = PyC_UnicodeFromByte(path ? path : "");
|
||||
BLI_assert(item != NULL);
|
||||
PyTuple_SET_ITEM(ret, 0, item);
|
||||
path = BKE_appdir_folder_id(BLENDER_USER_SCRIPTS, NULL);
|
||||
item = PyC_UnicodeFromByte(path ? path : "");
|
||||
BLI_assert(item != NULL);
|
||||
PyTuple_SET_ITEM(ret, 1, item);
|
||||
path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, NULL);
|
||||
item = PyC_UnicodeFromByte(path ? path : "");
|
||||
BLI_assert(item != NULL);
|
||||
PyTuple_SET_ITEM(ret, 0, item);
|
||||
path = BKE_appdir_folder_id(BLENDER_USER_SCRIPTS, NULL);
|
||||
item = PyC_UnicodeFromByte(path ? path : "");
|
||||
BLI_assert(item != NULL);
|
||||
PyTuple_SET_ITEM(ret, 1, item);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src)
|
||||
{
|
||||
PyList_APPEND((PyObject *)userdata, PyC_UnicodeFromByte(path_src));
|
||||
return false; /* never edits the path */
|
||||
PyList_APPEND((PyObject *)userdata, PyC_UnicodeFromByte(path_src));
|
||||
return false; /* never edits the path */
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_blend_paths_doc,
|
||||
".. function:: blend_paths(absolute=False, packed=False, local=False)\n"
|
||||
"\n"
|
||||
" Returns a list of paths to external files referenced by the loaded .blend file.\n"
|
||||
"\n"
|
||||
" :arg absolute: When true the paths returned are made absolute.\n"
|
||||
" :type absolute: boolean\n"
|
||||
" :arg packed: When true skip file paths for packed data.\n"
|
||||
" :type packed: boolean\n"
|
||||
" :arg local: When true skip linked library paths.\n"
|
||||
" :type local: boolean\n"
|
||||
" :return: path list.\n"
|
||||
" :rtype: list of strings\n"
|
||||
);
|
||||
".. function:: blend_paths(absolute=False, packed=False, local=False)\n"
|
||||
"\n"
|
||||
" Returns a list of paths to external files referenced by the loaded .blend file.\n"
|
||||
"\n"
|
||||
" :arg absolute: When true the paths returned are made absolute.\n"
|
||||
" :type absolute: boolean\n"
|
||||
" :arg packed: When true skip file paths for packed data.\n"
|
||||
" :type packed: boolean\n"
|
||||
" :arg local: When true skip linked library paths.\n"
|
||||
" :type local: boolean\n"
|
||||
" :return: path list.\n"
|
||||
" :rtype: list of strings\n");
|
||||
static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
int flag = 0;
|
||||
PyObject *list;
|
||||
int flag = 0;
|
||||
PyObject *list;
|
||||
|
||||
bool absolute = false;
|
||||
bool packed = false;
|
||||
bool local = false;
|
||||
bool absolute = false;
|
||||
bool packed = false;
|
||||
bool local = false;
|
||||
|
||||
static const char *_keywords[] = {"absolute", "packed", "local", NULL};
|
||||
static _PyArg_Parser _parser = {"|O&O&O&:blend_paths", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
PyC_ParseBool, &absolute,
|
||||
PyC_ParseBool, &packed,
|
||||
PyC_ParseBool, &local))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"absolute", "packed", "local", NULL};
|
||||
static _PyArg_Parser _parser = {"|O&O&O&:blend_paths", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args,
|
||||
kw,
|
||||
&_parser,
|
||||
PyC_ParseBool,
|
||||
&absolute,
|
||||
PyC_ParseBool,
|
||||
&packed,
|
||||
PyC_ParseBool,
|
||||
&local)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (absolute) {
|
||||
flag |= BKE_BPATH_TRAVERSE_ABS;
|
||||
}
|
||||
if (!packed) {
|
||||
flag |= BKE_BPATH_TRAVERSE_SKIP_PACKED;
|
||||
}
|
||||
if (local) {
|
||||
flag |= BKE_BPATH_TRAVERSE_SKIP_LIBRARY;
|
||||
}
|
||||
if (absolute) {
|
||||
flag |= BKE_BPATH_TRAVERSE_ABS;
|
||||
}
|
||||
if (!packed) {
|
||||
flag |= BKE_BPATH_TRAVERSE_SKIP_PACKED;
|
||||
}
|
||||
if (local) {
|
||||
flag |= BKE_BPATH_TRAVERSE_SKIP_LIBRARY;
|
||||
}
|
||||
|
||||
list = PyList_New(0);
|
||||
list = PyList_New(0);
|
||||
|
||||
BKE_bpath_traverse_main(G_MAIN, bpy_blend_paths_visit_cb, flag, (void *)list);
|
||||
BKE_bpath_traverse_main(G_MAIN, bpy_blend_paths_visit_cb, flag, (void *)list);
|
||||
|
||||
return list;
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
// PyDoc_STRVAR(bpy_user_resource_doc[] = // now in bpy/utils.py
|
||||
static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
const char *type;
|
||||
const char *subdir = NULL;
|
||||
int folder_id;
|
||||
const char *type;
|
||||
const char *subdir = NULL;
|
||||
int folder_id;
|
||||
|
||||
const char *path;
|
||||
const char *path;
|
||||
|
||||
static const char *_keywords[] = {"type", "subdir", NULL};
|
||||
static _PyArg_Parser _parser = {"s|s:user_resource", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&type, &subdir))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"type", "subdir", NULL};
|
||||
static _PyArg_Parser _parser = {"s|s:user_resource", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &type, &subdir)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* stupid string compare */
|
||||
if (STREQ(type, "DATAFILES")) { folder_id = BLENDER_USER_DATAFILES; }
|
||||
else if (STREQ(type, "CONFIG")) { folder_id = BLENDER_USER_CONFIG; }
|
||||
else if (STREQ(type, "SCRIPTS")) { folder_id = BLENDER_USER_SCRIPTS; }
|
||||
else if (STREQ(type, "AUTOSAVE")) { folder_id = BLENDER_USER_AUTOSAVE; }
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
|
||||
return NULL;
|
||||
}
|
||||
/* stupid string compare */
|
||||
if (STREQ(type, "DATAFILES")) {
|
||||
folder_id = BLENDER_USER_DATAFILES;
|
||||
}
|
||||
else if (STREQ(type, "CONFIG")) {
|
||||
folder_id = BLENDER_USER_CONFIG;
|
||||
}
|
||||
else if (STREQ(type, "SCRIPTS")) {
|
||||
folder_id = BLENDER_USER_SCRIPTS;
|
||||
}
|
||||
else if (STREQ(type, "AUTOSAVE")) {
|
||||
folder_id = BLENDER_USER_AUTOSAVE;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* same logic as BKE_appdir_folder_id_create(), but best leave it up to the script author to create */
|
||||
path = BKE_appdir_folder_id_user_notest(folder_id, subdir);
|
||||
/* same logic as BKE_appdir_folder_id_create(), but best leave it up to the script author to create */
|
||||
path = BKE_appdir_folder_id_user_notest(folder_id, subdir);
|
||||
|
||||
return PyC_UnicodeFromByte(path ? path : "");
|
||||
return PyC_UnicodeFromByte(path ? path : "");
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_resource_path_doc,
|
||||
".. function:: resource_path(type, major=bpy.app.version[0], minor=bpy.app.version[1])\n"
|
||||
"\n"
|
||||
" Return the base path for storing system files.\n"
|
||||
"\n"
|
||||
" :arg type: string in ['USER', 'LOCAL', 'SYSTEM'].\n"
|
||||
" :type type: string\n"
|
||||
" :arg major: major version, defaults to current.\n"
|
||||
" :type major: int\n"
|
||||
" :arg minor: minor version, defaults to current.\n"
|
||||
" :type minor: string\n"
|
||||
" :return: the resource path (not necessarily existing).\n"
|
||||
" :rtype: string\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpy_resource_path_doc,
|
||||
".. function:: resource_path(type, major=bpy.app.version[0], minor=bpy.app.version[1])\n"
|
||||
"\n"
|
||||
" Return the base path for storing system files.\n"
|
||||
"\n"
|
||||
" :arg type: string in ['USER', 'LOCAL', 'SYSTEM'].\n"
|
||||
" :type type: string\n"
|
||||
" :arg major: major version, defaults to current.\n"
|
||||
" :type major: int\n"
|
||||
" :arg minor: minor version, defaults to current.\n"
|
||||
" :type minor: string\n"
|
||||
" :return: the resource path (not necessarily existing).\n"
|
||||
" :rtype: string\n");
|
||||
static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
const char *type;
|
||||
int major = BLENDER_VERSION / 100, minor = BLENDER_VERSION % 100;
|
||||
int folder_id;
|
||||
const char *path;
|
||||
const char *type;
|
||||
int major = BLENDER_VERSION / 100, minor = BLENDER_VERSION % 100;
|
||||
int folder_id;
|
||||
const char *path;
|
||||
|
||||
static const char *_keywords[] = {"type", "major", "minor", NULL};
|
||||
static _PyArg_Parser _parser = {"s|ii:resource_path", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&type, &major, &minor))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"type", "major", "minor", NULL};
|
||||
static _PyArg_Parser _parser = {"s|ii:resource_path", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &type, &major, &minor)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* stupid string compare */
|
||||
if (STREQ(type, "USER")) { folder_id = BLENDER_RESOURCE_PATH_USER; }
|
||||
else if (STREQ(type, "LOCAL")) { folder_id = BLENDER_RESOURCE_PATH_LOCAL; }
|
||||
else if (STREQ(type, "SYSTEM")) { folder_id = BLENDER_RESOURCE_PATH_SYSTEM; }
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
|
||||
return NULL;
|
||||
}
|
||||
/* stupid string compare */
|
||||
if (STREQ(type, "USER")) {
|
||||
folder_id = BLENDER_RESOURCE_PATH_USER;
|
||||
}
|
||||
else if (STREQ(type, "LOCAL")) {
|
||||
folder_id = BLENDER_RESOURCE_PATH_LOCAL;
|
||||
}
|
||||
else if (STREQ(type, "SYSTEM")) {
|
||||
folder_id = BLENDER_RESOURCE_PATH_SYSTEM;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
path = BKE_appdir_folder_id_version(folder_id, (major * 100) + minor, false);
|
||||
path = BKE_appdir_folder_id_version(folder_id, (major * 100) + minor, false);
|
||||
|
||||
return PyC_UnicodeFromByte(path ? path : "");
|
||||
return PyC_UnicodeFromByte(path ? path : "");
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_escape_identifier_doc,
|
||||
".. function:: escape_identifier(string)\n"
|
||||
"\n"
|
||||
" Simple string escaping function used for animation paths.\n"
|
||||
"\n"
|
||||
" :arg string: text\n"
|
||||
" :type string: string\n"
|
||||
" :return: The escaped string.\n"
|
||||
" :rtype: string\n"
|
||||
);
|
||||
".. function:: escape_identifier(string)\n"
|
||||
"\n"
|
||||
" Simple string escaping function used for animation paths.\n"
|
||||
"\n"
|
||||
" :arg string: text\n"
|
||||
" :type string: string\n"
|
||||
" :return: The escaped string.\n"
|
||||
" :rtype: string\n");
|
||||
static PyObject *bpy_escape_identifier(PyObject *UNUSED(self), PyObject *value)
|
||||
{
|
||||
const char *value_str;
|
||||
Py_ssize_t value_str_len;
|
||||
const char *value_str;
|
||||
Py_ssize_t value_str_len;
|
||||
|
||||
char *value_escape_str;
|
||||
Py_ssize_t value_escape_str_len;
|
||||
PyObject *value_escape;
|
||||
size_t size;
|
||||
char *value_escape_str;
|
||||
Py_ssize_t value_escape_str_len;
|
||||
PyObject *value_escape;
|
||||
size_t size;
|
||||
|
||||
value_str = _PyUnicode_AsStringAndSize(value, &value_str_len);
|
||||
value_str = _PyUnicode_AsStringAndSize(value, &value_str_len);
|
||||
|
||||
if (value_str == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected a string");
|
||||
return NULL;
|
||||
}
|
||||
if (value_str == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected a string");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = (value_str_len * 2) + 1;
|
||||
value_escape_str = PyMem_MALLOC(size);
|
||||
value_escape_str_len = BLI_strescape(value_escape_str, value_str, size);
|
||||
size = (value_str_len * 2) + 1;
|
||||
value_escape_str = PyMem_MALLOC(size);
|
||||
value_escape_str_len = BLI_strescape(value_escape_str, value_str, size);
|
||||
|
||||
if (value_escape_str_len == value_str_len) {
|
||||
Py_INCREF(value);
|
||||
value_escape = value;
|
||||
}
|
||||
else {
|
||||
value_escape = PyUnicode_FromStringAndSize(value_escape_str, value_escape_str_len);
|
||||
}
|
||||
if (value_escape_str_len == value_str_len) {
|
||||
Py_INCREF(value);
|
||||
value_escape = value;
|
||||
}
|
||||
else {
|
||||
value_escape = PyUnicode_FromStringAndSize(value_escape_str, value_escape_str_len);
|
||||
}
|
||||
|
||||
PyMem_FREE(value_escape_str);
|
||||
PyMem_FREE(value_escape_str);
|
||||
|
||||
return value_escape;
|
||||
return value_escape;
|
||||
}
|
||||
|
||||
static PyMethodDef meth_bpy_script_paths =
|
||||
{"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc};
|
||||
static PyMethodDef meth_bpy_blend_paths =
|
||||
{"blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS | METH_KEYWORDS, bpy_blend_paths_doc};
|
||||
static PyMethodDef meth_bpy_user_resource =
|
||||
{"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS | METH_KEYWORDS, NULL};
|
||||
static PyMethodDef meth_bpy_resource_path =
|
||||
{"resource_path", (PyCFunction)bpy_resource_path, METH_VARARGS | METH_KEYWORDS, bpy_resource_path_doc};
|
||||
static PyMethodDef meth_bpy_escape_identifier =
|
||||
{"escape_identifier", (PyCFunction)bpy_escape_identifier, METH_O, bpy_escape_identifier_doc};
|
||||
static PyMethodDef meth_bpy_script_paths = {
|
||||
"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc};
|
||||
static PyMethodDef meth_bpy_blend_paths = {"blend_paths",
|
||||
(PyCFunction)bpy_blend_paths,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_blend_paths_doc};
|
||||
static PyMethodDef meth_bpy_user_resource = {
|
||||
"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS | METH_KEYWORDS, NULL};
|
||||
static PyMethodDef meth_bpy_resource_path = {"resource_path",
|
||||
(PyCFunction)bpy_resource_path,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_resource_path_doc};
|
||||
static PyMethodDef meth_bpy_escape_identifier = {
|
||||
"escape_identifier", (PyCFunction)bpy_escape_identifier, METH_O, bpy_escape_identifier_doc};
|
||||
|
||||
static PyObject *bpy_import_test(const char *modname)
|
||||
{
|
||||
PyObject *mod = PyImport_ImportModuleLevel(modname, NULL, NULL, NULL, 0);
|
||||
if (mod) {
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
else {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
PyObject *mod = PyImport_ImportModuleLevel(modname, NULL, NULL, NULL, 0);
|
||||
if (mod) {
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
else {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
return mod;
|
||||
return mod;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Description: Creates the bpy module and adds it to sys.modules for importing
|
||||
******************************************************************************/
|
||||
void BPy_init_modules(void)
|
||||
{
|
||||
PointerRNA ctx_ptr;
|
||||
PyObject *mod;
|
||||
PointerRNA ctx_ptr;
|
||||
PyObject *mod;
|
||||
|
||||
/* Needs to be first since this dir is needed for future modules */
|
||||
const char * const modpath = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, "modules");
|
||||
if (modpath) {
|
||||
// printf("bpy: found module path '%s'.\n", modpath);
|
||||
PyObject *sys_path = PySys_GetObject("path"); /* borrow */
|
||||
PyObject *py_modpath = PyUnicode_FromString(modpath);
|
||||
PyList_Insert(sys_path, 0, py_modpath); /* add first */
|
||||
Py_DECREF(py_modpath);
|
||||
}
|
||||
else {
|
||||
printf("bpy: couldnt find 'scripts/modules', blender probably wont start.\n");
|
||||
}
|
||||
/* stand alone utility modules not related to blender directly */
|
||||
IDProp_Init_Types(); /* not actually a submodule, just types */
|
||||
/* Needs to be first since this dir is needed for future modules */
|
||||
const char *const modpath = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, "modules");
|
||||
if (modpath) {
|
||||
// printf("bpy: found module path '%s'.\n", modpath);
|
||||
PyObject *sys_path = PySys_GetObject("path"); /* borrow */
|
||||
PyObject *py_modpath = PyUnicode_FromString(modpath);
|
||||
PyList_Insert(sys_path, 0, py_modpath); /* add first */
|
||||
Py_DECREF(py_modpath);
|
||||
}
|
||||
else {
|
||||
printf("bpy: couldnt find 'scripts/modules', blender probably wont start.\n");
|
||||
}
|
||||
/* stand alone utility modules not related to blender directly */
|
||||
IDProp_Init_Types(); /* not actually a submodule, just types */
|
||||
#ifdef WITH_FREESTYLE
|
||||
Freestyle_Init();
|
||||
Freestyle_Init();
|
||||
#endif
|
||||
|
||||
mod = PyModule_New("_bpy");
|
||||
mod = PyModule_New("_bpy");
|
||||
|
||||
/* add the module so we can import it */
|
||||
PyDict_SetItemString(PyImport_GetModuleDict(), "_bpy", mod);
|
||||
Py_DECREF(mod);
|
||||
/* add the module so we can import it */
|
||||
PyDict_SetItemString(PyImport_GetModuleDict(), "_bpy", mod);
|
||||
Py_DECREF(mod);
|
||||
|
||||
/* run first, initializes rna types */
|
||||
BPY_rna_init();
|
||||
/* run first, initializes rna types */
|
||||
BPY_rna_init();
|
||||
|
||||
/* needs to be first so bpy_types can run */
|
||||
PyModule_AddObject(mod, "types", BPY_rna_types());
|
||||
/* needs to be first so bpy_types can run */
|
||||
PyModule_AddObject(mod, "types", BPY_rna_types());
|
||||
|
||||
/* needs to be first so bpy_types can run */
|
||||
BPY_library_load_module(mod);
|
||||
BPY_library_write_module(mod);
|
||||
/* needs to be first so bpy_types can run */
|
||||
BPY_library_load_module(mod);
|
||||
BPY_library_write_module(mod);
|
||||
|
||||
BPY_rna_id_collection_module(mod);
|
||||
BPY_rna_id_collection_module(mod);
|
||||
|
||||
BPY_rna_gizmo_module(mod);
|
||||
BPY_rna_gizmo_module(mod);
|
||||
|
||||
bpy_import_test("bpy_types");
|
||||
PyModule_AddObject(mod, "data", BPY_rna_module()); /* imports bpy_types by running this */
|
||||
bpy_import_test("bpy_types");
|
||||
PyModule_AddObject(mod, "props", BPY_rna_props());
|
||||
/* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
|
||||
PyModule_AddObject(mod, "ops", BPY_operator_module());
|
||||
PyModule_AddObject(mod, "app", BPY_app_struct());
|
||||
PyModule_AddObject(mod, "_utils_units", BPY_utils_units());
|
||||
PyModule_AddObject(mod, "_utils_previews", BPY_utils_previews_module());
|
||||
PyModule_AddObject(mod, "msgbus", BPY_msgbus_module());
|
||||
bpy_import_test("bpy_types");
|
||||
PyModule_AddObject(mod, "data", BPY_rna_module()); /* imports bpy_types by running this */
|
||||
bpy_import_test("bpy_types");
|
||||
PyModule_AddObject(mod, "props", BPY_rna_props());
|
||||
/* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
|
||||
PyModule_AddObject(mod, "ops", BPY_operator_module());
|
||||
PyModule_AddObject(mod, "app", BPY_app_struct());
|
||||
PyModule_AddObject(mod, "_utils_units", BPY_utils_units());
|
||||
PyModule_AddObject(mod, "_utils_previews", BPY_utils_previews_module());
|
||||
PyModule_AddObject(mod, "msgbus", BPY_msgbus_module());
|
||||
|
||||
/* bpy context */
|
||||
RNA_pointer_create(NULL, &RNA_Context, (void *)BPy_GetContext(), &ctx_ptr);
|
||||
bpy_context_module = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ctx_ptr);
|
||||
/* odd that this is needed, 1 ref on creation and another for the module
|
||||
* but without we get a crash on exit */
|
||||
Py_INCREF(bpy_context_module);
|
||||
/* bpy context */
|
||||
RNA_pointer_create(NULL, &RNA_Context, (void *)BPy_GetContext(), &ctx_ptr);
|
||||
bpy_context_module = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ctx_ptr);
|
||||
/* odd that this is needed, 1 ref on creation and another for the module
|
||||
* but without we get a crash on exit */
|
||||
Py_INCREF(bpy_context_module);
|
||||
|
||||
PyModule_AddObject(mod, "context", (PyObject *)bpy_context_module);
|
||||
PyModule_AddObject(mod, "context", (PyObject *)bpy_context_module);
|
||||
|
||||
/* register bpy/rna classmethod callbacks */
|
||||
BPY_rna_register_cb();
|
||||
/* register bpy/rna classmethod callbacks */
|
||||
BPY_rna_register_cb();
|
||||
|
||||
/* utility func's that have nowhere else to go */
|
||||
PyModule_AddObject(mod, meth_bpy_script_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_script_paths, NULL));
|
||||
PyModule_AddObject(mod, meth_bpy_blend_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_blend_paths, NULL));
|
||||
PyModule_AddObject(mod, meth_bpy_user_resource.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_user_resource, NULL));
|
||||
PyModule_AddObject(mod, meth_bpy_resource_path.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_resource_path, NULL));
|
||||
PyModule_AddObject(mod, meth_bpy_escape_identifier.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_escape_identifier, NULL));
|
||||
/* utility func's that have nowhere else to go */
|
||||
PyModule_AddObject(mod,
|
||||
meth_bpy_script_paths.ml_name,
|
||||
(PyObject *)PyCFunction_New(&meth_bpy_script_paths, NULL));
|
||||
PyModule_AddObject(
|
||||
mod, meth_bpy_blend_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_blend_paths, NULL));
|
||||
PyModule_AddObject(mod,
|
||||
meth_bpy_user_resource.ml_name,
|
||||
(PyObject *)PyCFunction_New(&meth_bpy_user_resource, NULL));
|
||||
PyModule_AddObject(mod,
|
||||
meth_bpy_resource_path.ml_name,
|
||||
(PyObject *)PyCFunction_New(&meth_bpy_resource_path, NULL));
|
||||
PyModule_AddObject(mod,
|
||||
meth_bpy_escape_identifier.ml_name,
|
||||
(PyObject *)PyCFunction_New(&meth_bpy_escape_identifier, NULL));
|
||||
|
||||
/* register funcs (bpy_rna.c) */
|
||||
PyModule_AddObject(mod, meth_bpy_register_class.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_register_class, NULL));
|
||||
PyModule_AddObject(mod, meth_bpy_unregister_class.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_unregister_class, NULL));
|
||||
/* register funcs (bpy_rna.c) */
|
||||
PyModule_AddObject(mod,
|
||||
meth_bpy_register_class.ml_name,
|
||||
(PyObject *)PyCFunction_New(&meth_bpy_register_class, NULL));
|
||||
PyModule_AddObject(mod,
|
||||
meth_bpy_unregister_class.ml_name,
|
||||
(PyObject *)PyCFunction_New(&meth_bpy_unregister_class, NULL));
|
||||
|
||||
PyModule_AddObject(mod, meth_bpy_owner_id_get.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_owner_id_get, NULL));
|
||||
PyModule_AddObject(mod, meth_bpy_owner_id_set.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_owner_id_set, NULL));
|
||||
PyModule_AddObject(mod,
|
||||
meth_bpy_owner_id_get.ml_name,
|
||||
(PyObject *)PyCFunction_New(&meth_bpy_owner_id_get, NULL));
|
||||
PyModule_AddObject(mod,
|
||||
meth_bpy_owner_id_set.ml_name,
|
||||
(PyObject *)PyCFunction_New(&meth_bpy_owner_id_set, NULL));
|
||||
|
||||
/* add our own modules dir, this is a python package */
|
||||
bpy_package_py = bpy_import_test("bpy");
|
||||
/* add our own modules dir, this is a python package */
|
||||
bpy_package_py = bpy_import_test("bpy");
|
||||
}
|
||||
|
||||
@@ -31,4 +31,4 @@ void BPY_atexit_unregister(void);
|
||||
extern struct CLG_LogRef *BPY_LOG_CONTEXT;
|
||||
extern struct CLG_LogRef *BPY_LOG_RNA;
|
||||
|
||||
#endif /* __BPY_H__ */
|
||||
#endif /* __BPY_H__ */
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* however some writable variables have been added such as 'debug' and 'tempdir'
|
||||
*/
|
||||
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include "bpy_app.h"
|
||||
@@ -82,407 +81,504 @@ extern char build_system[];
|
||||
static PyTypeObject BlenderAppType;
|
||||
|
||||
static PyStructSequence_Field app_info_fields[] = {
|
||||
{(char *)"version", (char *)"The Blender version as a tuple of 3 numbers. eg. (2, 50, 11)"},
|
||||
{(char *)"version_string", (char *)"The Blender version formatted as a string"},
|
||||
{(char *)"version_char", (char *)"The Blender version character (for minor releases)"},
|
||||
{(char *)"version_cycle", (char *)"The release status of this build alpha/beta/rc/release"},
|
||||
{(char *)"binary_path", (char *)"The location of blenders executable, useful for utilities that spawn new instances"},
|
||||
{(char *)"background", (char *)"Boolean, True when blender is running without a user interface (started with -b)"},
|
||||
{(char *)"factory_startup", (char *)"Boolean, True when blender is running with --factory-startup)"},
|
||||
{(char *)"version", (char *)"The Blender version as a tuple of 3 numbers. eg. (2, 50, 11)"},
|
||||
{(char *)"version_string", (char *)"The Blender version formatted as a string"},
|
||||
{(char *)"version_char", (char *)"The Blender version character (for minor releases)"},
|
||||
{(char *)"version_cycle", (char *)"The release status of this build alpha/beta/rc/release"},
|
||||
{(char *)"binary_path",
|
||||
(char *)"The location of blenders executable, useful for utilities that spawn new instances"},
|
||||
{(char *)"background",
|
||||
(char *)"Boolean, True when blender is running without a user interface (started with -b)"},
|
||||
{(char *)"factory_startup",
|
||||
(char *)"Boolean, True when blender is running with --factory-startup)"},
|
||||
|
||||
/* buildinfo */
|
||||
{(char *)"build_date", (char *)"The date this blender instance was built"},
|
||||
{(char *)"build_time", (char *)"The time this blender instance was built"},
|
||||
{(char *)"build_commit_timestamp", (char *)"The unix timestamp of commit this blender instance was built"},
|
||||
{(char *)"build_commit_date", (char *)"The date of commit this blender instance was built"},
|
||||
{(char *)"build_commit_time", (char *)"The time of commit this blender instance was built"},
|
||||
{(char *)"build_hash", (char *)"The commit hash this blender instance was built with"},
|
||||
{(char *)"build_branch", (char *)"The branch this blender instance was built from"},
|
||||
{(char *)"build_platform", (char *)"The platform this blender instance was built for"},
|
||||
{(char *)"build_type", (char *)"The type of build (Release, Debug)"},
|
||||
{(char *)"build_cflags", (char *)"C compiler flags"},
|
||||
{(char *)"build_cxxflags", (char *)"C++ compiler flags"},
|
||||
{(char *)"build_linkflags", (char *)"Binary linking flags"},
|
||||
{(char *)"build_system", (char *)"Build system used"},
|
||||
/* buildinfo */
|
||||
{(char *)"build_date", (char *)"The date this blender instance was built"},
|
||||
{(char *)"build_time", (char *)"The time this blender instance was built"},
|
||||
{(char *)"build_commit_timestamp",
|
||||
(char *)"The unix timestamp of commit this blender instance was built"},
|
||||
{(char *)"build_commit_date", (char *)"The date of commit this blender instance was built"},
|
||||
{(char *)"build_commit_time", (char *)"The time of commit this blender instance was built"},
|
||||
{(char *)"build_hash", (char *)"The commit hash this blender instance was built with"},
|
||||
{(char *)"build_branch", (char *)"The branch this blender instance was built from"},
|
||||
{(char *)"build_platform", (char *)"The platform this blender instance was built for"},
|
||||
{(char *)"build_type", (char *)"The type of build (Release, Debug)"},
|
||||
{(char *)"build_cflags", (char *)"C compiler flags"},
|
||||
{(char *)"build_cxxflags", (char *)"C++ compiler flags"},
|
||||
{(char *)"build_linkflags", (char *)"Binary linking flags"},
|
||||
{(char *)"build_system", (char *)"Build system used"},
|
||||
|
||||
/* submodules */
|
||||
{(char *)"alembic", (char *)"Alembic library information backend"},
|
||||
{(char *)"ffmpeg", (char *)"FFmpeg library information backend"},
|
||||
{(char *)"ocio", (char *)"OpenColorIO library information backend"},
|
||||
{(char *)"oiio", (char *)"OpenImageIO library information backend"},
|
||||
{(char *)"opensubdiv", (char *)"OpenSubdiv library information backend"},
|
||||
{(char *)"openvdb", (char *)"OpenVDB library information backend"},
|
||||
{(char *)"sdl", (char *)"SDL library information backend"},
|
||||
{(char *)"build_options", (char *)"A set containing most important enabled optional build features"},
|
||||
{(char *)"handlers", (char *)"Application handler callbacks"},
|
||||
{(char *)"translations", (char *)"Application and addons internationalization API"},
|
||||
/* submodules */
|
||||
{(char *)"alembic", (char *)"Alembic library information backend"},
|
||||
{(char *)"ffmpeg", (char *)"FFmpeg library information backend"},
|
||||
{(char *)"ocio", (char *)"OpenColorIO library information backend"},
|
||||
{(char *)"oiio", (char *)"OpenImageIO library information backend"},
|
||||
{(char *)"opensubdiv", (char *)"OpenSubdiv library information backend"},
|
||||
{(char *)"openvdb", (char *)"OpenVDB library information backend"},
|
||||
{(char *)"sdl", (char *)"SDL library information backend"},
|
||||
{(char *)"build_options",
|
||||
(char *)"A set containing most important enabled optional build features"},
|
||||
{(char *)"handlers", (char *)"Application handler callbacks"},
|
||||
{(char *)"translations", (char *)"Application and addons internationalization API"},
|
||||
|
||||
/* Modules (not struct sequence). */
|
||||
{(char *)"icons", (char *)"Manage custom icons"},
|
||||
{(char *)"timers", (char *)"Manage timers"},
|
||||
{NULL},
|
||||
/* Modules (not struct sequence). */
|
||||
{(char *)"icons", (char *)"Manage custom icons"},
|
||||
{(char *)"timers", (char *)"Manage timers"},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(bpy_app_doc,
|
||||
"This module contains application values that remain unchanged during runtime.\n"
|
||||
"\n"
|
||||
"Submodules:\n"
|
||||
"\n"
|
||||
".. toctree::\n"
|
||||
" :maxdepth: 1\n"
|
||||
"\n"
|
||||
" bpy.app.handlers.rst\n"
|
||||
" bpy.app.icons.rst\n"
|
||||
" bpy.app.timers.rst\n"
|
||||
" bpy.app.translations.rst\n"
|
||||
);
|
||||
"This module contains application values that remain unchanged during runtime.\n"
|
||||
"\n"
|
||||
"Submodules:\n"
|
||||
"\n"
|
||||
".. toctree::\n"
|
||||
" :maxdepth: 1\n"
|
||||
"\n"
|
||||
" bpy.app.handlers.rst\n"
|
||||
" bpy.app.icons.rst\n"
|
||||
" bpy.app.timers.rst\n"
|
||||
" bpy.app.translations.rst\n");
|
||||
|
||||
static PyStructSequence_Desc app_info_desc = {
|
||||
(char *)"bpy.app", /* name */
|
||||
bpy_app_doc, /* doc */
|
||||
app_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_info_fields) - 1,
|
||||
(char *)"bpy.app", /* name */
|
||||
bpy_app_doc, /* doc */
|
||||
app_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_info_fields) - 1,
|
||||
};
|
||||
|
||||
static PyObject *make_app_info(void)
|
||||
{
|
||||
PyObject *app_info;
|
||||
int pos = 0;
|
||||
PyObject *app_info;
|
||||
int pos = 0;
|
||||
|
||||
app_info = PyStructSequence_New(&BlenderAppType);
|
||||
if (app_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#define SetIntItem(flag) \
|
||||
PyStructSequence_SET_ITEM(app_info, pos++, PyLong_FromLong(flag))
|
||||
#define SetStrItem(str) \
|
||||
PyStructSequence_SET_ITEM(app_info, pos++, PyUnicode_FromString(str))
|
||||
#define SetBytesItem(str) \
|
||||
PyStructSequence_SET_ITEM(app_info, pos++, PyBytes_FromString(str))
|
||||
#define SetObjItem(obj) \
|
||||
PyStructSequence_SET_ITEM(app_info, pos++, obj)
|
||||
app_info = PyStructSequence_New(&BlenderAppType);
|
||||
if (app_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#define SetIntItem(flag) PyStructSequence_SET_ITEM(app_info, pos++, PyLong_FromLong(flag))
|
||||
#define SetStrItem(str) PyStructSequence_SET_ITEM(app_info, pos++, PyUnicode_FromString(str))
|
||||
#define SetBytesItem(str) PyStructSequence_SET_ITEM(app_info, pos++, PyBytes_FromString(str))
|
||||
#define SetObjItem(obj) PyStructSequence_SET_ITEM(app_info, pos++, obj)
|
||||
|
||||
SetObjItem(PyC_Tuple_Pack_I32(BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION));
|
||||
SetObjItem(PyUnicode_FromFormat("%d.%02d (sub %d)",
|
||||
BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION));
|
||||
SetObjItem(PyUnicode_FromFormat(
|
||||
"%d.%02d (sub %d)", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION));
|
||||
|
||||
SetStrItem(STRINGIFY(BLENDER_VERSION_CHAR));
|
||||
SetStrItem(STRINGIFY(BLENDER_VERSION_CYCLE));
|
||||
SetStrItem(BKE_appdir_program_path());
|
||||
SetObjItem(PyBool_FromLong(G.background));
|
||||
SetObjItem(PyBool_FromLong(G.factory_startup));
|
||||
SetStrItem(STRINGIFY(BLENDER_VERSION_CHAR));
|
||||
SetStrItem(STRINGIFY(BLENDER_VERSION_CYCLE));
|
||||
SetStrItem(BKE_appdir_program_path());
|
||||
SetObjItem(PyBool_FromLong(G.background));
|
||||
SetObjItem(PyBool_FromLong(G.factory_startup));
|
||||
|
||||
/* build info, use bytes since we can't assume _any_ encoding:
|
||||
* see patch [#30154] for issue */
|
||||
/* build info, use bytes since we can't assume _any_ encoding:
|
||||
* see patch [#30154] for issue */
|
||||
#ifdef BUILD_DATE
|
||||
SetBytesItem(build_date);
|
||||
SetBytesItem(build_time);
|
||||
SetIntItem(build_commit_timestamp);
|
||||
SetBytesItem(build_commit_date);
|
||||
SetBytesItem(build_commit_time);
|
||||
SetBytesItem(build_hash);
|
||||
SetBytesItem(build_branch);
|
||||
SetBytesItem(build_platform);
|
||||
SetBytesItem(build_type);
|
||||
SetBytesItem(build_cflags);
|
||||
SetBytesItem(build_cxxflags);
|
||||
SetBytesItem(build_linkflags);
|
||||
SetBytesItem(build_system);
|
||||
SetBytesItem(build_date);
|
||||
SetBytesItem(build_time);
|
||||
SetIntItem(build_commit_timestamp);
|
||||
SetBytesItem(build_commit_date);
|
||||
SetBytesItem(build_commit_time);
|
||||
SetBytesItem(build_hash);
|
||||
SetBytesItem(build_branch);
|
||||
SetBytesItem(build_platform);
|
||||
SetBytesItem(build_type);
|
||||
SetBytesItem(build_cflags);
|
||||
SetBytesItem(build_cxxflags);
|
||||
SetBytesItem(build_linkflags);
|
||||
SetBytesItem(build_system);
|
||||
#else
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetIntItem(0);
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetIntItem(0);
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
SetBytesItem("Unknown");
|
||||
#endif
|
||||
|
||||
SetObjItem(BPY_app_alembic_struct());
|
||||
SetObjItem(BPY_app_ffmpeg_struct());
|
||||
SetObjItem(BPY_app_ocio_struct());
|
||||
SetObjItem(BPY_app_oiio_struct());
|
||||
SetObjItem(BPY_app_opensubdiv_struct());
|
||||
SetObjItem(BPY_app_openvdb_struct());
|
||||
SetObjItem(BPY_app_sdl_struct());
|
||||
SetObjItem(BPY_app_build_options_struct());
|
||||
SetObjItem(BPY_app_handlers_struct());
|
||||
SetObjItem(BPY_app_translations_struct());
|
||||
SetObjItem(BPY_app_alembic_struct());
|
||||
SetObjItem(BPY_app_ffmpeg_struct());
|
||||
SetObjItem(BPY_app_ocio_struct());
|
||||
SetObjItem(BPY_app_oiio_struct());
|
||||
SetObjItem(BPY_app_opensubdiv_struct());
|
||||
SetObjItem(BPY_app_openvdb_struct());
|
||||
SetObjItem(BPY_app_sdl_struct());
|
||||
SetObjItem(BPY_app_build_options_struct());
|
||||
SetObjItem(BPY_app_handlers_struct());
|
||||
SetObjItem(BPY_app_translations_struct());
|
||||
|
||||
/* modules */
|
||||
SetObjItem(BPY_app_icons_module());
|
||||
SetObjItem(BPY_app_timers_module());
|
||||
/* modules */
|
||||
SetObjItem(BPY_app_icons_module());
|
||||
SetObjItem(BPY_app_timers_module());
|
||||
|
||||
#undef SetIntItem
|
||||
#undef SetStrItem
|
||||
#undef SetBytesItem
|
||||
#undef SetObjItem
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(app_info);
|
||||
return NULL;
|
||||
}
|
||||
return app_info;
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(app_info);
|
||||
return NULL;
|
||||
}
|
||||
return app_info;
|
||||
}
|
||||
|
||||
/* a few getsets because it makes sense for them to be in bpy.app even though
|
||||
* they are not static */
|
||||
|
||||
PyDoc_STRVAR(bpy_app_debug_doc,
|
||||
"Boolean, for debug info (started with --debug / --debug_* matching this attribute name)"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpy_app_debug_doc,
|
||||
"Boolean, for debug info (started with --debug / --debug_* matching this attribute name)");
|
||||
static PyObject *bpy_app_debug_get(PyObject *UNUSED(self), void *closure)
|
||||
{
|
||||
const int flag = POINTER_AS_INT(closure);
|
||||
return PyBool_FromLong(G.debug & flag);
|
||||
const int flag = POINTER_AS_INT(closure);
|
||||
return PyBool_FromLong(G.debug & flag);
|
||||
}
|
||||
|
||||
static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *closure)
|
||||
{
|
||||
const int flag = POINTER_AS_INT(closure);
|
||||
const int param = PyObject_IsTrue(value);
|
||||
const int flag = POINTER_AS_INT(closure);
|
||||
const int param = PyObject_IsTrue(value);
|
||||
|
||||
if (param == -1) {
|
||||
PyErr_SetString(PyExc_TypeError, "bpy.app.debug can only be True/False");
|
||||
return -1;
|
||||
}
|
||||
if (param == -1) {
|
||||
PyErr_SetString(PyExc_TypeError, "bpy.app.debug can only be True/False");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (param) {
|
||||
G.debug |= flag;
|
||||
}
|
||||
else {
|
||||
G.debug &= ~flag;
|
||||
}
|
||||
if (param) {
|
||||
G.debug |= flag;
|
||||
}
|
||||
else {
|
||||
G.debug &= ~flag;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_app_global_flag_doc,
|
||||
"Boolean, for application behavior (started with --enable-* matching this attribute name)"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpy_app_global_flag_doc,
|
||||
"Boolean, for application behavior (started with --enable-* matching this attribute name)");
|
||||
static PyObject *bpy_app_global_flag_get(PyObject *UNUSED(self), void *closure)
|
||||
{
|
||||
const int flag = POINTER_AS_INT(closure);
|
||||
return PyBool_FromLong(G.f & flag);
|
||||
const int flag = POINTER_AS_INT(closure);
|
||||
return PyBool_FromLong(G.f & flag);
|
||||
}
|
||||
|
||||
static int bpy_app_global_flag_set(PyObject *UNUSED(self), PyObject *value, void *closure)
|
||||
{
|
||||
const int flag = POINTER_AS_INT(closure);
|
||||
const int param = PyObject_IsTrue(value);
|
||||
const int flag = POINTER_AS_INT(closure);
|
||||
const int param = PyObject_IsTrue(value);
|
||||
|
||||
if (param == -1) {
|
||||
PyErr_SetString(PyExc_TypeError, "bpy.app.use_* can only be True/False");
|
||||
return -1;
|
||||
}
|
||||
if (param == -1) {
|
||||
PyErr_SetString(PyExc_TypeError, "bpy.app.use_* can only be True/False");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (param) {
|
||||
G.f |= flag;
|
||||
}
|
||||
else {
|
||||
G.f &= ~flag;
|
||||
}
|
||||
if (param) {
|
||||
G.f |= flag;
|
||||
}
|
||||
else {
|
||||
G.f &= ~flag;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bpy_app_global_flag_set__only_disable(PyObject *UNUSED(self), PyObject *value, void *closure)
|
||||
static int bpy_app_global_flag_set__only_disable(PyObject *UNUSED(self),
|
||||
PyObject *value,
|
||||
void *closure)
|
||||
{
|
||||
const int param = PyObject_IsTrue(value);
|
||||
if (param == 1) {
|
||||
PyErr_SetString(PyExc_ValueError, "This bpy.app.use_* option can only be disabled");
|
||||
return -1;
|
||||
}
|
||||
return bpy_app_global_flag_set(NULL, value, closure);
|
||||
const int param = PyObject_IsTrue(value);
|
||||
if (param == 1) {
|
||||
PyErr_SetString(PyExc_ValueError, "This bpy.app.use_* option can only be disabled");
|
||||
return -1;
|
||||
}
|
||||
return bpy_app_global_flag_set(NULL, value, closure);
|
||||
}
|
||||
|
||||
#define BROKEN_BINARY_PATH_PYTHON_HACK
|
||||
|
||||
PyDoc_STRVAR(bpy_app_binary_path_python_doc,
|
||||
"String, the path to the python executable (read-only)"
|
||||
);
|
||||
"String, the path to the python executable (read-only)");
|
||||
static PyObject *bpy_app_binary_path_python_get(PyObject *self, void *UNUSED(closure))
|
||||
{
|
||||
/* refcount is held in BlenderAppType.tp_dict */
|
||||
static PyObject *ret = NULL;
|
||||
/* refcount is held in BlenderAppType.tp_dict */
|
||||
static PyObject *ret = NULL;
|
||||
|
||||
if (ret == NULL) {
|
||||
/* only run once */
|
||||
char fullpath[1024];
|
||||
BKE_appdir_program_python_search(
|
||||
fullpath, sizeof(fullpath),
|
||||
PY_MAJOR_VERSION, PY_MINOR_VERSION);
|
||||
ret = PyC_UnicodeFromByte(fullpath);
|
||||
if (ret == NULL) {
|
||||
/* only run once */
|
||||
char fullpath[1024];
|
||||
BKE_appdir_program_python_search(
|
||||
fullpath, sizeof(fullpath), PY_MAJOR_VERSION, PY_MINOR_VERSION);
|
||||
ret = PyC_UnicodeFromByte(fullpath);
|
||||
#ifdef BROKEN_BINARY_PATH_PYTHON_HACK
|
||||
Py_INCREF(ret);
|
||||
UNUSED_VARS(self);
|
||||
Py_INCREF(ret);
|
||||
UNUSED_VARS(self);
|
||||
#else
|
||||
PyDict_SetItem(BlenderAppType.tp_dict, /* XXX BAAAADDDDDD! self is not a PyDescr at all! it's bpy.app!!! */ PyDescr_NAME(self), ret);
|
||||
PyDict_SetItem(
|
||||
BlenderAppType.tp_dict,
|
||||
/* XXX BAAAADDDDDD! self is not a PyDescr at all! it's bpy.app!!! */ PyDescr_NAME(self),
|
||||
ret);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
Py_INCREF(ret);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Py_INCREF(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_app_debug_value_doc,
|
||||
"Short, number which can be set to non-zero values for testing purposes"
|
||||
);
|
||||
"Short, number which can be set to non-zero values for testing purposes");
|
||||
static PyObject *bpy_app_debug_value_get(PyObject *UNUSED(self), void *UNUSED(closure))
|
||||
{
|
||||
return PyLong_FromLong(G.debug_value);
|
||||
return PyLong_FromLong(G.debug_value);
|
||||
}
|
||||
|
||||
static int bpy_app_debug_value_set(PyObject *UNUSED(self), PyObject *value, void *UNUSED(closure))
|
||||
{
|
||||
short param = PyC_Long_AsI16(value);
|
||||
short param = PyC_Long_AsI16(value);
|
||||
|
||||
if (param == -1 && PyErr_Occurred()) {
|
||||
PyC_Err_SetString_Prefix(
|
||||
PyExc_TypeError,
|
||||
"bpy.app.debug_value can only be set to a whole number");
|
||||
return -1;
|
||||
}
|
||||
if (param == -1 && PyErr_Occurred()) {
|
||||
PyC_Err_SetString_Prefix(PyExc_TypeError,
|
||||
"bpy.app.debug_value can only be set to a whole number");
|
||||
return -1;
|
||||
}
|
||||
|
||||
G.debug_value = param;
|
||||
G.debug_value = param;
|
||||
|
||||
WM_main_add_notifier(NC_WINDOW, NULL);
|
||||
WM_main_add_notifier(NC_WINDOW, NULL);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_app_tempdir_doc,
|
||||
"String, the temp directory used by blender (read-only)"
|
||||
);
|
||||
PyDoc_STRVAR(bpy_app_tempdir_doc, "String, the temp directory used by blender (read-only)");
|
||||
static PyObject *bpy_app_tempdir_get(PyObject *UNUSED(self), void *UNUSED(closure))
|
||||
{
|
||||
return PyC_UnicodeFromByte(BKE_tempdir_session());
|
||||
return PyC_UnicodeFromByte(BKE_tempdir_session());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_app_driver_dict_doc,
|
||||
"Dictionary for drivers namespace, editable in-place, reset on file load (read-only)"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpy_app_driver_dict_doc,
|
||||
"Dictionary for drivers namespace, editable in-place, reset on file load (read-only)");
|
||||
static PyObject *bpy_app_driver_dict_get(PyObject *UNUSED(self), void *UNUSED(closure))
|
||||
{
|
||||
if (bpy_pydriver_Dict == NULL) {
|
||||
if (bpy_pydriver_create_dict() != 0) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "bpy.app.driver_namespace failed to create dictionary");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (bpy_pydriver_Dict == NULL) {
|
||||
if (bpy_pydriver_create_dict() != 0) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "bpy.app.driver_namespace failed to create dictionary");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return Py_INCREF_RET(bpy_pydriver_Dict);
|
||||
return Py_INCREF_RET(bpy_pydriver_Dict);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_app_preview_render_size_doc,
|
||||
"Reference size for icon/preview renders (read-only)"
|
||||
);
|
||||
"Reference size for icon/preview renders (read-only)");
|
||||
static PyObject *bpy_app_preview_render_size_get(PyObject *UNUSED(self), void *closure)
|
||||
{
|
||||
return PyLong_FromLong((long)UI_preview_render_size(POINTER_AS_INT(closure)));
|
||||
return PyLong_FromLong((long)UI_preview_render_size(POINTER_AS_INT(closure)));
|
||||
}
|
||||
|
||||
static PyObject *bpy_app_autoexec_fail_message_get(PyObject *UNUSED(self), void *UNUSED(closure))
|
||||
{
|
||||
return PyC_UnicodeFromByte(G.autoexec_fail);
|
||||
return PyC_UnicodeFromByte(G.autoexec_fail);
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(bpy_app_use_static_override_doc,
|
||||
"Boolean, whether static override is exposed in UI or not."
|
||||
);
|
||||
"Boolean, whether static override is exposed in UI or not.");
|
||||
static PyObject *bpy_app_use_static_override_get(PyObject *UNUSED(self), void *UNUSED(closure))
|
||||
{
|
||||
return PyBool_FromLong((long)BKE_override_static_is_enabled());
|
||||
return PyBool_FromLong((long)BKE_override_static_is_enabled());
|
||||
}
|
||||
|
||||
static int bpy_app_use_static_override_set(PyObject *UNUSED(self), PyObject *value, void *UNUSED(closure))
|
||||
static int bpy_app_use_static_override_set(PyObject *UNUSED(self),
|
||||
PyObject *value,
|
||||
void *UNUSED(closure))
|
||||
{
|
||||
const int param = PyC_Long_AsBool(value);
|
||||
const int param = PyC_Long_AsBool(value);
|
||||
|
||||
if (param == -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "bpy.app.use_static_override must be a boolean");
|
||||
return -1;
|
||||
}
|
||||
if (param == -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "bpy.app.use_static_override must be a boolean");
|
||||
return -1;
|
||||
}
|
||||
|
||||
BKE_override_static_enable((const bool)param);
|
||||
BKE_override_static_enable((const bool)param);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static PyGetSetDef bpy_app_getsets[] = {
|
||||
{(char *)"debug", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG},
|
||||
{(char *)"debug_ffmpeg", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_FFMPEG},
|
||||
{(char *)"debug_freestyle", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_FREESTYLE},
|
||||
{(char *)"debug_python", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_PYTHON},
|
||||
{(char *)"debug_events", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_EVENTS},
|
||||
{(char *)"debug_handlers", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_HANDLERS},
|
||||
{(char *)"debug_wm", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_WM},
|
||||
{(char *)"debug_depsgraph", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_DEPSGRAPH},
|
||||
{(char *)"debug_depsgraph_build", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_DEPSGRAPH_BUILD},
|
||||
{(char *)"debug_depsgraph_eval", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_DEPSGRAPH_EVAL},
|
||||
{(char *)"debug_depsgraph_tag", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_DEPSGRAPH_TAG},
|
||||
{(char *)"debug_depsgraph_time", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_DEPSGRAPH_TIME},
|
||||
{(char *)"debug_depsgraph_pretty", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_DEPSGRAPH_PRETTY},
|
||||
{(char *)"debug_simdata", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_SIMDATA},
|
||||
{(char *)"debug_gpumem", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_GPU_MEM},
|
||||
{(char *)"debug_io", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_IO},
|
||||
{(char *)"debug",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG},
|
||||
{(char *)"debug_ffmpeg",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_FFMPEG},
|
||||
{(char *)"debug_freestyle",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_FREESTYLE},
|
||||
{(char *)"debug_python",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_PYTHON},
|
||||
{(char *)"debug_events",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_EVENTS},
|
||||
{(char *)"debug_handlers",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_HANDLERS},
|
||||
{(char *)"debug_wm",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_WM},
|
||||
{(char *)"debug_depsgraph",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_DEPSGRAPH},
|
||||
{(char *)"debug_depsgraph_build",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_DEPSGRAPH_BUILD},
|
||||
{(char *)"debug_depsgraph_eval",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_DEPSGRAPH_EVAL},
|
||||
{(char *)"debug_depsgraph_tag",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_DEPSGRAPH_TAG},
|
||||
{(char *)"debug_depsgraph_time",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_DEPSGRAPH_TIME},
|
||||
{(char *)"debug_depsgraph_pretty",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_DEPSGRAPH_PRETTY},
|
||||
{(char *)"debug_simdata",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_SIMDATA},
|
||||
{(char *)"debug_gpumem",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_GPU_MEM},
|
||||
{(char *)"debug_io",
|
||||
bpy_app_debug_get,
|
||||
bpy_app_debug_set,
|
||||
(char *)bpy_app_debug_doc,
|
||||
(void *)G_DEBUG_IO},
|
||||
|
||||
{(char *)"use_static_override", bpy_app_use_static_override_get, bpy_app_use_static_override_set, (char *)bpy_app_use_static_override_doc, NULL},
|
||||
{(char *)"use_event_simulate", bpy_app_global_flag_get, bpy_app_global_flag_set__only_disable, (char *)bpy_app_global_flag_doc, (void *)G_FLAG_EVENT_SIMULATE},
|
||||
{(char *)"use_static_override",
|
||||
bpy_app_use_static_override_get,
|
||||
bpy_app_use_static_override_set,
|
||||
(char *)bpy_app_use_static_override_doc,
|
||||
NULL},
|
||||
{(char *)"use_event_simulate",
|
||||
bpy_app_global_flag_get,
|
||||
bpy_app_global_flag_set__only_disable,
|
||||
(char *)bpy_app_global_flag_doc,
|
||||
(void *)G_FLAG_EVENT_SIMULATE},
|
||||
|
||||
{(char *)"binary_path_python", bpy_app_binary_path_python_get, NULL, (char *)bpy_app_binary_path_python_doc, NULL},
|
||||
{(char *)"binary_path_python",
|
||||
bpy_app_binary_path_python_get,
|
||||
NULL,
|
||||
(char *)bpy_app_binary_path_python_doc,
|
||||
NULL},
|
||||
|
||||
{(char *)"debug_value", bpy_app_debug_value_get, bpy_app_debug_value_set, (char *)bpy_app_debug_value_doc, NULL},
|
||||
{(char *)"tempdir", bpy_app_tempdir_get, NULL, (char *)bpy_app_tempdir_doc, NULL},
|
||||
{(char *)"driver_namespace", bpy_app_driver_dict_get, NULL, (char *)bpy_app_driver_dict_doc, NULL},
|
||||
{(char *)"debug_value",
|
||||
bpy_app_debug_value_get,
|
||||
bpy_app_debug_value_set,
|
||||
(char *)bpy_app_debug_value_doc,
|
||||
NULL},
|
||||
{(char *)"tempdir", bpy_app_tempdir_get, NULL, (char *)bpy_app_tempdir_doc, NULL},
|
||||
{(char *)"driver_namespace",
|
||||
bpy_app_driver_dict_get,
|
||||
NULL,
|
||||
(char *)bpy_app_driver_dict_doc,
|
||||
NULL},
|
||||
|
||||
{(char *)"render_icon_size", bpy_app_preview_render_size_get, NULL, (char *)bpy_app_preview_render_size_doc, (void *)ICON_SIZE_ICON},
|
||||
{(char *)"render_preview_size", bpy_app_preview_render_size_get, NULL, (char *)bpy_app_preview_render_size_doc, (void *)ICON_SIZE_PREVIEW},
|
||||
{(char *)"render_icon_size",
|
||||
bpy_app_preview_render_size_get,
|
||||
NULL,
|
||||
(char *)bpy_app_preview_render_size_doc,
|
||||
(void *)ICON_SIZE_ICON},
|
||||
{(char *)"render_preview_size",
|
||||
bpy_app_preview_render_size_get,
|
||||
NULL,
|
||||
(char *)bpy_app_preview_render_size_doc,
|
||||
(void *)ICON_SIZE_PREVIEW},
|
||||
|
||||
/* security */
|
||||
{(char *)"autoexec_fail", bpy_app_global_flag_get, NULL, NULL, (void *)G_FLAG_SCRIPT_AUTOEXEC_FAIL},
|
||||
{(char *)"autoexec_fail_quiet", bpy_app_global_flag_get, NULL, NULL, (void *)G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET},
|
||||
{(char *)"autoexec_fail_message", bpy_app_autoexec_fail_message_get, NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
/* security */
|
||||
{(char *)"autoexec_fail",
|
||||
bpy_app_global_flag_get,
|
||||
NULL,
|
||||
NULL,
|
||||
(void *)G_FLAG_SCRIPT_AUTOEXEC_FAIL},
|
||||
{(char *)"autoexec_fail_quiet",
|
||||
bpy_app_global_flag_get,
|
||||
NULL,
|
||||
NULL,
|
||||
(void *)G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET},
|
||||
{(char *)"autoexec_fail_message", bpy_app_autoexec_fail_message_get, NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
};
|
||||
|
||||
static void py_struct_seq_getset_init(void)
|
||||
{
|
||||
/* tricky dynamic members, not to py-spec! */
|
||||
for (PyGetSetDef *getset = bpy_app_getsets; getset->name; getset++) {
|
||||
PyObject *item = PyDescr_NewGetSet(&BlenderAppType, getset);
|
||||
PyDict_SetItem(BlenderAppType.tp_dict, PyDescr_NAME(item), item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
/* tricky dynamic members, not to py-spec! */
|
||||
for (PyGetSetDef *getset = bpy_app_getsets; getset->name; getset++) {
|
||||
PyObject *item = PyDescr_NewGetSet(&BlenderAppType, getset);
|
||||
PyDict_SetItem(BlenderAppType.tp_dict, PyDescr_NAME(item), item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
}
|
||||
/* end dynamic bpy.app */
|
||||
|
||||
|
||||
PyObject *BPY_app_struct(void)
|
||||
{
|
||||
PyObject *ret;
|
||||
PyObject *ret;
|
||||
|
||||
PyStructSequence_InitType(&BlenderAppType, &app_info_desc);
|
||||
PyStructSequence_InitType(&BlenderAppType, &app_info_desc);
|
||||
|
||||
ret = make_app_info();
|
||||
ret = make_app_info();
|
||||
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppType.tp_init = NULL;
|
||||
BlenderAppType.tp_new = NULL;
|
||||
BlenderAppType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppType.tp_init = NULL;
|
||||
BlenderAppType.tp_new = NULL;
|
||||
BlenderAppType.tp_hash = (hashfunc)
|
||||
_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
|
||||
/* kindof a hack ontop of PyStructSequence */
|
||||
py_struct_seq_getset_init();
|
||||
/* kindof a hack ontop of PyStructSequence */
|
||||
py_struct_seq_getset_init();
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
|
||||
PyObject *BPY_app_struct(void);
|
||||
|
||||
#endif /* __BPY_APP_H__ */
|
||||
#endif /* __BPY_APP_H__ */
|
||||
|
||||
@@ -35,73 +35,72 @@
|
||||
static PyTypeObject BlenderAppABCType;
|
||||
|
||||
static PyStructSequence_Field app_alembic_info_fields[] = {
|
||||
{(char *)"supported", (char *)"Boolean, True when Blender is built with Alembic support"},
|
||||
{(char *)"version", (char *)"The Alembic version as a tuple of 3 numbers"},
|
||||
{(char *)"version_string", (char *)"The Alembic version formatted as a string"},
|
||||
{NULL},
|
||||
{(char *)"supported", (char *)"Boolean, True when Blender is built with Alembic support"},
|
||||
{(char *)"version", (char *)"The Alembic version as a tuple of 3 numbers"},
|
||||
{(char *)"version_string", (char *)"The Alembic version formatted as a string"},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static PyStructSequence_Desc app_alembic_info_desc = {
|
||||
(char *)"bpy.app.alembic", /* name */
|
||||
(char *)"This module contains information about Alembic blender is linked against", /* doc */
|
||||
app_alembic_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_alembic_info_fields) - 1,
|
||||
(char *)"bpy.app.alembic", /* name */
|
||||
(char *)"This module contains information about Alembic blender is linked against", /* doc */
|
||||
app_alembic_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_alembic_info_fields) - 1,
|
||||
};
|
||||
|
||||
static PyObject *make_alembic_info(void)
|
||||
{
|
||||
PyObject *alembic_info = PyStructSequence_New(&BlenderAppABCType);
|
||||
PyObject *alembic_info = PyStructSequence_New(&BlenderAppABCType);
|
||||
|
||||
if (alembic_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (alembic_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pos = 0;
|
||||
int pos = 0;
|
||||
|
||||
#ifndef WITH_ALEMBIC
|
||||
# define SetStrItem(str) \
|
||||
PyStructSequence_SET_ITEM(alembic_info, pos++, PyUnicode_FromString(str))
|
||||
# define SetStrItem(str) PyStructSequence_SET_ITEM(alembic_info, pos++, PyUnicode_FromString(str))
|
||||
#endif
|
||||
|
||||
#define SetObjItem(obj) \
|
||||
PyStructSequence_SET_ITEM(alembic_info, pos++, obj)
|
||||
#define SetObjItem(obj) PyStructSequence_SET_ITEM(alembic_info, pos++, obj)
|
||||
|
||||
#ifdef WITH_ALEMBIC
|
||||
const int curversion = ABC_get_version();
|
||||
const int major = curversion / 10000;
|
||||
const int minor = (curversion / 100) - (major * 100);
|
||||
const int patch = curversion - ((curversion / 100 ) * 100);
|
||||
const int curversion = ABC_get_version();
|
||||
const int major = curversion / 10000;
|
||||
const int minor = (curversion / 100) - (major * 100);
|
||||
const int patch = curversion - ((curversion / 100) * 100);
|
||||
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(major, minor, patch));
|
||||
SetObjItem(PyUnicode_FromFormat("%2d, %2d, %2d", major, minor, patch));
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(major, minor, patch));
|
||||
SetObjItem(PyUnicode_FromFormat("%2d, %2d, %2d", major, minor, patch));
|
||||
#else
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
|
||||
SetStrItem("Unknown");
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
|
||||
SetStrItem("Unknown");
|
||||
#endif
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(alembic_info);
|
||||
return NULL;
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(alembic_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef SetStrItem
|
||||
#undef SetObjItem
|
||||
|
||||
return alembic_info;
|
||||
return alembic_info;
|
||||
}
|
||||
|
||||
PyObject *BPY_app_alembic_struct(void)
|
||||
{
|
||||
PyStructSequence_InitType(&BlenderAppABCType, &app_alembic_info_desc);
|
||||
PyStructSequence_InitType(&BlenderAppABCType, &app_alembic_info_desc);
|
||||
|
||||
PyObject *ret = make_alembic_info();
|
||||
PyObject *ret = make_alembic_info();
|
||||
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppABCType.tp_init = NULL;
|
||||
BlenderAppABCType.tp_new = NULL;
|
||||
BlenderAppABCType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppABCType.tp_init = NULL;
|
||||
BlenderAppABCType.tp_new = NULL;
|
||||
BlenderAppABCType.tp_hash = (hashfunc)
|
||||
_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -26,4 +26,4 @@
|
||||
|
||||
PyObject *BPY_app_alembic_struct(void);
|
||||
|
||||
#endif /* __BPY_APP_ALEMBIC_H__ */
|
||||
#endif /* __BPY_APP_ALEMBIC_H__ */
|
||||
|
||||
@@ -27,265 +27,265 @@
|
||||
static PyTypeObject BlenderAppBuildOptionsType;
|
||||
|
||||
static PyStructSequence_Field app_builtopts_info_fields[] = {
|
||||
/* names mostly follow CMake options, lowercase, after WITH_ */
|
||||
{(char *)"bullet", NULL},
|
||||
{(char *)"codec_avi", NULL},
|
||||
{(char *)"codec_ffmpeg", NULL},
|
||||
{(char *)"codec_sndfile", NULL},
|
||||
{(char *)"compositor", NULL},
|
||||
{(char *)"cycles", NULL},
|
||||
{(char *)"cycles_osl", NULL},
|
||||
{(char *)"freestyle", NULL},
|
||||
{(char *)"image_cineon", NULL},
|
||||
{(char *)"image_dds", NULL},
|
||||
{(char *)"image_hdr", NULL},
|
||||
{(char *)"image_openexr", NULL},
|
||||
{(char *)"image_openjpeg", NULL},
|
||||
{(char *)"image_tiff", NULL},
|
||||
{(char *)"input_ndof", NULL},
|
||||
{(char *)"audaspace", NULL},
|
||||
{(char *)"international", NULL},
|
||||
{(char *)"openal", NULL},
|
||||
{(char *)"sdl", NULL},
|
||||
{(char *)"sdl_dynload", NULL},
|
||||
{(char *)"jack", NULL},
|
||||
{(char *)"libmv", NULL},
|
||||
{(char *)"mod_fluid", NULL},
|
||||
{(char *)"mod_oceansim", NULL},
|
||||
{(char *)"mod_remesh", NULL},
|
||||
{(char *)"mod_smoke", NULL},
|
||||
{(char *)"collada", NULL},
|
||||
{(char *)"opencolorio", NULL},
|
||||
{(char *)"openmp", NULL},
|
||||
{(char *)"openvdb", NULL},
|
||||
{(char *)"alembic", NULL},
|
||||
{NULL},
|
||||
/* names mostly follow CMake options, lowercase, after WITH_ */
|
||||
{(char *)"bullet", NULL},
|
||||
{(char *)"codec_avi", NULL},
|
||||
{(char *)"codec_ffmpeg", NULL},
|
||||
{(char *)"codec_sndfile", NULL},
|
||||
{(char *)"compositor", NULL},
|
||||
{(char *)"cycles", NULL},
|
||||
{(char *)"cycles_osl", NULL},
|
||||
{(char *)"freestyle", NULL},
|
||||
{(char *)"image_cineon", NULL},
|
||||
{(char *)"image_dds", NULL},
|
||||
{(char *)"image_hdr", NULL},
|
||||
{(char *)"image_openexr", NULL},
|
||||
{(char *)"image_openjpeg", NULL},
|
||||
{(char *)"image_tiff", NULL},
|
||||
{(char *)"input_ndof", NULL},
|
||||
{(char *)"audaspace", NULL},
|
||||
{(char *)"international", NULL},
|
||||
{(char *)"openal", NULL},
|
||||
{(char *)"sdl", NULL},
|
||||
{(char *)"sdl_dynload", NULL},
|
||||
{(char *)"jack", NULL},
|
||||
{(char *)"libmv", NULL},
|
||||
{(char *)"mod_fluid", NULL},
|
||||
{(char *)"mod_oceansim", NULL},
|
||||
{(char *)"mod_remesh", NULL},
|
||||
{(char *)"mod_smoke", NULL},
|
||||
{(char *)"collada", NULL},
|
||||
{(char *)"opencolorio", NULL},
|
||||
{(char *)"openmp", NULL},
|
||||
{(char *)"openvdb", NULL},
|
||||
{(char *)"alembic", NULL},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
|
||||
static PyStructSequence_Desc app_builtopts_info_desc = {
|
||||
(char *)"bpy.app.build_options", /* name */
|
||||
(char *)"This module contains information about options blender is built with", /* doc */
|
||||
app_builtopts_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_builtopts_info_fields) - 1,
|
||||
(char *)"bpy.app.build_options", /* name */
|
||||
(char *)"This module contains information about options blender is built with", /* doc */
|
||||
app_builtopts_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_builtopts_info_fields) - 1,
|
||||
};
|
||||
|
||||
static PyObject *make_builtopts_info(void)
|
||||
{
|
||||
PyObject *builtopts_info;
|
||||
int pos = 0;
|
||||
PyObject *builtopts_info;
|
||||
int pos = 0;
|
||||
|
||||
builtopts_info = PyStructSequence_New(&BlenderAppBuildOptionsType);
|
||||
if (builtopts_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
builtopts_info = PyStructSequence_New(&BlenderAppBuildOptionsType);
|
||||
if (builtopts_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define SetObjIncref(item) \
|
||||
PyStructSequence_SET_ITEM(builtopts_info, pos++, (Py_IncRef(item), item))
|
||||
PyStructSequence_SET_ITEM(builtopts_info, pos++, (Py_IncRef(item), item))
|
||||
|
||||
#ifdef WITH_BULLET
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AVI
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_FFMPEG
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SNDFILE
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_COMPOSITOR
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CYCLES
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CYCLES_OSL
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_FREESTYLE
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CINEON
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DDS
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_HDR
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENEXR
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENJPEG
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_TIFF
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AUDASPACE
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_INTERNATIONAL
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENAL
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SDL
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SDL_DYNLOAD
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_JACK
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LIBMV
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_MOD_FLUID
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OCEANSIM
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_MOD_REMESH
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SMOKE
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_COLLADA
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef _OPENMP
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_ALEMBIC
|
||||
SetObjIncref(Py_True);
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#undef SetObjIncref
|
||||
|
||||
return builtopts_info;
|
||||
return builtopts_info;
|
||||
}
|
||||
|
||||
PyObject *BPY_app_build_options_struct(void)
|
||||
{
|
||||
PyObject *ret;
|
||||
PyObject *ret;
|
||||
|
||||
PyStructSequence_InitType(&BlenderAppBuildOptionsType, &app_builtopts_info_desc);
|
||||
PyStructSequence_InitType(&BlenderAppBuildOptionsType, &app_builtopts_info_desc);
|
||||
|
||||
ret = make_builtopts_info();
|
||||
ret = make_builtopts_info();
|
||||
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppBuildOptionsType.tp_init = NULL;
|
||||
BlenderAppBuildOptionsType.tp_new = NULL;
|
||||
BlenderAppBuildOptionsType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppBuildOptionsType.tp_init = NULL;
|
||||
BlenderAppBuildOptionsType.tp_new = NULL;
|
||||
BlenderAppBuildOptionsType.tp_hash = (hashfunc)
|
||||
_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
|
||||
PyObject *BPY_app_build_options_struct(void);
|
||||
|
||||
#endif /* __BPY_APP_BUILD_OPTIONS_H__ */
|
||||
#endif /* __BPY_APP_BUILD_OPTIONS_H__ */
|
||||
|
||||
@@ -26,116 +26,121 @@
|
||||
#include "../generic/py_capi_utils.h"
|
||||
|
||||
#ifdef WITH_FFMPEG
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavdevice/avdevice.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/avutil.h>
|
||||
#include <libswscale/swscale.h>
|
||||
# include <libavcodec/avcodec.h>
|
||||
# include <libavdevice/avdevice.h>
|
||||
# include <libavformat/avformat.h>
|
||||
# include <libavutil/avutil.h>
|
||||
# include <libswscale/swscale.h>
|
||||
#endif
|
||||
|
||||
static PyTypeObject BlenderAppFFmpegType;
|
||||
|
||||
#define DEF_FFMPEG_LIB_VERSION(lib) \
|
||||
{(char *)(#lib "_version"), (char *)("The " #lib " version as a tuple of 3 numbers")}, \
|
||||
{(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")}
|
||||
{(char *)(#lib "_version"), (char *)("The " #lib " version as a tuple of 3 numbers")}, \
|
||||
{ \
|
||||
(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string") \
|
||||
}
|
||||
|
||||
static PyStructSequence_Field app_ffmpeg_info_fields[] = {
|
||||
{(char *)"supported", (char *)("Boolean, True when Blender is built with FFmpeg support")},
|
||||
{(char *)"supported", (char *)("Boolean, True when Blender is built with FFmpeg support")},
|
||||
|
||||
DEF_FFMPEG_LIB_VERSION(avcodec),
|
||||
DEF_FFMPEG_LIB_VERSION(avdevice),
|
||||
DEF_FFMPEG_LIB_VERSION(avformat),
|
||||
DEF_FFMPEG_LIB_VERSION(avutil),
|
||||
DEF_FFMPEG_LIB_VERSION(swscale),
|
||||
{NULL},
|
||||
DEF_FFMPEG_LIB_VERSION(avcodec),
|
||||
DEF_FFMPEG_LIB_VERSION(avdevice),
|
||||
DEF_FFMPEG_LIB_VERSION(avformat),
|
||||
DEF_FFMPEG_LIB_VERSION(avutil),
|
||||
DEF_FFMPEG_LIB_VERSION(swscale),
|
||||
{NULL},
|
||||
};
|
||||
|
||||
#undef DEF_FFMPEG_LIB_VERSION
|
||||
|
||||
static PyStructSequence_Desc app_ffmpeg_info_desc = {
|
||||
(char *)"bpy.app.ffmpeg", /* name */
|
||||
(char *)"This module contains information about FFmpeg blender is linked against", /* doc */
|
||||
app_ffmpeg_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_ffmpeg_info_fields) - 1,
|
||||
(char *)"bpy.app.ffmpeg", /* name */
|
||||
(char *)"This module contains information about FFmpeg blender is linked against", /* doc */
|
||||
app_ffmpeg_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_ffmpeg_info_fields) - 1,
|
||||
};
|
||||
|
||||
static PyObject *make_ffmpeg_info(void)
|
||||
{
|
||||
PyObject *ffmpeg_info;
|
||||
int pos = 0;
|
||||
PyObject *ffmpeg_info;
|
||||
int pos = 0;
|
||||
|
||||
#ifdef WITH_FFMPEG
|
||||
int curversion;
|
||||
int curversion;
|
||||
#endif
|
||||
|
||||
ffmpeg_info = PyStructSequence_New(&BlenderAppFFmpegType);
|
||||
if (ffmpeg_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ffmpeg_info = PyStructSequence_New(&BlenderAppFFmpegType);
|
||||
if (ffmpeg_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0 // UNUSED
|
||||
#define SetIntItem(flag) \
|
||||
PyStructSequence_SET_ITEM(ffmpeg_info, pos++, PyLong_FromLong(flag))
|
||||
#if 0 // UNUSED
|
||||
# define SetIntItem(flag) PyStructSequence_SET_ITEM(ffmpeg_info, pos++, PyLong_FromLong(flag))
|
||||
#endif
|
||||
#ifndef WITH_FFMPEG
|
||||
#define SetStrItem(str) \
|
||||
PyStructSequence_SET_ITEM(ffmpeg_info, pos++, PyUnicode_FromString(str))
|
||||
# define SetStrItem(str) PyStructSequence_SET_ITEM(ffmpeg_info, pos++, PyUnicode_FromString(str))
|
||||
#endif
|
||||
#define SetObjItem(obj) \
|
||||
PyStructSequence_SET_ITEM(ffmpeg_info, pos++, obj)
|
||||
#define SetObjItem(obj) PyStructSequence_SET_ITEM(ffmpeg_info, pos++, obj)
|
||||
|
||||
#ifdef WITH_FFMPEG
|
||||
# define FFMPEG_LIB_VERSION(lib) { \
|
||||
curversion = lib ## _version(); \
|
||||
SetObjItem(PyC_Tuple_Pack_I32(curversion >> 16, (curversion >> 8) % 256, curversion % 256)); \
|
||||
SetObjItem(PyUnicode_FromFormat("%2d, %2d, %2d", \
|
||||
curversion >> 16, (curversion >> 8) % 256, curversion % 256)); \
|
||||
} (void)0
|
||||
# define FFMPEG_LIB_VERSION(lib) \
|
||||
{ \
|
||||
curversion = lib##_version(); \
|
||||
SetObjItem( \
|
||||
PyC_Tuple_Pack_I32(curversion >> 16, (curversion >> 8) % 256, curversion % 256)); \
|
||||
SetObjItem(PyUnicode_FromFormat( \
|
||||
"%2d, %2d, %2d", curversion >> 16, (curversion >> 8) % 256, curversion % 256)); \
|
||||
} \
|
||||
(void)0
|
||||
#else
|
||||
# define FFMPEG_LIB_VERSION(lib) { \
|
||||
SetStrItem("Unknown"); \
|
||||
SetStrItem("Unknown"); \
|
||||
} (void)0
|
||||
# define FFMPEG_LIB_VERSION(lib) \
|
||||
{ \
|
||||
SetStrItem("Unknown"); \
|
||||
SetStrItem("Unknown"); \
|
||||
} \
|
||||
(void)0
|
||||
#endif
|
||||
|
||||
#ifdef WITH_FFMPEG
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
#else
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
#endif
|
||||
|
||||
FFMPEG_LIB_VERSION(avcodec);
|
||||
FFMPEG_LIB_VERSION(avdevice);
|
||||
FFMPEG_LIB_VERSION(avformat);
|
||||
FFMPEG_LIB_VERSION(avutil);
|
||||
FFMPEG_LIB_VERSION(swscale);
|
||||
FFMPEG_LIB_VERSION(avcodec);
|
||||
FFMPEG_LIB_VERSION(avdevice);
|
||||
FFMPEG_LIB_VERSION(avformat);
|
||||
FFMPEG_LIB_VERSION(avutil);
|
||||
FFMPEG_LIB_VERSION(swscale);
|
||||
|
||||
#undef FFMPEG_LIB_VERSION
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(ffmpeg_info);
|
||||
return NULL;
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(ffmpeg_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// #undef SetIntItem
|
||||
#undef SetStrItem
|
||||
#undef SetObjItem
|
||||
|
||||
return ffmpeg_info;
|
||||
return ffmpeg_info;
|
||||
}
|
||||
|
||||
PyObject *BPY_app_ffmpeg_struct(void)
|
||||
{
|
||||
PyObject *ret;
|
||||
PyObject *ret;
|
||||
|
||||
PyStructSequence_InitType(&BlenderAppFFmpegType, &app_ffmpeg_info_desc);
|
||||
PyStructSequence_InitType(&BlenderAppFFmpegType, &app_ffmpeg_info_desc);
|
||||
|
||||
ret = make_ffmpeg_info();
|
||||
ret = make_ffmpeg_info();
|
||||
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppFFmpegType.tp_init = NULL;
|
||||
BlenderAppFFmpegType.tp_new = NULL;
|
||||
BlenderAppFFmpegType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppFFmpegType.tp_init = NULL;
|
||||
BlenderAppFFmpegType.tp_new = NULL;
|
||||
BlenderAppFFmpegType.tp_hash = (hashfunc)
|
||||
_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
|
||||
PyObject *BPY_app_ffmpeg_struct(void);
|
||||
|
||||
#endif /* __BPY_APP_FFMPEG_H__ */
|
||||
#endif /* __BPY_APP_FFMPEG_H__ */
|
||||
|
||||
@@ -40,40 +40,42 @@ void bpy_app_generic_callback(struct Main *main, struct ID *id, void *arg);
|
||||
static PyTypeObject BlenderAppCbType;
|
||||
|
||||
static PyStructSequence_Field app_cb_info_fields[] = {
|
||||
{(char *)"frame_change_pre", (char *)"on frame change for playback and rendering (before)"},
|
||||
{(char *)"frame_change_post", (char *)"on frame change for playback and rendering (after)"},
|
||||
{(char *)"render_pre", (char *)"on render (before)"},
|
||||
{(char *)"render_post", (char *)"on render (after)"},
|
||||
{(char *)"render_write", (char *)"on writing a render frame (directly after the frame is written)"},
|
||||
{(char *)"render_stats", (char *)"on printing render statistics"},
|
||||
{(char *)"render_init", (char *)"on initialization of a render job"},
|
||||
{(char *)"render_complete", (char *)"on completion of render job"},
|
||||
{(char *)"render_cancel", (char *)"on canceling a render job"},
|
||||
{(char *)"load_pre", (char *)"on loading a new blend file (before)"},
|
||||
{(char *)"load_post", (char *)"on loading a new blend file (after)"},
|
||||
{(char *)"save_pre", (char *)"on saving a blend file (before)"},
|
||||
{(char *)"save_post", (char *)"on saving a blend file (after)"},
|
||||
{(char *)"undo_pre", (char *)"on loading an undo step (before)"},
|
||||
{(char *)"undo_post", (char *)"on loading an undo step (after)"},
|
||||
{(char *)"redo_pre", (char *)"on loading a redo step (before)"},
|
||||
{(char *)"redo_post", (char *)"on loading a redo step (after)"},
|
||||
{(char *)"depsgraph_update_pre", (char *)"on depsgraph update (pre)"},
|
||||
{(char *)"depsgraph_update_post", (char *)"on depsgraph update (post)"},
|
||||
{(char *)"version_update", (char *)"on ending the versioning code"},
|
||||
{(char *)"load_factory_startup_post", (char *)"on loading factory startup (after)"},
|
||||
{(char *)"frame_change_pre", (char *)"on frame change for playback and rendering (before)"},
|
||||
{(char *)"frame_change_post", (char *)"on frame change for playback and rendering (after)"},
|
||||
{(char *)"render_pre", (char *)"on render (before)"},
|
||||
{(char *)"render_post", (char *)"on render (after)"},
|
||||
{(char *)"render_write",
|
||||
(char *)"on writing a render frame (directly after the frame is written)"},
|
||||
{(char *)"render_stats", (char *)"on printing render statistics"},
|
||||
{(char *)"render_init", (char *)"on initialization of a render job"},
|
||||
{(char *)"render_complete", (char *)"on completion of render job"},
|
||||
{(char *)"render_cancel", (char *)"on canceling a render job"},
|
||||
{(char *)"load_pre", (char *)"on loading a new blend file (before)"},
|
||||
{(char *)"load_post", (char *)"on loading a new blend file (after)"},
|
||||
{(char *)"save_pre", (char *)"on saving a blend file (before)"},
|
||||
{(char *)"save_post", (char *)"on saving a blend file (after)"},
|
||||
{(char *)"undo_pre", (char *)"on loading an undo step (before)"},
|
||||
{(char *)"undo_post", (char *)"on loading an undo step (after)"},
|
||||
{(char *)"redo_pre", (char *)"on loading a redo step (before)"},
|
||||
{(char *)"redo_post", (char *)"on loading a redo step (after)"},
|
||||
{(char *)"depsgraph_update_pre", (char *)"on depsgraph update (pre)"},
|
||||
{(char *)"depsgraph_update_post", (char *)"on depsgraph update (post)"},
|
||||
{(char *)"version_update", (char *)"on ending the versioning code"},
|
||||
{(char *)"load_factory_startup_post", (char *)"on loading factory startup (after)"},
|
||||
|
||||
/* sets the permanent tag */
|
||||
/* sets the permanent tag */
|
||||
#define APP_CB_OTHER_FIELDS 1
|
||||
{(char *)"persistent", (char *)"Function decorator for callback functions not to be removed when loading new files"},
|
||||
{(char *)"persistent",
|
||||
(char *)"Function decorator for callback functions not to be removed when loading new files"},
|
||||
|
||||
{NULL},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static PyStructSequence_Desc app_cb_info_desc = {
|
||||
(char *)"bpy.app.handlers", /* name */
|
||||
(char *)"This module contains callback lists", /* doc */
|
||||
app_cb_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_cb_info_fields) - 1,
|
||||
(char *)"bpy.app.handlers", /* name */
|
||||
(char *)"This module contains callback lists", /* doc */
|
||||
app_cb_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_cb_info_fields) - 1,
|
||||
};
|
||||
|
||||
#if 0
|
||||
@@ -86,251 +88,250 @@ static PyStructSequence_Desc app_cb_info_desc = {
|
||||
/* permanent tagging code */
|
||||
#define PERMINENT_CB_ID "_bpy_persistent"
|
||||
|
||||
static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *UNUSED(kwds))
|
||||
static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type),
|
||||
PyObject *args,
|
||||
PyObject *UNUSED(kwds))
|
||||
{
|
||||
PyObject *value;
|
||||
PyObject *value;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O:bpy.app.handlers.persistent", &value)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "O:bpy.app.handlers.persistent", &value)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyFunction_Check(value)) {
|
||||
PyObject **dict_ptr = _PyObject_GetDictPtr(value);
|
||||
if (dict_ptr == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"bpy.app.handlers.persistent wasn't able to "
|
||||
"get the dictionary from the function passed");
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
/* set id */
|
||||
if (*dict_ptr == NULL) {
|
||||
*dict_ptr = PyDict_New();
|
||||
}
|
||||
if (PyFunction_Check(value)) {
|
||||
PyObject **dict_ptr = _PyObject_GetDictPtr(value);
|
||||
if (dict_ptr == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"bpy.app.handlers.persistent wasn't able to "
|
||||
"get the dictionary from the function passed");
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
/* set id */
|
||||
if (*dict_ptr == NULL) {
|
||||
*dict_ptr = PyDict_New();
|
||||
}
|
||||
|
||||
PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None);
|
||||
}
|
||||
PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None);
|
||||
}
|
||||
|
||||
Py_INCREF(value);
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"bpy.app.handlers.persistent expected a function");
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF(value);
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError, "bpy.app.handlers.persistent expected a function");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* dummy type because decorators can't be PyCFunctions */
|
||||
static PyTypeObject BPyPersistent_Type = {
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
#else
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
#endif
|
||||
|
||||
"persistent", /* tp_name */
|
||||
0, /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
/* methods */
|
||||
0, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_reserved */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
||||
Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||
0, /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
bpy_app_handlers_persistent_new, /* tp_new */
|
||||
0, /* tp_free */
|
||||
"persistent", /* tp_name */
|
||||
0, /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
/* methods */
|
||||
0, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_reserved */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||
0, /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
bpy_app_handlers_persistent_new, /* tp_new */
|
||||
0, /* tp_free */
|
||||
};
|
||||
|
||||
static PyObject *py_cb_array[BLI_CB_EVT_TOT] = {NULL};
|
||||
|
||||
static PyObject *make_app_cb_info(void)
|
||||
{
|
||||
PyObject *app_cb_info;
|
||||
int pos;
|
||||
PyObject *app_cb_info;
|
||||
int pos;
|
||||
|
||||
app_cb_info = PyStructSequence_New(&BlenderAppCbType);
|
||||
if (app_cb_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
app_cb_info = PyStructSequence_New(&BlenderAppCbType);
|
||||
if (app_cb_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
|
||||
if (app_cb_info_fields[pos].name == NULL) {
|
||||
Py_FatalError("invalid callback slots 1");
|
||||
}
|
||||
PyStructSequence_SET_ITEM(app_cb_info, pos, (py_cb_array[pos] = PyList_New(0)));
|
||||
}
|
||||
if (app_cb_info_fields[pos + APP_CB_OTHER_FIELDS].name != NULL) {
|
||||
Py_FatalError("invalid callback slots 2");
|
||||
}
|
||||
for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
|
||||
if (app_cb_info_fields[pos].name == NULL) {
|
||||
Py_FatalError("invalid callback slots 1");
|
||||
}
|
||||
PyStructSequence_SET_ITEM(app_cb_info, pos, (py_cb_array[pos] = PyList_New(0)));
|
||||
}
|
||||
if (app_cb_info_fields[pos + APP_CB_OTHER_FIELDS].name != NULL) {
|
||||
Py_FatalError("invalid callback slots 2");
|
||||
}
|
||||
|
||||
/* custom function */
|
||||
PyStructSequence_SET_ITEM(app_cb_info, pos++, (PyObject *)&BPyPersistent_Type);
|
||||
/* custom function */
|
||||
PyStructSequence_SET_ITEM(app_cb_info, pos++, (PyObject *)&BPyPersistent_Type);
|
||||
|
||||
return app_cb_info;
|
||||
return app_cb_info;
|
||||
}
|
||||
|
||||
PyObject *BPY_app_handlers_struct(void)
|
||||
{
|
||||
PyObject *ret;
|
||||
PyObject *ret;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
BPyPersistent_Type.ob_base.ob_base.ob_type = &PyType_Type;
|
||||
BPyPersistent_Type.ob_base.ob_base.ob_type = &PyType_Type;
|
||||
#endif
|
||||
|
||||
if (PyType_Ready(&BPyPersistent_Type) < 0) {
|
||||
BLI_assert(!"error initializing 'bpy.app.handlers.persistent'");
|
||||
}
|
||||
if (PyType_Ready(&BPyPersistent_Type) < 0) {
|
||||
BLI_assert(!"error initializing 'bpy.app.handlers.persistent'");
|
||||
}
|
||||
|
||||
PyStructSequence_InitType(&BlenderAppCbType, &app_cb_info_desc);
|
||||
PyStructSequence_InitType(&BlenderAppCbType, &app_cb_info_desc);
|
||||
|
||||
ret = make_app_cb_info();
|
||||
ret = make_app_cb_info();
|
||||
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppCbType.tp_init = NULL;
|
||||
BlenderAppCbType.tp_new = NULL;
|
||||
BlenderAppCbType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppCbType.tp_init = NULL;
|
||||
BlenderAppCbType.tp_new = NULL;
|
||||
BlenderAppCbType.tp_hash = (hashfunc)
|
||||
_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
|
||||
/* assign the C callbacks */
|
||||
if (ret) {
|
||||
static bCallbackFuncStore funcstore_array[BLI_CB_EVT_TOT] = {{NULL}};
|
||||
bCallbackFuncStore *funcstore;
|
||||
int pos = 0;
|
||||
/* assign the C callbacks */
|
||||
if (ret) {
|
||||
static bCallbackFuncStore funcstore_array[BLI_CB_EVT_TOT] = {{NULL}};
|
||||
bCallbackFuncStore *funcstore;
|
||||
int pos = 0;
|
||||
|
||||
for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
|
||||
funcstore = &funcstore_array[pos];
|
||||
funcstore->func = bpy_app_generic_callback;
|
||||
funcstore->alloc = 0;
|
||||
funcstore->arg = POINTER_FROM_INT(pos);
|
||||
BLI_callback_add(funcstore, pos);
|
||||
}
|
||||
}
|
||||
for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
|
||||
funcstore = &funcstore_array[pos];
|
||||
funcstore->func = bpy_app_generic_callback;
|
||||
funcstore->alloc = 0;
|
||||
funcstore->arg = POINTER_FROM_INT(pos);
|
||||
BLI_callback_add(funcstore, pos);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void BPY_app_handlers_reset(const short do_all)
|
||||
{
|
||||
PyGILState_STATE gilstate;
|
||||
int pos = 0;
|
||||
PyGILState_STATE gilstate;
|
||||
int pos = 0;
|
||||
|
||||
gilstate = PyGILState_Ensure();
|
||||
gilstate = PyGILState_Ensure();
|
||||
|
||||
if (do_all) {
|
||||
for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
|
||||
/* clear list */
|
||||
PyList_SetSlice(py_cb_array[pos], 0, PY_SSIZE_T_MAX, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* save string conversion thrashing */
|
||||
PyObject *perm_id_str = PyUnicode_FromString(PERMINENT_CB_ID);
|
||||
if (do_all) {
|
||||
for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
|
||||
/* clear list */
|
||||
PyList_SetSlice(py_cb_array[pos], 0, PY_SSIZE_T_MAX, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* save string conversion thrashing */
|
||||
PyObject *perm_id_str = PyUnicode_FromString(PERMINENT_CB_ID);
|
||||
|
||||
for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
|
||||
/* clear only items without PERMINENT_CB_ID */
|
||||
PyObject *ls = py_cb_array[pos];
|
||||
Py_ssize_t i;
|
||||
for (pos = 0; pos < BLI_CB_EVT_TOT; pos++) {
|
||||
/* clear only items without PERMINENT_CB_ID */
|
||||
PyObject *ls = py_cb_array[pos];
|
||||
Py_ssize_t i;
|
||||
|
||||
PyObject *item;
|
||||
PyObject **dict_ptr;
|
||||
PyObject *item;
|
||||
PyObject **dict_ptr;
|
||||
|
||||
for (i = PyList_GET_SIZE(ls) - 1; i >= 0; i--) {
|
||||
for (i = PyList_GET_SIZE(ls) - 1; i >= 0; i--) {
|
||||
|
||||
if ((PyFunction_Check((item = PyList_GET_ITEM(ls, i)))) &&
|
||||
(dict_ptr = _PyObject_GetDictPtr(item)) &&
|
||||
(*dict_ptr) &&
|
||||
(PyDict_GetItem(*dict_ptr, perm_id_str) != NULL))
|
||||
{
|
||||
/* keep */
|
||||
}
|
||||
else {
|
||||
/* remove */
|
||||
/* PySequence_DelItem(ls, i); */ /* more obvious buw slower */
|
||||
PyList_SetSlice(ls, i, i + 1, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((PyFunction_Check((item = PyList_GET_ITEM(ls, i)))) &&
|
||||
(dict_ptr = _PyObject_GetDictPtr(item)) && (*dict_ptr) &&
|
||||
(PyDict_GetItem(*dict_ptr, perm_id_str) != NULL)) {
|
||||
/* keep */
|
||||
}
|
||||
else {
|
||||
/* remove */
|
||||
/* PySequence_DelItem(ls, i); */ /* more obvious buw slower */
|
||||
PyList_SetSlice(ls, i, i + 1, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(perm_id_str);
|
||||
}
|
||||
Py_DECREF(perm_id_str);
|
||||
}
|
||||
|
||||
PyGILState_Release(gilstate);
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
|
||||
/* the actual callback - not necessarily called from py */
|
||||
void bpy_app_generic_callback(struct Main *UNUSED(main), struct ID *id, void *arg)
|
||||
{
|
||||
PyObject *cb_list = py_cb_array[POINTER_AS_INT(arg)];
|
||||
if (PyList_GET_SIZE(cb_list) > 0) {
|
||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||
PyObject *cb_list = py_cb_array[POINTER_AS_INT(arg)];
|
||||
if (PyList_GET_SIZE(cb_list) > 0) {
|
||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||
|
||||
PyObject *args = PyTuple_New(1); /* save python creating each call */
|
||||
PyObject *func;
|
||||
PyObject *ret;
|
||||
Py_ssize_t pos;
|
||||
PyObject *args = PyTuple_New(1); /* save python creating each call */
|
||||
PyObject *func;
|
||||
PyObject *ret;
|
||||
Py_ssize_t pos;
|
||||
|
||||
/* setup arguments */
|
||||
if (id) {
|
||||
PointerRNA id_ptr;
|
||||
RNA_id_pointer_create(id, &id_ptr);
|
||||
PyTuple_SET_ITEM(args, 0, pyrna_struct_CreatePyObject(&id_ptr));
|
||||
}
|
||||
else {
|
||||
PyTuple_SET_ITEM(args, 0, Py_INCREF_RET(Py_None));
|
||||
}
|
||||
/* setup arguments */
|
||||
if (id) {
|
||||
PointerRNA id_ptr;
|
||||
RNA_id_pointer_create(id, &id_ptr);
|
||||
PyTuple_SET_ITEM(args, 0, pyrna_struct_CreatePyObject(&id_ptr));
|
||||
}
|
||||
else {
|
||||
PyTuple_SET_ITEM(args, 0, Py_INCREF_RET(Py_None));
|
||||
}
|
||||
|
||||
/* Iterate the list and run the callbacks
|
||||
* note: don't store the list size since the scripts may remove themselves */
|
||||
for (pos = 0; pos < PyList_GET_SIZE(cb_list); pos++) {
|
||||
func = PyList_GET_ITEM(cb_list, pos);
|
||||
ret = PyObject_Call(func, args, NULL);
|
||||
if (ret == NULL) {
|
||||
/* Don't set last system variables because they might cause some
|
||||
* dangling pointers to external render engines (when exception
|
||||
* happens during rendering) which will break logic of render pipeline
|
||||
* which expects to be the only user of render engine when rendering
|
||||
* is finished.
|
||||
*/
|
||||
PyErr_PrintEx(0);
|
||||
PyErr_Clear();
|
||||
}
|
||||
else {
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
}
|
||||
/* Iterate the list and run the callbacks
|
||||
* note: don't store the list size since the scripts may remove themselves */
|
||||
for (pos = 0; pos < PyList_GET_SIZE(cb_list); pos++) {
|
||||
func = PyList_GET_ITEM(cb_list, pos);
|
||||
ret = PyObject_Call(func, args, NULL);
|
||||
if (ret == NULL) {
|
||||
/* Don't set last system variables because they might cause some
|
||||
* dangling pointers to external render engines (when exception
|
||||
* happens during rendering) which will break logic of render pipeline
|
||||
* which expects to be the only user of render engine when rendering
|
||||
* is finished.
|
||||
*/
|
||||
PyErr_PrintEx(0);
|
||||
PyErr_Clear();
|
||||
}
|
||||
else {
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(args);
|
||||
Py_DECREF(args);
|
||||
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,151 +33,149 @@
|
||||
#include "bpy_app_icons.h"
|
||||
|
||||
/* We may want to load direct from file. */
|
||||
PyDoc_STRVAR(bpy_app_icons_new_triangles_doc,
|
||||
".. function:: new_triangles(range, coords, colors)"
|
||||
"\n"
|
||||
" Create a new icon from triangle geometry.\n"
|
||||
"\n"
|
||||
" :arg range: Pair of ints.\n"
|
||||
" :type range: tuple.\n"
|
||||
" :arg coords: Sequence of bytes (6 floats for one triangle) for (X, Y) coordinates.\n"
|
||||
" :type coords: byte sequence.\n"
|
||||
" :arg colors: Sequence of ints (12 for one triangles) for RGBA.\n"
|
||||
" :type colors: byte sequence.\n"
|
||||
" :return: Unique icon value (pass to interface ``icon_value`` argument).\n"
|
||||
" :rtype: int\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpy_app_icons_new_triangles_doc,
|
||||
".. function:: new_triangles(range, coords, colors)"
|
||||
"\n"
|
||||
" Create a new icon from triangle geometry.\n"
|
||||
"\n"
|
||||
" :arg range: Pair of ints.\n"
|
||||
" :type range: tuple.\n"
|
||||
" :arg coords: Sequence of bytes (6 floats for one triangle) for (X, Y) coordinates.\n"
|
||||
" :type coords: byte sequence.\n"
|
||||
" :arg colors: Sequence of ints (12 for one triangles) for RGBA.\n"
|
||||
" :type colors: byte sequence.\n"
|
||||
" :return: Unique icon value (pass to interface ``icon_value`` argument).\n"
|
||||
" :rtype: int\n");
|
||||
static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
/* bytes */
|
||||
uchar coords_range[2];
|
||||
PyObject *py_coords, *py_colors;
|
||||
/* bytes */
|
||||
uchar coords_range[2];
|
||||
PyObject *py_coords, *py_colors;
|
||||
|
||||
static const char *_keywords[] = {"range", "coords", "colors", NULL};
|
||||
static _PyArg_Parser _parser = {"(BB)SS:new_triangles", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&coords_range[0], &coords_range[1], &py_coords, &py_colors))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"range", "coords", "colors", NULL};
|
||||
static _PyArg_Parser _parser = {"(BB)SS:new_triangles", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser, &coords_range[0], &coords_range[1], &py_coords, &py_colors)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int coords_len = PyBytes_GET_SIZE(py_coords);
|
||||
const int tris_len = coords_len / 6;
|
||||
if (tris_len * 6 != coords_len) {
|
||||
PyErr_SetString(PyExc_ValueError, "coords must be multiple of 6");
|
||||
return NULL;
|
||||
}
|
||||
if (PyBytes_GET_SIZE(py_colors) != 2 * coords_len) {
|
||||
PyErr_SetString(PyExc_ValueError, "colors must be twice size of coords");
|
||||
return NULL;
|
||||
}
|
||||
const int coords_len = PyBytes_GET_SIZE(py_coords);
|
||||
const int tris_len = coords_len / 6;
|
||||
if (tris_len * 6 != coords_len) {
|
||||
PyErr_SetString(PyExc_ValueError, "coords must be multiple of 6");
|
||||
return NULL;
|
||||
}
|
||||
if (PyBytes_GET_SIZE(py_colors) != 2 * coords_len) {
|
||||
PyErr_SetString(PyExc_ValueError, "colors must be twice size of coords");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int coords_size = sizeof(uchar[2]) * tris_len * 3;
|
||||
int colors_size = sizeof(uchar[4]) * tris_len * 3;
|
||||
uchar (*coords)[2] = MEM_mallocN(coords_size, __func__);
|
||||
uchar (*colors)[4] = MEM_mallocN(colors_size, __func__);
|
||||
int coords_size = sizeof(uchar[2]) * tris_len * 3;
|
||||
int colors_size = sizeof(uchar[4]) * tris_len * 3;
|
||||
uchar(*coords)[2] = MEM_mallocN(coords_size, __func__);
|
||||
uchar(*colors)[4] = MEM_mallocN(colors_size, __func__);
|
||||
|
||||
memcpy(coords, PyBytes_AS_STRING(py_coords), coords_size);
|
||||
memcpy(colors, PyBytes_AS_STRING(py_colors), colors_size);
|
||||
memcpy(coords, PyBytes_AS_STRING(py_coords), coords_size);
|
||||
memcpy(colors, PyBytes_AS_STRING(py_colors), colors_size);
|
||||
|
||||
struct Icon_Geom *geom = MEM_mallocN(sizeof(*geom), __func__);
|
||||
geom->coords_len = tris_len;
|
||||
geom->coords_range[0] = coords_range[0];
|
||||
geom->coords_range[1] = coords_range[1];
|
||||
geom->coords = coords;
|
||||
geom->colors = colors;
|
||||
geom->icon_id = 0;
|
||||
int icon_id = BKE_icon_geom_ensure(geom);
|
||||
return PyLong_FromLong(icon_id);
|
||||
struct Icon_Geom *geom = MEM_mallocN(sizeof(*geom), __func__);
|
||||
geom->coords_len = tris_len;
|
||||
geom->coords_range[0] = coords_range[0];
|
||||
geom->coords_range[1] = coords_range[1];
|
||||
geom->coords = coords;
|
||||
geom->colors = colors;
|
||||
geom->icon_id = 0;
|
||||
int icon_id = BKE_icon_geom_ensure(geom);
|
||||
return PyLong_FromLong(icon_id);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_app_icons_new_triangles_from_file_doc,
|
||||
".. function:: new_triangles_from_file(filename)"
|
||||
"\n"
|
||||
" Create a new icon from triangle geometry.\n"
|
||||
"\n"
|
||||
" :arg filename: File path.\n"
|
||||
" :type filename: string.\n"
|
||||
" :return: Unique icon value (pass to interface ``icon_value`` argument).\n"
|
||||
" :rtype: int\n"
|
||||
);
|
||||
static PyObject *bpy_app_icons_new_triangles_from_file(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
".. function:: new_triangles_from_file(filename)"
|
||||
"\n"
|
||||
" Create a new icon from triangle geometry.\n"
|
||||
"\n"
|
||||
" :arg filename: File path.\n"
|
||||
" :type filename: string.\n"
|
||||
" :return: Unique icon value (pass to interface ``icon_value`` argument).\n"
|
||||
" :rtype: int\n");
|
||||
static PyObject *bpy_app_icons_new_triangles_from_file(PyObject *UNUSED(self),
|
||||
PyObject *args,
|
||||
PyObject *kw)
|
||||
{
|
||||
/* bytes */
|
||||
char *filename;
|
||||
/* bytes */
|
||||
char *filename;
|
||||
|
||||
static const char *_keywords[] = {"filename", NULL};
|
||||
static _PyArg_Parser _parser = {"s:new_triangles_from_file", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&filename))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"filename", NULL};
|
||||
static _PyArg_Parser _parser = {"s:new_triangles_from_file", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &filename)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct Icon_Geom *geom = BKE_icon_geom_from_file(filename);
|
||||
if (geom == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "Unable to load from file");
|
||||
return NULL;
|
||||
}
|
||||
int icon_id = BKE_icon_geom_ensure(geom);
|
||||
return PyLong_FromLong(icon_id);
|
||||
struct Icon_Geom *geom = BKE_icon_geom_from_file(filename);
|
||||
if (geom == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "Unable to load from file");
|
||||
return NULL;
|
||||
}
|
||||
int icon_id = BKE_icon_geom_ensure(geom);
|
||||
return PyLong_FromLong(icon_id);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_app_icons_release_doc,
|
||||
".. function:: release(icon_id)"
|
||||
"\n"
|
||||
" Release the icon.\n"
|
||||
);
|
||||
".. function:: release(icon_id)"
|
||||
"\n"
|
||||
" Release the icon.\n");
|
||||
static PyObject *bpy_app_icons_release(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
int icon_id;
|
||||
static const char *_keywords[] = {"icon_id", NULL};
|
||||
static _PyArg_Parser _parser = {"i:release", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&icon_id))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
int icon_id;
|
||||
static const char *_keywords[] = {"icon_id", NULL};
|
||||
static _PyArg_Parser _parser = {"i:release", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &icon_id)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!BKE_icon_delete_unmanaged(icon_id)) {
|
||||
PyErr_SetString(PyExc_ValueError, "invalid icon_id");
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
if (!BKE_icon_delete_unmanaged(icon_id)) {
|
||||
PyErr_SetString(PyExc_ValueError, "invalid icon_id");
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static struct PyMethodDef M_AppIcons_methods[] = {
|
||||
{"new_triangles", (PyCFunction)bpy_app_icons_new_triangles,
|
||||
METH_VARARGS | METH_KEYWORDS, bpy_app_icons_new_triangles_doc},
|
||||
{"new_triangles_from_file", (PyCFunction)bpy_app_icons_new_triangles_from_file,
|
||||
METH_VARARGS | METH_KEYWORDS, bpy_app_icons_new_triangles_from_file_doc},
|
||||
{"release", (PyCFunction)bpy_app_icons_release,
|
||||
METH_VARARGS | METH_KEYWORDS, bpy_app_icons_release_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"new_triangles",
|
||||
(PyCFunction)bpy_app_icons_new_triangles,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_app_icons_new_triangles_doc},
|
||||
{"new_triangles_from_file",
|
||||
(PyCFunction)bpy_app_icons_new_triangles_from_file,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_app_icons_new_triangles_from_file_doc},
|
||||
{"release",
|
||||
(PyCFunction)bpy_app_icons_release,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_app_icons_release_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
static struct PyModuleDef M_AppIcons_module_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"bpy.app.icons", /* m_name */
|
||||
NULL, /* m_doc */
|
||||
0, /* m_size */
|
||||
M_AppIcons_methods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"bpy.app.icons", /* m_name */
|
||||
NULL, /* m_doc */
|
||||
0, /* m_size */
|
||||
M_AppIcons_methods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
};
|
||||
|
||||
PyObject *BPY_app_icons_module(void)
|
||||
{
|
||||
PyObject *sys_modules = PyImport_GetModuleDict();
|
||||
PyObject *sys_modules = PyImport_GetModuleDict();
|
||||
|
||||
PyObject *mod = PyModule_Create(&M_AppIcons_module_def);
|
||||
PyObject *mod = PyModule_Create(&M_AppIcons_module_def);
|
||||
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(mod), mod);
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(mod), mod);
|
||||
|
||||
return mod;
|
||||
return mod;
|
||||
}
|
||||
|
||||
@@ -32,76 +32,78 @@
|
||||
static PyTypeObject BlenderAppOCIOType;
|
||||
|
||||
static PyStructSequence_Field app_ocio_info_fields[] = {
|
||||
{(char *)"supported", (char *)("Boolean, True when Blender is built with OpenColorIO support")},
|
||||
{(char *)("version"), (char *)("The OpenColorIO version as a tuple of 3 numbers")},
|
||||
{(char *)("version_string"), (char *)("The OpenColorIO version formatted as a string")},
|
||||
{NULL},
|
||||
{(char *)"supported",
|
||||
(char *)("Boolean, True when Blender is built with OpenColorIO support")},
|
||||
{(char *)("version"), (char *)("The OpenColorIO version as a tuple of 3 numbers")},
|
||||
{(char *)("version_string"), (char *)("The OpenColorIO version formatted as a string")},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static PyStructSequence_Desc app_ocio_info_desc = {
|
||||
(char *)"bpy.app.ocio", /* name */
|
||||
(char *)"This module contains information about OpenColorIO blender is linked against", /* doc */
|
||||
app_ocio_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_ocio_info_fields) - 1,
|
||||
(char *)"bpy.app.ocio", /* name */
|
||||
(char
|
||||
*)"This module contains information about OpenColorIO blender is linked against", /* doc */
|
||||
app_ocio_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_ocio_info_fields) - 1,
|
||||
};
|
||||
|
||||
static PyObject *make_ocio_info(void)
|
||||
{
|
||||
PyObject *ocio_info;
|
||||
int pos = 0;
|
||||
PyObject *ocio_info;
|
||||
int pos = 0;
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
int curversion;
|
||||
int curversion;
|
||||
#endif
|
||||
|
||||
ocio_info = PyStructSequence_New(&BlenderAppOCIOType);
|
||||
if (ocio_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ocio_info = PyStructSequence_New(&BlenderAppOCIOType);
|
||||
if (ocio_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef WITH_OCIO
|
||||
#define SetStrItem(str) \
|
||||
PyStructSequence_SET_ITEM(ocio_info, pos++, PyUnicode_FromString(str))
|
||||
# define SetStrItem(str) PyStructSequence_SET_ITEM(ocio_info, pos++, PyUnicode_FromString(str))
|
||||
#endif
|
||||
|
||||
#define SetObjItem(obj) \
|
||||
PyStructSequence_SET_ITEM(ocio_info, pos++, obj)
|
||||
#define SetObjItem(obj) PyStructSequence_SET_ITEM(ocio_info, pos++, obj)
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
curversion = OCIO_getVersionHex();
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(curversion >> 24, (curversion >> 16) % 256, (curversion >> 8) % 256));
|
||||
SetObjItem(PyUnicode_FromFormat("%2d, %2d, %2d",
|
||||
curversion >> 24, (curversion >> 16) % 256, (curversion >> 8) % 256));
|
||||
curversion = OCIO_getVersionHex();
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
SetObjItem(
|
||||
PyC_Tuple_Pack_I32(curversion >> 24, (curversion >> 16) % 256, (curversion >> 8) % 256));
|
||||
SetObjItem(PyUnicode_FromFormat(
|
||||
"%2d, %2d, %2d", curversion >> 24, (curversion >> 16) % 256, (curversion >> 8) % 256));
|
||||
#else
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
|
||||
SetStrItem("Unknown");
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
|
||||
SetStrItem("Unknown");
|
||||
#endif
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(ocio_info);
|
||||
return NULL;
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(ocio_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef SetStrItem
|
||||
#undef SetObjItem
|
||||
|
||||
return ocio_info;
|
||||
return ocio_info;
|
||||
}
|
||||
|
||||
PyObject *BPY_app_ocio_struct(void)
|
||||
{
|
||||
PyObject *ret;
|
||||
PyObject *ret;
|
||||
|
||||
PyStructSequence_InitType(&BlenderAppOCIOType, &app_ocio_info_desc);
|
||||
PyStructSequence_InitType(&BlenderAppOCIOType, &app_ocio_info_desc);
|
||||
|
||||
ret = make_ocio_info();
|
||||
ret = make_ocio_info();
|
||||
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppOCIOType.tp_init = NULL;
|
||||
BlenderAppOCIOType.tp_new = NULL;
|
||||
BlenderAppOCIOType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppOCIOType.tp_init = NULL;
|
||||
BlenderAppOCIOType.tp_new = NULL;
|
||||
BlenderAppOCIOType.tp_hash = (hashfunc)
|
||||
_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
|
||||
PyObject *BPY_app_ocio_struct(void);
|
||||
|
||||
#endif /* __BPY_APP_OCIO_H__ */
|
||||
#endif /* __BPY_APP_OCIO_H__ */
|
||||
|
||||
@@ -32,76 +32,77 @@
|
||||
static PyTypeObject BlenderAppOIIOType;
|
||||
|
||||
static PyStructSequence_Field app_oiio_info_fields[] = {
|
||||
{(char *)"supported", (char *)("Boolean, True when Blender is built with OpenImageIO support")},
|
||||
{(char *)("version"), (char *)("The OpenImageIO version as a tuple of 3 numbers")},
|
||||
{(char *)("version_string"), (char *)("The OpenImageIO version formatted as a string")},
|
||||
{NULL},
|
||||
{(char *)"supported",
|
||||
(char *)("Boolean, True when Blender is built with OpenImageIO support")},
|
||||
{(char *)("version"), (char *)("The OpenImageIO version as a tuple of 3 numbers")},
|
||||
{(char *)("version_string"), (char *)("The OpenImageIO version formatted as a string")},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static PyStructSequence_Desc app_oiio_info_desc = {
|
||||
(char *)"bpy.app.oiio", /* name */
|
||||
(char *)"This module contains information about OpeImageIO blender is linked against", /* doc */
|
||||
app_oiio_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_oiio_info_fields) - 1,
|
||||
(char *)"bpy.app.oiio", /* name */
|
||||
(char
|
||||
*)"This module contains information about OpeImageIO blender is linked against", /* doc */
|
||||
app_oiio_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_oiio_info_fields) - 1,
|
||||
};
|
||||
|
||||
static PyObject *make_oiio_info(void)
|
||||
{
|
||||
PyObject *oiio_info;
|
||||
int pos = 0;
|
||||
PyObject *oiio_info;
|
||||
int pos = 0;
|
||||
|
||||
#ifdef WITH_OPENIMAGEIO
|
||||
int curversion;
|
||||
int curversion;
|
||||
#endif
|
||||
|
||||
oiio_info = PyStructSequence_New(&BlenderAppOIIOType);
|
||||
if (oiio_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
oiio_info = PyStructSequence_New(&BlenderAppOIIOType);
|
||||
if (oiio_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef WITH_OPENIMAGEIO
|
||||
#define SetStrItem(str) \
|
||||
PyStructSequence_SET_ITEM(oiio_info, pos++, PyUnicode_FromString(str))
|
||||
# define SetStrItem(str) PyStructSequence_SET_ITEM(oiio_info, pos++, PyUnicode_FromString(str))
|
||||
#endif
|
||||
|
||||
#define SetObjItem(obj) \
|
||||
PyStructSequence_SET_ITEM(oiio_info, pos++, obj)
|
||||
#define SetObjItem(obj) PyStructSequence_SET_ITEM(oiio_info, pos++, obj)
|
||||
|
||||
#ifdef WITH_OPENIMAGEIO
|
||||
curversion = OIIO_getVersionHex();
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(curversion / 10000, (curversion / 100) % 100, curversion % 100));
|
||||
SetObjItem(PyUnicode_FromFormat("%2d, %2d, %2d",
|
||||
curversion / 10000, (curversion / 100) % 100, curversion % 100));
|
||||
curversion = OIIO_getVersionHex();
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(curversion / 10000, (curversion / 100) % 100, curversion % 100));
|
||||
SetObjItem(PyUnicode_FromFormat(
|
||||
"%2d, %2d, %2d", curversion / 10000, (curversion / 100) % 100, curversion % 100));
|
||||
#else
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
|
||||
SetStrItem("Unknown");
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
|
||||
SetStrItem("Unknown");
|
||||
#endif
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(oiio_info);
|
||||
return NULL;
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(oiio_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef SetStrItem
|
||||
#undef SetObjItem
|
||||
|
||||
return oiio_info;
|
||||
return oiio_info;
|
||||
}
|
||||
|
||||
PyObject *BPY_app_oiio_struct(void)
|
||||
{
|
||||
PyObject *ret;
|
||||
PyObject *ret;
|
||||
|
||||
PyStructSequence_InitType(&BlenderAppOIIOType, &app_oiio_info_desc);
|
||||
PyStructSequence_InitType(&BlenderAppOIIOType, &app_oiio_info_desc);
|
||||
|
||||
ret = make_oiio_info();
|
||||
ret = make_oiio_info();
|
||||
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppOIIOType.tp_init = NULL;
|
||||
BlenderAppOIIOType.tp_new = NULL;
|
||||
BlenderAppOIIOType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppOIIOType.tp_init = NULL;
|
||||
BlenderAppOIIOType.tp_new = NULL;
|
||||
BlenderAppOIIOType.tp_hash = (hashfunc)
|
||||
_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
|
||||
PyObject *BPY_app_oiio_struct(void);
|
||||
|
||||
#endif /* __BPY_APP_OIIO_H__ */
|
||||
#endif /* __BPY_APP_OIIO_H__ */
|
||||
|
||||
@@ -32,73 +32,73 @@
|
||||
static PyTypeObject BlenderAppOpenSubdivType;
|
||||
|
||||
static PyStructSequence_Field app_opensubdiv_info_fields[] = {
|
||||
{(char *)"supported", (char *)("Boolean, True when Blender is built with OpenSubdiv support")},
|
||||
{(char *)("version"), (char *)("The OpenSubdiv version as a tuple of 3 numbers")},
|
||||
{(char *)("version_string"), (char *)("The OpenSubdiv version formatted as a string")},
|
||||
{NULL},
|
||||
{(char *)"supported", (char *)("Boolean, True when Blender is built with OpenSubdiv support")},
|
||||
{(char *)("version"), (char *)("The OpenSubdiv version as a tuple of 3 numbers")},
|
||||
{(char *)("version_string"), (char *)("The OpenSubdiv version formatted as a string")},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static PyStructSequence_Desc app_opensubdiv_info_desc = {
|
||||
(char *)"bpy.app.opensubdiv", /* name */
|
||||
(char *)"This module contains information about OpenSubdiv blender is linked against", /* doc */
|
||||
app_opensubdiv_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_opensubdiv_info_fields) - 1,
|
||||
(char *)"bpy.app.opensubdiv", /* name */
|
||||
(char
|
||||
*)"This module contains information about OpenSubdiv blender is linked against", /* doc */
|
||||
app_opensubdiv_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_opensubdiv_info_fields) - 1,
|
||||
};
|
||||
|
||||
static PyObject *make_opensubdiv_info(void)
|
||||
{
|
||||
PyObject *opensubdiv_info;
|
||||
int pos = 0;
|
||||
PyObject *opensubdiv_info;
|
||||
int pos = 0;
|
||||
|
||||
opensubdiv_info = PyStructSequence_New(&BlenderAppOpenSubdivType);
|
||||
if (opensubdiv_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
opensubdiv_info = PyStructSequence_New(&BlenderAppOpenSubdivType);
|
||||
if (opensubdiv_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef WITH_OPENSUBDIV
|
||||
#define SetStrItem(str) \
|
||||
PyStructSequence_SET_ITEM(opensubdiv_info, pos++, PyUnicode_FromString(str))
|
||||
# define SetStrItem(str) \
|
||||
PyStructSequence_SET_ITEM(opensubdiv_info, pos++, PyUnicode_FromString(str))
|
||||
#endif
|
||||
|
||||
#define SetObjItem(obj) \
|
||||
PyStructSequence_SET_ITEM(opensubdiv_info, pos++, obj)
|
||||
#define SetObjItem(obj) PyStructSequence_SET_ITEM(opensubdiv_info, pos++, obj)
|
||||
|
||||
#ifdef WITH_OPENSUBDIV
|
||||
int curversion = openSubdiv_getVersionHex();
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(curversion / 10000, (curversion / 100) % 100, curversion % 100));
|
||||
SetObjItem(PyUnicode_FromFormat("%2d, %2d, %2d",
|
||||
curversion / 10000, (curversion / 100) % 100, curversion % 100));
|
||||
int curversion = openSubdiv_getVersionHex();
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(curversion / 10000, (curversion / 100) % 100, curversion % 100));
|
||||
SetObjItem(PyUnicode_FromFormat(
|
||||
"%2d, %2d, %2d", curversion / 10000, (curversion / 100) % 100, curversion % 100));
|
||||
#else
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
|
||||
SetStrItem("Unknown");
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
|
||||
SetStrItem("Unknown");
|
||||
#endif
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(opensubdiv_info);
|
||||
return NULL;
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(opensubdiv_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef SetStrItem
|
||||
#undef SetObjItem
|
||||
|
||||
return opensubdiv_info;
|
||||
return opensubdiv_info;
|
||||
}
|
||||
|
||||
PyObject *BPY_app_opensubdiv_struct(void)
|
||||
{
|
||||
PyObject *ret;
|
||||
PyObject *ret;
|
||||
|
||||
PyStructSequence_InitType(&BlenderAppOpenSubdivType, &app_opensubdiv_info_desc);
|
||||
PyStructSequence_InitType(&BlenderAppOpenSubdivType, &app_opensubdiv_info_desc);
|
||||
|
||||
ret = make_opensubdiv_info();
|
||||
ret = make_opensubdiv_info();
|
||||
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppOpenSubdivType.tp_init = NULL;
|
||||
BlenderAppOpenSubdivType.tp_new = NULL;
|
||||
/* without this we can't do set(sys.modules) [#29635] */
|
||||
BlenderAppOpenSubdivType.tp_hash = (hashfunc)_Py_HashPointer;
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppOpenSubdivType.tp_init = NULL;
|
||||
BlenderAppOpenSubdivType.tp_new = NULL;
|
||||
/* without this we can't do set(sys.modules) [#29635] */
|
||||
BlenderAppOpenSubdivType.tp_hash = (hashfunc)_Py_HashPointer;
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
|
||||
PyObject *BPY_app_opensubdiv_struct(void);
|
||||
|
||||
#endif /* __BPY_APP_OPENSUBDIV_H__ */
|
||||
#endif /* __BPY_APP_OPENSUBDIV_H__ */
|
||||
|
||||
@@ -35,76 +35,76 @@
|
||||
static PyTypeObject BlenderAppOVDBType;
|
||||
|
||||
static PyStructSequence_Field app_openvdb_info_fields[] = {
|
||||
{(char *)"supported", (char *)("Boolean, True when Blender is built with OpenVDB support")},
|
||||
{(char *)("version"), (char *)("The OpenVDB version as a tuple of 3 numbers")},
|
||||
{(char *)("version_string"), (char *)("The OpenVDB version formatted as a string")},
|
||||
{NULL},
|
||||
{(char *)"supported", (char *)("Boolean, True when Blender is built with OpenVDB support")},
|
||||
{(char *)("version"), (char *)("The OpenVDB version as a tuple of 3 numbers")},
|
||||
{(char *)("version_string"), (char *)("The OpenVDB version formatted as a string")},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static PyStructSequence_Desc app_openvdb_info_desc = {
|
||||
(char *)"bpy.app.openvdb", /* name */
|
||||
(char *)"This module contains information about OpenVDB blender is linked against", /* doc */
|
||||
app_openvdb_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_openvdb_info_fields) - 1,
|
||||
(char *)"bpy.app.openvdb", /* name */
|
||||
(char *)"This module contains information about OpenVDB blender is linked against", /* doc */
|
||||
app_openvdb_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_openvdb_info_fields) - 1,
|
||||
};
|
||||
|
||||
static PyObject *make_openvdb_info(void)
|
||||
{
|
||||
PyObject *openvdb_info;
|
||||
int pos = 0;
|
||||
PyObject *openvdb_info;
|
||||
int pos = 0;
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
int curversion;
|
||||
int curversion;
|
||||
#endif
|
||||
|
||||
openvdb_info = PyStructSequence_New(&BlenderAppOVDBType);
|
||||
if (openvdb_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
openvdb_info = PyStructSequence_New(&BlenderAppOVDBType);
|
||||
if (openvdb_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef WITH_OPENVDB
|
||||
#define SetStrItem(str) \
|
||||
PyStructSequence_SET_ITEM(openvdb_info, pos++, PyUnicode_FromString(str))
|
||||
# define SetStrItem(str) PyStructSequence_SET_ITEM(openvdb_info, pos++, PyUnicode_FromString(str))
|
||||
#endif
|
||||
|
||||
#define SetObjItem(obj) \
|
||||
PyStructSequence_SET_ITEM(openvdb_info, pos++, obj)
|
||||
#define SetObjItem(obj) PyStructSequence_SET_ITEM(openvdb_info, pos++, obj)
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
curversion = OpenVDB_getVersionHex();
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(curversion >> 24, (curversion >> 16) % 256, (curversion >> 8) % 256));
|
||||
SetObjItem(PyUnicode_FromFormat("%2d, %2d, %2d",
|
||||
curversion >> 24, (curversion >> 16) % 256, (curversion >> 8) % 256));
|
||||
curversion = OpenVDB_getVersionHex();
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
SetObjItem(
|
||||
PyC_Tuple_Pack_I32(curversion >> 24, (curversion >> 16) % 256, (curversion >> 8) % 256));
|
||||
SetObjItem(PyUnicode_FromFormat(
|
||||
"%2d, %2d, %2d", curversion >> 24, (curversion >> 16) % 256, (curversion >> 8) % 256));
|
||||
#else
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
|
||||
SetStrItem("Unknown");
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
|
||||
SetStrItem("Unknown");
|
||||
#endif
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(openvdb_info);
|
||||
return NULL;
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(openvdb_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef SetStrItem
|
||||
#undef SetObjItem
|
||||
|
||||
return openvdb_info;
|
||||
return openvdb_info;
|
||||
}
|
||||
|
||||
PyObject *BPY_app_openvdb_struct(void)
|
||||
{
|
||||
PyObject *ret;
|
||||
PyObject *ret;
|
||||
|
||||
PyStructSequence_InitType(&BlenderAppOVDBType, &app_openvdb_info_desc);
|
||||
PyStructSequence_InitType(&BlenderAppOVDBType, &app_openvdb_info_desc);
|
||||
|
||||
ret = make_openvdb_info();
|
||||
ret = make_openvdb_info();
|
||||
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppOVDBType.tp_init = NULL;
|
||||
BlenderAppOVDBType.tp_new = NULL;
|
||||
BlenderAppOVDBType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppOVDBType.tp_init = NULL;
|
||||
BlenderAppOVDBType.tp_new = NULL;
|
||||
BlenderAppOVDBType.tp_hash = (hashfunc)
|
||||
_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -26,4 +26,4 @@
|
||||
|
||||
PyObject *BPY_app_openvdb_struct(void);
|
||||
|
||||
#endif /* __BPY_APP_OPENVDB_H__ */
|
||||
#endif /* __BPY_APP_OPENVDB_H__ */
|
||||
|
||||
@@ -46,98 +46,98 @@
|
||||
static PyTypeObject BlenderAppSDLType;
|
||||
|
||||
static PyStructSequence_Field app_sdl_info_fields[] = {
|
||||
{(char *)"supported", (char *)("Boolean, True when Blender is built with SDL support")},
|
||||
{(char *)"version", (char *)("The SDL version as a tuple of 3 numbers")},
|
||||
{(char *)"version_string", (char *)("The SDL version formatted as a string")},
|
||||
{(char *)"available", (char *)("Boolean, True when SDL is available. This is False when "
|
||||
"either *supported* is False, or *dynload* is True and "
|
||||
"Blender cannot find the correct library.")},
|
||||
{NULL},
|
||||
{(char *)"supported", (char *)("Boolean, True when Blender is built with SDL support")},
|
||||
{(char *)"version", (char *)("The SDL version as a tuple of 3 numbers")},
|
||||
{(char *)"version_string", (char *)("The SDL version formatted as a string")},
|
||||
{(char *)"available",
|
||||
(char *)("Boolean, True when SDL is available. This is False when "
|
||||
"either *supported* is False, or *dynload* is True and "
|
||||
"Blender cannot find the correct library.")},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static PyStructSequence_Desc app_sdl_info_desc = {
|
||||
(char *)"bpy.app.sdl", /* name */
|
||||
(char *)"This module contains information about SDL blender is linked against", /* doc */
|
||||
app_sdl_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_sdl_info_fields) - 1,
|
||||
(char *)"bpy.app.sdl", /* name */
|
||||
(char *)"This module contains information about SDL blender is linked against", /* doc */
|
||||
app_sdl_info_fields, /* fields */
|
||||
ARRAY_SIZE(app_sdl_info_fields) - 1,
|
||||
};
|
||||
|
||||
static PyObject *make_sdl_info(void)
|
||||
{
|
||||
PyObject *sdl_info;
|
||||
int pos = 0;
|
||||
PyObject *sdl_info;
|
||||
int pos = 0;
|
||||
#ifdef WITH_SDL
|
||||
bool sdl_available = false;
|
||||
SDL_version version = {0, 0, 0};
|
||||
bool sdl_available = false;
|
||||
SDL_version version = {0, 0, 0};
|
||||
#endif
|
||||
|
||||
sdl_info = PyStructSequence_New(&BlenderAppSDLType);
|
||||
if (sdl_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sdl_info = PyStructSequence_New(&BlenderAppSDLType);
|
||||
if (sdl_info == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define SetStrItem(str) \
|
||||
PyStructSequence_SET_ITEM(sdl_info, pos++, PyUnicode_FromString(str))
|
||||
#define SetStrItem(str) PyStructSequence_SET_ITEM(sdl_info, pos++, PyUnicode_FromString(str))
|
||||
|
||||
#define SetObjItem(obj) \
|
||||
PyStructSequence_SET_ITEM(sdl_info, pos++, obj)
|
||||
#define SetObjItem(obj) PyStructSequence_SET_ITEM(sdl_info, pos++, obj)
|
||||
|
||||
#ifdef WITH_SDL
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
SetObjItem(PyBool_FromLong(1));
|
||||
|
||||
# ifdef WITH_SDL_DYNLOAD
|
||||
if (sdlewInit() == SDLEW_SUCCESS) {
|
||||
SDL_GetVersion(&version);
|
||||
sdl_available = true;
|
||||
}
|
||||
# else // WITH_SDL_DYNLOAD=OFF
|
||||
sdl_available = true;
|
||||
# if SDL_MAJOR_VERSION >= 2
|
||||
SDL_GetVersion(&version);
|
||||
# else
|
||||
SDL_VERSION(&version);
|
||||
# ifdef WITH_SDL_DYNLOAD
|
||||
if (sdlewInit() == SDLEW_SUCCESS) {
|
||||
SDL_GetVersion(&version);
|
||||
sdl_available = true;
|
||||
}
|
||||
# else // WITH_SDL_DYNLOAD=OFF
|
||||
sdl_available = true;
|
||||
# if SDL_MAJOR_VERSION >= 2
|
||||
SDL_GetVersion(&version);
|
||||
# else
|
||||
SDL_VERSION(&version);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
|
||||
SetObjItem(PyC_Tuple_Pack_I32(version.major, version.minor, version.patch));
|
||||
if (sdl_available) {
|
||||
SetObjItem(PyUnicode_FromFormat("%d.%d.%d", version.major, version.minor, version.patch));
|
||||
}
|
||||
else {
|
||||
SetStrItem("Unknown");
|
||||
}
|
||||
SetObjItem(PyBool_FromLong(sdl_available));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(version.major, version.minor, version.patch));
|
||||
if (sdl_available) {
|
||||
SetObjItem(PyUnicode_FromFormat("%d.%d.%d", version.major, version.minor, version.patch));
|
||||
}
|
||||
else {
|
||||
SetStrItem("Unknown");
|
||||
}
|
||||
SetObjItem(PyBool_FromLong(sdl_available));
|
||||
|
||||
#else // WITH_SDL=OFF
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
|
||||
SetStrItem("Unknown");
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
#else // WITH_SDL=OFF
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
|
||||
SetStrItem("Unknown");
|
||||
SetObjItem(PyBool_FromLong(0));
|
||||
#endif
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(sdl_info);
|
||||
return NULL;
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
Py_CLEAR(sdl_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef SetStrItem
|
||||
#undef SetObjItem
|
||||
|
||||
return sdl_info;
|
||||
return sdl_info;
|
||||
}
|
||||
|
||||
PyObject *BPY_app_sdl_struct(void)
|
||||
{
|
||||
PyObject *ret;
|
||||
PyObject *ret;
|
||||
|
||||
PyStructSequence_InitType(&BlenderAppSDLType, &app_sdl_info_desc);
|
||||
PyStructSequence_InitType(&BlenderAppSDLType, &app_sdl_info_desc);
|
||||
|
||||
ret = make_sdl_info();
|
||||
ret = make_sdl_info();
|
||||
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppSDLType.tp_init = NULL;
|
||||
BlenderAppSDLType.tp_new = NULL;
|
||||
BlenderAppSDLType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
/* prevent user from creating new instances */
|
||||
BlenderAppSDLType.tp_init = NULL;
|
||||
BlenderAppSDLType.tp_new = NULL;
|
||||
BlenderAppSDLType.tp_hash = (hashfunc)
|
||||
_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
|
||||
PyObject *BPY_app_sdl_struct(void);
|
||||
|
||||
#endif /* __BPY_APP_SDL_H__ */
|
||||
#endif /* __BPY_APP_SDL_H__ */
|
||||
|
||||
@@ -29,167 +29,161 @@
|
||||
#include "../generic/py_capi_utils.h"
|
||||
#include "../generic/python_utildefines.h"
|
||||
|
||||
|
||||
static double handle_returned_value(PyObject *function, PyObject *ret)
|
||||
{
|
||||
if (ret == NULL) {
|
||||
PyErr_PrintEx(0);
|
||||
PyErr_Clear();
|
||||
return -1;
|
||||
}
|
||||
if (ret == NULL) {
|
||||
PyErr_PrintEx(0);
|
||||
PyErr_Clear();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == Py_None) {
|
||||
return -1;
|
||||
}
|
||||
if (ret == Py_None) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
double value = PyFloat_AsDouble(ret);
|
||||
if (value == -1.0f && PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
printf("Error: 'bpy.app.timers' callback ");
|
||||
PyObject_Print(function, stdout, Py_PRINT_RAW);
|
||||
printf(" did not return None or float.\n");
|
||||
return -1;
|
||||
}
|
||||
double value = PyFloat_AsDouble(ret);
|
||||
if (value == -1.0f && PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
printf("Error: 'bpy.app.timers' callback ");
|
||||
PyObject_Print(function, stdout, Py_PRINT_RAW);
|
||||
printf(" did not return None or float.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (value < 0.0) {
|
||||
value = 0.0;
|
||||
}
|
||||
if (value < 0.0) {
|
||||
value = 0.0;
|
||||
}
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
static double py_timer_execute(uintptr_t UNUSED(uuid), void *user_data)
|
||||
{
|
||||
PyObject *function = user_data;
|
||||
PyObject *function = user_data;
|
||||
|
||||
PyGILState_STATE gilstate;
|
||||
gilstate = PyGILState_Ensure();
|
||||
PyGILState_STATE gilstate;
|
||||
gilstate = PyGILState_Ensure();
|
||||
|
||||
PyObject *py_ret = PyObject_CallObject(function, NULL);
|
||||
double ret = handle_returned_value(function, py_ret);
|
||||
PyObject *py_ret = PyObject_CallObject(function, NULL);
|
||||
double ret = handle_returned_value(function, py_ret);
|
||||
|
||||
PyGILState_Release(gilstate);
|
||||
PyGILState_Release(gilstate);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void py_timer_free(uintptr_t UNUSED(uuid), void *user_data)
|
||||
{
|
||||
PyObject *function = user_data;
|
||||
PyObject *function = user_data;
|
||||
|
||||
PyGILState_STATE gilstate;
|
||||
gilstate = PyGILState_Ensure();
|
||||
PyGILState_STATE gilstate;
|
||||
gilstate = PyGILState_Ensure();
|
||||
|
||||
Py_DECREF(function);
|
||||
Py_DECREF(function);
|
||||
|
||||
PyGILState_Release(gilstate);
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(bpy_app_timers_register_doc,
|
||||
".. function:: register(function, first_interval=0, persistent=False)\n"
|
||||
"\n"
|
||||
" Add a new function that will be called after the specified amount of seconds.\n"
|
||||
" The function gets no arguments and is expected to return either None or a float.\n"
|
||||
" If ``None`` is returned, the timer will be unregistered.\n"
|
||||
" A returned number specifies the delay until the function is called again.\n"
|
||||
" ``functools.partial`` can be used to assign some parameters.\n"
|
||||
"\n"
|
||||
" :arg function: The function that should called.\n"
|
||||
" :type function: Callable[[], Union[float, None]]\n"
|
||||
" :arg first_interval: Seconds until the callback should be called the first time.\n"
|
||||
" :type first_interval: float\n"
|
||||
" :arg persistent: Don't remove timer when a new file is loaded.\n"
|
||||
" :type persistent: bool\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpy_app_timers_register_doc,
|
||||
".. function:: register(function, first_interval=0, persistent=False)\n"
|
||||
"\n"
|
||||
" Add a new function that will be called after the specified amount of seconds.\n"
|
||||
" The function gets no arguments and is expected to return either None or a float.\n"
|
||||
" If ``None`` is returned, the timer will be unregistered.\n"
|
||||
" A returned number specifies the delay until the function is called again.\n"
|
||||
" ``functools.partial`` can be used to assign some parameters.\n"
|
||||
"\n"
|
||||
" :arg function: The function that should called.\n"
|
||||
" :type function: Callable[[], Union[float, None]]\n"
|
||||
" :arg first_interval: Seconds until the callback should be called the first time.\n"
|
||||
" :type first_interval: float\n"
|
||||
" :arg persistent: Don't remove timer when a new file is loaded.\n"
|
||||
" :type persistent: bool\n");
|
||||
static PyObject *bpy_app_timers_register(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
PyObject *function;
|
||||
double first_interval = 0;
|
||||
int persistent = false;
|
||||
PyObject *function;
|
||||
double first_interval = 0;
|
||||
int persistent = false;
|
||||
|
||||
static const char *_keywords[] = {"function", "first_interval", "persistent", NULL};
|
||||
static _PyArg_Parser _parser = {"O|$dp:register", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&function, &first_interval, &persistent))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"function", "first_interval", "persistent", NULL};
|
||||
static _PyArg_Parser _parser = {"O|$dp:register", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser, &function, &first_interval, &persistent)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyCallable_Check(function)) {
|
||||
PyErr_SetString(PyExc_TypeError, "function is not callable");
|
||||
return NULL;
|
||||
}
|
||||
if (!PyCallable_Check(function)) {
|
||||
PyErr_SetString(PyExc_TypeError, "function is not callable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(function);
|
||||
BLI_timer_register(
|
||||
(intptr_t)function,
|
||||
py_timer_execute, function, py_timer_free,
|
||||
first_interval, persistent);
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(function);
|
||||
BLI_timer_register(
|
||||
(intptr_t)function, py_timer_execute, function, py_timer_free, first_interval, persistent);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_app_timers_unregister_doc,
|
||||
".. function:: unregister(function)\n"
|
||||
"\n"
|
||||
" Unregister timer.\n"
|
||||
"\n"
|
||||
" :arg function: Function to unregister.\n"
|
||||
" :type function: function\n"
|
||||
);
|
||||
".. function:: unregister(function)\n"
|
||||
"\n"
|
||||
" Unregister timer.\n"
|
||||
"\n"
|
||||
" :arg function: Function to unregister.\n"
|
||||
" :type function: function\n");
|
||||
static PyObject *bpy_app_timers_unregister(PyObject *UNUSED(self), PyObject *function)
|
||||
{
|
||||
if (!BLI_timer_unregister((intptr_t)function)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Error: function is not registered");
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
if (!BLI_timer_unregister((intptr_t)function)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Error: function is not registered");
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_app_timers_is_registered_doc,
|
||||
".. function:: is_registered(function)\n"
|
||||
"\n"
|
||||
" Check if this function is registered as a timer.\n"
|
||||
"\n"
|
||||
" :arg function: Function to check.\n"
|
||||
" :type function: int\n"
|
||||
" :return: True when this function is registered, otherwise False.\n"
|
||||
" :rtype: bool\n"
|
||||
);
|
||||
".. function:: is_registered(function)\n"
|
||||
"\n"
|
||||
" Check if this function is registered as a timer.\n"
|
||||
"\n"
|
||||
" :arg function: Function to check.\n"
|
||||
" :type function: int\n"
|
||||
" :return: True when this function is registered, otherwise False.\n"
|
||||
" :rtype: bool\n");
|
||||
static PyObject *bpy_app_timers_is_registered(PyObject *UNUSED(self), PyObject *function)
|
||||
{
|
||||
bool ret = BLI_timer_is_registered((intptr_t)function);
|
||||
return PyBool_FromLong(ret);
|
||||
bool ret = BLI_timer_is_registered((intptr_t)function);
|
||||
return PyBool_FromLong(ret);
|
||||
}
|
||||
|
||||
|
||||
static struct PyMethodDef M_AppTimers_methods[] = {
|
||||
{"register", (PyCFunction)bpy_app_timers_register,
|
||||
METH_VARARGS | METH_KEYWORDS, bpy_app_timers_register_doc},
|
||||
{"unregister", (PyCFunction)bpy_app_timers_unregister,
|
||||
METH_O, bpy_app_timers_unregister_doc},
|
||||
{"is_registered", (PyCFunction)bpy_app_timers_is_registered,
|
||||
METH_O, bpy_app_timers_is_registered_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"register",
|
||||
(PyCFunction)bpy_app_timers_register,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_app_timers_register_doc},
|
||||
{"unregister", (PyCFunction)bpy_app_timers_unregister, METH_O, bpy_app_timers_unregister_doc},
|
||||
{"is_registered",
|
||||
(PyCFunction)bpy_app_timers_is_registered,
|
||||
METH_O,
|
||||
bpy_app_timers_is_registered_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
static struct PyModuleDef M_AppTimers_module_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"bpy.app.timers", /* m_name */
|
||||
NULL, /* m_doc */
|
||||
0, /* m_size */
|
||||
M_AppTimers_methods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"bpy.app.timers", /* m_name */
|
||||
NULL, /* m_doc */
|
||||
0, /* m_size */
|
||||
M_AppTimers_methods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
};
|
||||
|
||||
PyObject *BPY_app_timers_module(void)
|
||||
{
|
||||
PyObject *sys_modules = PyImport_GetModuleDict();
|
||||
PyObject *mod = PyModule_Create(&M_AppTimers_module_def);
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(mod), mod);
|
||||
return mod;
|
||||
PyObject *sys_modules = PyImport_GetModuleDict();
|
||||
PyObject *mod = PyModule_Create(&M_AppTimers_module_def);
|
||||
PyDict_SetItem(sys_modules, PyModule_GetNameObject(mod), mod);
|
||||
return mod;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,6 @@
|
||||
#define __BPY_APP_TRANSLATIONS_H__
|
||||
|
||||
PyObject *BPY_app_translations_struct(void);
|
||||
void BPY_app_translations_end(void);
|
||||
void BPY_app_translations_end(void);
|
||||
|
||||
#endif /* __BPY_APP_TRANSLATIONS_H__ */
|
||||
|
||||
@@ -38,42 +38,48 @@
|
||||
#include "../generic/py_capi_utils.h"
|
||||
|
||||
static bContext *__py_context = NULL;
|
||||
bContext *BPy_GetContext(void) { return __py_context; }
|
||||
void BPy_SetContext(bContext *C) { __py_context = C; }
|
||||
bContext *BPy_GetContext(void)
|
||||
{
|
||||
return __py_context;
|
||||
}
|
||||
void BPy_SetContext(bContext *C)
|
||||
{
|
||||
__py_context = C;
|
||||
}
|
||||
|
||||
char *BPy_enum_as_string(const EnumPropertyItem *item)
|
||||
{
|
||||
DynStr *dynstr = BLI_dynstr_new();
|
||||
const EnumPropertyItem *e;
|
||||
char *cstring;
|
||||
DynStr *dynstr = BLI_dynstr_new();
|
||||
const EnumPropertyItem *e;
|
||||
char *cstring;
|
||||
|
||||
for (e = item; item->identifier; item++) {
|
||||
if (item->identifier[0]) {
|
||||
BLI_dynstr_appendf(dynstr, (e == item) ? "'%s'" : ", '%s'", item->identifier);
|
||||
}
|
||||
}
|
||||
for (e = item; item->identifier; item++) {
|
||||
if (item->identifier[0]) {
|
||||
BLI_dynstr_appendf(dynstr, (e == item) ? "'%s'" : ", '%s'", item->identifier);
|
||||
}
|
||||
}
|
||||
|
||||
cstring = BLI_dynstr_get_cstring(dynstr);
|
||||
BLI_dynstr_free(dynstr);
|
||||
return cstring;
|
||||
cstring = BLI_dynstr_get_cstring(dynstr);
|
||||
BLI_dynstr_free(dynstr);
|
||||
return cstring;
|
||||
}
|
||||
|
||||
short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool clear)
|
||||
{
|
||||
char *report_str;
|
||||
char *report_str;
|
||||
|
||||
report_str = BKE_reports_string(reports, RPT_ERROR);
|
||||
report_str = BKE_reports_string(reports, RPT_ERROR);
|
||||
|
||||
if (clear == true) {
|
||||
BKE_reports_clear(reports);
|
||||
}
|
||||
if (clear == true) {
|
||||
BKE_reports_clear(reports);
|
||||
}
|
||||
|
||||
if (report_str) {
|
||||
PyErr_SetString(exception, report_str);
|
||||
MEM_freeN(report_str);
|
||||
}
|
||||
if (report_str) {
|
||||
PyErr_SetString(exception, report_str);
|
||||
MEM_freeN(report_str);
|
||||
}
|
||||
|
||||
return (report_str == NULL) ? 0 : -1;
|
||||
return (report_str == NULL) ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,80 +87,78 @@ short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool
|
||||
*/
|
||||
void BPy_reports_write_stdout(const ReportList *reports, const char *header)
|
||||
{
|
||||
if (header) {
|
||||
PySys_WriteStdout("%s\n", header);
|
||||
}
|
||||
if (header) {
|
||||
PySys_WriteStdout("%s\n", header);
|
||||
}
|
||||
|
||||
for (const Report *report = reports->list.first; report; report = report->next) {
|
||||
PySys_WriteStdout("%s: %s\n", report->typestr, report->message);
|
||||
}
|
||||
for (const Report *report = reports->list.first; report; report = report->next) {
|
||||
PySys_WriteStdout("%s: %s\n", report->typestr, report->message);
|
||||
}
|
||||
}
|
||||
|
||||
bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const bool use_location)
|
||||
{
|
||||
PyObject *pystring;
|
||||
PyObject *pystring;
|
||||
|
||||
if (!PyErr_Occurred()) {
|
||||
return 1;
|
||||
}
|
||||
if (!PyErr_Occurred()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* less hassle if we allow NULL */
|
||||
if (reports == NULL) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
return 1;
|
||||
}
|
||||
/* less hassle if we allow NULL */
|
||||
if (reports == NULL) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (use_full) {
|
||||
pystring = PyC_ExceptionBuffer();
|
||||
}
|
||||
else {
|
||||
pystring = PyC_ExceptionBuffer_Simple();
|
||||
}
|
||||
if (use_full) {
|
||||
pystring = PyC_ExceptionBuffer();
|
||||
}
|
||||
else {
|
||||
pystring = PyC_ExceptionBuffer_Simple();
|
||||
}
|
||||
|
||||
if (pystring == NULL) {
|
||||
BKE_report(reports, RPT_ERROR, "Unknown py-exception, could not convert");
|
||||
return 0;
|
||||
}
|
||||
if (pystring == NULL) {
|
||||
BKE_report(reports, RPT_ERROR, "Unknown py-exception, could not convert");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (use_location) {
|
||||
const char *filename;
|
||||
int lineno;
|
||||
if (use_location) {
|
||||
const char *filename;
|
||||
int lineno;
|
||||
|
||||
PyObject *pystring_format; /* workaround, see below */
|
||||
const char *cstring;
|
||||
PyObject *pystring_format; /* workaround, see below */
|
||||
const char *cstring;
|
||||
|
||||
PyC_FileAndNum(&filename, &lineno);
|
||||
if (filename == NULL) {
|
||||
filename = "<unknown location>";
|
||||
}
|
||||
PyC_FileAndNum(&filename, &lineno);
|
||||
if (filename == NULL) {
|
||||
filename = "<unknown location>";
|
||||
}
|
||||
|
||||
#if 0 /* ARG!. workaround for a bug in blenders use of vsnprintf */
|
||||
BKE_reportf(reports, RPT_ERROR, "%s\nlocation: %s:%d\n", _PyUnicode_AsString(pystring), filename, lineno);
|
||||
BKE_reportf(reports, RPT_ERROR, "%s\nlocation: %s:%d\n", _PyUnicode_AsString(pystring), filename, lineno);
|
||||
#else
|
||||
pystring_format = PyUnicode_FromFormat(
|
||||
TIP_("%s\nlocation: %s:%d\n"),
|
||||
_PyUnicode_AsString(pystring), filename, lineno);
|
||||
pystring_format = PyUnicode_FromFormat(
|
||||
TIP_("%s\nlocation: %s:%d\n"), _PyUnicode_AsString(pystring), filename, lineno);
|
||||
|
||||
cstring = _PyUnicode_AsString(pystring_format);
|
||||
BKE_report(reports, RPT_ERROR, cstring);
|
||||
cstring = _PyUnicode_AsString(pystring_format);
|
||||
BKE_report(reports, RPT_ERROR, cstring);
|
||||
|
||||
/* not exactly needed. just for testing */
|
||||
fprintf(stderr, TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno);
|
||||
/* not exactly needed. just for testing */
|
||||
fprintf(stderr, TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno);
|
||||
|
||||
Py_DECREF(pystring_format); /* workaround */
|
||||
Py_DECREF(pystring_format); /* workaround */
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
BKE_report(reports, RPT_ERROR, _PyUnicode_AsString(pystring));
|
||||
}
|
||||
}
|
||||
else {
|
||||
BKE_report(reports, RPT_ERROR, _PyUnicode_AsString(pystring));
|
||||
}
|
||||
|
||||
|
||||
Py_DECREF(pystring);
|
||||
return 1;
|
||||
Py_DECREF(pystring);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool BPy_errors_to_report(ReportList *reports)
|
||||
{
|
||||
return BPy_errors_to_report_ex(reports, true, true);
|
||||
return BPy_errors_to_report_ex(reports, true, true);
|
||||
}
|
||||
|
||||
@@ -30,12 +30,17 @@ struct ReportList;
|
||||
|
||||
char *BPy_enum_as_string(const struct EnumPropertyItem *item);
|
||||
|
||||
#define BLANK_PYTHON_TYPE {PyVarObject_HEAD_INIT(NULL, 0) NULL}
|
||||
#define BLANK_PYTHON_TYPE \
|
||||
{ \
|
||||
PyVarObject_HEAD_INIT(NULL, 0) NULL \
|
||||
}
|
||||
|
||||
/* error reporting */
|
||||
short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear);
|
||||
void BPy_reports_write_stdout(const struct ReportList *reports, const char *header);
|
||||
bool BPy_errors_to_report_ex(struct ReportList *reports, const bool use_full, const bool use_location);
|
||||
bool BPy_errors_to_report_ex(struct ReportList *reports,
|
||||
const bool use_full,
|
||||
const bool use_location);
|
||||
bool BPy_errors_to_report(struct ReportList *reports);
|
||||
|
||||
/* TODO - find a better solution! */
|
||||
@@ -45,4 +50,4 @@ void BPy_SetContext(struct bContext *C);
|
||||
extern void bpy_context_set(struct bContext *C, PyGILState_STATE *gilstate);
|
||||
extern void bpy_context_clear(struct bContext *C, PyGILState_STATE *gilstate);
|
||||
|
||||
#endif /* __BPY_CAPI_UTILS_H__ */
|
||||
#endif /* __BPY_CAPI_UTILS_H__ */
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_global.h"
|
||||
|
||||
#include "bpy_rna_driver.h" /* for pyrna_driver_get_variable_value */
|
||||
#include "bpy_rna_driver.h" /* for pyrna_driver_get_variable_value */
|
||||
|
||||
#include "bpy_intern_string.h"
|
||||
|
||||
@@ -66,137 +66,136 @@ static PyObject *bpy_pydriver_Dict__whitelist = NULL;
|
||||
*/
|
||||
int bpy_pydriver_create_dict(void)
|
||||
{
|
||||
PyObject *d, *mod;
|
||||
PyObject *d, *mod;
|
||||
|
||||
/* validate namespace for driver evaluation */
|
||||
if (bpy_pydriver_Dict) {
|
||||
return -1;
|
||||
}
|
||||
/* validate namespace for driver evaluation */
|
||||
if (bpy_pydriver_Dict) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
d = PyDict_New();
|
||||
if (d == NULL) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
bpy_pydriver_Dict = d;
|
||||
}
|
||||
d = PyDict_New();
|
||||
if (d == NULL) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
bpy_pydriver_Dict = d;
|
||||
}
|
||||
|
||||
/* import some modules: builtins, bpy, math, (Blender.noise)*/
|
||||
PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
|
||||
/* import some modules: builtins, bpy, math, (Blender.noise)*/
|
||||
PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
|
||||
|
||||
mod = PyImport_ImportModule("math");
|
||||
if (mod) {
|
||||
PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - don't overwrite existing values */
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
mod = PyImport_ImportModule("math");
|
||||
if (mod) {
|
||||
PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - don't overwrite existing values */
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
#ifdef USE_BYTECODE_WHITELIST
|
||||
PyObject *mod_math = mod;
|
||||
PyObject *mod_math = mod;
|
||||
#endif
|
||||
|
||||
/* add bpy to global namespace */
|
||||
mod = PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
|
||||
if (mod) {
|
||||
PyDict_SetItemString(bpy_pydriver_Dict, "bpy", mod);
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
/* add bpy to global namespace */
|
||||
mod = PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
|
||||
if (mod) {
|
||||
PyDict_SetItemString(bpy_pydriver_Dict, "bpy", mod);
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
|
||||
/* add noise to global namespace */
|
||||
mod = PyImport_ImportModuleLevel("mathutils", NULL, NULL, NULL, 0);
|
||||
if (mod) {
|
||||
PyObject *modsub = PyDict_GetItemString(PyModule_GetDict(mod), "noise");
|
||||
PyDict_SetItemString(bpy_pydriver_Dict, "noise", modsub);
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
/* add noise to global namespace */
|
||||
mod = PyImport_ImportModuleLevel("mathutils", NULL, NULL, NULL, 0);
|
||||
if (mod) {
|
||||
PyObject *modsub = PyDict_GetItemString(PyModule_GetDict(mod), "noise");
|
||||
PyDict_SetItemString(bpy_pydriver_Dict, "noise", modsub);
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
|
||||
#ifdef USE_BYTECODE_WHITELIST
|
||||
/* setup the whitelist */
|
||||
{
|
||||
bpy_pydriver_Dict__whitelist = PyDict_New();
|
||||
const char *whitelist[] = {
|
||||
/* builtins (basic) */
|
||||
"all",
|
||||
"any",
|
||||
"len",
|
||||
/* builtins (numeric) */
|
||||
"max",
|
||||
"min",
|
||||
"pow",
|
||||
"round",
|
||||
"sum",
|
||||
/* types */
|
||||
"bool",
|
||||
"float",
|
||||
"int",
|
||||
/* setup the whitelist */
|
||||
{
|
||||
bpy_pydriver_Dict__whitelist = PyDict_New();
|
||||
const char *whitelist[] = {
|
||||
/* builtins (basic) */
|
||||
"all",
|
||||
"any",
|
||||
"len",
|
||||
/* builtins (numeric) */
|
||||
"max",
|
||||
"min",
|
||||
"pow",
|
||||
"round",
|
||||
"sum",
|
||||
/* types */
|
||||
"bool",
|
||||
"float",
|
||||
"int",
|
||||
|
||||
NULL,
|
||||
};
|
||||
NULL,
|
||||
};
|
||||
|
||||
for (int i = 0; whitelist[i]; i++) {
|
||||
PyDict_SetItemString(bpy_pydriver_Dict__whitelist, whitelist[i], Py_None);
|
||||
}
|
||||
for (int i = 0; whitelist[i]; i++) {
|
||||
PyDict_SetItemString(bpy_pydriver_Dict__whitelist, whitelist[i], Py_None);
|
||||
}
|
||||
|
||||
/* Add all of 'math' functions. */
|
||||
if (mod_math != NULL) {
|
||||
PyObject *mod_math_dict = PyModule_GetDict(mod_math);
|
||||
PyObject *arg_key, *arg_value;
|
||||
Py_ssize_t arg_pos = 0;
|
||||
while (PyDict_Next(mod_math_dict, &arg_pos, &arg_key, &arg_value)) {
|
||||
const char *arg_str = _PyUnicode_AsString(arg_key);
|
||||
if (arg_str[0] && arg_str[1] != '_') {
|
||||
PyDict_SetItem(bpy_pydriver_Dict__whitelist, arg_key, Py_None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* USE_BYTECODE_WHITELIST */
|
||||
/* Add all of 'math' functions. */
|
||||
if (mod_math != NULL) {
|
||||
PyObject *mod_math_dict = PyModule_GetDict(mod_math);
|
||||
PyObject *arg_key, *arg_value;
|
||||
Py_ssize_t arg_pos = 0;
|
||||
while (PyDict_Next(mod_math_dict, &arg_pos, &arg_key, &arg_value)) {
|
||||
const char *arg_str = _PyUnicode_AsString(arg_key);
|
||||
if (arg_str[0] && arg_str[1] != '_') {
|
||||
PyDict_SetItem(bpy_pydriver_Dict__whitelist, arg_key, Py_None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* USE_BYTECODE_WHITELIST */
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* note, this function should do nothing most runs, only when changing frame */
|
||||
/* not thread safe but neither is python */
|
||||
static struct {
|
||||
float evaltime;
|
||||
float evaltime;
|
||||
|
||||
/* borrowed reference to the 'self' in 'bpy_pydriver_Dict'
|
||||
* keep for as long as the same self is used. */
|
||||
PyObject *self;
|
||||
/* borrowed reference to the 'self' in 'bpy_pydriver_Dict'
|
||||
* keep for as long as the same self is used. */
|
||||
PyObject *self;
|
||||
} g_pydriver_state_prev = {
|
||||
.evaltime = FLT_MAX,
|
||||
.self = NULL,
|
||||
.evaltime = FLT_MAX,
|
||||
.self = NULL,
|
||||
};
|
||||
|
||||
static void bpy_pydriver_namespace_update_frame(const float evaltime)
|
||||
{
|
||||
if (g_pydriver_state_prev.evaltime != evaltime) {
|
||||
PyObject *item = PyFloat_FromDouble(evaltime);
|
||||
PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_frame, item);
|
||||
Py_DECREF(item);
|
||||
if (g_pydriver_state_prev.evaltime != evaltime) {
|
||||
PyObject *item = PyFloat_FromDouble(evaltime);
|
||||
PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_frame, item);
|
||||
Py_DECREF(item);
|
||||
|
||||
g_pydriver_state_prev.evaltime = evaltime;
|
||||
}
|
||||
g_pydriver_state_prev.evaltime = evaltime;
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_pydriver_namespace_update_self(struct PathResolvedRNA *anim_rna)
|
||||
{
|
||||
if ((g_pydriver_state_prev.self == NULL) ||
|
||||
(pyrna_driver_is_equal_anim_rna(anim_rna, g_pydriver_state_prev.self) == false))
|
||||
{
|
||||
PyObject *item = pyrna_driver_self_from_anim_rna(anim_rna);
|
||||
PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_self, item);
|
||||
Py_DECREF(item);
|
||||
if ((g_pydriver_state_prev.self == NULL) ||
|
||||
(pyrna_driver_is_equal_anim_rna(anim_rna, g_pydriver_state_prev.self) == false)) {
|
||||
PyObject *item = pyrna_driver_self_from_anim_rna(anim_rna);
|
||||
PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_self, item);
|
||||
Py_DECREF(item);
|
||||
|
||||
g_pydriver_state_prev.self = item;
|
||||
}
|
||||
g_pydriver_state_prev.self = item;
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_pydriver_namespace_clear_self(void)
|
||||
{
|
||||
if (g_pydriver_state_prev.self) {
|
||||
PyDict_DelItem(bpy_pydriver_Dict, bpy_intern_str_self);
|
||||
if (g_pydriver_state_prev.self) {
|
||||
PyDict_DelItem(bpy_pydriver_Dict, bpy_intern_str_self);
|
||||
|
||||
g_pydriver_state_prev.self = NULL;
|
||||
}
|
||||
g_pydriver_state_prev.self = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update function, it gets rid of pydrivers global dictionary, forcing
|
||||
@@ -206,171 +205,176 @@ static void bpy_pydriver_namespace_clear_self(void)
|
||||
*/
|
||||
void BPY_driver_reset(void)
|
||||
{
|
||||
PyGILState_STATE gilstate;
|
||||
bool use_gil = true; /* !PyC_IsInterpreterActive(); */
|
||||
PyGILState_STATE gilstate;
|
||||
bool use_gil = true; /* !PyC_IsInterpreterActive(); */
|
||||
|
||||
if (use_gil) {
|
||||
gilstate = PyGILState_Ensure();
|
||||
}
|
||||
if (use_gil) {
|
||||
gilstate = PyGILState_Ensure();
|
||||
}
|
||||
|
||||
if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
|
||||
PyDict_Clear(bpy_pydriver_Dict);
|
||||
Py_DECREF(bpy_pydriver_Dict);
|
||||
bpy_pydriver_Dict = NULL;
|
||||
}
|
||||
if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
|
||||
PyDict_Clear(bpy_pydriver_Dict);
|
||||
Py_DECREF(bpy_pydriver_Dict);
|
||||
bpy_pydriver_Dict = NULL;
|
||||
}
|
||||
|
||||
#ifdef USE_BYTECODE_WHITELIST
|
||||
if (bpy_pydriver_Dict__whitelist) {
|
||||
PyDict_Clear(bpy_pydriver_Dict__whitelist);
|
||||
Py_DECREF(bpy_pydriver_Dict__whitelist);
|
||||
bpy_pydriver_Dict__whitelist = NULL;
|
||||
}
|
||||
if (bpy_pydriver_Dict__whitelist) {
|
||||
PyDict_Clear(bpy_pydriver_Dict__whitelist);
|
||||
Py_DECREF(bpy_pydriver_Dict__whitelist);
|
||||
bpy_pydriver_Dict__whitelist = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_pydriver_state_prev.evaltime = FLT_MAX;
|
||||
g_pydriver_state_prev.evaltime = FLT_MAX;
|
||||
|
||||
/* freed when clearing driver dict */
|
||||
g_pydriver_state_prev.self = NULL;
|
||||
/* freed when clearing driver dict */
|
||||
g_pydriver_state_prev.self = NULL;
|
||||
|
||||
if (use_gil) {
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
if (use_gil) {
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
/* error return function for BPY_eval_pydriver */
|
||||
static void pydriver_error(ChannelDriver *driver)
|
||||
{
|
||||
driver->flag |= DRIVER_FLAG_INVALID; /* py expression failed */
|
||||
fprintf(stderr, "\nError in Driver: The following Python expression failed:\n\t'%s'\n\n", driver->expression);
|
||||
driver->flag |= DRIVER_FLAG_INVALID; /* py expression failed */
|
||||
fprintf(stderr,
|
||||
"\nError in Driver: The following Python expression failed:\n\t'%s'\n\n",
|
||||
driver->expression);
|
||||
|
||||
// BPy_errors_to_report(NULL); // TODO - reports
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
// BPy_errors_to_report(NULL); // TODO - reports
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
#ifdef USE_BYTECODE_WHITELIST
|
||||
|
||||
#define OK_OP(op) [op] = 1
|
||||
# define OK_OP(op) [op] = 1
|
||||
|
||||
static const char secure_opcodes[255] = {
|
||||
OK_OP(POP_TOP),
|
||||
OK_OP(ROT_TWO),
|
||||
OK_OP(ROT_THREE),
|
||||
OK_OP(DUP_TOP),
|
||||
OK_OP(DUP_TOP_TWO),
|
||||
OK_OP(NOP),
|
||||
OK_OP(UNARY_POSITIVE),
|
||||
OK_OP(UNARY_NEGATIVE),
|
||||
OK_OP(UNARY_NOT),
|
||||
OK_OP(UNARY_INVERT),
|
||||
OK_OP(BINARY_MATRIX_MULTIPLY),
|
||||
OK_OP(INPLACE_MATRIX_MULTIPLY),
|
||||
OK_OP(BINARY_POWER),
|
||||
OK_OP(BINARY_MULTIPLY),
|
||||
OK_OP(BINARY_MODULO),
|
||||
OK_OP(BINARY_ADD),
|
||||
OK_OP(BINARY_SUBTRACT),
|
||||
OK_OP(BINARY_SUBSCR),
|
||||
OK_OP(BINARY_FLOOR_DIVIDE),
|
||||
OK_OP(BINARY_TRUE_DIVIDE),
|
||||
OK_OP(INPLACE_FLOOR_DIVIDE),
|
||||
OK_OP(INPLACE_TRUE_DIVIDE),
|
||||
OK_OP(INPLACE_ADD),
|
||||
OK_OP(INPLACE_SUBTRACT),
|
||||
OK_OP(INPLACE_MULTIPLY),
|
||||
OK_OP(INPLACE_MODULO),
|
||||
OK_OP(BINARY_LSHIFT),
|
||||
OK_OP(BINARY_RSHIFT),
|
||||
OK_OP(BINARY_AND),
|
||||
OK_OP(BINARY_XOR),
|
||||
OK_OP(BINARY_OR),
|
||||
OK_OP(INPLACE_POWER),
|
||||
OK_OP(INPLACE_LSHIFT),
|
||||
OK_OP(INPLACE_RSHIFT),
|
||||
OK_OP(INPLACE_AND),
|
||||
OK_OP(INPLACE_XOR),
|
||||
OK_OP(INPLACE_OR),
|
||||
OK_OP(RETURN_VALUE),
|
||||
OK_OP(BUILD_TUPLE),
|
||||
OK_OP(BUILD_LIST),
|
||||
OK_OP(BUILD_SET),
|
||||
OK_OP(BUILD_MAP),
|
||||
OK_OP(COMPARE_OP),
|
||||
OK_OP(JUMP_FORWARD),
|
||||
OK_OP(JUMP_IF_FALSE_OR_POP),
|
||||
OK_OP(JUMP_IF_TRUE_OR_POP),
|
||||
OK_OP(JUMP_ABSOLUTE),
|
||||
OK_OP(POP_JUMP_IF_FALSE),
|
||||
OK_OP(POP_JUMP_IF_TRUE),
|
||||
OK_OP(LOAD_GLOBAL),
|
||||
OK_OP(LOAD_FAST),
|
||||
OK_OP(STORE_FAST),
|
||||
OK_OP(DELETE_FAST),
|
||||
OK_OP(LOAD_DEREF),
|
||||
OK_OP(STORE_DEREF),
|
||||
OK_OP(POP_TOP),
|
||||
OK_OP(ROT_TWO),
|
||||
OK_OP(ROT_THREE),
|
||||
OK_OP(DUP_TOP),
|
||||
OK_OP(DUP_TOP_TWO),
|
||||
OK_OP(NOP),
|
||||
OK_OP(UNARY_POSITIVE),
|
||||
OK_OP(UNARY_NEGATIVE),
|
||||
OK_OP(UNARY_NOT),
|
||||
OK_OP(UNARY_INVERT),
|
||||
OK_OP(BINARY_MATRIX_MULTIPLY),
|
||||
OK_OP(INPLACE_MATRIX_MULTIPLY),
|
||||
OK_OP(BINARY_POWER),
|
||||
OK_OP(BINARY_MULTIPLY),
|
||||
OK_OP(BINARY_MODULO),
|
||||
OK_OP(BINARY_ADD),
|
||||
OK_OP(BINARY_SUBTRACT),
|
||||
OK_OP(BINARY_SUBSCR),
|
||||
OK_OP(BINARY_FLOOR_DIVIDE),
|
||||
OK_OP(BINARY_TRUE_DIVIDE),
|
||||
OK_OP(INPLACE_FLOOR_DIVIDE),
|
||||
OK_OP(INPLACE_TRUE_DIVIDE),
|
||||
OK_OP(INPLACE_ADD),
|
||||
OK_OP(INPLACE_SUBTRACT),
|
||||
OK_OP(INPLACE_MULTIPLY),
|
||||
OK_OP(INPLACE_MODULO),
|
||||
OK_OP(BINARY_LSHIFT),
|
||||
OK_OP(BINARY_RSHIFT),
|
||||
OK_OP(BINARY_AND),
|
||||
OK_OP(BINARY_XOR),
|
||||
OK_OP(BINARY_OR),
|
||||
OK_OP(INPLACE_POWER),
|
||||
OK_OP(INPLACE_LSHIFT),
|
||||
OK_OP(INPLACE_RSHIFT),
|
||||
OK_OP(INPLACE_AND),
|
||||
OK_OP(INPLACE_XOR),
|
||||
OK_OP(INPLACE_OR),
|
||||
OK_OP(RETURN_VALUE),
|
||||
OK_OP(BUILD_TUPLE),
|
||||
OK_OP(BUILD_LIST),
|
||||
OK_OP(BUILD_SET),
|
||||
OK_OP(BUILD_MAP),
|
||||
OK_OP(COMPARE_OP),
|
||||
OK_OP(JUMP_FORWARD),
|
||||
OK_OP(JUMP_IF_FALSE_OR_POP),
|
||||
OK_OP(JUMP_IF_TRUE_OR_POP),
|
||||
OK_OP(JUMP_ABSOLUTE),
|
||||
OK_OP(POP_JUMP_IF_FALSE),
|
||||
OK_OP(POP_JUMP_IF_TRUE),
|
||||
OK_OP(LOAD_GLOBAL),
|
||||
OK_OP(LOAD_FAST),
|
||||
OK_OP(STORE_FAST),
|
||||
OK_OP(DELETE_FAST),
|
||||
OK_OP(LOAD_DEREF),
|
||||
OK_OP(STORE_DEREF),
|
||||
|
||||
/* special cases */
|
||||
OK_OP(LOAD_CONST), /* ok because constants are accepted */
|
||||
OK_OP(LOAD_NAME), /* ok, because PyCodeObject.names is checked */
|
||||
OK_OP(CALL_FUNCTION), /* ok, because we check its 'name' before calling */
|
||||
OK_OP(CALL_FUNCTION_KW),
|
||||
OK_OP(CALL_FUNCTION_EX),
|
||||
/* special cases */
|
||||
OK_OP(LOAD_CONST), /* ok because constants are accepted */
|
||||
OK_OP(LOAD_NAME), /* ok, because PyCodeObject.names is checked */
|
||||
OK_OP(CALL_FUNCTION), /* ok, because we check its 'name' before calling */
|
||||
OK_OP(CALL_FUNCTION_KW),
|
||||
OK_OP(CALL_FUNCTION_EX),
|
||||
};
|
||||
|
||||
#undef OK_OP
|
||||
# undef OK_OP
|
||||
|
||||
static bool bpy_driver_secure_bytecode_validate(PyObject *expr_code, PyObject *dict_arr[])
|
||||
{
|
||||
PyCodeObject *py_code = (PyCodeObject *)expr_code;
|
||||
PyCodeObject *py_code = (PyCodeObject *)expr_code;
|
||||
|
||||
/* Check names. */
|
||||
{
|
||||
for (int i = 0; i < PyTuple_GET_SIZE(py_code->co_names); i++) {
|
||||
PyObject *name = PyTuple_GET_ITEM(py_code->co_names, i);
|
||||
/* Check names. */
|
||||
{
|
||||
for (int i = 0; i < PyTuple_GET_SIZE(py_code->co_names); i++) {
|
||||
PyObject *name = PyTuple_GET_ITEM(py_code->co_names, i);
|
||||
|
||||
bool contains_name = false;
|
||||
for (int j = 0; dict_arr[j]; j++) {
|
||||
if (PyDict_Contains(dict_arr[j], name)) {
|
||||
contains_name = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool contains_name = false;
|
||||
for (int j = 0; dict_arr[j]; j++) {
|
||||
if (PyDict_Contains(dict_arr[j], name)) {
|
||||
contains_name = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (contains_name == false) {
|
||||
fprintf(stderr, "\tBPY_driver_eval() - restricted access disallows name '%s', "
|
||||
"enable auto-execution to support\n", _PyUnicode_AsString(name));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (contains_name == false) {
|
||||
fprintf(stderr,
|
||||
"\tBPY_driver_eval() - restricted access disallows name '%s', "
|
||||
"enable auto-execution to support\n",
|
||||
_PyUnicode_AsString(name));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check opcodes. */
|
||||
{
|
||||
const _Py_CODEUNIT *codestr;
|
||||
Py_ssize_t code_len;
|
||||
/* Check opcodes. */
|
||||
{
|
||||
const _Py_CODEUNIT *codestr;
|
||||
Py_ssize_t code_len;
|
||||
|
||||
PyBytes_AsStringAndSize(py_code->co_code, (char **)&codestr, &code_len);
|
||||
code_len /= sizeof(*codestr);
|
||||
PyBytes_AsStringAndSize(py_code->co_code, (char **)&codestr, &code_len);
|
||||
code_len /= sizeof(*codestr);
|
||||
|
||||
for (Py_ssize_t i = 0; i < code_len; i++) {
|
||||
const int opcode = _Py_OPCODE(codestr[i]);
|
||||
if (secure_opcodes[opcode] == 0) {
|
||||
fprintf(stderr, "\tBPY_driver_eval() - restricted access disallows opcode '%d', "
|
||||
"enable auto-execution to support\n", opcode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (Py_ssize_t i = 0; i < code_len; i++) {
|
||||
const int opcode = _Py_OPCODE(codestr[i]);
|
||||
if (secure_opcodes[opcode] == 0) {
|
||||
fprintf(stderr,
|
||||
"\tBPY_driver_eval() - restricted access disallows opcode '%d', "
|
||||
"enable auto-execution to support\n",
|
||||
opcode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#undef CODESIZE
|
||||
}
|
||||
# undef CODESIZE
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* USE_BYTECODE_WHITELIST */
|
||||
|
||||
#endif /* USE_BYTECODE_WHITELIST */
|
||||
|
||||
/* This evals py driver expressions, 'expr' is a Python expression that
|
||||
* should evaluate to a float number, which is returned.
|
||||
@@ -388,231 +392,239 @@ static bool bpy_driver_secure_bytecode_validate(PyObject *expr_code, PyObject *d
|
||||
* original driver, otherwise these would get freed while editing. Due to
|
||||
* the GIL this is thread-safe.
|
||||
*/
|
||||
float BPY_driver_exec(struct PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, const float evaltime)
|
||||
float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
|
||||
ChannelDriver *driver,
|
||||
ChannelDriver *driver_orig,
|
||||
const float evaltime)
|
||||
{
|
||||
PyObject *driver_vars = NULL;
|
||||
PyObject *retval = NULL;
|
||||
PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */
|
||||
PyObject *expr_code;
|
||||
PyGILState_STATE gilstate;
|
||||
bool use_gil;
|
||||
PyObject *driver_vars = NULL;
|
||||
PyObject *retval = NULL;
|
||||
PyObject *
|
||||
expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */
|
||||
PyObject *expr_code;
|
||||
PyGILState_STATE gilstate;
|
||||
bool use_gil;
|
||||
|
||||
DriverVar *dvar;
|
||||
double result = 0.0; /* default return */
|
||||
const char *expr;
|
||||
short targets_ok = 1;
|
||||
int i;
|
||||
DriverVar *dvar;
|
||||
double result = 0.0; /* default return */
|
||||
const char *expr;
|
||||
short targets_ok = 1;
|
||||
int i;
|
||||
|
||||
/* get the py expression to be evaluated */
|
||||
expr = driver_orig->expression;
|
||||
if (expr[0] == '\0') {
|
||||
return 0.0f;
|
||||
}
|
||||
/* get the py expression to be evaluated */
|
||||
expr = driver_orig->expression;
|
||||
if (expr[0] == '\0') {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
#ifndef USE_BYTECODE_WHITELIST
|
||||
if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
|
||||
if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET)) {
|
||||
G.f |= G_FLAG_SCRIPT_AUTOEXEC_FAIL;
|
||||
BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Driver '%s'", expr);
|
||||
if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
|
||||
if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET)) {
|
||||
G.f |= G_FLAG_SCRIPT_AUTOEXEC_FAIL;
|
||||
BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Driver '%s'", expr);
|
||||
|
||||
printf("skipping driver '%s', automatic scripts are disabled\n", expr);
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
printf("skipping driver '%s', automatic scripts are disabled\n", expr);
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
#else
|
||||
bool is_recompile = false;
|
||||
bool is_recompile = false;
|
||||
#endif
|
||||
|
||||
use_gil = true; /* !PyC_IsInterpreterActive(); */
|
||||
use_gil = true; /* !PyC_IsInterpreterActive(); */
|
||||
|
||||
if (use_gil) {
|
||||
gilstate = PyGILState_Ensure();
|
||||
}
|
||||
if (use_gil) {
|
||||
gilstate = PyGILState_Ensure();
|
||||
}
|
||||
|
||||
/* needed since drivers are updated directly after undo where 'main' is
|
||||
* re-allocated [#28807] */
|
||||
BPY_update_rna_module();
|
||||
/* needed since drivers are updated directly after undo where 'main' is
|
||||
* re-allocated [#28807] */
|
||||
BPY_update_rna_module();
|
||||
|
||||
/* init global dictionary for py-driver evaluation settings */
|
||||
if (!bpy_pydriver_Dict) {
|
||||
if (bpy_pydriver_create_dict() != 0) {
|
||||
fprintf(stderr, "PyDriver error: couldn't create Python dictionary\n");
|
||||
if (use_gil) {
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
/* init global dictionary for py-driver evaluation settings */
|
||||
if (!bpy_pydriver_Dict) {
|
||||
if (bpy_pydriver_create_dict() != 0) {
|
||||
fprintf(stderr, "PyDriver error: couldn't create Python dictionary\n");
|
||||
if (use_gil) {
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/* update global namespace */
|
||||
bpy_pydriver_namespace_update_frame(evaltime);
|
||||
/* update global namespace */
|
||||
bpy_pydriver_namespace_update_frame(evaltime);
|
||||
|
||||
if (driver_orig->flag & DRIVER_FLAG_USE_SELF) {
|
||||
bpy_pydriver_namespace_update_self(anim_rna);
|
||||
}
|
||||
else {
|
||||
bpy_pydriver_namespace_clear_self();
|
||||
}
|
||||
if (driver_orig->flag & DRIVER_FLAG_USE_SELF) {
|
||||
bpy_pydriver_namespace_update_self(anim_rna);
|
||||
}
|
||||
else {
|
||||
bpy_pydriver_namespace_clear_self();
|
||||
}
|
||||
|
||||
if (driver_orig->expr_comp == NULL) {
|
||||
driver_orig->flag |= DRIVER_FLAG_RECOMPILE;
|
||||
}
|
||||
if (driver_orig->expr_comp == NULL) {
|
||||
driver_orig->flag |= DRIVER_FLAG_RECOMPILE;
|
||||
}
|
||||
|
||||
/* compile the expression first if it hasn't been compiled or needs to be rebuilt */
|
||||
if (driver_orig->flag & DRIVER_FLAG_RECOMPILE) {
|
||||
Py_XDECREF(driver_orig->expr_comp);
|
||||
driver_orig->expr_comp = PyTuple_New(2);
|
||||
/* compile the expression first if it hasn't been compiled or needs to be rebuilt */
|
||||
if (driver_orig->flag & DRIVER_FLAG_RECOMPILE) {
|
||||
Py_XDECREF(driver_orig->expr_comp);
|
||||
driver_orig->expr_comp = PyTuple_New(2);
|
||||
|
||||
expr_code = Py_CompileString(expr, "<bpy driver>", Py_eval_input);
|
||||
PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, expr_code);
|
||||
expr_code = Py_CompileString(expr, "<bpy driver>", Py_eval_input);
|
||||
PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, expr_code);
|
||||
|
||||
driver_orig->flag &= ~DRIVER_FLAG_RECOMPILE;
|
||||
driver_orig->flag |= DRIVER_FLAG_RENAMEVAR; /* maybe this can be removed but for now best keep until were sure */
|
||||
driver_orig->flag &= ~DRIVER_FLAG_RECOMPILE;
|
||||
driver_orig->flag |=
|
||||
DRIVER_FLAG_RENAMEVAR; /* maybe this can be removed but for now best keep until were sure */
|
||||
#ifdef USE_BYTECODE_WHITELIST
|
||||
is_recompile = true;
|
||||
is_recompile = true;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 0);
|
||||
}
|
||||
|
||||
if (driver_orig->flag & DRIVER_FLAG_RENAMEVAR) {
|
||||
/* may not be set */
|
||||
expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
|
||||
Py_XDECREF(expr_vars);
|
||||
if (driver_orig->flag & DRIVER_FLAG_RENAMEVAR) {
|
||||
/* may not be set */
|
||||
expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
|
||||
Py_XDECREF(expr_vars);
|
||||
|
||||
expr_vars = PyTuple_New(BLI_listbase_count(&driver_orig->variables));
|
||||
PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 1, expr_vars);
|
||||
expr_vars = PyTuple_New(BLI_listbase_count(&driver_orig->variables));
|
||||
PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 1, expr_vars);
|
||||
|
||||
for (dvar = driver_orig->variables.first, i = 0; dvar; dvar = dvar->next) {
|
||||
PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name));
|
||||
}
|
||||
for (dvar = driver_orig->variables.first, i = 0; dvar; dvar = dvar->next) {
|
||||
PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name));
|
||||
}
|
||||
|
||||
driver_orig->flag &= ~DRIVER_FLAG_RENAMEVAR;
|
||||
}
|
||||
else {
|
||||
expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
|
||||
}
|
||||
driver_orig->flag &= ~DRIVER_FLAG_RENAMEVAR;
|
||||
}
|
||||
else {
|
||||
expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
|
||||
}
|
||||
|
||||
/* add target values to a dict that will be used as '__locals__' dict */
|
||||
driver_vars = _PyDict_NewPresized(PyTuple_GET_SIZE(expr_vars));
|
||||
for (dvar = driver->variables.first, i = 0; dvar; dvar = dvar->next) {
|
||||
PyObject *driver_arg = NULL;
|
||||
/* add target values to a dict that will be used as '__locals__' dict */
|
||||
driver_vars = _PyDict_NewPresized(PyTuple_GET_SIZE(expr_vars));
|
||||
for (dvar = driver->variables.first, i = 0; dvar; dvar = dvar->next) {
|
||||
PyObject *driver_arg = NULL;
|
||||
|
||||
/* support for any RNA data */
|
||||
/* support for any RNA data */
|
||||
#ifdef USE_RNA_AS_PYOBJECT
|
||||
if (dvar->type == DVAR_TYPE_SINGLE_PROP) {
|
||||
driver_arg = pyrna_driver_get_variable_value(driver, &dvar->targets[0]);
|
||||
if (dvar->type == DVAR_TYPE_SINGLE_PROP) {
|
||||
driver_arg = pyrna_driver_get_variable_value(driver, &dvar->targets[0]);
|
||||
|
||||
if (driver_arg == NULL) {
|
||||
driver_arg = PyFloat_FromDouble(0.0);
|
||||
dvar->curval = 0.0f;
|
||||
}
|
||||
else {
|
||||
/* no need to worry about overflow here, values from RNA are within limits. */
|
||||
if (PyFloat_CheckExact(driver_arg)) {
|
||||
dvar->curval = (float)PyFloat_AsDouble(driver_arg);
|
||||
}
|
||||
else if (PyLong_CheckExact(driver_arg)) {
|
||||
dvar->curval = (float)PyLong_AsLong(driver_arg);
|
||||
}
|
||||
else if (PyBool_Check(driver_arg)) {
|
||||
dvar->curval = (driver_arg == Py_True);
|
||||
}
|
||||
else {
|
||||
dvar->curval = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (driver_arg == NULL) {
|
||||
driver_arg = PyFloat_FromDouble(0.0);
|
||||
dvar->curval = 0.0f;
|
||||
}
|
||||
else {
|
||||
/* no need to worry about overflow here, values from RNA are within limits. */
|
||||
if (PyFloat_CheckExact(driver_arg)) {
|
||||
dvar->curval = (float)PyFloat_AsDouble(driver_arg);
|
||||
}
|
||||
else if (PyLong_CheckExact(driver_arg)) {
|
||||
dvar->curval = (float)PyLong_AsLong(driver_arg);
|
||||
}
|
||||
else if (PyBool_Check(driver_arg)) {
|
||||
dvar->curval = (driver_arg == Py_True);
|
||||
}
|
||||
else {
|
||||
dvar->curval = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* try to get variable value */
|
||||
float tval = driver_get_variable_value(driver, dvar);
|
||||
driver_arg = PyFloat_FromDouble((double)tval);
|
||||
}
|
||||
{
|
||||
/* try to get variable value */
|
||||
float tval = driver_get_variable_value(driver, dvar);
|
||||
driver_arg = PyFloat_FromDouble((double)tval);
|
||||
}
|
||||
|
||||
/* try to add to dictionary */
|
||||
/* if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) { */
|
||||
if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) != -1) {
|
||||
Py_DECREF(driver_arg);
|
||||
}
|
||||
else {
|
||||
/* this target failed - bad name */
|
||||
if (targets_ok) {
|
||||
/* first one - print some extra info for easier identification */
|
||||
fprintf(stderr, "\nBPY_driver_eval() - Error while evaluating PyDriver:\n");
|
||||
targets_ok = 0;
|
||||
}
|
||||
/* try to add to dictionary */
|
||||
/* if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) { */
|
||||
if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) != -1) {
|
||||
Py_DECREF(driver_arg);
|
||||
}
|
||||
else {
|
||||
/* this target failed - bad name */
|
||||
if (targets_ok) {
|
||||
/* first one - print some extra info for easier identification */
|
||||
fprintf(stderr, "\nBPY_driver_eval() - Error while evaluating PyDriver:\n");
|
||||
targets_ok = 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n", dvar->name);
|
||||
// BPy_errors_to_report(NULL); // TODO - reports
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
fprintf(
|
||||
stderr, "\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n", dvar->name);
|
||||
// BPy_errors_to_report(NULL); // TODO - reports
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_BYTECODE_WHITELIST
|
||||
if (is_recompile && expr_code) {
|
||||
if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
|
||||
if (!bpy_driver_secure_bytecode_validate(
|
||||
expr_code, (PyObject *[]){
|
||||
bpy_pydriver_Dict,
|
||||
bpy_pydriver_Dict__whitelist,
|
||||
driver_vars,
|
||||
NULL,}
|
||||
))
|
||||
{
|
||||
if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET)) {
|
||||
G.f |= G_FLAG_SCRIPT_AUTOEXEC_FAIL;
|
||||
BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Driver '%s'", expr);
|
||||
}
|
||||
if (is_recompile && expr_code) {
|
||||
if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
|
||||
if (!bpy_driver_secure_bytecode_validate(expr_code,
|
||||
(PyObject *[]){
|
||||
bpy_pydriver_Dict,
|
||||
bpy_pydriver_Dict__whitelist,
|
||||
driver_vars,
|
||||
NULL,
|
||||
})) {
|
||||
if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET)) {
|
||||
G.f |= G_FLAG_SCRIPT_AUTOEXEC_FAIL;
|
||||
BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Driver '%s'", expr);
|
||||
}
|
||||
|
||||
Py_DECREF(expr_code);
|
||||
expr_code = NULL;
|
||||
PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* USE_BYTECODE_WHITELIST */
|
||||
Py_DECREF(expr_code);
|
||||
expr_code = NULL;
|
||||
PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* USE_BYTECODE_WHITELIST */
|
||||
|
||||
#if 0 /* slow, with this can avoid all Py_CompileString above. */
|
||||
/* execute expression to get a value */
|
||||
retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
|
||||
#if 0 /* slow, with this can avoid all Py_CompileString above. */
|
||||
/* execute expression to get a value */
|
||||
retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
|
||||
#else
|
||||
/* evaluate the compiled expression */
|
||||
if (expr_code) {
|
||||
retval = PyEval_EvalCode((void *)expr_code, bpy_pydriver_Dict, driver_vars);
|
||||
}
|
||||
/* evaluate the compiled expression */
|
||||
if (expr_code) {
|
||||
retval = PyEval_EvalCode((void *)expr_code, bpy_pydriver_Dict, driver_vars);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* decref the driver vars first... */
|
||||
Py_DECREF(driver_vars);
|
||||
/* decref the driver vars first... */
|
||||
Py_DECREF(driver_vars);
|
||||
|
||||
/* process the result */
|
||||
if (retval == NULL) {
|
||||
pydriver_error(driver);
|
||||
}
|
||||
else if ((result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred()) {
|
||||
pydriver_error(driver);
|
||||
Py_DECREF(retval);
|
||||
result = 0.0;
|
||||
}
|
||||
else {
|
||||
/* all fine, make sure the "invalid expression" flag is cleared */
|
||||
driver->flag &= ~DRIVER_FLAG_INVALID;
|
||||
Py_DECREF(retval);
|
||||
}
|
||||
/* process the result */
|
||||
if (retval == NULL) {
|
||||
pydriver_error(driver);
|
||||
}
|
||||
else if ((result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred()) {
|
||||
pydriver_error(driver);
|
||||
Py_DECREF(retval);
|
||||
result = 0.0;
|
||||
}
|
||||
else {
|
||||
/* all fine, make sure the "invalid expression" flag is cleared */
|
||||
driver->flag &= ~DRIVER_FLAG_INVALID;
|
||||
Py_DECREF(retval);
|
||||
}
|
||||
|
||||
if (use_gil) {
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
if (use_gil) {
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
|
||||
if (isfinite(result)) {
|
||||
return (float)result;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "\tBPY_driver_eval() - driver '%s' evaluates to '%f'\n", driver->expression, result);
|
||||
return 0.0f;
|
||||
}
|
||||
if (isfinite(result)) {
|
||||
return (float)result;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"\tBPY_driver_eval() - driver '%s' evaluates to '%f'\n",
|
||||
driver->expression,
|
||||
result);
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,4 @@
|
||||
int bpy_pydriver_create_dict(void);
|
||||
extern PyObject *bpy_pydriver_Dict;
|
||||
|
||||
#endif /* __BPY_DRIVER_H__ */
|
||||
#endif /* __BPY_DRIVER_H__ */
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
#include "bpy_rna.h"
|
||||
#include "bpy_intern_string.h"
|
||||
#include "bpy_gizmo_wrap.h" /* own include */
|
||||
#include "bpy_gizmo_wrap.h" /* own include */
|
||||
|
||||
/* we may want to add, but not now */
|
||||
|
||||
@@ -47,176 +47,168 @@
|
||||
/** \name Gizmo
|
||||
* \{ */
|
||||
|
||||
|
||||
static bool bpy_gizmotype_target_property_def(
|
||||
wmGizmoType *gzt, PyObject *item)
|
||||
static bool bpy_gizmotype_target_property_def(wmGizmoType *gzt, PyObject *item)
|
||||
{
|
||||
/* Note: names based on 'rna_rna.c' */
|
||||
PyObject *empty_tuple = PyTuple_New(0);
|
||||
/* Note: names based on 'rna_rna.c' */
|
||||
PyObject *empty_tuple = PyTuple_New(0);
|
||||
|
||||
struct {
|
||||
char *id;
|
||||
char *type_id; int type;
|
||||
int array_length;
|
||||
} params = {
|
||||
.id = NULL, /* not optional */
|
||||
.type = PROP_FLOAT,
|
||||
.type_id = NULL,
|
||||
.array_length = 1,
|
||||
};
|
||||
struct {
|
||||
char *id;
|
||||
char *type_id;
|
||||
int type;
|
||||
int array_length;
|
||||
} params = {
|
||||
.id = NULL, /* not optional */
|
||||
.type = PROP_FLOAT,
|
||||
.type_id = NULL,
|
||||
.array_length = 1,
|
||||
};
|
||||
|
||||
static const char * const _keywords[] = {"id", "type", "array_length", NULL};
|
||||
static _PyArg_Parser _parser = {"|$ssi:register_class", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
empty_tuple, item,
|
||||
&_parser,
|
||||
¶ms.id,
|
||||
¶ms.type_id,
|
||||
¶ms.array_length))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
static const char *const _keywords[] = {"id", "type", "array_length", NULL};
|
||||
static _PyArg_Parser _parser = {"|$ssi:register_class", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
empty_tuple, item, &_parser, ¶ms.id, ¶ms.type_id, ¶ms.array_length)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (params.id == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "'id' argument not given");
|
||||
goto fail;
|
||||
}
|
||||
if (params.id == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "'id' argument not given");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((params.type_id != NULL) &&
|
||||
pyrna_enum_value_from_id(
|
||||
rna_enum_property_type_items, params.type_id, ¶ms.type, "'type' enum value") == -1)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
else {
|
||||
params.type = rna_enum_property_type_items[params.type].value;
|
||||
}
|
||||
if ((params.type_id != NULL) &&
|
||||
pyrna_enum_value_from_id(
|
||||
rna_enum_property_type_items, params.type_id, ¶ms.type, "'type' enum value") == -1) {
|
||||
goto fail;
|
||||
}
|
||||
else {
|
||||
params.type = rna_enum_property_type_items[params.type].value;
|
||||
}
|
||||
|
||||
if ((params.array_length < 1 || params.array_length > RNA_MAX_ARRAY_LENGTH)) {
|
||||
PyErr_SetString(PyExc_ValueError, "'array_length' out of range");
|
||||
goto fail;
|
||||
}
|
||||
if ((params.array_length < 1 || params.array_length > RNA_MAX_ARRAY_LENGTH)) {
|
||||
PyErr_SetString(PyExc_ValueError, "'array_length' out of range");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
WM_gizmotype_target_property_def(gzt, params.id, params.type, params.array_length);
|
||||
Py_DECREF(empty_tuple);
|
||||
return true;
|
||||
WM_gizmotype_target_property_def(gzt, params.id, params.type, params.array_length);
|
||||
Py_DECREF(empty_tuple);
|
||||
return true;
|
||||
|
||||
fail:
|
||||
Py_DECREF(empty_tuple);
|
||||
return false;
|
||||
Py_DECREF(empty_tuple);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gizmo_properties_init(wmGizmoType *gzt)
|
||||
{
|
||||
PyTypeObject *py_class = gzt->ext.data;
|
||||
RNA_struct_blender_type_set(gzt->ext.srna, gzt);
|
||||
PyTypeObject *py_class = gzt->ext.data;
|
||||
RNA_struct_blender_type_set(gzt->ext.srna, gzt);
|
||||
|
||||
/* only call this so pyrna_deferred_register_class gives a useful error
|
||||
* WM_operatortype_append_ptr will call RNA_def_struct_identifier
|
||||
* later */
|
||||
RNA_def_struct_identifier_no_struct_map(gzt->srna, gzt->idname);
|
||||
/* only call this so pyrna_deferred_register_class gives a useful error
|
||||
* WM_operatortype_append_ptr will call RNA_def_struct_identifier
|
||||
* later */
|
||||
RNA_def_struct_identifier_no_struct_map(gzt->srna, gzt->idname);
|
||||
|
||||
if (pyrna_deferred_register_class(gzt->srna, py_class) != 0) {
|
||||
PyErr_Print(); /* failed to register operator props */
|
||||
PyErr_Clear();
|
||||
}
|
||||
if (pyrna_deferred_register_class(gzt->srna, py_class) != 0) {
|
||||
PyErr_Print(); /* failed to register operator props */
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
/* Extract target property definitions from 'bl_target_properties' */
|
||||
{
|
||||
/* picky developers will notice that 'bl_targets' won't work with inheritance
|
||||
* get direct from the dict to avoid raising a load of attribute errors (yes this isnt ideal) - campbell */
|
||||
PyObject *py_class_dict = py_class->tp_dict;
|
||||
PyObject *bl_target_properties = PyDict_GetItem(py_class_dict, bpy_intern_str_bl_target_properties);
|
||||
/* Extract target property definitions from 'bl_target_properties' */
|
||||
{
|
||||
/* picky developers will notice that 'bl_targets' won't work with inheritance
|
||||
* get direct from the dict to avoid raising a load of attribute errors (yes this isnt ideal) - campbell */
|
||||
PyObject *py_class_dict = py_class->tp_dict;
|
||||
PyObject *bl_target_properties = PyDict_GetItem(py_class_dict,
|
||||
bpy_intern_str_bl_target_properties);
|
||||
|
||||
/* Some widgets may only exist to activate operators. */
|
||||
if (bl_target_properties != NULL) {
|
||||
PyObject *bl_target_properties_fast;
|
||||
if (!(bl_target_properties_fast = PySequence_Fast(
|
||||
bl_target_properties, "bl_target_properties sequence")))
|
||||
{
|
||||
/* PySequence_Fast sets the error */
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
return;
|
||||
}
|
||||
/* Some widgets may only exist to activate operators. */
|
||||
if (bl_target_properties != NULL) {
|
||||
PyObject *bl_target_properties_fast;
|
||||
if (!(bl_target_properties_fast = PySequence_Fast(bl_target_properties,
|
||||
"bl_target_properties sequence"))) {
|
||||
/* PySequence_Fast sets the error */
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
const uint items_len = PySequence_Fast_GET_SIZE(bl_target_properties_fast);
|
||||
PyObject **items = PySequence_Fast_ITEMS(bl_target_properties_fast);
|
||||
const uint items_len = PySequence_Fast_GET_SIZE(bl_target_properties_fast);
|
||||
PyObject **items = PySequence_Fast_ITEMS(bl_target_properties_fast);
|
||||
|
||||
for (uint i = 0; i < items_len; i++) {
|
||||
if (!bpy_gizmotype_target_property_def(gzt, items[i])) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (uint i = 0; i < items_len; i++) {
|
||||
if (!bpy_gizmotype_target_property_def(gzt, items[i])) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(bl_target_properties_fast);
|
||||
}
|
||||
}
|
||||
Py_DECREF(bl_target_properties_fast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BPY_RNA_gizmo_wrapper(wmGizmoType *gzt, void *userdata)
|
||||
{
|
||||
/* take care not to overwrite anything set in
|
||||
* WM_gizmomaptype_group_link_ptr before opfunc() is called */
|
||||
StructRNA *srna = gzt->srna;
|
||||
*gzt = *((wmGizmoType *)userdata);
|
||||
gzt->srna = srna; /* restore */
|
||||
/* take care not to overwrite anything set in
|
||||
* WM_gizmomaptype_group_link_ptr before opfunc() is called */
|
||||
StructRNA *srna = gzt->srna;
|
||||
*gzt = *((wmGizmoType *)userdata);
|
||||
gzt->srna = srna; /* restore */
|
||||
|
||||
/* don't do translations here yet */
|
||||
/* don't do translations here yet */
|
||||
#if 0
|
||||
/* Use i18n context from ext.srna if possible (py gizmogroups). */
|
||||
if (gt->ext.srna) {
|
||||
RNA_def_struct_translation_context(gt->srna, RNA_struct_translation_context(gt->ext.srna));
|
||||
}
|
||||
/* Use i18n context from ext.srna if possible (py gizmogroups). */
|
||||
if (gt->ext.srna) {
|
||||
RNA_def_struct_translation_context(gt->srna, RNA_struct_translation_context(gt->ext.srna));
|
||||
}
|
||||
#endif
|
||||
|
||||
gzt->struct_size = sizeof(wmGizmo);
|
||||
gzt->struct_size = sizeof(wmGizmo);
|
||||
|
||||
gizmo_properties_init(gzt);
|
||||
gizmo_properties_init(gzt);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Gizmo Group
|
||||
* \{ */
|
||||
|
||||
static void gizmogroup_properties_init(wmGizmoGroupType *gzgt)
|
||||
{
|
||||
PyTypeObject *py_class = gzgt->ext.data;
|
||||
RNA_struct_blender_type_set(gzgt->ext.srna, gzgt);
|
||||
PyTypeObject *py_class = gzgt->ext.data;
|
||||
RNA_struct_blender_type_set(gzgt->ext.srna, gzgt);
|
||||
|
||||
/* only call this so pyrna_deferred_register_class gives a useful error
|
||||
* WM_operatortype_append_ptr will call RNA_def_struct_identifier
|
||||
* later */
|
||||
RNA_def_struct_identifier_no_struct_map(gzgt->srna, gzgt->idname);
|
||||
/* only call this so pyrna_deferred_register_class gives a useful error
|
||||
* WM_operatortype_append_ptr will call RNA_def_struct_identifier
|
||||
* later */
|
||||
RNA_def_struct_identifier_no_struct_map(gzgt->srna, gzgt->idname);
|
||||
|
||||
if (pyrna_deferred_register_class(gzgt->srna, py_class) != 0) {
|
||||
PyErr_Print(); /* failed to register operator props */
|
||||
PyErr_Clear();
|
||||
}
|
||||
if (pyrna_deferred_register_class(gzgt->srna, py_class) != 0) {
|
||||
PyErr_Print(); /* failed to register operator props */
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void BPY_RNA_gizmogroup_wrapper(wmGizmoGroupType *gzgt, void *userdata)
|
||||
{
|
||||
/* take care not to overwrite anything set in
|
||||
* WM_gizmomaptype_group_link_ptr before opfunc() is called */
|
||||
StructRNA *srna = gzgt->srna;
|
||||
*gzgt = *((wmGizmoGroupType *)userdata);
|
||||
gzgt->srna = srna; /* restore */
|
||||
/* take care not to overwrite anything set in
|
||||
* WM_gizmomaptype_group_link_ptr before opfunc() is called */
|
||||
StructRNA *srna = gzgt->srna;
|
||||
*gzgt = *((wmGizmoGroupType *)userdata);
|
||||
gzgt->srna = srna; /* restore */
|
||||
|
||||
/* don't do translations here yet */
|
||||
/* don't do translations here yet */
|
||||
#if 0
|
||||
/* Use i18n context from ext.srna if possible (py gizmogroups). */
|
||||
if (gzgt->ext.srna) {
|
||||
RNA_def_struct_translation_context(gzgt->srna, RNA_struct_translation_context(gzgt->ext.srna));
|
||||
}
|
||||
/* Use i18n context from ext.srna if possible (py gizmogroups). */
|
||||
if (gzgt->ext.srna) {
|
||||
RNA_def_struct_translation_context(gzgt->srna, RNA_struct_translation_context(gzgt->ext.srna));
|
||||
}
|
||||
#endif
|
||||
|
||||
gizmogroup_properties_init(gzgt);
|
||||
gizmogroup_properties_init(gzgt);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -28,4 +28,4 @@ struct wmGizmoType;
|
||||
void BPY_RNA_gizmo_wrapper(struct wmGizmoType *gzt, void *userdata);
|
||||
void BPY_RNA_gizmogroup_wrapper(struct wmGizmoGroupType *gzgt, void *userdata);
|
||||
|
||||
#endif /* __BPY_GIZMO_WRAP_H__ */
|
||||
#endif /* __BPY_GIZMO_WRAP_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,24 +22,23 @@
|
||||
* resources.
|
||||
*/
|
||||
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "bpy_capi_utils.h"
|
||||
#include "bpy.h" /* own include */
|
||||
#include "bpy.h" /* own include */
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
static PyObject *bpy_atexit(PyObject *UNUSED(self), PyObject *UNUSED(args), PyObject *UNUSED(kw))
|
||||
{
|
||||
/* close down enough of blender at least not to crash */
|
||||
struct bContext *C = BPy_GetContext();
|
||||
/* close down enough of blender at least not to crash */
|
||||
struct bContext *C = BPy_GetContext();
|
||||
|
||||
WM_exit_ext(C, 0);
|
||||
WM_exit_ext(C, 0);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef meth_bpy_atexit = {"bpy_atexit", (PyCFunction)bpy_atexit, METH_NOARGS, NULL};
|
||||
@@ -47,45 +46,45 @@ static PyObject *func_bpy_atregister = NULL; /* borrowed referebce, atexit holds
|
||||
|
||||
static void atexit_func_call(const char *func_name, PyObject *atexit_func_arg)
|
||||
{
|
||||
/* note - no error checking, if any of these fail we'll get a crash
|
||||
* this is intended, but if its problematic it could be changed
|
||||
* - campbell */
|
||||
/* note - no error checking, if any of these fail we'll get a crash
|
||||
* this is intended, but if its problematic it could be changed
|
||||
* - campbell */
|
||||
|
||||
PyObject *atexit_mod = PyImport_ImportModuleLevel("atexit", NULL, NULL, NULL, 0);
|
||||
PyObject *atexit_func = PyObject_GetAttrString(atexit_mod, func_name);
|
||||
PyObject *args = PyTuple_New(1);
|
||||
PyObject *ret;
|
||||
PyObject *atexit_mod = PyImport_ImportModuleLevel("atexit", NULL, NULL, NULL, 0);
|
||||
PyObject *atexit_func = PyObject_GetAttrString(atexit_mod, func_name);
|
||||
PyObject *args = PyTuple_New(1);
|
||||
PyObject *ret;
|
||||
|
||||
PyTuple_SET_ITEM(args, 0, atexit_func_arg);
|
||||
Py_INCREF(atexit_func_arg); /* only incref so we don't dec'ref along with 'args' */
|
||||
PyTuple_SET_ITEM(args, 0, atexit_func_arg);
|
||||
Py_INCREF(atexit_func_arg); /* only incref so we don't dec'ref along with 'args' */
|
||||
|
||||
ret = PyObject_CallObject(atexit_func, args);
|
||||
ret = PyObject_CallObject(atexit_func, args);
|
||||
|
||||
Py_DECREF(atexit_mod);
|
||||
Py_DECREF(atexit_func);
|
||||
Py_DECREF(args);
|
||||
Py_DECREF(atexit_mod);
|
||||
Py_DECREF(atexit_func);
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret) {
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
else { /* should never happen */
|
||||
PyErr_Print();
|
||||
}
|
||||
if (ret) {
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
else { /* should never happen */
|
||||
PyErr_Print();
|
||||
}
|
||||
}
|
||||
|
||||
void BPY_atexit_register(void)
|
||||
{
|
||||
/* atexit module owns this new function reference */
|
||||
BLI_assert(func_bpy_atregister == NULL);
|
||||
/* atexit module owns this new function reference */
|
||||
BLI_assert(func_bpy_atregister == NULL);
|
||||
|
||||
func_bpy_atregister = (PyObject *)PyCFunction_New(&meth_bpy_atexit, NULL);
|
||||
atexit_func_call("register", func_bpy_atregister);
|
||||
func_bpy_atregister = (PyObject *)PyCFunction_New(&meth_bpy_atexit, NULL);
|
||||
atexit_func_call("register", func_bpy_atregister);
|
||||
}
|
||||
|
||||
void BPY_atexit_unregister(void)
|
||||
{
|
||||
BLI_assert(func_bpy_atregister != NULL);
|
||||
BLI_assert(func_bpy_atregister != NULL);
|
||||
|
||||
atexit_func_call("unregister", func_bpy_atregister);
|
||||
func_bpy_atregister = NULL; /* don't really need to set but just in case */
|
||||
atexit_func_call("unregister", func_bpy_atregister);
|
||||
func_bpy_atregister = NULL; /* don't really need to set but just in case */
|
||||
}
|
||||
|
||||
@@ -49,37 +49,40 @@ PyObject *bpy_intern_str_unregister;
|
||||
|
||||
void bpy_intern_string_init(void)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int i = 0;
|
||||
|
||||
#define BPY_INTERN_STR(var, str) \
|
||||
{ var = bpy_intern_str_arr[i++] = PyUnicode_FromString(str); } (void)0
|
||||
{ \
|
||||
var = bpy_intern_str_arr[i++] = PyUnicode_FromString(str); \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
BPY_INTERN_STR(bpy_intern_str___annotations__, "__annotations__");
|
||||
BPY_INTERN_STR(bpy_intern_str___doc__, "__doc__");
|
||||
BPY_INTERN_STR(bpy_intern_str___main__, "__main__");
|
||||
BPY_INTERN_STR(bpy_intern_str___module__, "__module__");
|
||||
BPY_INTERN_STR(bpy_intern_str___name__, "__name__");
|
||||
BPY_INTERN_STR(bpy_intern_str___slots__, "__slots__");
|
||||
BPY_INTERN_STR(bpy_intern_str_attr, "attr");
|
||||
BPY_INTERN_STR(bpy_intern_str_bl_property, "bl_property");
|
||||
BPY_INTERN_STR(bpy_intern_str_bl_rna, "bl_rna");
|
||||
BPY_INTERN_STR(bpy_intern_str_bl_target_properties, "bl_target_properties");
|
||||
BPY_INTERN_STR(bpy_intern_str_bpy_types, "bpy.types");
|
||||
BPY_INTERN_STR(bpy_intern_str_frame, "frame");
|
||||
BPY_INTERN_STR(bpy_intern_str_properties, "properties");
|
||||
BPY_INTERN_STR(bpy_intern_str_register, "register");
|
||||
BPY_INTERN_STR(bpy_intern_str_self, "self");
|
||||
BPY_INTERN_STR(bpy_intern_str_unregister, "unregister");
|
||||
BPY_INTERN_STR(bpy_intern_str___annotations__, "__annotations__");
|
||||
BPY_INTERN_STR(bpy_intern_str___doc__, "__doc__");
|
||||
BPY_INTERN_STR(bpy_intern_str___main__, "__main__");
|
||||
BPY_INTERN_STR(bpy_intern_str___module__, "__module__");
|
||||
BPY_INTERN_STR(bpy_intern_str___name__, "__name__");
|
||||
BPY_INTERN_STR(bpy_intern_str___slots__, "__slots__");
|
||||
BPY_INTERN_STR(bpy_intern_str_attr, "attr");
|
||||
BPY_INTERN_STR(bpy_intern_str_bl_property, "bl_property");
|
||||
BPY_INTERN_STR(bpy_intern_str_bl_rna, "bl_rna");
|
||||
BPY_INTERN_STR(bpy_intern_str_bl_target_properties, "bl_target_properties");
|
||||
BPY_INTERN_STR(bpy_intern_str_bpy_types, "bpy.types");
|
||||
BPY_INTERN_STR(bpy_intern_str_frame, "frame");
|
||||
BPY_INTERN_STR(bpy_intern_str_properties, "properties");
|
||||
BPY_INTERN_STR(bpy_intern_str_register, "register");
|
||||
BPY_INTERN_STR(bpy_intern_str_self, "self");
|
||||
BPY_INTERN_STR(bpy_intern_str_unregister, "unregister");
|
||||
|
||||
#undef BPY_INTERN_STR
|
||||
|
||||
BLI_assert(i == ARRAY_SIZE(bpy_intern_str_arr));
|
||||
BLI_assert(i == ARRAY_SIZE(bpy_intern_str_arr));
|
||||
}
|
||||
|
||||
void bpy_intern_string_exit(void)
|
||||
{
|
||||
unsigned int i = ARRAY_SIZE(bpy_intern_str_arr);
|
||||
while (i--) {
|
||||
Py_DECREF(bpy_intern_str_arr[i]);
|
||||
}
|
||||
unsigned int i = ARRAY_SIZE(bpy_intern_str_arr);
|
||||
while (i--) {
|
||||
Py_DECREF(bpy_intern_str_arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,4 +41,4 @@ extern PyObject *bpy_intern_str_register;
|
||||
extern PyObject *bpy_intern_str_self;
|
||||
extern PyObject *bpy_intern_str_unregister;
|
||||
|
||||
#endif /* __BPY_INTERN_STRING_H__ */
|
||||
#endif /* __BPY_INTERN_STRING_H__ */
|
||||
|
||||
@@ -24,4 +24,4 @@
|
||||
int BPY_library_load_module(PyObject *mod_par);
|
||||
int BPY_library_write_module(PyObject *mod_par);
|
||||
|
||||
#endif /* __BPY_LIBRARY_H__ */
|
||||
#endif /* __BPY_LIBRARY_H__ */
|
||||
|
||||
@@ -59,13 +59,13 @@
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD /* required python macro */
|
||||
/* collection iterator specific parts */
|
||||
char relpath[FILE_MAX];
|
||||
char abspath[FILE_MAX]; /* absolute path */
|
||||
BlendHandle *blo_handle;
|
||||
int flag;
|
||||
PyObject *dict;
|
||||
PyObject_HEAD /* required python macro */
|
||||
/* collection iterator specific parts */
|
||||
char relpath[FILE_MAX];
|
||||
char abspath[FILE_MAX]; /* absolute path */
|
||||
BlendHandle *blo_handle;
|
||||
int flag;
|
||||
PyObject *dict;
|
||||
} BPy_Library;
|
||||
|
||||
static PyObject *bpy_lib_load(PyObject *self, PyObject *args, PyObject *kwds);
|
||||
@@ -74,411 +74,407 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *args);
|
||||
static PyObject *bpy_lib_dir(BPy_Library *self);
|
||||
|
||||
static PyMethodDef bpy_lib_methods[] = {
|
||||
{"__enter__", (PyCFunction)bpy_lib_enter, METH_NOARGS},
|
||||
{"__exit__", (PyCFunction)bpy_lib_exit, METH_VARARGS},
|
||||
{"__dir__", (PyCFunction)bpy_lib_dir, METH_NOARGS},
|
||||
{NULL} /* sentinel */
|
||||
{"__enter__", (PyCFunction)bpy_lib_enter, METH_NOARGS},
|
||||
{"__exit__", (PyCFunction)bpy_lib_exit, METH_VARARGS},
|
||||
{"__dir__", (PyCFunction)bpy_lib_dir, METH_NOARGS},
|
||||
{NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static void bpy_lib_dealloc(BPy_Library *self)
|
||||
{
|
||||
Py_XDECREF(self->dict);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
Py_XDECREF(self->dict);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
}
|
||||
|
||||
|
||||
static PyTypeObject bpy_lib_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"bpy_lib", /* tp_name */
|
||||
sizeof(BPy_Library), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
/* methods */
|
||||
(destructor)bpy_lib_dealloc, /* tp_dealloc */
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
|
||||
NULL, /* tp_repr */
|
||||
PyVarObject_HEAD_INIT(NULL, 0) "bpy_lib", /* tp_name */
|
||||
sizeof(BPy_Library), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
/* methods */
|
||||
(destructor)bpy_lib_dealloc, /* tp_dealloc */
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
NULL,
|
||||
/* tp_compare */ /* DEPRECATED in python 3.0! */
|
||||
NULL, /* tp_repr */
|
||||
|
||||
/* Method suites for standard classes */
|
||||
/* Method suites for standard classes */
|
||||
|
||||
NULL, /* PyNumberMethods *tp_as_number; */
|
||||
NULL, /* PySequenceMethods *tp_as_sequence; */
|
||||
NULL, /* PyMappingMethods *tp_as_mapping; */
|
||||
NULL, /* PyNumberMethods *tp_as_number; */
|
||||
NULL, /* PySequenceMethods *tp_as_sequence; */
|
||||
NULL, /* PyMappingMethods *tp_as_mapping; */
|
||||
|
||||
/* More standard operations (here for binary compatibility) */
|
||||
/* More standard operations (here for binary compatibility) */
|
||||
|
||||
NULL, /* hashfunc tp_hash; */
|
||||
NULL, /* ternaryfunc tp_call; */
|
||||
NULL, /* reprfunc tp_str; */
|
||||
NULL, /* hashfunc tp_hash; */
|
||||
NULL, /* ternaryfunc tp_call; */
|
||||
NULL, /* reprfunc tp_str; */
|
||||
|
||||
/* will only use these if this is a subtype of a py class */
|
||||
NULL /*PyObject_GenericGetAttr is assigned later */, /* getattrofunc tp_getattro; */
|
||||
NULL, /* setattrofunc tp_setattro; */
|
||||
/* will only use these if this is a subtype of a py class */
|
||||
NULL /*PyObject_GenericGetAttr is assigned later */, /* getattrofunc tp_getattro; */
|
||||
NULL, /* setattrofunc tp_setattro; */
|
||||
|
||||
/* Functions to access object as input/output buffer */
|
||||
NULL, /* PyBufferProcs *tp_as_buffer; */
|
||||
/* Functions to access object as input/output buffer */
|
||||
NULL, /* PyBufferProcs *tp_as_buffer; */
|
||||
|
||||
/*** Flags to define presence of optional/expanded features ***/
|
||||
Py_TPFLAGS_DEFAULT, /* long tp_flags; */
|
||||
/*** Flags to define presence of optional/expanded features ***/
|
||||
Py_TPFLAGS_DEFAULT, /* long tp_flags; */
|
||||
|
||||
NULL, /* char *tp_doc; Documentation string */
|
||||
/*** Assigned meaning in release 2.0 ***/
|
||||
/* call function for all accessible objects */
|
||||
NULL, /* traverseproc tp_traverse; */
|
||||
NULL, /* char *tp_doc; Documentation string */
|
||||
/*** Assigned meaning in release 2.0 ***/
|
||||
/* call function for all accessible objects */
|
||||
NULL, /* traverseproc tp_traverse; */
|
||||
|
||||
/* delete references to contained objects */
|
||||
NULL, /* inquiry tp_clear; */
|
||||
/* delete references to contained objects */
|
||||
NULL, /* inquiry tp_clear; */
|
||||
|
||||
/*** Assigned meaning in release 2.1 ***/
|
||||
/*** rich comparisons (subclassed) ***/
|
||||
NULL, /* richcmpfunc tp_richcompare; */
|
||||
/*** Assigned meaning in release 2.1 ***/
|
||||
/*** rich comparisons (subclassed) ***/
|
||||
NULL, /* richcmpfunc tp_richcompare; */
|
||||
|
||||
/*** weak reference enabler ***/
|
||||
0,
|
||||
/*** Added in release 2.2 ***/
|
||||
/* Iterators */
|
||||
NULL, /* getiterfunc tp_iter; */
|
||||
NULL, /* iternextfunc tp_iternext; */
|
||||
/*** weak reference enabler ***/
|
||||
0,
|
||||
/*** Added in release 2.2 ***/
|
||||
/* Iterators */
|
||||
NULL, /* getiterfunc tp_iter; */
|
||||
NULL, /* iternextfunc tp_iternext; */
|
||||
|
||||
/*** Attribute descriptor and subclassing stuff ***/
|
||||
bpy_lib_methods, /* struct PyMethodDef *tp_methods; */
|
||||
NULL, /* struct PyMemberDef *tp_members; */
|
||||
NULL, /* struct PyGetSetDef *tp_getset; */
|
||||
NULL, /* struct _typeobject *tp_base; */
|
||||
NULL, /* PyObject *tp_dict; */
|
||||
NULL, /* descrgetfunc tp_descr_get; */
|
||||
NULL, /* descrsetfunc tp_descr_set; */
|
||||
offsetof(BPy_Library, dict), /* long tp_dictoffset; */
|
||||
NULL, /* initproc tp_init; */
|
||||
NULL, /* allocfunc tp_alloc; */
|
||||
NULL, /* newfunc tp_new; */
|
||||
/* Low-level free-memory routine */
|
||||
NULL, /* freefunc tp_free; */
|
||||
/* For PyObject_IS_GC */
|
||||
NULL, /* inquiry tp_is_gc; */
|
||||
NULL, /* PyObject *tp_bases; */
|
||||
/* method resolution order */
|
||||
NULL, /* PyObject *tp_mro; */
|
||||
NULL, /* PyObject *tp_cache; */
|
||||
NULL, /* PyObject *tp_subclasses; */
|
||||
NULL, /* PyObject *tp_weaklist; */
|
||||
NULL,
|
||||
/*** Attribute descriptor and subclassing stuff ***/
|
||||
bpy_lib_methods, /* struct PyMethodDef *tp_methods; */
|
||||
NULL, /* struct PyMemberDef *tp_members; */
|
||||
NULL, /* struct PyGetSetDef *tp_getset; */
|
||||
NULL, /* struct _typeobject *tp_base; */
|
||||
NULL, /* PyObject *tp_dict; */
|
||||
NULL, /* descrgetfunc tp_descr_get; */
|
||||
NULL, /* descrsetfunc tp_descr_set; */
|
||||
offsetof(BPy_Library, dict), /* long tp_dictoffset; */
|
||||
NULL, /* initproc tp_init; */
|
||||
NULL, /* allocfunc tp_alloc; */
|
||||
NULL, /* newfunc tp_new; */
|
||||
/* Low-level free-memory routine */
|
||||
NULL, /* freefunc tp_free; */
|
||||
/* For PyObject_IS_GC */
|
||||
NULL, /* inquiry tp_is_gc; */
|
||||
NULL, /* PyObject *tp_bases; */
|
||||
/* method resolution order */
|
||||
NULL, /* PyObject *tp_mro; */
|
||||
NULL, /* PyObject *tp_cache; */
|
||||
NULL, /* PyObject *tp_subclasses; */
|
||||
NULL, /* PyObject *tp_weaklist; */
|
||||
NULL,
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(bpy_lib_load_doc,
|
||||
".. method:: load(filepath, link=False, relative=False)\n"
|
||||
"\n"
|
||||
" Returns a context manager which exposes 2 library objects on entering.\n"
|
||||
" Each object has attributes matching bpy.data which are lists of strings to be linked.\n"
|
||||
"\n"
|
||||
" :arg filepath: The path to a blend file.\n"
|
||||
" :type filepath: string\n"
|
||||
" :arg link: When False reference to the original file is lost.\n"
|
||||
" :type link: bool\n"
|
||||
" :arg relative: When True the path is stored relative to the open blend file.\n"
|
||||
" :type relative: bool\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpy_lib_load_doc,
|
||||
".. method:: load(filepath, link=False, relative=False)\n"
|
||||
"\n"
|
||||
" Returns a context manager which exposes 2 library objects on entering.\n"
|
||||
" Each object has attributes matching bpy.data which are lists of strings to be linked.\n"
|
||||
"\n"
|
||||
" :arg filepath: The path to a blend file.\n"
|
||||
" :type filepath: string\n"
|
||||
" :arg link: When False reference to the original file is lost.\n"
|
||||
" :type link: bool\n"
|
||||
" :arg relative: When True the path is stored relative to the open blend file.\n"
|
||||
" :type relative: bool\n");
|
||||
static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
Main *bmain = CTX_data_main(BPy_GetContext());
|
||||
BPy_Library *ret;
|
||||
const char *filename = NULL;
|
||||
bool is_rel = false, is_link = false;
|
||||
Main *bmain = CTX_data_main(BPy_GetContext());
|
||||
BPy_Library *ret;
|
||||
const char *filename = NULL;
|
||||
bool is_rel = false, is_link = false;
|
||||
|
||||
static const char *_keywords[] = {"filepath", "link", "relative", NULL};
|
||||
static _PyArg_Parser _parser = {"s|O&O&:load", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&filename,
|
||||
PyC_ParseBool, &is_link,
|
||||
PyC_ParseBool, &is_rel))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {"filepath", "link", "relative", NULL};
|
||||
static _PyArg_Parser _parser = {"s|O&O&:load", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser, &filename, PyC_ParseBool, &is_link, PyC_ParseBool, &is_rel)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = PyObject_New(BPy_Library, &bpy_lib_Type);
|
||||
ret = PyObject_New(BPy_Library, &bpy_lib_Type);
|
||||
|
||||
BLI_strncpy(ret->relpath, filename, sizeof(ret->relpath));
|
||||
BLI_strncpy(ret->abspath, filename, sizeof(ret->abspath));
|
||||
BLI_path_abs(ret->abspath, BKE_main_blendfile_path(bmain));
|
||||
BLI_strncpy(ret->relpath, filename, sizeof(ret->relpath));
|
||||
BLI_strncpy(ret->abspath, filename, sizeof(ret->abspath));
|
||||
BLI_path_abs(ret->abspath, BKE_main_blendfile_path(bmain));
|
||||
|
||||
ret->blo_handle = NULL;
|
||||
ret->flag = ((is_link ? FILE_LINK : 0) |
|
||||
(is_rel ? FILE_RELPATH : 0));
|
||||
ret->blo_handle = NULL;
|
||||
ret->flag = ((is_link ? FILE_LINK : 0) | (is_rel ? FILE_RELPATH : 0));
|
||||
|
||||
ret->dict = _PyDict_NewPresized(MAX_LIBARRAY);
|
||||
ret->dict = _PyDict_NewPresized(MAX_LIBARRAY);
|
||||
|
||||
return (PyObject *)ret;
|
||||
return (PyObject *)ret;
|
||||
}
|
||||
|
||||
static PyObject *_bpy_names(BPy_Library *self, int blocktype)
|
||||
{
|
||||
PyObject *list;
|
||||
LinkNode *l, *names;
|
||||
int totnames;
|
||||
PyObject *list;
|
||||
LinkNode *l, *names;
|
||||
int totnames;
|
||||
|
||||
names = BLO_blendhandle_get_datablock_names(self->blo_handle, blocktype, &totnames);
|
||||
list = PyList_New(totnames);
|
||||
names = BLO_blendhandle_get_datablock_names(self->blo_handle, blocktype, &totnames);
|
||||
list = PyList_New(totnames);
|
||||
|
||||
if (names) {
|
||||
int counter = 0;
|
||||
for (l = names; l; l = l->next) {
|
||||
PyList_SET_ITEM(list, counter, PyUnicode_FromString((char *)l->link));
|
||||
counter++;
|
||||
}
|
||||
BLI_linklist_free(names, free); /* free linklist *and* each node's data */
|
||||
}
|
||||
if (names) {
|
||||
int counter = 0;
|
||||
for (l = names; l; l = l->next) {
|
||||
PyList_SET_ITEM(list, counter, PyUnicode_FromString((char *)l->link));
|
||||
counter++;
|
||||
}
|
||||
BLI_linklist_free(names, free); /* free linklist *and* each node's data */
|
||||
}
|
||||
|
||||
return list;
|
||||
return list;
|
||||
}
|
||||
|
||||
static PyObject *bpy_lib_enter(BPy_Library *self)
|
||||
{
|
||||
PyObject *ret;
|
||||
BPy_Library *self_from;
|
||||
PyObject *from_dict = _PyDict_NewPresized(MAX_LIBARRAY);
|
||||
ReportList reports;
|
||||
PyObject *ret;
|
||||
BPy_Library *self_from;
|
||||
PyObject *from_dict = _PyDict_NewPresized(MAX_LIBARRAY);
|
||||
ReportList reports;
|
||||
|
||||
BKE_reports_init(&reports, RPT_STORE);
|
||||
BKE_reports_init(&reports, RPT_STORE);
|
||||
|
||||
self->blo_handle = BLO_blendhandle_from_file(self->abspath, &reports);
|
||||
self->blo_handle = BLO_blendhandle_from_file(self->abspath, &reports);
|
||||
|
||||
if (self->blo_handle == NULL) {
|
||||
if (BPy_reports_to_error(&reports, PyExc_IOError, true) != -1) {
|
||||
PyErr_Format(PyExc_IOError,
|
||||
"load: %s failed to open blend file",
|
||||
self->abspath);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
int i = 0, code;
|
||||
while ((code = BKE_idcode_iter_step(&i))) {
|
||||
if (BKE_idcode_is_linkable(code)) {
|
||||
const char *name_plural = BKE_idcode_to_name_plural(code);
|
||||
PyObject *str = PyUnicode_FromString(name_plural);
|
||||
PyObject *item;
|
||||
if (self->blo_handle == NULL) {
|
||||
if (BPy_reports_to_error(&reports, PyExc_IOError, true) != -1) {
|
||||
PyErr_Format(PyExc_IOError, "load: %s failed to open blend file", self->abspath);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
int i = 0, code;
|
||||
while ((code = BKE_idcode_iter_step(&i))) {
|
||||
if (BKE_idcode_is_linkable(code)) {
|
||||
const char *name_plural = BKE_idcode_to_name_plural(code);
|
||||
PyObject *str = PyUnicode_FromString(name_plural);
|
||||
PyObject *item;
|
||||
|
||||
PyDict_SetItem(self->dict, str, item = PyList_New(0));
|
||||
Py_DECREF(item);
|
||||
PyDict_SetItem(from_dict, str, item = _bpy_names(self, code));
|
||||
Py_DECREF(item);
|
||||
PyDict_SetItem(self->dict, str, item = PyList_New(0));
|
||||
Py_DECREF(item);
|
||||
PyDict_SetItem(from_dict, str, item = _bpy_names(self, code));
|
||||
Py_DECREF(item);
|
||||
|
||||
Py_DECREF(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
Py_DECREF(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* create a dummy */
|
||||
self_from = PyObject_New(BPy_Library, &bpy_lib_Type);
|
||||
BLI_strncpy(self_from->relpath, self->relpath, sizeof(self_from->relpath));
|
||||
BLI_strncpy(self_from->abspath, self->abspath, sizeof(self_from->abspath));
|
||||
/* create a dummy */
|
||||
self_from = PyObject_New(BPy_Library, &bpy_lib_Type);
|
||||
BLI_strncpy(self_from->relpath, self->relpath, sizeof(self_from->relpath));
|
||||
BLI_strncpy(self_from->abspath, self->abspath, sizeof(self_from->abspath));
|
||||
|
||||
self_from->blo_handle = NULL;
|
||||
self_from->flag = 0;
|
||||
self_from->dict = from_dict; /* owns the dict */
|
||||
self_from->blo_handle = NULL;
|
||||
self_from->flag = 0;
|
||||
self_from->dict = from_dict; /* owns the dict */
|
||||
|
||||
/* return pair */
|
||||
ret = PyTuple_New(2);
|
||||
PyTuple_SET_ITEMS(ret,
|
||||
(PyObject *)self_from,
|
||||
(PyObject *)self);
|
||||
Py_INCREF(self);
|
||||
/* return pair */
|
||||
ret = PyTuple_New(2);
|
||||
PyTuple_SET_ITEMS(ret, (PyObject *)self_from, (PyObject *)self);
|
||||
Py_INCREF(self);
|
||||
|
||||
BKE_reports_clear(&reports);
|
||||
BKE_reports_clear(&reports);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void bpy_lib_exit_warn_idname(BPy_Library *self, const char *name_plural, const char *idname)
|
||||
static void bpy_lib_exit_warn_idname(BPy_Library *self,
|
||||
const char *name_plural,
|
||||
const char *idname)
|
||||
{
|
||||
PyObject *exc, *val, *tb;
|
||||
PyErr_Fetch(&exc, &val, &tb);
|
||||
if (PyErr_WarnFormat(PyExc_UserWarning, 1,
|
||||
"load: '%s' does not contain %s[\"%s\"]",
|
||||
self->abspath, name_plural, idname))
|
||||
{
|
||||
/* Spurious errors can appear at shutdown */
|
||||
if (PyErr_ExceptionMatches(PyExc_Warning)) {
|
||||
PyErr_WriteUnraisable((PyObject *)self);
|
||||
}
|
||||
}
|
||||
PyErr_Restore(exc, val, tb);
|
||||
PyObject *exc, *val, *tb;
|
||||
PyErr_Fetch(&exc, &val, &tb);
|
||||
if (PyErr_WarnFormat(PyExc_UserWarning,
|
||||
1,
|
||||
"load: '%s' does not contain %s[\"%s\"]",
|
||||
self->abspath,
|
||||
name_plural,
|
||||
idname)) {
|
||||
/* Spurious errors can appear at shutdown */
|
||||
if (PyErr_ExceptionMatches(PyExc_Warning)) {
|
||||
PyErr_WriteUnraisable((PyObject *)self);
|
||||
}
|
||||
}
|
||||
PyErr_Restore(exc, val, tb);
|
||||
}
|
||||
|
||||
static void bpy_lib_exit_warn_type(BPy_Library *self, PyObject *item)
|
||||
{
|
||||
PyObject *exc, *val, *tb;
|
||||
PyErr_Fetch(&exc, &val, &tb);
|
||||
if (PyErr_WarnFormat(PyExc_UserWarning, 1,
|
||||
"load: '%s' expected a string type, not a %.200s",
|
||||
self->abspath, Py_TYPE(item)->tp_name))
|
||||
{
|
||||
/* Spurious errors can appear at shutdown */
|
||||
if (PyErr_ExceptionMatches(PyExc_Warning)) {
|
||||
PyErr_WriteUnraisable((PyObject *)self);
|
||||
}
|
||||
}
|
||||
PyErr_Restore(exc, val, tb);
|
||||
PyObject *exc, *val, *tb;
|
||||
PyErr_Fetch(&exc, &val, &tb);
|
||||
if (PyErr_WarnFormat(PyExc_UserWarning,
|
||||
1,
|
||||
"load: '%s' expected a string type, not a %.200s",
|
||||
self->abspath,
|
||||
Py_TYPE(item)->tp_name)) {
|
||||
/* Spurious errors can appear at shutdown */
|
||||
if (PyErr_ExceptionMatches(PyExc_Warning)) {
|
||||
PyErr_WriteUnraisable((PyObject *)self);
|
||||
}
|
||||
}
|
||||
PyErr_Restore(exc, val, tb);
|
||||
}
|
||||
|
||||
static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
|
||||
{
|
||||
Main *bmain = CTX_data_main(BPy_GetContext());
|
||||
Main *mainl = NULL;
|
||||
int err = 0;
|
||||
const bool do_append = ((self->flag & FILE_LINK) == 0);
|
||||
Main *bmain = CTX_data_main(BPy_GetContext());
|
||||
Main *mainl = NULL;
|
||||
int err = 0;
|
||||
const bool do_append = ((self->flag & FILE_LINK) == 0);
|
||||
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
|
||||
|
||||
/* here appending/linking starts */
|
||||
mainl = BLO_library_link_begin(bmain, &(self->blo_handle), self->relpath);
|
||||
/* here appending/linking starts */
|
||||
mainl = BLO_library_link_begin(bmain, &(self->blo_handle), self->relpath);
|
||||
|
||||
{
|
||||
int idcode_step = 0, idcode;
|
||||
while ((idcode = BKE_idcode_iter_step(&idcode_step))) {
|
||||
if (BKE_idcode_is_linkable(idcode) && (idcode != ID_WS || do_append)) {
|
||||
const char *name_plural = BKE_idcode_to_name_plural(idcode);
|
||||
PyObject *ls = PyDict_GetItemString(self->dict, name_plural);
|
||||
// printf("lib: %s\n", name_plural);
|
||||
if (ls && PyList_Check(ls)) {
|
||||
/* loop */
|
||||
Py_ssize_t size = PyList_GET_SIZE(ls);
|
||||
Py_ssize_t i;
|
||||
{
|
||||
int idcode_step = 0, idcode;
|
||||
while ((idcode = BKE_idcode_iter_step(&idcode_step))) {
|
||||
if (BKE_idcode_is_linkable(idcode) && (idcode != ID_WS || do_append)) {
|
||||
const char *name_plural = BKE_idcode_to_name_plural(idcode);
|
||||
PyObject *ls = PyDict_GetItemString(self->dict, name_plural);
|
||||
// printf("lib: %s\n", name_plural);
|
||||
if (ls && PyList_Check(ls)) {
|
||||
/* loop */
|
||||
Py_ssize_t size = PyList_GET_SIZE(ls);
|
||||
Py_ssize_t i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
PyObject *item_src = PyList_GET_ITEM(ls, i);
|
||||
PyObject *item_dst; /* must be set below */
|
||||
const char *item_idname = _PyUnicode_AsString(item_src);
|
||||
for (i = 0; i < size; i++) {
|
||||
PyObject *item_src = PyList_GET_ITEM(ls, i);
|
||||
PyObject *item_dst; /* must be set below */
|
||||
const char *item_idname = _PyUnicode_AsString(item_src);
|
||||
|
||||
// printf(" %s\n", item_idname);
|
||||
// printf(" %s\n", item_idname);
|
||||
|
||||
if (item_idname) {
|
||||
ID *id = BLO_library_link_named_part(mainl, &(self->blo_handle), idcode, item_idname);
|
||||
if (id) {
|
||||
if (item_idname) {
|
||||
ID *id = BLO_library_link_named_part(
|
||||
mainl, &(self->blo_handle), idcode, item_idname);
|
||||
if (id) {
|
||||
#ifdef USE_RNA_DATABLOCKS
|
||||
/* swap name for pointer to the id */
|
||||
item_dst = PyCapsule_New((void *)id, NULL, NULL);
|
||||
/* swap name for pointer to the id */
|
||||
item_dst = PyCapsule_New((void *)id, NULL, NULL);
|
||||
#else
|
||||
/* leave as is */
|
||||
continue;
|
||||
/* leave as is */
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
bpy_lib_exit_warn_idname(self, name_plural, item_idname);
|
||||
/* just warn for now */
|
||||
/* err = -1; */
|
||||
item_dst = Py_INCREF_RET(Py_None);
|
||||
}
|
||||
}
|
||||
else {
|
||||
bpy_lib_exit_warn_idname(self, name_plural, item_idname);
|
||||
/* just warn for now */
|
||||
/* err = -1; */
|
||||
item_dst = Py_INCREF_RET(Py_None);
|
||||
}
|
||||
|
||||
/* ID or None */
|
||||
}
|
||||
else {
|
||||
/* XXX, could complain about this */
|
||||
bpy_lib_exit_warn_type(self, item_src);
|
||||
PyErr_Clear();
|
||||
item_dst = Py_INCREF_RET(Py_None);
|
||||
}
|
||||
/* ID or None */
|
||||
}
|
||||
else {
|
||||
/* XXX, could complain about this */
|
||||
bpy_lib_exit_warn_type(self, item_src);
|
||||
PyErr_Clear();
|
||||
item_dst = Py_INCREF_RET(Py_None);
|
||||
}
|
||||
|
||||
/* item_dst must be new or already incref'd */
|
||||
Py_DECREF(item_src);
|
||||
PyList_SET_ITEM(ls, i, item_dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* item_dst must be new or already incref'd */
|
||||
Py_DECREF(item_src);
|
||||
PyList_SET_ITEM(ls, i, item_dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (err == -1) {
|
||||
/* exception raised above, XXX, this leaks some memory */
|
||||
BLO_blendhandle_close(self->blo_handle);
|
||||
self->blo_handle = NULL;
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
Library *lib = mainl->curlib; /* newly added lib, assign before append end */
|
||||
BLO_library_link_end(mainl, &(self->blo_handle), self->flag, NULL, NULL, NULL, NULL);
|
||||
BLO_blendhandle_close(self->blo_handle);
|
||||
self->blo_handle = NULL;
|
||||
if (err == -1) {
|
||||
/* exception raised above, XXX, this leaks some memory */
|
||||
BLO_blendhandle_close(self->blo_handle);
|
||||
self->blo_handle = NULL;
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
Library *lib = mainl->curlib; /* newly added lib, assign before append end */
|
||||
BLO_library_link_end(mainl, &(self->blo_handle), self->flag, NULL, NULL, NULL, NULL);
|
||||
BLO_blendhandle_close(self->blo_handle);
|
||||
self->blo_handle = NULL;
|
||||
|
||||
GHash *old_to_new_ids = BLI_ghash_ptr_new(__func__);
|
||||
GHash *old_to_new_ids = BLI_ghash_ptr_new(__func__);
|
||||
|
||||
/* copied from wm_operator.c */
|
||||
{
|
||||
/* mark all library linked objects to be updated */
|
||||
BKE_main_lib_objects_recalc_all(bmain);
|
||||
/* copied from wm_operator.c */
|
||||
{
|
||||
/* mark all library linked objects to be updated */
|
||||
BKE_main_lib_objects_recalc_all(bmain);
|
||||
|
||||
/* append, rather than linking */
|
||||
if (do_append) {
|
||||
BKE_library_make_local(bmain, lib, old_to_new_ids, true, false);
|
||||
}
|
||||
}
|
||||
/* append, rather than linking */
|
||||
if (do_append) {
|
||||
BKE_library_make_local(bmain, lib, old_to_new_ids, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
|
||||
|
||||
/* finally swap the capsules for real bpy objects
|
||||
* important since BLO_library_append_end initializes NodeTree types used by srna->refine */
|
||||
/* finally swap the capsules for real bpy objects
|
||||
* important since BLO_library_append_end initializes NodeTree types used by srna->refine */
|
||||
#ifdef USE_RNA_DATABLOCKS
|
||||
{
|
||||
int idcode_step = 0, idcode;
|
||||
while ((idcode = BKE_idcode_iter_step(&idcode_step))) {
|
||||
if (BKE_idcode_is_linkable(idcode) && (idcode != ID_WS || do_append)) {
|
||||
const char *name_plural = BKE_idcode_to_name_plural(idcode);
|
||||
PyObject *ls = PyDict_GetItemString(self->dict, name_plural);
|
||||
if (ls && PyList_Check(ls)) {
|
||||
Py_ssize_t size = PyList_GET_SIZE(ls);
|
||||
Py_ssize_t i;
|
||||
PyObject *item;
|
||||
{
|
||||
int idcode_step = 0, idcode;
|
||||
while ((idcode = BKE_idcode_iter_step(&idcode_step))) {
|
||||
if (BKE_idcode_is_linkable(idcode) && (idcode != ID_WS || do_append)) {
|
||||
const char *name_plural = BKE_idcode_to_name_plural(idcode);
|
||||
PyObject *ls = PyDict_GetItemString(self->dict, name_plural);
|
||||
if (ls && PyList_Check(ls)) {
|
||||
Py_ssize_t size = PyList_GET_SIZE(ls);
|
||||
Py_ssize_t i;
|
||||
PyObject *item;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
item = PyList_GET_ITEM(ls, i);
|
||||
if (PyCapsule_CheckExact(item)) {
|
||||
PointerRNA id_ptr;
|
||||
ID *id;
|
||||
for (i = 0; i < size; i++) {
|
||||
item = PyList_GET_ITEM(ls, i);
|
||||
if (PyCapsule_CheckExact(item)) {
|
||||
PointerRNA id_ptr;
|
||||
ID *id;
|
||||
|
||||
id = PyCapsule_GetPointer(item, NULL);
|
||||
id = BLI_ghash_lookup_default(old_to_new_ids, id, id);
|
||||
Py_DECREF(item);
|
||||
id = PyCapsule_GetPointer(item, NULL);
|
||||
id = BLI_ghash_lookup_default(old_to_new_ids, id, id);
|
||||
Py_DECREF(item);
|
||||
|
||||
RNA_id_pointer_create(id, &id_ptr);
|
||||
item = pyrna_struct_CreatePyObject(&id_ptr);
|
||||
PyList_SET_ITEM(ls, i, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* USE_RNA_DATABLOCKS */
|
||||
RNA_id_pointer_create(id, &id_ptr);
|
||||
item = pyrna_struct_CreatePyObject(&id_ptr);
|
||||
PyList_SET_ITEM(ls, i, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* USE_RNA_DATABLOCKS */
|
||||
|
||||
BLI_ghash_free(old_to_new_ids, NULL, NULL);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
BLI_ghash_free(old_to_new_ids, NULL, NULL);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *bpy_lib_dir(BPy_Library *self)
|
||||
{
|
||||
return PyDict_Keys(self->dict);
|
||||
return PyDict_Keys(self->dict);
|
||||
}
|
||||
|
||||
|
||||
int BPY_library_load_module(PyObject *mod_par)
|
||||
{
|
||||
static PyMethodDef load_meth = {
|
||||
"load", (PyCFunction)bpy_lib_load,
|
||||
METH_STATIC | METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_lib_load_doc,
|
||||
};
|
||||
PyModule_AddObject(mod_par, "_library_load", PyCFunction_New(&load_meth, NULL));
|
||||
static PyMethodDef load_meth = {
|
||||
"load",
|
||||
(PyCFunction)bpy_lib_load,
|
||||
METH_STATIC | METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_lib_load_doc,
|
||||
};
|
||||
PyModule_AddObject(mod_par, "_library_load", PyCFunction_New(&load_meth, NULL));
|
||||
|
||||
/* some compilers don't like accessing this directly, delay assignment */
|
||||
bpy_lib_Type.tp_getattro = PyObject_GenericGetAttr;
|
||||
/* some compilers don't like accessing this directly, delay assignment */
|
||||
bpy_lib_Type.tp_getattro = PyObject_GenericGetAttr;
|
||||
|
||||
if (PyType_Ready(&bpy_lib_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (PyType_Ready(&bpy_lib_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -43,174 +43,177 @@
|
||||
|
||||
#include "../generic/py_capi_utils.h"
|
||||
|
||||
|
||||
PyDoc_STRVAR(bpy_lib_write_doc,
|
||||
".. method:: write(filepath, datablocks, relative_remap=False, fake_user=False, compress=False)\n"
|
||||
"\n"
|
||||
" Write data-blocks into a blend file.\n"
|
||||
"\n"
|
||||
" .. note::\n"
|
||||
"\n"
|
||||
" Indirectly referenced data-blocks will be expanded and written too.\n"
|
||||
"\n"
|
||||
" :arg filepath: The path to write the blend-file.\n"
|
||||
" :type filepath: string\n"
|
||||
" :arg datablocks: set of data-blocks (:class:`bpy.types.ID` instances).\n"
|
||||
" :type datablocks: set\n"
|
||||
" :arg relative_remap: When True, make paths relative to the current blend-file.\n"
|
||||
" :type relative_remap: bool\n"
|
||||
" :arg fake_user: When True, data-blocks will be written with fake-user flag enabled.\n"
|
||||
" :type fake_user: bool\n"
|
||||
" :arg compress: When True, write a compressed blend file.\n"
|
||||
" :type compress: bool\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpy_lib_write_doc,
|
||||
".. method:: write(filepath, datablocks, relative_remap=False, fake_user=False, "
|
||||
"compress=False)\n"
|
||||
"\n"
|
||||
" Write data-blocks into a blend file.\n"
|
||||
"\n"
|
||||
" .. note::\n"
|
||||
"\n"
|
||||
" Indirectly referenced data-blocks will be expanded and written too.\n"
|
||||
"\n"
|
||||
" :arg filepath: The path to write the blend-file.\n"
|
||||
" :type filepath: string\n"
|
||||
" :arg datablocks: set of data-blocks (:class:`bpy.types.ID` instances).\n"
|
||||
" :type datablocks: set\n"
|
||||
" :arg relative_remap: When True, make paths relative to the current blend-file.\n"
|
||||
" :type relative_remap: bool\n"
|
||||
" :arg fake_user: When True, data-blocks will be written with fake-user flag enabled.\n"
|
||||
" :type fake_user: bool\n"
|
||||
" :arg compress: When True, write a compressed blend file.\n"
|
||||
" :type compress: bool\n");
|
||||
static PyObject *bpy_lib_write(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
/* args */
|
||||
const char *filepath;
|
||||
char filepath_abs[FILE_MAX];
|
||||
PyObject *datablocks = NULL;
|
||||
bool use_relative_remap = false, use_fake_user = false, use_compress = false;
|
||||
/* args */
|
||||
const char *filepath;
|
||||
char filepath_abs[FILE_MAX];
|
||||
PyObject *datablocks = NULL;
|
||||
bool use_relative_remap = false, use_fake_user = false, use_compress = false;
|
||||
|
||||
static const char *_keywords[] = {
|
||||
"filepath", "datablocks",
|
||||
/* optional */
|
||||
"relative_remap", "fake_user", "compress",
|
||||
NULL,
|
||||
};
|
||||
static _PyArg_Parser _parser = {"sO!|$O&O&O&:write", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&filepath,
|
||||
&PySet_Type, &datablocks,
|
||||
PyC_ParseBool, &use_relative_remap,
|
||||
PyC_ParseBool, &use_fake_user,
|
||||
PyC_ParseBool, &use_compress))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {
|
||||
"filepath",
|
||||
"datablocks",
|
||||
/* optional */
|
||||
"relative_remap",
|
||||
"fake_user",
|
||||
"compress",
|
||||
NULL,
|
||||
};
|
||||
static _PyArg_Parser _parser = {"sO!|$O&O&O&:write", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args,
|
||||
kw,
|
||||
&_parser,
|
||||
&filepath,
|
||||
&PySet_Type,
|
||||
&datablocks,
|
||||
PyC_ParseBool,
|
||||
&use_relative_remap,
|
||||
PyC_ParseBool,
|
||||
&use_fake_user,
|
||||
PyC_ParseBool,
|
||||
&use_compress)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Main *bmain_src = G_MAIN;
|
||||
int write_flags = 0;
|
||||
Main *bmain_src = G_MAIN;
|
||||
int write_flags = 0;
|
||||
|
||||
if (use_relative_remap) {
|
||||
write_flags |= G_FILE_RELATIVE_REMAP;
|
||||
}
|
||||
if (use_relative_remap) {
|
||||
write_flags |= G_FILE_RELATIVE_REMAP;
|
||||
}
|
||||
|
||||
if (use_compress) {
|
||||
write_flags |= G_FILE_COMPRESS;
|
||||
}
|
||||
if (use_compress) {
|
||||
write_flags |= G_FILE_COMPRESS;
|
||||
}
|
||||
|
||||
BLI_strncpy(filepath_abs, filepath, FILE_MAX);
|
||||
BLI_path_abs(filepath_abs, BKE_main_blendfile_path_from_global());
|
||||
BLI_strncpy(filepath_abs, filepath, FILE_MAX);
|
||||
BLI_path_abs(filepath_abs, BKE_main_blendfile_path_from_global());
|
||||
|
||||
BKE_blendfile_write_partial_begin(bmain_src);
|
||||
BKE_blendfile_write_partial_begin(bmain_src);
|
||||
|
||||
/* array of ID's and backup any data we modify */
|
||||
struct {
|
||||
ID *id;
|
||||
/* original values */
|
||||
short id_flag;
|
||||
short id_us;
|
||||
} *id_store_array, *id_store;
|
||||
int id_store_len = 0;
|
||||
/* array of ID's and backup any data we modify */
|
||||
struct {
|
||||
ID *id;
|
||||
/* original values */
|
||||
short id_flag;
|
||||
short id_us;
|
||||
} * id_store_array, *id_store;
|
||||
int id_store_len = 0;
|
||||
|
||||
PyObject *ret;
|
||||
PyObject *ret;
|
||||
|
||||
/* collect all id data from the set and store in 'id_store_array' */
|
||||
{
|
||||
Py_ssize_t pos, hash;
|
||||
PyObject *key;
|
||||
/* collect all id data from the set and store in 'id_store_array' */
|
||||
{
|
||||
Py_ssize_t pos, hash;
|
||||
PyObject *key;
|
||||
|
||||
id_store_array = MEM_mallocN(sizeof(*id_store_array) * PySet_Size(datablocks), __func__);
|
||||
id_store = id_store_array;
|
||||
id_store_array = MEM_mallocN(sizeof(*id_store_array) * PySet_Size(datablocks), __func__);
|
||||
id_store = id_store_array;
|
||||
|
||||
pos = hash = 0;
|
||||
while (_PySet_NextEntry(datablocks, &pos, &key, &hash)) {
|
||||
pos = hash = 0;
|
||||
while (_PySet_NextEntry(datablocks, &pos, &key, &hash)) {
|
||||
|
||||
if (!pyrna_id_FromPyObject(key, &id_store->id)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Expected an ID type, not %.200s",
|
||||
Py_TYPE(key)->tp_name);
|
||||
ret = NULL;
|
||||
goto finally;
|
||||
}
|
||||
else {
|
||||
id_store->id_flag = id_store->id->flag;
|
||||
id_store->id_us = id_store->id->us;
|
||||
if (!pyrna_id_FromPyObject(key, &id_store->id)) {
|
||||
PyErr_Format(PyExc_TypeError, "Expected an ID type, not %.200s", Py_TYPE(key)->tp_name);
|
||||
ret = NULL;
|
||||
goto finally;
|
||||
}
|
||||
else {
|
||||
id_store->id_flag = id_store->id->flag;
|
||||
id_store->id_us = id_store->id->us;
|
||||
|
||||
if (use_fake_user) {
|
||||
id_store->id->flag |= LIB_FAKEUSER;
|
||||
}
|
||||
id_store->id->us = 1;
|
||||
if (use_fake_user) {
|
||||
id_store->id->flag |= LIB_FAKEUSER;
|
||||
}
|
||||
id_store->id->us = 1;
|
||||
|
||||
BKE_blendfile_write_partial_tag_ID(id_store->id, true);
|
||||
BKE_blendfile_write_partial_tag_ID(id_store->id, true);
|
||||
|
||||
id_store_len += 1;
|
||||
id_store++;
|
||||
}
|
||||
}
|
||||
}
|
||||
id_store_len += 1;
|
||||
id_store++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* write blend */
|
||||
int retval = 0;
|
||||
ReportList reports;
|
||||
/* write blend */
|
||||
int retval = 0;
|
||||
ReportList reports;
|
||||
|
||||
BKE_reports_init(&reports, RPT_STORE);
|
||||
BKE_reports_init(&reports, RPT_STORE);
|
||||
|
||||
retval = BKE_blendfile_write_partial(bmain_src, filepath_abs, write_flags, &reports);
|
||||
retval = BKE_blendfile_write_partial(bmain_src, filepath_abs, write_flags, &reports);
|
||||
|
||||
/* cleanup state */
|
||||
BKE_blendfile_write_partial_end(bmain_src);
|
||||
|
||||
if (retval) {
|
||||
BKE_reports_print(&reports, RPT_ERROR_ALL);
|
||||
BKE_reports_clear(&reports);
|
||||
ret = Py_None;
|
||||
Py_INCREF(ret);
|
||||
}
|
||||
else {
|
||||
if (BPy_reports_to_error(&reports, PyExc_IOError, true) == 0) {
|
||||
PyErr_SetString(PyExc_IOError, "Unknown error writing library data");
|
||||
}
|
||||
ret = NULL;
|
||||
}
|
||||
/* cleanup state */
|
||||
BKE_blendfile_write_partial_end(bmain_src);
|
||||
|
||||
if (retval) {
|
||||
BKE_reports_print(&reports, RPT_ERROR_ALL);
|
||||
BKE_reports_clear(&reports);
|
||||
ret = Py_None;
|
||||
Py_INCREF(ret);
|
||||
}
|
||||
else {
|
||||
if (BPy_reports_to_error(&reports, PyExc_IOError, true) == 0) {
|
||||
PyErr_SetString(PyExc_IOError, "Unknown error writing library data");
|
||||
}
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
finally:
|
||||
|
||||
/* clear all flags for ID's added to the store (may run on error too) */
|
||||
id_store = id_store_array;
|
||||
/* clear all flags for ID's added to the store (may run on error too) */
|
||||
id_store = id_store_array;
|
||||
|
||||
for (int i = 0; i < id_store_len; id_store++, i++) {
|
||||
for (int i = 0; i < id_store_len; id_store++, i++) {
|
||||
|
||||
if (use_fake_user) {
|
||||
if ((id_store->id_flag & LIB_FAKEUSER) == 0) {
|
||||
id_store->id->flag &= ~LIB_FAKEUSER;
|
||||
}
|
||||
}
|
||||
|
||||
if (use_fake_user) {
|
||||
if ((id_store->id_flag & LIB_FAKEUSER) == 0) {
|
||||
id_store->id->flag &= ~LIB_FAKEUSER;
|
||||
}
|
||||
}
|
||||
id_store->id->us = id_store->id_us;
|
||||
|
||||
id_store->id->us = id_store->id_us;
|
||||
BKE_blendfile_write_partial_tag_ID(id_store->id, false);
|
||||
}
|
||||
|
||||
BKE_blendfile_write_partial_tag_ID(id_store->id, false);
|
||||
}
|
||||
MEM_freeN(id_store_array);
|
||||
|
||||
MEM_freeN(id_store_array);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int BPY_library_write_module(PyObject *mod_par)
|
||||
{
|
||||
static PyMethodDef write_meth = {
|
||||
"write", (PyCFunction)bpy_lib_write,
|
||||
METH_STATIC | METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_lib_write_doc,
|
||||
};
|
||||
static PyMethodDef write_meth = {
|
||||
"write",
|
||||
(PyCFunction)bpy_lib_write,
|
||||
METH_STATIC | METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_lib_write_doc,
|
||||
};
|
||||
|
||||
PyModule_AddObject(mod_par, "_library_write", PyCFunction_New(&write_meth, NULL));
|
||||
PyModule_AddObject(mod_par, "_library_write", PyCFunction_New(&write_meth, NULL));
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -40,24 +40,22 @@
|
||||
#include "bpy_capi_utils.h"
|
||||
#include "bpy_rna.h"
|
||||
#include "bpy_intern_string.h"
|
||||
#include "bpy_gizmo_wrap.h" /* own include */
|
||||
|
||||
|
||||
#include "bpy_msgbus.h" /* own include */
|
||||
#include "bpy_gizmo_wrap.h" /* own include */
|
||||
|
||||
#include "bpy_msgbus.h" /* own include */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Internal Utils
|
||||
* \{ */
|
||||
|
||||
#define BPY_MSGBUS_RNA_MSGKEY_DOC \
|
||||
" :arg key: Represents the type of data being subscribed to\n" \
|
||||
"\n" \
|
||||
" Arguments include\n" \
|
||||
" - :class:`bpy.types.Property` instance.\n" \
|
||||
" - :class:`bpy.types.Struct` type.\n" \
|
||||
" - (:class:`bpy.types.Struct`, str) type and property name.\n" \
|
||||
" :type key: Muliple\n"
|
||||
" :arg key: Represents the type of data being subscribed to\n" \
|
||||
"\n" \
|
||||
" Arguments include\n" \
|
||||
" - :class:`bpy.types.Property` instance.\n" \
|
||||
" - :class:`bpy.types.Struct` type.\n" \
|
||||
" - (:class:`bpy.types.Struct`, str) type and property name.\n" \
|
||||
" :type key: Muliple\n"
|
||||
|
||||
/**
|
||||
* There are multiple ways we can get RNA from Python,
|
||||
@@ -69,87 +67,78 @@
|
||||
* \param msg_key_params: Message key with all members zeroed out.
|
||||
* \return -1 on failure, 0 on success.
|
||||
*/
|
||||
static int py_msgbus_rna_key_from_py(
|
||||
PyObject *py_sub,
|
||||
wmMsgParams_RNA *msg_key_params,
|
||||
const char *error_prefix)
|
||||
static int py_msgbus_rna_key_from_py(PyObject *py_sub,
|
||||
wmMsgParams_RNA *msg_key_params,
|
||||
const char *error_prefix)
|
||||
{
|
||||
|
||||
/* Allow common case, object rotation, location - etc. */
|
||||
if (BaseMathObject_CheckExact(py_sub)) {
|
||||
BaseMathObject *py_sub_math = (BaseMathObject *)py_sub;
|
||||
if (py_sub_math->cb_user == NULL) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError,
|
||||
"%s: math argument has no owner",
|
||||
error_prefix);
|
||||
return -1;
|
||||
}
|
||||
py_sub = py_sub_math->cb_user;
|
||||
/* Common case will use BPy_PropertyRNA_Check below. */
|
||||
}
|
||||
/* Allow common case, object rotation, location - etc. */
|
||||
if (BaseMathObject_CheckExact(py_sub)) {
|
||||
BaseMathObject *py_sub_math = (BaseMathObject *)py_sub;
|
||||
if (py_sub_math->cb_user == NULL) {
|
||||
PyErr_Format(PyExc_TypeError, "%s: math argument has no owner", error_prefix);
|
||||
return -1;
|
||||
}
|
||||
py_sub = py_sub_math->cb_user;
|
||||
/* Common case will use BPy_PropertyRNA_Check below. */
|
||||
}
|
||||
|
||||
if (BPy_PropertyRNA_Check(py_sub)) {
|
||||
BPy_PropertyRNA *data_prop = (BPy_PropertyRNA *)py_sub;
|
||||
PYRNA_PROP_CHECK_INT(data_prop);
|
||||
msg_key_params->ptr = data_prop->ptr;
|
||||
msg_key_params->prop = data_prop->prop;
|
||||
}
|
||||
else if (BPy_StructRNA_Check(py_sub)) {
|
||||
/* note, this isn't typically used since we don't edit structs directly. */
|
||||
BPy_StructRNA *data_srna = (BPy_StructRNA *)py_sub;
|
||||
PYRNA_STRUCT_CHECK_INT(data_srna);
|
||||
msg_key_params->ptr = data_srna->ptr;
|
||||
}
|
||||
/* TODO - property / type, not instance. */
|
||||
else if (PyType_Check(py_sub)) {
|
||||
StructRNA *data_type = pyrna_struct_as_srna(py_sub, false, error_prefix);
|
||||
if (data_type == NULL) {
|
||||
return -1;
|
||||
}
|
||||
msg_key_params->ptr.type = data_type;
|
||||
}
|
||||
else if (PyTuple_CheckExact(py_sub)) {
|
||||
if (PyTuple_GET_SIZE(py_sub) == 2) {
|
||||
PyObject *data_type_py = PyTuple_GET_ITEM(py_sub, 0);
|
||||
PyObject *data_prop_py = PyTuple_GET_ITEM(py_sub, 1);
|
||||
StructRNA *data_type = pyrna_struct_as_srna(data_type_py, false, error_prefix);
|
||||
if (data_type == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (!PyUnicode_CheckExact(data_prop_py)) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError,
|
||||
"%s: expected property to be a string",
|
||||
error_prefix);
|
||||
return -1;
|
||||
}
|
||||
PointerRNA data_type_ptr = { .type = data_type, };
|
||||
const char *data_prop_str = _PyUnicode_AsString(data_prop_py);
|
||||
PropertyRNA *data_prop = RNA_struct_find_property(&data_type_ptr, data_prop_str);
|
||||
if (BPy_PropertyRNA_Check(py_sub)) {
|
||||
BPy_PropertyRNA *data_prop = (BPy_PropertyRNA *)py_sub;
|
||||
PYRNA_PROP_CHECK_INT(data_prop);
|
||||
msg_key_params->ptr = data_prop->ptr;
|
||||
msg_key_params->prop = data_prop->prop;
|
||||
}
|
||||
else if (BPy_StructRNA_Check(py_sub)) {
|
||||
/* note, this isn't typically used since we don't edit structs directly. */
|
||||
BPy_StructRNA *data_srna = (BPy_StructRNA *)py_sub;
|
||||
PYRNA_STRUCT_CHECK_INT(data_srna);
|
||||
msg_key_params->ptr = data_srna->ptr;
|
||||
}
|
||||
/* TODO - property / type, not instance. */
|
||||
else if (PyType_Check(py_sub)) {
|
||||
StructRNA *data_type = pyrna_struct_as_srna(py_sub, false, error_prefix);
|
||||
if (data_type == NULL) {
|
||||
return -1;
|
||||
}
|
||||
msg_key_params->ptr.type = data_type;
|
||||
}
|
||||
else if (PyTuple_CheckExact(py_sub)) {
|
||||
if (PyTuple_GET_SIZE(py_sub) == 2) {
|
||||
PyObject *data_type_py = PyTuple_GET_ITEM(py_sub, 0);
|
||||
PyObject *data_prop_py = PyTuple_GET_ITEM(py_sub, 1);
|
||||
StructRNA *data_type = pyrna_struct_as_srna(data_type_py, false, error_prefix);
|
||||
if (data_type == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (!PyUnicode_CheckExact(data_prop_py)) {
|
||||
PyErr_Format(PyExc_TypeError, "%s: expected property to be a string", error_prefix);
|
||||
return -1;
|
||||
}
|
||||
PointerRNA data_type_ptr = {
|
||||
.type = data_type,
|
||||
};
|
||||
const char *data_prop_str = _PyUnicode_AsString(data_prop_py);
|
||||
PropertyRNA *data_prop = RNA_struct_find_property(&data_type_ptr, data_prop_str);
|
||||
|
||||
if (data_prop == NULL) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError,
|
||||
"%s: struct %.200s does not contain property %.200s",
|
||||
error_prefix,
|
||||
RNA_struct_identifier(data_type),
|
||||
data_prop_str);
|
||||
return -1;
|
||||
}
|
||||
if (data_prop == NULL) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%s: struct %.200s does not contain property %.200s",
|
||||
error_prefix,
|
||||
RNA_struct_identifier(data_type),
|
||||
data_prop_str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg_key_params->ptr.type = data_type;
|
||||
msg_key_params->prop = data_prop;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(
|
||||
PyExc_ValueError,
|
||||
"%s: Expected a pair (type, property_id)",
|
||||
error_prefix);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
msg_key_params->ptr.type = data_type;
|
||||
msg_key_params->prop = data_prop;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_ValueError, "%s: Expected a pair (type, property_id)", error_prefix);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -161,51 +150,52 @@ static int py_msgbus_rna_key_from_py(
|
||||
#define BPY_MSGBUS_USER_DATA_LEN 2
|
||||
|
||||
/* Follow wmMsgNotifyFn spec */
|
||||
static void bpy_msgbus_notify(
|
||||
bContext *C, wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val)
|
||||
static void bpy_msgbus_notify(bContext *C,
|
||||
wmMsgSubscribeKey *UNUSED(msg_key),
|
||||
wmMsgSubscribeValue *msg_val)
|
||||
{
|
||||
PyGILState_STATE gilstate;
|
||||
bpy_context_set(C, &gilstate);
|
||||
PyGILState_STATE gilstate;
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
PyObject *user_data = msg_val->user_data;
|
||||
BLI_assert(PyTuple_GET_SIZE(user_data) == BPY_MSGBUS_USER_DATA_LEN);
|
||||
PyObject *user_data = msg_val->user_data;
|
||||
BLI_assert(PyTuple_GET_SIZE(user_data) == BPY_MSGBUS_USER_DATA_LEN);
|
||||
|
||||
PyObject *callback_args = PyTuple_GET_ITEM(user_data, 0);
|
||||
PyObject *callback_notify = PyTuple_GET_ITEM(user_data, 1);
|
||||
PyObject *callback_args = PyTuple_GET_ITEM(user_data, 0);
|
||||
PyObject *callback_notify = PyTuple_GET_ITEM(user_data, 1);
|
||||
|
||||
const bool is_write_ok = pyrna_write_check();
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(true);
|
||||
}
|
||||
const bool is_write_ok = pyrna_write_check();
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(true);
|
||||
}
|
||||
|
||||
PyObject *ret = PyObject_CallObject(callback_notify, callback_args);
|
||||
PyObject *ret = PyObject_CallObject(callback_notify, callback_args);
|
||||
|
||||
if (ret == NULL) {
|
||||
PyC_Err_PrintWithFunc(callback_notify);
|
||||
}
|
||||
else {
|
||||
if (ret != Py_None) {
|
||||
PyErr_SetString(PyExc_ValueError, "the return value must be None");
|
||||
PyC_Err_PrintWithFunc(callback_notify);
|
||||
}
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
if (ret == NULL) {
|
||||
PyC_Err_PrintWithFunc(callback_notify);
|
||||
}
|
||||
else {
|
||||
if (ret != Py_None) {
|
||||
PyErr_SetString(PyExc_ValueError, "the return value must be None");
|
||||
PyC_Err_PrintWithFunc(callback_notify);
|
||||
}
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(false);
|
||||
}
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Follow wmMsgSubscribeValueFreeDataFn spec */
|
||||
static void bpy_msgbus_subscribe_value_free_data(
|
||||
struct wmMsgSubscribeKey *UNUSED(msg_key), struct wmMsgSubscribeValue *msg_val)
|
||||
static void bpy_msgbus_subscribe_value_free_data(struct wmMsgSubscribeKey *UNUSED(msg_key),
|
||||
struct wmMsgSubscribeValue *msg_val)
|
||||
{
|
||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||
Py_DECREF(msg_val->owner);
|
||||
Py_DECREF(msg_val->user_data);
|
||||
PyGILState_Release(gilstate);
|
||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||
Py_DECREF(msg_val->owner);
|
||||
Py_DECREF(msg_val->user_data);
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -214,201 +204,196 @@ static void bpy_msgbus_subscribe_value_free_data(
|
||||
/** \name Public Message Bus API
|
||||
* \{ */
|
||||
|
||||
PyDoc_STRVAR(bpy_msgbus_subscribe_rna_doc,
|
||||
".. function:: subscribe_rna(data, owner, args, notify, options=set())\n"
|
||||
"\n"
|
||||
BPY_MSGBUS_RNA_MSGKEY_DOC
|
||||
" :arg owner: Handle for this subscription (compared by identity).\n"
|
||||
" :type owner: Any type.\n"
|
||||
" :arg options: Change the behavior of the subscriber.\n"
|
||||
"\n"
|
||||
" - ``PERSISTENT`` when set, the subscriber will be kept when remapping ID data.\n"
|
||||
"\n"
|
||||
" :type options: set of str.\n"
|
||||
"\n"
|
||||
" Returns a new vector int property definition.\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpy_msgbus_subscribe_rna_doc,
|
||||
".. function:: subscribe_rna(data, owner, args, notify, options=set())\n"
|
||||
"\n" BPY_MSGBUS_RNA_MSGKEY_DOC
|
||||
" :arg owner: Handle for this subscription (compared by identity).\n"
|
||||
" :type owner: Any type.\n"
|
||||
" :arg options: Change the behavior of the subscriber.\n"
|
||||
"\n"
|
||||
" - ``PERSISTENT`` when set, the subscriber will be kept when remapping ID data.\n"
|
||||
"\n"
|
||||
" :type options: set of str.\n"
|
||||
"\n"
|
||||
" Returns a new vector int property definition.\n");
|
||||
static PyObject *bpy_msgbus_subscribe_rna(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
const char *error_prefix = "subscribe_rna";
|
||||
PyObject *py_sub = NULL;
|
||||
PyObject *py_owner = NULL;
|
||||
PyObject *callback_args = NULL;
|
||||
PyObject *callback_notify = NULL;
|
||||
const char *error_prefix = "subscribe_rna";
|
||||
PyObject *py_sub = NULL;
|
||||
PyObject *py_owner = NULL;
|
||||
PyObject *callback_args = NULL;
|
||||
PyObject *callback_notify = NULL;
|
||||
|
||||
enum {
|
||||
IS_PERSISTENT = (1 << 0),
|
||||
};
|
||||
PyObject *py_options = NULL;
|
||||
EnumPropertyItem py_options_enum[] = {
|
||||
{IS_PERSISTENT, "PERSISTENT", 0, ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
int options = 0;
|
||||
enum {
|
||||
IS_PERSISTENT = (1 << 0),
|
||||
};
|
||||
PyObject *py_options = NULL;
|
||||
EnumPropertyItem py_options_enum[] = {
|
||||
{IS_PERSISTENT, "PERSISTENT", 0, ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
int options = 0;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) != 0) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError,
|
||||
"%s: only keyword arguments are supported",
|
||||
error_prefix);
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {
|
||||
"key",
|
||||
"owner",
|
||||
"args",
|
||||
"notify",
|
||||
"options",
|
||||
NULL,
|
||||
};
|
||||
static _PyArg_Parser _parser = {"OOO!O|O!:subscribe_rna", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&py_sub, &py_owner,
|
||||
&PyTuple_Type, &callback_args,
|
||||
&callback_notify,
|
||||
&PySet_Type, &py_options))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (PyTuple_GET_SIZE(args) != 0) {
|
||||
PyErr_Format(PyExc_TypeError, "%s: only keyword arguments are supported", error_prefix);
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {
|
||||
"key",
|
||||
"owner",
|
||||
"args",
|
||||
"notify",
|
||||
"options",
|
||||
NULL,
|
||||
};
|
||||
static _PyArg_Parser _parser = {"OOO!O|O!:subscribe_rna", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args,
|
||||
kw,
|
||||
&_parser,
|
||||
&py_sub,
|
||||
&py_owner,
|
||||
&PyTuple_Type,
|
||||
&callback_args,
|
||||
&callback_notify,
|
||||
&PySet_Type,
|
||||
&py_options)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (py_options &&
|
||||
(pyrna_set_to_enum_bitfield(py_options_enum, py_options, &options, error_prefix)) == -1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (py_options &&
|
||||
(pyrna_set_to_enum_bitfield(py_options_enum, py_options, &options, error_prefix)) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Note: we may want to have a way to pass this in. */
|
||||
bContext *C = (bContext *)BPy_GetContext();
|
||||
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
|
||||
wmMsgParams_RNA msg_key_params = {{{0}}};
|
||||
/* Note: we may want to have a way to pass this in. */
|
||||
bContext *C = (bContext *)BPy_GetContext();
|
||||
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
|
||||
wmMsgParams_RNA msg_key_params = {{{0}}};
|
||||
|
||||
wmMsgSubscribeValue msg_val_params = {0};
|
||||
wmMsgSubscribeValue msg_val_params = {0};
|
||||
|
||||
if (py_msgbus_rna_key_from_py(py_sub, &msg_key_params, error_prefix) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (py_msgbus_rna_key_from_py(py_sub, &msg_key_params, error_prefix) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyFunction_Check(callback_notify)) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError,
|
||||
"notify expects a function, found %.200s",
|
||||
Py_TYPE(callback_notify)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
if (!PyFunction_Check(callback_notify)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"notify expects a function, found %.200s",
|
||||
Py_TYPE(callback_notify)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (options != 0) {
|
||||
if (options & IS_PERSISTENT) {
|
||||
msg_val_params.is_persistent = true;
|
||||
}
|
||||
}
|
||||
if (options != 0) {
|
||||
if (options & IS_PERSISTENT) {
|
||||
msg_val_params.is_persistent = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* owner can be anything. */
|
||||
{
|
||||
msg_val_params.owner = py_owner;
|
||||
Py_INCREF(py_owner);
|
||||
}
|
||||
/* owner can be anything. */
|
||||
{
|
||||
msg_val_params.owner = py_owner;
|
||||
Py_INCREF(py_owner);
|
||||
}
|
||||
|
||||
{
|
||||
PyObject *user_data = PyTuple_New(2);
|
||||
PyTuple_SET_ITEMS(
|
||||
user_data,
|
||||
Py_INCREF_RET(callback_args),
|
||||
Py_INCREF_RET(callback_notify));
|
||||
msg_val_params.user_data = user_data;
|
||||
}
|
||||
{
|
||||
PyObject *user_data = PyTuple_New(2);
|
||||
PyTuple_SET_ITEMS(user_data, Py_INCREF_RET(callback_args), Py_INCREF_RET(callback_notify));
|
||||
msg_val_params.user_data = user_data;
|
||||
}
|
||||
|
||||
msg_val_params.notify = bpy_msgbus_notify;
|
||||
msg_val_params.free_data = bpy_msgbus_subscribe_value_free_data;
|
||||
msg_val_params.notify = bpy_msgbus_notify;
|
||||
msg_val_params.free_data = bpy_msgbus_subscribe_value_free_data;
|
||||
|
||||
WM_msg_subscribe_rna_params(mbus, &msg_key_params, &msg_val_params, __func__);
|
||||
WM_msg_subscribe_rna_params(mbus, &msg_key_params, &msg_val_params, __func__);
|
||||
|
||||
WM_msg_dump(mbus, __func__);
|
||||
WM_msg_dump(mbus, __func__);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_msgbus_publish_rna_doc,
|
||||
".. function:: publish_rna(data, owner, args, notify)\n"
|
||||
"\n"
|
||||
BPY_MSGBUS_RNA_MSGKEY_DOC
|
||||
"\n"
|
||||
" Notify subscribers of changes to this property\n"
|
||||
" (this typically doesn't need to be called explicitly since changes will automatically publish updates).\n"
|
||||
" In some cases it may be useful to publish changes explicitly using more general keys.\n"
|
||||
);
|
||||
PyDoc_STRVAR(
|
||||
bpy_msgbus_publish_rna_doc,
|
||||
".. function:: publish_rna(data, owner, args, notify)\n"
|
||||
"\n" BPY_MSGBUS_RNA_MSGKEY_DOC
|
||||
"\n"
|
||||
" Notify subscribers of changes to this property\n"
|
||||
" (this typically doesn't need to be called explicitly since changes will automatically "
|
||||
"publish updates).\n"
|
||||
" In some cases it may be useful to publish changes explicitly using more general keys.\n");
|
||||
static PyObject *bpy_msgbus_publish_rna(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||
{
|
||||
const char *error_prefix = "publish_rna";
|
||||
PyObject *py_sub = NULL;
|
||||
const char *error_prefix = "publish_rna";
|
||||
PyObject *py_sub = NULL;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) != 0) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError,
|
||||
"%s: only keyword arguments are supported",
|
||||
error_prefix);
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {
|
||||
"key",
|
||||
NULL,
|
||||
};
|
||||
static _PyArg_Parser _parser = {"O:publish_rna", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(
|
||||
args, kw, &_parser,
|
||||
&py_sub))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (PyTuple_GET_SIZE(args) != 0) {
|
||||
PyErr_Format(PyExc_TypeError, "%s: only keyword arguments are supported", error_prefix);
|
||||
return NULL;
|
||||
}
|
||||
static const char *_keywords[] = {
|
||||
"key",
|
||||
NULL,
|
||||
};
|
||||
static _PyArg_Parser _parser = {"O:publish_rna", _keywords, 0};
|
||||
if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &py_sub)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Note: we may want to have a way to pass this in. */
|
||||
bContext *C = (bContext *)BPy_GetContext();
|
||||
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
|
||||
wmMsgParams_RNA msg_key_params = {{{0}}};
|
||||
/* Note: we may want to have a way to pass this in. */
|
||||
bContext *C = (bContext *)BPy_GetContext();
|
||||
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
|
||||
wmMsgParams_RNA msg_key_params = {{{0}}};
|
||||
|
||||
if (py_msgbus_rna_key_from_py(py_sub, &msg_key_params, error_prefix) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (py_msgbus_rna_key_from_py(py_sub, &msg_key_params, error_prefix) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WM_msg_publish_rna_params(mbus, &msg_key_params);
|
||||
WM_msg_publish_rna_params(mbus, &msg_key_params);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_msgbus_clear_by_owner_doc,
|
||||
".. function:: clear_by_owner(owner)\n"
|
||||
"\n"
|
||||
" Clear all subscribers using this owner.\n"
|
||||
);
|
||||
".. function:: clear_by_owner(owner)\n"
|
||||
"\n"
|
||||
" Clear all subscribers using this owner.\n");
|
||||
static PyObject *bpy_msgbus_clear_by_owner(PyObject *UNUSED(self), PyObject *py_owner)
|
||||
{
|
||||
bContext *C = (bContext *)BPy_GetContext();
|
||||
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
|
||||
WM_msgbus_clear_by_owner(mbus, py_owner);
|
||||
Py_RETURN_NONE;
|
||||
bContext *C = (bContext *)BPy_GetContext();
|
||||
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
|
||||
WM_msgbus_clear_by_owner(mbus, py_owner);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static struct PyMethodDef BPy_msgbus_methods[] = {
|
||||
{"subscribe_rna", (PyCFunction)bpy_msgbus_subscribe_rna, METH_VARARGS | METH_KEYWORDS, bpy_msgbus_subscribe_rna_doc},
|
||||
{"publish_rna", (PyCFunction)bpy_msgbus_publish_rna, METH_VARARGS | METH_KEYWORDS, bpy_msgbus_publish_rna_doc},
|
||||
{"clear_by_owner", (PyCFunction)bpy_msgbus_clear_by_owner, METH_O, bpy_msgbus_clear_by_owner_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"subscribe_rna",
|
||||
(PyCFunction)bpy_msgbus_subscribe_rna,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_msgbus_subscribe_rna_doc},
|
||||
{"publish_rna",
|
||||
(PyCFunction)bpy_msgbus_publish_rna,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_msgbus_publish_rna_doc},
|
||||
{"clear_by_owner",
|
||||
(PyCFunction)bpy_msgbus_clear_by_owner,
|
||||
METH_O,
|
||||
bpy_msgbus_clear_by_owner_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
static struct PyModuleDef _bpy_msgbus_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "msgbus",
|
||||
.m_methods = BPy_msgbus_methods,
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "msgbus",
|
||||
.m_methods = BPy_msgbus_methods,
|
||||
};
|
||||
|
||||
|
||||
PyObject *BPY_msgbus_module(void)
|
||||
{
|
||||
PyObject *submodule;
|
||||
PyObject *submodule;
|
||||
|
||||
submodule = PyModule_Create(&_bpy_msgbus_def);
|
||||
submodule = PyModule_Create(&_bpy_msgbus_def);
|
||||
|
||||
return submodule;
|
||||
return submodule;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
|
||||
PyObject *BPY_msgbus_module(void);
|
||||
|
||||
#endif /* __BPY_MSGBUS_H__ */
|
||||
#endif /* __BPY_MSGBUS_H__ */
|
||||
|
||||
@@ -59,385 +59,407 @@
|
||||
|
||||
static wmOperatorType *ot_lookup_from_py_string(PyObject *value, const char *py_fn_id)
|
||||
{
|
||||
const char *opname = _PyUnicode_AsString(value);
|
||||
if (opname == NULL) {
|
||||
PyErr_Format(PyExc_TypeError, "%s() expects a string argument", py_fn_id);
|
||||
return NULL;
|
||||
}
|
||||
const char *opname = _PyUnicode_AsString(value);
|
||||
if (opname == NULL) {
|
||||
PyErr_Format(PyExc_TypeError, "%s() expects a string argument", py_fn_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wmOperatorType *ot = WM_operatortype_find(opname, true);
|
||||
if (ot == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "%s(\"%s\") not found", py_fn_id, opname);
|
||||
return NULL;
|
||||
}
|
||||
return ot;
|
||||
wmOperatorType *ot = WM_operatortype_find(opname, true);
|
||||
if (ot == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "%s(\"%s\") not found", py_fn_id, opname);
|
||||
return NULL;
|
||||
}
|
||||
return ot;
|
||||
}
|
||||
|
||||
static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
wmOperatorType *ot;
|
||||
const char *opname;
|
||||
PyObject *context_dict = NULL; /* optional args */
|
||||
PyObject *context_dict_back;
|
||||
const char *context_str = NULL;
|
||||
PyObject *ret;
|
||||
wmOperatorType *ot;
|
||||
const char *opname;
|
||||
PyObject *context_dict = NULL; /* optional args */
|
||||
PyObject *context_dict_back;
|
||||
const char *context_str = NULL;
|
||||
PyObject *ret;
|
||||
|
||||
int context = WM_OP_EXEC_DEFAULT;
|
||||
int context = WM_OP_EXEC_DEFAULT;
|
||||
|
||||
/* XXX Todo, work out a better solution for passing on context,
|
||||
* could make a tuple from self and pack the name and Context into it... */
|
||||
bContext *C = (bContext *)BPy_GetContext();
|
||||
/* XXX Todo, work out a better solution for passing on context,
|
||||
* could make a tuple from self and pack the name and Context into it... */
|
||||
bContext *C = (bContext *)BPy_GetContext();
|
||||
|
||||
if (C == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators");
|
||||
return NULL;
|
||||
}
|
||||
if (C == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ot = WM_operatortype_find(opname, true);
|
||||
ot = WM_operatortype_find(opname, true);
|
||||
|
||||
if (ot == NULL) {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"Polling operator \"bpy.ops.%s\" error, "
|
||||
"could not be found", opname);
|
||||
return NULL;
|
||||
}
|
||||
if (ot == NULL) {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"Polling operator \"bpy.ops.%s\" error, "
|
||||
"could not be found",
|
||||
opname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (context_str) {
|
||||
if (RNA_enum_value_from_id(rna_enum_operator_context_items, context_str, &context) == 0) {
|
||||
char *enum_str = BPy_enum_as_string(rna_enum_operator_context_items);
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Calling operator \"bpy.ops.%s.poll\" error, "
|
||||
"expected a string enum in (%s)",
|
||||
opname, enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (context_str) {
|
||||
if (RNA_enum_value_from_id(rna_enum_operator_context_items, context_str, &context) == 0) {
|
||||
char *enum_str = BPy_enum_as_string(rna_enum_operator_context_items);
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Calling operator \"bpy.ops.%s.poll\" error, "
|
||||
"expected a string enum in (%s)",
|
||||
opname,
|
||||
enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (context_dict == NULL || context_dict == Py_None) {
|
||||
context_dict = NULL;
|
||||
}
|
||||
else if (!PyDict_Check(context_dict)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Calling operator \"bpy.ops.%s.poll\" error, "
|
||||
"custom context expected a dict or None, got a %.200s",
|
||||
opname, Py_TYPE(context_dict)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
if (context_dict == NULL || context_dict == Py_None) {
|
||||
context_dict = NULL;
|
||||
}
|
||||
else if (!PyDict_Check(context_dict)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Calling operator \"bpy.ops.%s.poll\" error, "
|
||||
"custom context expected a dict or None, got a %.200s",
|
||||
opname,
|
||||
Py_TYPE(context_dict)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context_dict_back = CTX_py_dict_get(C);
|
||||
CTX_py_dict_set(C, (void *)context_dict);
|
||||
Py_XINCREF(context_dict); /* so we done loose it */
|
||||
context_dict_back = CTX_py_dict_get(C);
|
||||
CTX_py_dict_set(C, (void *)context_dict);
|
||||
Py_XINCREF(context_dict); /* so we done loose it */
|
||||
|
||||
/* main purpose of this function */
|
||||
ret = WM_operator_poll_context((bContext *)C, ot, context) ? Py_True : Py_False;
|
||||
/* main purpose of this function */
|
||||
ret = WM_operator_poll_context((bContext *)C, ot, context) ? Py_True : Py_False;
|
||||
|
||||
/* restore with original context dict, probably NULL but need this for nested operator calls */
|
||||
Py_XDECREF(context_dict);
|
||||
CTX_py_dict_set(C, (void *)context_dict_back);
|
||||
/* restore with original context dict, probably NULL but need this for nested operator calls */
|
||||
Py_XDECREF(context_dict);
|
||||
CTX_py_dict_set(C, (void *)context_dict_back);
|
||||
|
||||
return Py_INCREF_RET(ret);
|
||||
return Py_INCREF_RET(ret);
|
||||
}
|
||||
|
||||
static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
wmOperatorType *ot;
|
||||
int error_val = 0;
|
||||
PointerRNA ptr;
|
||||
int operator_ret = OPERATOR_CANCELLED;
|
||||
wmOperatorType *ot;
|
||||
int error_val = 0;
|
||||
PointerRNA ptr;
|
||||
int operator_ret = OPERATOR_CANCELLED;
|
||||
|
||||
const char *opname;
|
||||
const char *context_str = NULL;
|
||||
PyObject *kw = NULL; /* optional args */
|
||||
PyObject *context_dict = NULL; /* optional args */
|
||||
PyObject *context_dict_back;
|
||||
const char *opname;
|
||||
const char *context_str = NULL;
|
||||
PyObject *kw = NULL; /* optional args */
|
||||
PyObject *context_dict = NULL; /* optional args */
|
||||
PyObject *context_dict_back;
|
||||
|
||||
/* note that context is an int, python does the conversion in this case */
|
||||
int context = WM_OP_EXEC_DEFAULT;
|
||||
int is_undo = false;
|
||||
/* note that context is an int, python does the conversion in this case */
|
||||
int context = WM_OP_EXEC_DEFAULT;
|
||||
int is_undo = false;
|
||||
|
||||
/* XXX Todo, work out a better solution for passing on context,
|
||||
* could make a tuple from self and pack the name and Context into it... */
|
||||
bContext *C = (bContext *)BPy_GetContext();
|
||||
/* XXX Todo, work out a better solution for passing on context,
|
||||
* could make a tuple from self and pack the name and Context into it... */
|
||||
bContext *C = (bContext *)BPy_GetContext();
|
||||
|
||||
if (C == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators");
|
||||
return NULL;
|
||||
}
|
||||
if (C == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sO|O!si:_bpy.ops.call",
|
||||
&opname, &context_dict, &PyDict_Type, &kw, &context_str, &is_undo))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"sO|O!si:_bpy.ops.call",
|
||||
&opname,
|
||||
&context_dict,
|
||||
&PyDict_Type,
|
||||
&kw,
|
||||
&context_str,
|
||||
&is_undo)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ot = WM_operatortype_find(opname, true);
|
||||
ot = WM_operatortype_find(opname, true);
|
||||
|
||||
if (ot == NULL) {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"Calling operator \"bpy.ops.%s\" error, "
|
||||
"could not be found", opname);
|
||||
return NULL;
|
||||
}
|
||||
if (ot == NULL) {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"Calling operator \"bpy.ops.%s\" error, "
|
||||
"could not be found",
|
||||
opname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!pyrna_write_check()) {
|
||||
PyErr_Format(PyExc_RuntimeError,
|
||||
"Calling operator \"bpy.ops.%s\" error, "
|
||||
"can't modify blend data in this state (drawing/rendering)",
|
||||
opname);
|
||||
return NULL;
|
||||
}
|
||||
if (!pyrna_write_check()) {
|
||||
PyErr_Format(PyExc_RuntimeError,
|
||||
"Calling operator \"bpy.ops.%s\" error, "
|
||||
"can't modify blend data in this state (drawing/rendering)",
|
||||
opname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (context_str) {
|
||||
if (RNA_enum_value_from_id(rna_enum_operator_context_items, context_str, &context) == 0) {
|
||||
char *enum_str = BPy_enum_as_string(rna_enum_operator_context_items);
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Calling operator \"bpy.ops.%s\" error, "
|
||||
"expected a string enum in (%s)",
|
||||
opname, enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (context_str) {
|
||||
if (RNA_enum_value_from_id(rna_enum_operator_context_items, context_str, &context) == 0) {
|
||||
char *enum_str = BPy_enum_as_string(rna_enum_operator_context_items);
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Calling operator \"bpy.ops.%s\" error, "
|
||||
"expected a string enum in (%s)",
|
||||
opname,
|
||||
enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (context_dict == NULL || context_dict == Py_None) {
|
||||
context_dict = NULL;
|
||||
}
|
||||
else if (!PyDict_Check(context_dict)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Calling operator \"bpy.ops.%s\" error, "
|
||||
"custom context expected a dict or None, got a %.200s",
|
||||
opname, Py_TYPE(context_dict)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
if (context_dict == NULL || context_dict == Py_None) {
|
||||
context_dict = NULL;
|
||||
}
|
||||
else if (!PyDict_Check(context_dict)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Calling operator \"bpy.ops.%s\" error, "
|
||||
"custom context expected a dict or None, got a %.200s",
|
||||
opname,
|
||||
Py_TYPE(context_dict)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context_dict_back = CTX_py_dict_get(C);
|
||||
context_dict_back = CTX_py_dict_get(C);
|
||||
|
||||
CTX_py_dict_set(C, (void *)context_dict);
|
||||
Py_XINCREF(context_dict); /* so we done loose it */
|
||||
CTX_py_dict_set(C, (void *)context_dict);
|
||||
Py_XINCREF(context_dict); /* so we done loose it */
|
||||
|
||||
if (WM_operator_poll_context((bContext *)C, ot, context) == false) {
|
||||
const char *msg = CTX_wm_operator_poll_msg_get(C);
|
||||
PyErr_Format(PyExc_RuntimeError,
|
||||
"Operator bpy.ops.%.200s.poll() %.200s",
|
||||
opname, msg ? msg : "failed, context is incorrect");
|
||||
CTX_wm_operator_poll_msg_set(C, NULL); /* better set to NULL else it could be used again */
|
||||
error_val = -1;
|
||||
}
|
||||
else {
|
||||
WM_operator_properties_create_ptr(&ptr, ot);
|
||||
WM_operator_properties_sanitize(&ptr, 0);
|
||||
if (WM_operator_poll_context((bContext *)C, ot, context) == false) {
|
||||
const char *msg = CTX_wm_operator_poll_msg_get(C);
|
||||
PyErr_Format(PyExc_RuntimeError,
|
||||
"Operator bpy.ops.%.200s.poll() %.200s",
|
||||
opname,
|
||||
msg ? msg : "failed, context is incorrect");
|
||||
CTX_wm_operator_poll_msg_set(C, NULL); /* better set to NULL else it could be used again */
|
||||
error_val = -1;
|
||||
}
|
||||
else {
|
||||
WM_operator_properties_create_ptr(&ptr, ot);
|
||||
WM_operator_properties_sanitize(&ptr, 0);
|
||||
|
||||
if (kw && PyDict_Size(kw)) {
|
||||
error_val = pyrna_pydict_to_props(&ptr, kw, false, "Converting py args to operator properties: ");
|
||||
}
|
||||
if (kw && PyDict_Size(kw)) {
|
||||
error_val = pyrna_pydict_to_props(
|
||||
&ptr, kw, false, "Converting py args to operator properties: ");
|
||||
}
|
||||
|
||||
if (error_val == 0) {
|
||||
ReportList *reports;
|
||||
if (error_val == 0) {
|
||||
ReportList *reports;
|
||||
|
||||
reports = MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
|
||||
BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD); /* own so these don't move into global reports */
|
||||
reports = MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
|
||||
BKE_reports_init(reports,
|
||||
RPT_STORE | RPT_OP_HOLD); /* own so these don't move into global reports */
|
||||
|
||||
#ifdef BPY_RELEASE_GIL
|
||||
/* release GIL, since a thread could be started from an operator
|
||||
* that updates a driver */
|
||||
/* note: I have not seen any examples of code that does this
|
||||
* so it may not be officially supported but seems to work ok. */
|
||||
{
|
||||
PyThreadState *ts = PyEval_SaveThread();
|
||||
/* release GIL, since a thread could be started from an operator
|
||||
* that updates a driver */
|
||||
/* note: I have not seen any examples of code that does this
|
||||
* so it may not be officially supported but seems to work ok. */
|
||||
{
|
||||
PyThreadState *ts = PyEval_SaveThread();
|
||||
#endif
|
||||
|
||||
operator_ret = WM_operator_call_py(C, ot, context, &ptr, reports, is_undo);
|
||||
operator_ret = WM_operator_call_py(C, ot, context, &ptr, reports, is_undo);
|
||||
|
||||
#ifdef BPY_RELEASE_GIL
|
||||
/* regain GIL */
|
||||
PyEval_RestoreThread(ts);
|
||||
}
|
||||
/* regain GIL */
|
||||
PyEval_RestoreThread(ts);
|
||||
}
|
||||
#endif
|
||||
|
||||
error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, false);
|
||||
error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, false);
|
||||
|
||||
/* operator output is nice to have in the terminal/console too */
|
||||
if (!BLI_listbase_is_empty(&reports->list)) {
|
||||
BPy_reports_write_stdout(reports, NULL);
|
||||
}
|
||||
/* operator output is nice to have in the terminal/console too */
|
||||
if (!BLI_listbase_is_empty(&reports->list)) {
|
||||
BPy_reports_write_stdout(reports, NULL);
|
||||
}
|
||||
|
||||
BKE_reports_clear(reports);
|
||||
if ((reports->flag & RPT_FREE) == 0) {
|
||||
MEM_freeN(reports);
|
||||
}
|
||||
else {
|
||||
/* The WM is now responsible for running the modal operator,
|
||||
* show reports in the info window. */
|
||||
reports->flag &= ~RPT_OP_HOLD;
|
||||
}
|
||||
}
|
||||
BKE_reports_clear(reports);
|
||||
if ((reports->flag & RPT_FREE) == 0) {
|
||||
MEM_freeN(reports);
|
||||
}
|
||||
else {
|
||||
/* The WM is now responsible for running the modal operator,
|
||||
* show reports in the info window. */
|
||||
reports->flag &= ~RPT_OP_HOLD;
|
||||
}
|
||||
}
|
||||
|
||||
WM_operator_properties_free(&ptr);
|
||||
WM_operator_properties_free(&ptr);
|
||||
|
||||
#if 0
|
||||
/* if there is some way to know an operator takes args we should use this */
|
||||
{
|
||||
/* no props */
|
||||
if (kw != NULL) {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"Operator \"%s\" does not take any args",
|
||||
opname);
|
||||
return NULL;
|
||||
}
|
||||
/* if there is some way to know an operator takes args we should use this */
|
||||
{
|
||||
/* no props */
|
||||
if (kw != NULL) {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"Operator \"%s\" does not take any args",
|
||||
opname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WM_operator_name_call(C, opname, WM_OP_EXEC_DEFAULT, NULL);
|
||||
}
|
||||
WM_operator_name_call(C, opname, WM_OP_EXEC_DEFAULT, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* restore with original context dict, probably NULL but need this for nested operator calls */
|
||||
Py_XDECREF(context_dict);
|
||||
CTX_py_dict_set(C, (void *)context_dict_back);
|
||||
/* restore with original context dict, probably NULL but need this for nested operator calls */
|
||||
Py_XDECREF(context_dict);
|
||||
CTX_py_dict_set(C, (void *)context_dict_back);
|
||||
|
||||
if (error_val == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (error_val == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* when calling bpy.ops.wm.read_factory_settings() bpy.data's main pointer is freed by clear_globals(),
|
||||
* further access will crash blender. setting context is not needed in this case, only calling because this
|
||||
* function corrects bpy.data (internal Main pointer) */
|
||||
BPY_modules_update(C);
|
||||
/* when calling bpy.ops.wm.read_factory_settings() bpy.data's main pointer is freed by clear_globals(),
|
||||
* further access will crash blender. setting context is not needed in this case, only calling because this
|
||||
* function corrects bpy.data (internal Main pointer) */
|
||||
BPY_modules_update(C);
|
||||
|
||||
/* needed for when WM_OT_read_factory_settings us called from within a script */
|
||||
bpy_import_main_set(CTX_data_main(C));
|
||||
|
||||
/* return operator_ret as a bpy enum */
|
||||
return pyrna_enum_bitfield_to_py(rna_enum_operator_return_items, operator_ret);
|
||||
/* needed for when WM_OT_read_factory_settings us called from within a script */
|
||||
bpy_import_main_set(CTX_data_main(C));
|
||||
|
||||
/* return operator_ret as a bpy enum */
|
||||
return pyrna_enum_bitfield_to_py(rna_enum_operator_return_items, operator_ret);
|
||||
}
|
||||
|
||||
static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
wmOperatorType *ot;
|
||||
PointerRNA ptr;
|
||||
wmOperatorType *ot;
|
||||
PointerRNA ptr;
|
||||
|
||||
const char *opname;
|
||||
PyObject *kw = NULL; /* optional args */
|
||||
bool all_args = true;
|
||||
bool macro_args = true;
|
||||
int error_val = 0;
|
||||
const char *opname;
|
||||
PyObject *kw = NULL; /* optional args */
|
||||
bool all_args = true;
|
||||
bool macro_args = true;
|
||||
int error_val = 0;
|
||||
|
||||
char *buf = NULL;
|
||||
PyObject *pybuf;
|
||||
char *buf = NULL;
|
||||
PyObject *pybuf;
|
||||
|
||||
bContext *C = (bContext *)BPy_GetContext();
|
||||
bContext *C = (bContext *)BPy_GetContext();
|
||||
|
||||
if (C == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Context is None, cant get the string representation of this object.");
|
||||
return NULL;
|
||||
}
|
||||
if (C == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Context is None, cant get the string representation of this object.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "s|O!O&O&:_bpy.ops.as_string",
|
||||
&opname, &PyDict_Type, &kw,
|
||||
PyC_ParseBool, &all_args,
|
||||
PyC_ParseBool, ¯o_args))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"s|O!O&O&:_bpy.ops.as_string",
|
||||
&opname,
|
||||
&PyDict_Type,
|
||||
&kw,
|
||||
PyC_ParseBool,
|
||||
&all_args,
|
||||
PyC_ParseBool,
|
||||
¯o_args)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ot = WM_operatortype_find(opname, true);
|
||||
ot = WM_operatortype_find(opname, true);
|
||||
|
||||
if (ot == NULL) {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"_bpy.ops.as_string: operator \"%.200s\" "
|
||||
"could not be found", opname);
|
||||
return NULL;
|
||||
}
|
||||
if (ot == NULL) {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"_bpy.ops.as_string: operator \"%.200s\" "
|
||||
"could not be found",
|
||||
opname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* WM_operator_properties_create(&ptr, opname); */
|
||||
/* Save another lookup */
|
||||
RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
|
||||
/* WM_operator_properties_create(&ptr, opname); */
|
||||
/* Save another lookup */
|
||||
RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
|
||||
|
||||
if (kw && PyDict_Size(kw)) {
|
||||
error_val = pyrna_pydict_to_props(&ptr, kw, false, "Converting py args to operator properties: ");
|
||||
}
|
||||
if (kw && PyDict_Size(kw)) {
|
||||
error_val = pyrna_pydict_to_props(
|
||||
&ptr, kw, false, "Converting py args to operator properties: ");
|
||||
}
|
||||
|
||||
if (error_val == 0) {
|
||||
buf = WM_operator_pystring_ex(C, NULL, all_args, macro_args, ot, &ptr);
|
||||
}
|
||||
if (error_val == 0) {
|
||||
buf = WM_operator_pystring_ex(C, NULL, all_args, macro_args, ot, &ptr);
|
||||
}
|
||||
|
||||
WM_operator_properties_free(&ptr);
|
||||
WM_operator_properties_free(&ptr);
|
||||
|
||||
if (error_val == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (error_val == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
pybuf = PyUnicode_FromString(buf);
|
||||
MEM_freeN(buf);
|
||||
}
|
||||
else {
|
||||
pybuf = PyUnicode_FromString("");
|
||||
}
|
||||
if (buf) {
|
||||
pybuf = PyUnicode_FromString(buf);
|
||||
MEM_freeN(buf);
|
||||
}
|
||||
else {
|
||||
pybuf = PyUnicode_FromString("");
|
||||
}
|
||||
|
||||
return pybuf;
|
||||
return pybuf;
|
||||
}
|
||||
|
||||
static PyObject *pyop_dir(PyObject *UNUSED(self))
|
||||
{
|
||||
GHashIterator iter;
|
||||
PyObject *list;
|
||||
int i;
|
||||
GHashIterator iter;
|
||||
PyObject *list;
|
||||
int i;
|
||||
|
||||
WM_operatortype_iter(&iter);
|
||||
list = PyList_New(BLI_ghash_len(iter.gh));
|
||||
WM_operatortype_iter(&iter);
|
||||
list = PyList_New(BLI_ghash_len(iter.gh));
|
||||
|
||||
for (i = 0; !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter), i++) {
|
||||
wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
|
||||
PyList_SET_ITEM(list, i, PyUnicode_FromString(ot->idname));
|
||||
}
|
||||
for (i = 0; !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter), i++) {
|
||||
wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
|
||||
PyList_SET_ITEM(list, i, PyUnicode_FromString(ot->idname));
|
||||
}
|
||||
|
||||
return list;
|
||||
return list;
|
||||
}
|
||||
|
||||
static PyObject *pyop_getrna_type(PyObject *UNUSED(self), PyObject *value)
|
||||
{
|
||||
wmOperatorType *ot;
|
||||
if ((ot = ot_lookup_from_py_string(value, "get_rna_type")) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
wmOperatorType *ot;
|
||||
if ((ot = ot_lookup_from_py_string(value, "get_rna_type")) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create(NULL, &RNA_Struct, ot->srna, &ptr);
|
||||
BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
|
||||
return (PyObject *)pyrna;
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create(NULL, &RNA_Struct, ot->srna, &ptr);
|
||||
BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
|
||||
return (PyObject *)pyrna;
|
||||
}
|
||||
|
||||
static struct PyMethodDef bpy_ops_methods[] = {
|
||||
{"poll", (PyCFunction) pyop_poll, METH_VARARGS, NULL},
|
||||
{"call", (PyCFunction) pyop_call, METH_VARARGS, NULL},
|
||||
{"as_string", (PyCFunction) pyop_as_string, METH_VARARGS, NULL},
|
||||
{"dir", (PyCFunction) pyop_dir, METH_NOARGS, NULL},
|
||||
{"get_rna_type", (PyCFunction) pyop_getrna_type, METH_O, NULL},
|
||||
{"macro_define", (PyCFunction) PYOP_wrap_macro_define, METH_VARARGS, NULL},
|
||||
{NULL, NULL, 0, NULL},
|
||||
{"poll", (PyCFunction)pyop_poll, METH_VARARGS, NULL},
|
||||
{"call", (PyCFunction)pyop_call, METH_VARARGS, NULL},
|
||||
{"as_string", (PyCFunction)pyop_as_string, METH_VARARGS, NULL},
|
||||
{"dir", (PyCFunction)pyop_dir, METH_NOARGS, NULL},
|
||||
{"get_rna_type", (PyCFunction)pyop_getrna_type, METH_O, NULL},
|
||||
{"macro_define", (PyCFunction)PYOP_wrap_macro_define, METH_VARARGS, NULL},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
static struct PyModuleDef bpy_ops_module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_bpy.ops",
|
||||
NULL,
|
||||
-1, /* multiple "initialization" just copies the module dict. */
|
||||
bpy_ops_methods,
|
||||
NULL, NULL, NULL, NULL,
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_bpy.ops",
|
||||
NULL,
|
||||
-1, /* multiple "initialization" just copies the module dict. */
|
||||
bpy_ops_methods,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
PyObject *BPY_operator_module(void)
|
||||
{
|
||||
PyObject *submodule;
|
||||
PyObject *submodule;
|
||||
|
||||
submodule = PyModule_Create(&bpy_ops_module);
|
||||
submodule = PyModule_Create(&bpy_ops_module);
|
||||
|
||||
return submodule;
|
||||
return submodule;
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
|
||||
extern PyTypeObject pyop_base_Type;
|
||||
|
||||
#define BPy_OperatorBase_Check(v) (PyObject_TypeCheck(v, &pyop_base_Type))
|
||||
#define BPy_OperatorBase_Check(v) (PyObject_TypeCheck(v, &pyop_base_Type))
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD /* required python macro */
|
||||
PyObject_HEAD /* required python macro */
|
||||
} BPy_OperatorBase;
|
||||
|
||||
PyObject *BPY_operator_module(void);
|
||||
|
||||
@@ -35,163 +35,158 @@
|
||||
|
||||
#include "bpy_rna.h"
|
||||
#include "bpy_intern_string.h"
|
||||
#include "bpy_operator_wrap.h" /* own include */
|
||||
#include "bpy_operator_wrap.h" /* own include */
|
||||
|
||||
static void operator_properties_init(wmOperatorType *ot)
|
||||
{
|
||||
PyTypeObject *py_class = ot->ext.data;
|
||||
RNA_struct_blender_type_set(ot->ext.srna, ot);
|
||||
PyTypeObject *py_class = ot->ext.data;
|
||||
RNA_struct_blender_type_set(ot->ext.srna, ot);
|
||||
|
||||
/* Only call this so pyrna_deferred_register_class gives a useful error
|
||||
* WM_operatortype_append_ptr will call RNA_def_struct_identifier later.
|
||||
*
|
||||
* Note the 'no_struct_map' function is used since the actual struct name is already used by the operator.
|
||||
*/
|
||||
RNA_def_struct_identifier_no_struct_map(ot->srna, ot->idname);
|
||||
/* Only call this so pyrna_deferred_register_class gives a useful error
|
||||
* WM_operatortype_append_ptr will call RNA_def_struct_identifier later.
|
||||
*
|
||||
* Note the 'no_struct_map' function is used since the actual struct name is already used by the operator.
|
||||
*/
|
||||
RNA_def_struct_identifier_no_struct_map(ot->srna, ot->idname);
|
||||
|
||||
if (pyrna_deferred_register_class(ot->srna, py_class) != 0) {
|
||||
PyErr_Print(); /* failed to register operator props */
|
||||
PyErr_Clear();
|
||||
}
|
||||
if (pyrna_deferred_register_class(ot->srna, py_class) != 0) {
|
||||
PyErr_Print(); /* failed to register operator props */
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
/* set the default property: ot->prop */
|
||||
{
|
||||
/* picky developers will notice that 'bl_property' won't work with inheritance
|
||||
* get direct from the dict to avoid raising a load of attribute errors (yes this isnt ideal) - campbell */
|
||||
PyObject *py_class_dict = py_class->tp_dict;
|
||||
PyObject *bl_property = PyDict_GetItem(py_class_dict, bpy_intern_str_bl_property);
|
||||
const char *prop_id;
|
||||
bool prop_raise_error;
|
||||
/* set the default property: ot->prop */
|
||||
{
|
||||
/* picky developers will notice that 'bl_property' won't work with inheritance
|
||||
* get direct from the dict to avoid raising a load of attribute errors (yes this isnt ideal) - campbell */
|
||||
PyObject *py_class_dict = py_class->tp_dict;
|
||||
PyObject *bl_property = PyDict_GetItem(py_class_dict, bpy_intern_str_bl_property);
|
||||
const char *prop_id;
|
||||
bool prop_raise_error;
|
||||
|
||||
if (bl_property) {
|
||||
if (PyUnicode_Check(bl_property)) {
|
||||
/* since the property is explicitly given, raise an error if its not found */
|
||||
prop_id = _PyUnicode_AsString(bl_property);
|
||||
prop_raise_error = true;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"%.200s.bl_property should be a string, not %.200s",
|
||||
ot->idname, Py_TYPE(bl_property)->tp_name);
|
||||
if (bl_property) {
|
||||
if (PyUnicode_Check(bl_property)) {
|
||||
/* since the property is explicitly given, raise an error if its not found */
|
||||
prop_id = _PyUnicode_AsString(bl_property);
|
||||
prop_raise_error = true;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"%.200s.bl_property should be a string, not %.200s",
|
||||
ot->idname,
|
||||
Py_TYPE(bl_property)->tp_name);
|
||||
|
||||
/* this could be done cleaner, for now its OK */
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
/* this could be done cleaner, for now its OK */
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
|
||||
prop_id = NULL;
|
||||
prop_raise_error = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* fallback to hard-coded string (pre 2.66, could be deprecated) */
|
||||
prop_id = "type";
|
||||
prop_raise_error = false;
|
||||
}
|
||||
prop_id = NULL;
|
||||
prop_raise_error = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* fallback to hard-coded string (pre 2.66, could be deprecated) */
|
||||
prop_id = "type";
|
||||
prop_raise_error = false;
|
||||
}
|
||||
|
||||
if (prop_id) {
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
if (prop_id) {
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
|
||||
RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
|
||||
prop = RNA_struct_find_property(&ptr, prop_id);
|
||||
if (prop) {
|
||||
ot->prop = prop;
|
||||
}
|
||||
else {
|
||||
if (prop_raise_error) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"%.200s.bl_property '%.200s' not found",
|
||||
ot->idname, prop_id);
|
||||
|
||||
/* this could be done cleaner, for now its OK */
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* end 'ot->prop' assignment */
|
||||
RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
|
||||
prop = RNA_struct_find_property(&ptr, prop_id);
|
||||
if (prop) {
|
||||
ot->prop = prop;
|
||||
}
|
||||
else {
|
||||
if (prop_raise_error) {
|
||||
PyErr_Format(
|
||||
PyExc_ValueError, "%.200s.bl_property '%.200s' not found", ot->idname, prop_id);
|
||||
|
||||
/* this could be done cleaner, for now its OK */
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* end 'ot->prop' assignment */
|
||||
}
|
||||
|
||||
void BPY_RNA_operator_wrapper(wmOperatorType *ot, void *userdata)
|
||||
{
|
||||
/* take care not to overwrite anything set in
|
||||
* WM_operatortype_append_ptr before opfunc() is called */
|
||||
StructRNA *srna = ot->srna;
|
||||
*ot = *((wmOperatorType *)userdata);
|
||||
ot->srna = srna; /* restore */
|
||||
/* take care not to overwrite anything set in
|
||||
* WM_operatortype_append_ptr before opfunc() is called */
|
||||
StructRNA *srna = ot->srna;
|
||||
*ot = *((wmOperatorType *)userdata);
|
||||
ot->srna = srna; /* restore */
|
||||
|
||||
/* Use i18n context from ext.srna if possible (py operators). */
|
||||
if (ot->ext.srna) {
|
||||
RNA_def_struct_translation_context(ot->srna, RNA_struct_translation_context(ot->ext.srna));
|
||||
}
|
||||
/* Use i18n context from ext.srna if possible (py operators). */
|
||||
if (ot->ext.srna) {
|
||||
RNA_def_struct_translation_context(ot->srna, RNA_struct_translation_context(ot->ext.srna));
|
||||
}
|
||||
|
||||
operator_properties_init(ot);
|
||||
operator_properties_init(ot);
|
||||
}
|
||||
|
||||
void BPY_RNA_operator_macro_wrapper(wmOperatorType *ot, void *userdata)
|
||||
{
|
||||
wmOperatorType *data = (wmOperatorType *)userdata;
|
||||
wmOperatorType *data = (wmOperatorType *)userdata;
|
||||
|
||||
/* only copy a couple of things, the rest is set by the macro registration */
|
||||
ot->name = data->name;
|
||||
ot->idname = data->idname;
|
||||
ot->description = data->description;
|
||||
ot->flag |= data->flag; /* append flags to the one set by registration */
|
||||
ot->pyop_poll = data->pyop_poll;
|
||||
ot->ui = data->ui;
|
||||
ot->ext = data->ext;
|
||||
/* only copy a couple of things, the rest is set by the macro registration */
|
||||
ot->name = data->name;
|
||||
ot->idname = data->idname;
|
||||
ot->description = data->description;
|
||||
ot->flag |= data->flag; /* append flags to the one set by registration */
|
||||
ot->pyop_poll = data->pyop_poll;
|
||||
ot->ui = data->ui;
|
||||
ot->ext = data->ext;
|
||||
|
||||
/* Use i18n context from ext.srna if possible (py operators). */
|
||||
if (ot->ext.srna) {
|
||||
RNA_def_struct_translation_context(ot->srna, RNA_struct_translation_context(ot->ext.srna));
|
||||
}
|
||||
/* Use i18n context from ext.srna if possible (py operators). */
|
||||
if (ot->ext.srna) {
|
||||
RNA_def_struct_translation_context(ot->srna, RNA_struct_translation_context(ot->ext.srna));
|
||||
}
|
||||
|
||||
operator_properties_init(ot);
|
||||
operator_properties_init(ot);
|
||||
}
|
||||
|
||||
PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
|
||||
{
|
||||
wmOperatorType *ot;
|
||||
wmOperatorTypeMacro *otmacro;
|
||||
PyObject *macro;
|
||||
PointerRNA ptr_otmacro;
|
||||
StructRNA *srna;
|
||||
wmOperatorType *ot;
|
||||
wmOperatorTypeMacro *otmacro;
|
||||
PyObject *macro;
|
||||
PointerRNA ptr_otmacro;
|
||||
StructRNA *srna;
|
||||
|
||||
const char *opname;
|
||||
const char *macroname;
|
||||
const char *opname;
|
||||
const char *macroname;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", ¯o, &opname)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", ¯o, &opname)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (WM_operatortype_find(opname, true) == NULL) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"Macro Define: '%s' is not a valid operator id",
|
||||
opname);
|
||||
return NULL;
|
||||
}
|
||||
if (WM_operatortype_find(opname, true) == NULL) {
|
||||
PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid operator id", opname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* identifiers */
|
||||
srna = pyrna_struct_as_srna((PyObject *)macro, false, "Macro Define:");
|
||||
if (srna == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
/* identifiers */
|
||||
srna = pyrna_struct_as_srna((PyObject *)macro, false, "Macro Define:");
|
||||
if (srna == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
macroname = RNA_struct_identifier(srna);
|
||||
ot = WM_operatortype_find(macroname, true);
|
||||
macroname = RNA_struct_identifier(srna);
|
||||
ot = WM_operatortype_find(macroname, true);
|
||||
|
||||
if (!ot) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"Macro Define: '%s' is not a valid macro",
|
||||
macroname);
|
||||
return NULL;
|
||||
}
|
||||
if (!ot) {
|
||||
PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid macro", macroname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
otmacro = WM_operatortype_macro_define(ot, opname);
|
||||
otmacro = WM_operatortype_macro_define(ot, opname);
|
||||
|
||||
RNA_pointer_create(NULL, &RNA_OperatorMacro, otmacro, &ptr_otmacro);
|
||||
RNA_pointer_create(NULL, &RNA_OperatorMacro, otmacro, &ptr_otmacro);
|
||||
|
||||
return pyrna_struct_CreatePyObject(&ptr_otmacro);
|
||||
return pyrna_struct_CreatePyObject(&ptr_otmacro);
|
||||
}
|
||||
|
||||
@@ -35,26 +35,26 @@ extern const char *imb_ext_audio[];
|
||||
|
||||
/*----------------------------MODULE INIT-------------------------*/
|
||||
static struct PyModuleDef _bpy_path_module_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_bpy_path", /* m_name */
|
||||
NULL, /* m_doc */
|
||||
0, /* m_size */
|
||||
NULL, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_bpy_path", /* m_name */
|
||||
NULL, /* m_doc */
|
||||
0, /* m_size */
|
||||
NULL, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL, /* m_free */
|
||||
};
|
||||
|
||||
PyObject *BPyInit__bpy_path(void)
|
||||
{
|
||||
PyObject *submodule;
|
||||
PyObject *submodule;
|
||||
|
||||
submodule = PyModule_Create(&_bpy_path_module_def);
|
||||
submodule = PyModule_Create(&_bpy_path_module_def);
|
||||
|
||||
PyModule_AddObject(submodule, "extensions_image", PyC_FrozenSetFromStrings(imb_ext_image));
|
||||
PyModule_AddObject(submodule, "extensions_movie", PyC_FrozenSetFromStrings(imb_ext_movie));
|
||||
PyModule_AddObject(submodule, "extensions_audio", PyC_FrozenSetFromStrings(imb_ext_audio));
|
||||
PyModule_AddObject(submodule, "extensions_image", PyC_FrozenSetFromStrings(imb_ext_image));
|
||||
PyModule_AddObject(submodule, "extensions_movie", PyC_FrozenSetFromStrings(imb_ext_movie));
|
||||
PyModule_AddObject(submodule, "extensions_audio", PyC_FrozenSetFromStrings(imb_ext_audio));
|
||||
|
||||
return submodule;
|
||||
return submodule;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
* \ingroup pythonintern
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __BPY_PATH_H__
|
||||
#define __BPY_PATH_H__
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,6 @@
|
||||
* \ingroup pythonintern
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __BPY_PROPS_H__
|
||||
#define __BPY_PROPS_H__
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user