From 4c429e921228259f47795f8ad913ad3eff8fac71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 11 Jul 2025 15:19:53 +0200 Subject: [PATCH] Read blendfile sub-version Add support for reading the blend file's sub-version. --- blender_asset_tracer/blendfile/__init__.py | 22 ++++++++++++++++++++++ tests/test_blendfile_loading.py | 12 ++++++++++++ 2 files changed, 34 insertions(+) diff --git a/blender_asset_tracer/blendfile/__init__.py b/blender_asset_tracer/blendfile/__init__.py index 041db61..e09ce3f 100644 --- a/blender_asset_tracer/blendfile/__init__.py +++ b/blender_asset_tracer/blendfile/__init__.py @@ -122,6 +122,7 @@ class BlendFile: self.filepath = path self.raw_filepath = path self._is_modified = False + self.file_subversion = 0 self.fileobj = self._open_file(path, mode) self.blocks = [] # type: BFBList @@ -169,6 +170,8 @@ class BlendFile: if block.code == b"DNA1": self.decode_structs(block) + elif block.code == b"GLOB": + self.decode_glob(block) else: self.fileobj.seek(block.size, os.SEEK_CUR) @@ -356,6 +359,25 @@ class BlendFile: dna_struct.append_field(field) dna_offset += dna_size + def decode_glob(self, block: "BlendFileBlock") -> None: + """Partially decode the GLOB block to get the file sub-version.""" + # Before this, the subversion didn't exist in 'FileGlobal'. + if self.header.version <= 242: + self.file_subversion = 0 + return + + # GLOB can appear in the file before DNA1, and so we cannot use DNA to + # parse the fields. + + # The subversion is always the `short` at offset 4. + # block_data = io.BytesIO(block.raw_data()) + endian = self.header.endian + self.fileobj.seek(4, os.SEEK_CUR) # Skip the next 4 bytes. + self.file_subversion = endian.read_short(self.fileobj) + + # Skip to the next block. + self.fileobj.seek(block.file_offset + block.size, os.SEEK_SET) + def abspath(self, relpath: bpathlib.BlendPath) -> bpathlib.BlendPath: """Construct an absolute path from a blendfile-relative path.""" diff --git a/tests/test_blendfile_loading.py b/tests/test_blendfile_loading.py index 505b101..4dea438 100644 --- a/tests/test_blendfile_loading.py +++ b/tests/test_blendfile_loading.py @@ -477,3 +477,15 @@ class BlendFileCacheTest(AbstractBlendFileTest): self.assertIs(bf, blendfile._cached_bfiles[other]) self.assertEqual(str(bf.raw_filepath), bf.fileobj.name) + + +class BlendFileSubVersionTest(AbstractBlendFileTest): + def test_file_subversion(self) -> None: + self.bf = blendfile.BlendFile(self.blendfiles / "multiple_materials.blend") + self.assertEqual(self.bf.file_subversion, 3) + + self.bf = blendfile.BlendFile( + self.blendfiles + / "compositor_nodes/compositor_nodes_blender500_library.blend" + ) + self.assertEqual(self.bf.file_subversion, 36)