예제 #1
0
static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyObject *args)
{
	VectorObject *line_a, *line_b, *sphere_co;
	float sphere_radius;
	int clip = TRUE;

	float isect_a[3];
	float isect_b[3];

	if (!PyArg_ParseTuple(args, "O!O!O!f|i:intersect_line_sphere_2d",
	                      &vector_Type, &line_a,
	                      &vector_Type, &line_b,
	                      &vector_Type, &sphere_co,
	                      &sphere_radius, &clip))
	{
		return NULL;
	}

	if (BaseMath_ReadCallback(line_a) == -1 ||
	    BaseMath_ReadCallback(line_b) == -1 ||
	    BaseMath_ReadCallback(sphere_co) == -1)
	{
		return NULL;
	}
	else {
		short use_a = TRUE;
		short use_b = TRUE;
		float lambda;

		PyObject *ret = PyTuple_New(2);

		switch (isect_line_sphere_v2(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) {
			case 1:
				if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a = FALSE;
				use_b = FALSE;
				break;
			case 2:
				if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a = FALSE;
				if (!(!clip || (((lambda = line_point_factor_v2(isect_b, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_b = FALSE;
				break;
			default:
				use_a = FALSE;
				use_b = FALSE;
		}

		if (use_a) { PyTuple_SET_ITEM(ret, 0,  Vector_CreatePyObject(isect_a, 2, Py_NEW, NULL)); }
		else       { PyTuple_SET_ITEM(ret, 0,  Py_None); Py_INCREF(Py_None); }

		if (use_b) { PyTuple_SET_ITEM(ret, 1,  Vector_CreatePyObject(isect_b, 2, Py_NEW, NULL)); }
		else       { PyTuple_SET_ITEM(ret, 1,  Py_None); Py_INCREF(Py_None); }

		return ret;
	}
}
예제 #2
0
static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObject *args)
{
	VectorObject *line_a1, *line_a2, *line_b1, *line_b2;
	float vi[2];
	if (!PyArg_ParseTuple(args, "O!O!O!O!:intersect_line_line_2d",
	                      &vector_Type, &line_a1,
	                      &vector_Type, &line_a2,
	                      &vector_Type, &line_b1,
	                      &vector_Type, &line_b2))
	{
		return NULL;
	}
	
	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 Vector_CreatePyObject(vi, 2, Py_NEW, NULL);
	}
	else {
		Py_RETURN_NONE;
	}
}
예제 #3
0
static PyObject *Freestyle_blendRamp(PyObject *self, PyObject *args)
{
	PyObject *obj1, *obj2;
	char *s;
	int type;
	float a[3], fac, b[3];

	if (!PyArg_ParseTuple(args, "sOfO", &s, &obj1, &fac, &obj2))
		return NULL;
	type = ramp_blend_type(s);
	if (type < 0) {
		PyErr_SetString(PyExc_TypeError, "argument 1 is an unknown ramp blend type");
		return NULL;
	}
	if (!float_array_from_PyObject(obj1, a, 3)) {
		PyErr_SetString(PyExc_TypeError,
		                "argument 2 must be a 3D vector (either a tuple/list of 3 elements or Vector)");
		return NULL;
	}
	if (!float_array_from_PyObject(obj2, b, 3)) {
		PyErr_SetString(PyExc_TypeError,
		                "argument 4 must be a 3D vector (either a tuple/list of 3 elements or Vector)");
		return NULL;
	}
	ramp_blend(type, a, fac, b);
	return Vector_CreatePyObject(a, 3, Py_NEW, NULL);
}
예제 #4
0
PyObject *Vector_from_Vec2f(Vec2f& vec)
{
	float vec_data[2]; // because vec->_coord is protected
	vec_data[0] = vec.x();
	vec_data[1] = vec.y();
	return Vector_CreatePyObject(vec_data, 2, Py_NEW, NULL);
}
예제 #5
0
PyObject *Vector_from_Vec3r(Vec3r& vec)
{
	float vec_data[3]; // because vec->_coord is protected
	vec_data[0] = vec.x();
	vec_data[1] = vec.y();
	vec_data[2] = vec.z();
	return Vector_CreatePyObject(vec_data, 3, NULL);
}
예제 #6
0
static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject *args)
{
	VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2;
	int resolu;
	int dims;
	int i;
	float *coord_array, *fp;
	PyObject *list;

	float k1[4] = {0.0, 0.0, 0.0, 0.0};
	float h1[4] = {0.0, 0.0, 0.0, 0.0};
	float k2[4] = {0.0, 0.0, 0.0, 0.0};
	float h2[4] = {0.0, 0.0, 0.0, 0.0};


	if (!PyArg_ParseTuple(args, "O!O!O!O!i:interpolate_bezier",
	                      &vector_Type, &vec_k1,
	                      &vector_Type, &vec_h1,
	                      &vector_Type, &vec_h2,
	                      &vector_Type, &vec_k2, &resolu))
	{
		return NULL;
	}

	if (resolu <= 1) {
		PyErr_SetString(PyExc_ValueError,
		                "resolution must be 2 or over");
		return NULL;
	}

	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);

	for (i = 0; i < vec_k1->size; i++) k1[i] = vec_k1->vec[i];
	for (i = 0; i < vec_h1->size; i++) h1[i] = vec_h1->vec[i];
	for (i = 0; i < vec_k2->size; i++) k2[i] = vec_k2->vec[i];
	for (i = 0; i < vec_h2->size; i++) h2[i] = vec_h2->vec[i];

	coord_array = MEM_callocN(dims * (resolu) * sizeof(float), "interpolate_bezier");
	for (i = 0; i < dims; i++) {
		BKE_curve_forward_diff_bezier(k1[i], h1[i], h2[i], k2[i], coord_array + i, resolu - 1, sizeof(float) * dims);
	}

	list = PyList_New(resolu);
	fp = coord_array;
	for (i = 0; i < resolu; i++, fp = fp + dims) {
		PyList_SET_ITEM(list, i, Vector_CreatePyObject(fp, dims, Py_NEW, NULL));
	}
	MEM_freeN(coord_array);
	return list;
}
예제 #7
0
static void kdtree_nearest_to_py_tuple(const KDTreeNearest *nearest, PyObject *py_retval)
{
	BLI_assert(nearest->index >= 0);
	BLI_assert(PyTuple_GET_SIZE(py_retval) == 3);

	PyTuple_SET_ITEM(py_retval, 0, Vector_CreatePyObject((float *)nearest->co, 3, Py_NEW, NULL));
	PyTuple_SET_ITEM(py_retval, 1, PyLong_FromLong(nearest->index));
	PyTuple_SET_ITEM(py_retval, 2, PyFloat_FromDouble(nearest->dist));
}
예제 #8
0
static PyObject *M_Geometry_intersect_plane_plane(PyObject *UNUSED(self), PyObject *args)
{
	PyObject *ret;
	VectorObject *plane_a_co, *plane_a_no, *plane_b_co, *plane_b_no;

	float isect_co[3];
	float isect_no[3];

	if (!PyArg_ParseTuple(args, "O!O!O!O!|i:intersect_plane_plane",
	                      &vector_Type, &plane_a_co,
	                      &vector_Type, &plane_a_no,
	                      &vector_Type, &plane_b_co,
	                      &vector_Type, &plane_b_no))
	{
		return NULL;
	}

	if (BaseMath_ReadCallback(plane_a_co) == -1 ||
	    BaseMath_ReadCallback(plane_a_no) == -1 ||
	    BaseMath_ReadCallback(plane_b_co) == -1 ||
	    BaseMath_ReadCallback(plane_b_no) == -1)
	{
		return NULL;
	}

	if (ELEM4(2, plane_a_co->size, plane_a_no->size, plane_b_co->size, plane_b_no->size)) {
		PyErr_SetString(PyExc_ValueError,
		                "geometry.intersect_plane_plane(...): "
		                " can't use 2D Vectors");
		return NULL;
	}

	isect_plane_plane_v3(isect_co, isect_no,
	                     plane_a_co->vec, plane_a_no->vec,
	                     plane_b_co->vec, plane_b_no->vec);

	normalize_v3(isect_no);

	ret = PyTuple_New(2);
	PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(isect_co, 3, Py_NEW, NULL));
	PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(isect_no, 3, Py_NEW, NULL));
	return ret;
}
예제 #9
0
PyObject *PyObjectFrom(const MT_Tuple2 &vec)
{
#ifdef USE_MATHUTILS
	float fvec[2];
	vec.getValue(fvec);
	return Vector_CreatePyObject(fvec, 2, NULL);
#else
	PyObject *list = PyList_New(2);
	PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0]));
	PyList_SET_ITEM(list, 1, PyFloat_FromDouble(vec[1]));
	return list;
