fix instancing in USD export #128897

Open
Michael B Johnson wants to merge 6 commits from wave/blender_wave_Apple:liz/fix_instancing into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.

this PR addresses the issues raised in

#126470

Authored by Apple: Zili Zhou

Here are two USD files; one with instancing off and one with it on.

this PR addresses the issues raised in https://projects.blender.org/blender/blender/issues/126470 Authored by Apple: Zili Zhou Here are two USD files; one with instancing off and one with it on.
Michael B Johnson added 2 commits 2024-10-11 18:29:55 +02:00
Updated PR to take into account Michael Kowalski's suggestions in #126470.
This ensures that the instanced prims do not contain any children (such as materials) but only a reference to the original prototype hierarchy.
Authored by Apple: Zili (Liz) Zhou, Matt McLin
Michael B Johnson requested review from Jesse Yurkovich 2024-10-11 18:30:58 +02:00
Michael B Johnson requested review from Michael Kowalski 2024-10-11 18:30:59 +02:00
Michael B Johnson added the
Interest
Pipeline & IO
Interest
USD
labels 2024-10-11 18:31:42 +02:00
Matt McLin added this to the USD project 2024-10-11 19:00:54 +02:00
Author
Member

We believe this PR fixes the issue without having to do step 1 in the design doc, which is also used by the Alembic exporter.
Therefore, our PR is USD specific and addresses the incorrect scene instancing in the current implementation.

We believe this PR fixes the issue without having to do step 1 in the design doc, which is also used by the Alembic exporter. Therefore, our PR is USD specific and addresses the incorrect scene instancing in the current implementation.
Michael B Johnson added 1 commit 2024-10-11 20:10:37 +02:00
Michael B Johnson changed title from liz/fix_instancing to WIP: fix instancing in USD export 2024-10-11 21:19:53 +02:00
Michael B Johnson added 1 commit 2024-10-12 00:37:34 +02:00
Michael B Johnson added 1 commit 2024-10-14 03:48:48 +02:00
Michael B Johnson added 1 commit 2024-10-14 03:51:16 +02:00
Michael B Johnson changed title from WIP: fix instancing in USD export to fix instancing in USD export 2024-10-14 03:51:23 +02:00

It would be good if some notes and discussion on this approach can be made over on the design task - notably about any pros/cons of not doing "step 1" as mentioned. Additionally the description to this PR could use some details about what's been done.

While testing, I've tried to use this with the example file provided at #126470 with the 2 instances in that file rotated (to give them transforms). When I Export with this PR in place, it seems like USD doesn't quite like what's being asked of it - a few Warnings that look like the following are printed:
Warning (secondary thread): in _ReportErrors at line 3172 of C:\db\build\S\VS1564R\build\usd\src\external_usd\pxr\usd\usd\stage.cpp -- In </root/Plane_001/Plane_0/Plane>: Unresolved reference prim path @t:/instanced_collection.usda@</root/Plane> introduced by @t:/instanced_collection.usda@</root/Plane_001/Plane_0/Plane> (recomposing stage on stage @t:/instanced_collection.usda@ <000001C38964ADD0>)

I think I have a few other questions that I'll mention in the design task too that we should get cleared up.

It would be good if some notes and discussion on this approach can be made over on the design task - notably about any pros/cons of not doing "step 1" as mentioned. Additionally the description to this PR could use some details about what's been done. While testing, I've tried to use this with the example file provided at #126470 with the 2 instances in that file rotated (to give them transforms). When I Export with this PR in place, it seems like USD doesn't quite like what's being asked of it - a few Warnings that look like the following are printed: `Warning (secondary thread): in _ReportErrors at line 3172 of C:\db\build\S\VS1564R\build\usd\src\external_usd\pxr\usd\usd\stage.cpp -- In </root/Plane_001/Plane_0/Plane>: Unresolved reference prim path @t:/instanced_collection.usda@</root/Plane> introduced by @t:/instanced_collection.usda@</root/Plane_001/Plane_0/Plane> (recomposing stage on stage @t:/instanced_collection.usda@ <000001C38964ADD0>)` I think I have a few other questions that I'll mention in the design task too that we should get cleared up.

I will review this today as well.

I will review this today as well.
Michael Kowalski requested changes 2024-10-15 01:20:07 +02:00
Michael Kowalski left a comment
Member

First of all, thank you so much for tackling this! Nice work!

I made a couple of comments and will continue my review tomorrow.

First of all, thank you so much for tackling this! Nice work! I made a couple of comments and will continue my review tomorrow.
@ -249,43 +249,6 @@ void USDAbstractWriter::write_visibility(const HierarchyContext &context,
usd_value_writer_.SetAttribute(attr_visibility, pxr::VtValue(visibility), timecode);
}
bool USDAbstractWriter::mark_as_instance(const HierarchyContext &context, const pxr::UsdPrim &prim)

