/** * Use with PyArg_ParseTuple's "O&" formatting. */ static int pygpu_offscreen_check_matrix(PyObject *o, void *p) { MatrixObject **pymat_p = p; MatrixObject *pymat = (MatrixObject *)o; if (!MatrixObject_Check(pymat)) { PyErr_Format(PyExc_TypeError, "expected a mathutils.Matrix, not a %.200s", Py_TYPE(o)->tp_name); return 0; } if (BaseMath_ReadCallback(pymat) == -1) { return 0; } if ((pymat->num_col != 4) || (pymat->num_row != 4)) { PyErr_SetString(PyExc_ValueError, "matrix must be 4x4"); return 0; } *pymat_p = pymat; 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 */ #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); } }
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix) { if (EulerObject_Check(value)) { if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } else { eulO_to_mat3(rmat, ((EulerObject *)value)->eul, ((EulerObject *)value)->order); return 0; } } else if (QuaternionObject_Check(value)) { if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } else { float tquat[4]; normalize_qt_qt(tquat, ((QuaternionObject *)value)->quat); quat_to_mat3(rmat, tquat); return 0; } } else if (MatrixObject_Check(value)) { if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } else if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) { PyErr_Format( PyExc_ValueError, "%.200s: matrix must have minimum 3x3 dimensions", error_prefix); return -1; } else { matrix_as_3x3(rmat, (MatrixObject *)value); normalize_m3(rmat); return 0; } } else { PyErr_Format(PyExc_TypeError, "%.200s: expected a Euler, Quaternion or Matrix type, " "found %.200s", error_prefix, Py_TYPE(value)->tp_name); return -1; } }
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) { int totdim = RNA_property_array_dimension(ptr, prop, NULL); const Py_ssize_t seq_size = PySequence_Size(seq); Py_ssize_t i; /* Regarding PySequence_GetItem() failing. * * This should never be NULL since we validated it, _but_ some tricky python * developer could write their own sequence type which succeeds on * validating but fails later somehow, so include checks for safety. */ /* Note that 'data can be NULL' */ if (seq_size == -1) { 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) { if (dim + 1 < totdim) { data = copy_values(item, ptr, prop, dim + 1, data, item_size, index, convert_item, rna_set_index); } else { data = copy_value_single(item, ptr, prop, data, item_size, index, convert_item, rna_set_index); } Py_DECREF(item); /* data may be NULL, but the for loop checks */ } else { return NULL; } } return data; }