Merged changes in the trunk up to revision 33765.
This commit is contained in:
@@ -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);
|
||||
//
|
||||
|
||||
@@ -16,5 +16,5 @@
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
ADD_SUBDIRECTORY(intern)
|
||||
ADD_SUBDIRECTORY(generic)
|
||||
add_subdirectory(intern)
|
||||
add_subdirectory(generic)
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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},
|
||||
@@ -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}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user