USD: optionally author subdivision schema on export #113267
No reviewers
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
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
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
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
Core
Module
Development Management
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
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
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#113267
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "wave/blender_wave_Apple:dev/author_subdivs_v2"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This PR adds support for exporting USD assets which have the subdivision schema applied. Current behavior prior to this PR is that the effects of Subdivision Surface modifiers are always applied to their mesh prior to export, such that it is not possible to recover the original base mesh.
In this PR we provide three options for the subdiv schema type:
None - Base mesh only (Export base mesh with subdiv type set to None)
None - Subdivided mesh (Export subdivided mesh with subdiv type set to None)
Best match (Export base mesh with subdiv schema type set to Catmull-Clark) <-- this is the default
"Best match" here means that Blender will set a subdiv scheme type in the exported USD asset when it is possible to closely match the subdivision surface type that was authored in Blender.
At this time Blender provides two subdivision types: Catmull-Clark and Simple.
Because Simple does not have a corresponding subdivision type in USD, we do not attempt to convert or represent it, and instead the Simple subdiv modifier will be evaluated and applied to the mesh during export.
Whenever a Catmull-Clark Subdivision Surface modifier is applied to an object, and is the last modifier in the stack, it is possible to set the subdiv scheme to Catmull-Clark for the respective prim in the exported USD file. In all other cases, any subdiv modifier will be evaluated and applied to the mesh prior to export -- unless, the user chooses the "None - Base mesh only" option in the export dialog.
Authored by Apple: Matt McLin
See attached subdivs.blend scene that we used for testing, and screenshots showing result of doing export for each of the three subdiv scheme options followed by importing back into Blender.
Also screenshot of the export UI:
dev/author_subdivs_v2to USD: optionally author subdivision schema on export@ -477,0 +495,4 @@
WM_reportf(RPT_WARNING, "USD export: Simple subdivision not supported, exporting subdivided mesh at render quality");
}
}
I wonder whether exporting normals should be skipped if the subdivision scheme is not set to "none". The USD docs seem to suggest this, if I'm reading them correctly:
Please see https://openusd.org/dev/api/class_usd_geom_mesh.html#details.
If that's the case, then maybe the code can be reordered to create normals only if needed:
But please let me know if I'm misunderstanding this point.
Thanks for the reminder on this, makes sense.
I have not looked at the implementation yet, but for the UI I suggest:
@ -93,1 +93,4 @@
const EnumPropertyItem rna_enum_usd_export_subdiv_mode_items[] = {
{USD_SUBDIV_NONE,
"SUBDIV_NONE",
No need for
SUBDIV_
prefix in the identifier.Thanks, how about this?
That looks fine. Just change BESTMATCH -> BEST_MATCH.
(I did not mean to approve yet.)
@ -0,0 +18,4 @@
/**
* This code is adapted from the SubdivModifierDisabler class
* implementation in the Alembic exporter.
Is it possible to move this code to
io/common
and share the implementation with Alembic?Will look into that
@ -477,0 +487,4 @@
if (subsurfData->subdivType == SUBSURF_TYPE_CATMULL_CLARK) {
if (usd_export_context_.export_params.export_subdiv == USD_SUBDIV_BESTMATCH) {
/* If a subdivision modifier exists, and it uses Catmull-Clark, then apply Catmull-Clark SubD scheme. */
usd_mesh.CreateSubdivisionSchemeAttr().Set(pxr::UsdGeomTokens->catmullClark);
It should be possible to export interpolation settings in the Advanced panel too.
CreateInterpolateBoundaryAttr
CreateFaceVaryingLinearInterpolationAttr
Maybe the Creases boolean can be taken into account as well, to skip exporting the crease attributes.
Great points, Brecht, will investigate.
@ -373,3 +381,3 @@
};
void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh, SubsurfModifierData* subsurfData)
I think
SubsurfModifierData* subsurfData
can be const.I think we may want to fetch the subdiv modifier only if it's the last modifer AND is enabled for the current depsgraph evaluation mode (
viewport
orrender
).Maybe the logic can be wrapped in a utility function similar to this (I haven't tested this extensively):
@brecht Do you think this makes sense?
@makowalski About taking evaluation mode into account for viewport vs render, that is a good catch, thanks, and thanks for the suggested code snippet. I think I just need a small change on that. Instead of asking the depsgraph for the evaluation mode, I think I need to look at the export option, right?
usd_export_context_.export_params.evaluation_mode
instead ofconst eEvaluationMode eval_mode = DEG_get_mode(depsgraph);
Or am I misunderstanding?
The evaluation mode is originally set on the depsgraph from the export params, so it amounts to the same thing. But, you are right, we don't need the depsgraph for anything else in this function, so it's cleaner to get the evaluation mode from the export params directly. (Originally, I thought the depsgraph would be needed to query the enabled state of the modifier, which is why I passed it in, but it turned out not to be the case and I forgot to change it. Sorry about that.)
USD: optionally author subdivision schema on exportto WIP: USD: optionally author subdivision schema on exporte7b0d3b04f
tod350ce3b3d
Using the code in this PR, I exported a test asset which exposes all six combinations of UV and geometry smoothing/interpolation options, so that the resulting USD output can be compared across renderers/DCCs. See attached.
Thanks, much closer now.
@ -94,0 +98,4 @@
"Ignore",
"SubD scheme = None, export base mesh without subdivision"},
{USD_SUBDIV_TESSELLATE,
"TESSELATE",
TESSELATE -> TESSELLATE
@ -336,1 +359,4 @@
"material assignments as geometry subsets");
RNA_def_enum(ot->srna,
"export_subdiv",
Don't abbreviate:
export_subdivision
@ -337,0 +362,4 @@
"export_subdiv",
rna_enum_usd_export_subdiv_mode_items,
USD_SUBDIV_BEST_MATCH,
"SubD Scheme", /* shortening "Subdivison surface" to "SubD" so this fits in the UI */
SubD Scheme -> Subdivision
We don't use the term "SubD" in the Blender interface,.
@ -59,0 +62,4 @@
BLI_assert(obj);
/* Return the subdiv modifier if it is the last modifier and has
* the required mode enabled. */
This seems inconsistent with
SubdivModifierDisabler::get_subsurf_modifier
, which skips displacement and particle system modifiers.Can we unify this code into a single function?
Ideally code would also be unified with Alembic export and moved into
io/common
@ -481,0 +517,4 @@
} else {
/* "Simple" is currently the only other subdivision type provided by Blender, */
/* and we do not yet provide a corresponding representation for USD export. */
WM_reportf(RPT_WARNING, "USD export: Simple subdivision not supported, exporting subdivided mesh");
#113883 recently eliminated all the usage of
WM_report
in this code, this will need to be changed as well.WIP: USD: optionally author subdivision schema on exportto WIP: USD: optionally author subdivision schema on exportWIP: USD: optionally author subdivision schema on exportto WIP: USD: optionally author subdivision schema on exportWIP: USD: optionally author subdivision schema on exportto USD: optionally author subdivision schema on exportWe believe we have addressed the issues raised, and we no longer consider this a WIP.
@blender-bot build
Looks good to me now.
Generally works well, just a few comments below, and one outstanding question related to the
frame_has_been_written_
condition.@ -94,0 +96,4 @@
"IGNORE",
0,
"Ignore",
"SubD scheme = None, export base mesh without subdivision"},
"SubD" -> "Subdivision" here and the other enum below since these are user-facing strings.
Thanks for catching, I thought I had already changed this
@ -94,0 +106,4 @@
"BEST_MATCH",
0,
"Best Match",
"Export base mesh with Catmull-Clark subdivision scheme when possible. "
To match the format of the text above. How about:
Also note that, due to a quirk of how these strings get processed. The last sentence should not end with a period(
.
)@ -0,0 +45,4 @@
* in the list or if it's the last modifier preceding any particle system modifiers.
* This function ignores Simple subsurf modifiers.
*/
static ModifierData *get_subsurf_modifier(Scene *scene, const Object *ob, ModifierMode mode);
Let's continue to use subdiv in the api names/comments as much as possible. the subsurf term is legacy. Use
get_subdiv_modifier
andsubdiv
in comments rather thansubsurf
.@ -56,18 +56,51 @@ bool USDGenericMeshWriter::is_supported(const HierarchyContext *context) const
return true;
}
static const SubsurfModifierData *get_subsurf_modifier(eEvaluationMode eval_mode, Object *obj)
Subsurf to subdiv in api names
@ -64,1 +92,4 @@
/* Only fetch the subdiv modifier if it is the last modifier, */
/* and is enabled for the selected evaluation mode. */
const SubsurfModifierData *subsurfData = get_subsurf_modifier(
Move this block into the
try
below as subsurfData is only used within that scope@ -476,7 +507,74 @@ void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
return;
I wonder... do we need to keep the subdiv+normals writing before this
frame_has_been_written_
condition? There's a fewusdview
warnings if I attempt an animation while keyframing SubD modifier enable:Invalid Hydra prim '/root/Plane_002/Plane_002': # of facevaryings mismatch (64 != 24) for primvar normals
These go away if subdiv+normals are written before the condition here. All that said, keyframing the enable buttons on viewport/render don't really do what I thought they'd do. Maybe look at that after the initial patch lands. Or maybe my understanding of what this condition protects is wrong.
Hi @deadpin , our assumption here is that the Subdivision scheme will never be animated, as we are not aware of any use cases where this would be desirable. I suggest we take this as a later update if such a use case arises.
@ -477,3 +508,3 @@
}
usd_mesh.CreateSubdivisionSchemeAttr().Set(pxr::UsdGeomTokens->none);
/* Default to setting the subdivision scheme to None. */
We should take this large block and factor it out to a
write_subdiv_and_normals
private method to help keep things organized.The changes look good to me. Thank you!
I know Jesse has requested additional changes, but I have no more comments to add, so I am approving this pull request.
Great! I think the only thing remaining is really the placement of the
write_subdiv_and_normals
call. Inmain
the normals are always written before theif (frame_has_been_written_)
condition. Now they are written afterwards, along with subdiv data. This will produce differences between files during animation. Even if subdiv is not animatable, the normals might be.@deadpin Hi Jesse, I think this means we should probably revert the factoring out into
write_subdiv_and_normals
, and go with our original implementation for that, as the subdiv scheme and normals need to be treated differently.It is important that the subdiv scheme is not written as animated. Per the USD spec it is uniform and cannot be animated, and also it would result in verbose USD file with schema being authored multiple times per timecode. So the subdivision scheme absolutely needs to be written after the
if (frame_has_been_written_)
check as we had it originally.@Matt-McLin I see, alright. I would expect something like the following then I suppose:
LGTM and tests fine locally.