diff --git a/utils/blendfile.py b/utils/blendfile.py
index 0891cfa43efff3b819f5791f5e7018b370fc7a9e..59bbd67c580b81df295c8db84e122305c127da43 100644
--- a/utils/blendfile.py
+++ b/utils/blendfile.py
@@ -410,6 +410,29 @@ class BlendFileBlock:
                 use_nil=use_nil, use_str=use_str,
                 )
 
+    def get_recursive_iter(self, path, path_root=b"",
+                           default=...,
+                           sdna_index_refine=None,
+                           use_nil=True, use_str=True,
+                           base_index=0,
+                           ):
+        path_full = path_root + b"." + path if path_root else path
+        try:
+            yield (path_full, self.get(path_full, default, sdna_index_refine, use_nil, use_str, base_index))
+        except NotImplementedError as err:
+            msg, dna_name, dna_type = err.args
+            struct_index = self.file.sdna_index_from_id.get(dna_type.dna_type_id, None)
+            if struct_index is None:
+                yield (path_full, "<%s>" % dna_type.dna_type_id.decode('ascii'))
+            else:
+                struct = self.file.structs[struct_index]
+                for f in struct.fields:
+                    yield from self.get_recursive_iter(f.dna_name.name_only, path_full, default, None, use_nil, use_str, 0)
+
+    def items_recursive_iter(self):
+        for k in self.keys():
+            yield from self.get_recursive_iter(k, use_str=False)
+
     def set(self, path, value,
             sdna_index_refine=None,
             ):
@@ -470,14 +493,16 @@ class BlendFileBlock:
             try:
                 yield self[k]
             except NotImplementedError as err:
-                yield ...
+                msg, dna_name, dna_type = err.args
+                yield "<%s>" % dna_type.dna_type_id.decode('ascii')
 
     def items(self):
         for k in self.keys():
             try:
                 yield (k, self[k])
             except NotImplementedError as err:
-                yield (k, ...)
+                msg, dna_name, dna_type = err.args
+                yield (k, "<%s>" % dna_type.dna_type_id.decode('ascii'))
 
 
 # -----------------------------------------------------------------------------
@@ -692,10 +717,20 @@ class DNAStruct:
         if dna_name.is_pointer:
             return DNA_IO.read_pointer(handle, header)
         elif dna_type.dna_type_id == b'int':
+            if dna_name.array_size > 1:
+                return [DNA_IO.read_int(handle, header) for i in range(dna_name.array_size)]
             return DNA_IO.read_int(handle, header)
         elif dna_type.dna_type_id == b'short':
+            if dna_name.array_size > 1:
+                return [DNA_IO.read_short(handle, header) for i in range(dna_name.array_size)]
             return DNA_IO.read_short(handle, header)
+        elif dna_type.dna_type_id == b'uint64_t':
+            if dna_name.array_size > 1:
+                return [DNA_IO.read_ulong(handle, header) for i in range(dna_name.array_size)]
+            return DNA_IO.read_ulong(handle, header)
         elif dna_type.dna_type_id == b'float':
+            if dna_name.array_size > 1:
+                return [DNA_IO.read_float(handle, header) for i in range(dna_name.array_size)]
             return DNA_IO.read_float(handle, header)
         elif dna_type.dna_type_id == b'char':
             if use_str:
@@ -709,7 +744,7 @@ class DNAStruct:
                 else:
                     return DNA_IO.read_bytes(handle, dna_name.array_size)
         else:
-            raise NotImplementedError("%r exists but isn't pointer, can't resolve field %r" % (path, dna_name.name_only))
+            raise NotImplementedError("%r exists but isn't pointer, can't resolve field %r" % (path, dna_name.name_only), dna_name, dna_type)
 
     def field_set(self, header, handle, path, value):
         assert(type(path) == bytes)
@@ -727,7 +762,7 @@ class DNAStruct:
             else:
                 return DNA_IO.write_bytes(handle, value, dna_name.array_size)
         else:
-            raise NotImplementedError("Setting %r is not yet supported" % dna_type[0])
+            raise NotImplementedError("Setting %r is not yet supported" % dna_type[0], dna_name, dna_type)
 
 
 class DNA_IO:
@@ -796,6 +831,13 @@ class DNA_IO:
         st = DNA_IO.USHORT[fileheader.endian_index]
         return st.unpack(handle.read(st.size))[0]
 
+    SSHORT = struct.Struct(b'<h'), struct.Struct(b'>h')
+
+    @staticmethod
+    def read_short(handle, fileheader):
+        st = DNA_IO.SSHORT[fileheader.endian_index]
+        return st.unpack(handle.read(st.size))[0]
+
     UINT = struct.Struct(b'<I'), struct.Struct(b'>I')
 
     @staticmethod
@@ -810,15 +852,11 @@ class DNA_IO:
         st = DNA_IO.SINT[fileheader.endian_index]
         return st.unpack(handle.read(st.size))[0]
 
-    @staticmethod
-    def read_float(handle, fileheader):
-        return struct.unpack(fileheader.endian_str + b'f', handle.read(4))[0]
-
-    SSHORT = struct.Struct(b'<h'), struct.Struct(b'>h')
+    FLOAT = struct.Struct(b'<f'), struct.Struct(b'>f')
 
     @staticmethod
-    def read_short(handle, fileheader):
-        st = DNA_IO.SSHORT[fileheader.endian_index]
+    def read_float(handle, fileheader):
+        st = DNA_IO.FLOAT[fileheader.endian_index]
         return st.unpack(handle.read(st.size))[0]
 
     ULONG = struct.Struct(b'<Q'), struct.Struct(b'>Q')