Example #1
0
/**
 * 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;
}
Example #2
0
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);
	}
}
Example #3
0
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;
  }
}
Example #4
0
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;
}