blender/scripts/modules/bpy_extras/id_map_utils.py
Campbell Barton 791505e2ed PyDoc: use :param: instead of :arg: in Sphinx docstrings
While "arg" isn't deprecated "param" is preferred and used in all
Sphinx's examples & tutorials.

Ref !154039
2026-02-07 14:30:16 +11:00

53 lines
1.7 KiB
Python

# SPDX-FileCopyrightText: 2022-2023 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
__all__ = (
"get_id_reference_map",
"get_all_referenced_ids",
)
def get_id_reference_map():
"""Return a dictionary of direct data-block references for every data-block in the blend file.
:return: Each datablock of the .blend file mapped to the set of IDs they directly reference.
:rtype: dict[bpy.types.ID, set[bpy.types.ID]]
"""
inv_map = {}
for key, values in bpy.data.user_map().items():
for value in values:
if value == key:
# So an object is not considered to be referencing itself.
continue
inv_map.setdefault(value, set()).add(key)
return inv_map
def get_all_referenced_ids(id, ref_map):
"""
Return a set of IDs directly or indirectly referenced by id.
:param id: Datablock whose references we're interested in.
:type id: bpy.types.ID
:param ref_map: The global ID reference map, retrieved from get_id_reference_map()
:type ref_map: dict[bpy.types.ID, set[bpy.types.ID]]
:return: Set of datablocks referenced by `id`.
:rtype: set[bpy.types.ID]
"""
def recursive_helper(ref_map, id, referenced_ids, visited):
if id in visited:
# Avoid infinite recursion from circular references.
return
visited.add(id)
for ref in ref_map.get(id, []):
referenced_ids.add(ref)
recursive_helper(ref_map=ref_map, id=ref, referenced_ids=referenced_ids, visited=visited)
referenced_ids = set()
recursive_helper(ref_map=ref_map, id=id, referenced_ids=referenced_ids, visited=set())
return referenced_ids