Support linked collections used as input in a Geometry Nodes modifier
Add support for linked collections that are used as input in a Geometry Nodes modifier. This requires iterating over the geometry nodes modifier settings, which consists of ID properties. If such an ID property is of type `IDP_ID`, its pointer is followed and the pointed-to datablock + its library are visited. This following of pointers happens in the 'expand' phase, which was only done for linked library blend files. Since this commit, the old behaviour of simply looping over all non-`DATA` datablocks of the to-be-packed blend file is not enough, and datablock expansion is done for all local datablocks as well.
This commit is contained in:
@@ -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")
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user