Add Support for Geometry Node Cache #92890
@ -166,6 +166,7 @@ class BlendFile:
|
||||
break
|
||||
|
||||
if block.code == b"DNA1":
|
||||
# for i in range(block.count):
|
||||
self.decode_structs(block)
|
||||
else:
|
||||
self.fileobj.seek(block.size, os.SEEK_CUR)
|
||||
@ -350,25 +351,10 @@ class BlendFile:
|
||||
else:
|
||||
dna_size = dna_type.size * dna_name.array_size
|
||||
|
||||
if dna_name.name_only == b"bakes":
|
||||
array_count = 3 # Total elements in the array
|
||||
item_size = 48 # Size of each item in the array
|
||||
dna_size = (
|
||||
item_size * array_count
|
||||
) # Total size occupied by the array
|
||||
|
||||
# Create a single field for the entire array
|
||||
field = dna.Field(dna_type, dna_name, dna_size, dna_offset)
|
||||
dna_struct.append_field(field)
|
||||
dna_offset += (
|
||||
dna_size # Increment offset by the total size of the array
|
||||
)
|
||||
|
||||
else:
|
||||
# For other fields, proceed as usual
|
||||
field = dna.Field(dna_type, dna_name, dna_size, dna_offset)
|
||||
dna_struct.append_field(field)
|
||||
dna_offset += dna_size
|
||||
# For other fields, proceed as usual
|
||||
field = dna.Field(dna_type, dna_name, dna_size, dna_offset)
|
||||
dna_struct.append_field(field)
|
||||
dna_offset += dna_size
|
||||
|
||||
def abspath(self, relpath: bpathlib.BlendPath) -> bpathlib.BlendPath:
|
||||
"""Construct an absolute path from a blendfile-relative path."""
|
||||
@ -486,6 +472,12 @@ class BlendFileBlock:
|
||||
self.addr_old = blockheader[2]
|
||||
self.sdna_index = blockheader[3]
|
||||
self.count = blockheader[4]
|
||||
|
||||
# if self.count > 1:
|
||||
# self.size = self.size // self.count
|
||||
# if self.count > 1:
|
||||
# print(self.count)
|
||||
# print("size is 144")
|
||||
self.file_offset = bfile.fileobj.tell()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
@ -774,6 +766,35 @@ class BlendFileBlock:
|
||||
continue
|
||||
yield dereferenced
|
||||
|
||||
def iter_array_from_pointer(
|
||||
self, path: dna.FieldPath, array_size: int
|
||||
) -> typing.Iterator["BlendFileBlock"]:
|
||||
"""Dereference pointers from an array field.
|
||||
|
||||
:param path: The array-of-pointers field.
|
||||
:param array_size: Number of items in the array. If None, the
|
||||
on-disk size of the DNA field is divided by the pointer size to
|
||||
obtain the array size.
|
||||
"""
|
||||
if array_size == 0:
|
||||
return
|
||||
|
||||
array = self.get_pointer(path)
|
||||
array_ptr = self.get(path)
|
||||
|
||||
assert array_ptr is not None
|
||||
|
||||
item_size = array.size // array_size
|
||||
|
||||
for i in range(array_size):
|
||||
print(i)
|
||||
address = array_ptr + (item_size * i)
|
||||
print(address)
|
||||
if address == 0:
|
||||
continue
|
||||
dereferenced = self.bfile.dereference_pointer(address)
|
||||
yield dereferenced
|
||||
|
||||
def iter_fixed_array_of_pointers(
|
||||
self, path: dna.FieldPath
|
||||
) -> typing.Iterator["BlendFileBlock"]:
|
||||
|
@ -27,7 +27,7 @@ import struct
|
||||
import logging
|
||||
import typing
|
||||
from blender_asset_tracer.blendfile import iterators
|
||||
from blender_asset_tracer.blendfile.dna import Struct
|
||||
from blender_asset_tracer.blendfile.dna import Struct, Field, Name
|
||||
|
||||
from blender_asset_tracer import blendfile, bpathlib, cdefs
|
||||
from . import result
|
||||
@ -325,13 +325,18 @@ def modifier_cloth(
|
||||
)
|
||||
|
||||
|
||||
def split_bytes_array(raw_data: bytes, item_size: int) -> typing.Iterator[bytes]:
|
||||
def split_bytes_array(block: blendfile.BlendFileBlock) -> typing.Iterator[bytes]:
|
||||
"""Split a bytes array into parts based on the Struct definition."""
|
||||
raw_data = block.raw_data()
|
||||
item_size = block.dna_type.size
|
||||
for i in range(0, len(raw_data), item_size):
|
||||
data_part = raw_data[i : i + item_size]
|
||||
yield data_part
|
||||
|
||||
|
||||
def bytes_to_struct(data_bytes: bytes, struct_type: Struct):
|
||||
def bytes_to_struct(
|
||||
data_bytes: bytes, struct_type: Struct, block: blendfile.BlendFileBlock
|
||||
) -> dict:
|
||||
"""Convert raw bytes into a struct based on the provided Struct definition."""
|
||||
struct_instance = {}
|
||||
|
||||
@ -340,9 +345,16 @@ def bytes_to_struct(data_bytes: bytes, struct_type: Struct):
|
||||
end = start + field.size
|
||||
field_data = data_bytes[start:end]
|
||||
|
||||
value = field_data.hex()
|
||||
if field.name.name_only == b"directory":
|
||||
directory_pointer = int.from_bytes(field_data, "little")
|
||||
directory = block.bfile.dereference_pointer(directory_pointer).as_string()
|
||||
struct_instance["directory"] = directory
|
||||
|
||||
struct_instance[field.name.name_only] = value
|
||||
if field.name.name_only == b"flag":
|
||||
flag_bin = bin(int.from_bytes(field_data, "little"))
|
||||
flag_bin_padded = flag_bin[2:].zfill(2)
|
||||
use_custom_directory = flag_bin_padded[0]
|
||||
struct_instance["use_custom_directory"] = use_custom_directory
|
||||
|
||||
return struct_instance
|
||||
|
||||
@ -352,22 +364,21 @@ def modifier_nodes(
|
||||
ctx: ModifierContext, modifier: blendfile.BlendFileBlock, block_name: bytes
|
||||
) -> typing.Iterator[result.BlockUsage]:
|
||||
bake_directory = modifier.get_pointer(b"simulation_bake_directory")
|
||||
# print(bake_directory)
|
||||
|
||||
bakes_ptr = modifier.get(b"bakes")
|
||||
bakes_num = modifier.get(b"bakes_num")
|
||||
bake_directory = bake_directory.as_string()
|
||||
bakes = modifier.get_pointer(b"bakes")
|
||||
raw_bakes = bakes.raw_data()
|
||||
|
||||
dna_type = bakes.dna_type
|
||||
print(list(bakes.values()))
|
||||
|
||||
bakes_split = split_bytes_array(raw_bakes, dna_type.size)
|
||||
bakes_split = split_bytes_array(bakes)
|
||||
|
||||
for bake_bytes in bakes_split:
|
||||
bake_struct = bytes_to_struct(bake_bytes, dna_type)
|
||||
print(bake_struct)
|
||||
bake_struct = bytes_to_struct(bake_bytes, dna_type, modifier)
|
||||
JonasDichelle marked this conversation as resolved
|
||||
if bake_struct["use_custom_directory"] == "1":
|
||||
directory = bake_struct["directory"]
|
||||
else:
|
||||
directory = bake_directory
|
||||
|
||||
# yield bake_struct
|
||||
print(directory)
|
||||
|
||||
quit()
|
||||
# yield from _walk_point_cache(
|
||||
# ctx, block_name, modifier.bfile, pointcache, cdefs.PTCACHE_EXT
|
||||
# )
|
||||
|
Loading…
Reference in New Issue
Block a user
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: