USD Export: Adding the ability to choose Stage Up Axis at export time. #121226

Merged
Jesse Yurkovich merged 6 commits from CharlesWardlaw/blender:feature/convert_orientation into main 2024-05-08 19:57:05 +02:00

This patch allows the user to choose the Stage Up Axis at export time, allowing the export to match another target software package. The most common is reorienting to Y up. The up axis is written to stage metadata and a top-level orientation is applied to reorient objects in the Stage.

This patch allows the user to choose the Stage Up Axis at export time, allowing the export to match another target software package. The most common is reorienting to Y up. The up axis is written to stage metadata and a top-level orientation is applied to reorient objects in the Stage.
Charles Wardlaw added 1 commit 2024-04-29 21:13:56 +02:00
First-time contributor

This PR is really appreciated. The difference in up axis between DCC's is one of the big pain points our artists and consumers hit when trying to integrate Blender into an existing USD workflow.

This PR is really appreciated. The difference in up axis between DCC's is one of the big pain points our artists and consumers hit when trying to integrate Blender into an existing USD workflow.

Blender already authors its upAxis USD document setting. Is that not enough for other DCCs to respect? During import we re-orient based on that value and that's what I thought it's there for? The description should probably explain why this isn't enough.

Blender already authors its upAxis USD document setting. Is that not enough for other DCCs to respect? During import we re-orient based on that value and that's what I thought it's there for? The description should probably explain why this isn't enough.
First-time contributor

The issue is when the file is integrated with USD composition. USD doesn't implicitly re-orient referenced layers for you when the axis metadata is misaligned.

So for example, if I predominantly have a Y up pipeline, when I reference in a Blender authored file, it'll come in sideways.
Some apps do try and intercept this by trying to apply a transform onto the target prim that is referencing in the Blender asset, but given that composition is unbounded, this can only be done in very specific cases.

This gets extra confusing for some folks because they'll import an asset into Blender for a quick edit and think it's facing the right way up. If this asset is being referenced in an existing environment, the resulting export will be flipped sideways. This makes it harder for creators to transition parts of their pipeline to Blender.

A specific case recently that came up was a customer using Houdini to procedurally place geometry around their environment. Each geometry points to an individual file that artists can customize from there. Artists who'd use Blender would end up breaking the pipeline accidentally.

The issue is when the file is integrated with USD composition. USD doesn't implicitly re-orient referenced layers for you when the axis metadata is misaligned. So for example, if I predominantly have a Y up pipeline, when I reference in a Blender authored file, it'll come in sideways. Some apps do try and intercept this by trying to apply a transform onto the target prim that is referencing in the Blender asset, but given that composition is unbounded, this can only be done in very specific cases. This gets extra confusing for some folks because they'll import an asset into Blender for a quick edit and think it's facing the right way up. If this asset is being referenced in an existing environment, the resulting export will be flipped sideways. This makes it harder for creators to transition parts of their pipeline to Blender. A specific case recently that came up was a customer using Houdini to procedurally place geometry around their environment. Each geometry points to an individual file that artists can customize from there. Artists who'd use Blender would end up breaking the pipeline accidentally.

Is this not fixable in Houdini or the USD spec itself? Why even allow z-up otherwise? Is this worth a thread on AOUSD or is there already a thread maybe?

Is this not fixable in Houdini or the USD spec itself? Why even allow z-up otherwise? Is this worth a thread on AOUSD or is there already a thread maybe?
First-time contributor

The stage metadata is not meant to reinterpret content through composition because of potential performance concerns, and how it might play through layers of composition. e.g someone overlays just the points of a mesh into a prim, but gets the axes and units wrong, they'd incur a fairly heavy cost.

The USD recommendation is that pipelines conform to a single setup or explicitly transform to mitigate it. I agree that this is not necessarily intuitive.

Houdini cannot fix the issue either unless a pipeline mandates that every edit then have to go through Houdini again to fix it. But if you take the example where Houdini has statically created the environment, Houdini itself has no knowledge when someone modifies the files after they're created. In that scenario, Houdini may never come up again in the pipeline for the environment.

I believe the FBX exporter in Blender also does a similar axis selection (https://docs.blender.org/manual/en/2.80/addons/io_scene_fbx.html#:~:text=Blender%20uses%20Y%20Forward%2C%20Z,Forward%2C%20Y%20Up%20is%20needed.) for a similar reason (albeit, its an easier problem to solve in FBX due to the lack of composition)

The stage metadata is not meant to reinterpret content through composition because of potential performance concerns, and how it might play through layers of composition. e.g someone overlays just the points of a mesh into a prim, but gets the axes and units wrong, they'd incur a fairly heavy cost. The USD recommendation is that pipelines conform to a single setup or explicitly transform to mitigate it. I agree that this is not necessarily intuitive. Houdini cannot fix the issue either unless a pipeline mandates that every edit then have to go through Houdini again to fix it. But if you take the example where Houdini has statically created the environment, Houdini itself has no knowledge when someone modifies the files after they're created. In that scenario, Houdini may never come up again in the pipeline for the environment. I believe the FBX exporter in Blender also does a similar axis selection (https://docs.blender.org/manual/en/2.80/addons/io_scene_fbx.html#:~:text=Blender%20uses%20Y%20Forward%2C%20Z,Forward%2C%20Y%20Up%20is%20needed.) for a similar reason (albeit, its an easier problem to solve in FBX due to the lack of composition)
Jesse Yurkovich requested changes 2024-05-03 10:30:56 +02:00
Dismissed
@ -213,0 +214,4 @@
const bool convert_orientation = RNA_boolean_get(op->ptr, "convert_orientation");
int global_forward = RNA_enum_get(op->ptr, "export_global_forward_selection");
int global_up = RNA_enum_get(op->ptr, "export_global_up_selection");

Make these 2 vars const as well.

Make these 2 vars const as well.
CharlesWardlaw marked this conversation as resolved
@ -259,6 +268,11 @@ static void wm_usd_export_draw(bContext *C, wmOperator *op)
col = uiLayoutColumn(box, true);
uiItemR(col, ptr, "selected_objects_only", UI_ITEM_NONE, nullptr, ICON_NONE);
uiItemR(col, ptr, "visible_objects_only", UI_ITEM_NONE, nullptr, ICON_NONE);
uiItemR(col, ptr, "convert_orientation", UI_ITEM_NONE, nullptr, ICON_NONE);

This needs to be moved outside the if conditional here as we want them drawn normally, for Collection Export, in all situations. Maybe shift them down towards the root_prim_path option?

This needs to be moved outside the if conditional here as we want them drawn normally, for Collection Export, in all situations. Maybe shift them down towards the `root_prim_path` option?
CharlesWardlaw marked this conversation as resolved
@ -459,0 +493,4 @@
false,
"Convert Orientation to Y Up",
"When checked, the USD exporter will convert orientation axis to Y up, matching "
"other applications");

The can just say "Convert Orientation" since it allows more than just Y Up. For the description maybe "Convert orientation axis to a different convention to match other applications"

The can just say "Convert Orientation" since it allows more than just Y Up. For the description maybe "Convert orientation axis to a different convention to match other applications"

Seems was missed? We had prior UI module feedback for removing the "When checked" type wording in these so just noting again.

Seems was missed? We had prior UI module feedback for removing the "When checked" type wording in these so just noting again.
Author
Member

This is the first I'm hearing of the "when checked" language removal-- taking it out now.

This is the first I'm hearing of the "when checked" language removal-- taking it out now.
CharlesWardlaw marked this conversation as resolved
@ -459,0 +508,4 @@
IO_AXIS_Y,
"Up Axis",
"Global Up axis for export");
RNA_def_property_update_runtime(prop, up_axis_update);

Our other exporters don't bother with the "Global Up axis for export" type messages. It's probably ok to leave the descriptions blank here too.

