Points taken: inverse() vs inverted(), I don't have a strong opinion on this one, both are acceptable (AFAIK), its just easier to remember to add 'ed' suffix to get a copy: normalized(). conjugated(), inverted(), transposed()
The second is not so easy: Disagree regarding: matix.to_euler() & matrix.to_quaternion() In a very general context I see your point: For eg, pretend api call: 'nurbs.to_mesh()' ... would convert a mesh to a curve (in place), but in python context converting between types is almost unheard of, I don't think its so confusing. You say it implies the matrix its self is being changed but to me this implies that the return value is converted into a different representation. But this point is valid for matrix.to_translation() since no conversion happens, its just convenient access to matrix[3][0:3]. So translation_part() is correct naming (where scale_part() and rotation_part() are incorrect IMHO). In this case I'm not convinced its worth to have an exception, to me matrix.to_translation() is not _incorrect_ "to_translation()" can be short for "to translation vector", but I see your point about the ambiguity. Perhaps matrix.translation_component() but that gets annoyingly verbose :S On Thu, Feb 3, 2011 at 10:23 PM, Bassam Kurdali <[email protected]> wrote: > +1 on the changes, with some qualifications: > > -for qualifying in place vs. returning new, whatabout verb/noun instead > of present/past tense of verb: > matrix.invert() inverts the matrix, returns none > matrix.inverse() returns the new inverse matrix. > > in the rename methods we go from translation_part() to to_translation() > however, (nit picking) the 'to' implies that the matrix is being > changed, we are getting into the same region of ambiguity that you were > attempting to solve in the earlier example. > a suggustion is to use the verb 'derive' > as in : > matrix.derive_quaternion() > matrix.derive_translation() > or some other similar verb. > cheers > Bassam > On Thu, 2011-02-03 at 21:54 +0000, Campbell Barton wrote: >> On Thu, Feb 3, 2011 at 11:25 AM, Alex Fraser <[email protected]> wrote: >> > On Thu, Feb 3, 2011 at 10:08 PM, Campbell Barton <[email protected]> >> > wrote: >> >> Here are some proposed changes to the mathutils API I'd like to make >> > >> > As discussed on IRC, these changes look fine to me. One more >> > suggestion: can we allow vector components to be specified without the >> > use of a tuple, i.e. Vector(x,y,z) instead of Vector((x,y,z))? >> > >> > Cheers, >> > Alex (z0r) >> >> Short answer is it doesn't make sense for Vectors to have one triple >> arg, so - we could. >> >> Longer answer: >> >> The reason I made this change is that Quaternions and Eulers have >> optional arguments which are more cumbersome to parse in C (see >> example below) >> >> Since if we support both we would want to allow the same for other types: eg. >> Quaternion(w, x, y, z) # 2.4x, NOT SUPPORTED IN 2.5x >> Quaternion((w, x, y, z)) >> Quaternion((x, y, z), angle) >> Quaternion(someOtherQuat) >> >> Euler(x, y, z) # 2.4x, NOT SUPPORTED IN 2.5x >> Euler((x, y, z)) >> Euler((x, y, z), 'ZXY') >> Euler(x, y, z, 'ZXY') # 2.4x didnt have order argument but perhaps >> this would be expected to work too? >> Euler(someOtherEuler) >> >> Since quats have axis/angle and eulers have optional order argument >> there needs to be checks for argument lengths '0, 1, 2, 4' for quats, >> and '0, 1, 2, 3, (possibly) 4' for eulers. >> >> The likelyhood we add new arguments to , Vector(x,y,z,w) is low so it >> could be an exception, but then its confusing as to why Vector(x,y,z) >> and Euler(x,y,z) doesn't. >> >> My preference is to have consistency between types rather then have >> Vector() as the exception, even though I can see its a bit annoying. >> >> To see what I mean about sloppy argument parsing, see comparison of >> 2.4x and 2.5x code below - both the same function though 2.5x uses >> mathutils_array_parse() utility function. >> The 2.4x code even had a memory leak for some time (refcount error). >> >> # --- 2.5x Code >> static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, >> PyObject *kwds) >> { >> PyObject *seq= NULL; >> double angle = 0.0f; >> float quat[QUAT_SIZE]= {0.0f, 0.0f, 0.0f, 0.0f}; >> >> if(kwds && PyDict_Size(kwds)) { >> PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): >> takes no >> keyword args"); >> return NULL; >> } >> >> if(!PyArg_ParseTuple(args, "|Od:mathutils.Quaternion", &seq, &angle)) >> return NULL; >> >> switch(PyTuple_GET_SIZE(args)) { >> case 0: >> break; >> case 1: >> if (mathutils_array_parse(quat, QUAT_SIZE, QUAT_SIZE, seq, >> "mathutils.Quaternion()") == -1) >> return NULL; >> break; >> case 2: >> if (mathutils_array_parse(quat, 3, 3, seq, >> "mathutils.Quaternion()") == -1) >> return NULL; >> angle= fmod(angle + M_PI*2, M_PI*4) - M_PI*2; /* clamp because >> of >> precision issues */ >> axis_angle_to_quat(quat, quat, angle); >> break; >> /* PyArg_ParseTuple assures no more then 2 */ >> } >> return newQuaternionObject(quat, Py_NEW, type); >> } >> >> >> >> >> # --- 2.4x Code: >> PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args) >> { >> PyObject *listObject = NULL, *n, *q, *f; >> int size, i; >> float quat[4]; >> double norm = 0.0f, angle = 0.0f; >> >> size = PySequence_Length(args); >> if (size == 1 || size == 2) { //seq? >> listObject = PySequence_GetItem(args, 0); >> if (PySequence_Check(listObject)) { >> size = PySequence_Length(listObject); >> if ((size == 4 && PySequence_Length(args) !=1) || >> (size == 3 && PySequence_Length(args) !=2) || >> (size >4 || size < 3)) { >> // invalid args/size >> Py_DECREF(listObject); >> PyErr_SetString(PyExc_AttributeError, >> "Mathutils.Quaternion(): 4d >> numeric sequence expected or 3d vector and number\n"); >> return NULL; >> } >> if(size == 3){ //get angle in axis/angle >> n = PySequence_GetItem(args, 1); >> if(n == NULL) { // parsed item not a number or >> getItem fail >> Py_DECREF(listObject); >> PyErr_SetString(PyExc_TypeError, >> "Mathutils.Quaternion(): 4d >> numeric sequence expected or 3d vector and number\n"); >> return NULL; >> } >> >> angle = PyFloat_AsDouble(n); >> Py_DECREF(n); >> >> if (angle==-1 && PyErr_Occurred()) { >> Py_DECREF(listObject); >> PyErr_SetString(PyExc_TypeError, >> "Mathutils.Quaternion(): 4d >> numeric sequence expected or 3d vector and number\n"); >> return NULL; >> } >> } >> }else{ >> Py_DECREF(listObject); /* assume the list is teh >> second arg */ >> listObject = PySequence_GetItem(args, 1); >> if (size>1 && PySequence_Check(listObject)) { >> size = PySequence_Length(listObject); >> if (size != 3) { >> // invalid args/size >> Py_DECREF(listObject); >> PyErr_SetString(PyExc_AttributeError, >> "Mathutils.Quaternion(): 4d >> numeric sequence expected or 3d vector and number\n"); >> return NULL; >> } >> n = PySequence_GetItem(args, 0); >> if(n == NULL) { // parsed item not a number or >> getItem fail >> Py_DECREF(listObject); >> PyErr_SetString(PyExc_TypeError, >> "Mathutils.Quaternion(): 4d >> numeric sequence expected or 3d vector and number\n"); >> return NULL; >> } >> angle = PyFloat_AsDouble(n); >> Py_DECREF(n); >> >> if (angle==-1 && PyErr_Occurred()) { >> Py_DECREF(listObject); >> PyErr_SetString(PyExc_TypeError, >> "Mathutils.Quaternion(): 4d >> numeric sequence expected or 3d vector and number\n"); >> return NULL; >> } >> } else { // argument was not a sequence >> Py_XDECREF(listObject); >> PyErr_SetString(PyExc_TypeError, >> "Mathutils.Quaternion(): 4d >> numeric sequence expected or 3d vector and number\n"); >> return NULL; >> } >> } >> } else if (size == 0) { //returns a new empty quat >> return newQuaternionObject(NULL, Py_NEW); >> } else { >> Py_INCREF(args); >> listObject = args; >> } >> >> if (size == 3) { // invalid quat size >> if(PySequence_Length(args) != 2){ >> Py_DECREF(listObject); >> PyErr_SetString(PyExc_AttributeError, >> "Mathutils.Quaternion(): 4d >> numeric sequence expected or 3d vector and number\n"); >> return NULL; >> } >> }else{ >> if(size != 4){ >> Py_DECREF(listObject); >> PyErr_SetString(PyExc_AttributeError, >> "Mathutils.Quaternion(): 4d >> numeric sequence expected or 3d vector and number\n"); >> return NULL; >> } >> } >> >> for (i=0; i<size; i++) { //parse >> q = PySequence_GetItem(listObject, i); >> if (q == NULL) { // Failed to read sequence >> Py_DECREF(listObject); >> PyErr_SetString(PyExc_RuntimeError, >> "Mathutils.Quaternion(): 4d >> numeric sequence expected or 3d vector and number\n"); >> return NULL; >> } >> >> f = PyNumber_Float(q); >> if(f == NULL) { // parsed item not a number >> Py_DECREF(q); >> Py_DECREF(listObject); >> PyErr_SetString(PyExc_TypeError, >> "Mathutils.Quaternion(): 4d >> numeric sequence expected or 3d vector and number\n"); >> return NULL; >> } >> >> quat[i] = (float)PyFloat_AS_DOUBLE(f); >> Py_DECREF(f); >> Py_DECREF(q); >> } >> if(size == 3){ //calculate the quat based on axis/angle >> norm = sqrt(quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * >> quat[2]); >> quat[0] /= (float)norm; >> quat[1] /= (float)norm; >> quat[2] /= (float)norm; >> >> angle = angle * (Py_PI / 180); >> quat[3] =(float) (sin(angle/ 2.0f)) * quat[2]; >> quat[2] =(float) (sin(angle/ 2.0f)) * quat[1]; >> quat[1] =(float) (sin(angle/ 2.0f)) * quat[0]; >> quat[0] =(float) (cos(angle/ 2.0f)); >> } >> >> Py_DECREF(listObject); >> return newQuaternionObject(quat, Py_NEW); >> } >> > > > _______________________________________________ > Bf-committers mailing list > [email protected] > http://lists.blender.org/mailman/listinfo/bf-committers > -- - Campbell _______________________________________________ Bf-committers mailing list [email protected] http://lists.blender.org/mailman/listinfo/bf-committers
