Added block expansion
The expansion process follows pointers and library links to construct the full set of actually-used data blocks. This set consists of all data blocks in the initial blend file, and all *actually linked-to* data blocks in linked blend files. I've also removed non-recursive dependency listing.
This commit is contained in:
@@ -300,7 +300,7 @@ class BlendFile:
|
||||
try:
|
||||
return self.block_from_addr[address]
|
||||
except KeyError:
|
||||
raise exceptions.SegmentationFault('address does not exist', address)
|
||||
raise exceptions.SegmentationFault('address does not exist', address) from None
|
||||
|
||||
|
||||
class BlendFileBlock:
|
||||
@@ -375,6 +375,10 @@ class BlendFileBlock:
|
||||
self.addr_old == other.addr_old and
|
||||
self.bfile.filepath == other.bfile.filepath)
|
||||
|
||||
def __bool__(self) -> bool:
|
||||
"""Data blocks are always True."""
|
||||
return True
|
||||
|
||||
@property
|
||||
def dna_type(self) -> dna.Struct:
|
||||
return self.bfile.structs[self.sdna_index]
|
||||
@@ -581,6 +585,8 @@ class BlendFileBlock:
|
||||
fileobj = self.bfile.fileobj
|
||||
fileobj.seek(file_offset + ps * i, os.SEEK_SET)
|
||||
address = endian.read_pointer(fileobj, ps)
|
||||
if address == 0:
|
||||
continue
|
||||
yield self.bfile.dereference_pointer(address)
|
||||
|
||||
def iter_fixed_array_of_pointers(self, path: dna.FieldPath) \
|
||||
|
||||
@@ -1,10 +1,39 @@
|
||||
import typing
|
||||
|
||||
from blender_asset_tracer import cdefs
|
||||
from . import BlendFileBlock
|
||||
from .dna import FieldPath
|
||||
|
||||
|
||||
def listbase(block: BlendFileBlock, next_path: FieldPath=b'next') -> BlendFileBlock:
|
||||
def listbase(block: BlendFileBlock, next_path: FieldPath = b'next') \
|
||||
-> typing.Iterator[BlendFileBlock]:
|
||||
"""Generator, yields all blocks in the ListBase linked list."""
|
||||
while block:
|
||||
yield block
|
||||
next_ptr = block[next_path]
|
||||
block = block.bfile.find_block_from_address(next_ptr)
|
||||
|
||||
|
||||
def sequencer_strips(sequence_editor: BlendFileBlock) \
|
||||
-> typing.Iterator[typing.Tuple[BlendFileBlock, int]]:
|
||||
"""Generator, yield all sequencer strip blocks with their type number.
|
||||
|
||||
Recurses into meta strips, yielding both the meta strip itself and the
|
||||
strips contained within it.
|
||||
|
||||
See blender_asset_tracer.cdefs.SEQ_TYPE_xxx for the type numbers.
|
||||
"""
|
||||
|
||||
def iter_seqbase(seqbase) -> typing.Iterator[BlendFileBlock]:
|
||||
for seq in listbase(seqbase):
|
||||
seq.refine_type(b'Sequence')
|
||||
seq_type = seq[b'type']
|
||||
yield seq, seq_type
|
||||
|
||||
if seq_type == cdefs.SEQ_TYPE_META:
|
||||
# Recurse into this meta-sequence.
|
||||
subseq = seq.get_pointer((b'seqbase', b'first'))
|
||||
yield from iter_seqbase(subseq)
|
||||
|
||||
sbase = sequence_editor.get_pointer((b'seqbase', b'first'))
|
||||
yield from iter_seqbase(sbase)
|
||||
|
||||
Reference in New Issue
Block a user