Merged changes in the trunk up to revision 33765.

This commit is contained in:
2010-12-18 11:49:12 +00:00
469 changed files with 9113 additions and 11515 deletions

View File

@@ -100,7 +100,7 @@ extern "C" {
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( void ); // XXX - annoying, need this for pointers that get out of date
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);
//

View File

@@ -16,5 +16,5 @@
#
# ***** END GPL LICENSE BLOCK *****
ADD_SUBDIRECTORY(intern)
ADD_SUBDIRECTORY(generic)
add_subdirectory(intern)
add_subdirectory(generic)

View File

@@ -18,7 +18,7 @@
#
# ***** END GPL LICENSE BLOCK *****
SET(INC
set(INC
.
../../blenlib
../../makesdna
@@ -28,10 +28,10 @@ SET(INC
${PYTHON_INC}
)
SET(SRC
set(SRC
IDProp.c
bgl.c
blf_api.c
blf_py_api.c
bpy_internal_import.c
mathutils.c
mathutils_color.c
@@ -45,7 +45,7 @@ SET(SRC
IDProp.h
bgl.h
blf_api.h
blf_py_api.h
bpy_internal_import.h
mathutils.h
mathutils_color.h
@@ -57,4 +57,4 @@ SET(SRC
py_capi_utils.h
)
BLENDERLIB(bf_python_ext "${SRC}" "${INC}")
blenderlib(bf_python_ext "${SRC}" "${INC}")

View File

@@ -23,7 +23,7 @@
*/
#include <Python.h>
#include "blf_api.h"
#include "blf_py_api.h"
#include "../../blenfont/BLF_api.h"
#include "BKE_utildefines.h"
@@ -99,7 +99,7 @@ static PyObject *py_blf_aspect(PyObject *UNUSED(self), PyObject *args)
if (!PyArg_ParseTuple(args, "if:blf.aspect", &fontid, &aspect))
return NULL;
BLF_aspect(fontid, aspect);
BLF_aspect(fontid, aspect, aspect, 1.0);
Py_RETURN_NONE;
}
@@ -367,7 +367,7 @@ struct PyMethodDef BLF_methods[] = {
{"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},
{"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},

View File

@@ -45,18 +45,152 @@
/*-------------------------DOC STRINGS ---------------------------*/
static char M_Geometry_doc[] = "The Blender geometry module\n\n";
static char M_Geometry_Intersect_doc[] = "(v1, v2, v3, ray, orig, clip=1) - returns the intersection between a ray and a triangle, if possible, returns None otherwise";
static char M_Geometry_TriangleArea_doc[] = "(v1, v2, v3) - returns the area size of the 2D or 3D triangle defined";
static char M_Geometry_TriangleNormal_doc[] = "(v1, v2, v3) - returns the normal of the 3D triangle defined";
static char M_Geometry_QuadNormal_doc[] = "(v1, v2, v3, v4) - returns the normal of the 3D quad defined";
static char M_Geometry_LineIntersect_doc[] = "(v1, v2, v3, v4) - returns a tuple with the points on each line respectively closest to the other";
static char M_Geometry_PolyFill_doc[] = "(veclist_list) - takes a list of polylines (each point a vector) and returns the point indicies for a polyline filled with triangles";
static char M_Geometry_LineIntersect2D_doc[] = "(lineA_p1, lineA_p2, lineB_p1, lineB_p2) - takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None";
static char M_Geometry_ClosestPointOnLine_doc[] = "(pt, line_p1, line_p2) - takes a point and a line and returns a (Vector, float) for the point on the line, and the bool so you can know if the point was between the 2 points";
static char M_Geometry_PointInTriangle2D_doc[] = "(pt, tri_p1, tri_p2, tri_p3) - takes 4 vectors, one is the point and the next 3 define the triangle, only the x and y are used from the vectors";
static char M_Geometry_PointInQuad2D_doc[] = "(pt, quad_p1, quad_p2, quad_p3, quad_p4) - takes 5 vectors, one is the point and the next 4 define the quad, only the x and y are used from the vectors";
static char M_Geometry_Intersect_doc[] =
".. function:: Intersect(v1, v2, v3, ray, orig, clip=True)\n"
"\n"
" Returns the intersection between a ray and a triangle, if possible, returns None otherwise.\n"
"\n"
" :rtype: boolean\n"
" :arg v1: Point1\n"
" :type v1: :class:`mathutils.Vector`\n"
" :arg v2: Point2\n"
" :type v2: :class:`mathutils.Vector`\n"
" :arg v3: Point3\n"
" :type v3: :class:`mathutils.Vector`\n"
" :arg ray: Direction of the projection\n"
" :type ray: :class:`mathutils.Vector`\n"
" :arg orig: Origin\n"
" :type orig: :class:`mathutils.Vector`\n"
" :arg clip: Clip by the ray length\n"
" :type clip: boolean\n";
static char M_Geometry_TriangleArea_doc[] =
".. function:: TriangleArea(v1, v2, v3)\n"
"\n"
" Returns the area size of the 2D or 3D triangle defined.\n"
"\n"
" :rtype: float\n"
" :arg v1: Point1\n"
" :type v1: :class:`mathutils.Vector`\n"
" :arg v2: Point2\n"
" :type v2: :class:`mathutils.Vector`\n"
" :arg v3: Point3\n"
" :type v3: :class:`mathutils.Vector`\n";
static char M_Geometry_TriangleNormal_doc[] =
".. function:: TriangleNormal(v1, v2, v3)\n"
"\n"
" Returns the normal of the 3D triangle defined.\n"
"\n"
" :rtype: :class:`mathutils.Vector`\n"
" :arg v1: Point1\n"
" :type v1: :class:`mathutils.Vector`\n"
" :arg v2: Point2\n"
" :type v2: :class:`mathutils.Vector`\n"
" :arg v3: Point3\n"
" :type v3: :class:`mathutils.Vector`\n";
static char M_Geometry_QuadNormal_doc[] =
".. function:: QuadNormal(v1, v2, v3, v4)\n"
"\n"
" Returns the normal of the 3D quad defined.\n"
"\n"
" :rtype: :class:`mathutils.Vector`\n"
" :arg v1: Point1\n"
" :type v1: :class:`mathutils.Vector`\n"
" :arg v2: Point2\n"
" :type v2: :class:`mathutils.Vector`\n"
" :arg v3: Point3\n"
" :type v3: :class:`mathutils.Vector`\n"
" :arg v4: Point4\n"
" :type v4: :class:`mathutils.Vector`\n";
static char M_Geometry_LineIntersect_doc[] =
".. function:: LineIntersect(v1, v2, v3, v4)\n"
"\n"
" Returns a tuple with the points on each line respectively closest to the other.\n"
"\n"
" :rtype: tuple with elements being of type :class:`mathutils.Vector`\n"
" :arg v1: First point of the first line\n"
" :type v1: :class:`mathutils.Vector`\n"
" :arg v2: Second point of the first line\n"
" :type v2: :class:`mathutils.Vector`\n"
" :arg v3: First point of the second line\n"
" :type v3: :class:`mathutils.Vector`\n"
" :arg v4: Second point of the second line\n"
" :type v4: :class:`mathutils.Vector`\n";
static char M_Geometry_PolyFill_doc[] =
".. function:: PolyFill(veclist_list)\n"
"\n"
" Takes a list of polylines (each point a vector) and returns the point indicies for a polyline filled with triangles.\n"
"\n"
" :rtype: list\n"
" :arg veclist_list: list of polylines\n";
static char M_Geometry_LineIntersect2D_doc[] =
".. function:: LineIntersect2D(lineA_p1, lineA_p2, lineB_p1, lineB_p2)\n"
"\n"
" Takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None.\n"
"\n"
" :rtype: :class:`mathutils.Vector`\n"
" :arg lineA_p1: First point of the first line\n"
" :type lineA_p1: :class:`mathutils.Vector`\n"
" :arg lineA_p2: Second point of the first line\n"
" :type lineA_p2: :class:`mathutils.Vector`\n"
" :arg lineB_p1: First point of the second line\n"
" :type lineB_p1: :class:`mathutils.Vector`\n"
" :arg lineB_p2: Second point of the second line\n"
" :type lineB_p2: :class:`mathutils.Vector`\n";
static char M_Geometry_ClosestPointOnLine_doc[] =
".. function:: ClosestPointOnLine(pt, line_p1, line_p2)\n"
"\n"
" Takes a point and a line and returns a tuple with the closest point on the line and its distance from the first point of the line as a percentage of the length of the line.\n"
"\n"
" :rtype: (:class:`mathutils.Vector`, float)\n"
" :arg pt: Point\n"
" :type pt: :class:`mathutils.Vector`\n"
" :arg line_p1: First point of the line\n"
" :type line_p1: :class:`mathutils.Vector`\n"
" :arg line_p1: Second point of the line\n"
" :type line_p1: :class:`mathutils.Vector`\n";
static char M_Geometry_PointInTriangle2D_doc[] =
".. function:: PointInTriangle2D(pt, tri_p1, tri_p2, tri_p3)\n"
"\n"
" Takes 4 vectors (using only the x and y coordinates): one is the point and the next 3 define the triangle. Returns 1 if the point is within the triangle, otherwise 0.\n"
"\n"
" :rtype: int\n"
" :arg pt: Point\n"
" :type v1: :class:`mathutils.Vector`\n"
" :arg tri_p1: First point of the triangle\n"
" :type tri_p1: :class:`mathutils.Vector`\n"
" :arg tri_p2: Second point of the triangle\n"
" :type tri_p2: :class:`mathutils.Vector`\n"
" :arg tri_p3: Third point of the triangle\n"
" :type tri_p3: :class:`mathutils.Vector`\n";
static char M_Geometry_PointInQuad2D_doc[] =
".. function:: PointInQuad2D(pt, quad_p1, quad_p2, quad_p3, quad_p4)\n"
"\n"
" Takes 5 vectors (using only the x and y coordinates): one is the point and the next 4 define the quad, only the x and y are used from the vectors. Returns 1 if the point is within the quad, otherwise 0.\n"
"\n"
" :rtype: int\n"
" :arg pt: Point\n"
" :type v1: :class:`mathutils.Vector`\n"
" :arg quad_p1: First point of the quad\n"
" :type quad_p1: :class:`mathutils.Vector`\n"
" :arg quad_p2: Second point of the quad\n"
" :type quad_p2: :class:`mathutils.Vector`\n"
" :arg quad_p3: Third point of the quad\n"
" :type quad_p3: :class:`mathutils.Vector`\n"
" :arg quad_p4: Forth point of the quad\n"
" :type quad_p4: :class:`mathutils.Vector`\n";
static char M_Geometry_BoxPack2D_doc[] = "";
static char M_Geometry_BezierInterp_doc[] = "";
static char M_Geometry_BarycentricTransform_doc[] = "";
//---------------------------------INTERSECTION FUNCTIONS--------------------
//----------------------------------geometry.Intersect() -------------------
@@ -453,7 +587,7 @@ static PyObject *M_Geometry_PolyFill(PyObject *UNUSED(self), PyObject * polyLine
static PyObject *M_Geometry_LineIntersect2D(PyObject *UNUSED(self), PyObject* args)
{
VectorObject *line_a1, *line_a2, *line_b1, *line_b2;
float a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y, xi, yi, a1,a2,b1,b2, newvec[2];
float vi[2];
if( !PyArg_ParseTuple ( args, "O!O!O!O!",
&vector_Type, &line_a1,
&vector_Type, &line_a2,
@@ -466,86 +600,12 @@ static PyObject *M_Geometry_LineIntersect2D(PyObject *UNUSED(self), PyObject* ar
if(!BaseMath_ReadCallback(line_a1) || !BaseMath_ReadCallback(line_a2) || !BaseMath_ReadCallback(line_b1) || !BaseMath_ReadCallback(line_b2))
return NULL;
a1x= line_a1->vec[0];
a1y= line_a1->vec[1];
a2x= line_a2->vec[0];
a2y= line_a2->vec[1];
b1x= line_b1->vec[0];
b1y= line_b1->vec[1];
b2x= line_b2->vec[0];
b2y= line_b2->vec[1];
if((MIN2(a1x, a2x) > MAX2(b1x, b2x)) ||
(MAX2(a1x, a2x) < MIN2(b1x, b2x)) ||
(MIN2(a1y, a2y) > MAX2(b1y, b2y)) ||
(MAX2(a1y, a2y) < MIN2(b1y, b2y)) ) {
if(isect_seg_seg_v2_point(line_a1->vec, line_a2->vec, line_b1->vec, line_b2->vec, vi) == 1) {
return newVectorObject(vi, 2, Py_NEW, NULL);
} else {
Py_RETURN_NONE;
}
/* Make sure the hoz/vert line comes first. */
if (fabs(b1x - b2x) < eps || fabs(b1y - b2y) < eps) {
SWAP_FLOAT(a1x, b1x, xi); /*abuse xi*/
SWAP_FLOAT(a1y, b1y, xi);
SWAP_FLOAT(a2x, b2x, xi);
SWAP_FLOAT(a2y, b2y, xi);
}
if (fabs(a1x-a2x) < eps) { /* verticle line */
if (fabs(b1x-b2x) < eps){ /*verticle second line */
Py_RETURN_NONE; /* 2 verticle lines dont intersect. */
}
else if (fabs(b1y-b2y) < eps) {
/*X of vert, Y of hoz. no calculation needed */
newvec[0]= a1x;
newvec[1]= b1y;
return newVectorObject(newvec, 2, Py_NEW, NULL);
}
yi = (float)(((b1y / fabs(b1x - b2x)) * fabs(b2x - a1x)) + ((b2y / fabs(b1x - b2x)) * fabs(b1x - a1x)));
if (yi > MAX2(a1y, a2y)) {/* New point above seg1's vert line */
Py_RETURN_NONE;
} else if (yi < MIN2(a1y, a2y)) { /* New point below seg1's vert line */
Py_RETURN_NONE;
}
newvec[0]= a1x;
newvec[1]= yi;
return newVectorObject(newvec, 2, Py_NEW, NULL);
} else if (fabs(a2y-a1y) < eps) { /* hoz line1 */
if (fabs(b2y-b1y) < eps) { /*hoz line2*/
Py_RETURN_NONE; /*2 hoz lines dont intersect*/
}
/* Can skip vert line check for seg 2 since its covered above. */
xi = (float)(((b1x / fabs(b1y - b2y)) * fabs(b2y - a1y)) + ((b2x / fabs(b1y - b2y)) * fabs(b1y - a1y)));
if (xi > MAX2(a1x, a2x)) { /* New point right of hoz line1's */
Py_RETURN_NONE;
} else if (xi < MIN2(a1x, a2x)) { /*New point left of seg1's hoz line */
Py_RETURN_NONE;
}
newvec[0]= xi;
newvec[1]= a1y;
return newVectorObject(newvec, 2, Py_NEW, NULL);
}
b1 = (a2y-a1y)/(a2x-a1x);
b2 = (b2y-b1y)/(b2x-b1x);
a1 = a1y-b1*a1x;
a2 = b1y-b2*b1x;
if (b1 - b2 == 0.0) {
Py_RETURN_NONE;
}
xi = - (a1-a2)/(b1-b2);
yi = a1+b1*xi;
if ((a1x-xi)*(xi-a2x) >= 0 && (b1x-xi)*(xi-b2x) >= 0 && (a1y-yi)*(yi-a2y) >= 0 && (b1y-yi)*(yi-b2y)>=0) {
newvec[0]= xi;
newvec[1]= yi;
return newVectorObject(newvec, 2, Py_NEW, NULL);
}
Py_RETURN_NONE;
}
static PyObject *M_Geometry_ClosestPointOnLine(PyObject *UNUSED(self), PyObject* args)
@@ -813,7 +873,7 @@ struct PyMethodDef M_Geometry_methods[] = {
{"PointInQuad2D", ( PyCFunction ) M_Geometry_PointInQuad2D, METH_VARARGS, M_Geometry_PointInQuad2D_doc},
{"BoxPack2D", ( PyCFunction ) M_Geometry_BoxPack2D, METH_O, M_Geometry_BoxPack2D_doc},
{"BezierInterp", ( PyCFunction ) M_Geometry_BezierInterp, METH_VARARGS, M_Geometry_BezierInterp_doc},
{"BarycentricTransform", ( PyCFunction ) M_Geometry_BarycentricTransform, METH_VARARGS, NULL},
{"BarycentricTransform", ( PyCFunction ) M_Geometry_BarycentricTransform, METH_VARARGS, M_Geometry_BarycentricTransform_doc},
{NULL, NULL, 0, NULL}
};

View File

@@ -71,6 +71,7 @@ static char Quaternion_ToEuler_doc[] =
static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
{
float tquat[4];
float eul[3];
char *order_str= NULL;
short order= EULER_ORDER_XYZ;
@@ -88,6 +89,8 @@ static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
if(order == -1)
return NULL;
}
normalize_qt_qt(tquat, self->quat);
if(eul_compat) {
float mat[3][3];
@@ -95,14 +98,14 @@ static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
if(!BaseMath_ReadCallback(eul_compat))
return NULL;
quat_to_mat3(mat, self->quat);
quat_to_mat3(mat, tquat);
if(order == EULER_ORDER_XYZ) mat3_to_compatible_eul(eul, eul_compat->eul, mat);
else mat3_to_compatible_eulO(eul, eul_compat->eul, order, mat);
}
else {
if(order == EULER_ORDER_XYZ) quat_to_eul(eul, self->quat);
else quat_to_eulO(eul, order, self->quat);
if(order == EULER_ORDER_XYZ) quat_to_eul(eul, tquat);
else quat_to_eulO(eul, order, tquat);
}
return newEulerObject(eul, order, Py_NEW, NULL);
@@ -765,21 +768,28 @@ static PyObject *Quaternion_getMagnitude(QuaternionObject * self, void *UNUSED(c
static PyObject *Quaternion_getAngle(QuaternionObject * self, void *UNUSED(closure))
{
float tquat[4];
if(!BaseMath_ReadCallback(self))
return NULL;
return PyFloat_FromDouble(2.0 * (saacos(self->quat[0])));
normalize_qt_qt(tquat, self->quat);
return PyFloat_FromDouble(2.0 * (saacos(tquat[0])));
}
static int Quaternion_setAngle(QuaternionObject * self, PyObject * value, void *UNUSED(closure))
{
float tquat[4];
float len;
float axis[3];
float angle;
if(!BaseMath_ReadCallback(self))
return -1;
quat_to_axis_angle(axis, &angle, self->quat);
len= normalize_qt_qt(tquat, self->quat);
quat_to_axis_angle(axis, &angle, tquat);
angle = PyFloat_AsDouble(value);
@@ -797,6 +807,7 @@ static int Quaternion_setAngle(QuaternionObject * self, PyObject * value, void *
}
axis_angle_to_quat(self->quat, axis, angle);
mul_qt_fl(self->quat, len);
if(!BaseMath_WriteCallback(self))
return -1;
@@ -806,13 +817,16 @@ static int Quaternion_setAngle(QuaternionObject * self, PyObject * value, void *
static PyObject *Quaternion_getAxisVec(QuaternionObject *self, void *UNUSED(closure))
{
float tquat[4];
float axis[3];
float angle;
if(!BaseMath_ReadCallback(self))
return NULL;
quat_to_axis_angle(axis, &angle, self->quat);
normalize_qt_qt(tquat, self->quat);
quat_to_axis_angle(axis, &angle, tquat);
/* If the axis of rotation is 0,0,0 set it to 1,0,0 - for zero-degree rotations */
if( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) &&
@@ -827,15 +841,20 @@ static PyObject *Quaternion_getAxisVec(QuaternionObject *self, void *UNUSED(clos
static int Quaternion_setAxisVec(QuaternionObject *self, PyObject *value, void *UNUSED(closure))
{
float tquat[4];
float len;
float axis[3];
float angle;
VectorObject *vec;
if(!BaseMath_ReadCallback(self))
return -1;
quat_to_axis_angle(axis, &angle, self->quat);
len= normalize_qt_qt(tquat, self->quat);
quat_to_axis_angle(axis, &angle, tquat);
if(!VectorObject_Check(value)) {
PyErr_SetString(PyExc_TypeError, "quaternion.axis = value: expected a 3D Vector");
@@ -847,6 +866,7 @@ static int Quaternion_setAxisVec(QuaternionObject *self, PyObject *value, void *
return -1;
axis_angle_to_quat(self->quat, vec->vec, angle);
mul_qt_fl(self->quat, len);
if(!BaseMath_WriteCallback(self))
return -1;

View File

@@ -23,7 +23,7 @@
#
# ***** END GPL LICENSE BLOCK *****
SET(INC
set(INC
../
../../blenlib
../../makesdna
@@ -37,7 +37,7 @@ SET(INC
${PYTHON_INC}
)
SET(SRC
set(SRC
bpy.c
bpy_app.c
bpy_driver.c
@@ -63,8 +63,8 @@ SET(SRC
)
# only to check if buildinfo is available
IF(WITH_BUILDINFO)
ADD_DEFINITIONS(-DBUILD_DATE)
ENDIF(WITH_BUILDINFO)
if(WITH_BUILDINFO)
add_definitions(-DBUILD_DATE)
endif()
BLENDERLIB(bf_python "${SRC}" "${INC}")
blenderlib(bf_python "${SRC}" "${INC}")

View File

@@ -37,13 +37,14 @@
#include "BLI_bpath.h"
#include "BKE_utildefines.h"
#include "BKE_global.h" /* XXX, G.main only */
#include "MEM_guardedalloc.h"
/* external util modules */
#include "../generic/mathutils.h"
#include "../generic/bgl.h"
#include "../generic/blf_api.h"
#include "../generic/blf_py_api.h"
#include "../generic/IDProp.h"
#include "AUD_PyInit.h"
@@ -94,11 +95,9 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
if (!PyArg_ParseTupleAndKeywords(args, kw, "|i:blend_paths", (char **)kwlist, &absolute))
return NULL;
BLI_bpathIterator_alloc(&bpi);
list= PyList_New(0);
for(BLI_bpathIterator_init(bpi, NULL); !BLI_bpathIterator_isDone(bpi); BLI_bpathIterator_step(bpi)) {
for(BLI_bpathIterator_init(&bpi, G.main, NULL); !BLI_bpathIterator_isDone(bpi); BLI_bpathIterator_step(bpi)) {
/* build the list */
if (absolute) {
BLI_bpathIterator_getPathExpanded(bpi, filepath_expanded);
@@ -119,23 +118,12 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
}
BLI_bpathIterator_free(bpi);
MEM_freeN((void *)bpi);
return list;
}
static char bpy_user_resource_doc[] =
".. function:: user_resource(type, subdir)\n"
"\n"
" Returns a list of paths to external files referenced by the loaded .blend file.\n"
"\n"
" :arg type: Resource type in ['DATAFILES', 'CONFIG', 'SCRIPTS', 'AUTOSAVE'].\n"
" :type type: string\n"
" :arg subdir: Optional subdirectory.\n"
" :type subdir: string\n"
" :return: a path.\n"
" :rtype: string\n";
// static char bpy_user_resource_doc[] = // now in bpy/utils.py
static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
char *type;
@@ -169,7 +157,7 @@ static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObj
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, bpy_user_resource_doc};
static PyMethodDef meth_bpy_user_resource = {"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS|METH_KEYWORDS, NULL};
static void bpy_import_test(const char *modname)
{
@@ -228,7 +216,7 @@ void BPy_init_modules( void )
PyModule_AddObject( mod, "app", BPY_app_struct() );
/* bpy context */
RNA_pointer_create(NULL, &RNA_Context, BPy_GetContext(), &ctx_ptr);
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 */

View File

@@ -59,10 +59,10 @@ static PyStructSequence_Field app_info_fields[] = {
{(char *)"build_revision", (char *)"The subversion revision this blender instance was built with"},
{(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 *)""},
{(char *)"build_cxxflags", (char *)""},
{(char *)"build_linkflags", (char *)""},
{(char *)"build_system", (char *)""},
{(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"},
{0}
};
@@ -153,6 +153,25 @@ static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *UNUS
return 0;
}
static PyObject *bpy_app_debug_value_get(PyObject *UNUSED(self), void *UNUSED(closure))
{
return PyLong_FromSsize_t(G.rt);
}
static int bpy_app_debug_value_set(PyObject *UNUSED(self), PyObject *value, void *UNUSED(closure))
{
int param= PyLong_AsSsize_t(value);
if (param == -1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, "bpy.app.debug_value can only be set to a whole number");
return -1;
}
G.rt= param;
return 0;
}
static PyObject *bpy_app_tempdir_get(PyObject *UNUSED(self), void *UNUSED(closure))
{
extern char btempdir[];
@@ -174,6 +193,7 @@ static PyObject *bpy_app_driver_dict_get(PyObject *UNUSED(self), void *UNUSED(cl
PyGetSetDef bpy_app_getsets[]= {
{(char *)"debug", bpy_app_debug_get, bpy_app_debug_set, (char *)"Boolean, set when blender is running in debug mode (started with -d)", NULL},
{(char *)"debug_value", bpy_app_debug_value_get, bpy_app_debug_value_set, (char *)"Int, number which can be set to non-zero values for testing purposes.", NULL},
{(char *)"tempdir", bpy_app_tempdir_get, NULL, (char *)"String, the temp directory used by blender (read-only)", NULL},
{(char *)"driver_namespace", bpy_app_driver_dict_get, NULL, (char *)"Dictionary for drivers namespace, editable in-place, reset on file load (read-only)", NULL},
{NULL, NULL, NULL, NULL, NULL}

View File

@@ -88,7 +88,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(); /* can give really bad results if this isnt here */
BPY_update_modules(C); /* can give really bad results if this isnt here */
#ifdef TIME_PY_RUN
if(bpy_timer_count==0) {
@@ -136,7 +136,7 @@ void BPY_free_compiled_text( struct Text *text )
}
}
void BPY_update_modules( void )
void BPY_update_modules(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);
@@ -146,7 +146,7 @@ void BPY_update_modules( void )
/* refreshes the main struct */
BPY_update_rna_module();
bpy_context_module->ptr.data= (void *)BPy_GetContext();
bpy_context_module->ptr.data= (void *)C;
}
/* must be called before Py_Initialize */

View File

@@ -52,8 +52,13 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
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 = BPy_GetContext();
bContext *C= (bContext *)BPy_GetContext();
if(C==NULL) {
PyErr_SetString(PyExc_SystemError, "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;
@@ -114,7 +119,12 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
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 = BPy_GetContext();
bContext *C = (bContext *)BPy_GetContext();
if(C==NULL) {
PyErr_SetString(PyExc_SystemError, "Context is None, cant poll any operators");
return NULL;
}
if (!PyArg_ParseTuple(args, "sO|O!s:_bpy.ops.call", &opname, &context_dict, &PyDict_Type, &kw, &context_str))
return NULL;
@@ -232,8 +242,13 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
char *buf = NULL;
PyObject *pybuf;
bContext *C = BPy_GetContext();
bContext *C = (bContext *)BPy_GetContext();
if(C==NULL) {
PyErr_SetString(PyExc_SystemError, "Context is None, cant get the string representation of this object.");
return NULL;
}
if (!PyArg_ParseTuple(args, "s|O!i:_bpy.ops.as_string", &opname, &PyDict_Type, &kw, &all_args))
return NULL;

View File

@@ -40,6 +40,12 @@ EnumPropertyItem property_flag_items[] = {
{PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""},
{0, NULL, 0, NULL, NULL}};
EnumPropertyItem property_flag_enum_items[] = {
{PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
{PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""},
{PROP_ENUM_FLAG, "ENUM_FLAG", 0, "Enum Flag", ""},
{0, NULL, 0, NULL, NULL}};
/* subtypes */
EnumPropertyItem property_subtype_string_items[] = {
{PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""},
@@ -134,7 +140,7 @@ static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
/* terse macros for error checks shared between all funcs cant use function
* calls because of static strins passed to pyrna_set_to_enum_bitfield */
#define BPY_PROPDEF_CHECK(_func) \
#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \
if(id_len >= MAX_IDPROP_NAME) { \
PyErr_Format(PyExc_TypeError, #_func"(): '%.200s' too long, max length is %d", id, MAX_IDPROP_NAME-1); \
return NULL; \
@@ -143,11 +149,11 @@ static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
PyErr_Format(PyExc_TypeError, #_func"(): '%s' is defined as a non-dynamic type", id); \
return NULL; \
} \
if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, #_func"(options={...}):")) \
if(pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, pyopts, &opts, #_func"(options={...}):")) \
return NULL; \
#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _subtype) \
BPY_PROPDEF_CHECK(_func) \
#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \
BPY_PROPDEF_CHECK(_func, _property_flag_items) \
if(pysubtype && RNA_enum_value_from_id(_subtype, pysubtype, &subtype)==0) { \
PyErr_Format(PyExc_TypeError, #_func"(subtype='%s'): invalid subtype", pysubtype); \
return NULL; \
@@ -196,7 +202,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssiO!s:BoolProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &PySet_Type, &pyopts, &pysubtype))
return NULL;
BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_subtype_number_items)
BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items)
prop= RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
RNA_def_property_boolean_default(prop, def);
@@ -243,7 +249,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssOO!si:BoolVectorProperty", (char **)kwlist, &id, &id_len, &name, &description, &pydef, &PySet_Type, &pyopts, &pysubtype, &size))
return NULL;
BPY_PROPDEF_SUBTYPE_CHECK(BoolVectorProperty, property_subtype_array_items)
BPY_PROPDEF_SUBTYPE_CHECK(BoolVectorProperty, property_flag_items, property_subtype_array_items)
if(size < 1 || size > PYRNA_STACK_ARRAY) {
PyErr_Format(PyExc_TypeError, "BoolVectorProperty(size=%d): size must be between 0 and " STRINGIFY(PYRNA_STACK_ARRAY), size);
@@ -298,7 +304,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssiiiiiiO!s:IntProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype))
return NULL;
BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_subtype_number_items)
BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items)
prop= RNA_def_property(srna, id, PROP_INT, subtype);
RNA_def_property_int_default(prop, def);
@@ -346,7 +352,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssOiiiiiO!si:IntVectorProperty", (char **)kwlist, &id, &id_len, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype, &size))
return NULL;
BPY_PROPDEF_SUBTYPE_CHECK(IntVectorProperty, property_subtype_array_items)
BPY_PROPDEF_SUBTYPE_CHECK(IntVectorProperty, property_flag_items, property_subtype_array_items)
if(size < 1 || size > PYRNA_STACK_ARRAY) {
PyErr_Format(PyExc_TypeError, "IntVectorProperty(size=%d): size must be between 0 and " STRINGIFY(PYRNA_STACK_ARRAY), size);
@@ -407,7 +413,7 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssffffffiO!ss:FloatProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &pyunit))
return NULL;
BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_subtype_number_items)
BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_flag_items, property_subtype_number_items)
if(pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit)==0) {
PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit");
@@ -460,7 +466,7 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssOfffffiO!si:FloatVectorProperty", (char **)kwlist, &id, &id_len, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &size))
return NULL;
BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty, property_subtype_array_items)
BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty, property_flag_items, property_subtype_array_items)
if(size < 1 || size > PYRNA_STACK_ARRAY) {
PyErr_Format(PyExc_TypeError, "FloatVectorProperty(size=%d): size must be between 0 and " STRINGIFY(PYRNA_STACK_ARRAY), size);
@@ -515,7 +521,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|sssiO!s:StringProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &maxlen, &PySet_Type, &pyopts, &pysubtype))
return NULL;
BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_subtype_string_items)
BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items)
prop= RNA_def_property(srna, id, PROP_STRING, subtype);
if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen + 1); /* +1 since it includes null terminator */
@@ -531,49 +537,102 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
Py_RETURN_NONE;
}
static EnumPropertyItem *enum_items_from_py(PyObject *value, const char *def, int *defvalue)
static EnumPropertyItem *enum_items_from_py(PyObject *value, PyObject *def, int *defvalue, const short is_enum_flag)
{
EnumPropertyItem *items= NULL;
PyObject *item;
int seq_len, i, totitem= 0;
short def_used= 0;
const char *def_cmp= NULL;
if(!PySequence_Check(value)) {
PyErr_SetString(PyExc_TypeError, "expected a sequence of tuples for the enum items");
PyErr_SetString(PyExc_TypeError, "EnumProperty(...): expected a sequence of tuples for the enum items");
return NULL;
}
seq_len = PySequence_Length(value);
seq_len= PySequence_Length(value);
if(is_enum_flag) {
if(seq_len > RNA_ENUM_BITFLAG_SIZE) {
PyErr_SetString(PyExc_TypeError, "EnumProperty(...): maximum " STRINGIFY(RNA_ENUM_BITFLAG_SIZE) " members for a ENUM_FLAG type property");
return NULL;
}
if(def && !PySet_Check(def)) {
PyErr_Format(PyExc_TypeError, "EnumProperty(...): default option must be a 'set' type when ENUM_FLAG is enabled, not a '%.200s'", Py_TYPE(def)->tp_name);
return NULL;
}
}
else {
if(def) {
def_cmp= _PyUnicode_AsString(def);
if(def_cmp==NULL) {
PyErr_Format(PyExc_TypeError, "EnumProperty(...): default option must be a 'str' type when ENUM_FLAG is disabled, not a '%.200s'", Py_TYPE(def)->tp_name);
return NULL;
}
}
}
/* blank value */
*defvalue= 0;
for(i=0; i<seq_len; i++) {
EnumPropertyItem tmp= {0, "", 0, "", ""};
item= PySequence_GetItem(value, i);
if(item==NULL || PyTuple_Check(item)==0) {
PyErr_SetString(PyExc_TypeError, "expected a sequence of tuples for the enum items");
PyErr_SetString(PyExc_TypeError, "EnumProperty(...): expected a sequence of tuples for the enum items");
if(items) MEM_freeN(items);
Py_XDECREF(item);
return NULL;
}
if(!PyArg_ParseTuple(item, "sss", &tmp.identifier, &tmp.name, &tmp.description)) {
PyErr_SetString(PyExc_TypeError, "expected an identifier, name and description in the tuple");
PyErr_SetString(PyExc_TypeError, "EnumProperty(...): expected an identifier, name and description in the tuple");
Py_DECREF(item);
return NULL;
}
tmp.value= i;
RNA_enum_item_add(&items, &totitem, &tmp);
if(is_enum_flag) {
tmp.value= 1<<i;
if(def[0] && strcmp(def, tmp.identifier) == 0)
*defvalue= tmp.value;
if(def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) {
*defvalue |= tmp.value;
def_used++;
}
}
else {
tmp.value= i;
if(def && def_used == 0 && strcmp(def_cmp, tmp.identifier)==0) {
*defvalue= tmp.value;
def_used++; /* only ever 1 */
}
}
RNA_enum_item_add(&items, &totitem, &tmp);
Py_DECREF(item);
}
if(!def[0])
*defvalue= 0;
RNA_enum_item_end(&items, &totitem);
if(is_enum_flag) {
/* strict check that all set members were used */
if(def && def_used != PySet_GET_SIZE(def)) {
MEM_freeN(items);
PyErr_Format(PyExc_TypeError, "EnumProperty(..., default={...}): set has %d unused member(s)", PySet_GET_SIZE(def) - def_used);
return NULL;
}
}
else {
if(def && def_used == 0) {
MEM_freeN(items);
PyErr_Format(PyExc_TypeError, "EnumProperty(..., default=\'%s\'): not found in enum members", def);
return NULL;
}
}
return items;
}
@@ -582,7 +641,9 @@ static char BPy_EnumProperty_doc[] =
"\n"
" Returns a new enumerator property definition.\n"
"\n"
" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
" :arg default: The default value for this enum, A string when *ENUM_FLAG* is disabled otherwise a set which may only contain string identifiers used in *items*.\n"
" :type default: string or set\n"
" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE', 'ENUM_FLAG'].\n"
" :type options: set\n"
" :arg items: The items that make up this enumerator.\n"
" :type items: sequence of string triplets";
@@ -594,7 +655,8 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
if(srna) {
static const char *kwlist[] = {"attr", "items", "name", "description", "default", "options", NULL};
const char *id=NULL, *name="", *description="", *def="";
const char *id=NULL, *name="", *description="";
PyObject *def= NULL;
int id_len;
int defvalue=0;
PyObject *items= Py_None;
@@ -603,12 +665,12 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
PyObject *pyopts= NULL;
int opts=0;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s#O|sssO!:EnumProperty", (char **)kwlist, &id, &id_len, &items, &name, &description, &def, &PySet_Type, &pyopts))
if (!PyArg_ParseTupleAndKeywords(args, kw, "s#O|ssOO!:EnumProperty", (char **)kwlist, &id, &id_len, &items, &name, &description, &def, &PySet_Type, &pyopts))
return NULL;
BPY_PROPDEF_CHECK(EnumProperty)
BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items)
eitems= enum_items_from_py(items, def, &defvalue);
eitems= enum_items_from_py(items, def, &defvalue, (opts & PROP_ENUM_FLAG)!=0);
if(!eitems)
return NULL;
@@ -616,6 +678,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
if(pyopts) {
if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
if(opts & PROP_ENUM_FLAG) RNA_def_property_flag(prop, PROP_ENUM_FLAG);
}
RNA_def_property_duplicate_pointers(srna, prop);
MEM_freeN(eitems);
@@ -673,7 +736,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
if (!PyArg_ParseTupleAndKeywords(args, kw, "s#O|ssO!:PointerProperty", (char **)kwlist, &id, &id_len, &type, &name, &description, &PySet_Type, &pyopts))
return NULL;
BPY_PROPDEF_CHECK(PointerProperty)
BPY_PROPDEF_CHECK(PointerProperty, property_flag_items)
ptype= pointer_type_from_py(type, "PointerProperty(...):");
if(!ptype)
@@ -717,7 +780,7 @@ static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject
if (!PyArg_ParseTupleAndKeywords(args, kw, "s#O|ssO!:CollectionProperty", (char **)kwlist, &id, &id_len, &type, &name, &description, &PySet_Type, &pyopts))
return NULL;
BPY_PROPDEF_CHECK(CollectionProperty)
BPY_PROPDEF_CHECK(CollectionProperty, property_flag_items)
ptype= pointer_type_from_py(type, "CollectionProperty(...):");
if(!ptype)

View File

@@ -50,24 +50,13 @@
#include "DNA_anim_types.h"
#include "ED_keyframing.h"
#include "../generic/IDProp.h" /* for IDprop lookups */
#include "../generic/py_capi_utils.h"
#define USE_PEDANTIC_WRITE
#define USE_MATHUTILS
#define USE_STRING_COERCE
#ifdef USE_MATHUTILS
#include "../generic/mathutils.h" /* so we can have mathutils callbacks */
#include "../generic/IDProp.h" /* for IDprop lookups */
#include "../generic/py_capi_utils.h"
static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix);
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length);
static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self);
static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self);
static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback);
static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item);
/* bpyrna vector/euler/quat callbacks */
static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */
#ifdef USE_PEDANTIC_WRITE
static short rna_disallow_writes= FALSE;
@@ -83,7 +72,7 @@ static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
else pyname= "<UNKNOWN>";
/* make a nice string error */
assert(idtype != NULL);
BKE_assert(idtype != NULL);
PyErr_Format(PyExc_RuntimeError, "Writing to ID classes in this context is not allowed: %.200s, %.200s datablock, error setting %.200s.%.200s", id->name+2, idtype, RNA_struct_identifier(ptr->type), pyname);
return TRUE;
@@ -92,7 +81,21 @@ static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
return FALSE;
}
#endif
#endif // USE_PEDANTIC_WRITE
static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self);
static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self);
static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix);
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 short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback);
/* bpyrna vector/euler/quat callbacks */
static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */
/* subtype not used much yet */
#define MATHUTILS_CB_SUBTYPE_EUL 0
@@ -135,7 +138,7 @@ static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
if(rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
return 0;
}
#endif
#endif // USE_PEDANTIC_WRITE
if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
PyErr_Format(PyExc_AttributeError, "bpy_prop \"%.200s.%.200s\" is read-only", RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
@@ -193,7 +196,7 @@ static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int UNUSED(subtyp
if(rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
return 0;
}
#endif
#endif // USE_PEDANTIC_WRITE
if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
PyErr_Format(PyExc_AttributeError, "bpy_prop \"%.200s.%.200s\" is read-only", RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
@@ -244,7 +247,7 @@ static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype))
if(rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
return 0;
}
#endif
#endif // USE_PEDANTIC_WRITE
if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
PyErr_Format(PyExc_AttributeError, "bpy_prop \"%.200s.%.200s\" is read-only", RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
@@ -268,19 +271,23 @@ Mathutils_Callback mathutils_rna_matrix_cb = {
NULL
};
/* same as RNA_enum_value_from_id but raises an exception */
int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value, const char *error_prefix)
static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback)
{
if(RNA_enum_value_from_id(item, identifier, value) == 0) {
char *enum_str= BPy_enum_as_string(item);
PyErr_Format(PyExc_TypeError, "%s: '%.200s' not found in (%s)", error_prefix, identifier, enum_str);
MEM_freeN(enum_str);
return -1;
/* attempt to get order */
if(*prop_eul_order==NULL)
*prop_eul_order= RNA_struct_find_property(ptr, "rotation_mode");
if(*prop_eul_order) {
short order= RNA_property_enum_get(ptr, *prop_eul_order);
if (order >= ROT_MODE_XYZ && order <= ROT_MODE_ZYX) /* could be quat or axisangle */
return order;
}
return 0;
return order_fallback;
}
#endif // USE_MATHUTILS
#define PROP_ALL_VECTOR_SUBTYPES PROP_TRANSLATION: case PROP_DIRECTION: case PROP_VELOCITY: case PROP_ACCELERATION: case PROP_XYZ: case PROP_XYZ_LENGTH
PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
@@ -401,27 +408,25 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the Mathutils PyObject */
}
}
#endif
#else // USE_MATHUTILS
(void)ptr;
(void)prop;
#endif // USE_MATHUTILS
return ret;
}
#endif
static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback)
/* same as RNA_enum_value_from_id but raises an exception */
int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value, const char *error_prefix)
{
/* attempt to get order */
if(*prop_eul_order==NULL)
*prop_eul_order= RNA_struct_find_property(ptr, "rotation_mode");
if(*prop_eul_order) {
short order= RNA_property_enum_get(ptr, *prop_eul_order);
if (order >= ROT_MODE_XYZ && order <= ROT_MODE_ZYX) /* could be quat or axisangle */
return order;
if(RNA_enum_value_from_id(item, identifier, value) == 0) {
char *enum_str= BPy_enum_as_string(item);
PyErr_Format(PyExc_TypeError, "%s: '%.200s' not found in (%s)", error_prefix, identifier, enum_str);
MEM_freeN(enum_str);
return -1;
}
return order_fallback;
return 0;
}
static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b )
@@ -853,9 +858,9 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
else {
ret= PyUnicode_FromString(buf);
}
#else
#else // USE_STRING_COERCE
ret= PyUnicode_FromString(buf);
#endif
#endif // USE_STRING_COERCE
MEM_freeN(buf);
break;
}
@@ -990,7 +995,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
if(!BaseMath_ReadCallback(mat))
return -1;
} else /* continue... */
#endif
#endif // USE_MATHUTILS
if (!PySequence_Check(value)) {
PyErr_Format(PyExc_TypeError, "%.200s RNA array assignment to %.200s.%.200s expected a sequence instead of %.200s instance", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
return -1;
@@ -1072,9 +1077,9 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
else {
param= _PyUnicode_AsString(value);
}
#else
#else // USE_STRING_COERCE
param= _PyUnicode_AsString(value);
#endif
#endif // USE_STRING_COERCE
if (param==NULL) {
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected a string type", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop));
@@ -1086,7 +1091,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
#ifdef USE_STRING_COERCE
Py_XDECREF(value_coerce);
#endif
#endif // USE_STRING_COERCE
break;
}
case PROP_ENUM:
@@ -1539,7 +1544,8 @@ static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, Po
break;
}
default:
/* probably will never happen */
BKE_assert(!"Invalid array type");
PyErr_SetString(PyExc_TypeError, "not an array type");
Py_DECREF(list);
list= NULL;
@@ -1951,7 +1957,7 @@ static int pyrna_struct_ass_subscript( BPy_StructRNA *self, PyObject *key, PyObj
if(rna_disallow_writes && rna_id_write_error(&self->ptr, key)) {
return -1;
}
#endif
#endif // USE_STRING_COERCE
if(group==NULL) {
PyErr_SetString(PyExc_TypeError, "bpy_struct[key] = val: id properties not supported for this type");
@@ -2673,6 +2679,8 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
break;
default:
/* should never happen */
BKE_assert(!"Invalid context type");
PyErr_Format(PyExc_AttributeError, "bpy_struct: Context type invalid %d, can't get \"%.200s\" from context", newtype, name);
ret= NULL;
}
@@ -2781,7 +2789,7 @@ static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObjec
if(rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
return -1;
}
#endif
#endif // USE_STRING_COERCE
if(name == NULL) {
PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string");
@@ -2900,7 +2908,7 @@ static int pyrna_prop_collection_setattro( BPy_PropertyRNA *self, PyObject *pyna
if(rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
return -1;
}
#endif
#endif // USE_STRING_COERCE
if(name == NULL) {
PyErr_SetString(PyExc_AttributeError, "bpy_prop: __setattr__ must be a string");
@@ -3301,6 +3309,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
break;
case PROP_RAW_UNSET:
/* should never happen */
BKE_assert(!"Invalid array type - set");
break;
}
@@ -3355,6 +3364,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
break;
case PROP_RAW_UNSET:
/* should never happen */
BKE_assert(!"Invalid array type - get");
break;
}
@@ -3566,6 +3576,7 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
break;
case PROP_FLOAT:
switch(RNA_property_subtype(prop)) {
#ifdef USE_MATHUTILS
case PROP_ALL_VECTOR_SUBTYPES:
ret= newVectorObject(data, len, Py_NEW, NULL);
break;
@@ -3579,6 +3590,7 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
break;
}
/* pass through */
#endif
default:
ret = PyTuple_New(len);
for(a=0; a<len; a++)
@@ -3710,6 +3722,8 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
void *retdata_single= NULL;
/* Should never happen but it does in rare cases */
BKE_assert(self_ptr != NULL);
if(self_ptr==NULL) {
PyErr_SetString(PyExc_RuntimeError, "rna functions internal rna pointer is NULL, this is a bug. aborting");
return NULL;
@@ -4901,7 +4915,7 @@ static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
PyObject *item, *key;
PyObject *order;
Py_ssize_t pos = 0;
int ret;
int ret= 0;
/* in both cases PyDict_CheckExact(class_dict) will be true even
* though Operators have a metaclass dict namespace */
@@ -4911,7 +4925,7 @@ static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
key= PyList_GET_ITEM(order, pos);
item= PyDict_GetItem(class_dict, key);
ret= deferred_register_prop(srna, key, item);
if(ret==-1)
if(ret != 0)
break;
}
}
@@ -4919,12 +4933,12 @@ static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
while (PyDict_Next(class_dict, &pos, &key, &item)) {
ret= deferred_register_prop(srna, key, item);
if(ret==-1)
if(ret != 0)
break;
}
}
return 0;
return ret;
}
static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject *py_class)
@@ -5122,10 +5136,10 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
return 0;
}
extern void BPY_update_modules( void ); //XXX temp solution
extern void BPY_update_modules(bContext *C); //XXX temp solution
/* TODO - multiple return values like with rna functions */
static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
{
PyObject *args;
PyObject *ret= NULL, *py_srna= NULL, *py_class, *py_class_instance= NULL, *parmitem;
@@ -5141,7 +5155,6 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
PyGILState_STATE gilstate;
bContext *C= BPy_GetContext(); // XXX - NEEDS FIXING, QUITE BAD.
#ifdef USE_PEDANTIC_WRITE
/* testing, for correctness, not operator and not draw function */
const short is_readonly= strstr("draw", RNA_function_identifier(func)) || !RNA_struct_is_a(ptr->type, &RNA_Operator);
@@ -5155,6 +5168,11 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
return -1;
}
/* XXX, this is needed because render engine calls without a context
* this should be supported at some point but at the moment its not! */
if(C==NULL)
C= BPy_GetContext();
bpy_context_set(C, &gilstate);
if (!is_static) {