Add Support for Geometry Node Cache #92890
No reviewers
Labels
No Label
legacy module
Platforms, Builds, Tests & Devices
legacy project
Blender Asset Tracer
legacy project
Platform: Windows
Priority::Normal
Status::Archived
Status::Confirmed
Status::Needs Triage
Status::Resolved
Type::Design
Type::Report
Type::To Do
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender-asset-tracer#92890
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "JonasDichelle/blender-asset-tracer:geonodes_support"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This PR adds support for tracking the geometry node cache through a custom iterator because
modifier.bakes
is a pointer to a dynamic array.Currently, BAT interprets the target of a pointer as a single block. Because dynamic arrays are defined only by a single pointer, they are decoded like this:
So, without changing the struct decoding behavior of BAT, this seems to be the best way to parse the array:
NodesModifierBake
block for each element of the array.To do this, I added a new iterator called
dynamic_array
that yields blocks representing each element within the dynamic array.Unless I'm mistaken, it looks like dynamic arrays aren't typically used for structs like this in Blender, which is likely why BAT hasn't had to handle them before.
I added a zip to test this PR:
Thanks for the PR! I've left some inline notes.
Could you also add some unit tests that cover these changes? Especially since you introduce the support for dynamic arrays (which is very nice to have in there), I feel that this should be tested properly (also to ensure it doesn't break in future updates).
@ -12,2 +12,4 @@
/docs/_build
/.env
The use of these directories is quite personal, and differs from developer to developer. Please put those into your
.git/info/exclude
file. That behaves like an extra.gitignore
but isn't tracked by Git.@ -130,3 +130,1 @@
self.code_index = collections.defaultdict(
list
) # type: typing.Dict[bytes, BFBList]
self.code_index = collections.defaultdict(list) # type: typing.Dict[bytes, BFBList]
Please keep formatting changes out of this PR. There is no direct need for this PR to modify this file.
Of course non-functional improvements like this are always welcome, but shouldn't be part of the same PR as functional changes.
@ -72,1 +72,4 @@
yield from listbase(mods, next_path=(b"modifier", b"next"))
def copy_block(block: BlendFileBlock) -> BlendFileBlock:
I think it's fine to make this function a method on
BlendFileBlock
. It could then simply be named.clone()
or.copy()
.Then again, is there any reason to not use copy.copy() and avoid the need for this function altogether?
yes copy should work fine for this too.
@ -73,0 +86,4 @@
def dynamic_array(block: BlendFileBlock) -> typing.Iterator[BlendFileBlock]:
"""Generator, yields all blocks in a block that is a dynamic array."""
Please add a bit more explanation to this documentation. This first line is fine, but then I would love to see some explanation of what a "dynamic array" is in this context.
@ -73,0 +91,4 @@
for i in range(block.count):
new_block = copy_block(block)
new_block.file_offset = offset
new_block.size = block.dna_type.size // block.count
Instead of making Python do the
block.dna_type.size
lookup twice per loop, do that once outside the loop and store the value in a local variable.@ -73,0 +94,4 @@
new_block.size = block.dna_type.size // block.count
yield new_block
offset += block.dna_type.size
Either
block.dna_type.size
is the total size of the entire array (in which case this needs the// block.count
) or it is the size of a single element in the array (in which case the// block.count
above is incorrect).It's the size of an element the division there is incorrect.
@ -354,0 +371,4 @@
flag = bake.get(b"flag")
flag_bin = bin(flag)
flag_bin_padded = flag_bin[2:].zfill(2)
use_custom_directory = flag_bin_padded[0] == "1"
Please don't use string operations to get a single bit flag. Add a constant to
cdefs.py
with the name of the flag, then use something like:@ -354,0 +382,4 @@
field = mod_directory_field
block = modifier
if directory_ptr == 0:
I think it's slightly nicer to not compare to a concrete value, and just use
if not directory_ptr:
Thank you for your feedback!
I made all of the changes you requested and added a unit test for dynamic arrays.
Might be good to add more tests in the future, not sure what would be some good structs to test on though.
Checkout
From your project repository, check out a new branch and test the changes.