6
$\begingroup$

In my script I am trying to store a Matrix, for example the region_3d.view_matrix of a 3D view. This returns:

Matrix(((0.04198726266622543, 0.9991182684898376, 3.666877432806359e-07, -0.32331380248069763),
        (-0.349155992269516, 0.014672632329165936, 0.9369498491287231, -0.4471516013145447),
        (0.9361235499382019, -0.03934017941355705, 0.3494640588760376, 0.5855286717414856),
        (0.0, 0.0, 0.0, 1.0)))

How can I store this in one of Blender's bpy.props properties for access later? I thought FloatVectorProperty was closest, but that was just a guess and depending on what I try it complains either that I'm providing tuples or that it only wants 3 items, not 4.

$\endgroup$
  • $\begingroup$ hmm, It might sound stupid but if you just need to store it for access why don't you just declare it in a python object. $\endgroup$ – Yvain Apr 11 '16 at 19:42
  • $\begingroup$ @Yvain Will that survive saving and reloading the blend file? $\endgroup$ – Ray Mairlot Apr 11 '16 at 20:21
  • $\begingroup$ No chance, it will actually disappear as soon as you stop the script even while remaining in blender. Unless you set your python script to write the variable on an output text file $\endgroup$ – Yvain Apr 12 '16 at 8:01
3
$\begingroup$

I haven't tested this extensively, but it looks like you can store a matrix as an "ID" property rather than a bpy.props property. I stored a matrix like this from the Python console:

>>> C.object['matrix'] = m

where m was a 4x4 matrix

It appears that it was actually stored as an array of four arrays:

>>> C.object['matrix']
[<bpy id property array [4]>, <bpy id property array [4]>,
<bpy id property array [4]>, <bpy id property array [4]>]

I saved the file and reopened it, and the value was still intact. It can even be typecast back to a Matrix:

>>> Matrix(C.object['matrix'])
Matrix(((0.68588, -0.31737, 0.65486, 7.48113),
        (0.72763, 0.31246, -0.61066, -6.50763),
        (-0.01081, 0.89534, 0.44524, 5.34366),
        (0.0, 0.0, 0.0, 1.0)))

(I truncated the precision of the numbers for readability).

$\endgroup$
5
$\begingroup$

If you choose MATRIX as subtype the property will return a mathutils.Matrix object on access. So you might define a utility function to set the attribute

import bpy
from mathutils import Matrix

def flatten(mat):
    dim = len(mat)
    return [mat[j][i] for i in range(dim) 
                      for j in range(dim)]

bpy.types.Scene.matrix_property = bpy.props.FloatVectorProperty(
    name="Matrix",
    size=16,
    subtype="MATRIX")

mat = Matrix([[i + j for j in range(4)]
                     for i in range(0, 16, 4)])

scene = bpy.context.scene
scene.matrix_property = flatten(mat)

print(mat)
print(scene.matrix_property)
$\endgroup$
  • 1
    $\begingroup$ Took me a while to understand what flattern was doing, but I get it now. Is it strange there is no built in way to flatten a Matrix? $\endgroup$ – Ray Mairlot Apr 12 '16 at 11:11
  • $\begingroup$ Just an into this, very weird indeed. Thanks @pink-vertex $\endgroup$ – MACHIN3 May 21 '18 at 18:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.