/* on error, -1 is returned and no allocation is made */ int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, const char *error_prefix) { int size; #if 1 /* approx 6x speedup for mathutils types */ if ((size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) || (size = EulerObject_Check(value) ? 3 : 0) || (size = QuaternionObject_Check(value) ? 4 : 0) || (size = ColorObject_Check(value) ? 3 : 0)) { if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } if (size < array_min) { PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected > %d", error_prefix, size, array_min); return -1; } *array = PyMem_Malloc(size * sizeof(float)); memcpy(*array, ((BaseMathObject *)value)->data, size * sizeof(float)); return size; } else #endif { PyObject *value_fast = NULL; // *array = NULL; int ret; /* non list/tuple cases */ if (!(value_fast = PySequence_Fast(value, error_prefix))) { /* PySequence_Fast sets the error */ return -1; } size = PySequence_Fast_GET_SIZE(value_fast); if (size < array_min) { PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected > %d", error_prefix, size, array_min); return -1; } *array = PyMem_Malloc(size * sizeof(float)); ret = mathutils_array_parse_fast(*array, size, value_fast, error_prefix); if (ret == -1) { PyMem_Free(*array); } return ret; } }
Vec2f *Vec2f_ptr_from_Vector(PyObject *obj) { if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 2) return NULL; float x = ((VectorObject *)obj)->vec[0]; float y = ((VectorObject *)obj)->vec[1]; return new Vec2f(x, y); }
Vec3r *Vec3r_ptr_from_Vector(PyObject *obj) { if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 3) return NULL; real x = ((VectorObject *)obj)->vec[0]; real y = ((VectorObject *)obj)->vec[1]; real z = ((VectorObject *)obj)->vec[2]; return new Vec3r(x, y, z); }
Vec3f *Vec3f_ptr_from_Vector(PyObject *obj) { if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 3) return NULL; float x = ((VectorObject *)obj)->vec[0]; float y = ((VectorObject *)obj)->vec[1]; float z = ((VectorObject *)obj)->vec[2]; return new Vec3f(x, y, z); }
bool Vec2f_ptr_from_Vector(PyObject *obj, Vec2f &vec) { if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 2) return false; if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) return false; vec[0] = ((VectorObject *)obj)->vec[0]; vec[1] = ((VectorObject *)obj)->vec[1]; return true; }
int float_array_from_PyObject(PyObject *obj, float *v, int n) { if (VectorObject_Check(obj) && ((VectorObject *)obj)->size == n) { for (int i = 0; i < n; i++) v[i] = ((VectorObject *)obj)->vec[i]; return 1; } else if (PyList_Check(obj) && PyList_Size(obj) == n) { return float_array_from_PyList(obj, v, n); } else if (PyTuple_Check(obj) && PyTuple_Size(obj) == n) { return float_array_from_PyTuple(obj, v, n); } return 0; }
/* helper functionm returns length of the 'value', -1 on error */ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix) { #if 1 /* approx 6x speedup for mathutils types */ int size; if ( (size= VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) || (size= EulerObject_Check(value) ? 3 : 0) || (size= QuaternionObject_Check(value) ? 4 : 0) || (size= ColorObject_Check(value) ? 3 : 0)) { if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } if (size > array_max || size < array_min) { if (array_max == array_min) { PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected %d", error_prefix, size, array_max); } else { PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected [%d - %d]", error_prefix, size, array_min, array_max); } return -1; } memcpy(array, ((BaseMathObject *)value)->data, size * sizeof(float)); return size; } else #endif { return mathutils_array_parse_fast(array, array_min, array_max, value, error_prefix); } }
bool float_array_from_PyObject(PyObject *obj, float *v, int n) { if (VectorObject_Check(obj) && ((VectorObject *)obj)->size == n) { if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) return 0; for (int i = 0; i < n; i++) v[i] = ((VectorObject *)obj)->vec[i]; return 1; } else if (ColorObject_Check(obj) && n == 3) { if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) return 0; for (int i = 0; i < n; i++) v[i] = ((ColorObject *)obj)->col[i]; return 1; } else if (PyList_Check(obj) && PyList_GET_SIZE(obj) == n) { return float_array_from_PyList(obj, v, n); } else if (PyTuple_Check(obj) && PyTuple_GET_SIZE(obj) == n) { return float_array_from_PyTuple(obj, v, n); } return 0; }
/* helper functionm returns length of the 'value', -1 on error */ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix) { int size; #if 1 /* approx 6x speedup for mathutils types */ if ((size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) || (size = EulerObject_Check(value) ? 3 : 0) || (size = QuaternionObject_Check(value) ? 4 : 0) || (size = ColorObject_Check(value) ? 3 : 0)) { if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } if (size > array_max || size < array_min) { if (array_max == array_min) { PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected %d", error_prefix, size, array_max); } else { PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected [%d - %d]", error_prefix, size, array_min, array_max); } return -1; } memcpy(array, ((BaseMathObject *)value)->data, size * sizeof(float)); return size; } else #endif { PyObject *value_fast = NULL; /* non list/tuple cases */ if (!(value_fast = PySequence_Fast(value, error_prefix))) { /* PySequence_Fast sets the error */ return -1; } size = PySequence_Fast_GET_SIZE(value_fast); if (size > array_max || size < array_min) { if (array_max == array_min) { PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected %d", error_prefix, size, array_max); } else { PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected [%d - %d]", error_prefix, size, array_min, array_max); } Py_DECREF(value_fast); return -1; } return mathutils_array_parse_fast(array, size, value_fast, error_prefix); } }
//------------------------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; }
/* PolyFill function, uses Blenders scanfill to fill multiple poly lines */ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq ) { PyObject *tri_list; /*return this list of tri's */ PyObject *polyLine, *polyVec; int i, len_polylines, len_polypoints, ls_error = 0; /* display listbase */ ListBase dispbase={NULL, NULL}; DispList *dl; float *fp; /*pointer to the array of malloced dl->verts to set the points from the vectors */ int index, *dl_face, totpoints=0; dispbase.first= dispbase.last= NULL; if(!PySequence_Check(polyLineSeq)) { PyErr_SetString( PyExc_TypeError, "expected a sequence of poly lines" ); return NULL; } len_polylines = PySequence_Size( polyLineSeq ); for( i = 0; i < len_polylines; ++i ) { polyLine= PySequence_GetItem( polyLineSeq, i ); if (!PySequence_Check(polyLine)) { freedisplist(&dispbase); Py_XDECREF(polyLine); /* may be null so use Py_XDECREF*/ PyErr_SetString( PyExc_TypeError, "One or more of the polylines is not a sequence of Mathutils.Vector's" ); return NULL; } len_polypoints= PySequence_Size( polyLine ); if (len_polypoints>0) { /* dont bother adding edges as polylines */ #if 0 if (EXPP_check_sequence_consistency( polyLine, &vector_Type ) != 1) { freedisplist(&dispbase); Py_DECREF(polyLine); PyErr_SetString( PyExc_TypeError, "A point in one of the polylines is not a Mathutils.Vector type" ); return NULL; } #endif dl= MEM_callocN(sizeof(DispList), "poly disp"); BLI_addtail(&dispbase, dl); dl->type= DL_INDEX3; dl->nr= len_polypoints; dl->type= DL_POLY; dl->parts= 1; /* no faces, 1 edge loop */ dl->col= 0; /* no material */ dl->verts= fp= MEM_callocN( sizeof(float)*3*len_polypoints, "dl verts"); dl->index= MEM_callocN(sizeof(int)*3*len_polypoints, "dl index"); for( index = 0; index<len_polypoints; ++index, fp+=3) { polyVec= PySequence_GetItem( polyLine, index ); if(VectorObject_Check(polyVec)) { if(!BaseMath_ReadCallback((VectorObject *)polyVec)) ls_error= 1; fp[0] = ((VectorObject *)polyVec)->vec[0]; fp[1] = ((VectorObject *)polyVec)->vec[1]; if( ((VectorObject *)polyVec)->size > 2 ) fp[2] = ((VectorObject *)polyVec)->vec[2]; else fp[2]= 0.0f; /* if its a 2d vector then set the z to be zero */ } else { ls_error= 1; } totpoints++; Py_DECREF(polyVec); } } Py_DECREF(polyLine); } if(ls_error) { freedisplist(&dispbase); /* possible some dl was allocated */ PyErr_SetString( PyExc_TypeError, "A point in one of the polylines is not a Mathutils.Vector type" ); return NULL; } else if (totpoints) { /* now make the list to return */ filldisplist(&dispbase, &dispbase); /* The faces are stored in a new DisplayList thats added to the head of the listbase */ dl= dispbase.first; tri_list= PyList_New(dl->parts); if( !tri_list ) { freedisplist(&dispbase); PyErr_SetString( PyExc_RuntimeError, "Geometry.PolyFill failed to make a new list" ); return NULL; } index= 0; dl_face= dl->index; while(index < dl->parts) { PyList_SetItem(tri_list, index, Py_BuildValue("iii", dl_face[0], dl_face[1], dl_face[2]) ); dl_face+= 3; index++; } freedisplist(&dispbase); } else { /* no points, do this so scripts dont barf */ freedisplist(&dispbase); /* possible some dl was allocated */ tri_list= PyList_New(0); } return tri_list; }