BlendFileBlock.get to support accessing different items in the file-block (#92898)
Add an `array_index` parameter to `block.get(property_name)` to get a specific item from an array. Example: ```python verts = self.bf.block_from_addr[verts_ptr] assert verts.get(b"co") == [-1.0, -1.0, -1.0] # index 0 assert verts.get(b"co", array_index=1) == [-1.0, -1.0, 1.0] ``` Reviewed-on: https://projects.blender.org/blender/blender-asset-tracer/pulls/92898
This commit is contained in:
committed by
Sybren A. Stüvel
parent
b1c4f5e116
commit
c69612b264
@@ -596,6 +596,7 @@ class BlendFileBlock:
|
||||
null_terminated=True,
|
||||
as_str=False,
|
||||
return_field=False,
|
||||
array_index=0,
|
||||
) -> typing.Any:
|
||||
"""Read a property and return the value.
|
||||
|
||||
@@ -612,8 +613,20 @@ class BlendFileBlock:
|
||||
(assumes UTF-8 encoding).
|
||||
:param return_field: When True, returns tuple (dna.Field, value).
|
||||
Otherwise just returns the value.
|
||||
:param array_index: If the property is an array, this determines the
|
||||
index of the returned item from that array. Also see
|
||||
`blendfile.iterators.dynamic_array()` for iterating such arrays.
|
||||
"""
|
||||
self.bfile.fileobj.seek(self.file_offset, os.SEEK_SET)
|
||||
file_offset = self.file_offset
|
||||
if array_index:
|
||||
if not (0 <= array_index < self.count):
|
||||
raise IndexError(
|
||||
"Invalid 'array_index' for file-block. "
|
||||
f"Expected int value in range 0-{self.count - 1}, got {array_index}."
|
||||
)
|
||||
file_offset += array_index * self.dna_type.size
|
||||
|
||||
self.bfile.fileobj.seek(file_offset, os.SEEK_SET)
|
||||
|
||||
dna_struct = self.bfile.structs[self.sdna_index]
|
||||
field, value = dna_struct.field_get(
|
||||
|
||||
@@ -81,6 +81,9 @@ def dynamic_array(block: BlendFileBlock) -> typing.Iterator[BlendFileBlock]:
|
||||
pointer. BAT interprets these as a single data block, making it hard to
|
||||
access individual elements. This function divides the array into individual
|
||||
blocks by creating modified copies of the original block.
|
||||
|
||||
See `some_block.get(b'name', array_index)` if you want to access elements by
|
||||
index (instead of iterating).
|
||||
"""
|
||||
|
||||
element_size = block.dna_type.size
|
||||
|
||||
Reference in New Issue
Block a user