diff --git a/CHANGELOG.md b/CHANGELOG.md index 81dd383..cf74bf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ This file logs the changes that are actually interesting to users (new features, changed functionality, fixed bugs). +## Version 1.6 (in development) + +- Support linked collections used as input in a Geometry Nodes modifier. + + ## Version 1.5.1 (2021-07-22) - Add log warning if SegmentationFault caused by dereferencing invalid pointer is silenced when strict_pointer_mode is turned off. diff --git a/blender_asset_tracer/cdefs.py b/blender_asset_tracer/cdefs.py index 38fbbca..bbc9bd1 100644 --- a/blender_asset_tracer/cdefs.py +++ b/blender_asset_tracer/cdefs.py @@ -61,6 +61,17 @@ OB_DUPLIGROUP = 1 << 8 PTCACHE_DISK_CACHE = 64 PTCACHE_EXTERNAL = 512 +# DNA_ID_types.h +IDP_STRING = 0 +IDP_INT = 1 +IDP_FLOAT = 2 +IDP_ARRAY = 5 +IDP_GROUP = 6 +IDP_ID = 7 +IDP_DOUBLE = 8 +IDP_IDPARRAY = 9 +IDP_NUMTYPES = 10 + # BKE_pointcache.h PTCACHE_FILE_PTCACHE = 0 PTCACHE_FILE_OPENVDB = 1 diff --git a/blender_asset_tracer/trace/expanders.py b/blender_asset_tracer/trace/expanders.py index bce34c0..6b8da42 100644 --- a/blender_asset_tracer/trace/expanders.py +++ b/blender_asset_tracer/trace/expanders.py @@ -103,6 +103,28 @@ def _expand_generic_nodetree(block: blendfile.BlendFileBlock): yield node.get_pointer(b"id") +def _expand_generic_idprops(block: blendfile.BlendFileBlock): + """Yield ID datablocks and their libraries referenced from ID properties.""" + + # TODO(@sybren): this code is very crude, and happens to work on ID + # properties of Geometry Nodes modifiers, which is what it was written for. + # It should probably be rewritten to properly iterate over & recurse into + # all groups. + settings_props = block.get_pointer((b"settings", b"properties")) + if not settings_props: + return + + subprops = settings_props.get_pointer((b"data", b"group", b"first")) + for idprop in iterators.listbase(subprops): + if idprop[b"type"] != cdefs.IDP_ID: + continue + id_datablock = idprop.get_pointer((b"data", b"pointer")) + if not id_datablock: + continue + yield id_datablock + yield id_datablock.get_pointer(b"lib") + + def _expand_generic_nodetree_id(block: blendfile.BlendFileBlock): block_ntree = block.get_pointer(b"nodetree", None) if block_ntree is not None: @@ -251,6 +273,7 @@ def _expand_object(block: blendfile.BlendFileBlock): # Currently only node groups are supported. If the support should expand # to more types, something more intelligent than this should be made. if mod_type == cdefs.eModifierType_Nodes: + yield from _expand_generic_idprops(block_mod) yield block_mod.get_pointer(b"node_group") diff --git a/blender_asset_tracer/trace/file2blocks.py b/blender_asset_tracer/trace/file2blocks.py index 8604c52..63074d4 100644 --- a/blender_asset_tracer/trace/file2blocks.py +++ b/blender_asset_tracer/trace/file2blocks.py @@ -110,11 +110,7 @@ class BlockIterator: self.to_visit.put(lib) continue - if limit_to: - # We're limiting the blocks, so we have to expand them to make - # sure we don't miss anything. Otherwise we're yielding the - # entire file anyway, and no expansion is necessary. - self._queue_dependencies(block) + self._queue_dependencies(block) self.blocks_yielded.add((bpath, block.addr_old)) yield block @@ -167,6 +163,7 @@ class BlockIterator: def _queue_dependencies(self, block: blendfile.BlendFileBlock): for block in expanders.expand_block(block): + assert isinstance(block, blendfile.BlendFileBlock), "unexpected %r" % block self.to_visit.put(block) diff --git a/tests/blendfiles/geometry-nodes-2/lib_trash.blend b/tests/blendfiles/geometry-nodes-2/lib_trash.blend new file mode 100644 index 0000000..c021619 Binary files /dev/null and b/tests/blendfiles/geometry-nodes-2/lib_trash.blend differ diff --git a/tests/blendfiles/geometry-nodes-2/set_file.blend b/tests/blendfiles/geometry-nodes-2/set_file.blend new file mode 100644 index 0000000..6d13c09 Binary files /dev/null and b/tests/blendfiles/geometry-nodes-2/set_file.blend differ diff --git a/tests/blendfiles/geometry-nodes-2/shot_file.blend b/tests/blendfiles/geometry-nodes-2/shot_file.blend new file mode 100644 index 0000000..025d169 Binary files /dev/null and b/tests/blendfiles/geometry-nodes-2/shot_file.blend differ diff --git a/tests/test_tracer.py b/tests/test_tracer.py index 1ea7820..caa744d 100644 --- a/tests/test_tracer.py +++ b/tests/test_tracer.py @@ -436,6 +436,34 @@ class DepsTest(AbstractTracerTest): }, ) + def test_geometry_nodes_modifier_input(self): + """Test linked collection as input to geom nodes modifier. + + Here a Geometry Nodes modifier references a collection that is not + instanced into the scene, which caused it to be missed. + """ + self.assert_deps( + "geometry-nodes-2/shot_file.blend", + { + b"LIset_file.blend": Expect( + type="Library", + full_field="name[1024]", + dirname_field=None, + basename_field=None, + asset_path=b"//set_file.blend", + is_sequence=False, + ), + b"LIlib_trash.blend": Expect( + type="Library", + full_field="name[1024]", + dirname_field=None, + basename_field=None, + asset_path=b"//lib_trash.blend", + is_sequence=False, + ), + }, + ) + def test_usage_abspath(self): deps = [ dep