From 6ffd9be9a6bf363998463c789d5339437e22e260 Mon Sep 17 00:00:00 2001 From: Jesse Yurkovich Date: Mon, 6 Oct 2025 04:42:39 +0200 Subject: [PATCH] Fix: USD: Prevent unsupported point instancing setups from causing warns If we detect an unsupported point instancing setup, do not attempt to still export it out. Depending on the number of instances this can spew 10's of thousands of USD warning traces to the console. Pull Request: https://projects.blender.org/blender/blender/pulls/147253 --- .../intern/abstract_hierarchy_iterator.cc | 2 +- .../io/usd/intern/usd_hierarchy_iterator.cc | 18 ++++++++++++------ .../io/usd/intern/usd_hierarchy_iterator.hh | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc index 0d9ab9123a2..9cf817167ef 100644 --- a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc +++ b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc @@ -667,7 +667,7 @@ void AbstractHierarchyIterator::make_writers(const HierarchyContext *parent_cont if (!transform_writer) { /* Unable to export, so there is nothing to attach any children to; just abort this entire * branch of the export hierarchy. */ - return; + continue; } const bool need_writers = context->is_point_proto || (!context->is_point_instance && diff --git a/source/blender/io/usd/intern/usd_hierarchy_iterator.cc b/source/blender/io/usd/intern/usd_hierarchy_iterator.cc index d7fee9724b1..ab19732e76d 100644 --- a/source/blender/io/usd/intern/usd_hierarchy_iterator.cc +++ b/source/blender/io/usd/intern/usd_hierarchy_iterator.cc @@ -149,23 +149,22 @@ USDExporterContext USDHierarchyIterator::create_usd_export_context(const Hierarc return exporter_context; } -void USDHierarchyIterator::determine_point_instancers(const HierarchyContext *context) +bool USDHierarchyIterator::determine_point_instancers(const HierarchyContext *context) { if (!context) { - return; + return true; } if (context->object->type == OB_ARMATURE) { - return; + return true; } + bool is_referencing_self = false; if (context->is_point_instancer()) { /* Mark the point instancer's children as a point instance. */ USDExporterContext usd_export_context = create_usd_export_context(context); const ExportChildren *children = graph_children(context); - bool is_referencing_self = false; - pxr::SdfPath instancer_path; if (!params_.root_prim_path.empty()) { instancer_path = pxr::SdfPath(params_.root_prim_path + context->export_path); @@ -243,6 +242,8 @@ void USDHierarchyIterator::determine_point_instancers(const HierarchyContext *co } } } + + return !is_referencing_self; } AbstractHierarchyWriter *USDHierarchyIterator::create_transform_writer( @@ -251,7 +252,12 @@ AbstractHierarchyWriter *USDHierarchyIterator::create_transform_writer( /* The transform writer is always called before data writers, * so determine if the #Xform's children is a point instancer before writing data. */ if (params_.use_instancing) { - determine_point_instancers(context); + if (!determine_point_instancers(context)) { + /* If we could not determine that our point instancing setup is safe, we should not continue + * writing. Continuing would result in enormous amounts of USD warnings about cyclic + * references. */ + return nullptr; + } } return new USDTransformWriter(create_usd_export_context(context)); diff --git a/source/blender/io/usd/intern/usd_hierarchy_iterator.hh b/source/blender/io/usd/intern/usd_hierarchy_iterator.hh index 32f9a95886b..2d25b091396 100644 --- a/source/blender/io/usd/intern/usd_hierarchy_iterator.hh +++ b/source/blender/io/usd/intern/usd_hierarchy_iterator.hh @@ -51,7 +51,7 @@ class USDHierarchyIterator : public AbstractHierarchyIterator { protected: bool mark_as_weak_export(const Object *object) const override; - void determine_point_instancers(const HierarchyContext *context); + bool determine_point_instancers(const HierarchyContext *context); AbstractHierarchyWriter *create_transform_writer(const HierarchyContext *context) override; AbstractHierarchyWriter *create_data_writer(const HierarchyContext *context) override;