[Bf-committers] Patches Submitted

Benoit Bolsee benoit.bolsee at online.be
Fri Jul 22 11:09:11 CEST 2011


Hi,

I changed the Matrix multiplication order beween 2.49 and 2.5 because it
was simply incorrect in 2.49, in the sense that it was not matching the
way you write matrix math on paper. 

In your example, 

>>> print (m1 * m2)
Matrix((0.0, 0.0, 1.0, 0.0),
(-1.0, 0.0, 0.0, 0.0),
(0.0, -1.0, 0.0, 0.0),
(0.62, 0.1, -0.05, 1.0))

is actually the correct answer if you remember that the matrix are
column major. The order should not be changed again. I see Campbell
reverted the patch, so that's ok.

@Campbell: the reason why numpy returns a different result than Blender
is because numpy matrix are row-major by default. The fact that Blender
uses column major matrix may be confusing when the matrix is printed
(columns are printed horizontally) but it's very convenient to extract
vectors from the matrix (e.g. the position vector).

While playing around I found something else that still doesn't work: in
the scientific literature, vectors are single column matrix, this means
that the only correct way to multiply a vector with a matrix is to put
it on the right side of the matrix:
v2 = m1 * v1
However, this doesn't work in Blender

>>> m
Matrix((1.0, 0.0, 0.0, 0.0),
       (0.0, 1.0, 0.0, 0.0),
       (1.0, 0.0, -1.0, 0.0),
       (0.0, 0.0, 0.0, 1.0))

>>> v
Vector((0.5, 0.0, 0.5, 1.0))

>>> m*v
Traceback (most recent call last):
  File "<blender_console>", line 1, in <module>
TypeError: Matrix multiplication: not supported between
'mathutils.Matrix' and 'mathutils.Vector' types

But the reverse expression gives the correct result (i.e the result of m
* v)

>>> v*m
Vector((1.0, 0.0, -0.5, 1.0))

which is illogical and should be fixed. Note that this incorrect form
has one benefit: it allows the use the shortcut expression "v*=m" to
apply a transformation matrix on a vector. 

I pretty certain that I set the matrix*vector multiplication order
correct at the same time I fixed the matrix*matrix multiplication order,
so I don't know where this new error is coming from. Note that v*m is an
acceptable expression if one considers that it turns v into a row
vector, but then the result of the multiplication is different of
course. 
In 2.49 it was possible to use both expressions m*v and v*m and they
were producing different results, except that there were the exact
opposite of what you should be by conventional matrix math.
 
Campbell, can you trace back what happened with vector multiplication in
Mathutils?

/Benoit

