=bmesh= merge from trunk at r36153

This commit is contained in:
Joseph Eagar
2011-04-15 01:19:13 +00:00
1589 changed files with 83673 additions and 48300 deletions

View File

@@ -78,7 +78,7 @@ void BPY_python_end( void );
/* 2.5 UI Scripts */
int BPY_filepath_exec(struct bContext *C, const char *filepath, struct ReportList *reports);
int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports);
int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const short do_jump);
void BPY_text_free_code(struct Text *text);
void BPY_modules_update(struct bContext *C); // XXX - annoying, need this for pointers that get out of date
void BPY_modules_load_user(struct bContext *C);
@@ -93,6 +93,8 @@ void BPY_DECREF(void *pyob_ptr); /* Py_DECREF() */
int BPY_context_member_get(struct bContext *C, const char *member, struct bContextDataResult *result);
void BPY_context_set(struct bContext *C);
void BPY_id_release(struct ID *id);
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@@ -1,24 +1,37 @@
#!/usr/bin/python
Import ('env')
sources = env.Glob('intern/*.c')
# TODO, split into 2 files.
Import ('env')
incs = '. ../editors/include ../makesdna ../makesrna ../blenlib ../blenkernel ../nodes'
incs += ' ../imbuf ../blenloader ../render/extern/include ../windowmanager'
incs += ' #intern/guardedalloc #intern/memutil #extern/glew/include'
incs += ' #intern/audaspace/intern ' + env['BF_PYTHON_INC']
is_debug = (env['OURPLATFORM'] in ('win32-mingw', 'win32-vc','win64-vc') and env['BF_DEBUG'])
# generic
defs = []
if is_debug:
defs.append('_DEBUG')
sources = env.Glob('generic/*.c')
env.BlenderLib( libname = 'bf_python_ext', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [362,165]) # ketsji is 360
# bpy
defs = []
if is_debug:
defs.append('_DEBUG')
if env['WITH_BF_PYTHON_SAFETY']:
defs.append('WITH_PYTHON_SAFETY')
if env['BF_BUILDINFO']:
defs.append('BUILD_DATE')
if env['OURPLATFORM'] in ('win32-mingw', 'win32-vc','win64-vc') and env['BF_DEBUG']:
defs.append('_DEBUG')
env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [361,160])
# generic
sources = env.Glob('generic/*.c')
env.BlenderLib( libname = 'bf_python_ext', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [362,165]) # ketsji is 360
sources = env.Glob('intern/*.c')
env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [361])

View File

@@ -25,7 +25,7 @@ set(INC
../../blenkernel
../../blenloader
../../../../intern/guardedalloc
../../../../extern/glew/include
${GLEW_INCLUDE_PATH}
${PYTHON_INCLUDE_DIRS}
)

View File

@@ -23,6 +23,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/IDProp.c
* \ingroup pygen
*/
#include <Python.h>
#include "IDProp.h"
@@ -311,10 +316,12 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(const char *name, IDProperty *g
if (PyFloat_Check(ob)) {
val.d = PyFloat_AsDouble(ob);
prop = IDP_New(IDP_DOUBLE, val, name);
} else if (PyLong_Check(ob)) {
}
else if (PyLong_Check(ob)) {
val.i = (int) PyLong_AsSsize_t(ob);
prop = IDP_New(IDP_INT, val, name);
} else if (PyUnicode_Check(ob)) {
}
else if (PyUnicode_Check(ob)) {
#ifdef USE_STRING_COERCE
PyObject *value_coerce= NULL;
val.str = (char *)PyC_UnicodeAsByte(ob, &value_coerce);
@@ -324,7 +331,8 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(const char *name, IDProperty *g
val.str = _PyUnicode_AsString(ob);
prop = IDP_New(IDP_STRING, val, name);
#endif
} else if (PySequence_Check(ob)) {
}
else if (PySequence_Check(ob)) {
PyObject *item;
int i;
@@ -367,7 +375,8 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(const char *name, IDProperty *g
}
break;
}
} else if (PyMapping_Check(ob)) {
}
else if (PyMapping_Check(ob)) {
PyObject *keys, *vals, *key, *pval;
int i, len;
/*yay! we get into recursive stuff now!*/
@@ -404,13 +413,15 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(const char *name, IDProperty *g
}
Py_XDECREF(keys);
Py_XDECREF(vals);
} else return "invalid property value";
}
else return "invalid property value";
if(group->type==IDP_IDPARRAY) {
IDP_AppendArray(group, prop);
// IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory
MEM_freeN(prop);
} else {
}
else {
IDP_ReplaceInGroup(group, prop);
}
@@ -431,7 +442,8 @@ int BPy_Wrap_SetMapItem(IDProperty *prop, PyObject *key, PyObject *val)
IDP_FreeProperty(pkey);
MEM_freeN(pkey);
return 0;
} else {
}
else {
PyErr_SetString(PyExc_KeyError, "property not found in group");
return -1;
}
@@ -502,10 +514,12 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
if (prop->subtype == IDP_FLOAT) {
PyList_SET_ITEM(seq, i,
PyFloat_FromDouble(((float*)prop->data.pointer)[i]));
} else if (prop->subtype == IDP_DOUBLE) {
}
else if (prop->subtype == IDP_DOUBLE) {
PyList_SET_ITEM(seq, i,
PyFloat_FromDouble(((double*)prop->data.pointer)[i]));
} else {
}
else {
PyList_SET_ITEM(seq, i,
PyLong_FromLong(((int*)prop->data.pointer)[i]));
}
@@ -1087,10 +1101,12 @@ static PyObject *BPy_Group_Iter_Next(BPy_IDGroup_Iter *self)
PyTuple_SET_ITEM(ret, 0, PyUnicode_FromString(cur->name));
PyTuple_SET_ITEM(ret, 1, BPy_IDGroup_WrapData(self->group->id, cur));
return ret;
} else {
}
else {
return PyUnicode_FromString(cur->name);
}
} else {
}
else {
PyErr_SetString(PyExc_StopIteration, "iterator at end");
return NULL;
}

View File

@@ -22,6 +22,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/IDProp.h
* \ingroup pygen
*/
#ifndef IDPROP_H
#define IDPROP_H

View File

