Merged changes in the trunk up to revision 34193.

Conflicts resolved:
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/animation/anim_channels_edit.c
source/blender/editors/animation/keyframes_draw.c
source/blender/editors/animation/keyframes_edit.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/space_nla/nla_channels.c
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_scene.c

API changes resolved:
source/blender/freestyle/intern/system/PythonInterpreter.h
This commit is contained in:
2011-01-09 15:07:14 +00:00
591 changed files with 9099 additions and 5273 deletions

View File

@@ -38,14 +38,12 @@ struct Object; /* DNA_object_types.h */
struct ChannelDriver; /* DNA_anim_types.h */
struct ListBase; /* DNA_listBase.h */
struct SpaceText; /* DNA_space_types.h */
struct SpaceScript; /* DNA_space_types.h */
struct ScrArea; /* DNA_screen_types.h */
struct bScreen; /* DNA_screen_types.h */
struct bConstraint; /* DNA_constraint_types.h */
struct bPythonConstraint; /* DNA_constraint_types.h */
struct bConstraintOb; /* DNA_constraint_types.h */
struct bConstraintTarget; /* DNA_constraint_types.h*/
struct Script; /* DNA_screen_types.h */
struct BPyMenu;
struct bContext;
struct bContextDataResult;
@@ -55,34 +53,15 @@ struct ReportList;
extern "C" {
#endif
/*These two next functions are important for making sure the Draw module
works correctly. Before calling any gui callback using the Draw module,
the following code must be executed:
if (some_drawspace_pylist) {
BPy_Set_DrawButtonsList(some_drawspace_pylist->but_refs);
BPy_Free_DrawButtonsList();
}
some_drawspace_pylist = PyList_New(0);
BPy_Set_DrawButtonsList(some_drawspace_pylist);
Also, BPy_Free_DrawButtonsList() must be called as necassary when a drawspace
with python callbacks is destroyed.
This is necassary to avoid blender buttons storing invalid pointers to freed
python data.*/
// void BPy_Set_DrawButtonsList(void *list);
// void BPy_Free_DrawButtonsList(void);
//
void BPY_pyconstraint_eval(struct bPythonConstraint *con, struct bConstraintOb *cob, struct ListBase *targets);
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_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_start_python( int argc, char **argv );
void BPY_end_python( void );
void BPY_python_start( int argc, char **argv );
void BPY_python_end( void );
// void init_syspath( int first_time );
// void syspath_append( char *dir );
// void BPY_rebuild_syspath( void );
@@ -90,55 +69,23 @@ extern "C" {
//
// int BPY_Err_getLinenumber( void );
// const char *BPY_Err_getFilename( void );
//
// int BPY_txt_do_python_Text( struct Text *text );
// int BPY_menu_do_python( short menutype, int event );
// int BPY_menu_do_shortcut( short menutype, unsigned short key, unsigned short modifiers );
// int BPY_menu_invoke( struct BPyMenu *pym, short menutype );
/* 2.5 UI Scripts */
int BPY_run_python_script( struct bContext *C, const char *filename, struct Text *text, struct ReportList *reports ); // 2.5 working
int BPY_run_script_space_draw(const struct bContext *C, struct SpaceScript * sc); // 2.5 working
// int BPY_run_script_space_listener(struct bContext *C, struct SpaceScript * sc, struct ARegion *ar, struct wmNotifier *wmn); // 2.5 working
void BPY_update_modules(struct bContext *C); // XXX - annoying, need this for pointers that get out of date
//
int BPY_context_get(struct bContext *C, const char *member, struct bContextDataResult *result);
//
// int BPY_run_script(struct Script *script);
void BPY_free_compiled_text( struct Text *text );
//
// int BPY_has_onload_script( void );
//
// int BPY_is_spacehandler(struct Text *text, char spacetype);
// int BPY_del_spacehandler(struct Text *text, struct ScrArea *sa);
// int BPY_add_spacehandler(struct Text *txt, struct ScrArea *sa,char spacetype);
// int BPY_has_spacehandler(struct Text *text, struct ScrArea *sa);
// void BPY_screen_free_spacehandlers(struct bScreen *sc);
// int BPY_do_spacehandlers(struct ScrArea *sa, unsigned short event,
// short eventValue, unsigned short space_event);
//
void BPY_reset_driver(void);
float BPY_eval_driver(struct ChannelDriver *driver);
//
int BPY_eval_button(struct bContext *C, const char *expr, double *value);
int BPY_eval_string(struct bContext *C, const char *expr);
/* 2.5 UI Scripts */
int BPY_filepath_exec(struct bContext *C, const char *filepath, struct ReportList *reports);
int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports);
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);
/* format importer hook */
int BPY_call_importloader(const char *name);
//
// void BPY_spacescript_do_pywin_draw( struct SpaceScript *sc );
// void BPY_spacescript_do_pywin_event( struct SpaceScript *sc,
// unsigned short event, short val, char ascii );
// void BPY_free_finished_script( struct Script *script );
// void BPY_scripts_clear_pyobjects( void );
//
// void error_pyscript( void );
void BPY_DECREF(void *pyob_ptr); /* Py_DECREF() */
void BPY_set_context(struct bContext *C);
/* void BPY_Err_Handle(struct Text *text); */
/* int BPY_spacetext_is_pywin(struct SpaceText *st); */
void BPY_load_user_modules(struct bContext *C);
void BPY_driver_reset(void);
float BPY_driver_exec(struct ChannelDriver *driver);
int BPY_button_exec(struct bContext *C, const char *expr, double *value);
int BPY_string_exec(struct bContext *C, const char *expr);
void BPY_DECREF(void *pyob_ptr); /* Py_DECREF() */
int BPY_context_member_get(struct bContext *C, const char *member, struct bContextDataResult *result);
void BPY_context_set(struct bContext *C);
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -24,11 +24,13 @@
*/
#include "IDProp.h"
#include "MEM_guardedalloc.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_idprop.h"
#include "BKE_utildefines.h"
#include "BLI_string.h"
#include "MEM_guardedalloc.h"
#define USE_STRING_COERCE

View File

@@ -35,7 +35,9 @@
#include <GL/glew.h>
#include "MEM_guardedalloc.h"
#include "BKE_utildefines.h"
#include "BLI_utildefines.h"
static char Method_Buffer_doc[] =
"(type, dimensions, [template]) - Create a new Buffer object\n\n\

View File

@@ -26,7 +26,10 @@
#include "blf_py_api.h"
#include "../../blenfont/BLF_api.h"
#include "BKE_utildefines.h"
#include "BLI_utildefines.h"
static char py_blf_position_doc[] =
".. function:: position(fontid, x, y, z)\n"

View File

@@ -27,22 +27,26 @@
*/
#include <Python.h>
#include <stddef.h>
#include "compile.h" /* for the PyCodeObject */
#include "eval.h" /* for PyEval_EvalCode */
#include "bpy_internal_import.h"
#include "MEM_guardedalloc.h"
#include "DNA_text_types.h"
#include "MEM_guardedalloc.h"
#include "BKE_utildefines.h" /* UNUSED */
#include "BKE_text.h" /* txt_to_buf */
#include "BKE_main.h"
#include "BKE_global.h" /* grr, only for G.main->name */
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include <stddef.h>
#include "BLI_utildefines.h"
/* UNUSED */
#include "BKE_text.h" /* txt_to_buf */
#include "BKE_main.h"
#include "BKE_global.h" /* grr, only for G.main->name */
static Main *bpy_import_main= NULL;

View File

@@ -46,6 +46,7 @@
* - Vector.toTrackQuat --> Vector.to_track_quat
* - Quaternion * Quaternion --> cross product (not dot product)
* - Euler.rotate(angle, axis) --> Euler.rotate_axis(axis, angle)
* - Euler.unique() *removed*, not a standard function only toggled different rotations.
*
* moved into class functions.
* - Mathutils.RotationMatrix -> mathutils.Matrix.Rotation
@@ -72,8 +73,9 @@
#include "mathutils.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_utildefines.h"
//-------------------------DOC STRINGS ---------------------------
static char M_Mathutils_doc[] =

View File

@@ -25,7 +25,9 @@
#include "mathutils.h"
#include "BLI_math.h"
#include "BKE_utildefines.h"
#include "BLI_utildefines.h"
#define COLOR_SIZE 3

View File

