forked from bartvdbraak/blender
Fix T91169: bpy_extras.io_utils.create_derived_objects -> duplis error
This function now takes a depsgraph and a list of objects to avoid inefficient O(n^2) iteration when extracting instances from all objects in the scene. Returning an object -> instance map. Note that keeping compatibility with the existing API wasn't practical in this case since instances can no longer be generated from the scene and it's objects.
This commit is contained in:
parent
0ceded7bc9
commit
a82c9e1e40
@ -25,7 +25,6 @@ __all__ = (
|
||||
"axis_conversion",
|
||||
"axis_conversion_ensure",
|
||||
"create_derived_objects",
|
||||
"free_derived_objects",
|
||||
"unpack_list",
|
||||
"unpack_face_list",
|
||||
"path_reference",
|
||||
@ -348,21 +347,40 @@ def axis_conversion_ensure(operator, forward_attr, up_attr):
|
||||
return False
|
||||
|
||||
|
||||
# return a tuple (free, object list), free is True if memory should be freed
|
||||
# later with free_derived_objects()
|
||||
def create_derived_objects(scene, ob):
|
||||
if ob.parent and ob.parent.instance_type in {'VERTS', 'FACES'}:
|
||||
return False, None
|
||||
def create_derived_objects(depsgraph, objects):
|
||||
"""
|
||||
This function takes a sequence of objects, returning their instances.
|
||||
|
||||
if ob.instance_type != 'NONE':
|
||||
ob.dupli_list_create(scene)
|
||||
return True, [(dob.object, dob.matrix) for dob in ob.dupli_list]
|
||||
else:
|
||||
return False, [(ob, ob.matrix_world)]
|
||||
:arg depsgraph: The evaluated depsgraph.
|
||||
:type depsgraph: :class:`bpy.types.Depsgraph`
|
||||
:arg objects: A sequencer of objects.
|
||||
:type objects: sequence of :class:`bpy.types.Object`
|
||||
:return: A dictionary where each key is an object from `objects`,
|
||||
values are lists of (:class:`bpy.types.Object`, :class:`mathutils.Matrix`) tuples representing instances.
|
||||
:rtype: dict
|
||||
"""
|
||||
result = {}
|
||||
has_instancer = False
|
||||
for ob in objects:
|
||||
ob_parent = ob.parent
|
||||
if ob_parent and ob_parent.instance_type in {'VERTS', 'FACES'}:
|
||||
continue
|
||||
result[ob] = [] if ob.is_instancer else [(ob, ob.matrix_world.copy())]
|
||||
|
||||
|
||||
def free_derived_objects(ob):
|
||||
ob.dupli_list_clear()
|
||||
if result:
|
||||
for dup in depsgraph.object_instances:
|
||||
dup_parent = dup.parent
|
||||
if dup_parent is None:
|
||||
continue
|
||||
dup_parent_original = dup_parent.original
|
||||
if not dup_parent_original.is_instancer:
|
||||
# The instance has already been added (on assignment).
|
||||
continue
|
||||
instance_list = result.get(dup_parent_original)
|
||||
if instance_list is None:
|
||||
continue
|
||||
instance_list.append((dup.instance_object.original, dup.matrix_world.copy()))
|
||||
return result
|
||||
|
||||
|
||||
def unpack_list(list_of_tuples):
|
||||
|
Loading…
Reference in New Issue
Block a user