@@ -27,6 +27,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/bgl.c
* \ingroup pygen
*/
/* This file is the 'bgl' module.
* The BGL submodule "wraps" OpenGL functions and constants,
* allowing script writers to make OpenGL calls in their Python scripts. */
@@ -165,7 +170,8 @@ Buffer *BGL_MakeBuffer(int type, int ndimensions, int *dimensions, void *initbuf
if (initbuffer) {
memcpy(buffer->buf.asvoid, initbuffer, length*size);
} else {
}
else {
memset(buffer->buf.asvoid, 0, length*size);
/*
for (i= 0; i<length; i++) {
@@ -275,7 +281,8 @@ static PyObject *Buffer_item(PyObject *self, int i)
case GL_FLOAT: return PyFloat_FromDouble(buf->buf.asfloat[i]);
case GL_DOUBLE: return Py_BuildValue("d", buf->buf.asdouble[i]);
}
} else {
}
else {
Buffer *newbuf;
int j, length, size;
@@ -345,17 +352,21 @@ static int Buffer_ass_item(PyObject *self, int i, PyObject *v)
if (buf->type==GL_BYTE) {
if (!PyArg_Parse(v, "b:Coordinates must be ints", &buf->buf.asbyte[i]))
return -1;
} else if (buf->type==GL_SHORT) {
}
else if (buf->type==GL_SHORT) {
if (!PyArg_Parse(v, "h:Coordinates must be ints", &buf->buf.asshort[i]))
return -1;
} else if (buf->type==GL_INT) {
}
else if (buf->type==GL_INT) {
if (!PyArg_Parse(v, "i:Coordinates must be ints", &buf->buf.asint[i]))
return -1;
} else if (buf->type==GL_FLOAT) {
}
else if (buf->type==GL_FLOAT) {
if (!PyArg_Parse(v, "f:Coordinates must be floats", &buf->buf.asfloat[i]))
return -1;
} else if (buf->type==GL_DOUBLE) {
}
else if (buf->type==GL_DOUBLE) {
if (!PyArg_Parse(v, "d:Coordinates must be floats", &buf->buf.asdouble[i]))
return -1;
}

View File

@@ -27,6 +27,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/bgl.h
* \ingroup pygen
*/
/* This is the Blender.BGL part of opy_draw.c, from the old bpython/intern
* dir, with minor changes to adapt it to the new Python implementation.
* The BGL submodule "wraps" OpenGL functions and constants, allowing script

View File

@@ -22,6 +22,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/blf_py_api.c
* \ingroup pygen
*/
#include <Python.h>
#include "blf_py_api.h"

View File

@@ -22,4 +22,9 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/blf_py_api.h
* \ingroup pygen
*/
PyObject *BPyInit_blf(void);

View File

@@ -26,6 +26,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/bpy_internal_import.c
* \ingroup pygen
*/
#include <Python.h>
#include <stddef.h>
@@ -50,10 +55,31 @@
static Main *bpy_import_main= NULL;
/* 'builtins' is most likely PyEval_GetBuiltins() */
void bpy_import_init(PyObject *builtins)
{
PyObject *item;
PyObject *mod;
PyDict_SetItemString(builtins, "__import__", item=PyCFunction_New(&bpy_import_meth, NULL)); Py_DECREF(item);
/* move reload here
* XXX, use import hooks */
mod= PyImport_ImportModuleLevel((char *)"imp", NULL, NULL, NULL, 0);
if(mod) {
PyDict_SetItemString(PyModule_GetDict(mod), "reload", item=PyCFunction_New(&bpy_reload_meth, NULL)); Py_DECREF(item);
Py_DECREF(mod);
}
else {
BLI_assert(!"unable to load 'imp' module.");
}
}
static void free_compiled_text(Text *text)
{
if(text->compiled) {
Py_DECREF(( PyObject * )text->compiled);
Py_DECREF((PyObject *)text->compiled);
}
text->compiled= NULL;
}
@@ -69,37 +95,30 @@ void bpy_import_main_set(struct Main *maggie)
}
/* returns a dummy filename for a textblock so we can tell what file a text block comes from */
void bpy_text_filename_get(char *fn, Text *text)
void bpy_text_filename_get(char *fn, size_t fn_len, Text *text)
{
#if PY_VERSION_HEX >= 0x03020000
sprintf(fn, "%s%c%s", text->id.lib ? text->id.lib->filepath : G.main->name, SEP, text->id.name+2);
#else
/* this is a bug in python's Py_CompileString()!, fixed for python 3.2.
the string encoding should not be required to be utf-8
reported: http://bugs.python.org/msg115202 */
strcpy(fn, text->id.name+2);
#endif
BLI_snprintf(fn, fn_len, "%s%c%s", text->id.lib ? text->id.lib->filepath : G.main->name, SEP, text->id.name+2);
}
PyObject *bpy_text_import(Text *text)
{
char *buf = NULL;
char *buf= NULL;
char modulename[24];
int len;
if( !text->compiled ) {
if(!text->compiled) {
char fn_dummy[256];
bpy_text_filename_get(fn_dummy, text);
bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text);
buf = txt_to_buf( text );
text->compiled = Py_CompileString( buf, fn_dummy, Py_file_input );
MEM_freeN( buf );
buf= txt_to_buf(text);
text->compiled= Py_CompileString(buf, fn_dummy, Py_file_input);
MEM_freeN(buf);
if( PyErr_Occurred( ) ) {
PyErr_Print( );
PyErr_Clear( );
if(PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
PySys_SetObject("last_traceback", NULL);
free_compiled_text( text );
free_compiled_text(text);
return NULL;
}
}
@@ -110,11 +129,11 @@ PyObject *bpy_text_import(Text *text)
return PyImport_ExecCodeModule(modulename, text->compiled);
}
PyObject *bpy_text_import_name( char *name, int *found )
PyObject *bpy_text_import_name(char *name, int *found)
{
Text *text;
char txtname[22]; /* 21+NULL */
int namelen = strlen( name );
int namelen= strlen(name);
//XXX Main *maggie= bpy_import_main ? bpy_import_main:G.main;
Main *maggie= bpy_import_main;
@@ -127,15 +146,15 @@ PyObject *bpy_text_import_name( char *name, int *found )
if (namelen>21-3) return NULL; /* we know this cant be importable, the name is too long for blender! */
memcpy( txtname, name, namelen );
memcpy( &txtname[namelen], ".py", 4 );
memcpy(txtname, name, namelen);
memcpy(&txtname[namelen], ".py", 4);
text= BLI_findstring(&maggie->text, txtname, offsetof(ID, name) + 2);
if( !text )
if(!text)
return NULL;
else
*found = 1;
*found= 1;
return bpy_text_import(text);
}
@@ -145,12 +164,12 @@ PyObject *bpy_text_import_name( char *name, int *found )
* find in-memory module and recompile
*/
PyObject *bpy_text_reimport( PyObject *module, int *found )
PyObject *bpy_text_reimport(PyObject *module, int *found)
{
Text *text;
const char *name;
char *filepath;
char *buf = NULL;
char *buf= NULL;
//XXX Main *maggie= bpy_import_main ? bpy_import_main:G.main;
Main *maggie= bpy_import_main;
@@ -172,50 +191,50 @@ PyObject *bpy_text_reimport( PyObject *module, int *found )
text= BLI_findstring(&maggie->text, BLI_path_basename(filepath), offsetof(ID, name) + 2);
/* uh-oh.... didn't find it */
if( !text )
if(!text)
return NULL;
else
*found = 1;
*found= 1;
/* if previously compiled, free the object */
/* (can't see how could be NULL, but check just in case) */
if( text->compiled ){
Py_DECREF( (PyObject *)text->compiled );
if(text->compiled){
Py_DECREF((PyObject *)text->compiled);
}
/* compile the buffer */
buf = txt_to_buf( text );
text->compiled = Py_CompileString( buf, text->id.name+2, Py_file_input );
MEM_freeN( buf );
buf= txt_to_buf(text);
text->compiled= Py_CompileString(buf, text->id.name+2, Py_file_input);
MEM_freeN(buf);
/* if compile failed.... return this error */
if( PyErr_Occurred( ) ) {
PyErr_Print( );
PyErr_Clear( );
if(PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
PySys_SetObject("last_traceback", NULL);
free_compiled_text( text );
free_compiled_text(text);
return NULL;
}
/* make into a module */
return PyImport_ExecCodeModule( (char *)name, text->compiled );
return PyImport_ExecCodeModule((char *)name, text->compiled);
}
static PyObject *blender_import(PyObject *UNUSED(self), PyObject *args, PyObject * kw)
static PyObject *blender_import(PyObject *UNUSED(self), PyObject *args, PyObject * kw)
{
PyObject *exception, *err, *tb;
char *name;
int found= 0;
PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
PyObject *globals= NULL, *locals= NULL, *fromlist= NULL;
int level= -1; /* relative imports */
PyObject *newmodule;
//PyObject_Print(args, stderr, 0);
static const char *kwlist[] = {"name", "globals", "locals", "fromlist", "level", NULL};
static const char *kwlist[]= {"name", "globals", "locals", "fromlist", "level", NULL};
if( !PyArg_ParseTupleAndKeywords(args, kw, "s|OOOi:bpy_import_meth", (char **)kwlist,
&name, &globals, &locals, &fromlist, &level) )
if(!PyArg_ParseTupleAndKeywords(args, kw, "s|OOOi:bpy_import_meth", (char **)kwlist,
&name, &globals, &locals, &fromlist, &level))
return NULL;
/* import existing builtin modules or modules that have been imported already */
@@ -224,28 +243,28 @@ static PyObject *blender_import(PyObject *UNUSED(self), PyObject *args, PyObjec
if(newmodule)
return newmodule;
PyErr_Fetch( &exception, &err, &tb ); /* get the python error incase we cant import as blender text either */
PyErr_Fetch(&exception, &err, &tb); /* get the python error incase we cant import as blender text either */
/* importing from existing modules failed, see if we have this module as blender text */
newmodule = bpy_text_import_name( name, &found );
newmodule= bpy_text_import_name(name, &found);
if( newmodule ) {/* found module as blender text, ignore above exception */
PyErr_Clear( );
Py_XDECREF( exception );
Py_XDECREF( err );
Py_XDECREF( tb );
/* printf( "imported from text buffer...\n" ); */
if(newmodule) {/* found module as blender text, ignore above exception */
PyErr_Clear();
Py_XDECREF(exception);
Py_XDECREF(err);
Py_XDECREF(tb);
/* printf("imported from text buffer...\n"); */
}
else if (found==1) { /* blender text module failed to execute but was found, use its error message */
Py_XDECREF( exception );
Py_XDECREF( err );
Py_XDECREF( tb );
Py_XDECREF(exception);
Py_XDECREF(err);
Py_XDECREF(tb);
return NULL;
}
else {
/* no blender text was found that could import the module
* rause the original error from PyImport_ImportModuleEx */
PyErr_Restore( exception, err, tb );
PyErr_Restore(exception, err, tb);
}
return newmodule;
}
@@ -258,42 +277,42 @@ static PyObject *blender_import(PyObject *UNUSED(self), PyObject *args, PyObjec
static PyObject *blender_reload(PyObject *UNUSED(self), PyObject * module)
{
PyObject *exception, *err, *tb;
PyObject *newmodule = NULL;
PyObject *newmodule= NULL;
int found= 0;
/* try reimporting from file */
newmodule = PyImport_ReloadModule( module );
if( newmodule )
newmodule= PyImport_ReloadModule(module);
if(newmodule)
return newmodule;
/* no file, try importing from memory */
PyErr_Fetch( &exception, &err, &tb ); /*restore for probable later use */
PyErr_Fetch(&exception, &err, &tb); /*restore for probable later use */
newmodule = bpy_text_reimport( module, &found );
if( newmodule ) {/* found module as blender text, ignore above exception */
PyErr_Clear( );
Py_XDECREF( exception );
Py_XDECREF( err );
Py_XDECREF( tb );
/* printf( "imported from text buffer...\n" ); */
newmodule= bpy_text_reimport(module, &found);
if(newmodule) {/* found module as blender text, ignore above exception */
PyErr_Clear();
Py_XDECREF(exception);
Py_XDECREF(err);
Py_XDECREF(tb);
/* printf("imported from text buffer...\n"); */
}
else if (found==1) { /* blender text module failed to execute but was found, use its error message */
Py_XDECREF( exception );
Py_XDECREF( err );
Py_XDECREF( tb );
Py_XDECREF(exception);
Py_XDECREF(err);
Py_XDECREF(tb);
return NULL;
}
else {
/* no blender text was found that could import the module
* rause the original error from PyImport_ImportModuleEx */
PyErr_Restore( exception, err, tb );
PyErr_Restore(exception, err, tb);
}
return newmodule;
}
PyMethodDef bpy_import_meth = {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"};
PyMethodDef bpy_reload_meth = {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"};
PyMethodDef bpy_import_meth= {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"};
PyMethodDef bpy_reload_meth= {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"};
/* Clear user modules.
@@ -329,7 +348,7 @@ void bpy_text_clear_modules(int clear_all)
/* looping over the dict */
PyObject *key, *value;
int pos = 0;
int pos= 0;
/* new list */
PyObject *list;
@@ -346,7 +365,7 @@ void bpy_text_clear_modules(int clear_all)
fname= PyModule_GetFilename(value);
if(fname) {
if (clear_all || ((strstr(fname, SEPSTR))==0)) { /* no path ? */
file_extension = strstr(fname, ".py");
file_extension= strstr(fname, ".py");
if(file_extension && (*(file_extension + 3) == '\0' || *(file_extension + 4) == '\0')) { /* .py or pyc extension? */
/* now we can be fairly sure its a python import from the blendfile */
PyList_Append(list, key); /* free'd with the list */

View File

@@ -26,6 +26,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/bpy_internal_import.h
* \ingroup pygen
*/
/* Note, the BGE needs to use this too, keep it minimal */
#ifndef BPY_INTERNAL_IMPORT_H
@@ -42,12 +47,14 @@
struct Text;
void bpy_import_init(PyObject *builtins);
PyObject* bpy_text_import(struct Text *text);
PyObject* bpy_text_import_name(char *name, int *found);
PyObject* bpy_text_reimport(PyObject *module, int *found);
/* void bpy_text_clear_modules(int clear_all);*/ /* Clear user modules */
void bpy_text_filename_get(char *fn, struct Text *text);
void bpy_text_filename_get(char *fn, size_t fn_len, struct Text *text);
extern PyMethodDef bpy_import_meth;
extern PyMethodDef bpy_reload_meth;

View File

@@ -27,64 +27,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
/* Note: Changes to Mathutils since 2.4x
* use radians rather then degrees
* - Mathutils.Vector/Euler/Quaternion(), now only take single sequence arguments.
* - Mathutils.MidpointVecs --> vector.lerp(other, fac)
* - Mathutils.AngleBetweenVecs --> vector.angle(other)
* - Mathutils.ProjectVecs --> vector.project(other)
* - Mathutils.DifferenceQuats --> quat.difference(other)
* - Mathutils.Slerp --> quat.slerp(other, fac)
* - Mathutils.Rand: removed, use pythons random module
* - Mathutils.RotationMatrix(angle, size, axis_flag, axis) --> Mathutils.RotationMatrix(angle, size, axis); merge axis & axis_flag args
* - Mathutils.OrthoProjectionMatrix(plane, size, axis) --> Mathutils.OrthoProjectionMatrix(axis, size); merge axis & plane args
* - Mathutils.ShearMatrix(plane, factor, size) --> Mathutils.ShearMatrix(plane, size, factor); swap size & factor args, match other constructors.
* - Matrix.scalePart --> Matrix.scale_part
* - Matrix.translationPart --> Matrix.translation_part
* - Matrix.rotationPart --> Matrix.rotation_part
* - mathutils.Matrix.Shear(plane, fac, size), now takes a pair of floats for 3x3 or 4x4 shear factor.
* - toMatrix --> to_matrix
* - toEuler --> to_euler
* - toQuat --> to_quat
* - Vector.toTrackQuat --> Vector.to_track_quat
* - Vector.rotate(axis, angle) --> rotate(other), where other can be Euler/Quaternion/Matrix.
* - Quaternion * Quaternion --> cross product (not dot product)
* - Euler.rotate(angle, axis) --> Euler.rotate_axis(axis, angle)
* - Euler.unique() *removed*, not a standard function only toggled different rotations.
* - Matrix.rotation_part() -> to_3x3()
* - Matrix.scale_part() -> to_scale()
* - Matrix.translation_part() -> to_translation()
* - Matrix.resize4x4() -> resize_4x4()
* - Euler.to_quat() -> to_quaternion()
* - Matrix.to_quat() -> to_quaternion()
* resizing nolonger returns the resized value.
* - Vector.resize2D -> resize_2d
* - Vector.resize3D -> resize_3d
* - Vector.resize4D -> resize_4d
* added new functions.
* - Vector.to_2d()
* - Vector.to_3d()
* - Vector.to_4d()
* moved into class functions.
* - Mathutils.RotationMatrix -> mathutils.Matrix.Rotation
* - Mathutils.ScaleMatrix -> mathutils.Matrix.Scale
* - Mathutils.ShearMatrix -> mathutils.Matrix.Shear
* - Mathutils.TranslationMatrix -> mathutils.Matrix.Translation
* - Mathutils.OrthoProjectionMatrix -> mathutils.Matrix.OrthoProjection
*
* Moved to Geometry module: Intersect, TriangleArea, TriangleNormal, QuadNormal, LineIntersect
* - geometry.Intersect -> intersect_ray_tri
* - geometry.ClosestPointOnLine -> intersect_point_line
* - geometry.PointInTriangle2D -> intersect_point_tri_2d
* - geometry.PointInQuad2D -> intersect_point_quad_2d
* - geometry.LineIntersect -> intersect_line_line
* - geometry.LineIntersect2D -> intersect_line_line_2d
* - geometry.BezierInterp -> interpolate_bezier
* - geometry.TriangleArea -> area_tri
* - geometry.QuadNormal, TriangleNormal -> normal
* - geometry.PolyFill -> tesselate_polygon
* - geometry.BoxPack2D -> box_pack_2d
* - geometry.BarycentricTransform -> barycentric_transform
/** \file blender/python/generic/mathutils.c
* \ingroup pygen
*/
#include <Python.h>
@@ -94,9 +38,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
//-------------------------DOC STRINGS ---------------------------
static char M_Mathutils_doc[] =
"This module provides access to matrices, eulers, quaternions and vectors."
;
@@ -125,7 +66,7 @@ static int mathutils_array_parse_fast(float *array, int array_min, int array_max
i= size;
do {
i--;
if(((array[i]= PyFloat_AsDouble((item= PySequence_Fast_GET_ITEM(value_fast, i)))) == -1.0) && PyErr_Occurred()) {
if(((array[i]= PyFloat_AsDouble((item= PySequence_Fast_GET_ITEM(value_fast, i)))) == -1.0f) && PyErr_Occurred()) {
PyErr_Format(PyExc_ValueError, "%.200s: sequence index %d expected a number, found '%.200s' type, ", error_prefix, i, Py_TYPE(item)->tp_name);
Py_DECREF(value_fast);
return -1;
@@ -147,7 +88,7 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
(QuaternionObject_Check(value) && (size= 4)) ||
(ColorObject_Check(value) && (size= 3))
) {
if(!BaseMath_ReadCallback((BaseMathObject *)value)) {
if(BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
return -1;
}
@@ -170,7 +111,7 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
{
if(EulerObject_Check(value)) {
if(!BaseMath_ReadCallback((BaseMathObject *)value)) {
if(BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
return -1;
}
else {
@@ -179,7 +120,7 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error
}
}
else if (QuaternionObject_Check(value)) {
if(!BaseMath_ReadCallback((BaseMathObject *)value)) {
if(BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
return -1;
}
else {
@@ -190,7 +131,7 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error
}
}
else if (MatrixObject_Check(value)) {
if(!BaseMath_ReadCallback((BaseMathObject *)value)) {
if(BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
return -1;
}
else if(((MatrixObject *)value)->col_size < 3 || ((MatrixObject *)value)->row_size < 3) {
@@ -269,45 +210,45 @@ int Mathutils_RegisterCallback(Mathutils_Callback *cb)
int _BaseMathObject_ReadCallback(BaseMathObject *self)
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
if(cb->get(self, self->cb_subtype))
return 1;
if(cb->get(self, self->cb_subtype) != -1)
return 0;
if(!PyErr_Occurred())
PyErr_Format(PyExc_RuntimeError, "%s user has become invalid", Py_TYPE(self)->tp_name);
return 0;
PyErr_Format(PyExc_RuntimeError, "%s read, user has become invalid", Py_TYPE(self)->tp_name);
return -1;
}
int _BaseMathObject_WriteCallback(BaseMathObject *self)
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
if(cb->set(self, self->cb_subtype))
return 1;
if(cb->set(self, self->cb_subtype) != -1)
return 0;
if(!PyErr_Occurred())
PyErr_Format(PyExc_RuntimeError, "%s user has become invalid", Py_TYPE(self)->tp_name);
return 0;
PyErr_Format(PyExc_RuntimeError, "%s write, user has become invalid", Py_TYPE(self)->tp_name);
return -1;
}
int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index)
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
if(cb->get_index(self, self->cb_subtype, index))
return 1;
if(cb->get_index(self, self->cb_subtype, index) != -1)
return 0;
if(!PyErr_Occurred())
PyErr_Format(PyExc_RuntimeError, "%s user has become invalid", Py_TYPE(self)->tp_name);
return 0;
PyErr_Format(PyExc_RuntimeError, "%s read index, user has become invalid", Py_TYPE(self)->tp_name);
return -1;
}
int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index)
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
if(cb->set_index(self, self->cb_subtype, index))
return 1;
if(cb->set_index(self, self->cb_subtype, index) != -1)
return 0;
if(!PyErr_Occurred())
PyErr_Format(PyExc_RuntimeError, "%s user has become invalid", Py_TYPE(self)->tp_name);
return 0;
PyErr_Format(PyExc_RuntimeError, "%s write index, user has become invalid", Py_TYPE(self)->tp_name);
return -1;
}
/* BaseMathObject generic functions for all mathutils types */
@@ -344,7 +285,10 @@ void BaseMathObject_dealloc(BaseMathObject *self)
PyMem_Free(self->data);
}
BaseMathObject_clear(self);
if(self->cb_user) {
PyObject_GC_UnTrack(self);
BaseMathObject_clear(self);
}
Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); // breaks subtypes
}
@@ -371,28 +315,28 @@ PyMODINIT_FUNC BPyInit_mathutils(void)
PyObject *submodule;
PyObject *item;
if( PyType_Ready( &vector_Type ) < 0 )
if(PyType_Ready(&vector_Type) < 0)
return NULL;
if( PyType_Ready( &matrix_Type ) < 0 )
if(PyType_Ready(&matrix_Type) < 0)
return NULL;
if( PyType_Ready( &euler_Type ) < 0 )
if(PyType_Ready(&euler_Type) < 0)
return NULL;
if( PyType_Ready( &quaternion_Type ) < 0 )
if(PyType_Ready(&quaternion_Type) < 0)
return NULL;
if( PyType_Ready( &color_Type ) < 0 )
if(PyType_Ready(&color_Type) < 0)
return NULL;
submodule = PyModule_Create(&M_Mathutils_module_def);
/* each type has its own new() function */
PyModule_AddObject( submodule, "Vector", (PyObject *)&vector_Type );
PyModule_AddObject( submodule, "Matrix", (PyObject *)&matrix_Type );
PyModule_AddObject( submodule, "Euler", (PyObject *)&euler_Type );
PyModule_AddObject( submodule, "Quaternion", (PyObject *)&quaternion_Type );
PyModule_AddObject( submodule, "Color", (PyObject *)&color_Type );
PyModule_AddObject(submodule, "Vector", (PyObject *)&vector_Type);
PyModule_AddObject(submodule, "Matrix", (PyObject *)&matrix_Type);
PyModule_AddObject(submodule, "Euler", (PyObject *)&euler_Type);
PyModule_AddObject(submodule, "Quaternion", (PyObject *)&quaternion_Type);
PyModule_AddObject(submodule, "Color", (PyObject *)&color_Type);
/* submodule */
PyModule_AddObject( submodule, "geometry", (item=BPyInit_mathutils_geometry()));
PyModule_AddObject(submodule, "geometry", (item=BPyInit_mathutils_geometry()));
/* XXX, python doesnt do imports with this usefully yet
* 'from mathutils.geometry import PolyFill'
* ...fails without this. */

View File

@@ -26,6 +26,11 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/mathutils.h
* \ingroup pygen
*/
//Include this file for access to vector, quat, matrix, euler, etc...
#ifndef MATHUTILS_H
@@ -94,10 +99,10 @@ int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index);
int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
/* since this is called so often avoid where possible */
#define BaseMath_ReadCallback(_self) (((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self):1))
#define BaseMath_WriteCallback(_self) (((_self)->cb_user ?_BaseMathObject_WriteCallback((BaseMathObject *)_self):1))
#define BaseMath_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):1))
#define BaseMath_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):1))
#define BaseMath_ReadCallback(_self) (((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self):0))
#define BaseMath_WriteCallback(_self) (((_self)->cb_user ?_BaseMathObject_WriteCallback((BaseMathObject *)_self):0))
#define BaseMath_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):0))
#define BaseMath_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):0))
/* utility func */
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);

View File

@@ -22,6 +22,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/mathutils_Color.c
* \ingroup pygen
*/
#include <Python.h>
#include "mathutils.h"
@@ -92,7 +97,7 @@ static char Color_copy_doc[] =
;
static PyObject *Color_copy(ColorObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
return newColorObject(self->col, Py_NEW, Py_TYPE(self));
@@ -104,8 +109,8 @@ static PyObject *Color_copy(ColorObject *self)
static PyObject *Color_repr(ColorObject * self)
{
PyObject *ret, *tuple;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
tuple= Color_ToTupleExt(self, -1);
@@ -127,7 +132,7 @@ static PyObject* Color_richcmpr(PyObject *a, PyObject *b, int op)
ColorObject *colA= (ColorObject*)a;
ColorObject *colB= (ColorObject*)b;
if(!BaseMath_ReadCallback(colA) || !BaseMath_ReadCallback(colB))
if(BaseMath_ReadCallback(colA) == -1 || BaseMath_ReadCallback(colB) == -1)
return NULL;
ok= EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1) ? 0 : -1;
@@ -172,7 +177,7 @@ static PyObject *Color_item(ColorObject * self, int i)
return NULL;
}
if(!BaseMath_ReadIndexCallback(self, i))
if(BaseMath_ReadIndexCallback(self, i) == -1)
return NULL;
return PyFloat_FromDouble(self->col[i]);
@@ -198,7 +203,7 @@ static int Color_ass_item(ColorObject * self, int i, PyObject * value)
self->col[i] = f;
if(!BaseMath_WriteIndexCallback(self, i))
if(BaseMath_WriteIndexCallback(self, i) == -1)
return -1;
return 0;
@@ -210,7 +215,7 @@ static PyObject *Color_slice(ColorObject * self, int begin, int end)
PyObject *tuple;
int count;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
CLAMP(begin, 0, COLOR_SIZE);
@@ -232,13 +237,13 @@ static int Color_ass_slice(ColorObject * self, int begin, int end, PyObject * se
int i, size;
float col[COLOR_SIZE];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return -1;
CLAMP(begin, 0, COLOR_SIZE);
if (end<0) end= (COLOR_SIZE + 1) + end;
CLAMP(end, 0, COLOR_SIZE);
begin = MIN2(begin,end);
begin = MIN2(begin, end);
if((size=mathutils_array_parse(col, 0, COLOR_SIZE, seq, "mathutils.Color[begin:end] = []")) == -1)
return -1;
@@ -265,7 +270,8 @@ static PyObject *Color_subscript(ColorObject *self, PyObject *item)
if (i < 0)
i += COLOR_SIZE;
return Color_item(self, i);
} else if (PySlice_Check(item)) {
}
else if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx((void *)item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0)
@@ -338,7 +344,7 @@ static PyMappingMethods Color_AsMapping = {
};
/* color channel, vector.r/g/b */
static PyObject *Color_getChannel( ColorObject * self, void *type )
static PyObject *Color_getChannel(ColorObject * self, void *type)
{
return Color_item(self, GET_INT_FROM_POINTER(type));
}
@@ -349,12 +355,12 @@ static int Color_setChannel(ColorObject * self, PyObject * value, void * type)
}
/* color channel (HSV), color.h/s/v */
static PyObject *Color_getChannelHSV( ColorObject * self, void *type )
static PyObject *Color_getChannelHSV(ColorObject * self, void *type)
{
float hsv[3];
int i= GET_INT_FROM_POINTER(type);
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
@@ -373,7 +379,7 @@ static int Color_setChannelHSV(ColorObject * self, PyObject * value, void * type
return -1;
}
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return -1;
rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
@@ -381,7 +387,7 @@ static int Color_setChannelHSV(ColorObject * self, PyObject * value, void * type
hsv[i] = f;
hsv_to_rgb(hsv[0], hsv[1], hsv[2], &(self->col[0]), &(self->col[1]), &(self->col[2]));
if(!BaseMath_WriteCallback(self))
if(BaseMath_WriteCallback(self) == -1)
return -1;
return 0;
@@ -393,7 +399,7 @@ static PyObject *Color_getHSV(ColorObject * self, void *UNUSED(closure))
float hsv[3];
PyObject *ret;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
@@ -418,7 +424,7 @@ static int Color_setHSV(ColorObject * self, PyObject * value, void *UNUSED(closu
hsv_to_rgb(hsv[0], hsv[1], hsv[2], &(self->col[0]), &(self->col[1]), &(self->col[2]));
if(!BaseMath_WriteCallback(self))
if(BaseMath_WriteCallback(self) == -1)
return -1;
return 0;
@@ -440,7 +446,7 @@ static PyGetSetDef Color_getseters[] = {
{(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL},
{(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
@@ -551,6 +557,7 @@ PyObject *newColorObject_cb(PyObject *cb_user, int cb_type, int cb_subtype)
self->cb_user= cb_user;
self->cb_type= (unsigned char)cb_type;
self->cb_subtype= (unsigned char)cb_subtype;
PyObject_GC_Track(self);
}
return (PyObject *)self;

View File

@@ -28,6 +28,11 @@
*
*/
/** \file blender/python/generic/mathutils_Color.h
* \ingroup pygen
*/
#ifndef MATHUTILS_COLOR_H
#define MATHUTILS_COLOR_H

View File

@@ -26,6 +26,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/mathutils_Euler.c
* \ingroup pygen
*/
#include <Python.h>
#include "mathutils.h"
@@ -133,7 +138,7 @@ static PyObject *Euler_to_quaternion(EulerObject * self)
{
float quat[4];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
eulO_to_quat(quat, self->eul, self->order);
@@ -154,7 +159,7 @@ static PyObject *Euler_to_matrix(EulerObject * self)
{
float mat[9];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
eulO_to_mat3((float (*)[3])mat, self->eul, self->order);
@@ -172,7 +177,9 @@ static PyObject *Euler_zero(EulerObject * self)
{
zero_v3(self->eul);
(void)BaseMath_WriteCallback(self);
if(BaseMath_WriteCallback(self) == -1)
return NULL;
Py_RETURN_NONE;
}
@@ -192,7 +199,7 @@ static PyObject *Euler_rotate_axis(EulerObject * self, PyObject *args)
const char *axis;
if(!PyArg_ParseTuple(args, "sf:rotate", &axis, &angle)){
PyErr_SetString(PyExc_TypeError, "euler.rotate(): expected angle (float) and axis (x,y,z)");
PyErr_SetString(PyExc_TypeError, "euler.rotate(): expected angle (float) and axis (x, y, z)");
return NULL;
}
if(!(ELEM3(*axis, 'X', 'Y', 'Z') && axis[1]=='\0')){
@@ -200,7 +207,7 @@ static PyObject *Euler_rotate_axis(EulerObject * self, PyObject *args)
return NULL;
}
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
@@ -223,7 +230,7 @@ static PyObject *Euler_rotate(EulerObject * self, PyObject *value)
{
float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_any_to_rotmat(other_rmat, value, "euler.rotate(value)") == -1)
@@ -249,7 +256,7 @@ static PyObject *Euler_make_compatible(EulerObject * self, PyObject *value)
{
float teul[EULER_SIZE];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_array_parse(teul, EULER_SIZE, EULER_SIZE, value, "euler.make_compatible(other), invalid 'other' arg") == -1)
@@ -277,7 +284,7 @@ static char Euler_copy_doc[] =
;
static PyObject *Euler_copy(EulerObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
return newEulerObject(self->eul, self->order, Py_NEW, Py_TYPE(self));
@@ -290,7 +297,7 @@ static PyObject *Euler_repr(EulerObject * self)
{
PyObject *ret, *tuple;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
tuple= Euler_ToTupleExt(self, -1);
@@ -310,7 +317,7 @@ static PyObject* Euler_richcmpr(PyObject *a, PyObject *b, int op)
EulerObject *eulA= (EulerObject*)a;
EulerObject *eulB= (EulerObject*)b;
if(!BaseMath_ReadCallback(eulA) || !BaseMath_ReadCallback(eulB))
if(BaseMath_ReadCallback(eulA) == -1 || BaseMath_ReadCallback(eulB) == -1)
return NULL;
ok= ((eulA->order == eulB->order) && EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1)) ? 0 : -1;
@@ -355,7 +362,7 @@ static PyObject *Euler_item(EulerObject * self, int i)
return NULL;
}
if(!BaseMath_ReadIndexCallback(self, i))
if(BaseMath_ReadIndexCallback(self, i) == -1)
return NULL;
return PyFloat_FromDouble(self->eul[i]);
@@ -381,7 +388,7 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject *value)
self->eul[i] = f;
if(!BaseMath_WriteIndexCallback(self, i))
if(BaseMath_WriteIndexCallback(self, i) == -1)
return -1;
return 0;
@@ -393,7 +400,7 @@ static PyObject *Euler_slice(EulerObject * self, int begin, int end)
PyObject *tuple;
int count;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
CLAMP(begin, 0, EULER_SIZE);
@@ -415,13 +422,13 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end, PyObject * se
int i, size;
float eul[EULER_SIZE];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return -1;
CLAMP(begin, 0, EULER_SIZE);
if (end<0) end= (EULER_SIZE + 1) + end;
CLAMP(end, 0, EULER_SIZE);
begin = MIN2(begin,end);
begin = MIN2(begin, end);
if((size=mathutils_array_parse(eul, 0, EULER_SIZE, seq, "mathutils.Euler[begin:end] = []")) == -1)
return -1;
@@ -448,7 +455,8 @@ static PyObject *Euler_subscript(EulerObject *self, PyObject *item)
if (i < 0)
i += EULER_SIZE;
return Euler_item(self, i);
} else if (PySlice_Check(item)) {
}
else if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx((void *)item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0)
@@ -524,7 +532,7 @@ static PyMappingMethods Euler_AsMapping = {
/*
* euler axis, euler.x/y/z
*/
static PyObject *Euler_getAxis(EulerObject *self, void *type )
static PyObject *Euler_getAxis(EulerObject *self, void *type)
{
return Euler_item(self, GET_INT_FROM_POINTER(type));
}
@@ -537,7 +545,7 @@ static int Euler_setAxis(EulerObject *self, PyObject *value, void *type)
/* rotation order */
static PyObject *Euler_getOrder(EulerObject *self, void *UNUSED(closure))
{
if(!BaseMath_ReadCallback(self)) /* can read order too */
if(BaseMath_ReadCallback(self) == -1) /* can read order too */
return NULL;
return PyUnicode_FromString(euler_order_str(self));
@@ -567,7 +575,7 @@ static PyGetSetDef Euler_getseters[] = {
{(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL},
{(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
@@ -688,6 +696,7 @@ PyObject *newEulerObject_cb(PyObject *cb_user, short order, int cb_type, int cb_
self->cb_user= cb_user;
self->cb_type= (unsigned char)cb_type;
self->cb_subtype= (unsigned char)cb_subtype;
PyObject_GC_Track(self);
}
return (PyObject *)self;

View File

@@ -28,6 +28,11 @@
*
*/
/** \file blender/python/generic/mathutils_Euler.h
* \ingroup pygen
*/
#ifndef MATHUTILS_EULER_H
#define MATHUTILS_EULER_H

View File

@@ -25,6 +25,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/mathutils_Matrix.c
* \ingroup pygen
*/
#include <Python.h>
#include "mathutils.h"
@@ -51,13 +56,13 @@ static int mathutils_matrix_vector_get(BaseMathObject *bmo, int subtype)
MatrixObject *self= (MatrixObject *)bmo->cb_user;
int i;
if(!BaseMath_ReadCallback(self))
return 0;
if(BaseMath_ReadCallback(self) == -1)
return -1;
for(i=0; i < self->col_size; i++)
bmo->data[i]= self->matrix[subtype][i];
return 1;
return 0;
}
static int mathutils_matrix_vector_set(BaseMathObject *bmo, int subtype)
@@ -65,38 +70,38 @@ static int mathutils_matrix_vector_set(BaseMathObject *bmo, int subtype)
MatrixObject *self= (MatrixObject *)bmo->cb_user;
int i;
if(!BaseMath_ReadCallback(self))
return 0;
if(BaseMath_ReadCallback(self) == -1)
return -1;
for(i=0; i < self->col_size; i++)
self->matrix[subtype][i]= bmo->data[i];
(void)BaseMath_WriteCallback(self);
return 1;
return 0;
}
static int mathutils_matrix_vector_get_index(BaseMathObject *bmo, int subtype, int index)
{
MatrixObject *self= (MatrixObject *)bmo->cb_user;
if(!BaseMath_ReadCallback(self))
return 0;
if(BaseMath_ReadCallback(self) == -1)
return -1;
bmo->data[index]= self->matrix[subtype][index];
return 1;
return 0;
}
static int mathutils_matrix_vector_set_index(BaseMathObject *bmo, int subtype, int index)
{
MatrixObject *self= (MatrixObject *)bmo->cb_user;
if(!BaseMath_ReadCallback(self))
return 0;
if(BaseMath_ReadCallback(self) == -1)
return -1;
self->matrix[subtype][index]= bmo->data[index];
(void)BaseMath_WriteCallback(self);
return 1;
return 0;
}
Mathutils_Callback mathutils_matrix_vector_cb = {
@@ -109,7 +114,7 @@ Mathutils_Callback mathutils_matrix_vector_cb = {
/* matrix vector callbacks, this is so you can do matrix[i][j] = val */
//----------------------------------mathutils.Matrix() -----------------
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc.
//create a new matrix type
static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
@@ -180,7 +185,7 @@ static void matrix_3x3_as_4x4(float mat[16])
/*-----------------------CLASS-METHODS----------------------------*/
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc.
static char C_Matrix_Rotation_doc[] =
".. classmethod:: Rotation(angle, size, axis)\n"
"\n"
@@ -221,8 +226,7 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args)
}
}
/* clamp angle between -360 and 360 in radians */
angle= fmod(angle + M_PI*2, M_PI*4) - M_PI*2;
angle= angle_wrap_rad(angle);
if(matSize != 2 && matSize != 3 && matSize != 4) {
PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix");
@@ -252,21 +256,24 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args)
mat[1] = (float) sin (angle);
mat[2] = -((float) sin(angle));
mat[3] = (float) cos(angle);
} else if(strcmp(axis, "X") == 0) {
}
else if(strcmp(axis, "X") == 0) {
//rotation around X
mat[0] = 1.0f;
mat[4] = (float) cos(angle);
mat[5] = (float) sin(angle);
mat[7] = -((float) sin(angle));
mat[8] = (float) cos(angle);
} else if(strcmp(axis, "Y") == 0) {
}
else if(strcmp(axis, "Y") == 0) {
//rotation around Y
mat[0] = (float) cos(angle);
mat[2] = -((float) sin(angle));
mat[4] = 1.0f;
mat[6] = (float) sin(angle);
mat[8] = (float) cos(angle);
} else if(strcmp(axis, "Z") == 0) {
}
else if(strcmp(axis, "Z") == 0) {
//rotation around Z
mat[0] = (float) cos(angle);
mat[1] = (float) sin(angle);
@@ -311,7 +318,7 @@ static PyObject *C_Matrix_Translation(PyObject *cls, PyObject *value)
return newMatrixObject(mat, 4, 4, Py_NEW, (PyTypeObject *)cls);
}
//----------------------------------mathutils.Matrix.Scale() -------------
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc.
static char C_Matrix_Scale_doc[] =
".. classmethod:: Scale(factor, size, axis)\n"
"\n"
@@ -394,7 +401,7 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args)
return newMatrixObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls);
}
//----------------------------------mathutils.Matrix.OrthoProjection() ---
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc.
static char C_Matrix_OrthoProjection_doc[] =
".. classmethod:: OrthoProjection(axis, size)\n"
"\n"
@@ -534,7 +541,7 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
if(matSize == 2) {
float const factor= PyFloat_AsDouble(fac);
if(factor==-1.0 && PyErr_Occurred()) {
if(factor==-1.0f && PyErr_Occurred()) {
PyErr_SetString(PyExc_AttributeError, "mathutils.Matrix.Shear(): the factor to be a float");
return NULL;
}
@@ -605,7 +612,8 @@ static float matrix_determinant_internal(MatrixObject *self)
if(self->row_size == 2) {
return determinant_m2(self->matrix[0][0], self->matrix[0][1],
self->matrix[1][0], self->matrix[1][1]);
} else if(self->row_size == 3) {
}
else if(self->row_size == 3) {
return determinant_m3(self->matrix[0][0], self->matrix[0][1],
self->matrix[0][2], self->matrix[1][0],
self->matrix[1][1], self->matrix[1][2],
@@ -630,7 +638,7 @@ static PyObject *Matrix_to_quaternion(MatrixObject *self)
{
float quat[4];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
@@ -639,9 +647,10 @@ static PyObject *Matrix_to_quaternion(MatrixObject *self)
return NULL;
}
if(self->col_size == 3){
mat3_to_quat( quat,(float (*)[3])self->contigPtr);
}else{
mat4_to_quat( quat,(float (*)[4])self->contigPtr);
mat3_to_quat(quat, (float (*)[3])self->contigPtr);
}
else {
mat4_to_quat(quat, (float (*)[4])self->contigPtr);
}
return newQuaternionObject(quat, Py_NEW, NULL);
@@ -670,14 +679,14 @@ static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args)
float tmat[3][3];
float (*mat)[3];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat))
return NULL;
if(eul_compat) {
if(!BaseMath_ReadCallback(eul_compat))
if(BaseMath_ReadCallback(eul_compat) == -1)
return NULL;
copy_v3_v3(eul_compatf, eul_compat->eul);
@@ -686,10 +695,12 @@ static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args)
/*must be 3-4 cols, 3-4 rows, square matrix*/
if(self->col_size ==3 && self->row_size ==3) {
mat= (float (*)[3])self->contigPtr;
}else if (self->col_size ==4 && self->row_size ==4) {
}
else if (self->col_size ==4 && self->row_size ==4) {
copy_m3_m4(tmat, (float (*)[4])self->contigPtr);
mat= tmat;
}else {
}
else {
PyErr_SetString(PyExc_AttributeError, "Matrix.to_euler(): inappropriate matrix size - expects 3x3 or 4x4 matrix");
return NULL;
}
@@ -702,7 +713,7 @@ static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args)
}
if(eul_compat) {
if(order == 1) mat3_to_compatible_eul( eul, eul_compatf, mat);
if(order == 1) mat3_to_compatible_eul(eul, eul_compatf, mat);
else mat3_to_compatible_eulO(eul, eul_compatf, order, mat);
}
else {
@@ -746,7 +757,8 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
index = (4 * (self->row_size + (blank_rows - 1))) + x;
if (index == 10 || index == 15){
self->contigPtr[index] = 1.0f;
}else{
}
else {
self->contigPtr[index] = 0.0f;
}
}
@@ -754,7 +766,7 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
for(x = 1; x <= self->row_size; x++){
first_row_elem = (self->col_size * (self->row_size - x));
curr_pos = (first_row_elem + (self->col_size -1));
new_pos = (4 * (self->row_size - x )) + (curr_pos - first_row_elem);
new_pos = (4 * (self->row_size - x)) + (curr_pos - first_row_elem);
for(blank_columns = (4 - self->col_size); blank_columns > 0; blank_columns--){
self->contigPtr[new_pos + blank_columns] = 0.0f;
}
@@ -779,7 +791,7 @@ static char Matrix_to_4x4_doc[] =
;
static PyObject *Matrix_to_4x4(MatrixObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(self->col_size==4 && self->row_size==4) {
@@ -808,7 +820,7 @@ static PyObject *Matrix_to_3x3(MatrixObject *self)
{
float mat[3][3];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if((self->col_size < 3) || (self->row_size < 3)) {
@@ -831,7 +843,7 @@ static char Matrix_to_translation_doc[] =
;
static PyObject *Matrix_to_translation(MatrixObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if((self->col_size < 3) || self->row_size < 4){
@@ -858,7 +870,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self)
float mat[3][3];
float size[3];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
@@ -893,7 +905,7 @@ static PyObject *Matrix_invert(MatrixObject *self)
float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(self->row_size != self->col_size){
@@ -967,7 +979,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value)
{
float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_any_to_rotmat(other_rmat, value, "matrix.rotate(value)") == -1)
@@ -1009,7 +1021,7 @@ static PyObject *Matrix_decompose(MatrixObject *self)
return NULL;
}
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
mat4_to_loc_rot_size(loc, rot, size, (float (*)[4])self->contigPtr);
@@ -1050,7 +1062,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
return NULL;
}
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(mat2))
if(BaseMath_ReadCallback(self) == -1 || BaseMath_ReadCallback(mat2) == -1)
return NULL;
/* TODO, different sized matrix */
@@ -1081,7 +1093,7 @@ static char Matrix_determinant_doc[] =
;
static PyObject *Matrix_determinant(MatrixObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(self->row_size != self->col_size){
@@ -1103,7 +1115,7 @@ static PyObject *Matrix_transpose(MatrixObject *self)
{
float t = 0.0f;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(self->row_size != self->col_size){
@@ -1151,7 +1163,7 @@ static PyObject *Matrix_zero(MatrixObject *self)
{
fill_vn(self->contigPtr, self->row_size * self->col_size, 0.0f);
if(!BaseMath_WriteCallback(self))
if(BaseMath_WriteCallback(self) == -1)
return NULL;
Py_RETURN_NONE;
@@ -1168,7 +1180,7 @@ static char Matrix_identity_doc[] =
;
static PyObject *Matrix_identity(MatrixObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(self->row_size != self->col_size){
@@ -1187,7 +1199,7 @@ static PyObject *Matrix_identity(MatrixObject *self)
unit_m4((float (*)[4])self->contigPtr);
}
if(!BaseMath_WriteCallback(self))
if(BaseMath_WriteCallback(self) == -1)
return NULL;
Py_RETURN_NONE;
@@ -1204,7 +1216,7 @@ static char Matrix_copy_doc[] =
;
static PyObject *Matrix_copy(MatrixObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
return (PyObject*)newMatrixObject((float (*))self->contigPtr, self->row_size, self->col_size, Py_NEW, Py_TYPE(self));
@@ -1217,7 +1229,7 @@ static PyObject *Matrix_repr(MatrixObject *self)
int x, y;
PyObject *rows[MATRIX_MAX_DIM]= {NULL};
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
for(x = 0; x < self->row_size; x++){
@@ -1253,7 +1265,7 @@ static PyObject* Matrix_richcmpr(PyObject *a, PyObject *b, int op)
MatrixObject *matA= (MatrixObject*)a;
MatrixObject *matB= (MatrixObject*)b;
if(!BaseMath_ReadCallback(matA) || !BaseMath_ReadCallback(matB))
if(BaseMath_ReadCallback(matA) == -1 || BaseMath_ReadCallback(matB) == -1)
return NULL;
ok= ( (matA->col_size == matB->col_size) &&
@@ -1295,7 +1307,7 @@ static int Matrix_len(MatrixObject *self)
the wrapped vector gives direct access to the matrix data*/
static PyObject *Matrix_item(MatrixObject *self, int i)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(i < 0 || i >= self->row_size) {
@@ -1310,7 +1322,7 @@ static PyObject *Matrix_item(MatrixObject *self, int i)
static int Matrix_ass_item(MatrixObject *self, int i, PyObject *value)
{
float vec[4];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return -1;
if(i >= self->row_size || i < 0){
@@ -1336,12 +1348,12 @@ static PyObject *Matrix_slice(MatrixObject *self, int begin, int end)
PyObject *tuple;
int count;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
CLAMP(begin, 0, self->row_size);
CLAMP(end, 0, self->row_size);
begin= MIN2(begin,end);
begin= MIN2(begin, end);
tuple= PyTuple_New(end - begin);
for(count= begin; count < end; count++) {
@@ -1358,12 +1370,12 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
{
PyObject *value_fast= NULL;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return -1;
CLAMP(begin, 0, self->row_size);
CLAMP(end, 0, self->row_size);
begin = MIN2(begin,end);
begin = MIN2(begin, end);
/* non list/tuple cases */
if(!(value_fast=PySequence_Fast(value, "matrix[begin:end] = value"))) {
@@ -1415,7 +1427,7 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
return NULL;
}
if(!BaseMath_ReadCallback(mat1) || !BaseMath_ReadCallback(mat2))
if(BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1)
return NULL;
if(mat1->row_size != mat2->row_size || mat1->col_size != mat2->col_size){
@@ -1442,7 +1454,7 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
return NULL;
}
if(!BaseMath_ReadCallback(mat1) || !BaseMath_ReadCallback(mat2))
if(BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1)
return NULL;
if(mat1->row_size != mat2->row_size || mat1->col_size != mat2->col_size){
@@ -1471,12 +1483,12 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
if(MatrixObject_Check(m1)) {
mat1 = (MatrixObject*)m1;
if(!BaseMath_ReadCallback(mat1))
if(BaseMath_ReadCallback(mat1) == -1)
return NULL;
}
if(MatrixObject_Check(m2)) {
mat2 = (MatrixObject*)m2;
if(!BaseMath_ReadCallback(mat2))
if(BaseMath_ReadCallback(mat2) == -1)
return NULL;
}
@@ -1507,12 +1519,12 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
}
}
else if(mat2) {
if (((scalar= PyFloat_AsDouble(m1)) == -1.0 && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX */
if (((scalar= PyFloat_AsDouble(m1)) == -1.0f && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX */
return matrix_mul_float(mat2, scalar);
}
}
else if(mat1) {
if (((scalar= PyFloat_AsDouble(m2)) == -1.0 && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX */
if (((scalar= PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX */
return matrix_mul_float(mat1, scalar);
}
}
@@ -1525,7 +1537,7 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
}
static PyObject* Matrix_inv(MatrixObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
return Matrix_invert(self);
@@ -1666,7 +1678,7 @@ static PyObject *Matrix_getMedianScale(MatrixObject *self, void *UNUSED(closure)
{
float mat[3][3];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
@@ -1682,7 +1694,7 @@ static PyObject *Matrix_getMedianScale(MatrixObject *self, void *UNUSED(closure)
static PyObject *Matrix_getIsNegative(MatrixObject *self, void *UNUSED(closure))
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
@@ -1707,7 +1719,7 @@ static PyGetSetDef Matrix_getseters[] = {
{(char *)"is_negative", (getter)Matrix_getIsNegative, (setter)NULL, (char *)"True if this matrix results in a negative scale, 3x3 and 4x4 only, (readonly).\n\n:type: bool", NULL},
{(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL},
{(char *)"owner",(getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
/*-----------------------METHOD DEFINITIONS ----------------------*/
@@ -1868,7 +1880,7 @@ PyObject *newMatrixObject(float *mat, const unsigned short rowSize, const unsign
}
}
}
else if (rowSize == colSize ) { /*or if no arguments are passed return identity matrix for square matrices */
else if (rowSize == colSize) { /*or if no arguments are passed return identity matrix for square matrices */
PyObject *ret_dummy= Matrix_identity(self);
Py_DECREF(ret_dummy);
}
@@ -1890,6 +1902,7 @@ PyObject *newMatrixObject_cb(PyObject *cb_user, int rowSize, int colSize, int cb
self->cb_user= cb_user;
self->cb_type= (unsigned char)cb_type;
self->cb_subtype= (unsigned char)cb_subtype;
PyObject_GC_Track(self);
}
return (PyObject *) self;
}

View File

@@ -27,6 +27,11 @@
*
*/
/** \file blender/python/generic/mathutils_Matrix.h
* \ingroup pygen
*/
#ifndef MATHUTILS_MATRIX_H
#define MATHUTILS_MATRIX_H

View File

@@ -26,6 +26,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/mathutils_Quaternion.c
* \ingroup pygen
*/
#include <Python.h>
#include "mathutils.h"
@@ -85,7 +90,7 @@ static PyObject *Quaternion_to_euler(QuaternionObject *self, PyObject *args)
if(!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat))
return NULL;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(order_str) {
@@ -100,7 +105,7 @@ static PyObject *Quaternion_to_euler(QuaternionObject *self, PyObject *args)
if(eul_compat) {
float mat[3][3];
if(!BaseMath_ReadCallback(eul_compat))
if(BaseMath_ReadCallback(eul_compat) == -1)
return NULL;
quat_to_mat3(mat, tquat);
@@ -128,10 +133,10 @@ static PyObject *Quaternion_to_matrix(QuaternionObject *self)
{
float mat[9]; /* all values are set */
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
quat_to_mat3( (float (*)[3]) mat,self->quat);
quat_to_mat3((float (*)[3])mat, self->quat);
return newMatrixObject(mat, 3, 3, Py_NEW, NULL);
}
@@ -150,7 +155,7 @@ static PyObject *Quaternion_cross(QuaternionObject *self, PyObject *value)
{
float quat[QUAT_SIZE], tquat[QUAT_SIZE];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "quaternion.cross(other), invalid 'other' arg") == -1)
@@ -175,7 +180,7 @@ static PyObject *Quaternion_dot(QuaternionObject *self, PyObject *value)
{
float tquat[QUAT_SIZE];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "quaternion.dot(other), invalid 'other' arg") == -1)
@@ -184,7 +189,7 @@ static PyObject *Quaternion_dot(QuaternionObject *self, PyObject *value)
return PyFloat_FromDouble(dot_qtqt(self->quat, tquat));
}
static char Quaternion_difference_doc[] =
static char Quaternion_rotation_difference_doc[] =
".. function:: difference(other)\n"
"\n"
" Returns a quaternion representing the rotational difference.\n"
@@ -194,11 +199,11 @@ static char Quaternion_difference_doc[] =
" :return: the rotational difference between the two quat rotations.\n"
" :rtype: :class:`Quaternion`\n"
;
static PyObject *Quaternion_difference(QuaternionObject *self, PyObject *value)
static PyObject *Quaternion_rotation_difference(QuaternionObject *self, PyObject *value)
{
float tquat[QUAT_SIZE], quat[QUAT_SIZE];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "quaternion.difference(other), invalid 'other' arg") == -1)
@@ -231,7 +236,7 @@ static PyObject *Quaternion_slerp(QuaternionObject *self, PyObject *args)
return NULL;
}
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "quaternion.slerp(other), invalid 'other' arg") == -1)
@@ -260,7 +265,7 @@ static PyObject *Quaternion_rotate(QuaternionObject *self, PyObject *value)
float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
float tquat[4], length;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_any_to_rotmat(other_rmat, value, "quaternion.rotate(value)") == -1)
@@ -278,7 +283,7 @@ static PyObject *Quaternion_rotate(QuaternionObject *self, PyObject *value)
}
//----------------------------Quaternion.normalize()----------------
//normalize the axis of rotation of [theta,vector]
//normalize the axis of rotation of [theta, vector]
static char Quaternion_normalize_doc[] =
".. function:: normalize()\n"
"\n"
@@ -286,7 +291,7 @@ static char Quaternion_normalize_doc[] =
;
static PyObject *Quaternion_normalize(QuaternionObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
normalize_qt(self->quat);
@@ -315,7 +320,7 @@ static char Quaternion_invert_doc[] =
;
static PyObject *Quaternion_invert(QuaternionObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
invert_qt(self->quat);
@@ -347,7 +352,7 @@ static char Quaternion_identity_doc[] =
;
static PyObject *Quaternion_identity(QuaternionObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
unit_qt(self->quat);
@@ -366,7 +371,7 @@ static char Quaternion_negate_doc[] =
;
static PyObject *Quaternion_negate(QuaternionObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
mul_qt_fl(self->quat, -1.0f);
@@ -382,7 +387,7 @@ static char Quaternion_conjugate_doc[] =
;
static PyObject *Quaternion_conjugate(QuaternionObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
conjugate_qt(self->quat);
@@ -416,7 +421,7 @@ static char Quaternion_copy_doc[] =
;
static PyObject *Quaternion_copy(QuaternionObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
return newQuaternionObject(self->quat, Py_NEW, Py_TYPE(self));
@@ -428,7 +433,7 @@ static PyObject *Quaternion_repr(QuaternionObject *self)
{
PyObject *ret, *tuple;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
tuple= Quaternion_to_tuple_ext(self, -1);
@@ -448,7 +453,7 @@ static PyObject* Quaternion_richcmpr(PyObject *a, PyObject *b, int op)
QuaternionObject *quatA= (QuaternionObject *)a;
QuaternionObject *quatB= (QuaternionObject *)b;
if(!BaseMath_ReadCallback(quatA) || !BaseMath_ReadCallback(quatB))
if(BaseMath_ReadCallback(quatA) == -1 || BaseMath_ReadCallback(quatB) == -1)
return NULL;
ok= (EXPP_VectorsAreEqual(quatA->quat, quatB->quat, QUAT_SIZE, 1)) ? 0 : -1;
@@ -493,7 +498,7 @@ static PyObject *Quaternion_item(QuaternionObject *self, int i)
return NULL;
}
if(!BaseMath_ReadIndexCallback(self, i))
if(BaseMath_ReadIndexCallback(self, i) == -1)
return NULL;
return PyFloat_FromDouble(self->quat[i]);
@@ -517,7 +522,7 @@ static int Quaternion_ass_item(QuaternionObject *self, int i, PyObject *ob)
}
self->quat[i] = scalar;
if(!BaseMath_WriteIndexCallback(self, i))
if(BaseMath_WriteIndexCallback(self, i) == -1)
return -1;
return 0;
@@ -529,7 +534,7 @@ static PyObject *Quaternion_slice(QuaternionObject *self, int begin, int end)
PyObject *tuple;
int count;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
CLAMP(begin, 0, QUAT_SIZE);
@@ -551,13 +556,13 @@ static int Quaternion_ass_slice(QuaternionObject *self, int begin, int end, PyOb
int i, size;
float quat[QUAT_SIZE];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return -1;
CLAMP(begin, 0, QUAT_SIZE);
if (end<0) end= (QUAT_SIZE + 1) + end;
CLAMP(end, 0, QUAT_SIZE);
begin = MIN2(begin,end);
begin = MIN2(begin, end);
if((size=mathutils_array_parse(quat, 0, QUAT_SIZE, seq, "mathutils.Quaternion[begin:end] = []")) == -1)
return -1;
@@ -654,7 +659,7 @@ static PyObject *Quaternion_add(PyObject *q1, PyObject *q2)
quat1 = (QuaternionObject*)q1;
quat2 = (QuaternionObject*)q2;
if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2))
if(BaseMath_ReadCallback(quat1) == -1 || BaseMath_ReadCallback(quat2) == -1)
return NULL;
add_qt_qtqt(quat, quat1->quat, quat2->quat, 1.0f);
@@ -676,7 +681,7 @@ static PyObject *Quaternion_sub(PyObject *q1, PyObject *q2)
quat1 = (QuaternionObject*)q1;
quat2 = (QuaternionObject*)q2;
if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2))
if(BaseMath_ReadCallback(quat1) == -1 || BaseMath_ReadCallback(quat2) == -1)
return NULL;
for(x = 0; x < QUAT_SIZE; x++) {
@@ -703,12 +708,12 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
if(QuaternionObject_Check(q1)) {
quat1 = (QuaternionObject*)q1;
if(!BaseMath_ReadCallback(quat1))
if(BaseMath_ReadCallback(quat1) == -1)
return NULL;
}
if(QuaternionObject_Check(q2)) {
quat2 = (QuaternionObject*)q2;
if(!BaseMath_ReadCallback(quat2))
if(BaseMath_ReadCallback(quat2) == -1)
return NULL;
}
@@ -716,14 +721,14 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
mul_qt_qtqt(quat, quat1->quat, quat2->quat);
return newQuaternionObject(quat, Py_NEW, Py_TYPE(q1));
}
/* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */
/* the only case this can happen (for a supported type is "FLOAT*QUAT") */
else if(quat2) { /* FLOAT*QUAT */
if(((scalar= PyFloat_AsDouble(q1)) == -1.0 && PyErr_Occurred())==0) {
if(((scalar= PyFloat_AsDouble(q1)) == -1.0f && PyErr_Occurred())==0) {
return quat_mul_float(quat2, scalar);
}
}
else if (quat1) { /* QUAT*FLOAT */
if((((scalar= PyFloat_AsDouble(q2)) == -1.0 && PyErr_Occurred())==0)) {
if((((scalar= PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred())==0)) {
return quat_mul_float(quat1, scalar);
}
}
@@ -741,7 +746,7 @@ static PyObject *Quaternion_neg(QuaternionObject *self)
{
float tquat[QUAT_SIZE];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
negate_v4_v4(tquat, self->quat);
@@ -806,19 +811,19 @@ static PyNumberMethods Quaternion_NumMethods = {
NULL, /* nb_index */
};
static PyObject *Quaternion_getAxis( QuaternionObject *self, void *type )
static PyObject *Quaternion_getAxis(QuaternionObject *self, void *type)
{
return Quaternion_item(self, GET_INT_FROM_POINTER(type));
}
static int Quaternion_setAxis( QuaternionObject *self, PyObject *value, void *type )
static int Quaternion_setAxis(QuaternionObject *self, PyObject *value, void *type)
{
return Quaternion_ass_item(self, GET_INT_FROM_POINTER(type), value);
}
static PyObject *Quaternion_getMagnitude(QuaternionObject *self, void *UNUSED(closure))
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
return PyFloat_FromDouble(sqrt(dot_qtqt(self->quat, self->quat)));
@@ -828,11 +833,11 @@ static PyObject *Quaternion_getAngle(QuaternionObject *self, void *UNUSED(closur
{
float tquat[4];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
normalize_qt_qt(tquat, self->quat);
return PyFloat_FromDouble(2.0 * (saacos(tquat[0])));
return PyFloat_FromDouble(2.0f * (saacos(tquat[0])));
}
static int Quaternion_setAngle(QuaternionObject *self, PyObject *value, void *UNUSED(closure))
@@ -843,7 +848,7 @@ static int Quaternion_setAngle(QuaternionObject *self, PyObject *value, void *UN
float axis[3], angle_dummy;
double angle;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return -1;
len= normalize_qt_qt(tquat, self->quat);
@@ -851,15 +856,15 @@ static int Quaternion_setAngle(QuaternionObject *self, PyObject *value, void *UN
angle= PyFloat_AsDouble(value);
if(angle==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
if(angle==-1.0 && PyErr_Occurred()) { /* parsed item not a number */
PyErr_SetString(PyExc_TypeError, "quaternion.angle = value: float expected");
return -1;
}
angle= fmod(angle + M_PI*2, M_PI*4) - M_PI*2;
angle= angle_wrap_rad(angle);
/* 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) &&
if( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) &&
EXPP_FloatsAreEqual(axis[1], 0.0f, 10) &&
EXPP_FloatsAreEqual(axis[2], 0.0f, 10)
) {
@@ -869,7 +874,7 @@ static int Quaternion_setAngle(QuaternionObject *self, PyObject *value, void *UN
axis_angle_to_quat(self->quat, axis, angle);
mul_qt_fl(self->quat, len);
if(!BaseMath_WriteCallback(self))
if(BaseMath_WriteCallback(self) == -1)
return -1;
return 0;
@@ -882,14 +887,14 @@ static PyObject *Quaternion_getAxisVec(QuaternionObject *self, void *UNUSED(clos
float axis[3];
float angle;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
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) &&
if( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) &&
EXPP_FloatsAreEqual(axis[1], 0.0f, 10) &&
EXPP_FloatsAreEqual(axis[2], 0.0f, 10)
) {
@@ -907,7 +912,7 @@ static int Quaternion_setAxisVec(QuaternionObject *self, PyObject *value, void *
float axis[3];
float angle;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return -1;
len= normalize_qt_qt(tquat, self->quat);
@@ -919,7 +924,7 @@ static int Quaternion_setAxisVec(QuaternionObject *self, PyObject *value, void *
axis_angle_to_quat(self->quat, axis, angle);
mul_qt_fl(self->quat, len);
if(!BaseMath_WriteCallback(self))
if(BaseMath_WriteCallback(self) == -1)
return -1;
return 0;
@@ -950,7 +955,7 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
case 2:
if (mathutils_array_parse(quat, 3, 3, seq, "mathutils.Quaternion()") == -1)
return NULL;
angle= fmod(angle + M_PI*2, M_PI*4) - M_PI*2; /* clamp because of precision issues */
angle= angle_wrap_rad(angle); /* clamp because of precision issues */
axis_angle_to_quat(quat, quat, angle);
break;
/* PyArg_ParseTuple assures no more then 2 */
@@ -995,7 +1000,7 @@ static struct PyMethodDef Quaternion_methods[] = {
/* operation between 2 or more types */
{"cross", (PyCFunction) Quaternion_cross, METH_O, Quaternion_cross_doc},
{"dot", (PyCFunction) Quaternion_dot, METH_O, Quaternion_dot_doc},
{"difference", (PyCFunction) Quaternion_difference, METH_O, Quaternion_difference_doc},
{"rotation_difference", (PyCFunction) Quaternion_rotation_difference, METH_O, Quaternion_rotation_difference_doc},
{"slerp", (PyCFunction) Quaternion_slerp, METH_VARARGS, Quaternion_slerp_doc},
{"rotate", (PyCFunction) Quaternion_rotate, METH_O, Quaternion_rotate_doc},
@@ -1017,7 +1022,7 @@ static PyGetSetDef Quaternion_getseters[] = {
{(char *)"axis",(getter)Quaternion_getAxisVec, (setter)Quaternion_setAxisVec, (char *)"quaternion axis as a vector.\n\n:type: :class:`Vector`", NULL},
{(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL},
{(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
//------------------PY_OBECT DEFINITION--------------------------
@@ -1098,12 +1103,13 @@ PyObject *newQuaternionObject(float *quat, int type, PyTypeObject *base_type)
self->quat = PyMem_Malloc(QUAT_SIZE * sizeof(float));
if(!quat) { //new empty
unit_qt(self->quat);
}else{
}
else {
QUATCOPY(self->quat, quat);
}
self->wrapped = Py_NEW;
}
else{
else {
PyErr_SetString(PyExc_RuntimeError, "Quaternion(): invalid type");
return NULL;
}
@@ -1119,6 +1125,7 @@ PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype)
self->cb_user= cb_user;
self->cb_type= (unsigned char)cb_type;
self->cb_subtype= (unsigned char)cb_subtype;
PyObject_GC_Track(self);
}
return (PyObject *)self;

View File

@@ -28,6 +28,11 @@
*
*/
/** \file blender/python/generic/mathutils_Quaternion.h
* \ingroup pygen
*/
#ifndef MATHUTILS_QUAT_H
#define MATHUTILS_QUAT_H

View File

@@ -25,6 +25,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/mathutils_Vector.c
* \ingroup pygen
*/
#include <Python.h>
#include "mathutils.h"
@@ -91,7 +96,9 @@ static PyObject *Vector_zero(VectorObject *self)
{
fill_vn(self->vec, self->size, 0.0f);
(void)BaseMath_WriteCallback(self);
if(BaseMath_WriteCallback(self) == -1)
return NULL;
Py_RETURN_NONE;
}
@@ -109,7 +116,7 @@ static PyObject *Vector_normalize(VectorObject *self)
int i;
float norm = 0.0f;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
for(i = 0; i < self->size; i++) {
@@ -221,10 +228,12 @@ static PyObject *Vector_resize_4d(VectorObject *self)
PyErr_SetString(PyExc_MemoryError, "vector.resize_4d(): problem allocating pointer space");
return NULL;
}
if(self->size == 2){
self->vec[2] = 0.0f;
self->vec[3] = 1.0f;
}else if(self->size == 3){
}
else if(self->size == 3){
self->vec[3] = 1.0f;
}
self->size = 4;
@@ -240,7 +249,7 @@ static char Vector_to_2d_doc[] =
;
static PyObject *Vector_to_2d(VectorObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
return newVectorObject(self->vec, 2, Py_NEW, Py_TYPE(self));
@@ -257,7 +266,7 @@ static PyObject *Vector_to_3d(VectorObject *self)
{
float tvec[3]= {0.0f};
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 3));
@@ -275,7 +284,7 @@ static PyObject *Vector_to_4d(VectorObject *self)
{
float tvec[4]= {0.0f, 0.0f, 0.0f, 1.0f};
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 4));
@@ -329,7 +338,7 @@ static PyObject *Vector_to_tuple(VectorObject *self, PyObject *args)
if(PyTuple_GET_SIZE(args)==0)
ndigits= -1;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
return Vector_to_tuple_ext(self, ndigits);
@@ -347,13 +356,13 @@ static char Vector_to_track_quat_doc[] =
" :return: rotation from the vector and the track and up axis.\n"
" :rtype: :class:`Quaternion`\n"
;
static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args )
static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args)
{
float vec[3], quat[4];
const char *strack, *sup;
short track = 2, up = 1;
if(!PyArg_ParseTuple( args, "|ss:to_track_quat", &strack, &sup))
if(!PyArg_ParseTuple(args, "|ss:to_track_quat", &strack, &sup))
return NULL;
if (self->size != 3) {
@@ -361,7 +370,7 @@ static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args )
return NULL;
}
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if (strack) {
@@ -444,7 +453,7 @@ static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args )
*/
negate_v3_v3(vec, self->vec);
vec_to_quat( quat,vec, track, up);
vec_to_quat(quat, vec, track, up);
return newQuaternionObject(quat, Py_NEW, NULL);
}
@@ -470,7 +479,7 @@ static PyObject *Vector_reflect(VectorObject *self, PyObject *value)
float reflect[3] = {0.0f};
float tvec[MAX_DIMENSIONS];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if((value_size= mathutils_array_parse(tvec, 2, 4, value, "vector.reflect(other), invalid 'other' arg")) == -1)
@@ -509,7 +518,7 @@ static PyObject *Vector_cross(VectorObject *self, PyObject *value)
VectorObject *ret;
float tvec[MAX_DIMENSIONS];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_array_parse(tvec, self->size, self->size, value, "vector.cross(other), invalid 'other' arg") == -1)
@@ -536,14 +545,14 @@ static PyObject *Vector_dot(VectorObject *self, PyObject *value)
double dot = 0.0;
int x;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_array_parse(tvec, self->size, self->size, value, "vector.dot(other), invalid 'other' arg") == -1)
return NULL;
for(x = 0; x < self->size; x++) {
dot += self->vec[x] * tvec[x];
dot += (double)(self->vec[x] * tvec[x]);
}
return PyFloat_FromDouble(dot);
@@ -575,15 +584,15 @@ static PyObject *Vector_angle(VectorObject *self, PyObject *args)
if(!PyArg_ParseTuple(args, "O|O:angle", &value, &fallback))
return NULL;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_array_parse(tvec, size, size, value, "vector.angle(other), invalid 'other' arg") == -1)
return NULL;
for(x = 0; x < size; x++) {
test_v1 += self->vec[x] * self->vec[x];
test_v2 += tvec[x] * tvec[x];
test_v1 += (double)(self->vec[x] * self->vec[x]);
test_v2 += (double)(tvec[x] * tvec[x]);
}
if (!test_v1 || !test_v2){
/* avoid exception */
@@ -599,14 +608,14 @@ static PyObject *Vector_angle(VectorObject *self, PyObject *args)
//dot product
for(x = 0; x < self->size; x++) {
dot += self->vec[x] * tvec[x];
dot += (double)(self->vec[x] * tvec[x]);
}
dot /= (sqrt(test_v1) * sqrt(test_v2));
return PyFloat_FromDouble(saacos(dot));
}
static char Vector_difference_doc[] =
static char Vector_rotation_difference_doc[] =
".. function:: difference(other)\n"
"\n"
" Returns a quaternion representing the rotational difference between this vector and another.\n"
@@ -618,7 +627,7 @@ static char Vector_difference_doc[] =
"\n"
" .. note:: 2D vectors raise an :exc:`AttributeError`.\n"
;
static PyObject *Vector_difference(VectorObject *self, PyObject *value)
static PyObject *Vector_rotation_difference(VectorObject *self, PyObject *value)
{
float quat[4], vec_a[3], vec_b[3];
@@ -627,7 +636,7 @@ static PyObject *Vector_difference(VectorObject *self, PyObject *value)
return NULL;
}
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_array_parse(vec_b, 3, MAX_DIMENSIONS, value, "vector.difference(other), invalid 'other' arg") == -1)
@@ -659,24 +668,24 @@ static PyObject *Vector_project(VectorObject *self, PyObject *value)
double dot = 0.0f, dot2 = 0.0f;
int x;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_array_parse(tvec, size, size, value, "vector.project(other), invalid 'other' arg") == -1)
return NULL;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
//get dot products
for(x = 0; x < size; x++) {
dot += self->vec[x] * tvec[x];
dot2 += tvec[x] * tvec[x];
dot += (double)(self->vec[x] * tvec[x]);
dot2 += (double)(tvec[x] * tvec[x]);
}
//projection
dot /= dot2;
for(x = 0; x < size; x++) {
vec[x] = (float)(dot * tvec[x]);
vec[x] = (float)dot * tvec[x];
}
return newVectorObject(vec, size, Py_NEW, Py_TYPE(self));
}
@@ -707,10 +716,10 @@ static PyObject *Vector_lerp(VectorObject *self, PyObject *args)
if(mathutils_array_parse(tvec, size, size, value, "vector.lerp(other), invalid 'other' arg") == -1)
return NULL;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
ifac= 1.0 - fac;
ifac= 1.0f - fac;
for(x = 0; x < size; x++) {
vec[x] = (ifac * self->vec[x]) + (fac * tvec[x]);
@@ -730,7 +739,7 @@ static PyObject *Vector_rotate(VectorObject *self, PyObject *value)
{
float other_rmat[3][3];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
if(mathutils_any_to_rotmat(other_rmat, value, "vector.rotate(value)") == -1)
@@ -759,7 +768,7 @@ static char Vector_copy_doc[] =
;
static PyObject *Vector_copy(VectorObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
return newVectorObject(self->vec, self->size, Py_NEW, Py_TYPE(self));
@@ -769,7 +778,7 @@ static PyObject *Vector_repr(VectorObject *self)
{
PyObject *ret, *tuple;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
tuple= Vector_to_tuple_ext(self, -1);
@@ -785,25 +794,31 @@ static int Vector_len(VectorObject *self)
return self->size;
}
/* sequence accessor (get): vector[index] */
static PyObject *Vector_item(VectorObject *self, int i)
static PyObject *vector_item_internal(VectorObject *self, int i, const int is_attr)
{
if(i<0) i= self->size-i;
if(i < 0 || i >= self->size) {
PyErr_SetString(PyExc_IndexError,"vector[index]: out of range");
if(is_attr) PyErr_Format(PyExc_AttributeError,"vector.%c: unavailable on %dd vector", *(((char *)"xyzw") + i), self->size);
else PyErr_SetString(PyExc_IndexError,"vector[index]: out of range");
return NULL;
}
if(!BaseMath_ReadIndexCallback(self, i))
if(BaseMath_ReadIndexCallback(self, i) == -1)
return NULL;
return PyFloat_FromDouble(self->vec[i]);
}
static PyObject *Vector_item(VectorObject *self, int i)
{
return vector_item_internal(self, i, FALSE);
}
/* sequence accessor (set): vector[index] = value */
static int Vector_ass_item(VectorObject *self, int i, PyObject * ob)
static int vector_ass_item_internal(VectorObject *self, int i, PyObject *value, const int is_attr)
{
float scalar;
if((scalar=PyFloat_AsDouble(ob))==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
if((scalar=PyFloat_AsDouble(value))==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
PyErr_SetString(PyExc_TypeError, "vector[index] = x: index argument not a number");
return -1;
}
@@ -811,23 +826,29 @@ static int Vector_ass_item(VectorObject *self, int i, PyObject * ob)
if(i<0) i= self->size-i;
if(i < 0 || i >= self->size){
PyErr_SetString(PyExc_IndexError, "vector[index] = x: assignment index out of range");
if(is_attr) PyErr_Format(PyExc_AttributeError,"vector.%c = x: unavailable on %dd vector", *(((char *)"xyzw") + i), self->size);
else PyErr_SetString(PyExc_IndexError, "vector[index] = x: assignment index out of range");
return -1;
}
self->vec[i] = scalar;
if(!BaseMath_WriteIndexCallback(self, i))
if(BaseMath_WriteIndexCallback(self, i) == -1)
return -1;
return 0;
}
static int Vector_ass_item(VectorObject *self, int i, PyObject *value)
{
return vector_ass_item_internal(self, i, value, FALSE);
}
/* sequence slice (get): vector[a:b] */
static PyObject *Vector_slice(VectorObject *self, int begin, int end)
{
PyObject *tuple;
int count;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
CLAMP(begin, 0, self->size);
@@ -849,12 +870,12 @@ static int Vector_ass_slice(VectorObject *self, int begin, int end,
int y, size = 0;
float vec[MAX_DIMENSIONS];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return -1;
CLAMP(begin, 0, self->size);
CLAMP(end, 0, self->size);
begin = MIN2(begin,end);
begin = MIN2(begin, end);
size = (end - begin);
if(mathutils_array_parse(vec, size, size, seq, "vector[begin:end] = [...]") == -1)
@@ -865,7 +886,7 @@ static int Vector_ass_slice(VectorObject *self, int begin, int end,
self->vec[begin + y] = vec[y];
}
if(!BaseMath_WriteCallback(self))
if(BaseMath_WriteCallback(self) == -1)
return -1;
return 0;
@@ -885,7 +906,7 @@ static PyObject *Vector_add(PyObject * v1, PyObject * v2)
vec1 = (VectorObject*)v1;
vec2 = (VectorObject*)v2;
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1)
return NULL;
/*VECTOR + VECTOR*/
@@ -916,7 +937,7 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2)
return NULL;
}
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1)
return NULL;
add_vn_vn(vec1->vec, vec2->vec, vec1->size);
@@ -939,7 +960,7 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2)
vec1 = (VectorObject*)v1;
vec2 = (VectorObject*)v2;
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1)
return NULL;
if(vec1->size != vec2->size) {
@@ -969,7 +990,7 @@ static PyObject *Vector_isub(PyObject * v1, PyObject * v2)
return NULL;
}
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1)
return NULL;
sub_vn_vn(vec1->vec, vec2->vec, vec1->size);
@@ -1013,7 +1034,7 @@ static int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject
for(x = 0; x < mat->col_size; x++) {
for(y = 0; y < mat->row_size; y++) {
dot += mat->matrix[y][x] * vec_cpy[y];
dot += (double)(mat->matrix[y][x] * vec_cpy[y]);
}
rvec[z++] = (float)dot;
dot = 0.0f;
@@ -1036,18 +1057,18 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
if VectorObject_Check(v1) {
vec1= (VectorObject *)v1;
if(!BaseMath_ReadCallback(vec1))
if(BaseMath_ReadCallback(vec1) == -1)
return NULL;
}
if VectorObject_Check(v2) {
vec2= (VectorObject *)v2;
if(!BaseMath_ReadCallback(vec2))
if(BaseMath_ReadCallback(vec2) == -1)
return NULL;
}
/* make sure v1 is always the vector */
if (vec1 && vec2 ) {
if (vec1 && vec2) {
int i;
double dot = 0.0f;
@@ -1058,7 +1079,7 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
/*dot product*/
for(i = 0; i < vec1->size; i++) {
dot += vec1->vec[i] * vec2->vec[i];
dot += (double)(vec1->vec[i] * vec2->vec[i]);
}
return PyFloat_FromDouble(dot);
}
@@ -1066,7 +1087,7 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
if (MatrixObject_Check(v2)) {
/* VEC * MATRIX */
float tvec[MAX_DIMENSIONS];
if(!BaseMath_ReadCallback((MatrixObject *)v2))
if(BaseMath_ReadCallback((MatrixObject *)v2) == -1)
return NULL;
if(column_vector_multiplication(tvec, vec1, (MatrixObject*)v2) == -1) {
return NULL;
@@ -1083,19 +1104,19 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported");
return NULL;
}
if(!BaseMath_ReadCallback(quat2)) {
if(BaseMath_ReadCallback(quat2) == -1) {
return NULL;
}
copy_v3_v3(tvec, vec1->vec);
mul_qt_v3(quat2->quat, tvec);
return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(vec1));
}
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* VEC*FLOAT */
return vector_mul_float(vec1, scalar);
}
}
else if (vec2) {
if (((scalar= PyFloat_AsDouble(v1)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
if (((scalar= PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred())==0) { /* VEC*FLOAT */
return vector_mul_float(vec2, scalar);
}
}
@@ -1113,14 +1134,14 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
VectorObject *vec = (VectorObject *)v1;
float scalar;
if(!BaseMath_ReadCallback(vec))
if(BaseMath_ReadCallback(vec) == -1)
return NULL;
/* only support vec*=float and vec*=mat
vec*=vec result is a float so that wont work */
if (MatrixObject_Check(v2)) {
float rvec[MAX_DIMENSIONS];
if(!BaseMath_ReadCallback((MatrixObject *)v2))
if(BaseMath_ReadCallback((MatrixObject *)v2) == -1)
return NULL;
if(column_vector_multiplication(rvec, vec, (MatrixObject*)v2) == -1)
@@ -1137,12 +1158,12 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
return NULL;
}
if(!BaseMath_ReadCallback(quat2)) {
if(BaseMath_ReadCallback(quat2) == -1) {
return NULL;
}
mul_qt_v3(quat2->quat, vec->vec);
}
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*=FLOAT */
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* VEC*=FLOAT */
mul_vn_fl(vec->vec, vec->size, scalar);
}
else {
@@ -1151,7 +1172,7 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
}
(void)BaseMath_WriteCallback(vec);
Py_INCREF( v1 );
Py_INCREF(v1);
return v1;
}
@@ -1168,7 +1189,7 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2)
}
vec1 = (VectorObject*)v1; /* vector */
if(!BaseMath_ReadCallback(vec1))
if(BaseMath_ReadCallback(vec1) == -1)
return NULL;
if((scalar=PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
@@ -1176,7 +1197,7 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2)
return NULL;
}
if(scalar==0.0) {
if(scalar==0.0f) {
PyErr_SetString(PyExc_ZeroDivisionError, "Vector division: divide by zero error");
return NULL;
}
@@ -1194,7 +1215,7 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2)
float scalar;
VectorObject *vec1 = (VectorObject*)v1;
if(!BaseMath_ReadCallback(vec1))
if(BaseMath_ReadCallback(vec1) == -1)
return NULL;
if((scalar=PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
@@ -1202,7 +1223,7 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2)
return NULL;
}
if(scalar==0.0) {
if(scalar==0.0f) {
PyErr_SetString(PyExc_ZeroDivisionError, "Vector division: divide by zero error");
return NULL;
}
@@ -1212,7 +1233,7 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2)
(void)BaseMath_WriteCallback(vec1);
Py_INCREF( v1 );
Py_INCREF(v1);
return v1;
}
@@ -1222,7 +1243,7 @@ static PyObject *Vector_neg(VectorObject *self)
{
float tvec[MAX_DIMENSIONS];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
negate_vn_vn(tvec, self->vec, self->size);
@@ -1236,7 +1257,7 @@ static double vec_magnitude_nosqrt(float *data, int size)
int i;
for(i=0; i<size; i++){
dot += data[i];
dot += (double)data[i];
}
/*return (double)sqrt(dot);*/
/* warning, line above removed because we are not using the length,
@@ -1252,26 +1273,28 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
{
VectorObject *vecA = NULL, *vecB = NULL;
int result = 0;
float epsilon = .000001f;
double lenA,lenB;
double epsilon = .000001f;
double lenA, lenB;
if (!VectorObject_Check(objectA) || !VectorObject_Check(objectB)){
if (comparison_type == Py_NE){
Py_RETURN_TRUE;
}else{
}
else {
Py_RETURN_FALSE;
}
}
vecA = (VectorObject*)objectA;
vecB = (VectorObject*)objectB;
if(!BaseMath_ReadCallback(vecA) || !BaseMath_ReadCallback(vecB))
if(BaseMath_ReadCallback(vecA) == -1 || BaseMath_ReadCallback(vecB) == -1)
return NULL;
if (vecA->size != vecB->size){
if (comparison_type == Py_NE){
Py_RETURN_TRUE;
}else{
}
else {
Py_RETURN_FALSE;
}
}
@@ -1280,16 +1303,17 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
case Py_LT:
lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size);
lenB = vec_magnitude_nosqrt(vecB->vec, vecB->size);
if( lenA < lenB ){
if(lenA < lenB){
result = 1;
}
break;
case Py_LE:
lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size);
lenB = vec_magnitude_nosqrt(vecB->vec, vecB->size);
if( lenA < lenB ){
if(lenA < lenB){
result = 1;
}else{
}
else {
result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
}
break;
@@ -1302,16 +1326,17 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
case Py_GT:
lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size);
lenB = vec_magnitude_nosqrt(vecB->vec, vecB->size);
if( lenA > lenB ){
if(lenA > lenB){
result = 1;
}
break;
case Py_GE:
lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size);
lenB = vec_magnitude_nosqrt(vecB->vec, vecB->size);
if( lenA > lenB ){
if(lenA > lenB){
result = 1;
}else{
}
else {
result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
}
break;
@@ -1321,7 +1346,8 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
}
if (result == 1){
Py_RETURN_TRUE;
}else{
}
else {
Py_RETURN_FALSE;
}
}
@@ -1350,7 +1376,8 @@ static PyObject *Vector_subscript(VectorObject* self, PyObject* item)
if (i < 0)
i += self->size;
return Vector_item(self, i);
} else if (PySlice_Check(item)) {
}
else if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx((void *)item, self->size, &start, &stop, &step, &slicelength) < 0)
@@ -1454,12 +1481,12 @@ static PyNumberMethods Vector_NumMethods = {
static PyObject *Vector_getAxis(VectorObject *self, void *type)
{
return Vector_item(self, GET_INT_FROM_POINTER(type));
return vector_item_internal(self, GET_INT_FROM_POINTER(type), TRUE);
}
static int Vector_setAxis(VectorObject *self, PyObject * value, void *type)
{
return Vector_ass_item(self, GET_INT_FROM_POINTER(type), value);
return vector_ass_item_internal(self, GET_INT_FROM_POINTER(type), value, TRUE);
}
/* vector.length */
@@ -1468,11 +1495,11 @@ static PyObject *Vector_getLength(VectorObject *self, void *UNUSED(closure))
double dot = 0.0f;
int i;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
for(i = 0; i < self->size; i++){
dot += (self->vec[i] * self->vec[i]);
dot += (double)(self->vec[i] * self->vec[i]);
}
return PyFloat_FromDouble(sqrt(dot));
}
@@ -1482,7 +1509,7 @@ static int Vector_setLength(VectorObject *self, PyObject *value)
double dot = 0.0f, param;
int i;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return -1;
if((param=PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred()) {
@@ -1490,17 +1517,17 @@ static int Vector_setLength(VectorObject *self, PyObject *value)
return -1;
}
if (param < 0.0f) {
if (param < 0.0) {
PyErr_SetString(PyExc_TypeError, "cannot set a vectors length to a negative value");
return -1;
}
if (param == 0.0f) {
if (param == 0.0) {
fill_vn(self->vec, self->size, 0.0f);
return 0;
}
for(i = 0; i < self->size; i++){
dot += (self->vec[i] * self->vec[i]);
dot += (double)(self->vec[i] * self->vec[i]);
}
if (!dot) /* cant sqrt zero */
@@ -1532,7 +1559,7 @@ static PyObject *Vector_getSwizzle(VectorObject *self, void *closure)
float vec[MAX_DIMENSIONS];
unsigned int swizzleClosure;
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
/* Unpack the axes from the closure into an array. */
@@ -1577,7 +1604,7 @@ static int Vector_setSwizzle(VectorObject *self, PyObject * value, void *closure
float tvec[MAX_DIMENSIONS];
float vec_assign[MAX_DIMENSIONS];
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return -1;
/* Check that the closure can be used with this vector: even 2D vectors have
@@ -1626,7 +1653,7 @@ static int Vector_setSwizzle(VectorObject *self, PyObject * value, void *closure
memcpy(self->vec, tvec, axis_from * sizeof(float));
/* continue with BaseMathObject_WriteCallback at the end */
if(!BaseMath_WriteCallback(self))
if(BaseMath_WriteCallback(self) == -1)
return -1;
else
return 0;
@@ -1982,7 +2009,7 @@ static PyGetSetDef Vector_getseters[] = {
{(char *)"wwwy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3071
{(char *)"wwwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3583
{(char *)"wwww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4095
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
/* Python script used to make swizzle array */
@@ -1994,7 +2021,7 @@ axis_dict = {}
axis_pos = {'x':0, 'y':1, 'z':2, 'w':3}
axises = 'xyzw'
while len(axises) >= 2:
for axis_0 in axises:
axis_0_pos = axis_pos[axis_0]
for axis_1 in axises:
@@ -2008,7 +2035,7 @@ while len(axises) >= 2:
for axis_3 in axises:
axis_3_pos = axis_pos[axis_3]
axis_dict[axis_0+axis_1+axis_2+axis_3] = '((%s|SWIZZLE_VALID_AXIS) | ((%s|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((%s|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((%s|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) ' % (axis_0_pos, axis_1_pos, axis_2_pos, axis_3_pos)
axises = axises[:-1]
@@ -2042,12 +2069,13 @@ static int row_vector_multiplication(float rvec[4], VectorObject* vec, MatrixObj
if(mat->colSize == 4 && vec_size != 3){
PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same");
return -1;
}else{
}
else {
vec_cpy[3] = 1.0f;
}
}
if(!BaseMath_ReadCallback(vec) || !BaseMath_ReadCallback(mat))
if(BaseMath_ReadCallback(vec) == -1 || BaseMath_ReadCallback(mat) == -1)
return -1;
memcpy(vec_cpy, vec->vec, vec_size * sizeof(float));
@@ -2076,9 +2104,9 @@ static char Vector_negate_doc[] =
;
static PyObject *Vector_negate(VectorObject *self)
{
if(!BaseMath_ReadCallback(self))
if(BaseMath_ReadCallback(self) == -1)
return NULL;
negate_vn(self->vec, self->size);
(void)BaseMath_WriteCallback(self); // already checked for error
@@ -2108,7 +2136,7 @@ static struct PyMethodDef Vector_methods[] = {
{"cross", (PyCFunction) Vector_cross, METH_O, Vector_cross_doc},
{"dot", (PyCFunction) Vector_dot, METH_O, Vector_dot_doc},
{"angle", (PyCFunction) Vector_angle, METH_VARARGS, Vector_angle_doc},
{"difference", (PyCFunction) Vector_difference, METH_O, Vector_difference_doc},
{"rotation_difference", (PyCFunction) Vector_rotation_difference, METH_O, Vector_rotation_difference_doc},
{"project", (PyCFunction) Vector_project, METH_O, Vector_project_doc},
{"lerp", (PyCFunction) Vector_lerp, METH_VARARGS, Vector_lerp_doc},
{"rotate", (PyCFunction) Vector_rotate, METH_O, Vector_rotate_doc},
@@ -2121,7 +2149,7 @@ static struct PyMethodDef Vector_methods[] = {
/* Note
Py_TPFLAGS_CHECKTYPES allows us to avoid casting all types to Vector when coercing
but this means for eg that
but this means for eg that
vec*mat and mat*vec both get sent to Vector_mul and it neesd to sort out the order
*/
@@ -2137,12 +2165,12 @@ PyTypeObject vector_Type = {
/* Methods to implement standard operations */
( destructor ) BaseMathObject_dealloc,/* destructor tp_dealloc; */
(destructor) BaseMathObject_dealloc,/* destructor tp_dealloc; */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
NULL, /* cmpfunc tp_compare; */
( reprfunc ) Vector_repr, /* reprfunc tp_repr; */
(reprfunc)Vector_repr, /* reprfunc tp_repr; */
/* Method suites for standard classes */
@@ -2162,7 +2190,7 @@ PyTypeObject vector_Type = {
NULL, /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
vector_doc, /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
@@ -2268,6 +2296,7 @@ PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_su
self->cb_user= cb_user;
self->cb_type= (unsigned char)cb_type;
self->cb_subtype= (unsigned char)cb_subtype;
PyObject_GC_Track(self);
}
return (PyObject *)self;

View File

@@ -28,6 +28,11 @@
*
*/
/** \file blender/python/generic/mathutils_Vector.h
* \ingroup pygen
*/
#ifndef MATHUTILS_VECTOR_H
#define MATHUTILS_VECTOR_H

View File

@@ -27,6 +27,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/mathutils_geometry.c
* \ingroup pygen
*/
#include <Python.h>
#include "mathutils_geometry.h"
@@ -43,7 +48,7 @@
#include "BKE_curve.h"
#define SWAP_FLOAT(a,b,tmp) tmp=a; a=b; b=tmp
#define SWAP_FLOAT(a, b, tmp) tmp=a; a=b; b=tmp
#define eps 0.000001
@@ -87,7 +92,7 @@ static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject*
return NULL;
}
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(ray) || !BaseMath_ReadCallback(ray_off))
if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1 || BaseMath_ReadCallback(ray) == -1 || BaseMath_ReadCallback(ray_off) == -1)
return NULL;
VECCOPY(v1, vec1->vec);
@@ -109,7 +114,7 @@ static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject*
/* if determinant is near zero, ray lies in plane of triangle */
det= dot_v3v3(e1, pvec);
if (det > -0.000001 && det < 0.000001) {
if (det > -0.000001f && det < 0.000001f) {
Py_RETURN_NONE;
}
@@ -174,7 +179,7 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject
return NULL;
}
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1 || BaseMath_ReadCallback(vec4) == -1)
return NULL;
if(vec1->size == 3 || vec1->size == 2) {
@@ -260,7 +265,7 @@ static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject* args)
return NULL;
}
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1)
return NULL;
normal_tri_v3(n, vec1->vec, vec2->vec, vec3->vec);
@@ -278,7 +283,7 @@ static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject* args)
return NULL;
}
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1 || BaseMath_ReadCallback(vec4) == -1)
return NULL;
normal_quad_v3(n, vec1->vec, vec2->vec, vec3->vec, vec4->vec);
@@ -315,7 +320,7 @@ static PyObject *M_Geometry_area_tri(PyObject *UNUSED(self), PyObject* args)
return NULL;
}
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1)
return NULL;
if (vec1->size == 3) {
@@ -392,7 +397,7 @@ static PyObject *M_Geometry_tesselate_polygon(PyObject *UNUSED(self), PyObject *
polyVec= PySequence_GetItem(polyLine, index);
if(VectorObject_Check(polyVec)) {
if(!BaseMath_ReadCallback((VectorObject *)polyVec))
if(BaseMath_ReadCallback((VectorObject *)polyVec) == -1)
ls_error= 1;
fp[0]= ((VectorObject *)polyVec)->vec[0];
@@ -441,7 +446,8 @@ static PyObject *M_Geometry_tesselate_polygon(PyObject *UNUSED(self), PyObject *
index++;
}
freedisplist(&dispbase);
} else {
}
else {
/* no points, do this so scripts dont barf */
freedisplist(&dispbase); /* possible some dl was allocated */
tri_list= PyList_New(0);
@@ -479,12 +485,13 @@ static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObj
return NULL;
}
if(!BaseMath_ReadCallback(line_a1) || !BaseMath_ReadCallback(line_a2) || !BaseMath_ReadCallback(line_b1) || !BaseMath_ReadCallback(line_b2))
if(BaseMath_ReadCallback(line_a1) == -1 || BaseMath_ReadCallback(line_a2) == -1 || BaseMath_ReadCallback(line_b1) == -1 || BaseMath_ReadCallback(line_b2) == -1)
return NULL;
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 {
}
else {
Py_RETURN_NONE;
}
}
@@ -518,7 +525,7 @@ static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObjec
return NULL;
}
if(!BaseMath_ReadCallback(pt) || !BaseMath_ReadCallback(line_1) || !BaseMath_ReadCallback(line_2))
if(BaseMath_ReadCallback(pt) == -1 || BaseMath_ReadCallback(line_1) == -1 || BaseMath_ReadCallback(line_2) == -1)
return NULL;
/* accept 2d verts */
@@ -532,7 +539,7 @@ static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObjec
else { l2[2]=0.0; VECCOPY2D(l2, line_2->vec) }
/* do the calculation */
lambda= closest_to_line_v3(pt_out,pt_in, l1, l2);
lambda= closest_to_line_v3(pt_out, pt_in, l1, l2);
ret= PyTuple_New(2);
PyTuple_SET_ITEM(ret, 0, newVectorObject(pt_out, 3, Py_NEW, NULL));
@@ -568,7 +575,7 @@ static PyObject *M_Geometry_intersect_point_tri_2d(PyObject *UNUSED(self), PyObj
return NULL;
}
if(!BaseMath_ReadCallback(pt_vec) || !BaseMath_ReadCallback(tri_p1) || !BaseMath_ReadCallback(tri_p2) || !BaseMath_ReadCallback(tri_p3))
if(BaseMath_ReadCallback(pt_vec) == -1 || BaseMath_ReadCallback(tri_p1) == -1 || BaseMath_ReadCallback(tri_p2) == -1 || BaseMath_ReadCallback(tri_p3) == -1)
return NULL;
return PyLong_FromLong(isect_point_tri_v2(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec));
@@ -605,7 +612,7 @@ static PyObject *M_Geometry_intersect_point_quad_2d(PyObject *UNUSED(self), PyOb
return NULL;
}
if(!BaseMath_ReadCallback(pt_vec) || !BaseMath_ReadCallback(quad_p1) || !BaseMath_ReadCallback(quad_p2) || !BaseMath_ReadCallback(quad_p3) || !BaseMath_ReadCallback(quad_p4))
if(BaseMath_ReadCallback(pt_vec) == -1 || BaseMath_ReadCallback(quad_p1) == -1 || BaseMath_ReadCallback(quad_p2) == -1 || BaseMath_ReadCallback(quad_p3) == -1 || BaseMath_ReadCallback(quad_p4) == -1)
return NULL;
return PyLong_FromLong(isect_point_quad_v2(pt_vec->vec, quad_p1->vec, quad_p2->vec, quad_p3->vec, quad_p4->vec));
@@ -679,7 +686,7 @@ static char M_Geometry_box_pack_2d_doc[] =
"\n"
" Returns the normal of the 3D tri or quad.\n"
"\n"
" :arg boxes: list of boxes, each box is a list where the first 4 items are [x,y, width, height, ...] other items are ignored.\n"
" :arg boxes: list of boxes, each box is a list where the first 4 items are [x, y, width, height, ...] other items are ignored.\n"
" :type boxes: list\n"
" :return: the width and height of the packed bounding box\n"
" :rtype: tuple, pair of floats\n"
@@ -692,7 +699,7 @@ static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlis
PyObject *ret;
if(!PyList_Check(boxlist)) {
PyErr_SetString(PyExc_TypeError, "expected a list of boxes [[x,y,w,h], ... ]");
PyErr_SetString(PyExc_TypeError, "expected a list of boxes [[x, y, w, h], ... ]");
return NULL;
}
@@ -762,7 +769,7 @@ static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject*
return NULL;
}
if(!BaseMath_ReadCallback(vec_k1) || !BaseMath_ReadCallback(vec_h1) || !BaseMath_ReadCallback(vec_k2) || !BaseMath_ReadCallback(vec_h2))
if(BaseMath_ReadCallback(vec_k1) == -1 || BaseMath_ReadCallback(vec_h1) == -1 || BaseMath_ReadCallback(vec_k2) == -1 || BaseMath_ReadCallback(vec_h2) == -1)
return NULL;
dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);

View File

@@ -26,6 +26,11 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/mathutils_geometry.h
* \ingroup pygen
*/
/*Include this file for access to vector, quat, matrix, euler, etc...*/
#ifndef MATHUTILS_GEOMETRY_H

View File

@@ -30,6 +30,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/noise_py_api.c
* \ingroup pygen
*/
/************************/
/* Blender Noise Module */
/************************/
@@ -207,8 +212,10 @@ static void randuvec(float v[3])
r = (float)sqrt(r);
v[0] = (float)(r * cos(a));
v[1] = (float)(r * sin(a));
} else
}
else {
v[2] = 1.f;
}
}
static PyObject *Noise_random(PyObject *UNUSED(self))

View File

@@ -21,6 +21,11 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/noise_py_api.h
* \ingroup pygen
*/
#ifndef NOISE_PY_API_H
#define NOISE_PY_API_H

View File

@@ -20,11 +20,18 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/py_capi_utils.c
* \ingroup pygen
*/
#include <Python.h>
#include <frameobject.h>
#include "py_capi_utils.h"
#define PYC_INTERPRETER_ACTIVE (((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) != NULL)
/* for debugging */
void PyC_ObSpit(const char *name, PyObject *var) {
fprintf(stderr, "<%s> : ", name);
@@ -46,27 +53,22 @@ void PyC_ObSpit(const char *name, PyObject *var) {
}
void PyC_LineSpit(void) {
const char *filename;
int lineno;
/* Note, allow calling from outside python (RNA) */
if(!PYC_INTERPRETER_ACTIVE) {
fprintf(stderr, "python line lookup failed, interpreter inactive\n");
return;
}
PyErr_Clear();
PyC_FileAndNum(&filename, &lineno);
fprintf(stderr, "%s:%d\n", filename, lineno);
}
/* python 3.2 only, copied from frameobjec.c */
#if PY_VERSION_HEX < 0x03020000
int
PyFrame_GetLineNumber(PyFrameObject *f)
{
if (f->f_trace)
return f->f_lineno;
else
return PyCode_Addr2Line(f->f_code, f->f_lasti);
}
#endif
void PyC_FileAndNum(const char **filename, int *lineno)
{
PyFrameObject *frame;
@@ -157,9 +159,11 @@ PyObject *PyC_ExceptionBuffer(void)
if(! (string_io_mod= PyImport_ImportModule("io")) ) {
goto error_cleanup;
} else if (! (string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) {
}
else if (! (string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) {
goto error_cleanup;
} else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) {
}
else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) {
goto error_cleanup;
}
@@ -219,29 +223,7 @@ const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
return PyBytes_AS_STRING(py_str);
}
else {
/* mostly copied from fileio.c's, fileio_init */
PyObject *stringobj;
PyObject *u;
PyErr_Clear();
u= PyUnicode_FromObject(py_str); /* coerce into unicode */
if (u == NULL)
return NULL;
stringobj= PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(u), PyUnicode_GET_SIZE(u), "surrogateescape");
Py_DECREF(u);
if (stringobj == NULL)
return NULL;
if (!PyBytes_Check(stringobj)) { /* this seems wrong but it works fine */
// printf("encoder failed to return bytes\n");
Py_DECREF(stringobj);
return NULL;
}
*coerce= stringobj;
return PyBytes_AS_STRING(stringobj);
return PyBytes_AS_STRING((*coerce= PyUnicode_EncodeFSDefault(py_str)));
}
}

View File

@@ -21,6 +21,11 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/py_capi_utils.h
* \ingroup pygen
*/
#ifndef PY_CAPI_UTILS_H
#define PY_CAPI_UTILS_H
@@ -42,4 +47,5 @@ void PyC_RunQuicky(const char *filepath, int n, ...);
void PyC_MainModule_Backup(PyObject **main_mod);
void PyC_MainModule_Restore(PyObject *main_mod);
#endif // PY_CAPI_UTILS_H

View File

@@ -42,10 +42,12 @@ set(SRC
bpy_app.c
bpy_driver.c
bpy_interface.c
bpy_library.c
bpy_operator.c
bpy_operator_wrap.c
bpy_props.c
bpy_rna.c
bpy_rna_anim.c
bpy_rna_array.c
bpy_rna_callback.c
bpy_traceback.c
@@ -59,6 +61,7 @@ set(SRC
bpy_operator_wrap.h
bpy_props.h
bpy_rna.h
bpy_rna_anim.h
bpy_rna_callback.h
bpy_traceback.h
bpy_util.h
@@ -74,4 +77,8 @@ if(WITH_PYTHON_MODULE)
add_definitions(-DWITH_PYTHON_MODULE)
endif()
if(WITH_PYTHON_SAFETY)
add_definitions(-DWITH_PYTHON_SAFETY)
endif()
blender_add_lib(bf_python "${SRC}" "${INC}")

View File

@@ -21,6 +21,11 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy.c
* \ingroup pythonintern
*/
/* This file defines the '_bpy' module which is used by python's 'bpy' package.
* a script writer should never directly access this module */
@@ -37,11 +42,15 @@
#include "bpy_operator.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_bpath.h"
#include "BLI_utildefines.h"
#include "BKE_global.h" /* XXX, G.main only */
#include "BKE_blender.h"
#include "RNA_access.h"
#include "MEM_guardedalloc.h"
@@ -61,8 +70,8 @@ static char bpy_script_paths_doc[] =
" Return 2 paths to blender scripts directories.\n"
"\n"
" :return: (system, user) strings will be empty when not found.\n"
" :rtype: tuple of strigs\n";
" :rtype: tuple of strings\n"
;
static PyObject *bpy_script_paths(PyObject *UNUSED(self))
{
PyObject *ret= PyTuple_New(2);
@@ -84,7 +93,8 @@ static char bpy_blend_paths_doc[] =
" :arg absolute: When true the paths returned are made absolute.\n"
" :type absolute: boolean\n"
" :return: path list.\n"
" :rtype: list of strigs\n";
" :rtype: list of strings\n"
;
static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
struct BPathIterator *bpi;
@@ -93,8 +103,8 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
char filepath_expanded[1024];
const char *lib;
int absolute = 0;
static const char *kwlist[] = {"absolute", NULL};
int absolute= 0;
static const char *kwlist[]= {"absolute", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kw, "|i:blend_paths", (char **)kwlist, &absolute))
return NULL;
@@ -107,8 +117,8 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
BLI_bpathIterator_getPathExpanded(bpi, filepath_expanded);
}
else {
lib = BLI_bpathIterator_getLib(bpi);
if (lib && (strcmp(lib, BLI_bpathIterator_getBasePath(bpi)))) { /* relative path to the library is NOT the same as our blendfile path, return an absolute path */
lib= BLI_bpathIterator_getLib(bpi);
if (lib && (BLI_path_cmp(lib, BLI_bpathIterator_getBasePath(bpi)))) { /* relative path to the library is NOT the same as our blendfile path, return an absolute path */
BLI_bpathIterator_getPathExpanded(bpi, filepath_expanded);
}
else {
@@ -127,13 +137,13 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
}
// static char bpy_user_resource_doc[] = // now in bpy/utils.py
// 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;
char *subdir= NULL;
int folder_id;
static const char *kwlist[] = {"type", "subdir", NULL};
static const char *kwlist[]= {"type", "subdir", NULL};
char *path;
@@ -154,14 +164,55 @@ static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObj
path= BLI_get_folder(folder_id, subdir);
if (!path)
path = BLI_get_user_folder_notest(folder_id, subdir);
path= BLI_get_user_folder_notest(folder_id, subdir);
return PyUnicode_FromString(path ? path : "");
return PyUnicode_DecodeFSDefault(path ? path : "");
}
static PyMethodDef meth_bpy_script_paths = {"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc};
static PyMethodDef meth_bpy_blend_paths = {"blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS|METH_KEYWORDS, bpy_blend_paths_doc};
static PyMethodDef meth_bpy_user_resource = {"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS|METH_KEYWORDS, NULL};
static char bpy_resource_path_doc[] =
".. function:: resource_path(type, major=2, minor=57)\n"
"\n"
" Return the base path for storing system files.\n"
"\n"
" :arg type: string in ['USER', 'LOCAL', 'SYSTEM'].\n"
" :type type: string\n"
" :arg major: major version, defaults to current.\n"
" :type major: int\n"
" :arg minor: minor version, defaults to current.\n"
" :type minor: string\n"
" :return: the resource path (not necessarily existing).\n"
" :rtype: string\n"
;
static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
char *type;
int major= BLENDER_VERSION/100, minor= BLENDER_VERSION%100;
static const char *kwlist[]= {"type", "major", "minor", NULL};
int folder_id;
char *path;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ii:resource_path", (char **)kwlist, &type, &major, &minor))
return NULL;
/* stupid string compare */
if (!strcmp(type, "USER")) folder_id= BLENDER_RESOURCE_PATH_USER;
else if(!strcmp(type, "LOCAL")) folder_id= BLENDER_RESOURCE_PATH_LOCAL;
else if(!strcmp(type, "SYSTEM")) folder_id= BLENDER_RESOURCE_PATH_SYSTEM;
else {
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
return NULL;
}
path= BLI_get_folder_version(folder_id, (major * 100) + minor, FALSE);
return PyUnicode_DecodeFSDefault(path);
}
static PyMethodDef meth_bpy_script_paths= {"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc};
static PyMethodDef meth_bpy_blend_paths= {"blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS|METH_KEYWORDS, bpy_blend_paths_doc};
static PyMethodDef meth_bpy_user_resource= {"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS|METH_KEYWORDS, NULL};
static PyMethodDef meth_bpy_resource_path= {"resource_path", (PyCFunction)bpy_resource_path, METH_VARARGS|METH_KEYWORDS, bpy_resource_path_doc};
static PyObject *bpy_import_test(const char *modname)
{
@@ -183,6 +234,7 @@ static PyObject *bpy_import_test(const char *modname)
void BPy_init_modules( void )
{
extern BPy_StructRNA *bpy_context_module;
extern int bpy_lib_init(PyObject *);
PointerRNA ctx_ptr;
PyObject *mod;
@@ -201,7 +253,7 @@ void BPy_init_modules( void )
/* stand alone utility modules not related to blender directly */
IDProp_Init_Types(); /* not actually a submodule, just types */
mod = PyModule_New("_bpy");
mod= PyModule_New("_bpy");
/* add the module so we can import it */
PyDict_SetItemString(PyImport_GetModuleDict(), "_bpy", mod);
@@ -212,7 +264,9 @@ void BPy_init_modules( void )
PyModule_AddObject( mod, "types", BPY_rna_types() ); /* needs to be first so bpy_types can run */
PyModule_AddObject(mod, "StructMetaPropGroup", (PyObject *)&pyrna_struct_meta_idprop_Type); /* metaclass for idprop types, bpy_types.py needs access */
bpy_lib_init(mod); /* adds '_bpy._library_load', must be called before 'bpy_types' which uses it */
bpy_import_test("bpy_types");
PyModule_AddObject( mod, "data", BPY_rna_module() ); /* imports bpy_types by running this */
bpy_import_test("bpy_types");
@@ -233,6 +287,7 @@ void BPy_init_modules( void )
PyModule_AddObject(mod, meth_bpy_script_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_script_paths, NULL));
PyModule_AddObject(mod, meth_bpy_blend_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_blend_paths, NULL));
PyModule_AddObject(mod, meth_bpy_user_resource.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_user_resource, NULL));
PyModule_AddObject(mod, meth_bpy_resource_path.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_resource_path, NULL));
/* register funcs (bpy_rna.c) */
PyModule_AddObject(mod, meth_bpy_register_class.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_register_class, NULL));

View File

@@ -20,6 +20,11 @@
* Contributor(s): Campbell Barton
*
* ***** END GPL LICENSE BLOCK ***** */
/** \file blender/python/intern/bpy.h
* \ingroup pythonintern
*/
void BPy_init_modules( void );
extern PyObject *bpy_package_py;

View File

@@ -22,6 +22,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_app.c
* \ingroup pythonintern
*/
#include <Python.h>
#include "bpy_app.h"
@@ -51,9 +56,11 @@ extern char build_system[];
static PyTypeObject BlenderAppType;
static PyStructSequence_Field app_info_fields[] = {
static PyStructSequence_Field app_info_fields[]= {
{(char *)"version", (char *)"The Blender version as a tuple of 3 numbers. eg. (2, 50, 11)"},
{(char *)"version_string", (char *)"The Blender version formatted as a string"},
{(char *)"version_char", (char *)"The Blender version character (for minor releases)"},
{(char *)"version_cycle", (char *)"The release status of this build alpha/beta/rc/release"},
{(char *)"binary_path", (char *)"The location of blenders executable, useful for utilities that spawn new instances"},
{(char *)"background", (char *)"Boolean, True when blender is running without a user interface (started with -b)"},
@@ -70,21 +77,24 @@ static PyStructSequence_Field app_info_fields[] = {
{NULL}
};
static PyStructSequence_Desc app_info_desc = {
static PyStructSequence_Desc app_info_desc= {
(char *)"bpy.app", /* name */
(char *)"This module contains application values that remain unchanged during runtime.", /* doc */
app_info_fields, /* fields */
(sizeof(app_info_fields)/sizeof(PyStructSequence_Field)) - 1
};
#define DO_EXPAND(VAL) VAL ## 1
#define EXPAND(VAL) DO_EXPAND(VAL)
static PyObject *make_app_info(void)
{
extern char bprogname[]; /* argv[0] from creator.c */
PyObject *app_info;
int pos = 0;
int pos= 0;
app_info = PyStructSequence_New(&BlenderAppType);
app_info= PyStructSequence_New(&BlenderAppType);
if (app_info == NULL) {
return NULL;
}
@@ -98,6 +108,12 @@ static PyObject *make_app_info(void)
SetObjItem(Py_BuildValue("(iii)", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION));
SetObjItem(PyUnicode_FromFormat("%d.%02d (sub %d)", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION));
#if defined(BLENDER_VERSION_CHAR) && EXPAND(BLENDER_VERSION_CHAR) != 1
SetStrItem(STRINGIFY(BLENDER_VERSION_CHAR));
#else
SetStrItem("");
#endif
SetStrItem(STRINGIFY(BLENDER_VERSION_CYCLE));
SetStrItem(bprogname);
SetObjItem(PyBool_FromLong(G.background));
@@ -224,8 +240,8 @@ PyObject *BPY_app_struct(void)
ret= make_app_info();
/* prevent user from creating new instances */
BlenderAppType.tp_init = NULL;
BlenderAppType.tp_new = NULL;
BlenderAppType.tp_init= NULL;
BlenderAppType.tp_new= NULL;
/* kindof a hack ontop of PyStructSequence */
py_struct_seq_getset_init();

View File

@@ -21,6 +21,11 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_app.h
* \ingroup pythonintern
*/
#ifndef BPY_APP_H
#define BPY_APP_H

View File

@@ -21,6 +21,11 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_driver.c
* \ingroup pythonintern
*/
/* ****************************************** */
/* Drivers - PyExpression Evaluation */
@@ -37,7 +42,7 @@
#include "bpy_driver.h"
/* for pydrivers (drivers using one-line Python expressions to express relationships between targets) */
PyObject *bpy_pydriver_Dict = NULL;
PyObject *bpy_pydriver_Dict= NULL;
/* For faster execution we keep a special dictionary for pydrivers, with
* the needed modules and aliases.
@@ -49,16 +54,16 @@ int bpy_pydriver_create_dict(void)
/* validate namespace for driver evaluation */
if (bpy_pydriver_Dict) return -1;
d = PyDict_New();
d= PyDict_New();
if (d == NULL)
return -1;
else
bpy_pydriver_Dict = d;
bpy_pydriver_Dict= d;
/* import some modules: builtins, bpy, math, (Blender.noise )*/
PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
mod = PyImport_ImportModule("math");
mod= PyImport_ImportModule("math");
if (mod) {
PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
Py_DECREF(mod);
@@ -85,12 +90,12 @@ void BPY_driver_reset(void)
int use_gil= 1; // (PyThreadState_Get()==NULL);
if(use_gil)
gilstate = PyGILState_Ensure();
gilstate= PyGILState_Ensure();
if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
PyDict_Clear(bpy_pydriver_Dict);
Py_DECREF(bpy_pydriver_Dict);
bpy_pydriver_Dict = NULL;
bpy_pydriver_Dict= NULL;
}
if(use_gil)
@@ -127,13 +132,13 @@ float BPY_driver_exec(ChannelDriver *driver)
int use_gil;
DriverVar *dvar;
double result = 0.0; /* default return */
char *expr = NULL;
double result= 0.0; /* default return */
char *expr= NULL;
short targets_ok= 1;
int i;
/* get the py expression to be evaluated */
expr = driver->expression;
expr= driver->expression;
if ((expr == NULL) || (expr[0]=='\0'))
return 0.0f;
@@ -145,7 +150,7 @@ float BPY_driver_exec(ChannelDriver *driver)
use_gil= 1; //(PyThreadState_Get()==NULL);
if(use_gil)
gilstate = PyGILState_Ensure();
gilstate= PyGILState_Ensure();
/* init global dictionary for py-driver evaluation settings */
if (!bpy_pydriver_Dict) {
@@ -195,10 +200,10 @@ float BPY_driver_exec(ChannelDriver *driver)
}
/* add target values to a dict that will be used as '__locals__' dict */
driver_vars = PyDict_New(); // XXX do we need to decref this?
driver_vars= PyDict_New(); // XXX do we need to decref this?
for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
PyObject *driver_arg = NULL;
float tval = 0.0f;
PyObject *driver_arg= NULL;
float tval= 0.0f;
/* try to get variable value */
tval= driver_get_variable_value(driver, dvar);
@@ -223,7 +228,7 @@ float BPY_driver_exec(ChannelDriver *driver)
#if 0 // slow, with this can avoid all Py_CompileString above.
/* execute expression to get a value */
retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
retval= PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
#else
/* evaluate the compiled expression */
if (expr_code)
@@ -236,10 +241,11 @@ float BPY_driver_exec(ChannelDriver *driver)
/* process the result */
if (retval == NULL) {
pydriver_error(driver);
} else if((result= PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred()) {
}
else if((result= PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred()) {
pydriver_error(driver);
Py_DECREF(retval);
result = 0.0;
result= 0.0;
}
else {
/* all fine, make sure the "invalid expression" flag is cleared */

View File

@@ -21,6 +21,11 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_driver.h
* \ingroup pythonintern
*/
#ifndef BPY_DRIVER_H
#define BPY_DRIVER_H

View File

@@ -22,6 +22,11 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_interface.c
* \ingroup pythonintern
*/
/* grr, python redefines */
#ifdef _POSIX_C_SOURCE
@@ -32,6 +37,8 @@
#include "MEM_guardedalloc.h"
#include "RNA_types.h"
#include "bpy.h"
#include "bpy_rna.h"
#include "bpy_util.h"
@@ -73,7 +80,7 @@ BPy_StructRNA *bpy_context_module= NULL; /* for fast access */
#ifdef TIME_PY_RUN
#include "PIL_time.h"
static int bpy_timer_count = 0;
static int bpy_timer_count= 0;
static double bpy_timer; /* time since python starts */
static double bpy_timer_run; /* time for each python script run */
static double bpy_timer_run_tot; /* accumulate python runs */
@@ -84,7 +91,7 @@ void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
py_call_level++;
if(gilstate)
*gilstate = PyGILState_Ensure();
*gilstate= PyGILState_Ensure();
if(py_call_level==1) {
@@ -102,7 +109,7 @@ void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
if(bpy_timer_count==0) {
/* record time from the beginning */
bpy_timer= PIL_check_seconds_timer();
bpy_timer_run = bpy_timer_run_tot = 0.0;
bpy_timer_run= bpy_timer_run_tot= 0.0;
}
bpy_timer_run= PIL_check_seconds_timer();
@@ -138,9 +145,9 @@ void bpy_context_clear(bContext *UNUSED(C), PyGILState_STATE *gilstate)
void BPY_text_free_code(Text *text)
{
if( text->compiled ) {
Py_DECREF( ( PyObject * ) text->compiled );
text->compiled = NULL;
if(text->compiled) {
Py_DECREF((PyObject *)text->compiled);
text->compiled= NULL;
}
}
@@ -148,8 +155,8 @@ void BPY_modules_update(bContext *C)
{
#if 0 // slow, this runs all the time poll, draw etc 100's of time a sec.
PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
PyModule_AddObject( mod, "data", BPY_rna_module() );
PyModule_AddObject( mod, "types", BPY_rna_types() ); // atm this does not need updating
PyModule_AddObject(mod, "data", BPY_rna_module());
PyModule_AddObject(mod, "types", BPY_rna_types()); // atm this does not need updating
#endif
/* refreshes the main struct */
@@ -163,9 +170,13 @@ static void bpy_python_start_path(void)
{
char *py_path_bundle= BLI_get_folder(BLENDER_PYTHON, NULL);
if(py_path_bundle==NULL)
if(py_path_bundle==NULL) {
/* Common enough to have bundled *nix python but complain on OSX/Win */
#if defined(__APPLE__) || defined(_WIN32)
fprintf(stderr, "Warning! bundled python not found and is expected on this platform. (if you built with CMake: 'install' target may have not been built)\n");
#endif
return;
}
/* set the environment path */
printf("found bundled python: %s\n", py_path_bundle);
@@ -221,26 +232,26 @@ static struct _inittab bpy_internal_modules[]= {
void BPY_python_start(int argc, const char **argv)
{
#ifndef WITH_PYTHON_MODULE
PyThreadState *py_tstate = NULL;
PyThreadState *py_tstate= NULL;
/* not essential but nice to set our name */
static wchar_t bprogname_wchar[FILE_MAXDIR+FILE_MAXFILE]; /* python holds a reference */
utf8towchar(bprogname_wchar, bprogname);
Py_SetProgramName(bprogname_wchar);
/* builtin modules */
/* must run before python initializes */
PyImport_ExtendInittab(bpy_internal_modules);
bpy_python_start_path(); /* allow to use our own included python */
/* Python 3.2 now looks for '2.56/python/include/python3.2d/pyconfig.h' to parse
/* Python 3.2 now looks for '2.57/python/include/python3.2d/pyconfig.h' to parse
* from the 'sysconfig' module which is used by 'site', so for now disable site.
* alternatively we could copy the file. */
Py_NoSiteFlag= 1;
Py_Initialize( );
Py_Initialize();
// PySys_SetArgv( argc, argv); // broken in py3, not a huge deal
// PySys_SetArgv(argc, argv); // broken in py3, not a huge deal
/* sigh, why do python guys not have a char** version anymore? :( */
{
int i;
@@ -257,39 +268,20 @@ void BPY_python_start(int argc, const char **argv)
#else
(void)argc;
(void)argv;
/* must run before python initializes */
PyImport_ExtendInittab(bpy_internal_modules);
#endif
/* bpy.* and lets us import it */
BPy_init_modules();
{ /* our own import and reload functions */
PyObject *item;
PyObject *mod;
//PyObject *m = PyImport_AddModule("__builtin__");
//PyObject *d = PyModule_GetDict(m);
PyObject *d = PyEval_GetBuiltins( );
// PyDict_SetItemString(d, "reload", item=PyCFunction_New(&bpy_reload_meth, NULL)); Py_DECREF(item);
PyDict_SetItemString(d, "__import__", item=PyCFunction_New(&bpy_import_meth, NULL)); Py_DECREF(item);
/* move reload here
* XXX, use import hooks */
mod= PyImport_ImportModuleLevel((char *)"imp", NULL, NULL, NULL, 0);
if(mod) {
PyDict_SetItemString(PyModule_GetDict(mod), "reload", item=PyCFunction_New(&bpy_reload_meth, NULL)); Py_DECREF(item);
Py_DECREF(mod);
}
else {
BLI_assert(!"unable to load 'imp' module.");
}
}
bpy_import_init(PyEval_GetBuiltins());
pyrna_alloc_types();
#ifndef WITH_PYTHON_MODULE
py_tstate = PyGILState_GetThisThreadState();
py_tstate= PyGILState_GetThisThreadState();
PyEval_ReleaseThread(py_tstate);
#endif
}
@@ -305,11 +297,11 @@ void BPY_python_end(void)
/* clear all python data from structs */
Py_Finalize( );
Py_Finalize();
#ifdef TIME_PY_RUN
// measure time since py started
bpy_timer = PIL_check_seconds_timer() - bpy_timer;
bpy_timer= PIL_check_seconds_timer() - bpy_timer;
printf("*bpy stats* - ");
printf("tot exec: %d, ", bpy_timer_count);
@@ -353,7 +345,7 @@ typedef struct {
} PyModuleObject;
#endif
static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const short do_jump)
{
PyObject *main_mod= NULL;
PyObject *py_dict= NULL, *py_result= NULL;
@@ -371,25 +363,26 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
if (text) {
char fn_dummy[FILE_MAXDIR];
bpy_text_filename_get(fn_dummy, text);
bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text);
if( !text->compiled ) { /* if it wasn't already compiled, do it now */
char *buf = txt_to_buf( text );
if(text->compiled == NULL) { /* if it wasn't already compiled, do it now */
char *buf= txt_to_buf(text);
text->compiled =
Py_CompileString( buf, fn_dummy, Py_file_input );
text->compiled= Py_CompileString(buf, fn_dummy, Py_file_input);
MEM_freeN( buf );
MEM_freeN(buf);
if(PyErr_Occurred()) {
python_script_error_jump_text(text);
if(do_jump) {
python_script_error_jump_text(text);
}
BPY_text_free_code(text);
}
}
if(text->compiled) {
py_dict = PyC_DefaultNameSpace(fn_dummy);
py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict);
py_dict= PyC_DefaultNameSpace(fn_dummy);
py_result= PyEval_EvalCode(text->compiled, py_dict, py_dict);
}
}
@@ -397,7 +390,7 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
FILE *fp= fopen(fn, "r");
if(fp) {
py_dict = PyC_DefaultNameSpace(fn);
py_dict= PyC_DefaultNameSpace(fn);
#ifdef _WIN32
/* Previously we used PyRun_File to run directly the code on a FILE
@@ -413,11 +406,11 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
pystring= MEM_mallocN(strlen(fn) + 32, "pystring");
pystring[0]= '\0';
sprintf(pystring, "exec(open(r'%s').read())", fn);
py_result = PyRun_String( pystring, Py_file_input, py_dict, py_dict );
py_result= PyRun_String(pystring, Py_file_input, py_dict, py_dict);
MEM_freeN(pystring);
}
#else
py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict);
py_result= PyRun_File(fp, fn, Py_file_input, py_dict, py_dict);
fclose(fp);
#endif
}
@@ -429,17 +422,20 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
if (!py_result) {
if(text) {
python_script_error_jump_text(text);
if(do_jump) {
python_script_error_jump_text(text);
}
}
BPy_errors_to_report(reports);
} else {
Py_DECREF( py_result );
}
else {
Py_DECREF(py_result);
}
if(py_dict) {
#ifdef PYMODULE_CLEAR_WORKAROUND
PyModuleObject *mmod= (PyModuleObject *)PyDict_GetItemString(PyThreadState_GET()->interp->modules, "__main__");
PyObject *dict_back = mmod->md_dict;
PyObject *dict_back= mmod->md_dict;
/* freeing the module will clear the namespace,
* gives problems running classes defined in this namespace being used later. */
mmod->md_dict= NULL;
@@ -459,18 +455,18 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
/* Can run a file or text block */
int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports)
{
return python_script_exec(C, filepath, NULL, reports);
return python_script_exec(C, filepath, NULL, reports, FALSE);
}
int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports)
int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const short do_jump)
{
return python_script_exec(C, NULL, text, reports);
return python_script_exec(C, NULL, text, reports, do_jump);
}
void BPY_DECREF(void *pyob_ptr)
{
PyGILState_STATE gilstate = PyGILState_Ensure();
PyGILState_STATE gilstate= PyGILState_Ensure();
Py_DECREF((PyObject *)pyob_ptr);
PyGILState_Release(gilstate);
}
@@ -479,7 +475,7 @@ int BPY_button_exec(bContext *C, const char *expr, double *value)
{
PyGILState_STATE gilstate;
PyObject *py_dict, *mod, *retval;
int error_ret = 0;
int error_ret= 0;
PyObject *main_mod= NULL;
if (!value || !expr) return -1;
@@ -495,7 +491,7 @@ int BPY_button_exec(bContext *C, const char *expr, double *value)
py_dict= PyC_DefaultNameSpace("<blender button>");
mod = PyImport_ImportModule("math");
mod= PyImport_ImportModule("math");
if (mod) {
PyDict_Merge(py_dict, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
Py_DECREF(mod);
@@ -505,7 +501,7 @@ int BPY_button_exec(bContext *C, const char *expr, double *value)
PyErr_Clear();
}
retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict);
retval= PyRun_String(expr, Py_eval_input, py_dict, py_dict);
if (retval == NULL) {
error_ret= -1;
@@ -524,7 +520,7 @@ int BPY_button_exec(bContext *C, const char *expr, double *value)
}
}
else {
val = PyFloat_AsDouble(retval);
val= PyFloat_AsDouble(retval);
}
Py_DECREF(retval);
@@ -555,7 +551,8 @@ int BPY_string_exec(bContext *C, const char *expr)
PyGILState_STATE gilstate;
PyObject *main_mod= NULL;
PyObject *py_dict, *retval;
int error_ret = 0;
int error_ret= 0;
Main *bmain_back; /* XXX, quick fix for release (Copy Settings crash), needs further investigation */
if (!expr) return -1;
@@ -569,7 +566,12 @@ int BPY_string_exec(bContext *C, const char *expr)
py_dict= PyC_DefaultNameSpace("<blender string>");
retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict);
bmain_back= bpy_import_main_get();
bpy_import_main_set(CTX_data_main(C));
retval= PyRun_String(expr, Py_eval_input, py_dict, py_dict);
bpy_import_main_set(bmain_back);
if (retval == NULL) {
error_ret= -1;
@@ -650,7 +652,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
else {
int len= PySequence_Fast_GET_SIZE(seq_fast);
int i;
for(i = 0; i < len; i++) {
for(i= 0; i < len; i++) {
PyObject *list_item= PySequence_Fast_GET_ITEM(seq_fast, i);
if(BPy_StructRNA_Check(list_item)) {
@@ -674,11 +676,13 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
}
if(done==0) {
if (item) printf("Context '%s' not a valid type\n", member);
else printf("Context '%s' not found\n", member);
if (item) printf("PyContext '%s' not a valid type\n", member);
else printf("PyContext '%s' not found\n", member);
}
else {
printf("Context '%s' found\n", member);
if(G.f & G_DEBUG) {
printf("PyContext '%s' found\n", member);
}
}
return done;
@@ -690,7 +694,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
/* TODO, reloading the module isnt functional at the moment. */
extern int main_python(int argc, const char **argv);
static struct PyModuleDef bpy_proxy_def = {
static struct PyModuleDef bpy_proxy_def= {
PyModuleDef_HEAD_INIT,
"bpy", /* m_name */
NULL, /* m_doc */
@@ -713,13 +717,13 @@ void bpy_module_delay_init(PyObject *bpy_proxy)
{
const int argc= 1;
const char *argv[2];
const char *filename_rel= PyModule_GetFilename(bpy_proxy); /* can be relative */
PyObject *filename_obj= PyModule_GetFilenameObject(bpy_proxy); /* updating the module dict below will loose the reference to __file__ */
const char *filename_rel= _PyUnicode_AsString(filename_obj); /* can be relative */
char filename_abs[1024];
BLI_strncpy(filename_abs, filename_rel, sizeof(filename_abs));
BLI_path_cwd(filename_abs);
argv[0]= filename_abs;
argv[1]= NULL;
@@ -733,7 +737,7 @@ void bpy_module_delay_init(PyObject *bpy_proxy)
static void dealloc_obj_dealloc(PyObject *self);
static PyTypeObject dealloc_obj_Type = {{{0}}};
static PyTypeObject dealloc_obj_Type= {{{0}}};
/* use our own dealloc so we can free a property if we use one */
static void dealloc_obj_dealloc(PyObject *self)
@@ -767,10 +771,10 @@ PyInit_bpy(void)
dealloc_obj *dob;
/* assign dummy type */
dealloc_obj_Type.tp_name = "dealloc_obj";
dealloc_obj_Type.tp_basicsize = sizeof(dealloc_obj);
dealloc_obj_Type.tp_dealloc = dealloc_obj_dealloc;
dealloc_obj_Type.tp_flags = Py_TPFLAGS_DEFAULT;
dealloc_obj_Type.tp_name= "dealloc_obj";
dealloc_obj_Type.tp_basicsize= sizeof(dealloc_obj);
dealloc_obj_Type.tp_dealloc= dealloc_obj_dealloc;
dealloc_obj_Type.tp_flags= Py_TPFLAGS_DEFAULT;
if(PyType_Ready(&dealloc_obj_Type) < 0)
return NULL;

View File

@@ -0,0 +1,367 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_library.c
* \ingroup pythonintern
*/
#include <Python.h>
#include <stddef.h>
#include "BLO_readfile.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_library.h"
#include "BKE_idcode.h"
#include "BKE_report.h"
#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_linklist.h"
#include "BLI_path_util.h"
#include "BLI_listbase.h"
#include "DNA_space_types.h" /* FILE_LINK, FILE_RELPATH */
#include "bpy_util.h"
typedef struct {
PyObject_HEAD /* required python macro */
/* collection iterator spesific parts */
char relpath[FILE_MAX];
char abspath[FILE_MAX]; /* absolute path */
BlendHandle *blo_handle;
int flag;
PyObject *dict;
} BPy_Library;
static PyObject *bpy_lib_load(PyObject *self, PyObject *args, PyObject *kwds);
static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *args);
static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *args);
static PyObject *bpy_lib_dir(BPy_Library *self);
static PyMethodDef bpy_lib_methods[]= {
{"__enter__", (PyCFunction)bpy_lib_enter, METH_NOARGS},
{"__exit__", (PyCFunction)bpy_lib_exit, METH_VARARGS},
{"__dir__", (PyCFunction)bpy_lib_dir, METH_NOARGS},
{NULL} /* sentinel */
};
static void bpy_lib_dealloc(BPy_Library *self)
{
Py_XDECREF(self->dict);
Py_TYPE(self)->tp_free(self);
}
PyTypeObject bpy_lib_Type= {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_lib", /* tp_name */
sizeof(BPy_Library), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)bpy_lib_dealloc,/* tp_dealloc */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
NULL, /* tp_repr */
/* Method suites for standard classes */
NULL, /* PyNumberMethods *tp_as_number; */
NULL, /* PySequenceMethods *tp_as_sequence; */
NULL, /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
NULL, /* hashfunc tp_hash; */
NULL, /* ternaryfunc tp_call; */
NULL, /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
NULL /*PyObject_GenericGetAttr is assigned later */, /* getattrofunc tp_getattro; */
NULL, /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
NULL, /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
Py_TPFLAGS_DEFAULT, /* long tp_flags; */
NULL, /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL, /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL, /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
NULL, /* subclassed */ /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
0,
/*** Added in release 2.2 ***/
/* Iterators */
NULL, /* getiterfunc tp_iter; */
NULL, /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
bpy_lib_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
NULL, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
NULL, /* PyObject *tp_dict; */
NULL, /* descrgetfunc tp_descr_get; */
NULL, /* descrsetfunc tp_descr_set; */
offsetof(BPy_Library, dict),/* long tp_dictoffset; */
NULL, /* initproc tp_init; */
NULL, /* allocfunc tp_alloc; */
NULL, /* newfunc tp_new; */
/* Low-level free-memory routine */
NULL, /* freefunc tp_free; */
/* For PyObject_IS_GC */
NULL, /* inquiry tp_is_gc; */
NULL, /* PyObject *tp_bases; */
/* method resolution order */
NULL, /* PyObject *tp_mro; */
NULL, /* PyObject *tp_cache; */
NULL, /* PyObject *tp_subclasses; */
NULL, /* PyObject *tp_weaklist; */
NULL
};
static char bpy_lib_load_doc[] =
".. method:: load(filepath, link=False, relative=False)\n"
"\n"
" Returns a context manager which exposes 2 library objects on entering.\n"
" Each object has attributes matching bpy.data which are lists of strings to be linked.\n"
"\n"
" :arg filepath: The path to a blend file.\n"
" :type filepath: string\n"
" :arg link: When False reference to the original file is lost.\n"
" :type link: bool\n"
" :arg relative: When True the path is stored relative to the open blend file.\n"
" :type relative: bool\n"
;
static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *kwds)
{
static const char *kwlist[]= {"filepath", "link", "relative", NULL};
BPy_Library *ret;
const char* filename= NULL;
int is_rel= 0, is_link= 0;
if(!PyArg_ParseTupleAndKeywords(args, kwds, "s|ii:load", (char **)kwlist, &filename, &is_link, &is_rel))
return NULL;
ret= PyObject_New(BPy_Library, &bpy_lib_Type);
BLI_strncpy(ret->relpath, filename, sizeof(ret->relpath));
BLI_strncpy(ret->abspath, filename, sizeof(ret->abspath));
BLI_path_abs(ret->abspath, G.main->name);
ret->blo_handle= NULL;
ret->flag= (is_link ? FILE_LINK : 0) |
(is_rel ? FILE_RELPATH : 0);
ret->dict= PyDict_New();
return (PyObject *)ret;
}
static PyObject *_bpy_names(BPy_Library *self, int blocktype)
{
PyObject *list;
LinkNode *l, *names;
int totnames;
names= BLO_blendhandle_get_datablock_names(self->blo_handle, blocktype, &totnames);
if(names) {
int counter= 0;
list= PyList_New(totnames);
for(l= names; l; l= l->next) {
PyList_SET_ITEM(list, counter, PyUnicode_FromString((char * )l->link));
counter++;
}
BLI_linklist_free(names, free); /* free linklist *and* each node's data */
}
else {
list= PyList_New(0);
}
return list;
}
static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *UNUSED(args))
{
PyObject *ret;
BPy_Library *self_from;
PyObject *from_dict= PyDict_New();
ReportList reports;
BKE_reports_init(&reports, RPT_STORE);
self->blo_handle= BLO_blendhandle_from_file(self->abspath, &reports);
if(self->blo_handle == NULL) {
if(BPy_reports_to_error(&reports, PyExc_IOError, TRUE) != -1) {
PyErr_Format(PyExc_IOError, "load: %s failed to open blend file", self->abspath);
}
return NULL;
}
else {
int i= 0, code;
while((code= BKE_idcode_iter_step(&i))) {
if(BKE_idcode_is_linkable(code)) {
const char *name_plural= BKE_idcode_to_name_plural(code);
PyObject *str= PyUnicode_FromString(name_plural);
PyDict_SetItem(self->dict, str, PyList_New(0));
PyDict_SetItem(from_dict, str, _bpy_names(self, code));
Py_DECREF(str);
}
}
}
/* create a dummy */
self_from= PyObject_New(BPy_Library, &bpy_lib_Type);
BLI_strncpy(self_from->relpath, self->relpath, sizeof(BPy_Library));
BLI_strncpy(self_from->abspath, self->abspath, sizeof(BPy_Library));
self_from->blo_handle= NULL;
self_from->flag= 0;
self_from->dict= from_dict; /* owns the dict */
/* return pair */
ret= PyTuple_New(2);
PyTuple_SET_ITEM(ret, 0, (PyObject *)self_from);
PyTuple_SET_ITEM(ret, 1, (PyObject *)self);
Py_INCREF(self);
BKE_reports_clear(&reports);
return ret;
}
static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
{
Main *mainl= NULL;
int err= 0;
flag_all_listbases_ids(LIB_PRE_EXISTING, 1);
/* here appending/linking starts */
mainl= BLO_library_append_begin(BPy_GetContext(), &(self->blo_handle), self->relpath);
{
int i= 0, code;
while((code= BKE_idcode_iter_step(&i))) {
if(BKE_idcode_is_linkable(code)) {
const char *name_plural= BKE_idcode_to_name_plural(code);
PyObject *ls= PyDict_GetItemString(self->dict, name_plural);
// printf("lib: %s\n", name_plural);
if(ls && PyList_Check(ls)) {
/* loop */
Py_ssize_t size= PyList_GET_SIZE(ls);
Py_ssize_t i;
PyObject *item;
const char *item_str;
for(i= 0; i < size; i++) {
item= PyList_GET_ITEM(ls, i);
item_str= _PyUnicode_AsString(item);
// printf(" %s\n", item_str);
if(item_str) {
if(!BLO_library_append_named_part(NULL, mainl, &(self->blo_handle), item_str, code, self->flag)) {
PyErr_Format(PyExc_KeyError, "load: %s does not contain %s[\"%s\"]", self->abspath, name_plural, item_str);
err= -1;
break;
}
}
else {
/* XXX, could complain about this */
PyErr_Clear();
}
}
}
}
}
}
if(err == -1) {
/* exception raised above, XXX, this leaks some memory */
BLO_blendhandle_close(self->blo_handle);
self->blo_handle= NULL;
flag_all_listbases_ids(LIB_PRE_EXISTING, 0);
return NULL;
}
else {
BLO_library_append_end(NULL, mainl, &(self->blo_handle), 0, self->flag);
BLO_blendhandle_close(self->blo_handle);
self->blo_handle= NULL;
{ /* copied from wm_operator.c */
/* mark all library linked objects to be updated */
recalc_all_library_objects(G.main);
/* append, rather than linking */
if((self->flag & FILE_LINK)==0) {
Library *lib= BLI_findstring(&G.main->library, self->abspath, offsetof(Library, name));
if(lib) all_local(lib, 1);
else BLI_assert(!"cant find name of just added library!");
}
}
flag_all_listbases_ids(LIB_PRE_EXISTING, 0);
Py_RETURN_NONE;
}
}
static PyObject *bpy_lib_dir(BPy_Library *self)
{
return PyDict_Keys(self->dict);
}
int bpy_lib_init(PyObject *mod_par)
{
static PyMethodDef load_meth= {"load", (PyCFunction)bpy_lib_load, METH_STATIC|METH_VARARGS|METH_KEYWORDS, bpy_lib_load_doc};
PyModule_AddObject(mod_par, "_library_load", PyCFunction_New(&load_meth, NULL));
/* some compilers dont like accessing this directly, delay assignment */
bpy_lib_Type.tp_getattro= PyObject_GenericGetAttr;
if(PyType_Ready(&bpy_lib_Type) < 0)
return -1;
return 0;
}

View File

@@ -1,5 +1,5 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -23,19 +23,28 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_operator.c
* \ingroup pythonintern
*/
/* Note, this module is not to be used directly by the user.
* Internally its exposed as '_bpy.ops', which provides functions for 'bpy.ops', a python package.
* */
#include <Python.h>
#include "RNA_types.h"
#include "bpy_operator.h"
#include "bpy_operator_wrap.h"
#include "bpy_rna.h" /* for setting arg props only - pyrna_py_to_prop() */
#include "bpy_util.h"
#include "../generic/bpy_internal_import.h"
#include "BLI_utildefines.h"
#include "RNA_access.h"
#include "RNA_enum_types.h"
#include "WM_api.h"
@@ -110,7 +119,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
{
wmOperatorType *ot;
int error_val = 0;
int error_val= 0;
PointerRNA ptr;
int operator_ret= OPERATOR_CANCELLED;
@@ -124,7 +133,7 @@ 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 = (bContext *)BPy_GetContext();
bContext *C= (bContext *)BPy_GetContext();
if(C==NULL) {
PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators");
@@ -186,12 +195,11 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
ReportList *reports;
reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
BKE_reports_init(reports, RPT_STORE);
BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD); /* own so these dont move into global reports */
operator_ret= WM_operator_call_py(C, ot, context, &ptr, reports);
if(BPy_reports_to_error(reports, FALSE))
error_val = -1;
error_val= BPy_reports_to_error(reports, PyExc_RuntimeError, FALSE);
/* operator output is nice to have in the terminal/console too */
if(reports->list.first) {
@@ -239,6 +247,8 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
* function corrects bpy.data (internal Main pointer) */
BPY_modules_update(C);
/* needed for when WM_OT_read_factory_settings us called fro within a script */
bpy_import_main_set(CTX_data_main(C));
/* return operator_ret as a bpy enum */
return pyrna_enum_bitfield_to_py(operator_return_items, operator_ret);
@@ -252,10 +262,10 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
char *opname;
PyObject *kw= NULL; /* optional args */
int all_args = 1;
int all_args= 1;
int error_val= 0;
char *buf = NULL;
char *buf= NULL;
PyObject *pybuf;
bContext *C= (bContext *)BPy_GetContext();
@@ -304,11 +314,11 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
static PyObject *pyop_dir(PyObject *UNUSED(self))
{
PyObject *list = PyList_New(0), *name;
PyObject *list= PyList_New(0), *name;
wmOperatorType *ot;
for(ot= WM_operatortype_first(); ot; ot= ot->next) {
name = PyUnicode_FromString(ot->idname);
name= PyUnicode_FromString(ot->idname);
PyList_Append(list, name);
Py_DECREF(name);
}
@@ -346,7 +356,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
return (PyObject *)pyrna;
}
static struct PyMethodDef bpy_ops_methods[] = {
static struct PyMethodDef bpy_ops_methods[]= {
{"poll", (PyCFunction) pyop_poll, METH_VARARGS, NULL},
{"call", (PyCFunction) pyop_call, METH_VARARGS, NULL},
{"as_string", (PyCFunction) pyop_as_string, METH_VARARGS, NULL},
@@ -356,7 +366,7 @@ static struct PyMethodDef bpy_ops_methods[] = {
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef bpy_ops_module = {
static struct PyModuleDef bpy_ops_module= {
PyModuleDef_HEAD_INIT,
"_bpy.ops",
NULL,

View File

@@ -21,6 +21,11 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_operator.h
* \ingroup pythonintern
*/
#ifndef BPY_OPERATOR_H
#define BPY_OPERATOR_H

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -22,6 +22,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_operator_wrap.c
* \ingroup pythonintern
*/
#include <Python.h>
#include "bpy_operator_wrap.h"
@@ -30,13 +35,14 @@
#include "BLI_utildefines.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "bpy_rna.h"
static void operator_properties_init(wmOperatorType *ot)
{
PyObject *py_class = ot->ext.data;
PyObject *py_class= ot->ext.data;
RNA_struct_blender_type_set(ot->ext.srna, ot);
/* only call this so pyrna_deferred_register_class gives a useful error
@@ -54,7 +60,7 @@ void operator_wrapper(wmOperatorType *ot, void *userdata)
{
/* take care not to overwrite anything set in
* WM_operatortype_append_ptr before opfunc() is called */
StructRNA *srna = ot->srna;
StructRNA *srna= ot->srna;
*ot= *((wmOperatorType *)userdata);
ot->srna= srna; /* restore */
@@ -65,7 +71,7 @@ void operator_wrapper(wmOperatorType *ot, void *userdata)
PropertyRNA *prop;
RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
prop = RNA_struct_find_property(&ptr, "type");
prop= RNA_struct_find_property(&ptr, "type");
if(prop)
ot->prop= prop;
}
@@ -73,16 +79,16 @@ void operator_wrapper(wmOperatorType *ot, void *userdata)
void macro_wrapper(wmOperatorType *ot, void *userdata)
{
wmOperatorType *data = (wmOperatorType *)userdata;
wmOperatorType *data= (wmOperatorType *)userdata;
/* only copy a couple of things, the rest is set by the macro registration */
ot->name = data->name;
ot->idname = data->idname;
ot->description = data->description;
ot->name= data->name;
ot->idname= data->idname;
ot->description= data->description;
ot->flag |= data->flag; /* append flags to the one set by registration */
ot->pyop_poll = data->pyop_poll;
ot->ui = data->ui;
ot->ext = data->ext;
ot->pyop_poll= data->pyop_poll;
ot->ui= data->ui;
ot->ext= data->ext;
operator_properties_init(ot);
}
@@ -108,16 +114,16 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
/* identifiers */
srna= srna_from_self(macro, "Macro Define:");
macroname = RNA_struct_identifier(srna);
macroname= RNA_struct_identifier(srna);
ot = WM_operatortype_find(macroname, TRUE);
ot= WM_operatortype_find(macroname, TRUE);
if (!ot) {
PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid macro or hasn't been registered yet", macroname);
return NULL;
}
otmacro = WM_operatortype_macro_define(ot, opname);
otmacro= WM_operatortype_macro_define(ot, opname);
RNA_pointer_create(NULL, &RNA_OperatorTypeMacro, otmacro, &ptr_otmacro);

View File

@@ -21,6 +21,11 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_operator_wrap.h
* \ingroup pythonintern
*/
#ifndef BPY_OPERATOR_WRAP_H
#define BPY_OPERATOR_WRAP_H

View File

@@ -22,14 +22,24 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_props.c
* \ingroup pythonintern
*/
#include <Python.h>
#include "RNA_types.h"
#include "bpy_props.h"
#include "bpy_rna.h"
#include "bpy_util.h"
#include "BLI_utildefines.h"
#include "BKE_idprop.h"
#include "RNA_access.h"
#include "RNA_define.h" /* for defining our own rna */
#include "RNA_enum_types.h"
@@ -37,19 +47,19 @@
#include "../generic/py_capi_utils.h"
static EnumPropertyItem property_flag_items[] = {
static EnumPropertyItem property_flag_items[]= {
{PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
{PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem property_flag_enum_items[] = {
static 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 */
static EnumPropertyItem property_subtype_string_items[] = {
static EnumPropertyItem property_subtype_string_items[]= {
{PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""},
{PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""},
{PROP_FILENAME, "FILENAME", 0, "Filename", ""},
@@ -57,7 +67,7 @@ static EnumPropertyItem property_subtype_string_items[] = {
{PROP_NONE, "NONE", 0, "None", ""},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem property_subtype_number_items[] = {
static EnumPropertyItem property_subtype_number_items[]= {
{PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned", ""},
{PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""},
{PROP_FACTOR, "FACTOR", 0, "Factor", ""},
@@ -68,7 +78,7 @@ static EnumPropertyItem property_subtype_number_items[] = {
{PROP_NONE, "NONE", 0, "None", ""},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem property_subtype_array_items[] = {
static EnumPropertyItem property_subtype_array_items[]= {
{PROP_COLOR, "COLOR", 0, "Color", ""},
{PROP_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
{PROP_DIRECTION, "DIRECTION", 0, "Direction", ""},
@@ -86,17 +96,17 @@ static EnumPropertyItem property_subtype_array_items[] = {
{0, NULL, 0, NULL, NULL}};
/* PyObject's */
static PyObject *pymeth_BoolProperty = NULL;
static PyObject *pymeth_BoolVectorProperty = NULL;
static PyObject *pymeth_IntProperty = NULL;
static PyObject *pymeth_IntVectorProperty = NULL;
static PyObject *pymeth_FloatProperty = NULL;
static PyObject *pymeth_FloatVectorProperty = NULL;
static PyObject *pymeth_StringProperty = NULL;
static PyObject *pymeth_EnumProperty = NULL;
static PyObject *pymeth_PointerProperty = NULL;
static PyObject *pymeth_CollectionProperty = NULL;
static PyObject *pymeth_RemoveProperty = NULL;
static PyObject *pymeth_BoolProperty= NULL;
static PyObject *pymeth_BoolVectorProperty= NULL;
static PyObject *pymeth_IntProperty= NULL;
static PyObject *pymeth_IntVectorProperty= NULL;
static PyObject *pymeth_FloatProperty= NULL;
static PyObject *pymeth_FloatVectorProperty= NULL;
static PyObject *pymeth_StringProperty= NULL;
static PyObject *pymeth_EnumProperty= NULL;
static PyObject *pymeth_PointerProperty= NULL;
static PyObject *pymeth_CollectionProperty= NULL;
static PyObject *pymeth_RemoveProperty= NULL;
/* operators and classes use this so it can store the args given but defer
@@ -104,7 +114,7 @@ static PyObject *pymeth_RemoveProperty = NULL;
* the default args for that operator instance */
static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
{
PyObject *ret = PyTuple_New(2);
PyObject *ret= PyTuple_New(2);
PyTuple_SET_ITEM(ret, 0, func);
Py_INCREF(func);
@@ -203,7 +213,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_HEAD(BoolProperty)
if(srna) {
static const char *kwlist[] = {"attr", "name", "description", "default", "options", "subtype", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default", "options", "subtype", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
int def=0;
@@ -245,7 +255,7 @@ BPY_PROPDEF_DESC_DOC
" :type options: set\n"
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
" :type subtype: string\n"
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
" :type size: int\n"
;
static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
@@ -255,7 +265,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
BPY_PROPDEF_HEAD(BoolVectorProperty)
if(srna) {
static const char *kwlist[] = {"attr", "name", "description", "default", "options", "subtype", "size", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default", "options", "subtype", "size", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
int def[PYRNA_STACK_ARRAY]={0};
@@ -315,7 +325,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_HEAD(IntProperty)
if(srna) {
static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def=0;
@@ -358,7 +368,7 @@ BPY_PROPDEF_DESC_DOC
" :type options: set\n"
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
" :type subtype: string\n"
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
" :type size: int\n"
;
static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
@@ -368,7 +378,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
BPY_PROPDEF_HEAD(IntVectorProperty)
if(srna) {
static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "size", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "size", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def[PYRNA_STACK_ARRAY]={0};
@@ -431,7 +441,7 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_HEAD(FloatProperty)
if(srna) {
static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "unit", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "unit", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def=0.0f;
@@ -482,7 +492,7 @@ BPY_PROPDEF_DESC_DOC
" :type options: set\n"
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
" :type subtype: string\n"
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
" :type size: int\n"
;
static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
@@ -492,7 +502,7 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
BPY_PROPDEF_HEAD(FloatVectorProperty)
if(srna) {
static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "size", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "size", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def[PYRNA_STACK_ARRAY]={0.0f};
@@ -552,7 +562,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
BPY_PROPDEF_HEAD(StringProperty)
if(srna) {
static const char *kwlist[] = {"attr", "name", "description", "default", "maxlen", "options", "subtype", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default", "maxlen", "options", "subtype", NULL};
const char *id=NULL, *name="", *description="", *def="";
int id_len;
int maxlen=0;
@@ -693,7 +703,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_HEAD(EnumProperty)
if(srna) {
static const char *kwlist[] = {"attr", "items", "name", "description", "default", "options", NULL};
static const char *kwlist[]= {"attr", "items", "name", "description", "default", "options", NULL};
const char *id=NULL, *name="", *description="";
PyObject *def= NULL;
int id_len;
@@ -778,7 +788,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
BPY_PROPDEF_HEAD(PointerProperty)
if(srna) {
static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL};
static const char *kwlist[]= {"attr", "type", "name", "description", "options", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
PropertyRNA *prop;
@@ -825,7 +835,7 @@ static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject
BPY_PROPDEF_HEAD(CollectionProperty)
if(srna) {
static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL};
static const char *kwlist[]= {"attr", "type", "name", "description", "options", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
PropertyRNA *prop;
@@ -887,7 +897,7 @@ static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw
return NULL;
}
else {
static const char *kwlist[] = {"attr", NULL};
static const char *kwlist[]= {"attr", NULL};
char *id=NULL;
@@ -902,7 +912,7 @@ static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw
Py_RETURN_NONE;
}
static struct PyMethodDef props_methods[] = {
static struct PyMethodDef props_methods[]= {
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolProperty_doc},
{"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolVectorProperty_doc},
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntProperty_doc},
@@ -918,7 +928,7 @@ static struct PyMethodDef props_methods[] = {
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef props_module = {
static struct PyModuleDef props_module= {
PyModuleDef_HEAD_INIT,
"bpy.props",
"This module defines properties to extend blenders internal data, the result of these functions"
@@ -944,7 +954,7 @@ PyObject *BPY_rna_props( void )
/* api needs the PyObjects internally */
submodule_dict= PyModule_GetDict(submodule);
#define ASSIGN_STATIC(_name) pymeth_##_name = PyDict_GetItemString(submodule_dict, #_name)
#define ASSIGN_STATIC(_name) pymeth_##_name= PyDict_GetItemString(submodule_dict, #_name)
ASSIGN_STATIC(BoolProperty);
ASSIGN_STATIC(BoolVectorProperty);

View File

@@ -22,6 +22,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_props.h
* \ingroup pythonintern
*/
#ifndef BPY_PROPS_H
#define BPY_PROPS_H

View File

@@ -22,23 +22,41 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_rna.c
* \ingroup pythonintern
*/
#include <Python.h>
#include <stddef.h>
#include <float.h> /* FLT_MIN/MAX */
#include "RNA_types.h"
#include "bpy_rna.h"
#include "bpy_rna_anim.h"
#include "bpy_props.h"
#include "bpy_util.h"
#include "bpy_rna_callback.h"
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
#include "MEM_guardedalloc.h"
#endif
#include "BLI_dynstr.h"
#include "BLI_string.h"
#include "BLI_listbase.h"
#include "BLI_math_rotation.h"
#include "BLI_utildefines.h"
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
#include "BLI_ghash.h"
#endif
#include "RNA_enum_types.h"
#include "RNA_define.h" /* RNA_def_property_free_identifier */
#include "RNA_access.h"
#include "MEM_guardedalloc.h"
@@ -46,15 +64,11 @@
#include "BKE_context.h"
#include "BKE_global.h" /* evil G.* */
#include "BKE_report.h"
#include "BKE_idprop.h"
#include "BKE_animsys.h"
#include "BKE_fcurve.h"
/* only for keyframing */
#include "DNA_scene_types.h"
#include "DNA_anim_types.h"
#include "ED_keyframing.h"
#include "../generic/IDProp.h" /* for IDprop lookups */
#include "../generic/py_capi_utils.h"
@@ -62,8 +76,217 @@
#define USE_MATHUTILS
#define USE_STRING_COERCE
static PyObject* pyrna_struct_Subtype(PointerRNA *ptr);
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
int pyrna_struct_validity_check(BPy_StructRNA *pysrna)
{
if(pysrna->ptr.type)
return 0;
PyErr_Format(PyExc_ReferenceError, "StructRNA of type %.200s has been removed", Py_TYPE(pysrna)->tp_name);
return -1;
}
int pyrna_prop_validity_check(BPy_PropertyRNA *self)
{
if(self->ptr.type)
return 0;
PyErr_Format(PyExc_ReferenceError, "PropertyRNA of type %.200s.%.200s has been removed", Py_TYPE(self)->tp_name, RNA_property_identifier(self->prop));
return -1;
}
#if defined(USE_PYRNA_INVALIDATE_GC) || defined(USE_PYRNA_INVALIDATE_WEAKREF)
static void pyrna_invalidate(BPy_DummyPointerRNA *self)
{
self->ptr.type= NULL; /* this is checked for validity */
self->ptr.id.data= NULL; /* should not be needed but prevent bad pointer access, just incase */
}
#endif
#ifdef USE_PYRNA_INVALIDATE_GC
#define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1))
/* only for sizeof() */
struct gc_generation {
PyGC_Head head;
int threshold;
int count;
} gc_generation;
static void id_release_gc(struct ID *id)
{
unsigned int j;
// unsigned int i= 0;
for(j=0; j<3; j++) {
/* hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed */
PyGC_Head *gen= (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j));
PyGC_Head *g= gen->gc.gc_next;
while ((g= g->gc.gc_next) != gen) {
PyObject *ob= FROM_GC(g);
if(PyType_IsSubtype(Py_TYPE(ob), &pyrna_struct_Type) || PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type)) {
BPy_DummyPointerRNA *ob_ptr= (BPy_DummyPointerRNA *)ob;
if(ob_ptr->ptr.id.data == id) {
pyrna_invalidate(ob_ptr);
// printf("freeing: %p %s, %.200s\n", (void *)ob, id->name, Py_TYPE(ob)->tp_name);
// i++;
}
}
}
}
// printf("id_release_gc freed '%s': %d\n", id->name, i);
}
#endif
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
//#define DEBUG_RNA_WEAKREF
struct GHash *id_weakref_pool= NULL;
static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref);
static PyMethodDef id_free_weakref_cb_def= {"id_free_weakref_cb", (PyCFunction)id_free_weakref_cb, METH_O, NULL};
/* adds a reference to the list, remember ot decref */
static GHash *id_weakref_pool_get(ID *id)
{
GHash *weakinfo_hash= NULL;
if(id_weakref_pool) {
weakinfo_hash= BLI_ghash_lookup(id_weakref_pool, (void *)id);
}
else {
/* first time, allocate pool */
id_weakref_pool= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "rna_global_pool");
weakinfo_hash= NULL;
}
if(weakinfo_hash==NULL) {
/* we're using a ghash as a set, could use libHX's HXMAP_SINGULAR but would be an extra dep. */
weakinfo_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "rna_id");
BLI_ghash_insert(id_weakref_pool, (void *)id, weakinfo_hash);
}
return weakinfo_hash;
}
/* called from pyrna_struct_CreatePyObject() and pyrna_prop_CreatePyObject() */
void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna)
{
PyObject *weakref;
PyObject *weakref_capsule;
PyObject *weakref_cb_py;
/* create a new function instance and insert the list as 'self' so we can remove ourself from it */
GHash *weakinfo_hash= id_weakref_pool_get(id); /* new or existing */
weakref_capsule= PyCapsule_New(weakinfo_hash, NULL, NULL);
weakref_cb_py= PyCFunction_New(&id_free_weakref_cb_def, weakref_capsule);
Py_DECREF(weakref_capsule);
/* add weakref to weakinfo_hash list */
weakref= PyWeakref_NewRef((PyObject *)pyrna, weakref_cb_py);
Py_DECREF(weakref_cb_py); /* function owned by the weakref now */
/* important to add at the end, since first removal looks at the end */
BLI_ghash_insert(weakinfo_hash, (void *)weakref, id); /* using a hash table as a set, all 'id's are the same */
/* weakinfo_hash owns the weakref */
}
/* workaround to get the last id without a lookup */
static ID *_id_tmp_ptr;
static void value_id_set(void *id)
{
_id_tmp_ptr= (ID *)id;
}
static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash);
static PyObject *id_free_weakref_cb(PyObject *weakinfo_capsule, PyObject *weakref)
{
/* important to search backwards */
GHash *weakinfo_hash= PyCapsule_GetPointer(weakinfo_capsule, NULL);
if(BLI_ghash_size(weakinfo_hash) > 1) {
BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL);
}
else { /* get the last id and free it */
BLI_ghash_remove(weakinfo_hash, weakref, NULL, value_id_set);
id_release_weakref_list(_id_tmp_ptr, weakinfo_hash);
}
Py_DECREF(weakref);
Py_RETURN_NONE;
}
static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
{
GHashIterator weakinfo_hash_iter;
BLI_ghashIterator_init(&weakinfo_hash_iter, weakinfo_hash);
#ifdef DEBUG_RNA_WEAKREF
fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_size(weakinfo_hash));
#endif
while (!BLI_ghashIterator_isDone(&weakinfo_hash_iter)) {
PyObject *weakref= (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter);
PyObject *item= PyWeakref_GET_OBJECT(weakref);
if(item != Py_None) {
#ifdef DEBUG_RNA_WEAKREF
PyC_ObSpit("id_release_weakref item ", item);
#endif
pyrna_invalidate((BPy_DummyPointerRNA *)item);
}
Py_DECREF(weakref);
BLI_ghashIterator_step(&weakinfo_hash_iter);
}
BLI_ghash_remove(id_weakref_pool, (void *)id, NULL, NULL);
BLI_ghash_free(weakinfo_hash, NULL, NULL);
if(BLI_ghash_size(id_weakref_pool) == 0) {
BLI_ghash_free(id_weakref_pool, NULL, NULL);
id_weakref_pool= NULL;
#ifdef DEBUG_RNA_WEAKREF
printf("id_release_weakref freeing pool\n");
#endif
}
}
static void id_release_weakref(struct ID *id)
{
GHash *weakinfo_hash= BLI_ghash_lookup(id_weakref_pool, (void *)id);
if(weakinfo_hash) {
id_release_weakref_list(id, weakinfo_hash);
}
}
#endif /* USE_PYRNA_INVALIDATE_WEAKREF */
void BPY_id_release(struct ID *id)
{
#ifdef USE_PYRNA_INVALIDATE_GC
id_release_gc(id);
#endif
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
if(id_weakref_pool) {
PyGILState_STATE gilstate= PyGILState_Ensure();
id_release_weakref(id);
PyGILState_Release(gilstate);
}
#endif /* USE_PYRNA_INVALIDATE_WEAKREF */
(void)id;
}
#ifdef USE_PEDANTIC_WRITE
static short rna_disallow_writes= FALSE;
@@ -125,14 +348,20 @@ static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */
static int mathutils_rna_generic_check(BaseMathObject *bmo)
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
return self->prop ? 1:0;
PYRNA_PROP_CHECK_INT(self)
return self->prop ? 0 : -1;
}
static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype)
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
PYRNA_PROP_CHECK_INT(self)
if(self->prop==NULL)
return 0;
return -1;
RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
@@ -143,25 +372,28 @@ static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype)
eul->order= pyrna_rotation_euler_order_get(&self->ptr, &prop_eul_order, eul->order);
}
return 1;
return 0;
}
static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
float min, max;
PYRNA_PROP_CHECK_INT(self)
if(self->prop==NULL)
return 0;
return -1;
#ifdef USE_PEDANTIC_WRITE
if(rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
return 0;
return -1;
}
#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));
return 0;
return -1;
}
RNA_property_float_range(&self->ptr, self->prop, &min, &max);
@@ -190,36 +422,40 @@ static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
}
}
}
return 1;
return 0;
}
static int mathutils_rna_vector_get_index(BaseMathObject *bmo, int UNUSED(subtype), int index)
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
PYRNA_PROP_CHECK_INT(self)
if(self->prop==NULL)
return 0;
return -1;
bmo->data[index]= RNA_property_float_get_index(&self->ptr, self->prop, index);
return 1;
return 0;
}
static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int UNUSED(subtype), int index)
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
PYRNA_PROP_CHECK_INT(self)
if(self->prop==NULL)
return 0;
return -1;
#ifdef USE_PEDANTIC_WRITE
if(rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
return 0;
return -1;
}
#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));
return 0;
return -1;
}
RNA_property_float_clamp(&self->ptr, self->prop, &bmo->data[index]);
@@ -229,10 +465,10 @@ static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int UNUSED(subtyp
RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
}
return 1;
return 0;
}
static Mathutils_Callback mathutils_rna_array_cb = {
static Mathutils_Callback mathutils_rna_array_cb= {
(BaseMathCheckFunc) mathutils_rna_generic_check,
(BaseMathGetFunc) mathutils_rna_vector_get,
(BaseMathSetFunc) mathutils_rna_vector_set,
@@ -248,29 +484,33 @@ static int mathutils_rna_matrix_get(BaseMathObject *bmo, int UNUSED(subtype))
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
PYRNA_PROP_CHECK_INT(self)
if(self->prop==NULL)
return 0;
return -1;
RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
return 1;
return 0;
}
static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype))
{
BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
PYRNA_PROP_CHECK_INT(self)
if(self->prop==NULL)
return 0;
return -1;
#ifdef USE_PEDANTIC_WRITE
if(rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
return 0;
return -1;
}
#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));
return 0;
return -1;
}
/* can ignore clamping here */
@@ -279,10 +519,10 @@ static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype))
if(RNA_property_update_check(self->prop)) {
RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
}
return 1;
return 0;
}
static Mathutils_Callback mathutils_rna_matrix_cb = {
static Mathutils_Callback mathutils_rna_matrix_cb= {
mathutils_rna_generic_check,
mathutils_rna_matrix_get,
mathutils_rna_matrix_set,
@@ -298,7 +538,7 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_
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 */
if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) /* could be quat or axisangle */
return order;
}
@@ -307,7 +547,9 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_
#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
/* note that PROP_NONE is included as a vector subtype. this is because its handy to
* have x/y access to fcurve keyframes and other fixed size float arrayas of length 2-4. */
#define PROP_ALL_VECTOR_SUBTYPES PROP_COORDS: case 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)
{
@@ -327,11 +569,11 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
len= RNA_property_array_length(ptr, prop);
subtype= RNA_property_subtype(prop);
totdim= RNA_property_array_dimension(ptr, prop, NULL);
is_thick = (flag & PROP_THICK_WRAP);
is_thick= (flag & PROP_THICK_WRAP);
if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) {
if(!is_thick)
ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the Mathutils PyObject */
ret= pyrna_prop_CreatePyObject(ptr, prop); /* owned by the Mathutils PyObject */
switch(RNA_property_subtype(prop)) {
case PROP_ALL_VECTOR_SUBTYPES:
@@ -377,14 +619,14 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
if(is_thick) {
/* attempt to get order, only needed for thick types since wrapped with update via callbacks */
PropertyRNA *prop_eul_order= NULL;
short order= pyrna_rotation_euler_order_get(ptr, &prop_eul_order, ROT_MODE_XYZ);
short order= pyrna_rotation_euler_order_get(ptr, &prop_eul_order, EULER_ORDER_XYZ);
ret= newEulerObject(NULL, order, Py_NEW, NULL); // TODO, get order from RNA
RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul);
}
else {
/* order will be updated from callback on use */
PyObject *eul_cb= newEulerObject_cb(ret, ROT_MODE_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); // TODO, get order from RNA
PyObject *eul_cb= newEulerObject_cb(ret, EULER_ORDER_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); // TODO, get order from RNA
Py_DECREF(ret); /* the euler owns now */
ret= eul_cb; /* return the euler instead */
}
@@ -402,6 +644,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
}
break;
case PROP_COLOR:
case PROP_COLOR_GAMMA:
if(len==3) { /* color */
if(is_thick) {
ret= newColorObject(NULL, Py_NEW, NULL); // TODO, get order from RNA
@@ -422,9 +665,10 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
if(is_thick) {
/* this is an array we cant reference (since its not thin wrappable)
* and cannot be coerced into a mathutils type, so return as a list */
ret = pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len);
} else {
ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the Mathutils PyObject */
ret= pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len);
}
else {
ret= pyrna_prop_CreatePyObject(ptr, prop); /* owned by the Mathutils PyObject */
}
}
#else // USE_MATHUTILS
@@ -435,7 +679,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
return ret;
}
/* same as RNA_enum_value_from_id but raises an exception */
/* 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)
{
if(RNA_enum_value_from_id(item, identifier, value) == 0) {
@@ -448,14 +692,14 @@ int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int
return 0;
}
static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b )
static int pyrna_struct_compare(BPy_StructRNA *a, BPy_StructRNA *b)
{
return (a->ptr.data==b->ptr.data) ? 0 : -1;
}
static int pyrna_prop_compare( BPy_PropertyRNA * a, BPy_PropertyRNA * b )
static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b)
{
return (a->prop==b->prop && a->ptr.data==b->ptr.data ) ? 0 : -1;
return (a->prop==b->prop && a->ptr.data==b->ptr.data) ? 0 : -1;
}
static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
@@ -468,16 +712,16 @@ static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
switch (op) {
case Py_NE:
ok = !ok; /* pass through */
ok= !ok; /* pass through */
case Py_EQ:
res = ok ? Py_False : Py_True;
res= ok ? Py_False : Py_True;
break;
case Py_LT:
case Py_LE:
case Py_GT:
case Py_GE:
res = Py_NotImplemented;
res= Py_NotImplemented;
break;
default:
PyErr_BadArgument();
@@ -497,16 +741,16 @@ static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
switch (op) {
case Py_NE:
ok = !ok; /* pass through */
ok= !ok; /* pass through */
case Py_EQ:
res = ok ? Py_False : Py_True;
res= ok ? Py_False : Py_True;
break;
case Py_LT:
case Py_LE:
case Py_GT:
case Py_GE:
res = Py_NotImplemented;
res= Py_NotImplemented;
break;
default:
PyErr_BadArgument();
@@ -517,55 +761,63 @@ static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
}
/*----------------------repr--------------------------------------------*/
static PyObject *pyrna_struct_str( BPy_StructRNA *self )
static PyObject *pyrna_struct_str(BPy_StructRNA *self)
{
PyObject *ret;
const char *name;
if(!PYRNA_STRUCT_IS_VALID(self)) {
return PyUnicode_FromFormat("<bpy_struct, %.200s dead>", Py_TYPE(self)->tp_name);
}
/* print name if available */
name= RNA_struct_name_get_alloc(&self->ptr, NULL, FALSE);
if(name) {
ret= PyUnicode_FromFormat( "<bpy_struct, %.200s(\"%.200s\")>", RNA_struct_identifier(self->ptr.type), name);
ret= PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\")>", RNA_struct_identifier(self->ptr.type), name);
MEM_freeN((void *)name);
return ret;
}
return PyUnicode_FromFormat( "<bpy_struct, %.200s at %p>", RNA_struct_identifier(self->ptr.type), self->ptr.data);
return PyUnicode_FromFormat("<bpy_struct, %.200s at %p>", RNA_struct_identifier(self->ptr.type), self->ptr.data);
}
static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
{
ID *id= self->ptr.id.data;
if(id == NULL)
if(id == NULL || !PYRNA_STRUCT_IS_VALID(self))
return pyrna_struct_str(self); /* fallback */
if(RNA_struct_is_ID(self->ptr.type)) {
return PyUnicode_FromFormat( "bpy.data.%s[\"%s\"]", BKE_idcode_to_name_plural(GS(id->name)), id->name+2);
return PyUnicode_FromFormat("bpy.data.%s[\"%s\"]", BKE_idcode_to_name_plural(GS(id->name)), id->name+2);
}
else {
PyObject *ret;
const char *path;
path= RNA_path_from_ID_to_struct(&self->ptr);
if(path) {
ret= PyUnicode_FromFormat( "bpy.data.%s[\"%s\"].%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, path);
ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"].%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, path);
MEM_freeN((void *)path);
}
else { /* cant find, print something sane */
ret= PyUnicode_FromFormat( "bpy.data.%s[\"%s\"]...%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, RNA_struct_identifier(self->ptr.type));
ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"]...%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, RNA_struct_identifier(self->ptr.type));
}
return ret;
}
}
static PyObject *pyrna_prop_str( BPy_PropertyRNA *self )
static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
{
PyObject *ret;
PointerRNA ptr;
const char *name;
const char *type_id= NULL;
char type_fmt[64]= "";
int type= RNA_property_type(self->prop);
int type;
PYRNA_PROP_CHECK_OBJ(self)
type= RNA_property_type(self->prop);
if(RNA_enum_id_from_value(property_type_items, type, &type_id)==0) {
PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error"); /* should never happen */
@@ -573,14 +825,15 @@ static PyObject *pyrna_prop_str( BPy_PropertyRNA *self )
}
else {
/* this should never fail */
int len = -1;
int len= -1;
char *c= type_fmt;
while ( (*c++= tolower(*type_id++)) ) {} ;
while ((*c++= tolower(*type_id++))) {} ;
if(type==PROP_COLLECTION) {
len= pyrna_prop_collection_length(self);
} else if (RNA_property_array_check(&self->ptr, self->prop)) {
}
else if (RNA_property_array_check(&self->ptr, self->prop)) {
len= pyrna_prop_array_length((BPy_PropertyArrayRNA *)self);
}
@@ -594,7 +847,7 @@ static PyObject *pyrna_prop_str( BPy_PropertyRNA *self )
name= RNA_struct_name_get_alloc(&ptr, NULL, FALSE);
if(name) {
ret= PyUnicode_FromFormat( "<bpy_%.200s, %.200s.%.200s(\"%.200s\")>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name);
ret= PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name);
MEM_freeN((void *)name);
return ret;
}
@@ -602,35 +855,37 @@ static PyObject *pyrna_prop_str( BPy_PropertyRNA *self )
if(RNA_property_type(self->prop) == PROP_COLLECTION) {
PointerRNA r_ptr;
if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
return PyUnicode_FromFormat( "<bpy_%.200s, %.200s>", type_fmt, RNA_struct_identifier(r_ptr.type));
return PyUnicode_FromFormat("<bpy_%.200s, %.200s>", type_fmt, RNA_struct_identifier(r_ptr.type));
}
}
return PyUnicode_FromFormat( "<bpy_%.200s, %.200s.%.200s>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop));
}
static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self)
{
ID *id= self->ptr.id.data;
ID *id;
PyObject *ret;
const char *path;
if(id == NULL)
PYRNA_PROP_CHECK_OBJ(self)
if((id= self->ptr.id.data) == NULL)
return pyrna_prop_str(self); /* fallback */
path= RNA_path_from_ID_to_property(&self->ptr, self->prop);
if(path) {
ret= PyUnicode_FromFormat( "bpy.data.%s[\"%s\"].%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, path);
ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"].%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, path);
MEM_freeN((void *)path);
}
else { /* cant find, print something sane */
ret= PyUnicode_FromFormat( "bpy.data.%s[\"%s\"]...%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, RNA_property_identifier(self->prop));
ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"]...%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, RNA_property_identifier(self->prop));
}
return ret;
}
static long pyrna_struct_hash( BPy_StructRNA *self )
static long pyrna_struct_hash(BPy_StructRNA *self)
{
return _Py_HashPointer(self->ptr.data);
}
@@ -638,23 +893,37 @@ static long pyrna_struct_hash( BPy_StructRNA *self )
/* from python's meth_hash v3.1.2 */
static long pyrna_prop_hash(BPy_PropertyRNA *self)
{
long x,y;
long x, y;
if (self->ptr.data == NULL)
x = 0;
x= 0;
else {
x = _Py_HashPointer(self->ptr.data);
x= _Py_HashPointer(self->ptr.data);
if (x == -1)
return -1;
}
y = _Py_HashPointer((void*)(self->prop));
y= _Py_HashPointer((void*)(self->prop));
if (y == -1)
return -1;
x ^= y;
if (x == -1)
x = -2;
x= -2;
return x;
}
#ifdef USE_PYRNA_STRUCT_REFERENCE
static int pyrna_struct_traverse(BPy_StructRNA *self, visitproc visit, void *arg)
{
Py_VISIT(self->reference);
return 0;
}
static int pyrna_struct_clear(BPy_StructRNA *self)
{
Py_CLEAR(self->reference);
return 0;
}
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
/* use our own dealloc so we can free a property if we use one */
static void pyrna_struct_dealloc(BPy_StructRNA *self)
{
@@ -665,21 +934,45 @@ static void pyrna_struct_dealloc(BPy_StructRNA *self)
}
#ifdef USE_WEAKREFS
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *)self);
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *)self);
}
#endif
#ifdef USE_PYRNA_STRUCT_REFERENCE
if(self->reference) {
PyObject_GC_UnTrack(self);
pyrna_struct_clear(self);
}
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
Py_TYPE(self)->tp_free(self);
}
#ifdef USE_PYRNA_STRUCT_REFERENCE
static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
{
if(self->reference) {
// PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED? */
pyrna_struct_clear(self);
}
/* reference is now NULL */
if(reference) {
self->reference= reference;
Py_INCREF(reference);
// PyObject_GC_Track(self); /* INITIALIZED TRACKED? */
}
}
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
/* use our own dealloc so we can free a property if we use one */
static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
{
#ifdef USE_WEAKREFS
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *)self);
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *)self);
}
#endif
/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
@@ -689,8 +982,8 @@ static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self)
{
#ifdef USE_WEAKREFS
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *)self);
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *)self);
}
#endif
/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
@@ -727,11 +1020,12 @@ static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *pr
PyErr_Format(PyExc_TypeError, "%.200s expected a string enum type in (%.200s)", error_prefix, enum_str);
MEM_freeN((void *)enum_str);
return 0;
} else {
}
else {
/* hack so that dynamic enums used for operator properties will be able to be built (i.e. context will be supplied to itemf)
* and thus running defining operator buttons for such operators in UI will work */
RNA_def_property_clear_flag(prop, PROP_ENUM_NO_CONTEXT);
RNA_def_property_clear_flag(prop, PROP_ENUM_NO_CONTEXT);
if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, val)) {
const char *enum_str= pyrna_enum_as_string(ptr, prop);
PyErr_Format(PyExc_TypeError, "%.200s enum \"%.200s\" not found in (%.200s)", error_prefix, param, enum_str);
@@ -749,9 +1043,9 @@ int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_
int ret, flag= 0;
/* set looping */
Py_ssize_t pos = 0;
Py_ssize_t pos= 0;
Py_ssize_t hash= 0;
PyObject *key;
long hash;
*r_value= 0;
@@ -842,8 +1136,9 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
else {
const char *identifier;
if (RNA_property_enum_identifier(BPy_GetContext(), ptr, prop, val, &identifier)) {
ret = PyUnicode_FromString(identifier);
} else {
ret= PyUnicode_FromString(identifier);
}
else {
EnumPropertyItem *enum_item;
int free= FALSE;
@@ -859,7 +1154,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
/* prefer not fail silently incase of api errors, maybe disable it later */
printf("RNA Warning: Current value \"%d\" matches no enum in '%s', '%s', '%s'\n", val, RNA_struct_identifier(ptr->type), ptr_name, RNA_property_identifier(prop));
#if 0 // gives python decoding errors while generating docs :(
#if 0 // gives python decoding errors while generating docs :(
char error_str[256];
snprintf(error_str, sizeof(error_str), "RNA Warning: Current value \"%d\" matches no enum in '%s', '%s', '%s'", val, RNA_struct_identifier(ptr->type), ptr_name, RNA_property_identifier(prop));
PyErr_Warn(PyExc_RuntimeWarning, error_str);
@@ -868,14 +1163,14 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
if(ptr_name)
MEM_freeN((void *)ptr_name);
ret = PyUnicode_FromString("");
ret= PyUnicode_FromString("");
}
if(free)
MEM_freeN(enum_item);
/*PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val);
ret = NULL;*/
ret= NULL;*/
}
}
@@ -885,7 +1180,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
{
PyObject *ret;
int type = RNA_property_type(prop);
int type= RNA_property_type(prop);
if (RNA_property_array_check(ptr, prop)) {
return pyrna_py_from_array(ptr, prop);
@@ -894,19 +1189,19 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
/* see if we can coorce into a python type - PropertyType */
switch (type) {
case PROP_BOOLEAN:
ret = PyBool_FromLong( RNA_property_boolean_get(ptr, prop) );
ret= PyBool_FromLong(RNA_property_boolean_get(ptr, prop));
break;
case PROP_INT:
ret = PyLong_FromSsize_t( (Py_ssize_t)RNA_property_int_get(ptr, prop) );
ret= PyLong_FromSsize_t((Py_ssize_t)RNA_property_int_get(ptr, prop));
break;
case PROP_FLOAT:
ret = PyFloat_FromDouble( RNA_property_float_get(ptr, prop) );
ret= PyFloat_FromDouble(RNA_property_float_get(ptr, prop));
break;
case PROP_STRING:
{
int subtype= RNA_property_subtype(prop);
const char *buf;
buf = RNA_property_string_get_alloc(ptr, prop, NULL, -1);
buf= RNA_property_string_get_alloc(ptr, prop, NULL, -1);
#ifdef USE_STRING_COERCE
/* only file paths get special treatment, they may contain non utf-8 chars */
if(ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
@@ -931,19 +1226,20 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
PointerRNA newptr;
newptr= RNA_property_pointer_get(ptr, prop);
if (newptr.data) {
ret = pyrna_struct_CreatePyObject(&newptr);
} else {
ret = Py_None;
ret= pyrna_struct_CreatePyObject(&newptr);
}
else {
ret= Py_None;
Py_INCREF(ret);
}
break;
}
case PROP_COLLECTION:
ret = pyrna_prop_CreatePyObject(ptr, prop);
ret= pyrna_prop_CreatePyObject(ptr, prop);
break;
default:
PyErr_Format(PyExc_TypeError, "bpy_struct internal error: unknown type '%d' (pyrna_prop_to_py)", type);
ret = NULL;
ret= NULL;
break;
}
@@ -954,12 +1250,12 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
* Its takes keyword args and fills them with property values */
int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix)
{
int error_val = 0;
int error_val= 0;
int totkw;
const char *arg_name= NULL;
PyObject *item;
totkw = kw ? PyDict_Size(kw):0;
totkw= kw ? PyDict_Size(kw):0;
RNA_STRUCT_BEGIN(ptr, prop) {
arg_name= RNA_property_identifier(prop);
@@ -977,10 +1273,11 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
if (item == NULL) {
if(all_args) {
PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" missing", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
error_val = -1; /* pyrna_py_to_prop sets the error */
error_val= -1; /* pyrna_py_to_prop sets the error */
break;
}
} else {
}
else {
if (pyrna_py_to_prop(ptr, prop, NULL, item, error_prefix)) {
error_val= -1;
break;
@@ -992,7 +1289,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
if (error_val==0 && totkw > 0) { /* some keywords were given that were not used :/ */
PyObject *key, *value;
Py_ssize_t pos = 0;
Py_ssize_t pos= 0;
while (PyDict_Next(kw, &pos, &key, &value)) {
arg_name= _PyUnicode_AsString(key);
@@ -1001,7 +1298,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
}
PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" unrecognized", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
error_val = -1;
error_val= -1;
}
return error_val;
@@ -1011,7 +1308,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw);
static PyObject *pyrna_func_to_py(BPy_DummyPointerRNA *pyrna, FunctionRNA *func)
{
static PyMethodDef func_meth = {"<generic rna function>", (PyCFunction)pyrna_func_call, METH_VARARGS|METH_KEYWORDS, "python rna function"};
static PyMethodDef func_meth= {"<generic rna function>", (PyCFunction)pyrna_func_call, METH_VARARGS|METH_KEYWORDS, "python rna function"};
PyObject *self;
PyObject *ret;
@@ -1038,7 +1335,7 @@ static PyObject *pyrna_func_to_py(BPy_DummyPointerRNA *pyrna, FunctionRNA *func)
static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix)
{
/* XXX hard limits should be checked here */
int type = RNA_property_type(prop);
int type= RNA_property_type(prop);
if (RNA_property_array_check(ptr, prop)) {
@@ -1063,14 +1360,15 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
* however so many poll functions return None or a valid Object.
* its a hassle to convert these into a bool before returning, */
if(RNA_property_flag(prop) & PROP_OUTPUT)
param = PyObject_IsTrue( value );
param= PyObject_IsTrue(value);
else
param = PyLong_AsLong( value );
param= PyLong_AsLong(value);
if(param < 0) {
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected True/False or 0/1, not %.200s", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
return -1;
} else {
}
else {
if(data) *((int*)data)= param;
else RNA_property_boolean_set(ptr, prop, param);
}
@@ -1087,7 +1385,8 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
else if (param==-1 && PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected an int type, not %.200s", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
return -1;
} else {
}
else {
int param_i= (int)param;
RNA_property_int_clamp(ptr, prop, &param_i);
if(data) *((int*)data)= param_i;
@@ -1097,11 +1396,12 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
case PROP_FLOAT:
{
float param = PyFloat_AsDouble(value);
float param= PyFloat_AsDouble(value);
if (PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected a float type, not %.200s", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
return -1;
} else {
}
else {
RNA_property_float_clamp(ptr, prop, (float *)&param);
if(data) *((float*)data)= param;
else RNA_property_float_set(ptr, prop, param);
@@ -1174,7 +1474,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
PyObject *value_new= NULL;
StructRNA *ptr_type= RNA_property_pointer_type(ptr, prop);
int flag = RNA_property_flag(prop);
int flag= RNA_property_flag(prop);
/* this is really nasty!, so we can fake the operator having direct properties eg:
* layout.prop(self, "filepath")
@@ -1198,7 +1498,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
/* if property is an OperatorProperties pointer and value is a map, forward back to pyrna_pydict_to_props */
if (RNA_struct_is_a(ptr_type, &RNA_OperatorProperties) && PyDict_Check(value)) {
PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
PointerRNA opptr= RNA_property_pointer_get(ptr, prop);
return pyrna_pydict_to_props(&opptr, value, 0, error_prefix);
}
@@ -1219,13 +1519,16 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
if(!BPy_StructRNA_Check(value) && value != Py_None) {
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected a %.200s type, not %.200s", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), RNA_struct_identifier(ptr_type), Py_TYPE(value)->tp_name);
Py_XDECREF(value_new); return -1;
} else if((flag & PROP_NEVER_NULL) && value == Py_None) {
}
else if((flag & PROP_NEVER_NULL) && value == Py_None) {
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s does not support a 'None' assignment %.200s type", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), RNA_struct_identifier(ptr_type));
Py_XDECREF(value_new); return -1;
} else if(value != Py_None && ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA*)value)->ptr.id.data)) {
}
else if(value != Py_None && ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA*)value)->ptr.id.data)) {
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s ID type does not support assignment to its self", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop));
Py_XDECREF(value_new); return -1;
} else {
}
else {
BPy_StructRNA *param= (BPy_StructRNA*)value;
int raise_error= FALSE;
if(data) {
@@ -1291,7 +1594,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
return -1;
}
seq_len = PySequence_Size(value);
seq_len= PySequence_Size(value);
for(i=0; i<seq_len; i++) {
item= PySequence_GetItem(value, i);
@@ -1345,14 +1648,15 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
return 0;
}
static PyObject * pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
static PyObject *pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
{
PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
}
static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value)
{
int ret = 0;
int ret= 0;
PointerRNA *ptr= &self->ptr;
PropertyRNA *prop= self->prop;
@@ -1370,23 +1674,25 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
{
int param = PyLong_AsLong( value );
int param= PyLong_AsLong(value);
if( param < 0 || param > 1) {
if(param < 0 || param > 1) {
PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
ret = -1;
} else {
ret= -1;
}
else {
RNA_property_boolean_set_index(ptr, prop, index, param);
}
break;
}
case PROP_INT:
{
int param = PyLong_AsLong(value);
int param= PyLong_AsLong(value);
if (param==-1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, "expected an int type");
ret = -1;
} else {
ret= -1;
}
else {
RNA_property_int_clamp(ptr, prop, &param);
RNA_property_int_set_index(ptr, prop, index, param);
}
@@ -1394,11 +1700,12 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P
}
case PROP_FLOAT:
{
float param = PyFloat_AsDouble(value);
float param= PyFloat_AsDouble(value);
if (PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, "expected a float type");
ret = -1;
} else {
ret= -1;
}
else {
RNA_property_float_clamp(ptr, prop, &param);
RNA_property_float_set_index(ptr, prop, index, param);
}
@@ -1406,7 +1713,7 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P
}
default:
PyErr_SetString(PyExc_AttributeError, "not an array type");
ret = -1;
ret= -1;
break;
}
}
@@ -1422,14 +1729,18 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P
//---------------sequence-------------------------------------------
static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
{
PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self)
if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1)
return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
else
return RNA_property_array_length(&self->ptr, self->prop);
}
static Py_ssize_t pyrna_prop_collection_length( BPy_PropertyRNA *self )
static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
{
PYRNA_PROP_CHECK_INT(self)
return RNA_property_collection_length(&self->ptr, self->prop);
}
@@ -1437,17 +1748,21 @@ static Py_ssize_t pyrna_prop_collection_length( BPy_PropertyRNA *self )
* of 1000's of items in a linked list for eg. */
static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
{
PYRNA_PROP_CHECK_INT(self)
return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
}
static int pyrna_prop_collection_bool( BPy_PropertyRNA *self )
static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
{
/* no callback defined, just iterate and find the nth item */
CollectionPropertyIterator iter;
int test;
PYRNA_PROP_CHECK_INT(self)
RNA_property_collection_begin(&self->ptr, self->prop, &iter);
test = iter.valid;
test= iter.valid;
RNA_property_collection_end(&iter);
return test;
}
@@ -1458,6 +1773,8 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s
PointerRNA newptr;
Py_ssize_t keynum_abs= keynum;
PYRNA_PROP_CHECK_OBJ(self)
/* notice getting the length of the collection is avoided unless negative index is used
* or to detect internal error with a valid index.
* This is done for faster lookups. */
@@ -1488,7 +1805,11 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s
static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
{
int len= pyrna_prop_array_length(self);
int len;
PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
len= pyrna_prop_array_length(self);
if(keynum < 0) keynum += len;
@@ -1502,6 +1823,9 @@ static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int
static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
{
PointerRNA newptr;
PYRNA_PROP_CHECK_OBJ(self)
if(RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
return pyrna_struct_CreatePyObject(&newptr);
@@ -1512,13 +1836,17 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons
static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
{
CollectionPropertyIterator rna_macro_iter;
int count= 0;
PyObject *list= PyList_New(0);
PyObject *list;
PyObject *item;
PYRNA_PROP_CHECK_OBJ(self)
list= PyList_New(0);
/* first loop up-until the start */
CollectionPropertyIterator rna_macro_iter;
for(RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
/* PointerRNA itemptr= rna_macro_iter.ptr; */
if(count == start) {
@@ -1551,13 +1879,18 @@ static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
{
int count, totdim;
PyObject *tuple;
PyObject *tuple= PyTuple_New(stop - start);
PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
totdim = RNA_property_array_dimension(ptr, prop, NULL);
tuple= PyTuple_New(stop - start);
/* PYRNA_PROP_CHECK_OBJ(self) isnt needed, internal use only */
totdim= RNA_property_array_dimension(ptr, prop, NULL);
if (totdim > 1) {
for (count = start; count < stop; count++)
for (count= start; count < stop; count++)
PyTuple_SET_ITEM(tuple, count - start, pyrna_prop_array_to_py_index(self, count));
}
else {
@@ -1623,11 +1956,13 @@ static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, Po
static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
{
PYRNA_PROP_CHECK_OBJ(self)
if (PyUnicode_Check(key)) {
return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
}
else if (PyIndex_Check(key)) {
Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
return NULL;
@@ -1677,11 +2012,14 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
{
PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
/*if (PyUnicode_Check(key)) {
return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
} else*/
}
else */
if (PyIndex_Check(key)) {
Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
return NULL;
return pyrna_prop_array_subscript_int(self, PyLong_AsLong(key));
@@ -1732,17 +2070,17 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, in
int ret= 0;
if(value_orig == NULL) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct");
PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]= value: deleting with list types is not supported by bpy_struct");
return -1;
}
if(!(value=PySequence_Fast(value_orig, "bpy_prop_array[slice] = value: assignment is not a sequence type"))) {
if(!(value=PySequence_Fast(value_orig, "bpy_prop_array[slice]= value: assignment is not a sequence type"))) {
return -1;
}
if(PySequence_Fast_GET_SIZE(value) != stop-start) {
Py_DECREF(value);
PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice] = value: resizing bpy_struct arrays isn't supported");
PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]= value: resizing bpy_struct arrays isn't supported");
return -1;
}
@@ -1761,9 +2099,9 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, in
RNA_property_float_get_array(ptr, prop, values);
for(count=start; count<stop; count++) {
fval = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, count-start));
fval= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, count-start));
CLAMP(fval, min, max);
values[count] = fval;
values[count]= fval;
}
if(PyErr_Occurred()) ret= -1;
@@ -1781,7 +2119,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, in
RNA_property_boolean_get_array(ptr, prop, values);
for(count=start; count<stop; count++)
values[count] = PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
values[count]= PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
if(PyErr_Occurred()) ret= -1;
else RNA_property_boolean_set_array(ptr, prop, values);
@@ -1802,9 +2140,9 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, in
RNA_property_int_get_array(ptr, prop, values);
for(count=start; count<stop; count++) {
ival = PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
ival= PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count-start));
CLAMP(ival, min, max);
values[count] = ival;
values[count]= ival;
}
if(PyErr_Occurred()) ret= -1;
@@ -1828,29 +2166,35 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, in
static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum, PyObject *value)
{
int len= pyrna_prop_array_length(self);
int len;
PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self)
len= pyrna_prop_array_length(self);
if(keynum < 0) keynum += len;
if(keynum >= 0 && keynum < len)
return pyrna_py_to_prop_array_index(self, keynum, value);
PyErr_SetString(PyExc_IndexError, "bpy_prop_array[index] = value: index out of range");
PyErr_SetString(PyExc_IndexError, "bpy_prop_array[index]= value: index out of range");
return -1;
}
static int pyrna_prop_array_ass_subscript( BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value )
static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value)
{
/* char *keyname = NULL; */ /* not supported yet */
/* char *keyname= NULL; */ /* not supported yet */
int ret= -1;
PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self)
if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type) );
PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type));
ret= -1;
}
else if (PyIndex_Check(key)) {
Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
Py_ssize_t i= PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred()) {
ret= -1;
}
@@ -1891,20 +2235,20 @@ static int pyrna_prop_array_ass_subscript( BPy_PropertyArrayRNA *self, PyObject
}
/* for slice only */
static PyMappingMethods pyrna_prop_array_as_mapping = {
( lenfunc ) pyrna_prop_array_length, /* mp_length */
( binaryfunc ) pyrna_prop_array_subscript, /* mp_subscript */
( objobjargproc ) pyrna_prop_array_ass_subscript, /* mp_ass_subscript */
static PyMappingMethods pyrna_prop_array_as_mapping= {
(lenfunc) pyrna_prop_array_length, /* mp_length */
(binaryfunc) pyrna_prop_array_subscript, /* mp_subscript */
(objobjargproc) pyrna_prop_array_ass_subscript, /* mp_ass_subscript */
};
static PyMappingMethods pyrna_prop_collection_as_mapping = {
( lenfunc ) pyrna_prop_collection_length, /* mp_length */
( binaryfunc ) pyrna_prop_collection_subscript, /* mp_subscript */
( objobjargproc ) NULL, /* mp_ass_subscript */
static PyMappingMethods pyrna_prop_collection_as_mapping= {
(lenfunc) pyrna_prop_collection_length, /* mp_length */
(binaryfunc) pyrna_prop_collection_subscript, /* mp_subscript */
(objobjargproc) NULL, /* mp_ass_subscript */
};
/* only for fast bool's, large structs, assign nb_bool on init */
static PyNumberMethods pyrna_prop_array_as_number = {
static PyNumberMethods pyrna_prop_array_as_number= {
NULL, /* nb_add */
NULL, /* nb_subtract */
NULL, /* nb_multiply */
@@ -1916,7 +2260,7 @@ static PyNumberMethods pyrna_prop_array_as_number = {
NULL, /* nb_absolute */
(inquiry) pyrna_prop_array_bool, /* nb_bool */
};
static PyNumberMethods pyrna_prop_collection_as_number = {
static PyNumberMethods pyrna_prop_collection_as_number= {
NULL, /* nb_add */
NULL, /* nb_subtract */
NULL, /* nb_multiply */
@@ -1939,7 +2283,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *value
PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */
/* key in dict style check */
const char *keyname = _PyUnicode_AsString(value);
const char *keyname= _PyUnicode_AsString(value);
if(keyname==NULL) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.__contains__: expected a string");
@@ -1955,7 +2299,9 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *value
static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
{
IDProperty *group;
const char *name = _PyUnicode_AsString(value);
const char *name= _PyUnicode_AsString(value);
PYRNA_STRUCT_CHECK_INT(self)
if (!name) {
PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
@@ -1975,7 +2321,7 @@ static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
return IDP_GetPropertyFromGroup(group, name) ? 1:0;
}
static PySequenceMethods pyrna_prop_array_as_sequence = {
static PySequenceMethods pyrna_prop_array_as_sequence= {
(lenfunc)pyrna_prop_array_length, /* Cant set the len otherwise it can evaluate as false */
NULL, /* sq_concat */
NULL, /* sq_repeat */
@@ -1988,7 +2334,7 @@ static PySequenceMethods pyrna_prop_array_as_sequence = {
(ssizeargfunc) NULL, /* sq_inplace_repeat */
};
static PySequenceMethods pyrna_prop_collection_as_sequence = {
static PySequenceMethods pyrna_prop_collection_as_sequence= {
(lenfunc)pyrna_prop_collection_length, /* Cant set the len otherwise it can evaluate as false */
NULL, /* sq_concat */
NULL, /* sq_repeat */
@@ -2001,7 +2347,7 @@ static PySequenceMethods pyrna_prop_collection_as_sequence = {
(ssizeargfunc) NULL, /* sq_inplace_repeat */
};
static PySequenceMethods pyrna_struct_as_sequence = {
static PySequenceMethods pyrna_struct_as_sequence= {
NULL, /* Cant set the len otherwise it can evaluate as false */
NULL, /* sq_concat */
NULL, /* sq_repeat */
@@ -2014,12 +2360,14 @@ static PySequenceMethods pyrna_struct_as_sequence = {
(ssizeargfunc) NULL, /* sq_inplace_repeat */
};
static PyObject *pyrna_struct_subscript( BPy_StructRNA *self, PyObject *key )
static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
{
/* mostly copied from BPy_IDGroup_Map_GetItem */
IDProperty *group, *idprop;
const char *name= _PyUnicode_AsString(key);
PYRNA_STRUCT_CHECK_OBJ(self)
if(RNA_struct_idprops_check(self->ptr.type)==0) {
PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
return NULL;
@@ -2047,9 +2395,13 @@ static PyObject *pyrna_struct_subscript( BPy_StructRNA *self, PyObject *key )
return BPy_IDGroup_WrapData(self->ptr.id.data, idprop);
}
static int pyrna_struct_ass_subscript( BPy_StructRNA *self, PyObject *key, PyObject *value )
static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObject *value)
{
IDProperty *group= RNA_struct_idprops(&self->ptr, 1);
IDProperty *group;
PYRNA_STRUCT_CHECK_INT(self)
group= RNA_struct_idprops(&self->ptr, 1);
#ifdef USE_PEDANTIC_WRITE
if(rna_disallow_writes && rna_id_write_error(&self->ptr, key)) {
@@ -2058,17 +2410,17 @@ static int pyrna_struct_ass_subscript( BPy_StructRNA *self, PyObject *key, PyObj
#endif // USE_STRING_COERCE
if(group==NULL) {
PyErr_SetString(PyExc_TypeError, "bpy_struct[key] = val: id properties not supported for this type");
PyErr_SetString(PyExc_TypeError, "bpy_struct[key]= val: id properties not supported for this type");
return -1;
}
return BPy_Wrap_SetMapItem(group, key, value);
}
static PyMappingMethods pyrna_struct_as_mapping = {
( lenfunc ) NULL, /* mp_length */
( binaryfunc ) pyrna_struct_subscript, /* mp_subscript */
( objobjargproc ) pyrna_struct_ass_subscript, /* mp_ass_subscript */
static PyMappingMethods pyrna_struct_as_mapping= {
(lenfunc) NULL, /* mp_length */
(binaryfunc) pyrna_struct_subscript, /* mp_subscript */
(objobjargproc) pyrna_struct_ass_subscript, /* mp_ass_subscript */
};
static char pyrna_struct_keys_doc[] =
@@ -2152,300 +2504,6 @@ static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
return BPy_Wrap_GetValues(self->ptr.id.data, group);
}
/* for keyframes and drivers */
static int pyrna_struct_anim_args_parse(PointerRNA *ptr, const char *error_prefix, const char *path,
const char **path_full, int *index)
{
const int is_idbase= RNA_struct_is_ID(ptr->type);
PropertyRNA *prop;
PointerRNA r_ptr;
if (ptr->data==NULL) {
PyErr_Format(PyExc_TypeError, "%.200s this struct has no data, can't be animated", error_prefix);
return -1;
}
/* full paths can only be given from ID base */
if(is_idbase) {
int r_index= -1;
if(RNA_path_resolve_full(ptr, path, &r_ptr, &prop, &r_index)==0) {
prop= NULL;
}
else if(r_index != -1) {
PyErr_Format(PyExc_ValueError, "%.200s path includes index, must be a separate argument", error_prefix, path);
return -1;
}
else if(ptr->id.data != r_ptr.id.data) {
PyErr_Format(PyExc_ValueError, "%.200s path spans ID blocks", error_prefix, path);
return -1;
}
}
else {
prop = RNA_struct_find_property(ptr, path);
r_ptr= *ptr;
}
if (prop==NULL) {
PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not found", error_prefix, path);
return -1;
}
if (!RNA_property_animateable(&r_ptr, prop)) {
PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not animatable", error_prefix, path);
return -1;
}
if(RNA_property_array_check(&r_ptr, prop) == 0) {
if((*index) == -1) {
*index= 0;
}
else {
PyErr_Format(PyExc_TypeError, "%.200s index %d was given while property \"%s\" is not an array", error_prefix, *index, path);
return -1;
}
}
else {
int array_len= RNA_property_array_length(&r_ptr, prop);
if((*index) < -1 || (*index) >= array_len) {
PyErr_Format(PyExc_TypeError, "%.200s index out of range \"%s\", given %d, array length is %d", error_prefix, path, *index, array_len);
return -1;
}
}
if(is_idbase) {
*path_full= BLI_strdup(path);
}
else {
*path_full= RNA_path_from_ID_to_property(&r_ptr, prop);
if (*path_full==NULL) {
PyErr_Format(PyExc_TypeError, "%.200s could not make path to \"%s\"", error_prefix, path);
return -1;
}
}
return 0;
}
/* internal use for insert and delete */
static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix,
const char **path_full, int *index, float *cfra, const char **group_name) /* return values */
{
static const char *kwlist[] = {"data_path", "index", "frame", "group", NULL};
const char *path;
/* note, parse_str MUST start with 's|ifs' */
if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name))
return -1;
if(pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) < 0)
return -1;
if(*cfra==FLT_MAX)
*cfra= CTX_data_scene(BPy_GetContext())->r.cfra;
return 0; /* success */
}
static char pyrna_struct_keyframe_insert_doc[] =
".. method:: keyframe_insert(data_path, index=-1, frame=bpy.context.scene.frame_current, group=\"\")\n"
"\n"
" Insert a keyframe on the property given, adding fcurves and animation data when necessary.\n"
"\n"
" :arg data_path: path to the property to key, analogous to the fcurve's data path.\n"
" :type data_path: string\n"
" :arg index: array index of the property to key. Defaults to -1 which will key all indices or a single channel if the property is not an array.\n"
" :type index: int\n"
" :arg frame: The frame on which the keyframe is inserted, defaulting to the current frame.\n"
" :type frame: float\n"
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
" :type group: str\n"
" :return: Success of keyframe insertion.\n"
" :rtype: boolean\n"
;
static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw)
{
/* args, pyrna_struct_keyframe_parse handles these */
const char *path_full= NULL;
int index= -1;
float cfra= FLT_MAX;
const char *group_name= NULL;
if(pyrna_struct_keyframe_parse(&self->ptr, args, kw, "s|ifs:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()", &path_full, &index, &cfra, &group_name) == -1) {
return NULL;
}
else {
short result;
ReportList reports;
BKE_reports_init(&reports, RPT_STORE);
result= insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
MEM_freeN((void *)path_full);
if(BPy_reports_to_error(&reports, TRUE))
return NULL;
return PyBool_FromLong(result);
}
}
static char pyrna_struct_keyframe_delete_doc[] =
".. method:: keyframe_delete(data_path, index=-1, frame=bpy.context.scene.frame_current, group=\"\")\n"
"\n"
" Remove a keyframe from this properties fcurve.\n"
"\n"
" :arg data_path: path to the property to remove a key, analogous to the fcurve's data path.\n"
" :type data_path: string\n"
" :arg index: array index of the property to remove a key. Defaults to -1 removing all indices or a single channel if the property is not an array.\n"
" :type index: int\n"
" :arg frame: The frame on which the keyframe is deleted, defaulting to the current frame.\n"
" :type frame: float\n"
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
" :type group: str\n"
" :return: Success of keyframe deleation.\n"
" :rtype: boolean\n"
;
static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
{
/* args, pyrna_struct_keyframe_parse handles these */
const char *path_full= NULL;
int index= -1;
float cfra= FLT_MAX;
const char *group_name= NULL;
if(pyrna_struct_keyframe_parse(&self->ptr, args, kw, "s|ifs:bpy_struct.keyframe_delete()", "bpy_struct.keyframe_insert()", &path_full, &index, &cfra, &group_name) == -1) {
return NULL;
}
else {
short result;
ReportList reports;
BKE_reports_init(&reports, RPT_STORE);
result= delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
MEM_freeN((void *)path_full);
if(BPy_reports_to_error(&reports, TRUE))
return NULL;
return PyBool_FromLong(result);
}
}
static char pyrna_struct_driver_add_doc[] =
".. method:: driver_add(path, index=-1)\n"
"\n"
" Adds driver(s) to the given property\n"
"\n"
" :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
" :type path: string\n"
" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
" :type index: int\n"
" :return: The driver(s) added.\n"
" :rtype: :class:`FCurve` or list if index is -1 with an array property.\n"
;
static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
{
const char *path, *path_full;
int index= -1;
if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
return NULL;
if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) < 0) {
return NULL;
}
else {
PyObject *ret= NULL;
ReportList reports;
int result;
BKE_reports_init(&reports, RPT_STORE);
result= ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON);
if(BPy_reports_to_error(&reports, TRUE))
return NULL;
if(result) {
ID *id= self->ptr.id.data;
AnimData *adt= BKE_animdata_from_id(id);
FCurve *fcu;
PointerRNA tptr;
PyObject *item;
if(index == -1) { /* all, use a list */
int i= 0;
ret= PyList_New(0);
while((fcu= list_find_fcurve(&adt->drivers, path_full, i++))) {
RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
item= pyrna_struct_CreatePyObject(&tptr);
PyList_Append(ret, item);
Py_DECREF(item);
}
}
else {
fcu= list_find_fcurve(&adt->drivers, path_full, index);
RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
ret= pyrna_struct_CreatePyObject(&tptr);
}
}
else {
/* XXX, should be handled by reports, */
PyErr_SetString(PyExc_TypeError, "bpy_struct.driver_add(): failed because of an internal error");
return NULL;
}
MEM_freeN((void *)path_full);
return ret;
}
}
static char pyrna_struct_driver_remove_doc[] =
".. method:: driver_remove(path, index=-1)\n"
"\n"
" Remove driver(s) from the given property\n"
"\n"
" :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
" :type path: string\n"
" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
" :type index: int\n"
" :return: Success of driver removal.\n"
" :rtype: boolean\n"
;
static PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
{
const char *path, *path_full;
int index= -1;
if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
return NULL;
if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) < 0) {
return NULL;
}
else {
short result;
ReportList reports;
BKE_reports_init(&reports, RPT_STORE);
result= ANIM_remove_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0);
MEM_freeN((void *)path_full);
if(BPy_reports_to_error(&reports, TRUE))
return NULL;
return PyBool_FromLong(result);
}
}
static char pyrna_struct_is_property_set_doc[] =
".. method:: is_property_set(property)\n"
@@ -2461,6 +2519,8 @@ static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *arg
const char *name;
int ret;
PYRNA_STRUCT_CHECK_OBJ(self)
if (!PyArg_ParseTuple(args, "s:is_property_set", &name))
return NULL;
@@ -2500,6 +2560,8 @@ static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *
PropertyRNA *prop;
const char *name;
PYRNA_STRUCT_CHECK_OBJ(self)
if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name))
return NULL;
@@ -2529,6 +2591,8 @@ static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
PropertyRNA *r_prop;
int index= -1;
PYRNA_STRUCT_CHECK_OBJ(self)
if (!PyArg_ParseTuple(args, "s|O!:path_resolve", &path, &PyBool_Type, &coerce))
return NULL;
@@ -2579,6 +2643,8 @@ static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
PropertyRNA *prop;
PyObject *ret;
PYRNA_STRUCT_CHECK_OBJ(self)
if (!PyArg_ParseTuple(args, "|s:path_from_id", &name))
return NULL;
@@ -2618,7 +2684,7 @@ static char pyrna_prop_path_from_id_doc[] =
static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
{
const char *path;
PropertyRNA *prop = self->prop;
PropertyRNA *prop= self->prop;
PyObject *ret;
path= RNA_path_from_ID_to_property(&self->ptr, self->prop);
@@ -2645,6 +2711,9 @@ static char pyrna_struct_type_recast_doc[] =
static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self)
{
PointerRNA r_ptr;
PYRNA_STRUCT_CHECK_OBJ(self)
RNA_pointer_recast(&self->ptr, &r_ptr);
return pyrna_struct_CreatePyObject(&r_ptr);
}
@@ -2658,14 +2727,14 @@ static void pyrna_dir_members_py(PyObject *list, PyObject *self)
dict_ptr= _PyObject_GetDictPtr((PyObject *)self);
if(dict_ptr && (dict=*dict_ptr)) {
list_tmp = PyDict_Keys(dict);
list_tmp= PyDict_Keys(dict);
PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp);
Py_DECREF(list_tmp);
}
dict= ((PyTypeObject *)Py_TYPE(self))->tp_dict;
if(dict) {
list_tmp = PyDict_Keys(dict);
list_tmp= PyDict_Keys(dict);
PyList_SetSlice(list, INT_MAX, INT_MAX, list_tmp);
Py_DECREF(list_tmp);
}
@@ -2687,7 +2756,7 @@ static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
RNA_PROP_BEGIN(&tptr, itemptr, iterprop) {
idname= RNA_function_identifier(itemptr.data);
pystring = PyUnicode_FromString(idname);
pystring= PyUnicode_FromString(idname);
PyList_Append(list, pystring);
Py_DECREF(pystring);
}
@@ -2706,7 +2775,7 @@ static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
if(nameptr) {
pystring = PyUnicode_FromString(nameptr);
pystring= PyUnicode_FromString(nameptr);
PyList_Append(list, pystring);
Py_DECREF(pystring);
@@ -2724,10 +2793,12 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA *self)
PyObject *ret;
PyObject *pystring;
PYRNA_STRUCT_CHECK_OBJ(self)
/* Include this incase this instance is a subtype of a python class
* In these instances we may want to return a function or variable provided by the subtype
* */
ret = PyList_New(0);
ret= PyList_New(0);
if (!BPy_StructRNA_CheckExact(self))
pyrna_dir_members_py(ret, (PyObject *)self);
@@ -2735,11 +2806,11 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA *self)
pyrna_dir_members_rna(ret, &self->ptr);
if(self->ptr.type == &RNA_Context) {
ListBase lb = CTX_data_dir_get(self->ptr.data);
ListBase lb= CTX_data_dir_get(self->ptr.data);
LinkData *link;
for(link=lb.first; link; link=link->next) {
pystring = PyUnicode_FromString(link->data);
pystring= PyUnicode_FromString(link->data);
PyList_Append(ret, pystring);
Py_DECREF(pystring);
}
@@ -2762,36 +2833,38 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA *self)
}
//---------------getattr--------------------------------------------
static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
{
const char *name = _PyUnicode_AsString(pyname);
const char *name= _PyUnicode_AsString(pyname);
PyObject *ret;
PropertyRNA *prop;
FunctionRNA *func;
PYRNA_STRUCT_CHECK_OBJ(self)
if(name == NULL) {
PyErr_SetString(PyExc_AttributeError, "bpy_struct: __getattr__ must be a string");
ret = NULL;
ret= NULL;
}
else if(name[0]=='_') { // rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups
/* annoying exception, maybe we need to have different types for this... */
if((strcmp(name, "__getitem__")==0 || strcmp(name, "__setitem__")==0) && !RNA_struct_idprops_check(self->ptr.type)) {
PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type");
ret = NULL;
ret= NULL;
}
else {
ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
ret= PyObject_GenericGetAttr((PyObject *)self, pyname);
}
}
else if ((prop = RNA_struct_find_property(&self->ptr, name))) {
ret = pyrna_prop_to_py(&self->ptr, prop);
else if ((prop= RNA_struct_find_property(&self->ptr, name))) {
ret= pyrna_prop_to_py(&self->ptr, prop);
}
/* RNA function only if callback is declared (no optional functions) */
else if ((func = RNA_struct_find_function(&self->ptr, name)) && RNA_function_defined(func)) {
ret = pyrna_func_to_py((BPy_DummyPointerRNA *)self, func);
else if ((func= RNA_struct_find_function(&self->ptr, name)) && RNA_function_defined(func)) {
ret= pyrna_func_to_py((BPy_DummyPointerRNA *)self, func);
}
else if (self->ptr.type == &RNA_Context) {
bContext *C = self->ptr.data;
bContext *C= self->ptr.data;
if(C==NULL) {
PyErr_Format(PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context", name);
ret= NULL;
@@ -2819,7 +2892,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
CollectionPointerLink *link;
PyObject *linkptr;
ret = PyList_New(0);
ret= PyList_New(0);
for(link=newlb.first; link; link=link->next) {
linkptr= pyrna_struct_CreatePyObject(&link->ptr);
@@ -2837,12 +2910,12 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
}
}
else if (done==-1) { /* found but not set */
ret = Py_None;
ret= Py_None;
Py_INCREF(ret);
}
else { /* not found in the context */
/* lookup the subclass. raise an error if its not found */
ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
ret= PyObject_GenericGetAttr((PyObject *)self, pyname);
}
BLI_freelistN(&newlb);
@@ -2851,7 +2924,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
else {
#if 0
PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name);
ret = NULL;
ret= NULL;
#endif
/* Include this incase this instance is a subtype of a python class
* In these instances we may want to return a function or variable provided by the subtype
@@ -2860,7 +2933,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
* */
/* The error raised here will be displayed */
ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
ret= PyObject_GenericGetAttr((PyObject *)self, pyname);
}
return ret;
@@ -2889,7 +2962,7 @@ static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *attr
PyObject *ret= PyType_Type.tp_getattro(cls, attr);
/* Allows:
* >>> bpy.types.Scene.foo = BoolProperty()
* >>> bpy.types.Scene.foo= BoolProperty()
* >>> bpy.types.Scene.foo
* <bpy_struct, BooleanProperty("foo")>
* ...rather then returning the defered class register tuple as checked by pyrna_is_deferred_prop()
@@ -2917,13 +2990,21 @@ static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *attr
static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyObject *value)
{
StructRNA *srna= srna_from_self(cls, "StructRNA.__setattr__");
const int is_deferred_prop= (value && pyrna_is_deferred_prop(value));
if(srna && !pyrna_write_check() && (is_deferred_prop || RNA_struct_type_find_property(srna, _PyUnicode_AsString(attr)))) {
PyErr_Format(PyExc_AttributeError, "pyrna_struct_meta_idprop_setattro() can't set in readonly state '%.200s.%S'", ((PyTypeObject *)cls)->tp_name, attr);
return -1;
}
if(srna == NULL) {
if(value && pyrna_is_deferred_prop(value)) {
/* allow setting on unregistered classes which can be registered later on */
/*
if(value && is_deferred_prop) {
PyErr_Format(PyExc_AttributeError, "pyrna_struct_meta_idprop_setattro() unable to get srna from class '%.200s'", ((PyTypeObject *)cls)->tp_name);
return -1;
}
*/
/* srna_from_self may set an error */
PyErr_Clear();
return PyType_Type.tp_setattro(cls, attr, value);
@@ -2931,7 +3012,7 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb
if(value) {
/* check if the value is a property */
if(pyrna_is_deferred_prop(value)) {
if(is_deferred_prop) {
int ret= deferred_register_prop(srna, attr, value);
if(ret == -1) {
/* error set */
@@ -2962,11 +3043,13 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb
return PyType_Type.tp_setattro(cls, attr, value);
}
static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObject *value )
static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject *value)
{
const char *name = _PyUnicode_AsString(pyname);
const char *name= _PyUnicode_AsString(pyname);
PropertyRNA *prop= NULL;
PYRNA_STRUCT_CHECK_INT(self)
#ifdef USE_PEDANTIC_WRITE
if(rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
return -1;
@@ -2979,13 +3062,13 @@ static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObjec
}
else if (name[0] != '_' && (prop= RNA_struct_find_property(&self->ptr, name))) {
if (!RNA_property_editable_flag(&self->ptr, prop)) {
PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(prop), RNA_struct_identifier(self->ptr.type) );
PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(prop), RNA_struct_identifier(self->ptr.type));
return -1;
}
}
else if (self->ptr.type == &RNA_Context) {
/* code just raises correct error, context prop's cant be set, unless its apart of the py class */
bContext *C = self->ptr.data;
bContext *C= self->ptr.data;
if(C==NULL) {
PyErr_Format(PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't set \"%.200s\" from context", name);
return -1;
@@ -3013,7 +3096,7 @@ static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObjec
PyErr_SetString(PyExc_AttributeError, "bpy_struct: del not supported");
return -1;
}
return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "bpy_struct: item.attr = val:");
return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "bpy_struct: item.attr= val:");
}
else {
return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
@@ -3028,7 +3111,7 @@ static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
/* Include this incase this instance is a subtype of a python class
* In these instances we may want to return a function or variable provided by the subtype
* */
ret = PyList_New(0);
ret= PyList_New(0);
if (!BPy_PropertyRNA_CheckExact(self))
pyrna_dir_members_py(ret, (PyObject *)self);
@@ -3040,14 +3123,14 @@ static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
}
static PyObject *pyrna_prop_array_getattro( BPy_PropertyRNA *self, PyObject *pyname )
static PyObject *pyrna_prop_array_getattro(BPy_PropertyRNA *self, PyObject *pyname)
{
return PyObject_GenericGetAttr((PyObject *)self, pyname);
}
static PyObject *pyrna_prop_collection_getattro( BPy_PropertyRNA *self, PyObject *pyname )
static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject *pyname)
{
const char *name = _PyUnicode_AsString(pyname);
const char *name= _PyUnicode_AsString(pyname);
if(name == NULL) {
PyErr_SetString(PyExc_AttributeError, "bpy_prop_collection: __getattr__ must be a string");
@@ -3060,14 +3143,14 @@ static PyObject *pyrna_prop_collection_getattro( BPy_PropertyRNA *self, PyObject
PointerRNA r_ptr;
if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
if ((prop = RNA_struct_find_property(&r_ptr, name))) {
ret = pyrna_prop_to_py(&r_ptr, prop);
if ((prop= RNA_struct_find_property(&r_ptr, name))) {
ret= pyrna_prop_to_py(&r_ptr, prop);
return ret;
}
else if ((func = RNA_struct_find_function(&r_ptr, name))) {
else if ((func= RNA_struct_find_function(&r_ptr, name))) {
PyObject *self_collection= pyrna_struct_CreatePyObject(&r_ptr);
ret = pyrna_func_to_py((BPy_DummyPointerRNA *)self_collection, func);
ret= pyrna_func_to_py((BPy_DummyPointerRNA *)self_collection, func);
Py_DECREF(self_collection);
return ret;
@@ -3075,14 +3158,45 @@ static PyObject *pyrna_prop_collection_getattro( BPy_PropertyRNA *self, PyObject
}
}
/* The error raised here will be displayed */
#if 0
return PyObject_GenericGetAttr((PyObject *)self, pyname);
#else
{
/* Could just do this except for 1 awkward case.
* PyObject_GenericGetAttr((PyObject *)self, pyname);
* so as to support 'bpy.data.library.load()'
* note, this _only_ supports static methods */
PyObject *ret= PyObject_GenericGetAttr((PyObject *)self, pyname);
if(ret == NULL && name[0] != '_') { /* avoid inheriting __call__ and similar */
/* since this is least common case, handle it last */
PointerRNA r_ptr;
if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
PyObject *cls;
PyObject *error_type, *error_value, *error_traceback;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
PyErr_Clear();
cls= pyrna_struct_Subtype(&r_ptr); /* borrows */
ret= PyObject_GenericGetAttr(cls, pyname);
/* restore the original error */
if(ret == NULL) {
PyErr_Restore(error_type, error_value, error_traceback);
}
}
}
return ret;
}
#endif
}
//--------------- setattr-------------------------------------------
static int pyrna_prop_collection_setattro( BPy_PropertyRNA *self, PyObject *pyname, PyObject *value )
static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pyname, PyObject *value)
{
const char *name = _PyUnicode_AsString(pyname);
const char *name= _PyUnicode_AsString(pyname);
PropertyRNA *prop;
PointerRNA r_ptr;
@@ -3101,7 +3215,7 @@ static int pyrna_prop_collection_setattro( BPy_PropertyRNA *self, PyObject *pyna
return -1;
}
else if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
if ((prop = RNA_struct_find_property(&r_ptr, name))) {
if ((prop= RNA_struct_find_property(&r_ptr, name))) {
/* pyrna_py_to_prop sets its own exceptions */
return pyrna_py_to_prop(&r_ptr, prop, NULL, value, "BPy_PropertyRNA - Attribute (setattr):");
}
@@ -3176,17 +3290,25 @@ static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self)
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef pyrna_prop_getseters[] = {
static PyGetSetDef pyrna_prop_getseters[]= {
{(char *)"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, (char *)"The :class:`ID` object this datablock is from or None, (not available for all data types)", NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
static PyGetSetDef pyrna_struct_getseters[] = {
static PyGetSetDef pyrna_struct_getseters[]= {
{(char *)"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, (char *)"The :class:`ID` object this datablock is from or None, (not available for all data types)", NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
static char pyrna_prop_collection_keys_doc[] =
".. method:: keys()\n"
"\n"
" Return the identifiers of collection members (matching pythons dict.keys() functionality).\n"
"\n"
" :return: the identifiers for each member of this collection.\n"
" :rtype: list of stings\n"
;
static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self)
{
PyObject *ret= PyList_New(0);
@@ -3198,7 +3320,7 @@ static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self)
if(nameptr) {
/* add to python list */
item = PyUnicode_FromString( nameptr );
item= PyUnicode_FromString(nameptr);
PyList_Append(ret, item);
Py_DECREF(item);
/* done */
@@ -3212,6 +3334,14 @@ static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self)
return ret;
}
static char pyrna_prop_collection_items_doc[] =
".. method:: items()\n"
"\n"
" Return the identifiers of collection members (matching pythons dict.items() functionality).\n"
"\n"
" :return: (key, value) pairs for each member of this collection.\n"
" :rtype: list of tuples\n"
;
static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self)
{
PyObject *ret= PyList_New(0);
@@ -3225,7 +3355,7 @@ static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self)
item= PyTuple_New(2);
nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
if(nameptr) {
PyTuple_SET_ITEM(item, 0, PyUnicode_FromString( nameptr ));
PyTuple_SET_ITEM(item, 0, PyUnicode_FromString(nameptr));
if(name != nameptr)
MEM_freeN(nameptr);
}
@@ -3245,6 +3375,14 @@ static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self)
return ret;
}
static char pyrna_prop_collection_values_doc[] =
".. method:: values()\n"
"\n"
" Return the values of collection (matching pythons dict.values() functionality).\n"
"\n"
" :return: the members of this collection.\n"
" :rtype: list\n"
;
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self)
{
/* re-use slice*/
@@ -3268,7 +3406,9 @@ static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
IDProperty *group, *idprop;
const char *key;
PyObject* def = Py_None;
PyObject* def= Py_None;
PYRNA_STRUCT_CHECK_OBJ(self)
if (!PyArg_ParseTuple(args, "s|O:get", &key, &def))
return NULL;
@@ -3305,12 +3445,24 @@ static PyObject *pyrna_struct_as_pointer(BPy_StructRNA *self)
return PyLong_FromVoidPtr(self->ptr.data);
}
static char pyrna_prop_collection_get_doc[] =
".. method:: get(key, default=None)\n"
"\n"
" Returns the value of the item assigned to key or default when not found (matches pythons dictionary function of the same name).\n"
"\n"
" :arg key: The identifier for the collection member.\n"
" :type key: string\n"
" :arg default: Optional argument for the value to return if *key* is not found.\n"
" :type default: Undefined\n"
;
static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args)
{
PointerRNA newptr;
const char *key;
PyObject* def = Py_None;
PyObject* def= Py_None;
PYRNA_PROP_CHECK_OBJ(self)
if (!PyArg_ParseTuple(args, "s|O:get", &key, &def))
return NULL;
@@ -3323,7 +3475,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args
static void foreach_attr_type( BPy_PropertyRNA *self, const char *attr,
/* values to assign */
RawPropertyType *raw_type, int *attr_tot, int *attr_signed )
RawPropertyType *raw_type, int *attr_tot, int *attr_signed)
{
PropertyRNA *prop;
*raw_type= PROP_RAW_UNSET;
@@ -3332,9 +3484,9 @@ static void foreach_attr_type( BPy_PropertyRNA *self, const char *attr,
/* note: this is fail with zero length lists, so dont let this get caled in that case */
RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
prop = RNA_struct_find_property(&itemptr, attr);
prop= RNA_struct_find_property(&itemptr, attr);
*raw_type= RNA_property_raw_type(prop);
*attr_tot = RNA_property_array_length(&itemptr, prop);
*attr_tot= RNA_property_array_length(&itemptr, prop);
*attr_signed= (RNA_property_subtype(prop)==PROP_UNSIGNED) ? FALSE:TRUE;
break;
}
@@ -3372,9 +3524,9 @@ static int foreach_parse_args(
*attr_tot= 1;
if (RNA_property_type(self->prop) == PROP_COLLECTION)
array_tot = RNA_property_collection_length(&self->ptr, self->prop);
array_tot= RNA_property_collection_length(&self->ptr, self->prop);
else
array_tot = RNA_property_array_length(&self->ptr, self->prop);
array_tot= RNA_property_array_length(&self->ptr, self->prop);
target_tot= array_tot * (*attr_tot);
@@ -3398,7 +3550,7 @@ static int foreach_parse_args(
static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
{
char f = format ? *format:'B'; /* B is assumed when not set */
char f= format ? *format:'B'; /* B is assumed when not set */
switch(raw_type) {
case PROP_RAW_CHAR:
@@ -3423,7 +3575,7 @@ static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, cons
static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
{
PyObject *item = NULL;
PyObject *item= NULL;
int i=0, ok=0, buffer_is_compat;
void *array= NULL;
@@ -3433,7 +3585,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
int tot, size, attr_tot, attr_signed;
RawPropertyType raw_type;
if(foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0)
if(foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0)
return NULL;
if(tot==0)
@@ -3442,17 +3594,17 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
if(set) { /* get the array from python */
buffer_is_compat = FALSE;
buffer_is_compat= FALSE;
if(PyObject_CheckBuffer(seq)) {
Py_buffer buf;
PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT);
/* check if the buffer matches */
buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format);
buffer_is_compat= foreach_compat_buffer(raw_type, attr_signed, buf.format);
if(buffer_is_compat) {
ok = RNA_property_collection_raw_set(NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot);
ok= RNA_property_collection_raw_set(NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot);
}
PyBuffer_Release(&buf);
@@ -3489,21 +3641,21 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
Py_DECREF(item);
}
ok = RNA_property_collection_raw_set(NULL, &self->ptr, self->prop, attr, array, raw_type, tot);
ok= RNA_property_collection_raw_set(NULL, &self->ptr, self->prop, attr, array, raw_type, tot);
}
}
else {
buffer_is_compat = FALSE;
buffer_is_compat= FALSE;
if(PyObject_CheckBuffer(seq)) {
Py_buffer buf;
PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT);
/* check if the buffer matches, TODO - signed/unsigned types */
buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format);
buffer_is_compat= foreach_compat_buffer(raw_type, attr_signed, buf.format);
if(buffer_is_compat) {
ok = RNA_property_collection_raw_get(NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot);
ok= RNA_property_collection_raw_get(NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot);
}
PyBuffer_Release(&buf);
@@ -3513,7 +3665,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
if(!buffer_is_compat) {
array= PyMem_Malloc(size * tot);
ok = RNA_property_collection_raw_get(NULL, &self->ptr, self->prop, attr, array, raw_type, tot);
ok= RNA_property_collection_raw_get(NULL, &self->ptr, self->prop, attr, array, raw_type, tot);
if(!ok) i= tot; /* skip the loop */
@@ -3521,19 +3673,19 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
switch(raw_type) {
case PROP_RAW_CHAR:
item= PyLong_FromSsize_t( (Py_ssize_t) ((char *)array)[i] );
item= PyLong_FromSsize_t((Py_ssize_t) ((char *)array)[i]);
break;
case PROP_RAW_SHORT:
item= PyLong_FromSsize_t( (Py_ssize_t) ((short *)array)[i] );
item= PyLong_FromSsize_t((Py_ssize_t) ((short *)array)[i]);
break;
case PROP_RAW_INT:
item= PyLong_FromSsize_t( (Py_ssize_t) ((int *)array)[i] );
item= PyLong_FromSsize_t((Py_ssize_t) ((int *)array)[i]);
break;
case PROP_RAW_FLOAT:
item= PyFloat_FromDouble( (double) ((float *)array)[i] );
item= PyFloat_FromDouble((double) ((float *)array)[i]);
break;
case PROP_RAW_DOUBLE:
item= PyFloat_FromDouble( (double) ((double *)array)[i] );
item= PyFloat_FromDouble((double) ((double *)array)[i]);
break;
case PROP_RAW_UNSET:
/* should never happen */
@@ -3574,11 +3726,13 @@ static char pyrna_prop_collection_foreach_get_doc[] =
" collection.foreach_get(someseq, attr)\n"
"\n"
" # Python equivelent\n"
" for i in range(len(seq)): someseq[i] = getattr(collection, attr)\n"
" for i in range(len(seq)): someseq[i]= getattr(collection, attr)\n"
"\n"
;
static PyObject *pyrna_prop_collection_foreach_get(BPy_PropertyRNA *self, PyObject *args)
{
PYRNA_PROP_CHECK_OBJ(self)
return foreach_getset(self, args, 0);
}
@@ -3595,8 +3749,10 @@ static char pyrna_prop_collection_foreach_set_doc[] =
" for i in range(len(seq)): setattr(collection[i], attr, seq[i])\n"
"\n"
;
static PyObject *pyrna_prop_collection_foreach_set(BPy_PropertyRNA *self, PyObject *args)
static PyObject *pyrna_prop_collection_foreach_set(BPy_PropertyRNA *self, PyObject *args)
{
PYRNA_PROP_CHECK_OBJ(self)
return foreach_getset(self, args, 1);
}
@@ -3607,19 +3763,26 @@ static PyObject *pyrna_prop_array_iter(BPy_PropertyArrayRNA *self)
/* Try get values from a collection */
PyObject *ret;
PyObject *iter= NULL;
int len= pyrna_prop_array_length(self);
ret = pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
int len;
PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
len= pyrna_prop_array_length(self);
ret= pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
/* we know this is a list so no need to PyIter_Check
* otherwise it could be NULL (unlikely) if conversion failed */
if(ret) {
iter = PyObject_GetIter(ret);
iter= PyObject_GetIter(ret);
Py_DECREF(ret);
}
return iter;
}
static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self);
#ifndef USE_PYRNA_ITER
static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
{
/* Try get values from a collection */
@@ -3630,14 +3793,15 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
/* we know this is a list so no need to PyIter_Check
* otherwise it could be NULL (unlikely) if conversion failed */
if(ret) {
iter = PyObject_GetIter(ret);
iter= PyObject_GetIter(ret);
Py_DECREF(ret);
}
return iter;
}
#endif /* # !USE_PYRNA_ITER */
static struct PyMethodDef pyrna_struct_methods[] = {
static struct PyMethodDef pyrna_struct_methods[]= {
/* only for PointerRNA's with ID'props */
{"keys", (PyCFunction)pyrna_struct_keys, METH_NOARGS, pyrna_struct_keys_doc},
@@ -3648,10 +3812,12 @@ static struct PyMethodDef pyrna_struct_methods[] = {
{"as_pointer", (PyCFunction)pyrna_struct_as_pointer, METH_NOARGS, pyrna_struct_as_pointer_doc},
/* bpy_rna_anim.c */
{"keyframe_insert", (PyCFunction)pyrna_struct_keyframe_insert, METH_VARARGS|METH_KEYWORDS, pyrna_struct_keyframe_insert_doc},
{"keyframe_delete", (PyCFunction)pyrna_struct_keyframe_delete, METH_VARARGS|METH_KEYWORDS, pyrna_struct_keyframe_delete_doc},
{"driver_add", (PyCFunction)pyrna_struct_driver_add, METH_VARARGS, pyrna_struct_driver_add_doc},
{"driver_remove", (PyCFunction)pyrna_struct_driver_remove, METH_VARARGS, pyrna_struct_driver_remove_doc},
{"is_property_set", (PyCFunction)pyrna_struct_is_property_set, METH_VARARGS, pyrna_struct_is_property_set_doc},
{"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, pyrna_struct_is_property_hidden_doc},
{"path_resolve", (PyCFunction)pyrna_struct_path_resolve, METH_VARARGS, pyrna_struct_path_resolve_doc},
@@ -3665,29 +3831,29 @@ static struct PyMethodDef pyrna_struct_methods[] = {
{NULL, NULL, 0, NULL}
};
static struct PyMethodDef pyrna_prop_methods[] = {
static struct PyMethodDef pyrna_prop_methods[]= {
{"path_from_id", (PyCFunction)pyrna_prop_path_from_id, METH_NOARGS, pyrna_prop_path_from_id_doc},
{"__dir__", (PyCFunction)pyrna_prop_dir, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL}
};
static struct PyMethodDef pyrna_prop_array_methods[] = {
static struct PyMethodDef pyrna_prop_array_methods[]= {
{NULL, NULL, 0, NULL}
};
static struct PyMethodDef pyrna_prop_collection_methods[] = {
static struct PyMethodDef pyrna_prop_collection_methods[]= {
{"foreach_get", (PyCFunction)pyrna_prop_collection_foreach_get, METH_VARARGS, pyrna_prop_collection_foreach_get_doc},
{"foreach_set", (PyCFunction)pyrna_prop_collection_foreach_set, METH_VARARGS, pyrna_prop_collection_foreach_set_doc},
{"keys", (PyCFunction)pyrna_prop_collection_keys, METH_NOARGS, NULL},
{"items", (PyCFunction)pyrna_prop_collection_items, METH_NOARGS,NULL},
{"values", (PyCFunction)pyrna_prop_collection_values, METH_NOARGS, NULL},
{"keys", (PyCFunction)pyrna_prop_collection_keys, METH_NOARGS, pyrna_prop_collection_keys_doc},
{"items", (PyCFunction)pyrna_prop_collection_items, METH_NOARGS, pyrna_prop_collection_items_doc},
{"values", (PyCFunction)pyrna_prop_collection_values, METH_NOARGS, pyrna_prop_collection_values_doc},
{"get", (PyCFunction)pyrna_prop_collection_get, METH_VARARGS, NULL},
{"get", (PyCFunction)pyrna_prop_collection_get, METH_VARARGS, pyrna_prop_collection_get_doc},
{NULL, NULL, 0, NULL}
};
static struct PyMethodDef pyrna_prop_collection_idprop_methods[] = {
static struct PyMethodDef pyrna_prop_collection_idprop_methods[]= {
{"add", (PyCFunction)pyrna_prop_collection_idprop_add, METH_NOARGS, NULL},
{"remove", (PyCFunction)pyrna_prop_collection_idprop_remove, METH_O, NULL},
{"move", (PyCFunction)pyrna_prop_collection_idprop_move, METH_VARARGS, NULL},
@@ -3696,31 +3862,31 @@ static struct PyMethodDef pyrna_prop_collection_idprop_methods[] = {
/* only needed for subtyping, so a new class gets a valid BPy_StructRNA
* todo - also accept useful args */
static PyObject * pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds))
static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds))
{
if(PyTuple_GET_SIZE(args) == 1) {
BPy_StructRNA *base= (BPy_StructRNA *)PyTuple_GET_ITEM(args, 0);
if (type == Py_TYPE(base)) {
if (Py_TYPE(base) == type) {
Py_INCREF(base);
return (PyObject *)base;
}
else if (PyType_IsSubtype(type, &pyrna_struct_Type)) {
else if (PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) {
/* this almost never runs, only when using user defined subclasses of built-in object.
* this isnt common since its NOT related to registerable subclasses. eg:
>>> class MyObSubclass(bpy.types.Object):
... def test_func(self):
... print(100)
...
>>> myob = MyObSubclass(bpy.context.object)
...
>>> myob= MyObSubclass(bpy.context.object)
>>> myob.test_func()
100
*
*
* Keep this since it could be useful.
*/
BPy_StructRNA *ret;
if((ret= (BPy_StructRNA *)type->tp_alloc(type, 0))) {
ret->ptr = base->ptr;
ret->ptr= base->ptr;
}
/* pass on exception & NULL if tp_alloc fails */
return (PyObject *)ret;
@@ -3738,7 +3904,7 @@ static PyObject * pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject
/* only needed for subtyping, so a new class gets a valid BPy_StructRNA
* todo - also accept useful args */
static PyObject * pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds)) {
static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds)) {
BPy_PropertyRNA *base;
@@ -3748,10 +3914,11 @@ static PyObject * pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *U
if (type == Py_TYPE(base)) {
Py_INCREF(base);
return (PyObject *)base;
} else if (PyType_IsSubtype(type, &pyrna_prop_Type)) {
BPy_PropertyRNA *ret = (BPy_PropertyRNA *) type->tp_alloc(type, 0);
ret->ptr = base->ptr;
ret->prop = base->prop;
}
else if (PyType_IsSubtype(type, &pyrna_prop_Type)) {
BPy_PropertyRNA *ret= (BPy_PropertyRNA *) type->tp_alloc(type, 0);
ret->ptr= base->ptr;
ret->prop= base->prop;
return (PyObject *)ret;
}
else {
@@ -3763,8 +3930,8 @@ static PyObject * pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *U
static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
{
PyObject *ret;
int type = RNA_property_type(prop);
int flag = RNA_property_flag(prop);
int type= RNA_property_type(prop);
int flag= RNA_property_flag(prop);
if(RNA_property_array_check(ptr, prop)) {
int a, len;
@@ -3783,14 +3950,14 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
switch (type) {
case PROP_BOOLEAN:
ret = PyTuple_New(len);
ret= PyTuple_New(len);
for(a=0; a<len; a++)
PyTuple_SET_ITEM(ret, a, PyBool_FromLong( ((int*)data)[a] ));
PyTuple_SET_ITEM(ret, a, PyBool_FromLong(((int*)data)[a]));
break;
case PROP_INT:
ret = PyTuple_New(len);
ret= PyTuple_New(len);
for(a=0; a<len; a++)
PyTuple_SET_ITEM(ret, a, PyLong_FromSsize_t( (Py_ssize_t)((int*)data)[a] ));
PyTuple_SET_ITEM(ret, a, PyLong_FromSsize_t((Py_ssize_t)((int*)data)[a]));
break;
case PROP_FLOAT:
switch(RNA_property_subtype(prop)) {
@@ -3810,15 +3977,15 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
/* pass through */
#endif
default:
ret = PyTuple_New(len);
ret= PyTuple_New(len);
for(a=0; a<len; a++)
PyTuple_SET_ITEM(ret, a, PyFloat_FromDouble( ((float*)data)[a] ));
PyTuple_SET_ITEM(ret, a, PyFloat_FromDouble(((float*)data)[a]));
}
break;
default:
PyErr_Format(PyExc_TypeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type);
ret = NULL;
ret= NULL;
break;
}
}
@@ -3826,13 +3993,13 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
/* see if we can coorce into a python type - PropertyType */
switch (type) {
case PROP_BOOLEAN:
ret = PyBool_FromLong( *(int*)data );
ret= PyBool_FromLong(*(int*)data);
break;
case PROP_INT:
ret = PyLong_FromSsize_t( (Py_ssize_t)*(int*)data );
ret= PyLong_FromSsize_t((Py_ssize_t)*(int*)data);
break;
case PROP_FLOAT:
ret = PyFloat_FromDouble( *(float*)data );
ret= PyFloat_FromDouble(*(float*)data);
break;
case PROP_STRING:
{
@@ -3853,7 +4020,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
ret= PyUnicode_FromString(data_ch);
}
#else
ret = PyUnicode_FromString(data_ch);
ret= PyUnicode_FromString(data_ch);
#endif
#ifdef USE_STRING_COERCE
@@ -3879,7 +4046,8 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
else {
if(RNA_struct_is_ID(ptype)) {
RNA_id_pointer_create(*(void**)data, &newptr);
} else {
}
else {
/* note: this is taken from the function's ID pointer
* and will break if a function returns a pointer from
* another ID block, watch this! - it should at least be
@@ -3889,9 +4057,10 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
}
if (newptr.data) {
ret = pyrna_struct_CreatePyObject(&newptr);
} else {
ret = Py_None;
ret= pyrna_struct_CreatePyObject(&newptr);
}
else {
ret= Py_None;
Py_INCREF(ret);
}
break;
@@ -3902,7 +4071,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
CollectionPointerLink *link;
PyObject *linkptr;
ret = PyList_New(0);
ret= PyList_New(0);
for(link=lb->first; link; link=link->next) {
linkptr= pyrna_struct_CreatePyObject(&link->ptr);
@@ -3914,7 +4083,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
}
default:
PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type);
ret = NULL;
ret= NULL;
break;
}
}
@@ -3922,11 +4091,11 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
return ret;
}
static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
static PyObject *pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
{
/* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here */
PointerRNA *self_ptr= &(((BPy_DummyPointerRNA *)PyTuple_GET_ITEM(self, 0))->ptr);
FunctionRNA *self_func= PyCapsule_GetPointer(PyTuple_GET_ITEM(self, 1), NULL);
FunctionRNA *self_func= PyCapsule_GetPointer(PyTuple_GET_ITEM(self, 1), NULL);
PointerRNA funcptr;
ParameterList parms;
@@ -4007,7 +4176,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
kw_arg= FALSE;
}
else if (kw != NULL) {
item= PyDict_GetItemString(kw, parm_id); /* borrow ref */
item= PyDict_GetItemString(kw, parm_id); /* borrow ref */
if(item)
kw_tot++; /* make sure invalid keywords are not given */
@@ -4052,7 +4221,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
*/
if(err == 0 && kw && (pykw_len > kw_tot)) {
PyObject *key, *value;
Py_ssize_t pos = 0;
Py_ssize_t pos= 0;
DynStr *bad_args= BLI_dynstr_new();
DynStr *good_args= BLI_dynstr_new();
@@ -4125,10 +4294,10 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
BKE_reports_init(&reports, RPT_STORE);
RNA_function_call(C, &reports, self_ptr, self_func, &parms);
err= (BPy_reports_to_error(&reports, TRUE))? -1: 0;
err= (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE));
/* return value */
if(err==0) {
if(err != -1) {
if (ret_len > 0) {
if (ret_len > 1) {
ret= PyTuple_New(ret_len);
@@ -4172,7 +4341,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
/* subclasses of pyrna_struct_Type which support idprop definitions use this as a metaclass */
/* note: tp_base member is set to &PyType_Type on init */
PyTypeObject pyrna_struct_meta_idprop_Type = {
PyTypeObject pyrna_struct_meta_idprop_Type= {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_struct_meta_idprop", /* tp_name */
sizeof(PyHeapTypeObject), /* tp_basicsize */ // XXX, would be PyTypeObject, but subtypes of Type must be PyHeapTypeObject's
@@ -4250,7 +4419,7 @@ PyTypeObject pyrna_struct_meta_idprop_Type = {
/*-----------------------BPy_StructRNA method def------------------------------*/
PyTypeObject pyrna_struct_Type = {
PyTypeObject pyrna_struct_Type= {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_struct", /* tp_name */
sizeof(BPy_StructRNA), /* tp_basicsize */
@@ -4261,7 +4430,7 @@ PyTypeObject pyrna_struct_Type = {
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
( reprfunc ) pyrna_struct_repr, /* tp_repr */
(reprfunc) pyrna_struct_repr, /* tp_repr */
/* Method suites for standard classes */
@@ -4271,25 +4440,32 @@ PyTypeObject pyrna_struct_Type = {
/* More standard operations (here for binary compatibility) */
( hashfunc )pyrna_struct_hash, /* hashfunc tp_hash; */
(hashfunc) pyrna_struct_hash, /* hashfunc tp_hash; */
NULL, /* ternaryfunc tp_call; */
(reprfunc) pyrna_struct_str, /* reprfunc tp_str; */
( getattrofunc ) pyrna_struct_getattro, /* getattrofunc tp_getattro; */
( setattrofunc ) pyrna_struct_setattro, /* setattrofunc tp_setattro; */
(getattrofunc) pyrna_struct_getattro, /* getattrofunc tp_getattro; */
(setattrofunc) pyrna_struct_setattro, /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
NULL, /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* long tp_flags; */
NULL, /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL, /* traverseproc tp_traverse; */
#ifdef USE_PYRNA_STRUCT_REFERENCE
(traverseproc) pyrna_struct_traverse, /* traverseproc tp_traverse; */
/* delete references to contained objects */
(inquiry)pyrna_struct_clear, /* inquiry tp_clear; */
#else
NULL, /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL, /* inquiry tp_clear; */
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
@@ -4332,7 +4508,7 @@ PyTypeObject pyrna_struct_Type = {
};
/*-----------------------BPy_PropertyRNA method def------------------------------*/
PyTypeObject pyrna_prop_Type = {
PyTypeObject pyrna_prop_Type= {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_prop", /* tp_name */
sizeof(BPy_PropertyRNA), /* tp_basicsize */
@@ -4353,7 +4529,7 @@ PyTypeObject pyrna_prop_Type = {
/* More standard operations (here for binary compatibility) */
( hashfunc ) pyrna_prop_hash, /* hashfunc tp_hash; */
(hashfunc) pyrna_prop_hash, /* hashfunc tp_hash; */
NULL, /* ternaryfunc tp_call; */
(reprfunc) pyrna_prop_str, /* reprfunc tp_str; */
@@ -4416,7 +4592,7 @@ PyTypeObject pyrna_prop_Type = {
NULL
};
PyTypeObject pyrna_prop_array_Type = {
PyTypeObject pyrna_prop_array_Type= {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_prop_array", /* tp_name */
sizeof(BPy_PropertyArrayRNA), /* tp_basicsize */
@@ -4442,7 +4618,7 @@ PyTypeObject pyrna_prop_array_Type = {
NULL, /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
( getattrofunc ) pyrna_prop_array_getattro, /* getattrofunc tp_getattro; */
(getattrofunc) pyrna_prop_array_getattro, /* getattrofunc tp_getattro; */
NULL, /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
@@ -4499,7 +4675,7 @@ PyTypeObject pyrna_prop_array_Type = {
NULL
};
PyTypeObject pyrna_prop_collection_Type = {
PyTypeObject pyrna_prop_collection_Type= {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_prop_collection", /* tp_name */
sizeof(BPy_PropertyRNA), /* tp_basicsize */
@@ -4525,8 +4701,8 @@ PyTypeObject pyrna_prop_collection_Type = {
NULL, /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
( getattrofunc ) pyrna_prop_collection_getattro, /* getattrofunc tp_getattro; */
( setattrofunc ) pyrna_prop_collection_setattro, /* setattrofunc tp_setattro; */
(getattrofunc) pyrna_prop_collection_getattro, /* getattrofunc tp_getattro; */
(setattrofunc) pyrna_prop_collection_setattro, /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
NULL, /* PyBufferProcs *tp_as_buffer; */
@@ -4584,7 +4760,7 @@ PyTypeObject pyrna_prop_collection_Type = {
};
/* only for add/remove/move methods */
static PyTypeObject pyrna_prop_collection_idprop_Type = {
static PyTypeObject pyrna_prop_collection_idprop_Type= {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_prop_collection_idprop", /* tp_name */
sizeof(BPy_PropertyRNA), /* tp_basicsize */
@@ -4668,18 +4844,175 @@ static PyTypeObject pyrna_prop_collection_idprop_Type = {
NULL
};
#ifdef USE_PYRNA_ITER
/* --- collection iterator: start --- */
/* wrap rna collection iterator functions */
/*
* RNA_property_collection_begin(...)
* RNA_property_collection_next(...)
* RNA_property_collection_end(...)
*/
static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self);
static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self);
PyTypeObject pyrna_prop_collection_iter_Type= {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_prop_collection_iter", /* tp_name */
sizeof(BPy_PropertyCollectionIterRNA), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)pyrna_prop_collection_iter_dealloc, /* tp_dealloc */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
NULL,/* subclassed */ /* tp_repr */
/* Method suites for standard classes */
NULL, /* PyNumberMethods *tp_as_number; */
NULL, /* PySequenceMethods *tp_as_sequence; */
NULL, /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
NULL, /* hashfunc tp_hash; */
NULL, /* ternaryfunc tp_call; */
NULL, /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
PyObject_GenericGetAttr, /* getattrofunc tp_getattro; */
NULL, /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
NULL, /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
Py_TPFLAGS_DEFAULT, /* long tp_flags; */
NULL, /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL, /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL, /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
NULL, /* subclassed */ /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
#ifdef USE_WEAKREFS
offsetof(BPy_PropertyCollectionIterRNA, in_weakreflist), /* long tp_weaklistoffset; */
#else
0,
#endif
/*** Added in release 2.2 ***/
/* Iterators */
PyObject_SelfIter, /* getiterfunc tp_iter; */
(iternextfunc) pyrna_prop_collection_iter_next, /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
NULL, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
NULL, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
NULL, /* PyObject *tp_dict; */
NULL, /* descrgetfunc tp_descr_get; */
NULL, /* descrsetfunc tp_descr_set; */
0, /* long tp_dictoffset; */
NULL, /* initproc tp_init; */
NULL, /* allocfunc tp_alloc; */
NULL, /* newfunc tp_new; */
/* Low-level free-memory routine */
NULL, /* freefunc tp_free; */
/* For PyObject_IS_GC */
NULL, /* inquiry tp_is_gc; */
NULL, /* PyObject *tp_bases; */
/* method resolution order */
NULL, /* PyObject *tp_mro; */
NULL, /* PyObject *tp_cache; */
NULL, /* PyObject *tp_subclasses; */
NULL, /* PyObject *tp_weaklist; */
NULL
};
PyObject *pyrna_prop_collection_iter_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop)
{
BPy_PropertyCollectionIterRNA *self= PyObject_New(BPy_PropertyCollectionIterRNA, &pyrna_prop_collection_iter_Type);
#ifdef USE_WEAKREFS
self->in_weakreflist= NULL;
#endif
RNA_property_collection_begin(ptr, prop, &self->iter);
return (PyObject *)self;
}
static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
{
return pyrna_prop_collection_iter_CreatePyObject(&self->ptr, self->prop);
}
static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self)
{
if(self->iter.valid == FALSE) {
PyErr_SetString(PyExc_StopIteration, "pyrna_prop_collection_iter stop");
return NULL;
}
else {
BPy_StructRNA *pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr);
#ifdef USE_PYRNA_STRUCT_REFERENCE
if(pyrna) { /* unlikely but may fail */
if((PyObject *)pyrna != Py_None) {
/* hold a reference to the iterator since it may have
* allocated memory 'pyrna' needs. eg: introspecting dynamic enum's */
/* TODO, we could have an api call to know if this is needed since most collections don't */
pyrna_struct_reference_set(pyrna, (PyObject *)self);
}
}
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
RNA_property_collection_next(&self->iter);
return (PyObject *)pyrna;
}
}
static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self)
{
#ifdef USE_WEAKREFS
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *)self);
}
#endif
RNA_property_collection_end(&self->iter);
PyObject_DEL(self);
}
/* --- collection iterator: end --- */
#endif /* !USE_PYRNA_ITER */
static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
{
PointerRNA ptr;
PyObject *item;
Py_INCREF(newclass);
if (RNA_struct_py_type_get(srna))
PyC_ObSpit("RNA WAS SET - ", RNA_struct_py_type_get(srna));
Py_XDECREF(((PyObject *)RNA_struct_py_type_get(srna)));
RNA_struct_py_type_set(srna, (void *)newclass); /* Store for later use */
/* Not 100% needed but useful,
@@ -4687,12 +5020,12 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
/* python deals with the curcular ref */
RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr);
item = pyrna_struct_CreatePyObject(&ptr);
item= pyrna_struct_CreatePyObject(&ptr);
/* note, must set the class not the __dict__ else the internal slots are not updated correctly */
PyObject_SetAttrString(newclass, "bl_rna", item);
Py_DECREF(item);
/* done with rna instance */
}
@@ -4740,7 +5073,7 @@ static PyObject* pyrna_srna_ExternalType(StructRNA *srna)
fprintf(stderr, "pyrna_srna_ExternalType: failed to find 'bpy_types' module\n");
return NULL;
}
bpy_types_dict = PyModule_GetDict(bpy_types); // borrow
bpy_types_dict= PyModule_GetDict(bpy_types); // borrow
Py_DECREF(bpy_types); // fairly safe to assume the dict is kept
}
@@ -4752,7 +5085,7 @@ static PyObject* pyrna_srna_ExternalType(StructRNA *srna)
//PyObject *slots= PyObject_GetAttrString(newclass, "__slots__"); // cant do this because it gets superclasses values!
//PyObject *bases= PyObject_GetAttrString(newclass, "__bases__"); // can do this but faster not to.
PyObject *bases= ((PyTypeObject *)newclass)->tp_bases;
PyObject *slots = PyDict_GetItemString(((PyTypeObject *)newclass)->tp_dict, "__slots__");
PyObject *slots= PyDict_GetItemString(((PyTypeObject *)newclass)->tp_dict, "__slots__");
if(slots==NULL) {
fprintf(stderr, "pyrna_srna_ExternalType: expected class '%s' to have __slots__ defined\n\nSee bpy_types.py\n", idname);
@@ -4778,7 +5111,7 @@ static PyObject* pyrna_srna_ExternalType(StructRNA *srna)
static PyObject* pyrna_srna_Subtype(StructRNA *srna)
{
PyObject *newclass = NULL;
PyObject *newclass= NULL;
/* stupid/simple case */
if (srna == NULL) {
@@ -4796,7 +5129,7 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna)
/* subclass equivelents
- class myClass(myBase):
some='value' # or ...
- myClass = type(name='myClass', bases=(myBase,), dict={'__module__':'bpy.types'})
- myClass= type(name='myClass', bases=(myBase,), dict={'__module__':'bpy.types'})
*/
/* Assume RNA_struct_py_type_get(srna) was already checked */
@@ -4807,7 +5140,7 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna)
/* remove __doc__ for now */
// const char *descr= RNA_struct_ui_description(srna);
// if(!descr) descr= "(no docs)";
// "__doc__",descr
// "__doc__", descr
if(RNA_struct_idprops_check(srna) && !PyObject_IsSubclass(py_base, (PyObject *)&pyrna_struct_meta_idprop_Type)) {
metaclass= (PyObject *)&pyrna_struct_meta_idprop_Type;
@@ -4817,7 +5150,7 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna)
}
/* always use O not N when calling, N causes refcount errors */
newclass = PyObject_CallFunction(metaclass, (char *)"s(O){sss()}", idname, py_base, "__module__","bpy.types", "__slots__");
newclass= PyObject_CallFunction(metaclass, (char *)"s(O){sss()}", idname, py_base, "__module__","bpy.types", "__slots__");
/* newclass will now have 2 ref's, ???, probably 1 is internal since decrefing here segfaults */
@@ -4837,7 +5170,7 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna)
PyErr_Clear();
}
}
return newclass;
}
@@ -4859,7 +5192,7 @@ static PyObject* pyrna_struct_Subtype(PointerRNA *ptr)
}
/*-----------------------CreatePyObject---------------------------------*/
PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
{
BPy_StructRNA *pyrna= NULL;
@@ -4868,35 +5201,44 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
Py_RETURN_NONE;
}
else {
PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr);
PyTypeObject *tp= (PyTypeObject *)pyrna_struct_Subtype(ptr);
if (tp) {
pyrna = (BPy_StructRNA *) tp->tp_alloc(tp, 0);
pyrna= (BPy_StructRNA *) tp->tp_alloc(tp, 0);
Py_DECREF(tp); /* srna owns, cant hold a ref */
}
else {
fprintf(stderr, "Could not make type\n");
pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
pyrna= (BPy_StructRNA *) PyObject_GC_New(BPy_StructRNA, &pyrna_struct_Type);
#ifdef USE_WEAKREFS
pyrna->in_weakreflist= NULL;
#endif
}
}
if( !pyrna ) {
if(pyrna == NULL) {
PyErr_SetString(PyExc_MemoryError, "couldn't create bpy_struct object");
return NULL;
}
pyrna->ptr= *ptr;
pyrna->freeptr= FALSE;
#ifdef USE_PYRNA_STRUCT_REFERENCE
pyrna->reference= NULL;
#endif
// PyC_ObSpit("NewStructRNA: ", (PyObject *)pyrna);
return ( PyObject * ) pyrna;
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
if(ptr->id.data) {
id_weakref_pool_add(ptr->id.data, (BPy_DummyPointerRNA *)pyrna);
}
#endif
return (PyObject *)pyrna;
}
PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop)
{
BPy_PropertyRNA *pyrna;
@@ -4911,17 +5253,17 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
type= &pyrna_prop_collection_Type;
}
else {
type= &pyrna_prop_collection_idprop_Type;
type= &pyrna_prop_collection_idprop_Type;
}
}
pyrna = (BPy_PropertyRNA *) PyObject_NEW(BPy_PropertyRNA, type);
pyrna= (BPy_PropertyRNA *) PyObject_NEW(BPy_PropertyRNA, type);
#ifdef USE_WEAKREFS
pyrna->in_weakreflist= NULL;
#endif
}
else {
pyrna = (BPy_PropertyRNA *) PyObject_NEW(BPy_PropertyArrayRNA, &pyrna_prop_array_Type);
pyrna= (BPy_PropertyRNA *) PyObject_NEW(BPy_PropertyArrayRNA, &pyrna_prop_array_Type);
((BPy_PropertyArrayRNA *)pyrna)->arraydim= 0;
((BPy_PropertyArrayRNA *)pyrna)->arrayoffset= 0;
#ifdef USE_WEAKREFS
@@ -4929,15 +5271,21 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
#endif
}
if( !pyrna ) {
if(pyrna == NULL) {
PyErr_SetString(PyExc_MemoryError, "couldn't create BPy_rna object");
return NULL;
}
pyrna->ptr = *ptr;
pyrna->prop = prop;
return ( PyObject * ) pyrna;
pyrna->ptr= *ptr;
pyrna->prop= prop;
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
if(ptr->id.data) {
id_weakref_pool_add(ptr->id.data, (BPy_DummyPointerRNA *)pyrna);
}
#endif
return (PyObject *)pyrna;
}
void BPY_rna_init(void)
@@ -4946,26 +5294,31 @@ void BPY_rna_init(void)
mathutils_rna_array_cb_index= Mathutils_RegisterCallback(&mathutils_rna_array_cb);
mathutils_rna_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_rna_matrix_cb);
#endif
/* metaclass */
pyrna_struct_meta_idprop_Type.tp_base= &PyType_Type;
if( PyType_Ready( &pyrna_struct_meta_idprop_Type ) < 0 )
return;
if( PyType_Ready( &pyrna_struct_Type ) < 0 )
if(PyType_Ready(&pyrna_struct_meta_idprop_Type) < 0)
return;
if( PyType_Ready( &pyrna_prop_Type ) < 0 )
if(PyType_Ready(&pyrna_struct_Type) < 0)
return;
if( PyType_Ready( &pyrna_prop_array_Type ) < 0 )
if(PyType_Ready(&pyrna_prop_Type) < 0)
return;
if( PyType_Ready( &pyrna_prop_collection_Type ) < 0 )
if(PyType_Ready(&pyrna_prop_array_Type) < 0)
return;
if( PyType_Ready( &pyrna_prop_collection_idprop_Type ) < 0 )
if(PyType_Ready(&pyrna_prop_collection_Type) < 0)
return;
if(PyType_Ready(&pyrna_prop_collection_idprop_Type) < 0)
return;
#ifdef USE_PYRNA_ITER
if(PyType_Ready(&pyrna_prop_collection_iter_Type) < 0)
return;
#endif
}
/* bpy.data from python */
@@ -4978,7 +5331,7 @@ PyObject *BPY_rna_module(void)
/* for now, return the base RNA type rather then a real module */
RNA_main_pointer_create(G.main, &ptr);
pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
rna_module_ptr= &pyrna->ptr;
return (PyObject *)pyrna;
}
@@ -4991,13 +5344,13 @@ void BPY_update_rna_module(void)
#if 0
/* This is a way we can access docstrings for RNA types
* without having the datatypes in blender */
PyObject *BPY_rna_doc( void )
PyObject *BPY_rna_doc(void)
{
PointerRNA ptr;
/* for now, return the base RNA type rather then a real module */
RNA_blender_rna_pointer_create(&ptr);
return pyrna_struct_CreatePyObject(&ptr);
}
#endif
@@ -5006,7 +5359,7 @@ PyObject *BPY_rna_doc( void )
/* pyrna_basetype_* - BPy_BaseTypeRNA is just a BPy_PropertyRNA struct with a differnt type
* the self->ptr and self->prop are always set to the "structs" collection */
//---------------getattr--------------------------------------------
static PyObject *pyrna_basetype_getattro( BPy_BaseTypeRNA *self, PyObject *pyname )
static PyObject *pyrna_basetype_getattro(BPy_BaseTypeRNA *self, PyObject *pyname)
{
PointerRNA newptr;
PyObject *ret;
@@ -5014,7 +5367,7 @@ static PyObject *pyrna_basetype_getattro( BPy_BaseTypeRNA *self, PyObject *pynam
if(name == NULL) {
PyErr_SetString(PyExc_AttributeError, "bpy.types: __getattr__ must be a string");
ret = NULL;
ret= NULL;
}
else if (RNA_property_collection_lookup_string(&self->ptr, self->prop, name, &newptr)) {
ret= pyrna_struct_Subtype(&newptr);
@@ -5038,7 +5391,7 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self);
static PyObject *pyrna_register_class(PyObject *self, PyObject *py_class);
static PyObject *pyrna_unregister_class(PyObject *self, PyObject *py_class);
static struct PyMethodDef pyrna_basetype_methods[] = {
static struct PyMethodDef pyrna_basetype_methods[]= {
{"__dir__", (PyCFunction)pyrna_basetype_dir, METH_NOARGS, ""},
{NULL, NULL, 0, NULL}
};
@@ -5055,7 +5408,7 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
#if 0 /* for now only contains __dir__ */
for(meth=pyrna_basetype_methods; meth->ml_name; meth++) {
name = PyUnicode_FromString(meth->ml_name);
name= PyUnicode_FromString(meth->ml_name);
PyList_Append(list, name);
Py_DECREF(name);
}
@@ -5063,28 +5416,28 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
return list;
}
static PyTypeObject pyrna_basetype_Type = BLANK_PYTHON_TYPE;
static PyTypeObject pyrna_basetype_Type= BLANK_PYTHON_TYPE;
PyObject *BPY_rna_types(void)
{
BPy_BaseTypeRNA *self;
if ((pyrna_basetype_Type.tp_flags & Py_TPFLAGS_READY)==0) {
pyrna_basetype_Type.tp_name = "RNA_Types";
pyrna_basetype_Type.tp_basicsize = sizeof(BPy_BaseTypeRNA);
pyrna_basetype_Type.tp_getattro = ( getattrofunc )pyrna_basetype_getattro;
pyrna_basetype_Type.tp_flags = Py_TPFLAGS_DEFAULT;
pyrna_basetype_Type.tp_methods = pyrna_basetype_methods;
if( PyType_Ready( &pyrna_basetype_Type ) < 0 )
if ((pyrna_basetype_Type.tp_flags & Py_TPFLAGS_READY)==0) {
pyrna_basetype_Type.tp_name= "RNA_Types";
pyrna_basetype_Type.tp_basicsize= sizeof(BPy_BaseTypeRNA);
pyrna_basetype_Type.tp_getattro= (getattrofunc) pyrna_basetype_getattro;
pyrna_basetype_Type.tp_flags= Py_TPFLAGS_DEFAULT;
pyrna_basetype_Type.tp_methods= pyrna_basetype_methods;
if(PyType_Ready(&pyrna_basetype_Type) < 0)
return NULL;
}
self= (BPy_BaseTypeRNA *)PyObject_NEW( BPy_BaseTypeRNA, &pyrna_basetype_Type );
self= (BPy_BaseTypeRNA *)PyObject_NEW(BPy_BaseTypeRNA, &pyrna_basetype_Type);
/* avoid doing this lookup for every getattr */
RNA_blender_rna_pointer_create(&self->ptr);
self->prop = RNA_struct_find_property(&self->ptr, "structs");
self->prop= RNA_struct_find_property(&self->ptr, "structs");
#ifdef USE_WEAKREFS
self->in_weakreflist= NULL;
#endif
@@ -5093,12 +5446,12 @@ PyObject *BPY_rna_types(void)
StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix)
{
BPy_StructRNA *py_srna = NULL;
BPy_StructRNA *py_srna= NULL;
StructRNA *srna;
/* ack, PyObject_GetAttrString wont look up this types tp_dict first :/ */
if(PyType_Check(self)) {
py_srna = (BPy_StructRNA *)PyDict_GetItemString(((PyTypeObject *)self)->tp_dict, "bl_rna");
py_srna= (BPy_StructRNA *)PyDict_GetItemString(((PyTypeObject *)self)->tp_dict, "bl_rna");
Py_XINCREF(py_srna);
}
@@ -5106,7 +5459,7 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_pr
/* be very careful with this since it will return a parent classes srna.
* modifying this will do confusing stuff! */
if(py_srna==NULL)
py_srna = (BPy_StructRNA*)PyObject_GetAttrString(self, "bl_rna");
py_srna= (BPy_StructRNA*)PyObject_GetAttrString(self, "bl_rna");
}
if(py_srna==NULL) {
@@ -5183,15 +5536,15 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item
PyErr_Format(PyExc_ValueError, "bpy_struct \"%.200s\" registration error: %.200s could not register because the property starts with an '_'\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key));
return -1;
}
py_srna_cobject = PyCapsule_New(srna, NULL, NULL);
py_srna_cobject= PyCapsule_New(srna, NULL, NULL);
/* not 100% nice :/, modifies the dict passed, should be ok */
PyDict_SetItemString(py_kw, "attr", key);
args_fake= PyTuple_New(1);
PyTuple_SET_ITEM(args_fake, 0, py_srna_cobject);
py_ret = PyObject_Call(py_func, args_fake, py_kw);
py_ret= PyObject_Call(py_func, args_fake, py_kw);
Py_DECREF(args_fake); /* free's py_srna_cobject too */
@@ -5224,7 +5577,7 @@ static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
{
PyObject *item, *key;
PyObject *order;
Py_ssize_t pos = 0;
Py_ssize_t pos= 0;
int ret= 0;
/* in both cases PyDict_CheckExact(class_dict) will be true even
@@ -5273,7 +5626,7 @@ static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject
!PyObject_IsSubclass((PyObject *)py_superclass, (PyObject *)&pyrna_struct_Type)
) {
ret= pyrna_deferred_register_class_recursive(srna, py_superclass);
if(ret != 0) {
return ret;
}
@@ -5281,7 +5634,7 @@ static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject
}
/* not register out own properties */
return pyrna_deferred_register_props(srna, py_class->tp_dict); /* getattr(..., "__dict__") returns a proxy */
return pyrna_deferred_register_props(srna, py_class->tp_dict); /* getattr(..., "__dict__") returns a proxy */
}
int pyrna_deferred_register_class(StructRNA *srna, PyObject *py_class)
@@ -5308,7 +5661,7 @@ static int rna_function_arg_count(FunctionRNA *func)
if(!(RNA_property_flag(parm) & PROP_OUTPUT))
count++;
}
return count;
}
@@ -5325,7 +5678,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
PyObject *item;
PyObject *py_arg_count;
int i, flag, arg_count, func_arg_count;
const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; // __name__
const char *py_class_name= ((PyTypeObject *)py_class)->tp_name; // __name__
if (base_class) {
@@ -5345,7 +5698,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
if(!(flag & FUNC_REGISTER))
continue;
item = PyObject_GetAttrString(py_class, RNA_function_identifier(func));
item= PyObject_GetAttrString(py_class, RNA_function_identifier(func));
have_function[i]= (item != NULL);
i++;
@@ -5377,8 +5730,8 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
func_arg_count= rna_function_arg_count(func);
if (func_arg_count >= 0) { /* -1 if we dont care*/
py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(item), "co_argcount");
arg_count = PyLong_AsLong(py_arg_count);
py_arg_count= PyObject_GetAttrString(PyFunction_GET_CODE(item), "co_argcount");
arg_count= PyLong_AsLong(py_arg_count);
Py_DECREF(py_arg_count);
/* note, the number of args we check for and the number of args we give to
@@ -5405,7 +5758,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
continue;
identifier= RNA_property_identifier(prop);
item = PyObject_GetAttrString(py_class, identifier);
item= PyObject_GetAttrString(py_class, identifier);
if (item==NULL) {
/* Sneaky workaround to use the class name as the bl_idname */
@@ -5457,7 +5810,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
ParameterIterator iter;
PointerRNA funcptr;
int err= 0, i, flag, ret_len=0;
int is_static = RNA_function_flag(func) & FUNC_NO_SELF;
int is_static= RNA_function_flag(func) & FUNC_NO_SELF;
PropertyRNA *pret_single= NULL;
void *retdata_single= NULL;
@@ -5469,9 +5822,9 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
/* testing, for correctness, not operator and not draw function */
const short is_readonly= strstr("draw", func_id) || /*strstr("render", func_id) ||*/ !RNA_struct_is_a(ptr->type, &RNA_Operator);
#endif
py_class= RNA_struct_py_type_get(ptr->type);
/* rare case. can happen when registering subclasses */
if(py_class==NULL) {
fprintf(stderr, "bpy_class_call(): unable to get python class for rna struct '%.200s'\n", RNA_struct_identifier(ptr->type));
@@ -5501,19 +5854,19 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
}
}
/* end exception */
if(py_class_instance==NULL)
py_srna= pyrna_struct_CreatePyObject(ptr);
if(py_class_instance) {
/* special case, instance is cached */
}
else if(py_srna == NULL) {
py_class_instance = NULL;
py_class_instance= NULL;
}
else if(py_srna == Py_None) { /* probably wont ever happen but possible */
Py_DECREF(py_srna);
py_class_instance = NULL;
py_class_instance= NULL;
}
else {
#if 1
@@ -5523,10 +5876,10 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
*/
if(py_class->tp_init) {
/* true in most cases even when the class its self doesnt define an __init__ function. */
args = PyTuple_New(0);
if (py_class->tp_init(py_srna, args, NULL) < 0) {
Py_DECREF(py_srna);
py_srna= NULL;
args= PyTuple_New(0);
if (py_class->tp_init(py_srna, args, NULL) < 0) {
Py_DECREF(py_srna);
py_srna= NULL;
/* err set below */
}
Py_DECREF(args);
@@ -5537,23 +5890,23 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
#else
/* 'almost' all the time calling the class isnt needed.
* We could just do...
py_class_instance = py_srna;
py_class_instance= py_srna;
Py_INCREF(py_class_instance);
* This would work fine but means __init__ functions wouldnt run.
* none of blenders default scripts use __init__ but its nice to call it
* for general correctness. just to note why this is here when it could be safely removed.
*/
args = PyTuple_New(1);
args= PyTuple_New(1);
PyTuple_SET_ITEM(args, 0, py_srna);
py_class_instance= PyObject_Call(py_class, args, NULL);
Py_DECREF(args);
#endif
#endif
if(py_class_instance == NULL) {
err= -1; /* so the error is not overridden below */
}
else if(py_class_instance_store) {
*py_class_instance_store = py_class_instance;
*py_class_instance_store= py_class_instance;
Py_INCREF(py_class_instance);
}
}
@@ -5566,8 +5919,8 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
if(item) {
RNA_pointer_create(NULL, &RNA_Function, func, &funcptr);
args = PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */
args= PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */
if(is_static) {
i= 0;
}
@@ -5600,11 +5953,11 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
}
#ifdef USE_PEDANTIC_WRITE
rna_disallow_writes= is_readonly ? TRUE:FALSE;
rna_disallow_writes= is_readonly ? TRUE:FALSE;
#endif
/* *** Main Caller *** */
ret = PyObject_Call(item, args, NULL);
ret= PyObject_Call(item, args, NULL);
/* *** Done Calling *** */
@@ -5695,7 +6048,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
}
bpy_context_clear(C, &gilstate);
return err;
}
@@ -5704,7 +6057,7 @@ static void bpy_class_free(void *pyob_ptr)
PyObject *self= (PyObject *)pyob_ptr;
PyGILState_STATE gilstate;
gilstate = PyGILState_Ensure();
gilstate= PyGILState_Ensure();
// breaks re-registering classes
// PyDict_Clear(((PyTypeObject*)self)->tp_dict);
@@ -5732,12 +6085,12 @@ void pyrna_alloc_types(void)
PointerRNA ptr;
PropertyRNA *prop;
gilstate = PyGILState_Ensure();
gilstate= PyGILState_Ensure();
/* avoid doing this lookup for every getattr */
RNA_blender_rna_pointer_create(&ptr);
prop = RNA_struct_find_property(&ptr, "structs");
prop= RNA_struct_find_property(&ptr, "structs");
RNA_PROP_BEGIN(&ptr, itemptr, prop) {
PyObject *item= pyrna_struct_Subtype(&itemptr);
@@ -5764,7 +6117,7 @@ void pyrna_free_types(void)
/* avoid doing this lookup for every getattr */
RNA_blender_rna_pointer_create(&ptr);
prop = RNA_struct_find_property(&ptr, "structs");
prop= RNA_struct_find_property(&ptr, "structs");
RNA_PROP_BEGIN(&ptr, itemptr, prop) {
@@ -5796,10 +6149,12 @@ static char pyrna_register_class_doc[] =
"\n"
" Register a subclass of a blender type in (:class:`Panel`, :class:`Menu`, :class:`Header`, :class:`Operator`, :class:`KeyingSetInfo`, :class:`RenderEngine`).\n"
"\n"
" If the class has a *register* class method it will be called before registration.\n"
"\n"
" .. note:: :exc:`ValueError` exception is raised if the class is not a subclass of a registerable blender class.\n"
"\n"
;
PyMethodDef meth_bpy_register_class = {"register_class", pyrna_register_class, METH_O, pyrna_register_class_doc};
PyMethodDef meth_bpy_register_class= {"register_class", pyrna_register_class, METH_O, pyrna_register_class_doc};
static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class)
{
bContext *C= NULL;
@@ -5808,6 +6163,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
StructRNA *srna;
StructRNA *srna_new;
const char *identifier;
PyObject *py_cls_meth;
if(PyDict_GetItemString(((PyTypeObject*)py_class)->tp_dict, "bl_rna")) {
PyErr_SetString(PyExc_AttributeError, "register_class(...): already registered as a subclass");
@@ -5818,7 +6174,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
srna= pyrna_struct_as_srna(py_class, 1, "register_class(...):");
if(srna==NULL)
return NULL;
/* fails in cases, cant use this check but would like to :| */
/*
if(RNA_struct_py_type_get(srna)) {
@@ -5834,7 +6190,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
PyErr_Format(PyExc_ValueError, "register_class(...): expected a subclass of a registerable rna type (%.200s does not support registration)", RNA_struct_identifier(srna));
return NULL;
}
/* get the context, so register callback can do necessary refreshes */
C= BPy_GetContext();
@@ -5845,7 +6201,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
srna_new= reg(C, &reports, py_class, identifier, bpy_class_validate, bpy_class_call, bpy_class_free);
if(BPy_reports_to_error(&reports, TRUE))
if(BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
return NULL;
/* python errors validating are not converted into reports so the check above will fail.
@@ -5855,7 +6211,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
pyrna_subtype_set_rna(py_class, srna_new); /* takes a ref to py_class */
/* old srna still references us, keep the check incase registering somehow can free it */
/* old srna still references us, keep the check incase registering somehow can free it */
if(RNA_struct_py_type_get(srna)) {
RNA_struct_py_type_set(srna, NULL);
// Py_DECREF(py_class); // shuld be able to do this XXX since the old rna adds a new ref.
@@ -5868,6 +6224,21 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
if(pyrna_deferred_register_class(srna_new, py_class)!=0)
return NULL;
/* call classed register method () */
py_cls_meth= PyObject_GetAttrString(py_class, "register");
if(py_cls_meth == NULL) {
PyErr_Clear();
}
else {
PyObject *ret= PyObject_CallObject(py_cls_meth, NULL);
if(ret) {
Py_DECREF(ret);
}
else {
return NULL;
}
}
Py_RETURN_NONE;
}
@@ -5900,13 +6271,16 @@ static char pyrna_unregister_class_doc[] =
".. method:: unregister_class(cls)\n"
"\n"
" Unload the python class from blender.\n"
"\n"
" If the class has an *unregister* class method it will be called before unregistering.\n"
;
PyMethodDef meth_bpy_unregister_class = {"unregister_class", pyrna_unregister_class, METH_O, pyrna_unregister_class_doc};
PyMethodDef meth_bpy_unregister_class= {"unregister_class", pyrna_unregister_class, METH_O, pyrna_unregister_class_doc};
static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_class)
{
bContext *C= NULL;
StructUnregisterFunc unreg;
StructRNA *srna;
PyObject *py_cls_meth;
/*if(PyDict_GetItemString(((PyTypeObject*)py_class)->tp_dict, "bl_rna")==NULL) {
PWM_cursor_wait(0);
@@ -5917,7 +6291,7 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla
srna= pyrna_struct_as_srna(py_class, 0, "unregister_class(...):");
if(srna==NULL)
return NULL;
/* check that we have a unregister callback for this type */
unreg= RNA_struct_unregister(srna);
@@ -5925,7 +6299,22 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla
PyErr_SetString(PyExc_ValueError, "unregister_class(...): expected a Type subclassed from a registerable rna type (no unregister supported)");
return NULL;
}
/* call classed unregister method */
py_cls_meth= PyObject_GetAttrString(py_class, "unregister");
if(py_cls_meth == NULL) {
PyErr_Clear();
}
else {
PyObject *ret= PyObject_CallObject(py_cls_meth, NULL);
if(ret) {
Py_DECREF(ret);
}
else {
return NULL;
}
}
/* should happen all the time but very slow */
if(G.f & G_DEBUG) {
/* remove all properties using this class */
@@ -5935,25 +6324,25 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla
const char *prop_identifier= NULL;
RNA_blender_rna_pointer_create(&ptr_rna);
prop_rna = RNA_struct_find_property(&ptr_rna, "structs");
prop_rna= RNA_struct_find_property(&ptr_rna, "structs");
/* loop over all structs */
RNA_PROP_BEGIN(&ptr_rna, itemptr, prop_rna) {
srna_iter = itemptr.data;
srna_iter= itemptr.data;
if(pyrna_srna_contains_pointer_prop_srna(srna_iter, srna, &prop_identifier)) {
break;
}
}
RNA_PROP_END;
if(prop_identifier) {
PyErr_Format(PyExc_RuntimeError, "unregister_class(...): can't unregister %s because %s.%s pointer property is using this", RNA_struct_identifier(srna), RNA_struct_identifier(srna_iter), prop_identifier);
return NULL;
}
}
}
/* get the context, so register callback can do necessary refreshes */
C= BPy_GetContext();

View File

@@ -21,14 +21,52 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_rna.h
* \ingroup pythonintern
*/
#ifndef BPY_RNA_H
#define BPY_RNA_H
#include "RNA_access.h"
#include "RNA_types.h"
#include "BKE_idprop.h"
/* --- bpy build options --- */
#ifdef WITH_PYTHON_SAFETY
#include <Python.h>
/* play it safe and keep optional for now, need to test further now this affects looping on 10000's of verts for eg. */
#define USE_WEAKREFS
/* method to invalidate removed py data, XXX, slow to remove objects, otherwise no overhead */
/* #define USE_PYRNA_INVALIDATE_GC */
/* different method */
#define USE_PYRNA_INVALIDATE_WEAKREF
/* support for inter references, currently only needed for corner case */
#define USE_PYRNA_STRUCT_REFERENCE
/* use real collection iterators rather then faking with a list */
#define USE_PYRNA_ITER
#else /* WITH_PYTHON_SAFETY */
/* default, no defines! */
#endif /* !WITH_PYTHON_SAFETY */
/* sanity checks on above defs */
#if defined(USE_PYRNA_INVALIDATE_WEAKREF) && !defined(USE_WEAKREFS)
#define USE_WEAKREFS
#endif
#if defined(USE_PYRNA_INVALIDATE_GC) && defined(USE_PYRNA_INVALIDATE_WEAKREF)
#error "Only 1 reference check method at a time!"
#endif
/* --- end bpy build options --- */
struct ID;
extern PyTypeObject pyrna_struct_meta_idprop_Type;
extern PyTypeObject pyrna_struct_Type;
extern PyTypeObject pyrna_prop_Type;
@@ -40,47 +78,70 @@ extern PyTypeObject pyrna_prop_collection_Type;
#define BPy_PropertyRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_prop_Type))
#define BPy_PropertyRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_prop_Type)
/* play it safe and keep optional for now, need to test further now this affects looping on 10000's of verts for eg. */
// #define USE_WEAKREFS
#define PYRNA_STRUCT_CHECK_OBJ(obj) if(pyrna_struct_validity_check(obj) == -1) { return NULL; }
#define PYRNA_STRUCT_CHECK_INT(obj) if(pyrna_struct_validity_check(obj) == -1) { return -1; }
#define PYRNA_PROP_CHECK_OBJ(obj) if(pyrna_prop_validity_check(obj) == -1) { return NULL; }
#define PYRNA_PROP_CHECK_INT(obj) if(pyrna_prop_validity_check(obj) == -1) { return -1; }
#define PYRNA_STRUCT_IS_VALID(pysrna) (((BPy_StructRNA *)(pysrna))->ptr.type != NULL)
#define PYRNA_PROP_IS_VALID(pysrna) (((BPy_PropertyRNA *)(pysrna))->ptr.type != NULL)
/* 'in_weakreflist' MUST be aligned */
typedef struct {
PyObject_HEAD /* required python macro */
PointerRNA ptr;
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
PointerRNA ptr;
} BPy_DummyPointerRNA;
typedef struct {
PyObject_HEAD /* required python macro */
PointerRNA ptr;
int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
PointerRNA ptr;
#ifdef USE_PYRNA_STRUCT_REFERENCE
/* generic PyObject we hold a reference to, example use:
* hold onto the collection iterator to prevent it from freeing allocated data we may use */
PyObject *reference;
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */
} BPy_StructRNA;
typedef struct {
PyObject_HEAD /* required python macro */
PointerRNA ptr;
PropertyRNA *prop;
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
PointerRNA ptr;
PropertyRNA *prop;
} BPy_PropertyRNA;
typedef struct {
PyObject_HEAD /* required python macro */
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
PointerRNA ptr;
PropertyRNA *prop;
/* Arystan: this is a hack to allow sub-item r/w access like: face.uv[n][m] */
int arraydim; /* array dimension, e.g: 0 for face.uv, 2 for face.uv[n][m], etc. */
int arrayoffset; /* array first item offset, e.g. if face.uv is [4][2], arrayoffset for face.uv[n] is 2n */
} BPy_PropertyArrayRNA;
typedef struct {
PyObject_HEAD /* required python macro */
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
} BPy_PropertyArrayRNA;
/* collection iterator spesific parts */
CollectionPropertyIterator iter;
} BPy_PropertyCollectionIterRNA;
/* cheap trick */
#define BPy_BaseTypeRNA BPy_PropertyRNA
@@ -124,10 +185,15 @@ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
int pyrna_write_check(void);
int pyrna_struct_validity_check(BPy_StructRNA *pysrna);
int pyrna_prop_validity_check(BPy_PropertyRNA *self);
void BPY_modules_update(struct bContext *C); //XXX temp solution
/* bpy.utils.(un)register_class */
extern PyMethodDef meth_bpy_register_class;
extern PyMethodDef meth_bpy_unregister_class;
void BPY_id_release(struct ID *id);
#endif

View File

@@ -0,0 +1,354 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_rna_anim.c
* \ingroup pythonintern
*/
#include <Python.h>
#include <float.h> /* FLT_MIN/MAX */
#include "MEM_guardedalloc.h"
#include "BLI_string.h"
#include "DNA_scene_types.h"
#include "DNA_anim_types.h"
#include "ED_keyframing.h"
#include "BKE_report.h"
#include "BKE_context.h"
#include "BKE_animsys.h"
#include "BKE_fcurve.h"
#include "RNA_access.h"
#include "bpy_rna.h"
#include "bpy_util.h"
#include "bpy_rna_anim.h"
#define TRUE 1
#define FALSE 0
/* for keyframes and drivers */
static int pyrna_struct_anim_args_parse(PointerRNA *ptr, const char *error_prefix, const char *path,
const char **path_full, int *index)
{
const int is_idbase= RNA_struct_is_ID(ptr->type);
PropertyRNA *prop;
PointerRNA r_ptr;
if (ptr->data==NULL) {
PyErr_Format(PyExc_TypeError, "%.200s this struct has no data, can't be animated", error_prefix);
return -1;
}
/* full paths can only be given from ID base */
if(is_idbase) {
int r_index= -1;
if(RNA_path_resolve_full(ptr, path, &r_ptr, &prop, &r_index)==0) {
prop= NULL;
}
else if(r_index != -1) {
PyErr_Format(PyExc_ValueError, "%.200s path includes index, must be a separate argument", error_prefix, path);
return -1;
}
else if(ptr->id.data != r_ptr.id.data) {
PyErr_Format(PyExc_ValueError, "%.200s path spans ID blocks", error_prefix, path);
return -1;
}
}
else {
prop= RNA_struct_find_property(ptr, path);
r_ptr= *ptr;
}
if (prop==NULL) {
PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not found", error_prefix, path);
return -1;
}
if (!RNA_property_animateable(&r_ptr, prop)) {
PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not animatable", error_prefix, path);
return -1;
}
if(RNA_property_array_check(&r_ptr, prop) == 0) {
if((*index) == -1) {
*index= 0;
}
else {
PyErr_Format(PyExc_TypeError, "%.200s index %d was given while property \"%s\" is not an array", error_prefix, *index, path);
return -1;
}
}
else {
int array_len= RNA_property_array_length(&r_ptr, prop);
if((*index) < -1 || (*index) >= array_len) {
PyErr_Format(PyExc_TypeError, "%.200s index out of range \"%s\", given %d, array length is %d", error_prefix, path, *index, array_len);
return -1;
}
}
if(is_idbase) {
*path_full= BLI_strdup(path);
}
else {
*path_full= RNA_path_from_ID_to_property(&r_ptr, prop);
if (*path_full==NULL) {
PyErr_Format(PyExc_TypeError, "%.200s could not make path to \"%s\"", error_prefix, path);
return -1;
}
}
return 0;
}
/* internal use for insert and delete */
static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix,
const char **path_full, int *index, float *cfra, const char **group_name) /* return values */
{
static const char *kwlist[]= {"data_path", "index", "frame", "group", NULL};
const char *path;
/* note, parse_str MUST start with 's|ifs' */
if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name))
return -1;
if(pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) < 0)
return -1;
if(*cfra==FLT_MAX)
*cfra= CTX_data_scene(BPy_GetContext())->r.cfra;
return 0; /* success */
}
char pyrna_struct_keyframe_insert_doc[] =
".. method:: keyframe_insert(data_path, index=-1, frame=bpy.context.scene.frame_current, group=\"\")\n"
"\n"
" Insert a keyframe on the property given, adding fcurves and animation data when necessary.\n"
"\n"
" :arg data_path: path to the property to key, analogous to the fcurve's data path.\n"
" :type data_path: string\n"
" :arg index: array index of the property to key. Defaults to -1 which will key all indices or a single channel if the property is not an array.\n"
" :type index: int\n"
" :arg frame: The frame on which the keyframe is inserted, defaulting to the current frame.\n"
" :type frame: float\n"
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
" :type group: str\n"
" :return: Success of keyframe insertion.\n"
" :rtype: boolean\n"
;
PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw)
{
/* args, pyrna_struct_keyframe_parse handles these */
const char *path_full= NULL;
int index= -1;
float cfra= FLT_MAX;
const char *group_name= NULL;
PYRNA_STRUCT_CHECK_OBJ(self)
if(pyrna_struct_keyframe_parse(&self->ptr, args, kw, "s|ifs:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()", &path_full, &index, &cfra, &group_name) == -1) {
return NULL;
}
else {
short result;
ReportList reports;
BKE_reports_init(&reports, RPT_STORE);
result= insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
MEM_freeN((void *)path_full);
if(BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
return NULL;
return PyBool_FromLong(result);
}
}
char pyrna_struct_keyframe_delete_doc[] =
".. method:: keyframe_delete(data_path, index=-1, frame=bpy.context.scene.frame_current, group=\"\")\n"
"\n"
" Remove a keyframe from this properties fcurve.\n"
"\n"
" :arg data_path: path to the property to remove a key, analogous to the fcurve's data path.\n"
" :type data_path: string\n"
" :arg index: array index of the property to remove a key. Defaults to -1 removing all indices or a single channel if the property is not an array.\n"
" :type index: int\n"
" :arg frame: The frame on which the keyframe is deleted, defaulting to the current frame.\n"
" :type frame: float\n"
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
" :type group: str\n"
" :return: Success of keyframe deleation.\n"
" :rtype: boolean\n"
;
PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
{
/* args, pyrna_struct_keyframe_parse handles these */
const char *path_full= NULL;
int index= -1;
float cfra= FLT_MAX;
const char *group_name= NULL;
PYRNA_STRUCT_CHECK_OBJ(self)
if(pyrna_struct_keyframe_parse(&self->ptr, args, kw, "s|ifs:bpy_struct.keyframe_delete()", "bpy_struct.keyframe_insert()", &path_full, &index, &cfra, &group_name) == -1) {
return NULL;
}
else {
short result;
ReportList reports;
BKE_reports_init(&reports, RPT_STORE);
result= delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
MEM_freeN((void *)path_full);
if(BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
return NULL;
return PyBool_FromLong(result);
}
}
char pyrna_struct_driver_add_doc[] =
".. method:: driver_add(path, index=-1)\n"
"\n"
" Adds driver(s) to the given property\n"
"\n"
" :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
" :type path: string\n"
" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
" :type index: int\n"
" :return: The driver(s) added.\n"
" :rtype: :class:`FCurve` or list if index is -1 with an array property.\n"
;
PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
{
const char *path, *path_full;
int index= -1;
PYRNA_STRUCT_CHECK_OBJ(self)
if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
return NULL;
if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) < 0) {
return NULL;
}
else {
PyObject *ret= NULL;
ReportList reports;
int result;
BKE_reports_init(&reports, RPT_STORE);
result= ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON);
if(BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
return NULL;
if(result) {
ID *id= self->ptr.id.data;
AnimData *adt= BKE_animdata_from_id(id);
FCurve *fcu;
PointerRNA tptr;
PyObject *item;
if(index == -1) { /* all, use a list */
int i= 0;
ret= PyList_New(0);
while((fcu= list_find_fcurve(&adt->drivers, path_full, i++))) {
RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
item= pyrna_struct_CreatePyObject(&tptr);
PyList_Append(ret, item);
Py_DECREF(item);
}
}
else {
fcu= list_find_fcurve(&adt->drivers, path_full, index);
RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
ret= pyrna_struct_CreatePyObject(&tptr);
}
}
else {
/* XXX, should be handled by reports, */
PyErr_SetString(PyExc_TypeError, "bpy_struct.driver_add(): failed because of an internal error");
return NULL;
}
MEM_freeN((void *)path_full);
return ret;
}
}
char pyrna_struct_driver_remove_doc[] =
".. method:: driver_remove(path, index=-1)\n"
"\n"
" Remove driver(s) from the given property\n"
"\n"
" :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
" :type path: string\n"
" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
" :type index: int\n"
" :return: Success of driver removal.\n"
" :rtype: boolean\n"
;
PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
{
const char *path, *path_full;
int index= -1;
PYRNA_STRUCT_CHECK_OBJ(self)
if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
return NULL;
if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) < 0) {
return NULL;
}
else {
short result;
ReportList reports;
BKE_reports_init(&reports, RPT_STORE);
result= ANIM_remove_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0);
MEM_freeN((void *)path_full);
if(BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
return NULL;
return PyBool_FromLong(result);
}
}

View File

@@ -0,0 +1,37 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_rna_anim.h
* \ingroup pythonintern
*/
extern char pyrna_struct_keyframe_insert_doc[];
extern char pyrna_struct_keyframe_delete_doc[];
extern char pyrna_struct_driver_add_doc[];
extern char pyrna_struct_driver_remove_doc[];
PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw);
PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw);
PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args);
PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args);

View File

@@ -21,12 +21,21 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_rna_array.c
* \ingroup pythonintern
*/
#include <Python.h>
#include "RNA_types.h"
#include "bpy_rna.h"
#include "BKE_global.h"
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#define MAX_ARRAY_DIMENSION 10
typedef void (*ItemConvertFunc)(PyObject *, char *);
@@ -40,7 +49,7 @@ typedef void (*RNA_SetIndexFunc)(PointerRNA *, PropertyRNA *, int index, void *)
*/
/*
arr[2] = x
arr[2]= x
py_to_array_index(arraydim=0, arrayoffset=0, index=2)
validate_array(lvalue_dim=0)
@@ -58,6 +67,10 @@ static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[]
if (dim + 1 < totdim) {
/* check that a sequence contains dimsize[dim] items */
const int seq_size= PySequence_Size(seq);
if(seq_size == -1) {
PyErr_Format(PyExc_ValueError, "%s sequence expected at dimension %d, not %s", error_prefix, (int)dim + 1, Py_TYPE(seq)->tp_name);
return 0;
}
for (i= 0; i < seq_size; i++) {
PyObject *item;
int ok= 1;
@@ -91,6 +104,10 @@ static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[]
else {
/* check that items are of correct type */
const int seq_size= PySequence_Size(seq);
if(seq_size == -1) {
PyErr_Format(PyExc_ValueError, "%s sequence expected at dimension %d, not %s", error_prefix, (int)dim + 1, Py_TYPE(seq)->tp_name);
return 0;
}
for (i= 0; i < seq_size; i++) {
PyObject *item= PySequence_GetItem(seq, i);
@@ -137,7 +154,7 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA
int tot, totdim, len;
totdim= RNA_property_array_dimension(ptr, prop, dimsize);
tot= count_items(rvalue, totdim);
tot= count_items(rvalue, totdim - lvalue_dim);
if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) {
if (RNA_property_array_length(ptr, prop) != tot) {
@@ -170,16 +187,16 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA
/* arr[3][4][5]
arr[2] = x
arr[2]= x
dimsize={4, 5}
dimsize[1] = 4
dimsize[2] = 5
dimsize[1]= 4
dimsize[2]= 5
lvalue_dim=0, totdim=3
arr[2][3] = x
arr[2][3]= x
lvalue_dim=1
arr[2][3][4] = x
arr[2][3][4]= x
lvalue_dim=2 */
for (i= lvalue_dim; i < totdim; i++)
len *= dimsize[i];
@@ -217,7 +234,7 @@ static char *copy_value_single(PyObject *item, PointerRNA *ptr, PropertyRNA *pro
convert_item(item, value);
rna_set_index(ptr, prop, *index, value);
*index = *index + 1;
*index= *index + 1;
}
else {
convert_item(item, data);
@@ -233,6 +250,8 @@ static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, int
int totdim= RNA_property_array_dimension(ptr, prop, NULL);
const int seq_size= PySequence_Size(seq);
assert(seq_size != -1);
for (i= 0; i < seq_size; i++) {
PyObject *item= PySequence_GetItem(seq, i);
@@ -301,11 +320,11 @@ static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, i
/* arr[3][4][5]
arr[2] = x
lvalue_dim=0, index = 0 + 2 * 4 * 5
arr[2]= x
lvalue_dim=0, index= 0 + 2 * 4 * 5
arr[2][3] = x
lvalue_dim=1, index = 40 + 3 * 5 */
arr[2][3]= x
lvalue_dim=1, index= 40 + 3 * 5 */
lvalue_dim++;
@@ -485,7 +504,7 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr,
BPy_PropertyArrayRNA *ret= NULL;
arraydim= self ? self->arraydim : 0;
arrayoffset = self ? self->arrayoffset : 0;
arrayoffset= self ? self->arrayoffset : 0;
/* just in case check */
len= RNA_property_multi_array_length(ptr, prop, arraydim);
@@ -505,11 +524,11 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr,
/* arr[3][4][5]
x = arr[2]
index = 0 + 2 * 4 * 5
x= arr[2]
index= 0 + 2 * 4 * 5
x = arr[2][3]
index = offset + 3 * 5 */
x= arr[2][3]
index= offset + 3 * 5 */
for (i= arraydim + 1; i < totdim; i++)
index *= dimsize[i];
@@ -517,7 +536,7 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr,
ret->arrayoffset= arrayoffset + index;
}
else {
index = arrayoffset + index;
index= arrayoffset + index;
ret= (BPy_PropertyArrayRNA *)pyrna_array_index(ptr, prop, index);
}

View File

@@ -22,8 +22,15 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_rna_callback.c
* \ingroup pythonintern
*/
#include <Python.h>
#include "RNA_types.h"
#include "bpy_rna.h"
#include "bpy_rna_callback.h"
#include "bpy_util.h"
@@ -32,6 +39,8 @@
#include "DNA_screen_types.h"
#include "RNA_access.h"
#include "BKE_context.h"
#include "ED_space_api.h"
@@ -48,7 +57,7 @@ static void cb_region_draw(const bContext *C, ARegion *UNUSED(ar), void *customd
cb_func= PyTuple_GET_ITEM((PyObject *)customdata, 0);
cb_args= PyTuple_GET_ITEM((PyObject *)customdata, 1);
result = PyObject_CallObject(cb_func, cb_args);
result= PyObject_CallObject(cb_func, cb_args);
if(result) {
Py_DECREF(result);
@@ -79,7 +88,7 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
if(cb_event_str) {
static EnumPropertyItem region_draw_mode_items[] = {
static EnumPropertyItem region_draw_mode_items[]= {
{REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
{REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Post View", ""},
{REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},

View File

@@ -22,6 +22,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_rna_callback.h
* \ingroup pythonintern
*/
struct BPy_StructRNA;
struct PyObject;

View File

@@ -20,6 +20,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_traceback.c
* \ingroup pythonintern
*/
#include <Python.h>
#include <frameobject.h>
@@ -72,7 +77,8 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
*offset = -1;
Py_DECREF(v);
v = NULL;
} else {
}
else {
hold = PyLong_AsLong(v);
Py_DECREF(v);
v = NULL;

View File

@@ -20,6 +20,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_traceback.h
* \ingroup pythonintern
*/
#ifndef BPY_TRACEBACK_H
#define BPY_TRACEBACK_H

View File

@@ -22,6 +22,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_util.c
* \ingroup pythonintern
*/
#include <Python.h>
#include "bpy_util.h"
@@ -32,7 +37,7 @@
#include "../generic/py_capi_utils.h"
static bContext* __py_context = NULL;
static bContext* __py_context= NULL;
bContext* BPy_GetContext(void) { return __py_context; }
void BPy_SetContext(bContext *C) { __py_context= C; }
@@ -47,12 +52,12 @@ char *BPy_enum_as_string(EnumPropertyItem *item)
BLI_dynstr_appendf(dynstr, (e==item)?"'%s'":", '%s'", item->identifier);
}
cstring = BLI_dynstr_get_cstring(dynstr);
cstring= BLI_dynstr_get_cstring(dynstr);
BLI_dynstr_free(dynstr);
return cstring;
}
short BPy_reports_to_error(ReportList *reports, const short clear)
short BPy_reports_to_error(ReportList *reports, PyObject *exception, const short clear)
{
char *report_str;
@@ -63,11 +68,11 @@ short BPy_reports_to_error(ReportList *reports, const short clear)
}
if(report_str) {
PyErr_SetString(PyExc_RuntimeError, report_str);
PyErr_SetString(exception, report_str);
MEM_freeN(report_str);
}
return (report_str != NULL);
return (report_str == NULL) ? 0 : -1;
}
@@ -141,19 +146,19 @@ int PyC_AsArray(void *array, PyObject *value, int length, PyTypeObject *type, co
if(type == &PyFloat_Type) {
float *array_float= array;
for(i=0; i<length; i++) {
array_float[i] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
array_float[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
}
}
else if(type == &PyLong_Type) {
int *array_int= array;
for(i=0; i<length; i++) {
array_int[i] = PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i));
array_int[i]= PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i));
}
}
else if(type == &PyBool_Type) {
int *array_bool= array;
for(i=0; i<length; i++) {
array_bool[i] = (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i)) != 0);
array_bool[i]= (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i)) != 0);
}
}
else {

View File

@@ -22,11 +22,16 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_util.h
* \ingroup pythonintern
*/
#ifndef BPY_UTIL_H
#define BPY_UTIL_H
#if PY_VERSION_HEX < 0x03010000
#error "Python versions below 3.1 are not supported anymore, you'll need to update your python."
#if PY_VERSION_HEX < 0x03020000
#error "Python 3.2 or greater is required, you'll need to update your python."
#endif
#include "RNA_types.h" /* for EnumPropertyItem only */
@@ -39,7 +44,7 @@ char *BPy_enum_as_string(struct EnumPropertyItem *item);
#define BLANK_PYTHON_TYPE {PyVarObject_HEAD_INIT(NULL, 0) NULL}
/* error reporting */
short BPy_reports_to_error(struct ReportList *reports, const short clear);
short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const short clear);
short BPy_errors_to_report(struct ReportList *reports);
/* TODO - find a better solution! */

View File

@@ -26,6 +26,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/stubs.c
* \ingroup pythonintern
*/
/* python, will come back */
//void BPY_script_exec(void) {}
//void BPY_python_start(void) {}