@@ -29,7 +29,9 @@
#include "mathutils.h"
#include "BLI_math.h"
#include "BKE_utildefines.h"
#include "BLI_utildefines.h"
#ifndef int32_t
#include "BLO_sys_types.h"
@@ -155,65 +157,6 @@ static PyObject *Euler_ToMatrix(EulerObject * self)
return newMatrixObject(mat, 3, 3 , Py_NEW, NULL);
}
//sets the x,y,z values to a unique euler rotation
// TODO, check if this works with rotation order!!!
static char Euler_Unique_doc[] =
".. method:: unique()\n"
"\n"
" Calculate a unique rotation for this euler. Avoids gimble lock.\n"
"\n"
" :return: an instance of itself\n"
" :rtype: :class:`Euler`\n";
static PyObject *Euler_Unique(EulerObject * self)
{
#define PI_2 (Py_PI * 2.0)
#define PI_HALF (Py_PI / 2.0)
#define PI_INV (1.0 / Py_PI)
double heading, pitch, bank;
if(!BaseMath_ReadCallback(self))
return NULL;
heading = self->eul[0];
pitch = self->eul[1];
bank = self->eul[2];
//wrap heading in +180 / -180
pitch += Py_PI;
pitch -= floor(pitch * PI_INV) * PI_2;
pitch -= Py_PI;
if(pitch < -PI_HALF) {
pitch = -Py_PI - pitch;
heading += Py_PI;
bank += Py_PI;
} else if(pitch > PI_HALF) {
pitch = Py_PI - pitch;
heading += Py_PI;
bank += Py_PI;
}
//gimbal lock test
if(fabs(pitch) > PI_HALF - 1e-4) {
heading += bank;
bank = 0.0f;
} else {
bank += Py_PI;
bank -= (floor(bank * PI_INV)) * PI_2;
bank -= Py_PI;
}
heading += Py_PI;
heading -= (floor(heading * PI_INV)) * PI_2;
heading -= Py_PI;
(void)BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
//sets the euler to 0,0,0
static char Euler_Zero_doc[] =
".. method:: zero()\n"
@@ -629,7 +572,6 @@ static PyGetSetDef Euler_getseters[] = {
//-----------------------METHOD DEFINITIONS ----------------------
static struct PyMethodDef Euler_methods[] = {
{"zero", (PyCFunction) Euler_Zero, METH_NOARGS, Euler_Zero_doc},
{"unique", (PyCFunction) Euler_Unique, METH_NOARGS, Euler_Unique_doc},
{"to_matrix", (PyCFunction) Euler_ToMatrix, METH_NOARGS, Euler_ToMatrix_doc},
{"to_quat", (PyCFunction) Euler_ToQuat, METH_NOARGS, Euler_ToQuat_doc},
{"rotate_axis", (PyCFunction) Euler_rotate_axis, METH_VARARGS, Euler_rotate_axis_doc},

View File

@@ -30,14 +30,16 @@
#include "mathutils_geometry.h"
/* Used for PolyFill */
#include "BKE_displist.h"
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BKE_utildefines.h"
#include "BKE_curve.h"
#include "BLI_boxpack2d.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_displist.h"
#include "BKE_curve.h"
#define SWAP_FLOAT(a,b,tmp) tmp=a; a=b; b=tmp
#define eps 0.000001
@@ -75,11 +77,11 @@ static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject*
float det, inv_det, u, v, t;
int clip= 1;
if(!PyArg_ParseTuple(args, "intersect_ray_tri:O!O!O!O!O!|i", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &ray, &vector_Type, &ray_off , &clip)) {
if(!PyArg_ParseTuple(args, "O!O!O!O!O!|i:intersect_ray_tri", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &ray, &vector_Type, &ray_off , &clip)) {
return NULL;
}
if(vec1->size != 3 || vec2->size != 3 || vec3->size != 3 || ray->size != 3 || ray_off->size != 3) {
PyErr_SetString(PyExc_TypeError, "only 3D vectors for all parameters");
PyErr_SetString(PyExc_ValueError, "only 3D vectors for all parameters");
return NULL;
}
@@ -162,11 +164,11 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject
VectorObject *vec1, *vec2, *vec3, *vec4;
float v1[3], v2[3], v3[3], v4[3], i1[3], i2[3];
if(!PyArg_ParseTuple(args, "intersect_line_line:O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4)) {
if(!PyArg_ParseTuple(args, "O!O!O!O!:intersect_line_line", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4)) {
return NULL;
}
if(vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) {
PyErr_SetString(PyExc_TypeError,"vectors must be of the same size");
PyErr_SetString(PyExc_ValueError,"vectors must be of the same size");
return NULL;
}
@@ -214,7 +216,7 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject
}
}
else {
PyErr_SetString(PyExc_TypeError, "2D/3D vectors only");
PyErr_SetString(PyExc_ValueError, "2D/3D vectors only");
return NULL;
}
}
@@ -244,15 +246,15 @@ static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject* args)
float n[3];
if(PyTuple_GET_SIZE(args) == 3) {
if(!PyArg_ParseTuple(args, "normal:O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3)) {
if(!PyArg_ParseTuple(args, "O!O!O!:normal", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3)) {
return NULL;
}
if(vec1->size != vec2->size || vec1->size != vec3->size) {
PyErr_SetString(PyExc_TypeError, "vectors must be of the same size");
PyErr_SetString(PyExc_ValueError, "vectors must be of the same size");
return NULL;
}
if(vec1->size < 3) {
PyErr_SetString(PyExc_TypeError, "2D vectors unsupported");
PyErr_SetString(PyExc_ValueError, "2D vectors unsupported");
return NULL;
}
@@ -262,15 +264,15 @@ static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject* args)
normal_tri_v3(n, vec1->vec, vec2->vec, vec3->vec);
}
else {
if(!PyArg_ParseTuple(args, "normal:O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4)) {
if(!PyArg_ParseTuple(args, "O!O!O!O!:normal", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4)) {
return NULL;
}
if(vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size) {
PyErr_SetString(PyExc_TypeError,"vectors must be of the same size");
PyErr_SetString(PyExc_ValueError,"vectors must be of the same size");
return NULL;
}
if(vec1->size < 3) {
PyErr_SetString(PyExc_TypeError, "2D vectors unsupported");
PyErr_SetString(PyExc_ValueError, "2D vectors unsupported");
return NULL;
}
@@ -302,12 +304,12 @@ static PyObject *M_Geometry_area_tri(PyObject *UNUSED(self), PyObject* args)
{
VectorObject *vec1, *vec2, *vec3;
if(!PyArg_ParseTuple(args, "area_tri:O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3)) {
if(!PyArg_ParseTuple(args, "O!O!O!:area_tri", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3)) {
return NULL;
}
if(vec1->size != vec2->size || vec1->size != vec3->size) {
PyErr_SetString(PyExc_TypeError, "vectors must be of the same size");
PyErr_SetString(PyExc_ValueError, "vectors must be of the same size");
return NULL;
}
@@ -321,7 +323,7 @@ static PyObject *M_Geometry_area_tri(PyObject *UNUSED(self), PyObject* args)
return PyFloat_FromDouble(area_tri_v2(vec1->vec, vec2->vec, vec3->vec));
}
else {
PyErr_SetString(PyExc_TypeError, "only 2D,3D vectors are supported");
PyErr_SetString(PyExc_ValueError, "only 2D,3D vectors are supported");
return NULL;
}
}
@@ -466,7 +468,7 @@ static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObj
{
VectorObject *line_a1, *line_a2, *line_b1, *line_b2;
float vi[2];
if(!PyArg_ParseTuple (args, "intersect_line_line_2d:O!O!O!O!",
if(!PyArg_ParseTuple(args, "O!O!O!O!:intersect_line_line_2d",
&vector_Type, &line_a1,
&vector_Type, &line_a2,
&vector_Type, &line_b1,
@@ -506,7 +508,7 @@ static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObjec
float lambda;
PyObject *ret;
if(!PyArg_ParseTuple (args, "intersect_point_line:O!O!O!",
if(!PyArg_ParseTuple(args, "O!O!O!:intersect_point_line",
&vector_Type, &pt,
&vector_Type, &line_1,
&vector_Type, &line_2)
@@ -555,7 +557,7 @@ static PyObject *M_Geometry_intersect_point_tri_2d(PyObject *UNUSED(self), PyObj
{
VectorObject *pt_vec, *tri_p1, *tri_p2, *tri_p3;
if(!PyArg_ParseTuple (args, "intersect_point_tri_2d:O!O!O!O!",
if(!PyArg_ParseTuple(args, "O!O!O!O!:intersect_point_tri_2d",
&vector_Type, &pt_vec,
&vector_Type, &tri_p1,
&vector_Type, &tri_p2,
@@ -591,7 +593,7 @@ static PyObject *M_Geometry_intersect_point_quad_2d(PyObject *UNUSED(self), PyOb
{
VectorObject *pt_vec, *quad_p1, *quad_p2, *quad_p3, *quad_p4;
if(!PyArg_ParseTuple (args, "intersect_point_quad_2d:O!O!O!O!O!",
if(!PyArg_ParseTuple(args, "O!O!O!O!O!:intersect_point_quad_2d",
&vector_Type, &pt_vec,
&vector_Type, &quad_p1,
&vector_Type, &quad_p2,
@@ -616,7 +618,7 @@ static int boxPack_FromPyObject(PyObject *value, boxPack **boxarray)
/* Error checking must already be done */
if(!PyList_Check(value)) {
PyErr_SetString(PyExc_TypeError, "can only back a list of [x,y,x,w]");
PyErr_SetString(PyExc_TypeError, "can only back a list of [x, y, w, h]");
return -1;
}
@@ -629,7 +631,7 @@ static int boxPack_FromPyObject(PyObject *value, boxPack **boxarray)
list_item= PyList_GET_ITEM(value, i);
if(!PyList_Check(list_item) || PyList_Size(list_item) < 4) {
MEM_freeN(*boxarray);
PyErr_SetString(PyExc_TypeError, "can only back a list of [x,y,x,w]");
PyErr_SetString(PyExc_TypeError, "can only pack a list of [x, y, w, h]");
return -1;
}
@@ -638,15 +640,16 @@ static int boxPack_FromPyObject(PyObject *value, boxPack **boxarray)
item_1= PyList_GET_ITEM(list_item, 2);
item_2= PyList_GET_ITEM(list_item, 3);
if (!PyNumber_Check(item_1) || !PyNumber_Check(item_2)) {
MEM_freeN(*boxarray);
PyErr_SetString(PyExc_TypeError, "can only back a list of 2d boxes [x,y,x,w]");
return -1;
}
box->w= (float)PyFloat_AsDouble(item_1);
box->h= (float)PyFloat_AsDouble(item_2);
box->index= i;
if (box->w < 0.0f || box->h < 0.0f) {
MEM_freeN(*boxarray);
PyErr_SetString(PyExc_TypeError, "error parsing width and height values from list: [x, y, w, h], not numbers or below zero");
return -1;
}
/* verts will be added later */
}
return 0;
@@ -743,19 +746,23 @@ static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject*
float h2[4]= {0.0, 0.0, 0.0, 0.0};
if(!PyArg_ParseTuple (args, "O!O!O!O!i",
if(!PyArg_ParseTuple(args, "O!O!O!O!i:interpolate_bezier",
&vector_Type, &vec_k1,
&vector_Type, &vec_h1,
&vector_Type, &vec_h2,
&vector_Type, &vec_k2, &resolu) || (resolu<=1)
&vector_Type, &vec_k2, &resolu)
) {
PyErr_SetString(PyExc_TypeError, "expected 4 vector types and an int greater then 1");
return NULL;
}
if(resolu <= 1) {
PyErr_SetString(PyExc_ValueError, "resolution must be 2 or over");
return NULL;
}
if(!BaseMath_ReadCallback(vec_k1) || !BaseMath_ReadCallback(vec_h1) || !BaseMath_ReadCallback(vec_k2) || !BaseMath_ReadCallback(vec_h2))
return NULL;
dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);
for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i];
@@ -806,25 +813,30 @@ static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObje
VectorObject *vec_t1_src, *vec_t2_src, *vec_t3_src;
float vec[3];
if(!PyArg_ParseTuple (args, "O!O!O!O!O!O!O!",
if(!PyArg_ParseTuple(args, "O!O!O!O!O!O!O!:barycentric_transform",
&vector_Type, &vec_pt,
&vector_Type, &vec_t1_src,
&vector_Type, &vec_t2_src,
&vector_Type, &vec_t3_src,
&vector_Type, &vec_t1_tar,
&vector_Type, &vec_t2_tar,
&vector_Type, &vec_t3_tar) ||(vec_pt->size != 3 ||
vec_t1_src->size != 3 ||
vec_t2_src->size != 3 ||
vec_t3_src->size != 3 ||
vec_t1_tar->size != 3 ||
vec_t2_tar->size != 3 ||
vec_t3_tar->size != 3)
&vector_Type, &vec_t3_tar)
) {
PyErr_SetString(PyExc_TypeError, "expected 7, 3D vector types");
return NULL;
}
if( vec_pt->size != 3 ||
vec_t1_src->size != 3 ||
vec_t2_src->size != 3 ||
vec_t3_src->size != 3 ||
vec_t1_tar->size != 3 ||
vec_t2_tar->size != 3 ||
vec_t3_tar->size != 3)
{
PyErr_SetString(PyExc_ValueError, "One of more of the vector arguments wasnt a 3D vector");
return NULL;
}
barycentric_transform(vec, vec_pt->vec,
vec_t1_tar->vec, vec_t2_tar->vec, vec_t3_tar->vec,
vec_t1_src->vec, vec_t2_src->vec, vec_t3_src->vec);

View File

@@ -27,9 +27,11 @@
#include "mathutils.h"
#include "BKE_utildefines.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
/* matrix vector callbacks */
int mathutils_matrix_vector_cb_index= -1;
@@ -848,10 +850,8 @@ static char Matrix_TranslationPart_doc[] =
" Return a the translation part of a 4 row matrix.\n"
"\n"
" :return: Return a the translation of a matrix.\n"
" :rtype: :class:`Matrix`\n"
"\n"
" .. note:: Note that the (4,4) element of a matrix can be used for uniform scaling too.\n";
" :rtype: :class:`Vector`\n"
;
PyObject *Matrix_TranslationPart(MatrixObject * self)
{
if(!BaseMath_ReadCallback(self))
@@ -1243,7 +1243,7 @@ static PyObject *Matrix_repr(MatrixObject * self)
return NULL;
for(x = 0; x < self->rowSize; x++){
rows[x]= PyTuple_New(self->rowSize);
rows[x]= PyTuple_New(self->colSize);
for(y = 0; y < self->colSize; y++) {
PyTuple_SET_ITEM(rows[x], y, PyFloat_FromDouble(self->matrix[x][y]));
}
@@ -1342,57 +1342,29 @@ static PyObject *Matrix_item(MatrixObject * self, int i)
return newVectorObject_cb((PyObject *)self, self->colSize, mathutils_matrix_vector_cb_index, i);
}
/*----------------------------object[]-------------------------
sequence accessor (set)*/
static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob)
{
int y, x, size = 0;
float vec[4];
PyObject *m, *f;
sequence accessor (set) */
static int Matrix_ass_item(MatrixObject *self, int i, PyObject *value)
{
float vec[4];
if(!BaseMath_ReadCallback(self))
return -1;
if(i >= self->rowSize || i < 0){
PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad column");
return -1;
}
if(PySequence_Check(ob)){
size = PySequence_Length(ob);
if(size != self->colSize){
PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad sequence size");
return -1;
}
for (x = 0; x < size; x++) {
m = PySequence_GetItem(ob, x);
if (m == NULL) { /*Failed to read sequence*/
PyErr_SetString(PyExc_RuntimeError, "matrix[attribute] = x: unable to read sequence");
return -1;
}
f = PyNumber_Float(m);
if(f == NULL) { /*parsed item not a number*/
Py_DECREF(m);
PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: sequence argument not a number");
return -1;
}
vec[x] = (float)PyFloat_AS_DOUBLE(f);
Py_DECREF(m);
Py_DECREF(f);
}
/*parsed well - now set in matrix*/
for(y = 0; y < size; y++){
self->matrix[i][y] = vec[y];
}
(void)BaseMath_WriteCallback(self);
return 0;
}else{
PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: expects a sequence of column size");
if(mathutils_array_parse(vec, self->colSize, self->colSize, value, "matrix[i] = value assignment") < 0) {
return -1;
}
memcpy(self->matrix[i], vec, self->colSize * sizeof(float));
(void)BaseMath_WriteCallback(self);
return 0;
}
/*----------------------------object[z:y]------------------------
sequence slice (get)*/
static PyObject *Matrix_slice(MatrixObject * self, int begin, int end)
@@ -1419,12 +1391,9 @@ static PyObject *Matrix_slice(MatrixObject * self, int begin, int end)
}
/*----------------------------object[z:y]------------------------
sequence slice (set)*/
static int Matrix_ass_slice(MatrixObject * self, int begin, int end, PyObject * seq)
static int Matrix_ass_slice(MatrixObject * self, int begin, int end, PyObject *value)
{
int i, x, y, size, sub_size = 0;
float mat[16], f;
PyObject *subseq;
PyObject *m;
PyObject *value_fast= NULL;
if(!BaseMath_ReadCallback(self))
return -1;
@@ -1433,74 +1402,46 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end, PyObject *
CLAMP(end, 0, self->rowSize);
begin = MIN2(begin,end);
if(PySequence_Check(seq)){
size = PySequence_Length(seq);
if(size != (end - begin)){
/* non list/tuple cases */
if(!(value_fast=PySequence_Fast(value, "matrix[begin:end] = value"))) {
/* PySequence_Fast sets the error */
return -1;
}
else {
const int size= end - begin;
int i;
float mat[16];
if(PySequence_Fast_GET_SIZE(value_fast) != size) {
Py_DECREF(value_fast);
PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: size mismatch in slice assignment");
return -1;
}
/*parse sub items*/
for (i = 0; i < size; i++) {
/*parse each sub sequence*/
subseq = PySequence_GetItem(seq, i);
if (subseq == NULL) { /*Failed to read sequence*/
PyErr_SetString(PyExc_RuntimeError, "matrix[begin:end] = []: unable to read sequence");
PyObject *item= PySequence_Fast_GET_ITEM(value_fast, i);
if(mathutils_array_parse(&mat[i * self->colSize], self->colSize, self->colSize, item, "matrix[begin:end] = value assignment") < 0) {
return -1;
}
if(PySequence_Check(subseq)){
/*subsequence is also a sequence*/
sub_size = PySequence_Length(subseq);
if(sub_size != self->colSize){
Py_DECREF(subseq);
PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: size mismatch in slice assignment");
return -1;
}
for (y = 0; y < sub_size; y++) {
m = PySequence_GetItem(subseq, y);
if (m == NULL) { /*Failed to read sequence*/
Py_DECREF(subseq);
PyErr_SetString(PyExc_RuntimeError, "matrix[begin:end] = []: unable to read sequence");
return -1;
}
f = PyFloat_AsDouble(m); /* faster to assume a float and raise an error after */
if(f == -1 && PyErr_Occurred()) { /*parsed item not a number*/
Py_DECREF(m);
Py_DECREF(subseq);
PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: sequence argument not a number");
return -1;
}
mat[(i * self->colSize) + y] = f;
Py_DECREF(m);
}
}else{
Py_DECREF(subseq);
PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: illegal argument type for built-in operation");
return -1;
}
Py_DECREF(subseq);
}
Py_DECREF(value_fast);
/*parsed well - now set in matrix*/
for(x = 0; x < (size * sub_size); x++){
self->matrix[begin + (int)floor(x / self->colSize)][x % self->colSize] = mat[x];
}
memcpy(self->contigPtr + (begin * self->colSize), mat, sizeof(float) * (size * self->colSize));
(void)BaseMath_WriteCallback(self);
return 0;
}else{
PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: illegal argument type for built-in operation");
return -1;
}
}
/*------------------------NUMERIC PROTOCOLS----------------------
------------------------obj + obj------------------------------*/
static PyObject *Matrix_add(PyObject * m1, PyObject * m2)
{
int x, y;
float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
float mat[16];
MatrixObject *mat1 = NULL, *mat2 = NULL;
mat1 = (MatrixObject*)m1;
@@ -1519,21 +1460,15 @@ static PyObject *Matrix_add(PyObject * m1, PyObject * m2)
return NULL;
}
for(x = 0; x < mat1->rowSize; x++) {
for(y = 0; y < mat1->colSize; y++) {
mat[((x * mat1->colSize) + y)] = mat1->matrix[x][y] + mat2->matrix[x][y];
}
}
add_vn_vnvn(mat, mat1->contigPtr, mat2->contigPtr, mat1->rowSize * mat1->colSize);
return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, NULL);
return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, Py_TYPE(mat1));
}
/*------------------------obj - obj------------------------------
subtraction*/
static PyObject *Matrix_sub(PyObject * m1, PyObject * m2)
{
int x, y;
float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
float mat[16];
MatrixObject *mat1 = NULL, *mat2 = NULL;
mat1 = (MatrixObject*)m1;
@@ -1552,23 +1487,23 @@ static PyObject *Matrix_sub(PyObject * m1, PyObject * m2)
return NULL;
}
for(x = 0; x < mat1->rowSize; x++) {
for(y = 0; y < mat1->colSize; y++) {
mat[((x * mat1->colSize) + y)] = mat1->matrix[x][y] - mat2->matrix[x][y];
}
}
sub_vn_vnvn(mat, mat1->contigPtr, mat2->contigPtr, mat1->rowSize * mat1->colSize);
return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, NULL);
return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, Py_TYPE(mat1));
}
/*------------------------obj * obj------------------------------
mulplication*/
static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar)
{
float tmat[16];
mul_vn_vn_fl(tmat, mat->contigPtr, mat->rowSize * mat->colSize, scalar);
return newMatrixObject(tmat, mat->rowSize, mat->colSize, Py_NEW, Py_TYPE(mat));
}
static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
{
int x, y, z;
float scalar;
float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
double dot = 0.0f;
MatrixObject *mat1 = NULL, *mat2 = NULL;
if(MatrixObject_Check(m1)) {
@@ -1587,54 +1522,42 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
PyErr_SetString(PyExc_AttributeError,"Matrix multiplication: matrix A rowsize must equal matrix B colsize");
return NULL;
}
for(x = 0; x < mat2->rowSize; x++) {
for(y = 0; y < mat1->colSize; y++) {
for(z = 0; z < mat1->rowSize; z++) {
dot += (mat1->matrix[z][y] * mat2->matrix[x][z]);
}
mat[((x * mat1->colSize) + y)] = (float)dot;
dot = 0.0f;
}
}
return newMatrixObject(mat, mat2->rowSize, mat1->colSize, Py_NEW, Py_TYPE(mat1));
}
if(mat1==NULL){
scalar=PyFloat_AsDouble(m1); // may not be a float
if ((scalar == -1.0 && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX, this line annoys theeth, lets see if he finds it */
for(x = 0; x < mat2->rowSize; x++) {
for(y = 0; y < mat2->colSize; y++) {
mat[((x * mat2->colSize) + y)] = scalar * mat2->matrix[x][y];
}
}
return newMatrixObject(mat, mat2->rowSize, mat2->colSize, Py_NEW, Py_TYPE(mat2));
}
PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation");
return NULL;
}
else /* if(mat1) { */ {
if(VectorObject_Check(m2)) { /* MATRIX*VECTOR */
PyErr_SetString(PyExc_TypeError, "Matrix multiplication: Only 'vec * matrix' is supported, not the reverse");
return NULL;
}
else {
scalar= PyFloat_AsDouble(m2);
if ((scalar == -1.0 && PyErr_Occurred())==0) { /* MATRIX*FLOAT/INT */
for(x = 0; x < mat1->rowSize; x++) {
for(y = 0; y < mat1->colSize; y++) {
mat[((x * mat1->colSize) + y)] = scalar * mat1->matrix[x][y];
float mat[16]= {0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f};
double dot = 0.0f;
int x, y, z;
for(x = 0; x < mat2->rowSize; x++) {
for(y = 0; y < mat1->colSize; y++) {
for(z = 0; z < mat1->rowSize; z++) {
dot += (mat1->matrix[z][y] * mat2->matrix[x][z]);
}
mat[((x * mat1->colSize) + y)] = (float)dot;
dot = 0.0f;
}
return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, Py_TYPE(mat1));
}
return newMatrixObject(mat, mat2->rowSize, mat1->colSize, Py_NEW, Py_TYPE(mat1));
}
PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation");
return NULL;
}
else if(mat2) {
if (((scalar= PyFloat_AsDouble(m1)) == -1.0 && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX */
return matrix_mul_float(mat2, scalar);
}
}
else if(mat1) {
if (((scalar= PyFloat_AsDouble(m2)) == -1.0 && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX */
return matrix_mul_float(mat1, scalar);
}
}
else {
BKE_assert(!"internal error");
}
PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation");
PyErr_Format(PyExc_TypeError, "Matrix multiplication: not supported between '%.200s' and '%.200s' types", Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name);
return NULL;
}
static PyObject* Matrix_inv(MatrixObject *self)
@@ -1651,9 +1574,9 @@ static PySequenceMethods Matrix_SeqMethods = {
(binaryfunc) NULL, /* sq_concat */
(ssizeargfunc) NULL, /* sq_repeat */
(ssizeargfunc) Matrix_item, /* sq_item */
(ssizessizeargfunc) Matrix_slice, /* sq_slice, deprecated TODO, replace */
(ssizessizeargfunc) NULL, /* sq_slice, deprecated */
(ssizeobjargproc) Matrix_ass_item, /* sq_ass_item */
(ssizessizeobjargproc) Matrix_ass_slice, /* sq_ass_slice, deprecated TODO, replace */
(ssizessizeobjargproc) NULL, /* sq_ass_slice, deprecated */
(objobjproc) NULL, /* sq_contains */
(binaryfunc) NULL, /* sq_inplace_concat */
(ssizeargfunc) NULL, /* sq_inplace_repeat */

View File

@@ -29,7 +29,9 @@
#include "mathutils.h"
#include "BLI_math.h"
#include "BKE_utildefines.h"
#include "BLI_utildefines.h"
#define QUAT_SIZE 4
@@ -639,6 +641,15 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2)
return newQuaternionObject(quat, Py_NEW, Py_TYPE(q1));
}
static PyObject *quat_mul_float(QuaternionObject *quat, const float scalar)
{
float tquat[4];
copy_qt_qt(tquat, quat->quat);
mul_qt_fl(tquat, scalar);
return newQuaternionObject(tquat, Py_NEW, Py_TYPE(quat));
}
//------------------------obj * obj------------------------------
//mulplication
static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
@@ -661,33 +672,22 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
mul_qt_qtqt(quat, quat1->quat, quat2->quat);
return newQuaternionObject(quat, Py_NEW, Py_TYPE(q1));
}
/* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */
if(!QuaternionObject_Check(q1)) {
scalar= PyFloat_AsDouble(q1);
if ((scalar == -1.0 && PyErr_Occurred())==0) { /* FLOAT*QUAT */
QUATCOPY(quat, quat2->quat);
mul_qt_fl(quat, scalar);
return newQuaternionObject(quat, Py_NEW, Py_TYPE(q2));
}
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: val * quat, val is not an acceptable type");
return NULL;
}
else { /* QUAT*SOMETHING */
if(VectorObject_Check(q2)){ /* QUAT*VEC */
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: Only 'vector * quaternion' is supported, not the reverse");
return NULL;
}
scalar= PyFloat_AsDouble(q2);
if ((scalar == -1.0 && PyErr_Occurred())==0) { /* QUAT*FLOAT */
QUATCOPY(quat, quat1->quat);
mul_qt_fl(quat, scalar);
return newQuaternionObject(quat, Py_NEW, Py_TYPE(q1));
else if(quat2) { /* FLOAT*QUAT */
if(((scalar= PyFloat_AsDouble(q1)) == -1.0 && PyErr_Occurred())==0) {
return quat_mul_float(quat2, scalar);
}
}
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: arguments not acceptable for this operation");
else if (quat1) { /* QUAT*FLOAT */
if((((scalar= PyFloat_AsDouble(q2)) == -1.0 && PyErr_Occurred())==0)) {
return quat_mul_float(quat1, scalar);
}
}
else {
BKE_assert(!"internal error");
}
PyErr_Format(PyExc_TypeError, "Quaternion multiplication: not supported between '%.200s' and '%.200s' types", Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
return NULL;
}

View File

@@ -28,8 +28,10 @@
#include "mathutils.h"
#include "BLI_blenlib.h"
#include "BKE_utildefines.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#define MAX_DIMENSIONS 4
/* Swizzle axes get packed into a single value that is used as a closure. Each
@@ -1045,6 +1047,17 @@ static int column_vector_multiplication(float *rvec, VectorObject* vec, MatrixOb
return 0;
}
static PyObject *vector_mul_float(VectorObject *vec, const float scalar)
{
float tvec[MAX_DIMENSIONS];
int i;
for(i = 0; i < vec->size; i++) {
tvec[i] = vec->vec[i] * scalar;
}
return newVectorObject(tvec, vec->size, Py_NEW, Py_TYPE(vec));
}
static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
{
VectorObject *vec1 = NULL, *vec2 = NULL;
@@ -1078,55 +1091,48 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
}
return PyFloat_FromDouble(dot);
}
/* swap so vec1 is always the vector */
/* note: it would seem from this code that the matrix multiplication below
* is communicative. however the matrix class will always handle the
* (matrix * vector) case so we can ignore it here.
* This is NOT so for Quaternions: TODO, check if communicative (vec * quat) is correct */
if (vec2) {
vec1= vec2;
v2= v1;
else if (vec1) {
if (MatrixObject_Check(v2)) {
/* VEC * MATRIX */
float tvec[MAX_DIMENSIONS];
if(!BaseMath_ReadCallback((MatrixObject *)v2))
return NULL;
if(column_vector_multiplication(tvec, vec1, (MatrixObject*)v2) == -1) {
return NULL;
}
return newVectorObject(tvec, vec1->size, Py_NEW, Py_TYPE(vec1));
}
else if (QuaternionObject_Check(v2)) {
/* VEC * QUAT */
QuaternionObject *quat2 = (QuaternionObject*)v2;
float tvec[3];
if(vec1->size != 3) {
PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported");
return NULL;
}
if(!BaseMath_ReadCallback(quat2)) {
return NULL;
}
copy_v3_v3(tvec, vec1->vec);
mul_qt_v3(quat2->quat, tvec);
return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(vec1));
}
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
return vector_mul_float(vec1, scalar);
}
}
else if (vec2) {
if (((scalar= PyFloat_AsDouble(v1)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
return vector_mul_float(vec2, scalar);
}
}
else {
BKE_assert(!"internal error");
}
if (MatrixObject_Check(v2)) {
/* VEC * MATRIX */
float tvec[MAX_DIMENSIONS];
if(!BaseMath_ReadCallback((MatrixObject *)v2))
return NULL;
if(column_vector_multiplication(tvec, vec1, (MatrixObject*)v2) == -1) {
return NULL;
}
return newVectorObject(tvec, vec1->size, Py_NEW, Py_TYPE(vec1));
} else if (QuaternionObject_Check(v2)) {
/* VEC * QUAT */
QuaternionObject *quat2 = (QuaternionObject*)v2;
float tvec[3];
if(vec1->size != 3) {
PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported");
return NULL;
}
if(!BaseMath_ReadCallback(quat2)) {
return NULL;
}
copy_v3_v3(tvec, vec1->vec);
mul_qt_v3(quat2->quat, tvec);
return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(vec1));
}
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
int i;
float vec[MAX_DIMENSIONS];
for(i = 0; i < vec1->size; i++) {
vec[i] = vec1->vec[i] * scalar;
}
return newVectorObject(vec, vec1->size, Py_NEW, Py_TYPE(vec1));
}
PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation");
PyErr_Format(PyExc_TypeError, "Vector multiplication: not supported between '%.200s' and '%.200s' types", Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
return NULL;
}

View File

@@ -38,9 +38,11 @@
#include "structseq.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "DNA_texture_types.h"
#include "BKE_utildefines.h"
/*-----------------------------------------*/
/* 'mersenne twister' random number generator */

View File

@@ -35,8 +35,9 @@
#include "BLI_path_util.h"
#include "BLI_bpath.h"
#include "BLI_utildefines.h"
#include "BKE_utildefines.h"
#include "BKE_global.h" /* XXX, G.main only */
#include "MEM_guardedalloc.h"

View File

@@ -25,8 +25,9 @@
#include "bpy_app.h"
#include "BLI_path_util.h"
#include "BLI_utildefines.h"
#include "BKE_utildefines.h"
#include "BKE_blender.h"
#include "BKE_global.h"
#include "structseq.h"

View File

@@ -69,41 +69,15 @@ int bpy_pydriver_create_dict(void)
Py_DECREF(mod);
}
#if 0 // non existant yet
mod = PyImport_ImportModule("Blender.Noise");
if (mod) {
PyDict_SetItemString(d, "noise", mod);
PyDict_SetItemString(d, "n", mod);
Py_DECREF(mod);
} else {
PyErr_Clear();
}
/* If there's a Blender text called pydrivers.py, import it.
* Users can add their own functions to this module.
*/
if (G.f & G_SCRIPT_AUTOEXEC) {
mod = importText("pydrivers"); /* can also use PyImport_Import() */
if (mod) {
PyDict_SetItemString(d, "pydrivers", mod);
PyDict_SetItemString(d, "p", mod);
Py_DECREF(mod);
} else {
PyErr_Clear();
}
}
#endif // non existant yet
return 0;
}
/* Update function, it gets rid of pydrivers global dictionary, forcing
* BPY_eval_driver to recreate it. This function is used to force
* BPY_driver_exec to recreate it. This function is used to force
* reloading the Blender text module "pydrivers.py", if available, so
* updates in it reach pydriver evaluation.
*/
void BPY_reset_driver(void)
void BPY_driver_reset(void)
{
PyGILState_STATE gilstate;
int use_gil= 1; // (PyThreadState_Get()==NULL);
@@ -124,7 +98,7 @@ void BPY_reset_driver(void)
}
/* error return function for BPY_eval_pydriver */
static float pydriver_error(ChannelDriver *driver)
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);
@@ -132,8 +106,6 @@ static float pydriver_error(ChannelDriver *driver)
// BPy_errors_to_report(NULL); // TODO - reports
PyErr_Print();
PyErr_Clear();
return 0.0f;
}
/* This evals py driver expressions, 'expr' is a Python expression that
@@ -143,7 +115,7 @@ static float pydriver_error(ChannelDriver *driver)
* bake operator which intern starts a thread which calls scene update which
* does a driver update. to avoid a deadlock check PyThreadState_Get() if PyGILState_Ensure() is needed.
*/
float BPY_eval_driver (ChannelDriver *driver)
float BPY_driver_exec(ChannelDriver *driver)
{
PyObject *driver_vars=NULL;
PyObject *retval= NULL;
@@ -232,15 +204,15 @@ float BPY_eval_driver (ChannelDriver *driver)
/* 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)) { /* use string interning for faster namespace creation */
if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) < 0) { /* use string interning for faster namespace creation */
/* this target failed - bad name */
if (targets_ok) {
/* first one - print some extra info for easier identification */
fprintf(stderr, "\nBPY_eval_driver() - Error while evaluating PyDriver:\n");
fprintf(stderr, "\nBPY_driver_eval() - Error while evaluating PyDriver:\n");
targets_ok= 0;
}
fprintf(stderr, "\tBPY_eval_driver() - couldn't add variable '%s' to namespace\n", dvar->name);
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();
@@ -280,7 +252,7 @@ float BPY_eval_driver (ChannelDriver *driver)
return (float)result;
}
else {
fprintf(stderr, "\tBPY_eval_driver() - driver '%s' evaluates to '%f'\n", dvar->name, result);
fprintf(stderr, "\tBPY_driver_eval() - driver '%s' evaluates to '%f'\n", dvar->name, result);
return 0.0f;
}
}

View File

@@ -30,6 +30,8 @@
#include <Python.h>
#include "MEM_guardedalloc.h"
#include "bpy.h"
#include "bpy_rna.h"
#include "bpy_util.h"
@@ -37,12 +39,12 @@
#include "DNA_space_types.h"
#include "DNA_text_types.h"
#include "MEM_guardedalloc.h"
#include "BLI_path_util.h"
#include "BLI_math_base.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_utildefines.h"
#include "BKE_context.h"
#include "BKE_text.h"
#include "BKE_font.h" /* only for utf8towchar */
@@ -88,7 +90,7 @@ void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
fprintf(stderr, "ERROR: Python context called with a NULL Context. this should not happen!\n");
}
BPY_update_modules(C); /* can give really bad results if this isnt here */
BPY_modules_update(C); /* can give really bad results if this isnt here */
#ifdef TIME_PY_RUN
if(bpy_timer_count==0) {
@@ -128,7 +130,7 @@ void bpy_context_clear(bContext *UNUSED(C), PyGILState_STATE *gilstate)
}
}
void BPY_free_compiled_text( struct Text *text )
void BPY_text_free_code(Text *text)
{
if( text->compiled ) {
Py_DECREF( ( PyObject * ) text->compiled );
@@ -136,7 +138,7 @@ void BPY_free_compiled_text( struct Text *text )
}
}
void BPY_update_modules(bContext *C)
void BPY_modules_update(bContext *C)
{
#if 0 // slow, this runs all the time poll, draw etc 100's of time a sec.
PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
@@ -150,7 +152,7 @@ void BPY_update_modules(bContext *C)
}
/* must be called before Py_Initialize */
void BPY_start_python_path(void)
void BPY_python_start_path(void)
{
char *py_path_bundle= BLI_get_folder(BLENDER_PYTHON, NULL);
@@ -191,7 +193,7 @@ void BPY_start_python_path(void)
void BPY_set_context(bContext *C)
void BPY_context_set(bContext *C)
{
BPy_SetContext(C);
}
@@ -214,8 +216,8 @@ static struct _inittab bpy_internal_modules[]= {
{NULL, NULL}
};
/* call BPY_set_context first */
void BPY_start_python( int argc, char **argv )
/* call BPY_context_set first */
void BPY_python_start( int argc, char **argv )
{
PyThreadState *py_tstate = NULL;
@@ -227,7 +229,7 @@ void BPY_start_python( int argc, char **argv )
/* builtin modules */
PyImport_ExtendInittab(bpy_internal_modules);
BPY_start_python_path(); /* allow to use our own included python */
BPY_python_start_path(); /* allow to use our own included python */
Py_Initialize( );
@@ -278,7 +280,7 @@ void BPY_start_python( int argc, char **argv )
PyEval_ReleaseThread(py_tstate);
}
void BPY_end_python( void )
void BPY_python_end(void)
{
// fprintf(stderr, "Ending Python!\n");
@@ -312,12 +314,13 @@ void BPY_end_python( void )
}
/* Can run a file or text block */
int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
{
PyObject *py_dict= NULL, *py_result= NULL;
PyGILState_STATE gilstate;
BKE_assert(fn || text);
if (fn==NULL && text==NULL) {
return 0;
}
@@ -327,7 +330,7 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
if (text) {
char fn_dummy[FILE_MAXDIR];
bpy_text_filename_get(fn_dummy, text);
if( !text->compiled ) { /* if it wasn't already compiled, do it now */
char *buf = txt_to_buf( text );
@@ -336,8 +339,8 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
MEM_freeN( buf );
if( PyErr_Occurred( ) ) {
BPY_free_compiled_text( text );
if(PyErr_Occurred()) {
BPY_text_free_code(text);
}
}
@@ -345,7 +348,7 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
py_dict = PyC_DefaultNameSpace(fn_dummy);
py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict);
}
}
else {
FILE *fp= fopen(fn, "r");
@@ -354,9 +357,9 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
py_dict = PyC_DefaultNameSpace(fn);
#ifdef _WIN32
/* Previously we used PyRun_File to run directly the code on a FILE
/* Previously we used PyRun_File to run directly the code on a FILE
* object, but as written in the Python/C API Ref Manual, chapter 2,
* 'FILE structs for different C libraries can be different and
* 'FILE structs for different C libraries can be different and
* incompatible'.
* So now we load the script file data to a buffer */
{
@@ -380,14 +383,14 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
py_result= NULL;
}
}
if (!py_result) {
BPy_errors_to_report(reports);
} else {
Py_DECREF( py_result );
}
/* super annoying, undo _PyModule_Clear() */
/* super annoying, undo _PyModule_Clear() */
#define PYMODULE_CLEAR_WORKAROUND
if(py_dict) {
@@ -405,92 +408,22 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
#endif
#undef PYMODULE_CLEAR_WORKAROUND
}
bpy_context_clear(C, &gilstate);
return py_result ? 1:0;
return (py_result != NULL);
}
/* Can run a file or text block */
int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports)
{
return python_script_exec(C, filepath, NULL, reports);
}
/* TODO - move into bpy_space.c ? */
/* GUI interface routines */
/* Copied from Draw.c */
static void exit_pydraw( SpaceScript * sc, short err )
int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports)
{
Script *script = NULL;
if( !sc || !sc->script )
return;
script = sc->script;
if( err ) {
BPy_errors_to_report(NULL); // TODO, reports
script->flags = 0; /* mark script struct for deletion */
SCRIPT_SET_NULL(script);
script->scriptname[0] = '\0';
script->scriptarg[0] = '\0';
// XXX 2.5 error_pyscript();
// XXX 2.5 scrarea_queue_redraw( sc->area );
}
#if 0 // XXX 2.5
BPy_Set_DrawButtonsList(sc->but_refs);
BPy_Free_DrawButtonsList(); /*clear all temp button references*/
#endif
sc->but_refs = NULL;
Py_XDECREF( ( PyObject * ) script->py_draw );
Py_XDECREF( ( PyObject * ) script->py_event );
Py_XDECREF( ( PyObject * ) script->py_button );
script->py_draw = script->py_event = script->py_button = NULL;
}
static int bpy_run_script_init(bContext *C, SpaceScript * sc)
{
if (sc->script==NULL)
return 0;
if (sc->script->py_draw==NULL && sc->script->scriptname[0] != '\0')
BPY_run_python_script(C, sc->script->scriptname, NULL, NULL);
if (sc->script->py_draw==NULL)
return 0;
return 1;
}
int BPY_run_script_space_draw(const struct bContext *C, SpaceScript * sc)
{
if (bpy_run_script_init( (bContext *)C, sc)) {
PyGILState_STATE gilstate = PyGILState_Ensure();
PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
if (result==NULL)
exit_pydraw(sc, 1);
PyGILState_Release(gilstate);
}
return 1;
}
// XXX - not used yet, listeners dont get a context
int BPY_run_script_space_listener(bContext *C, SpaceScript * sc)
{
if (bpy_run_script_init(C, sc)) {
PyGILState_STATE gilstate = PyGILState_Ensure();
PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
if (result==NULL)
exit_pydraw(sc, 1);
PyGILState_Release(gilstate);
}
return 1;
return python_script_exec(C, NULL, text, reports);
}
void BPY_DECREF(void *pyob_ptr)
@@ -500,57 +433,7 @@ void BPY_DECREF(void *pyob_ptr)
PyGILState_Release(gilstate);
}
#if 0
/* called from the the scripts window, assume context is ok */
int BPY_run_python_script_space(const char *modulename, const char *func)
{
PyObject *py_dict, *py_result= NULL;
char pystring[512];
PyGILState_STATE gilstate;
/* for calling the module function */
PyObject *py_func,
gilstate = PyGILState_Ensure();
py_dict = PyC_DefaultNameSpace("<dummy>");
PyObject *module = PyImport_ImportModule(scpt->script.filename);
if (module==NULL) {
PyErr_SetFormat(PyExc_SystemError, "could not import '%s'", scpt->script.filename);
}
else {
py_func = PyObject_GetAttrString(modulename, func);
if (py_func==NULL) {
PyErr_SetFormat(PyExc_SystemError, "module has no function '%s.%s'\n", scpt->script.filename, func);
}
else {
Py_DECREF(py_func);
if (!PyCallable_Check(py_func)) {
PyErr_SetFormat(PyExc_SystemError, "module item is not callable '%s.%s'\n", scpt->script.filename, func);
}
else {
py_result= PyObject_CallObject(py_func, NULL); // XXX will need args eventually
}
}
}
if (!py_result) {
BPy_errors_to_report(NULL); // TODO - reports
} else
Py_DECREF( py_result );
Py_XDECREF(module);
PyDict_SetItemString(PyThreadState_GET()->interp->modules, "__main__", Py_None);
PyGILState_Release(gilstate);
return 1;
}
#endif
int BPY_eval_button(bContext *C, const char *expr, double *value)
int BPY_button_exec(bContext *C, const char *expr, double *value)
{
PyGILState_STATE gilstate;
PyObject *py_dict, *mod, *retval;
@@ -622,7 +505,7 @@ int BPY_eval_button(bContext *C, const char *expr, double *value)
return error_ret;
}
int BPY_eval_string(bContext *C, const char *expr)
int BPY_string_exec(bContext *C, const char *expr)
{
PyGILState_STATE gilstate;
PyObject *py_dict, *retval;
@@ -657,7 +540,7 @@ int BPY_eval_string(bContext *C, const char *expr)
}
void BPY_load_user_modules(bContext *C)
void BPY_modules_load_user(bContext *C)
{
PyGILState_STATE gilstate;
Main *bmain= CTX_data_main(C);
@@ -690,7 +573,7 @@ void BPY_load_user_modules(bContext *C)
bpy_context_clear(C, &gilstate);
}
int BPY_context_get(bContext *C, const char *member, bContextDataResult *result)
int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result)
{
PyObject *pyctx= (PyObject *)CTX_py_dict_get(C);
PyObject *item= PyDict_GetItemString(pyctx, member);

View File

@@ -32,6 +32,8 @@
#include "bpy_rna.h" /* for setting arg props only - pyrna_py_to_prop() */
#include "bpy_util.h"
#include "BLI_utildefines.h"
#include "RNA_enum_types.h"
#include "WM_api.h"

View File

@@ -27,6 +27,8 @@
#include "WM_api.h"
#include "WM_types.h"
#include "BLI_utildefines.h"
#include "RNA_define.h"
#include "bpy_rna.h"

View File

@@ -26,7 +26,9 @@
#include "bpy_rna.h"
#include "bpy_util.h"
#include "BKE_utildefines.h"
#include "BLI_utildefines.h"
#include "RNA_define.h" /* for defining our own rna */
#include "RNA_enum_types.h"

View File

@@ -21,22 +21,23 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <float.h> /* FLT_MIN/MAX */
#include "bpy_rna.h"
#include "bpy_props.h"
#include "bpy_util.h"
#include "bpy_rna_callback.h"
//#include "blendef.h"
#include "BLI_dynstr.h"
#include "BLI_string.h"
#include "BLI_listbase.h"
#include "float.h" /* FLT_MIN/MAX */
#include "BLI_utildefines.h"
#include "RNA_enum_types.h"
#include "RNA_define.h" /* RNA_def_property_free_identifier */
#include "MEM_guardedalloc.h"
#include "BKE_utildefines.h"
#include "BKE_idcode.h"
#include "BKE_context.h"
#include "BKE_global.h" /* evil G.* */
@@ -57,6 +58,8 @@
#define USE_MATHUTILS
#define USE_STRING_COERCE
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
#ifdef USE_PEDANTIC_WRITE
static short rna_disallow_writes= FALSE;
@@ -91,7 +94,7 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item
#ifdef USE_MATHUTILS
#include "../generic/mathutils.h" /* so we can have mathutils callbacks */
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length);
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length);
static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback);
/* bpyrna vector/euler/quat callbacks */
@@ -1414,20 +1417,34 @@ static int pyrna_prop_collection_bool( BPy_PropertyRNA *self )
static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
{
PointerRNA newptr;
int len= RNA_property_collection_length(&self->ptr, self->prop);
Py_ssize_t keynum_abs= keynum;
if(keynum < 0) keynum += len;
/* notice getting the length of the collection is avoided unless negative index is used
* or to detect internal error with a valid index.
* This is done for faster lookups. */
if(keynum < 0) {
keynum_abs += RNA_property_collection_length(&self->ptr, self->prop);
if(keynum >= 0 && keynum < len) {
if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr)) {
return pyrna_struct_CreatePyObject(&newptr);
}
else { /* fail's if ptr.data == NULL, valid for mesh.materials */
Py_RETURN_NONE;
if(keynum_abs < 0) {
PyErr_Format(PyExc_IndexError, "bpy_prop_collection[%d]: out of range.", keynum);
return NULL;
}
}
PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d out of range, size %d", keynum, len);
return NULL;
if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
return pyrna_struct_CreatePyObject(&newptr);
}
else {
const int len= RNA_property_collection_length(&self->ptr, self->prop);
if(keynum_abs >= len) {
PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d out of range, size %d", keynum, len);
}
else {
PyErr_Format(PyExc_RuntimeError, "bpy_prop_collection[index]: internal error, valid index %d given in %d sized collection but value not found", keynum_abs, len);
}
return NULL;
}
}
static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
@@ -1454,26 +1471,37 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons
}
/* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
static PyObject *pyrna_prop_collection_subscript_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop)
static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
{
PointerRNA newptr;
PyObject *list = PyList_New(stop - start);
int count;
int count= 0;
start = MIN2(start,stop); /* values are clamped from */
PyObject *list= PyList_New(0);
PyObject *item;
for(count = start; count < stop; count++) {
if(RNA_property_collection_lookup_int(ptr, prop, count - start, &newptr)) {
PyList_SET_ITEM(list, count - start, pyrna_struct_CreatePyObject(&newptr));
/* first loop up-until the start */
CollectionPropertyIterator rna_macro_iter;
for(RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
/* PointerRNA itemptr= rna_macro_iter.ptr; */
if(count == start) {
break;
}
else {
Py_DECREF(list);
count++;
}
PyErr_SetString(PyExc_RuntimeError, "error getting an rna struct from a collection");
return NULL;
/* add items until stop */
for(; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
item= pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
PyList_Append(list, item);
Py_DECREF(item);
count++;
if(count == stop) {
break;
}
}
RNA_property_collection_end(&rna_macro_iter);
return list;
}
@@ -1481,7 +1509,7 @@ static PyObject *pyrna_prop_collection_subscript_slice(PointerRNA *ptr, Property
* note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower
* since at the moment it reads (and even allocates) the entire array for each index.
*/
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length)
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
{
int count, totdim;
@@ -1567,21 +1595,39 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
return pyrna_prop_collection_subscript_int(self, i);
}
else if (PySlice_Check(key)) {
int len= RNA_property_collection_length(&self->ptr, self->prop);
Py_ssize_t start, stop, step, slicelength;
PySliceObject *key_slice= (PySliceObject *)key;
Py_ssize_t step= 1;
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
if(key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
return NULL;
if (slicelength <= 0) {
return PyList_New(0);
}
else if (step == 1) {
return pyrna_prop_collection_subscript_slice(&self->ptr, self->prop, start, stop);
else if (step != 1) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
return NULL;
}
else if(key_slice->start == Py_None && key_slice->stop == Py_None) {
return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
}
else {
PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported with rna");
return NULL;
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;
if(start < 0 || stop < 0) {
/* only get the length for negative values */
Py_ssize_t len= (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
if(start < 0) start += len;
if(stop < 0) start += len;
}
if (stop - start <= 0) {
return PyList_New(0);
}
else {
return pyrna_prop_collection_subscript_slice(self, start, stop);
}
}
}
else {
@@ -1602,21 +1648,34 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject
return pyrna_prop_array_subscript_int(self, PyLong_AsLong(key));
}
else if (PySlice_Check(key)) {
Py_ssize_t start, stop, step, slicelength;
int len = pyrna_prop_array_length(self);
Py_ssize_t step= 1;
PySliceObject *key_slice= (PySliceObject *)key;
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
if(key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
return NULL;
if (slicelength <= 0) {
return PyList_New(0);
}
else if (step == 1) {
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
else if (step != 1) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
return NULL;
}
else if(key_slice->start == Py_None && key_slice->stop == Py_None) {
/* note, no significant advantage with optimizing [:] slice as with collections but include here for consistency with collection slice func */
Py_ssize_t len= (Py_ssize_t)pyrna_prop_array_length(self);
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
}
else {
PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported with rna");
return NULL;
int len= pyrna_prop_array_length(self);
Py_ssize_t start, stop, slicelength;
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
return NULL;
if (slicelength <= 0) {
return PyTuple_New(0);
}
else {
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
}
}
}
else {
@@ -3046,7 +3105,7 @@ static PyGetSetDef pyrna_struct_getseters[] = {
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
static PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self)
{
PyObject *ret= PyList_New(0);
PyObject *item;
@@ -3071,7 +3130,7 @@ static PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
return ret;
}
static PyObject *pyrna_prop_items(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self)
{
PyObject *ret= PyList_New(0);
PyObject *item;
@@ -3104,19 +3163,10 @@ static PyObject *pyrna_prop_items(BPy_PropertyRNA *self)
return ret;
}
static PyObject *pyrna_prop_values(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self)
{
PyObject *ret= PyList_New(0);
PyObject *item;
RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
item = pyrna_struct_CreatePyObject(&itemptr);
PyList_Append(ret, item);
Py_DECREF(item);
}
RNA_PROP_END;
return ret;
/* re-use slice*/
return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
}
static char pyrna_struct_get_doc[] =
@@ -3173,7 +3223,7 @@ static PyObject *pyrna_struct_as_pointer(BPy_StructRNA *self)
return PyLong_FromVoidPtr(self->ptr.data);
}
static PyObject *pyrna_prop_get(BPy_PropertyRNA *self, PyObject *args)
static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args)
{
PointerRNA newptr;
@@ -3209,7 +3259,7 @@ static void foreach_attr_type( BPy_PropertyRNA *self, char *attr,
RNA_PROP_END;
}
/* pyrna_prop_foreach_get/set both use this */
/* pyrna_prop_collection_foreach_get/set both use this */
static int foreach_parse_args(
BPy_PropertyRNA *self, PyObject *args,
@@ -3432,12 +3482,12 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
Py_RETURN_NONE;
}
static PyObject *pyrna_prop_foreach_get(BPy_PropertyRNA *self, PyObject *args)
static PyObject *pyrna_prop_collection_foreach_get(BPy_PropertyRNA *self, PyObject *args)
{
return foreach_getset(self, args, 0);
}
static PyObject *pyrna_prop_foreach_set(BPy_PropertyRNA *self, PyObject *args)
static PyObject *pyrna_prop_collection_foreach_set(BPy_PropertyRNA *self, PyObject *args)
{
return foreach_getset(self, args, 1);
}
@@ -3467,7 +3517,7 @@ PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
/* Try get values from a collection */
PyObject *ret;
PyObject *iter= NULL;
ret = pyrna_prop_values(self);
ret= pyrna_prop_collection_values(self);
/* we know this is a list so no need to PyIter_Check
* otherwise it could be NULL (unlikely) if conversion failed */
@@ -3518,14 +3568,14 @@ static struct PyMethodDef pyrna_prop_array_methods[] = {
};
static struct PyMethodDef pyrna_prop_collection_methods[] = {
{"foreach_get", (PyCFunction)pyrna_prop_foreach_get, METH_VARARGS, NULL},
{"foreach_set", (PyCFunction)pyrna_prop_foreach_set, METH_VARARGS, NULL},
{"foreach_get", (PyCFunction)pyrna_prop_collection_foreach_get, METH_VARARGS, NULL},
{"foreach_set", (PyCFunction)pyrna_prop_collection_foreach_set, METH_VARARGS, NULL},
{"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, NULL},
{"items", (PyCFunction)pyrna_prop_items, METH_NOARGS,NULL},
{"values", (PyCFunction)pyrna_prop_values, METH_NOARGS, NULL},
{"keys", (PyCFunction)pyrna_prop_collection_keys, METH_NOARGS, NULL},
{"items", (PyCFunction)pyrna_prop_collection_items, METH_NOARGS,NULL},
{"values", (PyCFunction)pyrna_prop_collection_values, METH_NOARGS, NULL},
{"get", (PyCFunction)pyrna_prop_get, METH_VARARGS, NULL},
{"get", (PyCFunction)pyrna_prop_collection_get, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL}
};
@@ -4796,7 +4846,7 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
PyObject *list, *name;
PyMethodDef *meth;
list= pyrna_prop_keys(self); /* like calling structs.keys(), avoids looping here */
list= pyrna_prop_collection_keys(self); /* like calling structs.keys(), avoids looping here */
for(meth=pyrna_basetype_methods; meth->ml_name; meth++) {
name = PyUnicode_FromString(meth->ml_name);
@@ -5176,7 +5226,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
return 0;
}
extern void BPY_update_modules(bContext *C); //XXX temp solution
extern void BPY_modules_update(bContext *C); //XXX temp solution
/* TODO - multiple return values like with rna functions */
static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
@@ -5416,12 +5466,13 @@ static void bpy_class_free(void *pyob_ptr)
if(PyErr_Occurred())
PyErr_Clear();
#if 0 /* needs further investigation, too annoying so quiet for now */
if(G.f&G_DEBUG) {
if(self->ob_refcnt > 1) {
PyC_ObSpit("zombie class - ref should be 1", self);
}
}
#endif
Py_DECREF((PyObject *)pyob_ptr);
PyGILState_Release(gilstate);
@@ -5541,7 +5592,10 @@ static PyObject *pyrna_basetype_register(PyObject *UNUSED(self), PyObject *py_cl
if(BPy_reports_to_error(&reports, TRUE))
return NULL;
BKE_assert(srna_new != NULL);
/* python errors validating are not converted into reports so the check above will fail.
* the cause for returning NULL will be printed as an error */
if(srna_new == NULL)
return NULL;
pyrna_subtype_set_rna(py_class, srna_new); /* takes a ref to py_class */

View File

@@ -26,8 +26,10 @@
#include "bpy_rna.h"
#include "bpy_util.h"
#include "BLI_utildefines.h"
#include "DNA_screen_types.h"
#include "BKE_utildefines.h"
#include "BKE_context.h"
#include "ED_space_api.h"

View File

@@ -27,11 +27,10 @@
*/
/* python, will come back */
//void BPY_run_python_script(void) {}
//void BPY_start_python(void) {}
void BPY_call_importloader(const char *filepath) {(void)filepath;}
//void BPY_free_compiled_text(void) {}
void BPY_pyconstraint_eval(void) {}
//void BPY_script_exec(void) {}
//void BPY_python_start(void) {}
//void BPY_text_free_code(void) {}
void BPY_pyconstraint_exec(void) {}
void BPY_pyconstraint_target(void) {}
int BPY_is_pyconstraint(void) {return 0;}
void BPY_pyconstraint_update(void) {}