From c9f1ca961aaedfce52cfd9608b4a908087b8b3ef Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 22 Dec 2011 08:44:08 +0000 Subject: fix for matrix assignment with recent changes which broke for eg: ob.matrix_world = matrix --- source/blender/python/intern/bpy_rna_array.c | 69 ++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) (limited to 'source') diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c index 1d1cab1c66d..2a4c004d84c 100644 --- a/source/blender/python/intern/bpy_rna_array.c +++ b/source/blender/python/intern/bpy_rna_array.c @@ -36,6 +36,12 @@ #include "RNA_access.h" +#define USE_MATHUTILS + +#ifdef USE_MATHUTILS +# include "../mathutils/mathutils.h" /* so we can have mathutils callbacks */ +#endif + #define MAX_ARRAY_DIMENSION 10 typedef void (*ItemConvertFunc)(PyObject *, char *); @@ -259,10 +265,47 @@ static int validate_array(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, /* 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) == -1) - return -1; - return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix); +#ifdef USE_MATHUTILS + if (lvalue_dim == 0) { /* only valid for first level array */ + if (MatrixObject_Check(rvalue)) { + MatrixObject *pymat= (MatrixObject *)rvalue; + + if (BaseMath_ReadCallback(pymat) == -1) + return -1; + + if (RNA_property_type(prop) != PROP_FLOAT) { + PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, matrix assign to non float array", + error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop)); + return -1; + } + else if (totdim != 2) { + PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, matrix assign array with %d dimensions", + error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), totdim); + return -1; + } + else if (pymat->num_col != dimsize[0] || pymat->num_row != dimsize[1]) { + PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, matrix assign dimension size mismatch, " + "is %dx%d, expected be %dx%d", + error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), + pymat->num_col, pymat->num_row, dimsize[0], dimsize[1]); + return -1; + } + else { + *totitem= dimsize[0] * dimsize[1]; + return 0; + } + } + } +#endif /* USE_MATHUTILS */ + + + { + if (validate_array_type(rvalue, lvalue_dim, totdim, dimsize, check_item_type, item_type_str, error_prefix) == -1) + return -1; + + return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix); + } } static char *copy_value_single(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, @@ -305,6 +348,26 @@ static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, return NULL; } + +#ifdef USE_MATHUTILS + if (dim == 0) { + if (MatrixObject_Check(seq)) { + MatrixObject *pymat= (MatrixObject *)seq; + size_t allocsize= pymat->num_col * pymat->num_row * sizeof(float); + + /* read callback already done by validate */ + /* since this is the first iteration we can assume data is allocated */ + memcpy(data, pymat->matrix, allocsize); + + /* not really needed but do for completeness */ + data += allocsize; + + return data; + } + } +#endif /* USE_MATHUTILS */ + + for (i= 0; i < seq_size; i++) { PyObject *item= PySequence_GetItem(seq, i); if (item) { -- cgit v1.2.3