It looks like you replaced this function with a comparable block of code in usd_writer_transform::do_write() but I wonder if this is necessary. For one thing, the new code introduces an error (see my comment below) but also the original function performs additional error checking. I think the original function needs one change to set the instanceable flag to fix the underlying issue, as I note below.

But please let me know if I'm missing something and there is a reason for replacing this function entirely.

It looks like you replaced this function with a comparable block of code in `usd_writer_transform::do_write()` but I wonder if this is necessary. For one thing, the new code introduces an error (see my comment below) but also the original function performs additional error checking. I think the original function needs one change to set the instanceable flag to fix the underlying issue, as I note below. But please let me know if I'm missing something and there is a reason for replacing this function entirely.
makowalski marked this conversation as resolved
@ -110,0 +110,4 @@
/* If the xform hierarchy is being instanced, then we want to create a new
* xform prim that will reference the prototype's xform. */
if (usd_export_context_.export_params.use_instancing && context.is_instance()) {

If you restore USDAbstractWriter::mark_as_instance() function (modified to set the instanceable flag on the prim) you could replace this if clause with the following (though I haven't tested this):

if (usd_export_context_.export_params.use_instancing && context.is_instance()) {
    mark_as_instance(context, xform.GetPrim());
 }

This would also fix an error I indicated below.

If you restore `USDAbstractWriter::mark_as_instance()` function (modified to set the instanceable flag on the prim) you could replace this `if` clause with the following (though I haven't tested this): ``` if (usd_export_context_.export_params.use_instancing && context.is_instance()) { mark_as_instance(context, xform.GetPrim()); } ``` This would also fix an error I indicated below.
makowalski marked this conversation as resolved
@ -110,0 +120,4 @@
pxr::SdfPath inst_path(inst_path_str);
/* To avoid USD errors, make sure the referenced path exists. */
auto new_prim = usd_export_context_.stage->DefinePrim(inst_path);

Actually, we want to define the ref_path prim being referenced below, like this:

usd_export_context_.stage->DefinePrim(ref_path);

Not doing this causes the Unresolved reference prim path USD errors noted by @deadpin.

But. again, I would simply call the original USDAbstractWriter::mark_as_instance() instead.

Actually, we want to define the `ref_path` prim being referenced below, like this: ``` usd_export_context_.stage->DefinePrim(ref_path); ``` Not doing this causes the `Unresolved reference prim path` USD errors noted by @deadpin. But. again, I would simply call the original `USDAbstractWriter::mark_as_instance()` instead.
makowalski marked this conversation as resolved

While testing, I've tried to use this with the example file provided at #126470 with the 2 instances in that file rotated (to give them transforms). When I Export with this PR in place, it seems like USD doesn't quite like what's being asked of it - a few Warnings that look like the following are printed:
Warning (secondary thread): in _ReportErrors at line 3172 of C:\db\build\S\VS1564R\build\usd\src\external_usd\pxr\usd\usd\stage.cpp -- In </root/Plane_001/Plane_0/Plane>: Unresolved reference prim path @t:/instanced_collection.usda@</root/Plane> introduced by @t:/instanced_collection.usda@</root/Plane_001/Plane_0/Plane> (recomposing stage on stage @t:/instanced_collection.usda@ <000001C38964ADD0>)

I noted the cause of this error in my review comments.

EDIT: see my additional comment below.

> While testing, I've tried to use this with the example file provided at #126470 with the 2 instances in that file rotated (to give them transforms). When I Export with this PR in place, it seems like USD doesn't quite like what's being asked of it - a few Warnings that look like the following are printed: > `Warning (secondary thread): in _ReportErrors at line 3172 of C:\db\build\S\VS1564R\build\usd\src\external_usd\pxr\usd\usd\stage.cpp -- In </root/Plane_001/Plane_0/Plane>: Unresolved reference prim path @t:/instanced_collection.usda@</root/Plane> introduced by @t:/instanced_collection.usda@</root/Plane_001/Plane_0/Plane> (recomposing stage on stage @t:/instanced_collection.usda@ <000001C38964ADD0>)` I noted the cause of this error in my review comments. EDIT: see my additional comment below.
Michael Kowalski reviewed 2024-10-15 01:27:38 +02:00
@ -282,4 +252,0 @@
context.original_export_path.c_str());
return false;
}

You would need to add this line

 prim.SetInstanceable(true);

To fix the instancing issue.

You would need to add this line ``` prim.SetInstanceable(true); ``` To fix the instancing issue.
makowalski marked this conversation as resolved

I deleted my last comment regarding the scene hierarchy, as I believe this was a local issue for me.

I deleted my last comment regarding the scene hierarchy, as I believe this was a local issue for me.

Okay, I think I was misunderstanding what you were doing. My comments were based on the design I originally had in mind, and you are doing something different. My apologies. Let me close my current comments to avoid confusion and start fresh.

So, the fix to the error noted by @deadpin is to add the following line to the new logic in usd_writer_transform.cc:

usd_export_context_.stage->DefinePrim(ref_path);
Okay, I think I was misunderstanding what you were doing. My comments were based on the design I originally had in mind, and you are doing something different. My apologies. Let me close my current comments to avoid confusion and start fresh. So, the fix to the error noted by @deadpin is to *add* the following line to the new logic in `usd_writer_transform.cc`: ``` usd_export_context_.stage->DefinePrim(ref_path); ```

I think there may be issues when exporting parented meshes. For example, if you export the attached mesh_hierarchy_instance.blend with instancing enabled to USDA, it looks like /root/proto/Plane_0 references /root/Plane and /root/proto/Plane_0/ references /root/Plane/Plane_001 so that I believe /root/Plane/Plane_001 effectively gets instanced twice.

But I could be wrong. Please let me know if I'm misunderstanding.

I think there may be issues when exporting parented meshes. For example, if you export the attached `mesh_hierarchy_instance.blend` with instancing enabled to USDA, it looks like `/root/proto/Plane_0` references `/root/Plane` and `/root/proto/Plane_0/` references `/root/Plane/Plane_001` so that I believe `/root/Plane/Plane_001` effectively gets instanced twice. But I could be wrong. Please let me know if I'm misunderstanding.
Member

Thanks Michael and Jesse for the reviews, and for the repro scene for the parenting issue. Yes, we will fix that, and will follow up the discussion in the design task.

Thanks Michael and Jesse for the reviews, and for the repro scene for the parenting issue. Yes, we will fix that, and will follow up the discussion in the design task.
First-time contributor

Thanks @makowalski @deadpin for the review. We have a fix for the issue Jess mentioned in #128897 (comment), and will push after an internal review.

I'd like to discuss about Michael's comment #128897 (comment). For the example mentioned, both Blender LTS and this PR branch fail to correctly instance the hierarchy. I think this is because Blender USD exporter cannot recognize Collection, since it is not a blender object. In the example attached to the comment mesh_hierarchy_instance.blend, the prototype also collection proto is not added to the hierarchy in the exported USD file.

My proposed solution is:
Add Collection to the object type for letting blender USD exporter know it's a Collection and add it as a Xform --- add OB_COLLECTION = 31 to ObjectType in DNA_object_types.h . Change other places like AbstractHierarchyWriter accordingly.

This solution requires some lower-level changes, so I wanted to consult with everyone first. I’ve attached the proposed USD file for reference. In the USD file, the collection proto is a Xform, so its instancer proto_001 can easily instance the whole hierarchy by using prepend references = </root/proto> without needing to know the details about its children.

Adding Collection as an object type can benefit the following point instancing fix too.

Loop @mont29 in for further discussion.

Thanks @makowalski @deadpin for the review. We have a fix for the issue Jess mentioned in https://projects.blender.org/blender/blender/pulls/128897#issuecomment-1318187, and will push after an internal review. I'd like to discuss about Michael's comment https://projects.blender.org/blender/blender/pulls/128897#issuecomment-1319324. For the example mentioned, both Blender LTS and this PR branch fail to correctly instance the hierarchy. I think this is because Blender USD exporter cannot recognize `Collection`, since it is not a blender object. In the example attached to the comment `mesh_hierarchy_instance.blend`, the prototype also collection `proto` is not added to the hierarchy in the exported USD file. My proposed solution is: _Add `Collection` to the object type for letting blender USD exporter know it's a `Collection` and add it as a `Xform` --- add `OB_COLLECTION = 31` to `ObjectType` in `DNA_object_types.h` . Change other places like `AbstractHierarchyWriter` accordingly._ This solution requires some lower-level changes, so I wanted to consult with everyone first. I’ve attached the proposed USD file for reference. In the USD file, the collection `proto` is a `Xform`, so its instancer `proto_001` can easily instance the whole hierarchy by using `prepend references = </root/proto>` without needing to know the details about its children. Adding `Collection` as an object type can benefit the following point instancing fix too. Loop @mont29 in for further discussion.
Matt McLin requested review from Bastien Montagne 2024-12-05 00:35:30 +01:00
Merge conflict checking is in progress. Try again in few moments.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u liz/fix_instancing:wave-liz/fix_instancing
git checkout wave-liz/fix_instancing
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Code Documentation
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
FBX
Interest
Freestyle
Interest
Geometry Nodes
Interest
glTF
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Viewport & EEVEE
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Asset System
Module
Core
Module
Development Management
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Module
Viewport & EEVEE
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Severity
High
Severity
Low
Severity
Normal
Severity
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
5 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#128897
No description provided.