Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArystanbek Dyussenov <arystan.d@gmail.com>2009-09-11 22:09:58 +0400
committerArystanbek Dyussenov <arystan.d@gmail.com>2009-09-11 22:09:58 +0400
commit3b2ad838e8c628a468ee19ac77fb1336dd6072cf (patch)
treebc1e229f3055e4114086775122c7a47facb42679 /source/blender/python
parent7220792f187f91a2ef3eb0c930a13674b2a8a80a (diff)
parent15d77f17a40398a63f95e16607deb81257c02698 (diff)
Merge with -r 22620:23107.
Next: update scripts and merge in 2.5.
Diffstat (limited to 'source/blender/python')
-rw-r--r--source/blender/python/CMakeLists.txt16
-rw-r--r--source/blender/python/SConscript4
-rw-r--r--source/blender/python/epy_doc_gen.py212
-rw-r--r--source/blender/python/generic/bpy_internal_import.h9
-rw-r--r--source/blender/python/generic/matrix.c43
-rw-r--r--source/blender/python/generic/vector.c50
-rw-r--r--source/blender/python/intern/bpy_array.c515
-rw-r--r--source/blender/python/intern/bpy_interface.c43
-rw-r--r--source/blender/python/intern/bpy_operator.c35
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c4
-rw-r--r--source/blender/python/intern/bpy_rna.c529
-rw-r--r--source/blender/python/intern/bpy_rna.h12
-rw-r--r--source/blender/python/intern/bpy_util.c38
-rw-r--r--source/blender/python/intern/bpy_util.h2
14 files changed, 1086 insertions, 426 deletions
diff --git a/source/blender/python/CMakeLists.txt b/source/blender/python/CMakeLists.txt
index 7700e6bc2aa..7abec566505 100644
--- a/source/blender/python/CMakeLists.txt
+++ b/source/blender/python/CMakeLists.txt
@@ -27,23 +27,23 @@ FILE(GLOB SRC intern/*.c)
FILE(GLOB GENSRC generic/*.c)
SET(INC
- . ../../../intern/guardedalloc ../blenlib ../makesdna ../makesrna
- ../blenkernel ../editors/include ../windowmanager ${PYTHON_INC}
- ../../../extern/glew/include
+ . ../../../intern/guardedalloc ../blenlib ../makesdna ../makesrna
+ ../blenkernel ../editors/include ../windowmanager ${PYTHON_INC}
+ ../../../extern/glew/include
)
IF(WITH_OPENEXR)
- ADD_DEFINITIONS(-DWITH_OPENEXR)
+ ADD_DEFINITIONS(-DWITH_OPENEXR)
ENDIF(WITH_OPENEXR)
IF(WITH_QUICKTIME)
- SET(INC ${INC} ${QUICKTIME_INC})
- ADD_DEFINITIONS(-DWITH_QUICKTIME)
+ SET(INC ${INC} ${QUICKTIME_INC})
+ ADD_DEFINITIONS(-DWITH_QUICKTIME)
ENDIF(WITH_QUICKTIME)
IF(WITH_FFMPEG)
- SET(INC ${INC} ${FFMPEG_INC})
- ADD_DEFINITIONS(-DWITH_FFMPEG)
+ SET(INC ${INC} ${FFMPEG_INC})
+ ADD_DEFINITIONS(-DWITH_FFMPEG)
ENDIF(WITH_FFMPEG)
ADD_DEFINITIONS(-DWITH_CCGSUBSURF)
diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript
index d44cf762a0f..ca742a3646a 100644
--- a/source/blender/python/SConscript
+++ b/source/blender/python/SConscript
@@ -13,9 +13,9 @@ defs = []
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'], priority = [140])
+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_gen_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [361]) # ketsji is 360
+env.BlenderLib( libname = 'bf_gen_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [362,165]) # ketsji is 360
diff --git a/source/blender/python/epy_doc_gen.py b/source/blender/python/epy_doc_gen.py
index 6a515648340..c2ef6bbc0d0 100644
--- a/source/blender/python/epy_doc_gen.py
+++ b/source/blender/python/epy_doc_gen.py
@@ -37,6 +37,94 @@ Generate html docs by running...
# if you dont have graphvis installed ommit the --graph arg.
+# GLOBALS['BASEDIR'] = './source/blender/python/doc'
+
+import os
+
+SUBMODULES = {}
+INIT_SUBMODULES = {} # store initialized files
+
+INIT_SUBMODULES_IMPORTS = {} # dont import the same module twice
+
+def append_package(package_path, mod_name):
+
+ init_path = os.path.join(os.path.dirname(package_path), "__init__.py")
+
+ # avoid double ups
+ if mod_name:
+ imports = INIT_SUBMODULES_IMPORTS.setdefault(init_path, [])
+ if mod_name in imports:
+ return
+ imports.append(mod_name)
+
+ try:
+ os.makedirs(os.path.dirname(init_path)) # make the dirs if they are not there
+ except:
+ pass
+
+ # Open the new file for the first time, otherwise keep it open.
+ f = INIT_SUBMODULES.get(init_path)
+ if f == None:
+ f = INIT_SUBMODULES[init_path] = open(init_path, 'w')
+
+ if mod_name:
+ f.write("import %s\n" % mod_name)
+
+ return f
+
+def append_package_recursive(package_path, BASEPATH):
+ '''
+ assume the last item of package_path will be a file (not a dir thats created)
+ '''
+
+ package_path = os.path.splitext(package_path)[0] # incase of .py
+
+ try:
+ os.makedirs(os.path.join(BASEPATH, os.path.dirname(package_path))) # make the dirs if they are not there
+ except:
+ pass
+
+ new_path = BASEPATH
+
+ for mod_name in package_path.split(os.sep):
+ init_path = os.path.join(new_path, "__init__.py")
+ new_path = os.path.join(new_path, mod_name)
+ append_package(init_path, mod_name)
+
+
+def open_submodule(subpath, BASEPATH):
+ '''
+ This is a utility function that lets us quickly add submodules
+ '''
+
+ # create all the package paths leading up to this module
+ append_package_recursive(subpath, BASEPATH)
+
+ module_name = os.path.basename( os.path.splitext(subpath)[0] )
+ mod_path = os.path.join(BASEPATH, subpath)
+
+ # Open the new file for the first time, otherwise keep it open.
+ f = SUBMODULES.get(mod_path)
+ if f == None:
+ f = SUBMODULES[mod_path] = open(mod_path, 'w')
+
+ f = open(mod_path, 'w')
+ return f
+
+def close_all():
+ for files in (INIT_SUBMODULES.values(), SUBMODULES.values()):
+ for f in files:
+ if f.name.endswith('.py'):
+ f_name = f.name
+ f.close()
+
+ f = open(f_name, 'a')
+ f.write("\ndel __package__\n") # annoying, no need do show this
+
+
+ f.close()
+
+
def range_str(val):
if val < -10000000: return '-inf'
if val > 10000000: return 'inf'
@@ -59,6 +147,19 @@ def full_rna_struct_path(rna_struct):
else:
return rna_struct.identifier
+def rna_id_ignore(rna_id):
+ if rna_id == "rna_type":
+ return True
+
+ if "_OT_" in rna_id:
+ return True
+ if "_MT_" in rna_id:
+ return True
+ if "_PT_" in rna_id:
+ return True
+
+ return False
+
def write_func(rna, ident, out, func_type):
# Keyword attributes
kw_args = [] # "foo = 1", "bar=0.5", "spam='ENUM'"
@@ -68,7 +169,7 @@ def write_func(rna, ident, out, func_type):
# Operators and functions work differently
if func_type=='OPERATOR':
- rna_func_name = rna_struct.identifier
+ rna_func_name = rna_struct.identifier.split("_OT_")[-1]
rna_func_desc = rna_struct.description.strip()
items = rna_struct.properties.items()
else:
@@ -78,7 +179,7 @@ def write_func(rna, ident, out, func_type):
for rna_prop_identifier, rna_prop in items:
- if rna_prop_identifier=='rna_type':
+ if rna_id_ignore(rna_prop_identifier):
continue
# clear vars
@@ -196,7 +297,7 @@ def write_func(rna, ident, out, func_type):
-def rna2epy(target_path):
+def rna2epy(BASEPATH):
# Use for faster lookups
# use rna_struct.identifier as the key for each dict
@@ -255,7 +356,7 @@ def rna2epy(target_path):
for rna_prop_identifier, rna_prop in rna_struct.properties.items():
if rna_prop_identifier=='RNA': continue
- if rna_prop_identifier=='rna_type': continue
+ if rna_id_ignore(rna_prop_identifier): continue
if rna_prop_identifier in rna_base_prop_keys: continue # does this prop exist in our parent class, if so skip
rna_desc = rna_prop.description.strip()
@@ -320,7 +421,10 @@ def rna2epy(target_path):
for child in rna_children_dict[identifier]:
write_struct(child, ident + '\t')
- out = open(target_path, 'w')
+
+
+ # out = open(target_path, 'w')
+ out = open_submodule("types.py", BASEPATH) # bpy.types
def base_id(rna_struct):
try: return rna_struct.base.identifier
@@ -343,21 +447,23 @@ def rna2epy(target_path):
#if not rna_type_name.startswith('__'):
identifier = rna_struct.identifier
- structs.append( (base_id(rna_struct), identifier, rna_struct) )
-
- # Simple lookup
- rna_struct_dict[identifier] = rna_struct
-
- # Store full rna path 'GameObjectSettings' -> 'Object.GameObjectSettings'
- rna_full_path_dict[identifier] = full_rna_struct_path(rna_struct)
-
- # Store a list of functions, remove inherited later
- rna_functions_dict[identifier]= list(rna_struct.functions)
-
- # fill in these later
- rna_children_dict[identifier]= []
- rna_references_dict[identifier]= []
+ if not rna_id_ignore(identifier):
+ structs.append( (base_id(rna_struct), identifier, rna_struct) )
+
+ # Simple lookup
+ rna_struct_dict[identifier] = rna_struct
+
+ # Store full rna path 'GameObjectSettings' -> 'Object.GameObjectSettings'
+ rna_full_path_dict[identifier] = full_rna_struct_path(rna_struct)
+
+ # Store a list of functions, remove inherited later
+ rna_functions_dict[identifier]= list(rna_struct.functions)
+
+
+ # fill in these later
+ rna_children_dict[identifier]= []
+ rna_references_dict[identifier]= []
else:
@@ -417,7 +523,7 @@ def rna2epy(target_path):
for rna_prop_identifier, rna_prop in rna_struct.properties.items():
if rna_prop_identifier=='RNA': continue
- if rna_prop_identifier=='rna_type': continue
+ if rna_id_ignore(rna_prop_identifier): continue
if rna_prop_identifier in rna_base_prop_keys: continue
try: rna_prop_ptr = rna_prop.fixed_type
@@ -431,7 +537,7 @@ def rna2epy(target_path):
for rna_prop_identifier, rna_prop in rna_func.parameters.items():
if rna_prop_identifier=='RNA': continue
- if rna_prop_identifier=='rna_type': continue
+ if rna_id_ignore(rna_prop_identifier): continue
if rna_prop_identifier in rna_base_func_keys: continue
@@ -476,6 +582,7 @@ def rna2epy(target_path):
# # We could also just run....
# os.system('epydoc source/blender/python/doc/rna.py -o ./source/blender/python/doc/html -v')
+ target_path = os.path.join(BASEPATH, "dump.py") # XXX - used for other funcs
# Write graphviz
out= open(target_path.replace('.py', '.dot'), 'w')
@@ -546,8 +653,8 @@ def rna2epy(target_path):
out.write('%s\n' % w)
-def op2epy(target_path):
- out = open(target_path, 'w')
+def op2epy(BASEPATH):
+ # out = open(target_path, 'w')
op_mods = dir(bpy.ops)
op_mods.remove('add')
@@ -556,26 +663,73 @@ def op2epy(target_path):
for op_mod_name in sorted(op_mods):
if op_mod_name.startswith('__'):
continue
+
+ # open the submodule
+ mod_path = os.path.join("ops", op_mod_name + ".py")
+ out = open_submodule(mod_path, BASEPATH)
+
op_mod = getattr(bpy.ops, op_mod_name)
-
operators = dir(op_mod)
for op in sorted(operators):
# rna = getattr(bpy.types, op).__rna__
rna = getattr(op_mod, op).get_rna()
write_func(rna, '', out, 'OPERATOR')
+
+ out.write('\n')
+ out.close()
+
+def misc2epy(BASEPATH):
+ '''
+ Hard coded modules, try to avoid adding stuff here
+ '''
- out.write('\n')
- out.close()
+ f = append_package(os.path.join(BASEPATH, ""), ""); # add a slash on the end of the base path
+ f.write('''
+"""
+@type data: L{bpy.types.Main}
+@var data: blender data is accessed from here
+"""
+''')
+
+ f = open_submodule("props.py", BASEPATH)
+ f.write('''
+MAX_INT= 2**31
+MAX_FLOAT= 1e+37
+def BoolProperty(attr, name="", description="", default=False):
+ """
+ return a new bool property
+ """
+def IntProperty(attr, name="", description="", min=-MAX_INT, max=MAX_INT, soft_min=-MAX_INT, soft_max=MAX_INT, default=0):
+ """
+ return a new int property
+ """
+def FloatProperty(attr, name="", description="", min=-MAX_FLOAT, max=MAX_FLOAT, soft_min=-MAX_FLOAT, soft_max=MAX_FLOAT, default=0.0):
+ """
+ return a new float property
+ """
+def StringProperty(attr, name="", description="", maxlen=0, default=""):
+ """
+ return a new string property
+ """
+def EnumProperty(attr, items, name="", description="", default=""):
+ """
+ return a new enum property
+ """
+''')
+
if __name__ == '__main__':
if 'bpy' not in dir():
print("\nError, this script must run from inside blender2.5")
print(script_help_msg)
-
else:
- rna2epy('source/blender/python/doc/rna.py')
- op2epy('source/blender/python/doc/bpyoperator.py')
+ misc2epy('source/blender/python/doc/bpy') # first to write in info in some of the modules.
+ rna2epy('source/blender/python/doc/bpy')
+ op2epy('source/blender/python/doc/bpy')
+
+
+ close_all()
import sys
sys.exit()
diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h
index c93d930dab0..4e761fe8da0 100644
--- a/source/blender/python/generic/bpy_internal_import.h
+++ b/source/blender/python/generic/bpy_internal_import.h
@@ -31,6 +31,15 @@
#ifndef EXPP_bpy_import_h
#define EXPP_bpy_import_h
+/* python redefines :/ */
+#ifdef _POSIX_C_SOURCE
+#undef _POSIX_C_SOURCE
+#endif
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
#include <Python.h>
#include "compile.h" /* for the PyCodeObject */
#include "eval.h" /* for PyEval_EvalCode */
diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c
index be3e704460a..edb6fb7af63 100644
--- a/source/blender/python/generic/matrix.c
+++ b/source/blender/python/generic/matrix.c
@@ -598,18 +598,18 @@ static PyObject *Matrix_repr(MatrixObject * self)
return NULL;
BLI_strncpy(str,"",1024);
- for(x = 0; x < self->rowSize; x++){
+ for(x = 0; x < self->colSize; x++){
sprintf(buffer, "[");
strcat(str,buffer);
- for(y = 0; y < (self->colSize - 1); y++) {
- sprintf(buffer, "%.6f, ", self->matrix[x][y]);
+ for(y = 0; y < (self->rowSize - 1); y++) {
+ sprintf(buffer, "%.6f, ", self->matrix[y][x]);
strcat(str,buffer);
}
- if(x < (self->rowSize-1)){
- sprintf(buffer, "%.6f](matrix [row %d])\n", self->matrix[x][y], x);
+ if(x < (self->colSize-1)){
+ sprintf(buffer, "%.6f](matrix [row %d])\n", self->matrix[y][x], x);
strcat(str,buffer);
}else{
- sprintf(buffer, "%.6f](matrix [row %d])", self->matrix[x][y], x);
+ sprintf(buffer, "%.6f](matrix [row %d])", self->matrix[y][x], x);
strcat(str,buffer);
}
}
@@ -703,7 +703,7 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob)
return -1;
if(i >= self->rowSize || i < 0){
- PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad row\n");
+ PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad column\n");
return -1;
}
@@ -933,21 +933,21 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
}
if(mat1 && mat2) { /*MATRIX * MATRIX*/
- if(mat1->colSize != mat2->rowSize){
+ if(mat1->rowSize != mat2->colSize){
PyErr_SetString(PyExc_AttributeError,"Matrix multiplication: matrix A rowsize must equal matrix B colsize");
return NULL;
}
- for(x = 0; x < mat1->rowSize; x++) {
- for(y = 0; y < mat2->colSize; y++) {
- for(z = 0; z < mat1->colSize; z++) {
- dot += (mat1->matrix[x][z] * mat2->matrix[z][y]);
+ for(x = 0; x < mat2->rowSize; x++) {
+ for(y = 0; y < mat1->colSize; y++) {
+ for(z = 0; z < mat1->rowSize; z++) {
+ dot += (mat1->matrix[z][y] * mat2->matrix[x][z]);
}
- mat[((x * mat1->rowSize) + y)] = (float)dot;
+ mat[((x * mat1->colSize) + y)] = (float)dot;
dot = 0.0f;
}
}
- return newMatrixObject(mat, mat1->rowSize, mat2->colSize, Py_NEW, NULL);
+ return newMatrixObject(mat, mat2->rowSize, mat1->colSize, Py_NEW, NULL);
}
if(mat1==NULL){
@@ -1288,9 +1288,9 @@ PyObject *newMatrixObject_cb(PyObject *cb_user, int rowSize, int colSize, int cb
//----------------column_vector_multiplication (internal)---------
//COLUMN VECTOR Multiplication (Matrix X Vector)
-// [1][2][3] [a]
-// [4][5][6] * [b]
-// [7][8][9] [c]
+// [1][4][7] [a]
+// [2][5][8] * [b]
+// [3][6][9] [c]
//vector/matrix multiplication IS NOT COMMUTATIVE!!!!
static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec)
{
@@ -1312,11 +1312,12 @@ static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject*
for(x = 0; x < vec->size; x++){
vecCopy[x] = vec->vec[x];
- }
+ }
+ vecNew[3] = 1.0f;
- for(x = 0; x < mat->rowSize; x++) {
- for(y = 0; y < mat->colSize; y++) {
- dot += mat->matrix[x][y] * vecCopy[y];
+ for(x = 0; x < mat->colSize; z++) {
+ for(y = 0; y < mat->rowSize; y++) {
+ dot += mat->matrix[y][x] * vecCopy[y];
}
vecNew[z++] = (float)dot;
dot = 0.0f;
diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c
index 923c4bbe58a..605f45be128 100644
--- a/source/blender/python/generic/vector.c
+++ b/source/blender/python/generic/vector.c
@@ -168,7 +168,7 @@ static PyObject *Vector_Resize2D(VectorObject * self)
return NULL;
}
if(self->cb_user) {
- PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner");
+ PyErr_SetString(PyExc_TypeError, "vector.resize2d(): cannot resize a vector that has an owner");
return NULL;
}
@@ -191,7 +191,7 @@ static PyObject *Vector_Resize3D(VectorObject * self)
return NULL;
}
if(self->cb_user) {
- PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner");
+ PyErr_SetString(PyExc_TypeError, "vector.resize3d(): cannot resize a vector that has an owner");
return NULL;
}
@@ -354,18 +354,12 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
/*----------------------------Vector.reflect(mirror) ----------------------
return a reflected vector on the mirror normal
- ((2 * DotVecs(vec, mirror)) * mirror) - vec
- using arithb.c would be nice here */
+ vec - ((2 * DotVecs(vec, mirror)) * mirror)
+*/
static PyObject *Vector_Reflect( VectorObject * self, VectorObject * value )
{
- float mirror[3];
- float vec[3];
- float reflect[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- float dot2;
-
- /* for normalizing */
- int i;
- float norm = 0.0f;
+ float mirror[3], vec[3];
+ float reflect[3] = {0.0f, 0.0f, 0.0f};
if (!VectorObject_Check(value)) {
PyErr_SetString( PyExc_TypeError, "vec.reflect(value): expected a vector argument" );
@@ -380,26 +374,12 @@ static PyObject *Vector_Reflect( VectorObject * self, VectorObject * value )
if (value->size > 2) mirror[2] = value->vec[2];
else mirror[2] = 0.0;
- /* normalize, whos idea was it not to use arithb.c? :-/ */
- for(i = 0; i < 3; i++) {
- norm += mirror[i] * mirror[i];
- }
- norm = (float) sqrt(norm);
- for(i = 0; i < 3; i++) {
- mirror[i] /= norm;
- }
- /* done */
-
vec[0] = self->vec[0];
vec[1] = self->vec[1];
if (self->size > 2) vec[2] = self->vec[2];
else vec[2] = 0.0;
- dot2 = 2 * vec[0]*mirror[0]+vec[1]*mirror[1]+vec[2]*mirror[2];
-
- reflect[0] = (dot2 * mirror[0]) - vec[0];
- reflect[1] = (dot2 * mirror[1]) - vec[1];
- reflect[2] = (dot2 * mirror[2]) - vec[2];
+ VecReflect(reflect, vec, mirror);
return newVectorObject(reflect, self->size, Py_NEW, NULL);
}
@@ -1955,9 +1935,9 @@ PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_su
//-----------------row_vector_multiplication (internal)-----------
//ROW VECTOR Multiplication - Vector X Matrix
-//[x][y][z] * [1][2][3]
-// [4][5][6]
-// [7][8][9]
+//[x][y][z] * [1][4][7]
+// [2][5][8]
+// [3][6][9]
//vector/matrix multiplication IS NOT COMMUTATIVE!!!!
static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat)
{
@@ -1966,7 +1946,7 @@ static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat
int x, y, z = 0, vec_size = vec->size;
if(mat->colSize != vec_size){
- if(mat->rowSize == 4 && vec_size != 3){
+ 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 NULL;
}else{
@@ -1980,11 +1960,11 @@ static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat
for(x = 0; x < vec_size; x++){
vecCopy[x] = vec->vec[x];
}
-
+ vecNew[3] = 1.0f;
//muliplication
- for(x = 0; x < mat->colSize; x++) {
- for(y = 0; y < mat->rowSize; y++) {
- dot += mat->matrix[y][x] * vecCopy[y];
+ for(x = 0; x < mat->rowSize; x++) {
+ for(y = 0; y < mat->colSize; y++) {
+ dot += mat->matrix[x][y] * vecCopy[y];
}
vecNew[z++] = (float)dot;
dot = 0.0f;
diff --git a/source/blender/python/intern/bpy_array.c b/source/blender/python/intern/bpy_array.c
new file mode 100644
index 00000000000..f11c95e7ed5
--- /dev/null
+++ b/source/blender/python/intern/bpy_array.c
@@ -0,0 +1,515 @@
+/**
+ *
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contributor(s): Arystanbek Dyussenov
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "Python.h"
+
+#include "bpy_rna.h"
+
+#include "RNA_access.h"
+
+#include "BLI_string.h"
+
+#include "BKE_global.h"
+
+#include "MEM_guardedalloc.h"
+
+#define MAX_ARRAY_DIMENSION 10
+
+typedef void (*ItemConvertFunc)(PyObject *, char *);
+typedef int (*ItemTypeCheckFunc)(PyObject *);
+typedef void (*RNA_SetArrayFunc)(PointerRNA *, PropertyRNA *, const char *);
+typedef void (*RNA_SetIndexFunc)(PointerRNA *, PropertyRNA *, int index, void *);
+
+/*
+ arr[3][4][5]
+ 0 1 2 <- dimension index
+*/
+
+/*
+ arr[2] = x
+
+ py_to_array_index(arraydim=0, arrayoffset=0, index=2)
+ validate_array(lvalue_dim=0)
+ ... make real index ...
+*/
+
+/* arr[3]=x, self->arraydim is 0, lvalue_dim is 1 */
+/* Ensures that a python sequence has expected number of items/sub-items and items are of desired type. */
+static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[],
+ ItemTypeCheckFunc check_item_type, const char *item_type_str, const char *error_prefix)
+{
+ int i;
+
+ /* not the last dimension */
+ if (dim + 1 < totdim) {
+ /* check that a sequence contains dimsize[dim] items */
+
+ for (i= 0; i < PySequence_Length(seq); i++) {
+ PyObject *item;
+ int ok= 1;
+ item= PySequence_GetItem(seq, i);
+
+ if (!PySequence_Check(item)) {
+ /* BLI_snprintf(error_str, error_str_size, "expected a sequence of %s", item_type_str); */
+ PyErr_Format(PyExc_TypeError, "%s expected a sequence of %s", error_prefix, item_type_str);
+ ok= 0;
+ }
+ /* arr[3][4][5]
+ dimsize[1]=4
+ dimsize[2]=5
+
+ dim=0 */
+ else if (PySequence_Length(item) != dimsize[dim + 1]) {
+ /* BLI_snprintf(error_str, error_str_size, "sequences of dimension %d should contain %d items", (int)dim + 1, (int)dimsize[dim + 1]); */
+ PyErr_Format(PyExc_ValueError, "%s sequences of dimension %d should contain %d items", error_prefix, (int)dim + 1, (int)dimsize[dim + 1]);
+ ok= 0;
+ }
+ else if (!validate_array_type(item, dim + 1, totdim, dimsize, check_item_type, item_type_str, error_prefix)) {
+ ok= 0;
+ }
+
+ Py_DECREF(item);
+
+ if (!ok)
+ return 0;
+ }
+ }
+ else {
+ /* check that items are of correct type */
+ for (i= 0; i < PySequence_Length(seq); i++) {
+ PyObject *item= PySequence_GetItem(seq, i);
+
+ if (!check_item_type(item)) {
+ Py_DECREF(item);
+
+ /* BLI_snprintf(error_str, error_str_size, "sequence items should be of type %s", item_type_str); */
+ PyErr_Format(PyExc_TypeError, "sequence items should be of type %s", item_type_str);
+ return 0;
+ }
+
+ Py_DECREF(item);
+ }
+ }
+
+ return 1;
+}
+
+/* Returns the number of items in a single- or multi-dimensional sequence. */
+static int count_items(PyObject *seq)
+{
+ int totitem= 0;
+
+ if (PySequence_Check(seq)) {
+ int i;
+ for (i= 0; i < PySequence_Length(seq); i++) {
+ PyObject *item= PySequence_GetItem(seq, i);
+ totitem += count_items(item);
+ Py_DECREF(item);
+ }
+ }
+ else
+ totitem= 1;
+
+ return totitem;
+}
+
+/* Modifies property array length if needed and PROP_DYNAMIC flag is set. */
+static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int *totitem, const char *error_prefix)
+{
+ int dimsize[MAX_ARRAY_DIMENSION];
+ int tot, totdim, len;
+
+ tot= count_items(rvalue);
+ totdim= RNA_property_array_dimension(ptr, prop, dimsize);
+
+ if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) {
+ if (RNA_property_array_length(ptr, prop) != tot) {
+#if 0
+ /* length is flexible */
+ if (!RNA_property_dynamic_array_set_length(ptr, prop, tot)) {
+ /* BLI_snprintf(error_str, error_str_size, "%s.%s: array length cannot be changed to %d", RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); */
+ PyErr_Format(PyExc_ValueError, "%s %s.%s: array length cannot be changed to %d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot);
+ return 0;
+ }
+#else
+ PyErr_Format(PyExc_ValueError, "%s %s.%s: array length cannot be changed to %d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot);
+ return 0;
+#endif
+ }
+
+ len= tot;
+ }
+ else {
+ /* length is a constraint */
+ if (!lvalue_dim) {
+ len= RNA_property_array_length(ptr, prop);
+ }
+ /* array item assignment */
+ else {
+ int i;
+
+ len= 1;
+
+ /* arr[3][4][5]
+
+ arr[2] = x
+ dimsize={4, 5}
+ dimsize[1] = 4
+ dimsize[2] = 5
+ lvalue_dim=0, totdim=3
+
+ arr[2][3] = x
+ lvalue_dim=1
+
+ arr[2][3][4] = x
+ lvalue_dim=2 */
+ for (i= lvalue_dim; i < totdim; i++)
+ len *= dimsize[i];
+ }
+
+ if (tot != len) {
+ /* BLI_snprintf(error_str, error_str_size, "sequence must have length of %d", len); */
+ PyErr_Format(PyExc_ValueError, "%s sequence must have %d items total", error_prefix, len);
+ return 0;
+ }
+ }
+
+ *totitem= len;
+
+ return 1;
+}
+
+static int validate_array(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, ItemTypeCheckFunc check_item_type, const char *item_type_str, int *totitem, const char *error_prefix)
+{
+ int dimsize[MAX_ARRAY_DIMENSION];
+ int totdim= RNA_property_array_dimension(ptr, prop, dimsize);
+
+ /* validate type first because length validation may modify property array length */
+
+ if (!validate_array_type(rvalue, lvalue_dim, totdim, dimsize, check_item_type, item_type_str, error_prefix))
+ return 0;
+
+ return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix);
+}
+
+static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, int dim, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index)
+{
+ unsigned int i;
+ int totdim= RNA_property_array_dimension(ptr, prop, NULL);
+
+ for (i= 0; i < PySequence_Length(seq); i++) {
+ PyObject *item= PySequence_GetItem(seq, i);
+
+ if (dim + 1 < totdim) {
+ data= copy_values(item, ptr, prop, dim + 1, data, item_size, index, convert_item, rna_set_index);
+ }
+ else {
+ if (!data) {
+ char value[sizeof(int)];
+
+ convert_item(item, value);
+ rna_set_index(ptr, prop, *index, value);
+ *index = *index + 1;
+ }
+ else {
+ convert_item(item, data);
+ data += item_size;
+ }
+ }
+
+ Py_DECREF(item);
+ }
+
+ return data;
+}
+
+static int py_to_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size, ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array, const char *error_prefix)
+{
+ int totdim, dim_size[MAX_ARRAY_DIMENSION];
+ int totitem;
+ char *data= NULL;
+
+ totdim= RNA_property_array_dimension(ptr, prop, dim_size);
+
+ if (!validate_array(py, ptr, prop, 0, check_item_type, item_type_str, &totitem, error_prefix)) {
+ return 0;
+ }
+
+ if (totitem) {
+ if (!param_data || RNA_property_flag(prop) & PROP_DYNAMIC)
+ data= MEM_callocN(item_size * totitem, "pyrna primitive type array");
+ else
+ data= param_data;
+
+ copy_values(py, ptr, prop, 0, data, item_size, NULL, convert_item, NULL);
+
+ if (param_data) {
+ if (RNA_property_flag(prop) & PROP_DYNAMIC) {
+ /* not freeing allocated mem, RNA_parameter_list_free will do this */
+ *(char**)param_data= data;
+ }
+ }
+ else {
+ /* NULL can only pass through in case RNA property arraylength is 0 (impossible?) */
+ rna_set_array(ptr, prop, data);
+ MEM_freeN(data);
+ }
+ }
+
+ return 1;
+}
+
+static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int arrayoffset, int index, ItemTypeCheckFunc check_item_type, const char *item_type_str, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index, const char *error_prefix)
+{
+ int totdim, dimsize[MAX_ARRAY_DIMENSION];
+ int totitem, i;
+
+ totdim= RNA_property_array_dimension(ptr, prop, dimsize);
+
+ /* convert index */
+
+ /* arr[3][4][5]
+
+ arr[2] = x
+ lvalue_dim=0, index = 0 + 2 * 4 * 5
+
+ arr[2][3] = x
+ lvalue_dim=1, index = 40 + 3 * 5 */
+
+ lvalue_dim++;
+
+ for (i= lvalue_dim; i < totdim; i++)
+ index *= dimsize[i];
+
+ index += arrayoffset;
+
+ if (!validate_array(py, ptr, prop, lvalue_dim, check_item_type, item_type_str, &totitem, error_prefix))
+ return 0;
+
+ if (totitem)
+ copy_values(py, ptr, prop, lvalue_dim, NULL, 0, &index, convert_item, rna_set_index);
+
+ return 1;
+}
+
+static void py_to_float(PyObject *py, char *data)
+{
+ *(float*)data= (float)PyFloat_AsDouble(py);
+}
+
+static void py_to_int(PyObject *py, char *data)
+{
+ *(int*)data= (int)PyLong_AsSsize_t(py);
+}
+
+static void py_to_bool(PyObject *py, char *data)
+{
+ *(int*)data= (int)PyObject_IsTrue(py);
+}
+
+static int py_float_check(PyObject *py)
+{
+ /* accept both floats and integers */
+ return PyFloat_Check(py) || PyLong_Check(py);
+}
+
+static int py_int_check(PyObject *py)
+{
+ /* accept only integers */
+ return PyLong_Check(py);
+}
+
+static int py_bool_check(PyObject *py)
+{
+ return PyBool_Check(py);
+}
+
+static void float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value)
+{
+ RNA_property_float_set_index(ptr, prop, index, *(float*)value);
+}
+
+static void int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value)
+{
+ RNA_property_int_set_index(ptr, prop, index, *(int*)value);
+}
+
+static void bool_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value)
+{
+ RNA_property_boolean_set_index(ptr, prop, index, *(int*)value);
+}
+
+int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix)
+{
+ int ret;
+ switch (RNA_property_type(prop)) {
+ case PROP_FLOAT:
+ ret= py_to_array(py, ptr, prop, param_data, py_float_check, "float", sizeof(float), py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array, error_prefix);
+ break;
+ case PROP_INT:
+ ret= py_to_array(py, ptr, prop, param_data, py_int_check, "int", sizeof(int), py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array, error_prefix);
+ break;
+ case PROP_BOOLEAN:
+ ret= py_to_array(py, ptr, prop, param_data, py_bool_check, "boolean", sizeof(int), py_to_bool, (RNA_SetArrayFunc)RNA_property_boolean_set_array, error_prefix);
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "not an array type");
+ ret= 0;
+ }
+
+ return ret;
+}
+
+int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix)
+{
+ int ret;
+ switch (RNA_property_type(prop)) {
+ case PROP_FLOAT:
+ ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_float_check, "float", py_to_float, float_set_index, error_prefix);
+ break;
+ case PROP_INT:
+ ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_int_check, "int", py_to_int, int_set_index, error_prefix);
+ break;
+ case PROP_BOOLEAN:
+ ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_bool_check, "boolean", py_to_bool, bool_set_index, error_prefix);
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "not an array type");
+ ret= 0;
+ }
+
+ return ret;
+}
+
+static PyObject *pyrna_array_item(PointerRNA *ptr, PropertyRNA *prop, int index)
+{
+ PyObject *item;
+
+ switch (RNA_property_type(prop)) {
+ case PROP_FLOAT:
+ item= PyFloat_FromDouble(RNA_property_float_get_index(ptr, prop, index));
+ break;
+ case PROP_BOOLEAN:
+ item= PyBool_FromLong(RNA_property_boolean_get_index(ptr, prop, index));
+ break;
+ case PROP_INT:
+ item= PyLong_FromSsize_t(RNA_property_int_get_index(ptr, prop, index));
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "not an array type");
+ item= NULL;
+ }
+
+ return item;
+}
+
+#if 0
+/* XXX this is not used (and never will?) */
+/* Given an array property, creates an N-dimensional tuple of values. */
+static PyObject *pyrna_py_from_array_internal(PointerRNA *ptr, PropertyRNA *prop, int dim, int *index)
+{
+ PyObject *tuple;
+ int i, len;
+ int totdim= RNA_property_array_dimension(ptr, prop, NULL);
+
+ len= RNA_property_multi_array_length(ptr, prop, dim);
+
+ tuple= PyTuple_New(len);
+
+ for (i= 0; i < len; i++) {
+ PyObject *item;
+
+ if (dim + 1 < totdim)
+ item= pyrna_py_from_array_internal(ptr, prop, dim + 1, index);
+ else {
+ item= pyrna_array_item(ptr, prop, *index);
+ *index= *index + 1;
+ }
+
+ if (!item) {
+ Py_DECREF(tuple);
+ return NULL;
+ }
+
+ PyTuple_SetItem(tuple, i, item);
+ }
+
+ return tuple;
+}
+#endif
+
+PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index)
+{
+ int totdim, i, len;
+ int dimsize[MAX_ARRAY_DIMENSION];
+ BPy_PropertyRNA *ret= NULL;
+
+ /* just in case check */
+ len= RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
+ if (index >= len || index < 0) {
+ /* this shouldn't happen because higher level funcs must check for invalid index */
+ if (G.f & G_DEBUG) printf("pyrna_py_from_array_index: invalid index %d for array with length=%d\n", index, len);
+
+ PyErr_SetString(PyExc_IndexError, "out of range");
+ return NULL;
+ }
+
+ totdim= RNA_property_array_dimension(&self->ptr, self->prop, dimsize);
+
+ if (self->arraydim + 1 < totdim) {
+ ret= (BPy_PropertyRNA*)pyrna_prop_CreatePyObject(&self->ptr, self->prop);
+ ret->arraydim= self->arraydim + 1;
+
+ /* arr[3][4][5]
+
+ x = arr[2]
+ index = 0 + 2 * 4 * 5
+
+ x = arr[2][3]
+ index = offset + 3 * 5 */
+
+ for (i= self->arraydim + 1; i < totdim; i++)
+ index *= dimsize[i];
+
+ ret->arrayoffset= self->arrayoffset + index;
+ }
+ else {
+ index = self->arrayoffset + index;
+ ret= (BPy_PropertyRNA*)pyrna_array_item(&self->ptr, self->prop, index);
+ }
+
+ return (PyObject*)ret;
+}
+
+PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop)
+{
+ PyObject *ret;
+
+ ret= pyrna_math_object_from_array(ptr, prop);
+
+ /* is this a maths object? */
+ if (ret) return ret;
+
+ return pyrna_prop_CreatePyObject(ptr, prop);
+}
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index ae2f4244eac..3e089fffe6c 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -1,13 +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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contributor(s): Michel Selten, Willian P. Germano, Stephen Swaney,
+ * Chris Keith, Chris Want, Ken Hughes, Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
-#ifndef WIN32
-#include <dirent.h>
-#else
-#include "BLI_winstuff.h"
+
+/* grr, python redefines */
+#ifdef _POSIX_C_SOURCE
+#undef _POSIX_C_SOURCE
#endif
#include <Python.h>
@@ -20,6 +44,12 @@
#include "bpy_sys.h"
#include "bpy_util.h"
+#ifndef WIN32
+#include <dirent.h>
+#else
+#include "BLI_winstuff.h"
+#endif
+
#include "DNA_anim_types.h"
#include "DNA_space_types.h"
#include "DNA_text_types.h"
@@ -27,6 +57,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_util.h"
+#include "BLI_storage.h"
#include "BLI_fileops.h"
#include "BLI_string.h"
@@ -592,7 +623,7 @@ void BPY_run_ui_scripts(bContext *C, int reload)
}
}
#ifndef __linux__
- else if( BLI_join_dirfile(path, dirname, de->d_name), S_ISDIR(BLI_exists(path))) {
+ else if( BLI_join_dirfile(path, dirname, de->d_name), S_ISDIR(BLI_exist(path))) {
#else
else if(de->d_type==DT_DIR) {
BLI_join_dirfile(path, dirname, de->d_name);
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index e431f2a21e9..062db42e0e9 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -40,42 +40,23 @@
#include "BKE_utildefines.h"
-/* 'self' stores the operator string */
static PyObject *pyop_call( PyObject * self, PyObject * args)
{
wmOperatorType *ot;
int error_val = 0;
PointerRNA ptr;
- char *opname;
- PyObject *kw= NULL;
+ char *opname;
+ PyObject *kw= NULL; /* optional args */
+
+ /* note that context is an int, python does the conversion in this case */
+ int context= WM_OP_EXEC_DEFAULT;
// XXX Todo, work out a better solution for passing on context, could make a tuple from self and pack the name and Context into it...
bContext *C = BPy_GetContext();
-
- switch(PyTuple_Size(args)) {
- case 2:
- kw = PyTuple_GET_ITEM(args, 1);
-
- if(!PyDict_Check(kw)) {
- PyErr_SetString( PyExc_AttributeError, "bpy.__ops__.call: expected second arg to be a dict");
- return NULL;
- }
- /* pass through */
- case 1:
- opname = _PyUnicode_AsString(PyTuple_GET_ITEM(args, 0));
-
- if(opname==NULL) {
- PyErr_SetString( PyExc_AttributeError, "bpy.__ops__.call: expected the first arg to be a string");
- return NULL;
- }
- break;
- default:
- PyErr_SetString( PyExc_AttributeError, "bpy.__ops__.call: expected a string and optional dict");
+ if (!PyArg_ParseTuple(args, "s|O!i:bpy.__ops__.call", &opname, &PyDict_Type, &kw, &context))
return NULL;
- }
-
ot= WM_operatortype_find(opname, TRUE);
@@ -88,7 +69,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
PyErr_SetString( PyExc_SystemError, "bpy.__ops__.call: operator poll() function failed, context is incorrect");
return NULL;
}
-
+
/* WM_operator_properties_create(&ptr, opname); */
/* Save another lookup */
RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
@@ -102,7 +83,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
BKE_reports_init(&reports, RPT_STORE);
- WM_operator_call_py(C, ot, &ptr, &reports);
+ WM_operator_call_py(C, ot, context, &ptr, &reports);
if(BPy_reports_to_error(&reports))
error_val = -1;
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 9a74bf0aee8..0a487a8dbe8 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -228,7 +228,7 @@ static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
return PYTHON_OT_generic(PYOP_INVOKE, C, op, event);
}
-static int PYTHON_OT_exec(bContext *C, wmOperator *op)
+static int PYTHON_OT_execute(bContext *C, wmOperator *op)
{
return PYTHON_OT_generic(PYOP_EXEC, C, op, NULL);
}
@@ -268,7 +268,7 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
if (PyObject_HasAttrString(py_class, "invoke"))
ot->invoke= PYTHON_OT_invoke;
if (PyObject_HasAttrString(py_class, "execute"))
- ot->exec= PYTHON_OT_exec;
+ ot->exec= PYTHON_OT_execute;
if (PyObject_HasAttrString(py_class, "poll"))
ot->poll= PYTHON_OT_poll;
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 0f031318446..8395e5c82e4 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -130,6 +130,70 @@ Mathutils_Callback mathutils_rna_matrix_cb = {
(BaseMathSetIndexFunc) NULL
};
+PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
+{
+ PyObject *ret= NULL;
+
+#ifdef USE_MATHUTILS
+ int type, subtype, totdim;
+ int len;
+
+ len= RNA_property_array_length(ptr, prop);
+ type= RNA_property_type(prop);
+ subtype= RNA_property_subtype(prop);
+ totdim= RNA_property_array_dimension(ptr, prop, NULL);
+
+ if (type != PROP_FLOAT) return NULL;
+
+ if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) {
+ ret = pyrna_prop_CreatePyObject(ptr, prop);
+
+ switch(RNA_property_subtype(prop)) {
+ case PROP_TRANSLATION:
+ case PROP_DIRECTION:
+ case PROP_VELOCITY:
+ case PROP_ACCELERATION:
+ case PROP_XYZ:
+ if(len>=2 && len <= 4) {
+ PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, FALSE);
+ Py_DECREF(ret); /* the vector owns now */
+ ret= vec_cb; /* return the vector instead */
+ }
+ break;
+ case PROP_MATRIX:
+ if(len==16) {
+ PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE);
+ Py_DECREF(ret); /* the matrix owns now */
+ ret= mat_cb; /* return the matrix instead */
+ }
+ else if (len==9) {
+ PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE);
+ Py_DECREF(ret); /* the matrix owns now */
+ ret= mat_cb; /* return the matrix instead */
+ }
+ break;
+ case PROP_EULER:
+ case PROP_QUATERNION:
+ if(len==3) { /* euler */
+ PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
+ Py_DECREF(ret); /* the matrix owns now */
+ ret= eul_cb; /* return the matrix instead */
+ }
+ else if (len==4) {
+ PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
+ Py_DECREF(ret); /* the matrix owns now */
+ ret= quat_cb; /* return the matrix instead */
+ }
+ break;
+ default:
+ break;
+ }
+ }
+#endif
+
+ return ret;
+}
+
#endif
static StructRNA *pyrna_struct_as_srna(PyObject *self);
@@ -144,25 +208,64 @@ static int pyrna_prop_compare( BPy_PropertyRNA * a, BPy_PropertyRNA * b )
return (a->prop==b->prop && a->ptr.data==b->ptr.data ) ? 0 : -1;
}
-/* For some reason python3 needs these :/ */
-static PyObject *pyrna_struct_richcmp(BPy_StructRNA * a, BPy_StructRNA * b, int op)
+static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
{
- int cmp_result= -1; /* assume false */
- if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) {
- cmp_result= pyrna_struct_compare(a, b);
+ PyObject *res;
+ int ok= -1; /* zero is true */
+
+ if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b))
+ ok= pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b);
+
+ switch (op) {
+ case Py_NE:
+ ok = !ok; /* pass through */
+ case Py_EQ:
+ res = ok ? Py_False : Py_True;
+ break;
+
+ case Py_LT:
+ case Py_LE:
+ case Py_GT:
+ case Py_GE:
+ res = Py_NotImplemented;
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
}
- return Py_CmpToRich(op, cmp_result);
+ Py_INCREF(res);
+ return res;
}
-static PyObject *pyrna_prop_richcmp(BPy_PropertyRNA * a, BPy_PropertyRNA * b, int op)
+static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
{
- int cmp_result= -1; /* assume false */
- if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) {
- cmp_result= pyrna_prop_compare(a, b);
+ PyObject *res;
+ int ok= -1; /* zero is true */
+
+ if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b))
+ ok= pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b);
+
+ switch (op) {
+ case Py_NE:
+ ok = !ok; /* pass through */
+ case Py_EQ:
+ res = ok ? Py_False : Py_True;
+ break;
+
+ case Py_LT:
+ case Py_LE:
+ case Py_GT:
+ case Py_GE:
+ res = Py_NotImplemented;
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
}
- return Py_CmpToRich(op, cmp_result);
+ Py_INCREF(res);
+ return res;
}
/*----------------------repr--------------------------------------------*/
@@ -267,61 +370,10 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
{
PyObject *ret;
int type = RNA_property_type(prop);
- int len = RNA_property_array_length(prop);
+ int len = RNA_property_array_length(ptr, prop);
if (len > 0) {
- /* resolve the array from a new pytype */
- PyObject *ret = pyrna_prop_CreatePyObject(ptr, prop);
-
-#ifdef USE_MATHUTILS
-
- /* return a mathutils vector where possible */
- if(RNA_property_type(prop)==PROP_FLOAT) {
- switch(RNA_property_subtype(prop)) {
- case PROP_TRANSLATION:
- case PROP_DIRECTION:
- case PROP_VELOCITY:
- case PROP_ACCELERATION:
- case PROP_XYZ:
- if(len>=2 && len <= 4) {
- PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, FALSE);
- Py_DECREF(ret); /* the vector owns now */
- ret= vec_cb; /* return the vector instead */
- }
- break;
- case PROP_MATRIX:
- if(len==16) {
- PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE);
- Py_DECREF(ret); /* the matrix owns now */
- ret= mat_cb; /* return the matrix instead */
- }
- else if (len==9) {
- PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE);
- Py_DECREF(ret); /* the matrix owns now */
- ret= mat_cb; /* return the matrix instead */
- }
- break;
- case PROP_EULER:
- case PROP_QUATERNION:
- if(len==3) { /* euler */
- PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
- Py_DECREF(ret); /* the matrix owns now */
- ret= eul_cb; /* return the matrix instead */
- }
- else if (len==4) {
- PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
- Py_DECREF(ret); /* the matrix owns now */
- ret= quat_cb; /* return the matrix instead */
- }
- break;
- default:
- break;
- }
- }
-
-#endif
-
- return ret;
+ return pyrna_py_from_array(ptr, prop);
}
/* see if we can coorce into a python type - PropertyType */
@@ -490,128 +542,32 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
{
/* XXX hard limits should be checked here */
int type = RNA_property_type(prop);
- int len = RNA_property_array_length(prop);
+ int len = RNA_property_array_length(ptr, prop);
if (len > 0) {
- PyObject *item;
- int py_len = -1;
- int i;
-
+ /* char error_str[512]; */
+ int ok= 1;
#ifdef USE_MATHUTILS
if(MatrixObject_Check(value)) {
MatrixObject *mat = (MatrixObject*)value;
if(!BaseMath_ReadCallback(mat))
return -1;
-
- py_len = mat->rowSize * mat->colSize;
} else /* continue... */
#endif
- if (PySequence_Check(value)) {
- py_len= (int)PySequence_Length(value);
- }
- else {
+ if (!PySequence_Check(value)) {
PyErr_Format(PyExc_TypeError, "%.200s RNA array assignment expected a sequence instead of %.200s instance.", error_prefix, Py_TYPE(value)->tp_name);
return -1;
}
/* done getting the length */
-
- if (py_len != len) {
- PyErr_Format(PyExc_TypeError, "%.200s python sequence length %d did not match the RNA array length %d.", error_prefix, py_len, len);
- return -1;
- }
-
- /* for arrays we have a limited number of types */
- switch (type) {
- case PROP_BOOLEAN:
- {
- int *param_arr;
- if(data) param_arr= (int*)data;
- else param_arr= MEM_mallocN(sizeof(int) * len, "pyrna bool array");
-
-
- /* collect the variables before assigning, incase one of them is incorrect */
- for (i=0; i<len; i++) {
- item = PySequence_GetItem(value, i);
- param_arr[i] = PyObject_IsTrue( item );
- Py_DECREF(item);
-
- if (param_arr[i] < 0) {
- if(data==NULL)
- MEM_freeN(param_arr);
- PyErr_Format(PyExc_AttributeError, "%.200s one or more of the values in the sequence is not a boolean", error_prefix);
- return -1;
- }
- }
- if(data==NULL) {
- RNA_property_boolean_set_array(ptr, prop, param_arr);
- MEM_freeN(param_arr);
- }
-
- break;
- }
- case PROP_INT:
- {
- int *param_arr;
- if(data) param_arr= (int*)data;
- else param_arr= MEM_mallocN(sizeof(int) * len, "pyrna int array");
+ ok= pyrna_py_to_array(ptr, prop, data, value, error_prefix);
-
- /* collect the variables */
- for (i=0; i<len; i++) {
- item = PySequence_GetItem(value, i);
- param_arr[i] = (int)PyLong_AsSsize_t(item); /* deal with any errors later */
- Py_DECREF(item);
- }
-
- if (PyErr_Occurred()) {
- if(data==NULL)
- MEM_freeN(param_arr);
- PyErr_Format(PyExc_AttributeError, "%.200s one or more of the values in the sequence could not be used as an int", error_prefix);
- return -1;
- }
- if(data==NULL) {
- RNA_property_int_set_array(ptr, prop, param_arr);
- MEM_freeN(param_arr);
- }
- break;
- }
- case PROP_FLOAT:
- {
- float *param_arr;
- if(data) param_arr = (float*)data;
- else param_arr = MEM_mallocN(sizeof(float) * len, "pyrna float array");
-
-
-#ifdef USE_MATHUTILS
- if(MatrixObject_Check(value) && RNA_property_subtype(prop) == PROP_MATRIX) {
- MatrixObject *mat = (MatrixObject*)value;
- memcpy(param_arr, mat->contigPtr, sizeof(float) * len);
- } else /* continue... */
-#endif
- {
- /* collect the variables */
- for (i=0; i<len; i++) {
- item = PySequence_GetItem(value, i);
- param_arr[i] = (float)PyFloat_AsDouble(item); /* deal with any errors later */
- Py_DECREF(item);
- }
- }
-
- if (PyErr_Occurred()) {
- if(data==NULL)
- MEM_freeN(param_arr);
- PyErr_Format(PyExc_AttributeError, "%.200s one or more of the values in the sequence could not be used as a float", error_prefix);
- return -1;
- }
- if(data==NULL) {
- RNA_property_float_set_array(ptr, prop, param_arr);
- MEM_freeN(param_arr);
- }
- break;
- }
+ if (!ok) {
+ /* PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str); */
+ return -1;
}
- } else {
+ }
+ else {
/* Normal Property (not an array) */
/* see if we can coorce into a python type - PropertyType */
@@ -809,82 +765,84 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
return 0;
}
-static PyObject * pyrna_prop_to_py_index(PointerRNA *ptr, PropertyRNA *prop, int index)
+static PyObject * pyrna_prop_to_py_index(BPy_PropertyRNA *self, int index)
{
- PyObject *ret;
- int type = RNA_property_type(prop);
-
- /* see if we can coorce into a python type - PropertyType */
- switch (type) {
- case PROP_BOOLEAN:
- ret = PyBool_FromLong( RNA_property_boolean_get_index(ptr, prop, index) );
- break;
- case PROP_INT:
- ret = PyLong_FromSsize_t( (Py_ssize_t)RNA_property_int_get_index(ptr, prop, index) );
- break;
- case PROP_FLOAT:
- ret = PyFloat_FromDouble( RNA_property_float_get_index(ptr, prop, index) );
- break;
- default:
- PyErr_SetString(PyExc_AttributeError, "not an array type");
- ret = NULL;
- break;
- }
-
- return ret;
+ return pyrna_py_from_array_index(self, index);
}
-static int pyrna_py_to_prop_index(PointerRNA *ptr, PropertyRNA *prop, int index, PyObject *value)
+static int pyrna_py_to_prop_index(BPy_PropertyRNA *self, int index, PyObject *value)
{
int ret = 0;
+ int totdim;
+ PointerRNA *ptr= &self->ptr;
+ PropertyRNA *prop= self->prop;
int type = RNA_property_type(prop);
-
- /* see if we can coorce into a python type - PropertyType */
- switch (type) {
- case PROP_BOOLEAN:
- {
- int param = PyObject_IsTrue( value );
-
- if( param < 0 ) {
- PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
- ret = -1;
- } else {
- RNA_property_boolean_set_index(ptr, prop, index, param);
- }
- break;
- }
- case PROP_INT:
- {
- int param = PyLong_AsSsize_t(value);
- if (PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError, "expected an int type");
- ret = -1;
- } else {
- RNA_property_int_set_index(ptr, prop, index, param);
+
+ totdim= RNA_property_array_dimension(ptr, prop, NULL);
+
+ if (totdim > 1) {
+ /* char error_str[512]; */
+ if (!pyrna_py_to_array_index(&self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "")) {
+ /* PyErr_SetString(PyExc_AttributeError, error_str); */
+ ret= -1;
}
- break;
}
- case PROP_FLOAT:
- {
- float param = PyFloat_AsDouble(value);
- if (PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError, "expected a float type");
+ else {
+ /* see if we can coorce into a python type - PropertyType */
+ switch (type) {
+ case PROP_BOOLEAN:
+ {
+ int param = PyObject_IsTrue( value );
+
+ if( param < 0 ) {
+ PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
+ ret = -1;
+ } else {
+ RNA_property_boolean_set_index(ptr, prop, index, param);
+ }
+ break;
+ }
+ case PROP_INT:
+ {
+ int param = PyLong_AsSsize_t(value);
+ if (PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError, "expected an int type");
+ ret = -1;
+ } else {
+ RNA_property_int_set_index(ptr, prop, index, param);
+ }
+ break;
+ }
+ case PROP_FLOAT:
+ {
+ float param = PyFloat_AsDouble(value);
+ if (PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError, "expected a float type");
+ ret = -1;
+ } else {
+ RNA_property_float_set_index(ptr, prop, index, param);
+ }
+ break;
+ }
+ default:
+ PyErr_SetString(PyExc_AttributeError, "not an array type");
ret = -1;
- } else {
- RNA_property_float_set_index(ptr, prop, index, param);
+ break;
}
- break;
- }
- default:
- PyErr_SetString(PyExc_AttributeError, "not an array type");
- ret = -1;
- break;
}
return ret;
}
//---------------sequence-------------------------------------------
+static int pyrna_prop_array_length(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_len( BPy_PropertyRNA * self )
{
Py_ssize_t len;
@@ -892,10 +850,10 @@ static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self )
if (RNA_property_type(self->prop) == PROP_COLLECTION) {
len = RNA_property_collection_length(&self->ptr, self->prop);
} else {
- len = RNA_property_array_length(self->prop);
+ len = pyrna_prop_array_length(self);
if (len==0) { /* not an array*/
- PyErr_SetString(PyExc_AttributeError, "len() only available for collection RNA types");
+ PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types");
return -1;
}
}
@@ -916,14 +874,15 @@ static PyObject *prop_subscript_collection_int(BPy_PropertyRNA * self, int keynu
PyErr_Format(PyExc_IndexError, "index %d out of range", keynum);
return NULL;
}
+
static PyObject *prop_subscript_array_int(BPy_PropertyRNA * self, int keynum)
{
- int len= RNA_property_array_length(self->prop);
+ int len= pyrna_prop_array_length(self);
if(keynum < 0) keynum += len;
if(keynum >= 0 && keynum < len)
- return pyrna_prop_to_py_index(&self->ptr, self->prop, keynum);
+ return pyrna_prop_to_py_index(self, keynum);
PyErr_Format(PyExc_IndexError, "index %d out of range", keynum);
return NULL;
@@ -970,7 +929,7 @@ static PyObject *prop_subscript_array_slice(BPy_PropertyRNA * self, int start, i
start = MIN2(start,stop); /* values are clamped from PySlice_GetIndicesEx */
for(count = start; count < stop; count++)
- PyList_SetItem(list, count - start, pyrna_prop_to_py_index(&self->ptr, self->prop, count));
+ PyList_SetItem(list, count - start, pyrna_prop_to_py_index(self, count));
return list;
}
@@ -1023,8 +982,8 @@ static PyObject *prop_subscript_array(BPy_PropertyRNA * self, PyObject *key)
return prop_subscript_array_int(self, PyLong_AsSsize_t(key));
}
else if (PySlice_Check(key)) {
- int len= RNA_property_array_length(self->prop);
Py_ssize_t start, stop, step, slicelength;
+ int len = pyrna_prop_array_length(self);
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
return NULL;
@@ -1050,13 +1009,12 @@ static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key )
{
if (RNA_property_type(self->prop) == PROP_COLLECTION) {
return prop_subscript_collection(self, key);
- } else if (RNA_property_array_length(self->prop)) { /* arrays are currently fixed length, zero length means its not an array */
+ } else if (RNA_property_array_length(&self->ptr, self->prop)) { /* zero length means its not an array */
return prop_subscript_array(self, key);
- } else {
- PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection");
- return NULL;
- }
+ }
+ PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection");
+ return NULL;
}
static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int end, PyObject *value)
@@ -1067,7 +1025,7 @@ static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int
begin = MIN2(begin,end);
for(count = begin; count < end; count++) {
- if(pyrna_py_to_prop_index(&self->ptr, self->prop, count - begin, value) == -1) {
+ if(pyrna_py_to_prop_index(self, count - begin, value) == -1) {
/* TODO - this is wrong since some values have been assigned... will need to fix that */
return -1; /* pyrna_struct_CreatePyObject should set the error */
}
@@ -1078,13 +1036,12 @@ static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int
static int prop_subscript_ass_array_int(BPy_PropertyRNA * self, int keynum, PyObject *value)
{
-
- int len= RNA_property_array_length(self->prop);
+ int len= pyrna_prop_array_length(self);
if(keynum < 0) keynum += len;
if(keynum >= 0 && keynum < len)
- return pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value);
+ return pyrna_py_to_prop_index(self, keynum, value);
PyErr_SetString(PyExc_IndexError, "out of range");
return -1;
@@ -1113,7 +1070,7 @@ static int pyrna_prop_ass_subscript( BPy_PropertyRNA * self, PyObject *key, PyOb
return prop_subscript_ass_array_int(self, i, value);
}
else if (PySlice_Check(key)) {
- int len= RNA_property_array_length(self->prop);
+ int len= RNA_property_array_length(&self->ptr, self->prop);
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
@@ -1526,7 +1483,7 @@ static void foreach_attr_type( BPy_PropertyRNA *self, char *attr,
RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
prop = RNA_struct_find_property(&itemptr, attr);
*raw_type= RNA_property_raw_type(prop);
- *attr_tot = RNA_property_array_length(prop);
+ *attr_tot = RNA_property_array_length(&itemptr, prop);
*attr_signed= (RNA_property_subtype(prop)==PROP_UNSIGNED) ? FALSE:TRUE;
break;
}
@@ -1565,7 +1522,7 @@ static int foreach_parse_args(
if (RNA_property_type(self->prop) == PROP_COLLECTION)
array_tot = RNA_property_collection_length(&self->ptr, self->prop);
else
- array_tot = RNA_property_array_length(self->prop);
+ array_tot = RNA_property_array_length(&self->ptr, self->prop);
target_tot= array_tot * (*attr_tot);
@@ -1758,7 +1715,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
if (ret==NULL) {
/* collection did not work, try array */
- int len = RNA_property_array_length(self->prop);
+ int len = pyrna_prop_array_length(self);
if (len) {
int i;
@@ -1766,7 +1723,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
ret = PyList_New(len);
for (i=0; i < len; i++) {
- PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(&self->ptr, self->prop, i));
+ PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i));
}
}
}
@@ -1849,7 +1806,7 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
{
PyObject *ret;
int type = RNA_property_type(prop);
- int len = RNA_property_array_length(prop);
+ int len = RNA_property_array_length(ptr, prop);
int a;
@@ -1858,7 +1815,7 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
ret = PyTuple_New(len);
/* for return values, data is a pointer to an array, not first element pointer */
- if (RNA_property_flag(prop) & PROP_DYNAMIC_ARRAY)
+ if (RNA_property_flag(prop) & PROP_DYNAMIC)
data = *(char**)(char*)data;
switch (type) {
@@ -2525,6 +2482,9 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
pyrna->ptr = *ptr;
pyrna->prop = prop;
+
+ pyrna->arraydim= 0;
+ pyrna->arrayoffset= 0;
return ( PyObject * ) pyrna;
}
@@ -2689,8 +2649,17 @@ PyObject *BPY_rna_props( void )
static StructRNA *pyrna_struct_as_srna(PyObject *self)
{
- BPy_StructRNA *py_srna= (BPy_StructRNA*)PyObject_GetAttrString(self, "__rna__");
+ BPy_StructRNA *py_srna;
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, "__rna__");
+ Py_XINCREF(py_srna);
+ }
+
+ if(py_srna==NULL)
+ py_srna = (BPy_StructRNA*)PyObject_GetAttrString(self, "__rna__");
if(py_srna==NULL) {
PyErr_SetString(PyExc_SystemError, "internal error, self had no __rna__ attribute, should never happen.");
@@ -2965,12 +2934,12 @@ static StructRNA *pointer_type_from_py(PyObject *value)
srna= srna_from_self(value);
if(!srna) {
- PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup (1)");
+ PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup");
return NULL;
}
if(!RNA_struct_is_a(srna, &RNA_IDPropertyGroup)) {
- PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup (3)");
+ PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup");
return NULL;
}
@@ -3047,6 +3016,52 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
+static int deferred_register_props(PyObject *py_class, StructRNA *srna)
+{
+ PyObject *props, *dummy_args, *item;
+ int i;
+
+ props= PyObject_GetAttrString(py_class, "__props__");
+
+ if(!props) {
+ PyErr_Clear();
+ return 1;
+ }
+
+ dummy_args = PyTuple_New(0);
+
+ for(i=0; i<PyList_Size(props); i++) {
+ PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
+ item = PyList_GET_ITEM(props, i);
+
+ if(PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
+ PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
+ pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
+ py_srna_cobject = PyCObject_FromVoidPtr(srna, NULL);
+
+ py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
+ Py_DECREF(py_srna_cobject);
+
+ if(py_ret) {
+ Py_DECREF(py_ret);
+ }
+ else {
+ Py_DECREF(dummy_args);
+ return 0;
+ }
+ }
+ else {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_AttributeError, "expected list of dicts for __props__.");
+ Py_DECREF(dummy_args);
+ return 0;
+ }
+ }
+
+ Py_DECREF(dummy_args);
+ return 1;
+}
+
/*-------------------- Type Registration ------------------------*/
static int rna_function_arg_count(FunctionRNA *func)
@@ -3407,6 +3422,9 @@ PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class)
// Py_DECREF(py_class); // shuld be able to do this XXX since the old rna adds a new ref.
}
+ if(!deferred_register_props(py_class, srna_new))
+ return NULL;
+
Py_RETURN_NONE;
}
@@ -3430,7 +3448,6 @@ PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *py_class)
/* get the context, so register callback can do necessary refreshes */
C= BPy_GetContext();
-
/* call unregister */
unreg(C, srna); /* calls bpy_class_free, this decref's py_class */
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index 1b8d69bc511..d006b168f45 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -55,6 +55,10 @@ typedef struct {
PyObject_HEAD /* required python macro */
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_PropertyRNA;
/* cheap trick */
@@ -91,4 +95,12 @@ PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *args);
void pyrna_alloc_types(void);
void pyrna_free_types(void);
+/* primitive type conversion */
+int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix);
+int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix);
+
+PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop);
+PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index);
+PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop);
+
#endif
diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c
index 924d1dbf06a..7e35d51bb6d 100644
--- a/source/blender/python/intern/bpy_util.c
+++ b/source/blender/python/intern/bpy_util.c
@@ -127,44 +127,6 @@ int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag)
return 0; /* ok */
}
-
-/* Copied from pythons 3's Object.c */
-PyObject *
-Py_CmpToRich(int op, int cmp)
-{
- PyObject *res;
- int ok;
-
- if (PyErr_Occurred())
- return NULL;
- switch (op) {
- case Py_LT:
- ok = cmp < 0;
- break;
- case Py_LE:
- ok = cmp <= 0;
- break;
- case Py_EQ:
- ok = cmp == 0;
- break;
- case Py_NE:
- ok = cmp != 0;
- break;
- case Py_GT:
- ok = cmp > 0;
- break;
- case Py_GE:
- ok = cmp >= 0;
- break;
- default:
- PyErr_BadArgument();
- return NULL;
- }
- res = ok ? Py_True : Py_False;
- Py_INCREF(res);
- return res;
-}
-
/* for debugging */
void PyObSpit(char *name, PyObject *var) {
fprintf(stderr, "<%s> : ", name);
diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h
index 0400d595520..83fa7a5b7c4 100644
--- a/source/blender/python/intern/bpy_util.h
+++ b/source/blender/python/intern/bpy_util.h
@@ -50,8 +50,6 @@ void PyObSpit(char *name, PyObject *var);
void PyLineSpit(void);
void BPY_getFileAndNum(char **filename, int *lineno);
-PyObject *Py_CmpToRich(int op, int cmp);
-
PyObject *BPY_exception_buffer(void);
/* own python like utility function */