Our other exporters don't bother with the "Global Up axis for export" type messages. It's probably ok to leave the descriptions blank here too.
CharlesWardlaw marked this conversation as resolved
@ -14,3 +16,4 @@
namespace blender::io::usd {
static const float UNIT_M4[4][4] = {

Can you move this inside do_write and make it constexpr instead of static const.

Can you move this inside `do_write` and make it `constexpr` instead of static const.
CharlesWardlaw marked this conversation as resolved
@ -19,0 +49,4 @@
return false;
}
if (BLI_strnlen(usd_export_context_.export_params.root_prim_path, 1024) != 0) {

We've been standardizing on just checking root_prim_path[0] != '\0' instead of doing a length check for most strings like this across blender.

We've been standardizing on just checking `root_prim_path[0] != '\0'` instead of doing a length check for most strings like this across blender.
CharlesWardlaw marked this conversation as resolved
@ -25,6 +25,24 @@ struct GeometrySet;
namespace blender::io::usd {
typedef enum USD_global_forward_axis {

Are these enums necessary? They're pretty much the same as eIOAxis inside IO_orientation.hh. Can also see how they're used in the other exporters.

Are these enums necessary? They're pretty much the same as `eIOAxis` inside `IO_orientation.hh`. Can also see how they're used in the other exporters.
CharlesWardlaw marked this conversation as resolved

Are the "recommendations" consolidated somewhere? It would be helpful if they were so we could mention the scenario in our commit description etc.

That said it does look like there's some precedent out there. I feel a bit better about this now. One software, also z-up, has a direct option in its export settings. Another allows to set it indirectly through it's own preferences. And another does not have this as an option at all currently, but does have an open bug to do something about it.

@DhruvGovil Does the solution here match what you'd expect? Basically the structure of the USD would now be as follows:

def Xform root
    [the newly added xformOp:rotateXYZ which does the rotate]

    def Xform "Cube" ...
    def Xform "Camera" ...
    def Xform "Light" ...
Are the "recommendations" consolidated somewhere? It would be helpful if they were so we could mention the scenario in our commit description etc. That said it does look like there's some precedent out there. I feel a bit better about this now. One software, also z-up, has a direct option in its export settings. Another allows to set it indirectly through it's own preferences. And another does not have this as an option at all currently, but does have an open bug to do something about it. @DhruvGovil Does the solution here match what you'd expect? Basically the structure of the USD would now be as follows: ``` def Xform root [the newly added xformOp:rotateXYZ which does the rotate] def Xform "Cube" ... def Xform "Camera" ... def Xform "Light" ... ```
Charles Wardlaw added 2 commits 2024-05-04 00:24:16 +02:00
First-time contributor

I'll ask and see if I can find the recommendations. I suspect it's largely spread across the forums, but I agree it's something that should be consolidated.

But yes, having a rotate op would make sense to me to have the easiest form of the fix. The alternate is just multiplying the rotation matrix by everything but that can get tricky.

I'll ask and see if I can find the recommendations. I suspect it's largely spread across the forums, but I agree it's something that should be consolidated. But yes, having a rotate op would make sense to me to have the easiest form of the fix. The alternate is just multiplying the rotation matrix by everything but that can get tricky.
Jesse Yurkovich reviewed 2024-05-06 21:52:00 +02:00
@ -33,0 +65,4 @@
pxr::UsdGeomXformable xform = create_xformable();
if (!xform) {
printf("INTERNAL ERROR: USDTransformWriter: couldn't create xformable.\n");

Missed this the first time through but we should remove the raw printf. Can you add a CLOG here as follows:

#include "CLG_log.h"
static CLG_LogRef LOG = {"io.usd"};

Then just do:

CLOG_ERROR(&LOG, "USDTransformWriter: couldn't create xformable");
Missed this the first time through but we should remove the raw printf. Can you add a CLOG here as follows: ``` #include "CLG_log.h" static CLG_LogRef LOG = {"io.usd"}; ``` Then just do: ``` CLOG_ERROR(&LOG, "USDTransformWriter: couldn't create xformable"); ```
CharlesWardlaw marked this conversation as resolved
Charles Wardlaw added 2 commits 2024-05-06 23:47:58 +02:00
buildbot/vexp-code-patch-lint Build done. Details
buildbot/vexp-code-patch-darwin-x86_64 Build done. Details
buildbot/vexp-code-patch-linux-x86_64 Build done. Details
buildbot/vexp-code-patch-darwin-arm64 Build done. Details
buildbot/vexp-code-patch-windows-amd64 Build done. Details
buildbot/vexp-code-patch-coordinator Build done. Details
c824f51920
Switching to use CLOG for error print.

@blender-bot build

@blender-bot build
Charles Wardlaw added 1 commit 2024-05-08 16:08:18 +02:00
buildbot/vexp-code-patch-lint Build done. Details
buildbot/vexp-code-patch-linux-x86_64 Build done. Details
buildbot/vexp-code-patch-darwin-x86_64 Build done. Details
buildbot/vexp-code-patch-windows-amd64 Build done. Details
buildbot/vexp-code-patch-darwin-arm64 Build done. Details
buildbot/vexp-code-patch-coordinator Build done. Details
29105ad93c
Ran make format
Author
Member

@blender-bot build

@blender-bot build
Member

Only blender organization members with write access can start builds. See documentation for details.

Only blender organization members with write access can start builds. See [documentation](https://projects.blender.org/infrastructure/blender-bot/src/branch/main/README.md) for details.
Member

@blender-bot build

@blender-bot build
Jesse Yurkovich approved these changes 2024-05-08 19:41:16 +02:00
Jesse Yurkovich merged commit 2415380061 into main 2024-05-08 19:57:05 +02:00
Sign in to join this conversation.
No reviewers
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
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, Assets & 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
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
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
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
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#121226
No description provided.