#endif
}
예제 #10
0
static PyObject *Quaternion_axis_vector_get(QuaternionObject *self, void *UNUSED(closure))
{
	float tquat[4];

	float axis[3];
	float angle_dummy;

	if (BaseMath_ReadCallback(self) == -1)
		return NULL;

	normalize_qt_qt(tquat, self->quat);
	quat_to_axis_angle(axis, &angle_dummy, tquat);

	quat__axis_angle_sanitize(axis, NULL);

	return Vector_CreatePyObject(axis, 3, Py_NEW, NULL);
}
예제 #11
0
static PyObject *Freestyle_evaluateColorRamp(PyObject *self, PyObject *args)
{
	BPy_StructRNA *py_srna;
	ColorBand *coba;
	float in, out[4];

	if (!(PyArg_ParseTuple(args, "O!f", &pyrna_struct_Type, &py_srna, &in)))
		return NULL;
	if (!RNA_struct_is_a(py_srna->ptr.type, &RNA_ColorRamp)) {
		PyErr_SetString(PyExc_TypeError, "1st argument is not a ColorRamp object");
		return NULL;
	}
	coba = (ColorBand *)py_srna->ptr.data;
	if (!do_colorband(coba, in, out)) {
		PyErr_SetString(PyExc_ValueError, "failed to evaluate the color ramp");
		return NULL;
	}
	return Vector_CreatePyObject(out, 4, Py_NEW, NULL);
}
예제 #12
0
static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObject *args)
{
	VectorObject *pt, *line_1, *line_2;
	float pt_in[3], pt_out[3], l1[3], l2[3];
	float lambda;
	PyObject *ret;
	
	if (!PyArg_ParseTuple(args, "O!O!O!:intersect_point_line",
	                      &vector_Type, &pt,
	                      &vector_Type, &line_1,
	                      &vector_Type, &line_2))
	{
		return NULL;
	}

	if (BaseMath_ReadCallback(pt) == -1 ||
	    BaseMath_ReadCallback(line_1) == -1 ||
	    BaseMath_ReadCallback(line_2) == -1)
	{
		return NULL;
	}

	/* accept 2d verts */
	if (pt->size == 3) {     copy_v3_v3(pt_in, pt->vec); }
	else { pt_in[2] = 0.0f;  copy_v2_v2(pt_in, pt->vec); }
	
	if (line_1->size == 3) { copy_v3_v3(l1, line_1->vec); }
	else { l1[2] = 0.0f;     copy_v2_v2(l1, line_1->vec); }
	
	if (line_2->size == 3) { copy_v3_v3(l2, line_2->vec); }
	else { l2[2] = 0.0f;     copy_v2_v2(l2, line_2->vec); }
	
	/* do the calculation */
	lambda = closest_to_line_v3(pt_out, pt_in, l1, l2);
	
	ret = PyTuple_New(2);
	PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(pt_out, 3, Py_NEW, NULL));
	PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(lambda));
	return ret;
}
예제 #13
0
static PyObject *Quaternion_to_axis_angle(QuaternionObject *self)
{
	PyObject *ret;

	float tquat[4];

	float axis[3];
	float angle;

	if (BaseMath_ReadCallback(self) == -1)
		return NULL;

	normalize_qt_qt(tquat, self->quat);
	quat_to_axis_angle(axis, &angle, tquat);

	quat__axis_angle_sanitize(axis, &angle);

	ret = PyTuple_New(2);
	PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(axis, 3, Py_NEW, NULL));
	PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(angle));
	return ret;
}
예제 #14
0
static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObject *args)
{
	VectorObject *vec_pt;
	VectorObject *vec_t1_tar, *vec_t2_tar, *vec_t3_tar;
	VectorObject *vec_t1_src, *vec_t2_src, *vec_t3_src;
	float vec[3];

	if (!PyArg_ParseTuple(args, "O!O!O!O!O!O!O!:barycentric_transform",
	                      &vector_Type, &vec_pt,
	                      &vector_Type, &vec_t1_src,
	                      &vector_Type, &vec_t2_src,
	                      &vector_Type, &vec_t3_src,
	                      &vector_Type, &vec_t1_tar,
	                      &vector_Type, &vec_t2_tar,
	                      &vector_Type, &vec_t3_tar))
	{
		return NULL;
	}

	if (vec_pt->size != 3 ||
	    vec_t1_src->size != 3 ||
	    vec_t2_src->size != 3 ||
	    vec_t3_src->size != 3 ||
	    vec_t1_tar->size != 3 ||
	    vec_t2_tar->size != 3 ||
	    vec_t3_tar->size != 3)
	{
		PyErr_SetString(PyExc_ValueError,
		                "One of more of the vector arguments wasn't a 3D vector");
		return NULL;
	}

	barycentric_transform(vec, vec_pt->vec,
	                      vec_t1_tar->vec, vec_t2_tar->vec, vec_t3_tar->vec,
	                      vec_t1_src->vec, vec_t2_src->vec, vec_t3_src->vec);

	return Vector_CreatePyObject(vec, 3, Py_NEW, NULL);
}
예제 #15
0
static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObject *args)
{
	VectorObject *line_a, *line_b, *plane_co, *plane_no;
	int no_flip = 0;
	float isect[3];
	if (!PyArg_ParseTuple(args, "O!O!O!O!|i:intersect_line_plane",
	                      &vector_Type, &line_a,
	                      &vector_Type, &line_b,
	                      &vector_Type, &plane_co,
	                      &vector_Type, &plane_no,
	                      &no_flip))
	{
		return NULL;
	}

	if (BaseMath_ReadCallback(line_a) == -1 ||
	    BaseMath_ReadCallback(line_b) == -1 ||
	    BaseMath_ReadCallback(plane_co) == -1 ||
	    BaseMath_ReadCallback(plane_no) == -1)
	{
		return NULL;
	}

	if (ELEM4(2, line_a->size, line_b->size, plane_co->size, plane_no->size)) {
		PyErr_SetString(PyExc_ValueError,
		                "geometry.intersect_line_plane(...): "
		                " can't use 2D Vectors");
		return NULL;
	}

	if (isect_line_plane_v3(isect, line_a->vec, line_b->vec, plane_co->vec, plane_no->vec, no_flip) == 1) {
		return Vector_CreatePyObject(isect, 3, Py_NEW, NULL);
	}
	else {
		Py_RETURN_NONE;
	}
}
예제 #16
0
static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject *args)
{
	VectorObject *vec1, *vec2, *vec3, *vec4;
	float n[3];

	if (PyTuple_GET_SIZE(args) == 3) {
		if (!PyArg_ParseTuple(args, "O!O!O!:normal",
		                      &vector_Type, &vec1,
		                      &vector_Type, &vec2,
		                      &vector_Type, &vec3))
		{
			return NULL;
		}

		if (vec1->size != vec2->size || vec1->size != vec3->size) {
			PyErr_SetString(PyExc_ValueError,
			                "vectors must be of the same size");
			return NULL;
		}
		if (vec1->size < 3) {
			PyErr_SetString(PyExc_ValueError,
			                "2D vectors unsupported");
			return NULL;
		}

		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);
	}
	else {
		if (!PyArg_ParseTuple(args, "O!O!O!O!:normal",
		                      &vector_Type, &vec1,
		                      &vector_Type, &vec2,
		                      &vector_Type, &vec3,
		                      &vector_Type, &vec4))
		{
			return NULL;
		}
		if (vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size) {
			PyErr_SetString(PyExc_ValueError,
			                "vectors must be of the same size");
			return NULL;
		}
		if (vec1->size < 3) {
			PyErr_SetString(PyExc_ValueError,
			                "2D vectors unsupported");
			return NULL;
		}

		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);
	}

	return Vector_CreatePyObject(n, 3, Py_NEW, NULL);
}
예제 #17
0
/* note, this is called as a python 'getset, where the PyAttributeDef is the closure */
PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *attrdef)
{
	PyObjectPlus *ref= (BGE_PROXY_REF(self_py));
	char* ptr = (attrdef->m_usePtr) ? (char*)BGE_PROXY_PTR(self_py) : (char*)ref;
	if (ptr == NULL || (BGE_PROXY_PYREF(self_py) && (ref==NULL || !ref->py_is_valid()))) {
		if (attrdef == BGE_PY_ATTR_INVALID)
			Py_RETURN_TRUE; // don't bother running the function

		PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
		return NULL;
	}

	if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY)
	{
		// fake attribute, ignore
		return NULL;
	}
	if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_FUNCTION)
	{
		// the attribute has no field correspondence, handover processing to function.
		if (attrdef->m_getFunction == NULL)
			return NULL;
		return (*attrdef->m_getFunction)(ptr, attrdef);
	}
	ptr += attrdef->m_offset;
	if (attrdef->m_length > 1)
	{
		PyObject *resultlist = PyList_New(attrdef->m_length);
		for (unsigned int i=0; i<attrdef->m_length; i++)
		{
			switch (attrdef->m_type) {
			case KX_PYATTRIBUTE_TYPE_BOOL:
				{
					bool *val = reinterpret_cast<bool*>(ptr);
					ptr += sizeof(bool);
					PyList_SET_ITEM(resultlist, i, PyBool_FromLong(*val));
					break;
				}
			case KX_PYATTRIBUTE_TYPE_SHORT:
				{
					short int *val = reinterpret_cast<short int*>(ptr);
					ptr += sizeof(short int);
					PyList_SET_ITEM(resultlist, i, PyLong_FromLong(*val));
					break;
				}
			case KX_PYATTRIBUTE_TYPE_ENUM:
				// enum are like int, just make sure the field size is the same
				if (sizeof(int) != attrdef->m_size)
				{
					Py_DECREF(resultlist);
					return NULL;
				}
				// walkthrough
			case KX_PYATTRIBUTE_TYPE_INT:
				{
					int *val = reinterpret_cast<int*>(ptr);
					ptr += sizeof(int);
					PyList_SET_ITEM(resultlist, i, PyLong_FromLong(*val));
					break;
				}
			case KX_PYATTRIBUTE_TYPE_FLOAT:
				{
					float *val = reinterpret_cast<float*>(ptr);
					ptr += sizeof(float);
					PyList_SET_ITEM(resultlist, i, PyFloat_FromDouble(*val));
					break;
				}
			default:
				// no support for array of complex data
				Py_DECREF(resultlist);
				return NULL;
			}
		}
		return resultlist;
	}
	else
	{
		switch (attrdef->m_type) {
		case KX_PYATTRIBUTE_TYPE_FLAG:
			{
				bool bval;
				switch (attrdef->m_size) {
				case 1:
					{
						unsigned char *val = reinterpret_cast<unsigned char*>(ptr);
						bval = (*val & attrdef->m_imin);
						break;
					}
				case 2:
					{
						unsigned short *val = reinterpret_cast<unsigned short*>(ptr);
						bval = (*val & attrdef->m_imin);
						break;
					}
				case 4:
					{
						unsigned int *val = reinterpret_cast<unsigned int*>(ptr);
						bval = (*val & attrdef->m_imin);
						break;
					}
				default:
					return NULL;
				}
				if (attrdef->m_imax)
					bval = !bval;
				return PyBool_FromLong(bval);
			}
		case KX_PYATTRIBUTE_TYPE_BOOL:
			{
				bool *val = reinterpret_cast<bool*>(ptr);
				return PyBool_FromLong(*val);
			}
		case KX_PYATTRIBUTE_TYPE_SHORT:
			{
				short int *val = reinterpret_cast<short int*>(ptr);
				return PyLong_FromLong(*val);
			}
		case KX_PYATTRIBUTE_TYPE_ENUM:
			// enum are like int, just make sure the field size is the same
			if (sizeof(int) != attrdef->m_size)
			{
				return NULL;
			}
			// walkthrough
		case KX_PYATTRIBUTE_TYPE_INT:
			{
				int *val = reinterpret_cast<int*>(ptr);
				return PyLong_FromLong(*val);
			}
		case KX_PYATTRIBUTE_TYPE_FLOAT:
			{
				float *val = reinterpret_cast<float*>(ptr);
				if (attrdef->m_imin == 0) {
					if (attrdef->m_imax == 0) {
						return PyFloat_FromDouble(*val);
					} else {
						// vector, verify size
						if (attrdef->m_size != attrdef->m_imax*sizeof(float)) 
						{
							return NULL;
						}
#ifdef USE_MATHUTILS
						return Vector_CreatePyObject(val, attrdef->m_imax, NULL);
#else
						PyObject *resultlist = PyList_New(attrdef->m_imax);
						for (unsigned int i=0; i<attrdef->m_imax; i++)
						{
							PyList_SET_ITEM(resultlist, i, PyFloat_FromDouble(val[i]));
						}
						return resultlist;
#endif
					}
				} else {
					// matrix case
					if (attrdef->m_size != attrdef->m_imax*attrdef->m_imin*sizeof(float)) 
					{
						return NULL;
					}
#ifdef USE_MATHUTILS
					return Matrix_CreatePyObject_wrap(val, attrdef->m_imin, attrdef->m_imax, NULL);
#else
					PyObject *collist = PyList_New(attrdef->m_imin);
					for (unsigned int i=0; i<attrdef->m_imin; i++)
					{
						PyObject *col = PyList_New(attrdef->m_imax);
						for (unsigned int j=0; j<attrdef->m_imax; j++)
						{
							PyList_SET_ITEM(col, j, PyFloat_FromDouble(val[j]));
						}
						PyList_SET_ITEM(collist, i, col);
						val += attrdef->m_imax;
					}
					return collist;
#endif
				}
			}
		case KX_PYATTRIBUTE_TYPE_VECTOR:
			{
				MT_Vector3 *val = reinterpret_cast<MT_Vector3*>(ptr);
#ifdef USE_MATHUTILS
				float fval[3];
				val->getValue(fval);
				return Vector_CreatePyObject(fval, 3, NULL);
#else
				PyObject *resultlist = PyList_New(3);
				for (unsigned int i=0; i<3; i++)
				{
					PyList_SET_ITEM(resultlist, i, PyFloat_FromDouble((*val)[i]));
				}
				return resultlist;
#endif
			}
		case KX_PYATTRIBUTE_TYPE_STRING:
			{
				STR_String *val = reinterpret_cast<STR_String*>(ptr);
				return PyUnicode_From_STR_String(*val);
			}
		case KX_PYATTRIBUTE_TYPE_CHAR:
			{
				return PyUnicode_FromString(ptr);
			}
		default:
			return NULL;
		}
	}
}
예제 #18
0
PyObject* BL_ArmatureChannel::py_attr_get_joint_rotation(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef)
{
	bPoseChannel* pchan = static_cast<bPoseChannel*>(self_v);
	// decompose the pose matrix in euler rotation
	float rest_mat[3][3];
	float pose_mat[3][3];
	float joint_mat[3][3];
	float joints[3];
	float norm;
	double sa, ca;
	// get rotation in armature space
	copy_m3_m4(pose_mat, pchan->pose_mat);
	normalize_m3(pose_mat);
	if (pchan->parent) {
		// bone has a parent, compute the rest pose of the bone taking actual pose of parent
		mult_m3_m3m4(rest_mat, pchan->parent->pose_mat, pchan->bone->bone_mat);
		normalize_m3(rest_mat);
	} else {
		// otherwise, the bone matrix in armature space is the rest pose
		copy_m3_m4(rest_mat, pchan->bone->arm_mat);
	}
	// remove the rest pose to get the joint movement
	transpose_m3(rest_mat);
	mul_m3_m3m3(joint_mat, rest_mat, pose_mat);		
	joints[0] = joints[1] = joints[2] = 0.f;
	// returns a 3 element list that gives corresponding joint
	int flag = 0;
	if (!(pchan->ikflag & BONE_IK_NO_XDOF))
		flag |= 1;
	if (!(pchan->ikflag & BONE_IK_NO_YDOF))
		flag |= 2;
	if (!(pchan->ikflag & BONE_IK_NO_ZDOF))
		flag |= 4;
	switch (flag) {
	case 0:	// fixed joint
		break;
	case 1:	// X only
		mat3_to_eulO( joints, EULER_ORDER_XYZ,joint_mat);
		joints[1] = joints[2] = 0.f;
		break;
	case 2:	// Y only
		mat3_to_eulO( joints, EULER_ORDER_XYZ,joint_mat);
		joints[0] = joints[2] = 0.f;
		break;
	case 3:	// X+Y
		mat3_to_eulO( joints, EULER_ORDER_ZYX,joint_mat);
		joints[2] = 0.f;
		break;
	case 4:	// Z only
		mat3_to_eulO( joints, EULER_ORDER_XYZ,joint_mat);
		joints[0] = joints[1] = 0.f;
		break;
	case 5:	// X+Z
		// decompose this as an equivalent rotation vector in X/Z plane
		joints[0] = joint_mat[1][2];
		joints[2] = -joint_mat[1][0];
		norm = normalize_v3(joints);
		if (norm < FLT_EPSILON) {
			norm = (joint_mat[1][1] < 0.f) ? M_PI : 0.f;
		} else {
			norm = acos(joint_mat[1][1]);
		}
		mul_v3_fl(joints, norm);
		break;
	case 6:	// Y+Z
		mat3_to_eulO( joints, EULER_ORDER_XYZ,joint_mat);
		joints[0] = 0.f;
		break;
	case 7: // X+Y+Z
		// equivalent axis
		joints[0] = (joint_mat[1][2]-joint_mat[2][1])*0.5f;
		joints[1] = (joint_mat[2][0]-joint_mat[0][2])*0.5f;
		joints[2] = (joint_mat[0][1]-joint_mat[1][0])*0.5f;
		sa = len_v3(joints);
		ca = (joint_mat[0][0]+joint_mat[1][1]+joint_mat[1][1]-1.0f)*0.5f;
		if (sa > FLT_EPSILON) {
			norm = atan2(sa,ca)/sa;
		} else {
			if (ca < 0.0) {
				norm = M_PI;
				mul_v3_fl(joints,0.f);
				if (joint_mat[0][0] > 0.f) {
					joints[0] = 1.0f;
				} else if (joint_mat[1][1] > 0.f) {
					joints[1] = 1.0f;
				} else {
					joints[2] = 1.0f;
				}
			} else {
				norm = 0.0;
			}
		}
		mul_v3_fl(joints,norm);
		break;
	}
	return Vector_CreatePyObject(joints, 3, Py_NEW, NULL);
}
예제 #19
0
static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject *args)
{
	VectorObject *ray, *ray_off, *vec1, *vec2, *vec3;
	float dir[3], orig[3], v1[3], v2[3], v3[3], e1[3], e2[3], pvec[3], tvec[3], qvec[3];
	float det, inv_det, u, v, t;
	int clip = 1;

	if (!PyArg_ParseTuple(args,
	                      "O!O!O!O!O!|i:intersect_ray_tri",
	                      &vector_Type, &vec1,
	                      &vector_Type, &vec2,
	                      &vector_Type, &vec3,
	                      &vector_Type, &ray,
	                      &vector_Type, &ray_off, &clip))
	{
		return NULL;
	}
	if (vec1->size != 3 || vec2->size != 3 || vec3->size != 3 || ray->size != 3 || ray_off->size != 3) {
		PyErr_SetString(PyExc_ValueError,
		                "only 3D vectors for all parameters");
		return NULL;
	}

	if (BaseMath_ReadCallback(vec1) == -1 ||
	    BaseMath_ReadCallback(vec2) == -1 ||
	    BaseMath_ReadCallback(vec3) == -1 ||
	    BaseMath_ReadCallback(ray)  == -1 ||
	    BaseMath_ReadCallback(ray_off) == -1)
	{
		return NULL;
	}

	copy_v3_v3(v1, vec1->vec);
	copy_v3_v3(v2, vec2->vec);
	copy_v3_v3(v3, vec3->vec);

	copy_v3_v3(dir, ray->vec);
	normalize_v3(dir);

	copy_v3_v3(orig, ray_off->vec);

	/* find vectors for two edges sharing v1 */
	sub_v3_v3v3(e1, v2, v1);
	sub_v3_v3v3(e2, v3, v1);

	/* begin calculating determinant - also used to calculated U parameter */
	cross_v3_v3v3(pvec, dir, e2);

	/* if determinant is near zero, ray lies in plane of triangle */
	det = dot_v3v3(e1, pvec);

	if (det > -0.000001f && det < 0.000001f) {
		Py_RETURN_NONE;
	}

	inv_det = 1.0f / det;

	/* calculate distance from v1 to ray origin */
	sub_v3_v3v3(tvec, orig, v1);

	/* calculate U parameter and test bounds */
	u = dot_v3v3(tvec, pvec) * inv_det;
	if (clip && (u < 0.0f || u > 1.0f)) {
		Py_RETURN_NONE;
	}

	/* prepare to test the V parameter */
	cross_v3_v3v3(qvec, tvec, e1);

	/* calculate V parameter and test bounds */
	v = dot_v3v3(dir, qvec) * inv_det;

	if (clip && (v < 0.0f || u + v > 1.0f)) {
		Py_RETURN_NONE;
	}

	/* calculate t, ray intersects triangle */
	t = dot_v3v3(e2, qvec) * inv_det;

	mul_v3_fl(dir, t);
	add_v3_v3v3(pvec, orig, dir);

	return Vector_CreatePyObject(pvec, 3, Py_NEW, NULL);
}
예제 #20
0
static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject *args)
{
	PyObject *tuple;
	VectorObject *vec1, *vec2, *vec3, *vec4;
	float v1[3], v2[3], v3[3], v4[3], i1[3], i2[3];

	if (!PyArg_ParseTuple(args, "O!O!O!O!:intersect_line_line",
	                      &vector_Type, &vec1,
	                      &vector_Type, &vec2,
	                      &vector_Type, &vec3,
	                      &vector_Type, &vec4))
	{
		return NULL;
	}

	if (vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) {
		PyErr_SetString(PyExc_ValueError,
		                "vectors must be of the same size");
		return NULL;
	}

	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) {
		int result;

		if (vec1->size == 3) {
			copy_v3_v3(v1, vec1->vec);
			copy_v3_v3(v2, vec2->vec);
			copy_v3_v3(v3, vec3->vec);
			copy_v3_v3(v4, vec4->vec);
		}
		else {
			v1[0] = vec1->vec[0];
			v1[1] = vec1->vec[1];
			v1[2] = 0.0f;

			v2[0] = vec2->vec[0];
			v2[1] = vec2->vec[1];
			v2[2] = 0.0f;

			v3[0] = vec3->vec[0];
			v3[1] = vec3->vec[1];
			v3[2] = 0.0f;

			v4[0] = vec4->vec[0];
			v4[1] = vec4->vec[1];
			v4[2] = 0.0f;
		}

		result = isect_line_line_v3(v1, v2, v3, v4, i1, i2);

		if (result == 0) {
			/* colinear */
			Py_RETURN_NONE;
		}
		else {
			tuple = PyTuple_New(2);
			PyTuple_SET_ITEM(tuple, 0, Vector_CreatePyObject(i1, vec1->size, Py_NEW, NULL));
			PyTuple_SET_ITEM(tuple, 1, Vector_CreatePyObject(i2, vec1->size, Py_NEW, NULL));
			return tuple;
		}
	}
	else {
		PyErr_SetString(PyExc_ValueError,
		                "2D/3D vectors only");
		return NULL;
	}
}
/**
 *\brief BMElem.__getitem__()
 *
 * assume all error checks are done, eg:
 *
 *     uv = vert[uv_layer]
 */
PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
{
	void *value = bpy_bmlayeritem_ptr_get(py_ele, py_layer);
	PyObject *ret;

	if (UNLIKELY(value == NULL)) {
		return NULL;
	}

	switch (py_layer->type) {
		case CD_MDEFORMVERT:
		{
			ret = BPy_BMDeformVert_CreatePyObject(value);
			break;
		}
		case CD_PROP_FLT:
		{
			ret = PyFloat_FromDouble(*(float *)value);
			break;
		}
		case CD_PROP_INT:
		{
			ret = PyLong_FromLong(*(int *)value);
			break;
		}
		case CD_PROP_STR:
		{
			MStringProperty *mstring = value;
			ret = PyBytes_FromStringAndSize(mstring->s, mstring->s_len);
			break;
		}
		case CD_MTEXPOLY:
		{
			ret = BPy_BMTexPoly_CreatePyObject(value);
			break;
		}
		case CD_MLOOPUV:
		{
			ret = BPy_BMLoopUV_CreatePyObject(value);
			break;
		}
		case CD_MLOOPCOL:
		{
			ret = BPy_BMLoopColor_CreatePyObject(value);
			break;
		}
		case CD_SHAPEKEY:
		{
			ret = Vector_CreatePyObject((float *)value, 3, Py_WRAP, NULL);
			break;
		}
		case CD_BWEIGHT:
		{
			ret = PyFloat_FromDouble(*(float *)value);
			break;
		}
		case CD_CREASE:
		{
			ret = PyFloat_FromDouble(*(float *)value);
			break;
		}
		default:
		{
			ret = Py_NotImplemented; /* TODO */
			Py_INCREF(ret);
			break;
		}
	}

	return ret;
}
static PyObject *bpy_bmloopuv_uv_get(BPy_BMLoopUV *self, void *UNUSED(closure))
{
	return Vector_CreatePyObject(self->data->uv, 2, Py_WRAP, NULL);
}
예제 #23
0
//------------------------obj * obj------------------------------
//mulplication
static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
{
	float quat[QUAT_SIZE], scalar;
	QuaternionObject *quat1 = NULL, *quat2 = NULL;

	if (QuaternionObject_Check(q1)) {
		quat1 = (QuaternionObject *)q1;
		if (BaseMath_ReadCallback(quat1) == -1)
			return NULL;
	}
	if (QuaternionObject_Check(q2)) {
		quat2 = (QuaternionObject *)q2;
		if (BaseMath_ReadCallback(quat2) == -1)
			return NULL;
	}

	if (quat1 && quat2) { /* QUAT * QUAT (cross product) */
		mul_qt_qtqt(quat, quat1->quat, quat2->quat);
		return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1));
	}
	/* the only case this can happen (for a supported type is "FLOAT * QUAT") */
	else if (quat2) { /* FLOAT * QUAT */
		if (((scalar = PyFloat_AsDouble(q1)) == -1.0f && PyErr_Occurred()) == 0) {
			return quat_mul_float(quat2, scalar);
		}
	}
	else if (quat1) {
		/* QUAT * VEC */
		if (VectorObject_Check(q2)) {
			VectorObject *vec2 = (VectorObject *)q2;
			float tvec[3];

			if (vec2->size != 3) {
				PyErr_SetString(PyExc_ValueError,
				                "Vector multiplication: "
				                "only 3D vector rotations (with quats) "
				                "currently supported");
				return NULL;
			}
			if (BaseMath_ReadCallback(vec2) == -1) {
				return NULL;
			}

			copy_v3_v3(tvec, vec2->vec);
			mul_qt_v3(quat1->quat, tvec);

			return Vector_CreatePyObject(tvec, 3, Py_NEW, Py_TYPE(vec2));
		}
		/* QUAT * FLOAT */
		else if ((((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) {
			return quat_mul_float(quat1, scalar);
		}
	}
	else {
		BLI_assert(!"internal error");
	}

	PyErr_Format(PyExc_TypeError,
	             "Quaternion multiplication: "
	             "not supported between '%.200s' and '%.200s' types",
	             Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
	return NULL;
}
예제 #24
0
/* note: this function could be optimized by some spatial structure */
static PyObject *M_Geometry_points_in_planes(PyObject *UNUSED(self), PyObject *args)
{
	PyObject *py_planes;
	float (*planes)[4];
	unsigned int planes_len;

	if (!PyArg_ParseTuple(args, "O:points_in_planes",
	                      &py_planes))
	{
		return NULL;
	}

	if ((planes_len = mathutils_array_parse_alloc_v((float **)&planes, 4, py_planes, "points_in_planes")) == -1) {
		return NULL;
	}
	else {
		/* note, this could be refactored into plain C easy - py bits are noted */
		const float eps = 0.0001f;
		const unsigned int len = (unsigned int)planes_len;
		unsigned int i, j, k, l;

		float n1n2[3], n2n3[3], n3n1[3];
		float potentialVertex[3];
		char *planes_used = MEM_callocN(sizeof(char) * len, __func__);

		/* python */
		PyObject *py_verts = PyList_New(0);
		PyObject *py_plene_index = PyList_New(0);

		for (i = 0; i < len; i++) {
			const float *N1 = planes[i];
			for (j = i + 1; j < len; j++) {
				const float *N2 = planes[j];
				cross_v3_v3v3(n1n2, N1, N2);
				if (len_squared_v3(n1n2) > eps) {
					for (k = j + 1; k < len; k++) {
						const float *N3 = planes[k];
						cross_v3_v3v3(n2n3, N2, N3);
						if (len_squared_v3(n2n3) > eps) {
							cross_v3_v3v3(n3n1, N3, N1);
							if (len_squared_v3(n3n1) > eps) {
								const float quotient = dot_v3v3(N1, n2n3);
								if (fabsf(quotient) > eps) {
									/* potentialVertex = (n2n3 * N1[3] + n3n1 * N2[3] + n1n2 * N3[3]) * (-1.0 / quotient); */
									const float quotient_ninv = -1.0f / quotient;
									potentialVertex[0] = ((n2n3[0] * N1[3]) + (n3n1[0] * N2[3]) + (n1n2[0] * N3[3])) * quotient_ninv;
									potentialVertex[1] = ((n2n3[1] * N1[3]) + (n3n1[1] * N2[3]) + (n1n2[1] * N3[3])) * quotient_ninv;
									potentialVertex[2] = ((n2n3[2] * N1[3]) + (n3n1[2] * N2[3]) + (n1n2[2] * N3[3])) * quotient_ninv;
									for (l = 0; l < len; l++) {
										const float *NP = planes[l];
										if ((dot_v3v3(NP, potentialVertex) + NP[3]) > 0.000001f) {
											break;
										}
									}

									if (l == len) { /* ok */
										/* python */
										PyObject *item = Vector_CreatePyObject(potentialVertex, 3, Py_NEW, NULL);
										PyList_Append(py_verts, item);
										Py_DECREF(item);

										planes_used[i] = planes_used[j] = planes_used[k] = TRUE;
									}
								}
							}
						}
					}
				}
			}
		}

		PyMem_Free(planes);

		/* now make a list of used planes */
		for (i = 0; i < len; i++) {
			if (planes_used[i]) {
				PyObject *item = PyLong_FromLong(i);
				PyList_Append(py_plene_index, item);
				Py_DECREF(item);
			}
		}
		MEM_freeN(planes_used);

		{
			PyObject *ret = PyTuple_New(2);
			PyTuple_SET_ITEM(ret, 0, py_verts);
			PyTuple_SET_ITEM(ret, 1, py_plene_index);
			return ret;
		}
	}
}