On Wed, 20 Jul 2011 20:12:50 -0500, "Scott Giese"
<scott.giese at comcast.net> wrote:
> 
> My reasoning for assuming this was a bug:
> 
> 1. Previously working scripts (2.49) broke.
> 
> 2. m1 *= m2 is equivalent to m1 = m1 * m2, where m1 
> represents the Base matrix and m2 represents the Influencing 
> matrix.  This is more intuitive to me.
> 	There is no equivalent shorthand for m1 = m2 * m1.
> 
> 	e.g. Apply a series of transforms to produce a single 
> transformation matrix
> 		contextMatrix = mathutils.Matrix()
> 		for part in parts:
> 			contextMatrix *= 
> data.tran.matrix[part.matrix_index]
> 			contextMatrix *=
> data.tran.matrix[part.parent.matrix_index]
> 		...
> 			newObject.matrix_basis = contextMatrix
> 			
> 3. Treating leftMatrix as the Base and rightMatrix as the 
> Influencing facilitates a hypothetical method of varying 
> argument counts.
> 	e.g.  resultMatrix = Matrix.Combine(baseMatrix, 
> translateMatrix, rotationMatrix, scaleMatrix, ...)
> 
> The above outlines my thought process.  I was not aware that 
> the change was intentional.  In light of the "... stop 
> breaking APIs?" discussion, we may be better served by 
> leaving it as-is.
> 
> Scott
> 
> -----Original Message-----
> From: Campbell Barton [mailto:ideasman42 at gmail.com] 
> Sent: Wednesday, July 20, 2011 2:16 AM
> To: bf-blender developers
> Subject: Re: [Bf-committers] Patches Submitted
> 
> On Wed, Jul 20, 2011 at 3:37 PM, Scott Giese <scott.giese at comcast.net>
> wrote:
> > Hi Gang,
> >
> >
> >
> > FYI. I submitted 3 patches for your review. ?I'm new to the 
> list and I 
> > wanted to give back to the Blender community.
> >
> >
> >
> > 28030 ?SCONS Build: Build Date reflects
> >
> <http://projects.blender.org/tracker/index.php?func=detail&aid
> =28030&group_i
> > d=9&atid=127> "1" instead of actual date of build
> >
> > 28031 ?Minor typo in Blenlib
> >
> <http://projects.blender.org/tracker/index.php?func=detail&aid
> =28031&group_i
> > d=9&atid=127>
> >
> > 28032 ?Python Mathutils: Matrix Multiplication Error
> >
> <http://projects.blender.org/tracker/index.php?func=detail&aid
> =28032&group_i
> > d=9&atid=127>
> >
> >
> >
> > Great work guys! ?Appreciate the great product.
> >
> >
> >
> > Scott
> 
> Thanks for the fixes, committed all patches however you're 
> changes to mathutils effectively only change the order of 
> multiplication,
> 
> http://projects.blender.org/tracker/index.php?func=detail&aid=
> 28032&group_id
> =9&atid=127
> 
> In you're example
> >>> print (m1 * m2)
> 
> Change to...
> >>> print (m2 * m1)
> 
> This is a bit confusing because in C we have
> mul_m4_m4m4(m1, m2);
>  which is the equivalent to "m2 * m1" in python.
> 
> A while back Benoit Bolsee was concerned our matrix 
> multiplication order was wrong so we switched it (between 
> 2.4x and 2.5x)
> 
> What makes you think the order in blender is wrong? what's 
> you're reference?
> 
> Just checked and we're currently doing matrix multiplication 
> differently to numpy which doesn't bode well :S - test:
> 
> # --- snip
> m1 = ((0.0, 0.0, 1.0, 0.0), (-1.0, 0.0, 0.0, 0.0), (0.0, 
> -1.0, 0.0, 0.0), (0.6, 0.0, -0.05, 1.0)) m2 = ((1.0, 0.0, 
> 0.0, 0.0), (0.0, 1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, 
> -0.02, -0.1, 1.0))
> 
> from numpy import matrix
> n_m1 = matrix(m1)
> n_m2 = matrix(m2)
> print("\nnumpy\n%r" % (n_m1 * n_m2))
> 
> from mathutils import Matrix
> b_m1 = Matrix(m1)
> b_m2 = Matrix(m2)
> print("\nmathutils\n%r" % (b_m1 * b_m2))
> 
> # --- output
> 
> numpy
> matrix([[ 0.  ,  0.  ,  1.  ,  0.  ],
>         [-1.  ,  0.  ,  0.  ,  0.  ],
>         [ 0.  , -1.  ,  0.  ,  0.  ],
>         [ 0.6 , -0.02, -0.15,  1.  ]])
> 
> mathutils
> Matrix((0.0, 0.0, 1.0, 0.0),
>        (-1.0, 0.0, 0.0, 0.0),
>        (0.0, -1.0, 0.0, 0.0),
>        (0.62, 0.1, -0.05, 1.0))
> 
> 
> # --- switch m1/m2 order for both mathutils and numpy. re-run
> 
> numpy
> matrix([[ 0.  ,  0.  ,  1.  ,  0.  ],
>         [-1.  ,  0.  ,  0.  ,  0.  ],
>         [ 0.  , -1.  ,  0.  ,  0.  ],
>         [ 0.62,  0.1 , -0.05,  1.  ]])
> 
> mathutils
> Matrix((0.0, 0.0, 1.0, 0.0),
>        (-1.0, 0.0, 0.0, 0.0),
>        (0.0, -1.0, 0.0, 0.0),
>        (0.6, -0.0, -0.15, 1.0))




More information about the Bf-committers mailing list