stub block loading functions
This commit is contained in:
parent
eb971d6905
commit
0ded5249d8
@ -11,11 +11,6 @@ class Blendfile(io.FileIO):
|
||||
self.read_header()
|
||||
# Offsets of each file block by code.
|
||||
self._block_offsets = self._read_block_offsets()
|
||||
|
||||
# Looping through file block headers to find scene header
|
||||
for block_code, offset in self._block_offsets.items():
|
||||
if block_code.startswith("SC"):
|
||||
print(f"Found scene block at offset {offset}!")
|
||||
|
||||
def _read_block_offsets(self):
|
||||
"""
|
||||
@ -33,7 +28,7 @@ class Blendfile(io.FileIO):
|
||||
block_offsets[block_code] = self.tell()
|
||||
# Size of file block, after this header
|
||||
block_size = int.from_bytes(self.read(4), self.endianness)
|
||||
|
||||
|
||||
# Skip rest of file header.
|
||||
self.seek(self.pointer_size + 8, io.SEEK_CUR)
|
||||
# Skip to next file block.
|
||||
@ -41,6 +36,19 @@ class Blendfile(io.FileIO):
|
||||
|
||||
return block_offsets
|
||||
|
||||
def _read_sdna_indexes(self):
|
||||
"""
|
||||
Cache the index and offset of each SDNA structure name.
|
||||
"""
|
||||
pass
|
||||
|
||||
def _load_sdna(self, sdna_index):
|
||||
"""
|
||||
Load an SDNA struct as a dict describing the structures.
|
||||
"""
|
||||
# We could consider caching recently loaded SDNA structs.
|
||||
pass
|
||||
|
||||
def read_header(self):
|
||||
self.seek(0)
|
||||
|
||||
@ -54,4 +62,52 @@ class Blendfile(io.FileIO):
|
||||
self.endianness = "little" if self.read(1).decode("utf-8") == "v" else "big"
|
||||
|
||||
# Blender version, 3-byte int; v2.93 is represented as 293, and so on
|
||||
self.version = int(self.read(3))
|
||||
self.version = int(self.read(3))
|
||||
|
||||
def get_blocks(self, match=""):
|
||||
"""
|
||||
Get file blocks from the blend file.
|
||||
|
||||
To be efficient, functions that load the file blocks will be returned.
|
||||
|
||||
:param match: Filter file blocks by matching the beginning of the name
|
||||
against a string. Default is "" (matches everything). Case sensitive.
|
||||
:return A dictionary mapping identifiers to a function to load the
|
||||
block.
|
||||
"""
|
||||
# Invoking the load_block() closure will load the file block at offset.
|
||||
def create_loader(at_offset):
|
||||
def load_block():
|
||||
return self._load_block(at_offset)
|
||||
return load_block
|
||||
|
||||
matched_blocks = {}
|
||||
for identifier, offset in self._block_offsets.items():
|
||||
if identifier.startswith(match):
|
||||
matched_blocks[identifier] = create_loader(offset)
|
||||
return matched_blocks
|
||||
|
||||
def _load_block(self, offset):
|
||||
"""
|
||||
Load a file block at a given offset to the beginning of the blend file.
|
||||
|
||||
:param offset: The offset of the file block.
|
||||
:return Generator that yields dictionaries, each representing a struct.
|
||||
"""
|
||||
# We might allow loading cached blocks after the file is closed, so
|
||||
# I'm leaving this here to be explicit. XD
|
||||
if self.closed:
|
||||
raise ValueError("I/O operation on a closed file.")
|
||||
|
||||
# Grab SDNA index and struct count from file block header.
|
||||
|
||||
self.seek(offset + 4 + 4 + self.pointer_size)
|
||||
sdna_index = int.from_bytes(self.read(4), self.endianness)
|
||||
count = int.from_bytes(self.read(4), self.endianness)
|
||||
|
||||
sdna_struct = self._load_sdna(sdna_index)
|
||||
|
||||
# TODO load structs according to SDNA.
|
||||
for _ in range(count):
|
||||
translated = {}
|
||||
yield translated
|
Loading…
x
Reference in New Issue
Block a user