This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/release/scripts/modules/bpy_extras/id_map_utils.py
Demeter Dzadik 26d375467b bpy_extras: Add utilities for getting ID references
An alternate to D14839, implemented in Python and
relying on bpy.data.user_map(). That function
gives us a mapping of what ID is referenced by
what set of IDs. The inverse of this would also
be useful, which is now available from
bpy_extras.id_map_utils.get_id_reference_map().

From there, we can use get_all_referenced_ids()
to get a set of all IDs referenced by a given ID
either directly or indirectly.

To get only the direct references, we can simply
pass the ID of interest as a key to the dictionary
returned from get_id_reference_map().

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D14843
2022-05-06 16:42:59 +02:00

50 lines
1.4 KiB
Python

# SPDX-License-Identifier: GPL-2.0-or-later
# <pep8 compliant>
from typing import Dict, Set
import bpy
from bpy.types import ID
__all__ = (
"get_id_reference_map",
"get_all_referenced_ids",
)
def get_id_reference_map() -> Dict[ID, Set[ID]]:
"""Return a dictionary of direct datablock references for every datablock in the blend file."""
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 recursive_get_referenced_ids(
ref_map: Dict[ID, Set[ID]], id: ID, referenced_ids: Set, visited: Set
):
"""Recursively populate referenced_ids with IDs referenced by id."""
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_get_referenced_ids(
ref_map=ref_map, id=ref, referenced_ids=referenced_ids, visited=visited
)
def get_all_referenced_ids(id: ID, ref_map: Dict[ID, Set[ID]]) -> Set[ID]:
"""Return a set of IDs directly or indirectly referenced by id."""
referenced_ids = set()
recursive_get_referenced_ids(
ref_map=ref_map, id=id, referenced_ids=referenced_ids, visited=set()
)
return referenced_ids