USD: Add common Blender attribute to USD primvar utilities #121145
No reviewers
Labels
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
3 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#121145
Loading…
Reference in New Issue
No description provided.
Delete Branch "deadpin/blender:usd-commonattributes"
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 factors out the current set of attribute-to-primvar functions
inside the USD mesh reader/writer so we can use them elsewhere. Namely
they will also be used for exporting Curves attributes like UVs etc.
Outside of this PR I've verified these common functions should be
directly useful for upcoming PointCloud support and for our Curves.
@ -0,0 +177,4 @@
attribute.typed<math::Quaternion>(), timecode, primvar, value_writer);
break;
default:
BLI_assert_unreachable();
Note: Generally this function works in concert with
convert_blender_type_to_usd
so we shouldn't see this even though e.g. a FLOAT4X4 type exists today.Yeah, it seems valuable to have similar utilities for reading attributes, to avoid duplication between meshes, point clouds, and curves.
That's a complex topic I think, but I think it's good enough. I left a comment there anyway.
The benefit would be reducing compile time? Not sure it's worth it if the templates are only used twice. But no strong opinion, and more information may help make that decision.
I think they are avoidable, left a comment inline.
@ -0,0 +42,4 @@
/* Conversion utilities to convert a Blender type to an USD type. */
template<typename BlenderT, typename USDT> inline USDT convert_value(const BlenderT value);
template<> inline bool convert_value(const bool value)
I think you could avoid these redundant
convert_value
functions by usingif constexpr
incopy_blender_buffer_to_primvar
@ -0,0 +115,4 @@
if (const std::optional<BlenderT> value = buffer.get_if_single()) {
usd_data.assign(buffer.size(), detail::convert_value<BlenderT, USDT>(*value));
}
else if (buffer.is_span() && (is_same || is_compatible)) {
const VArraySpan<T> src(buffer);
would make this simpler (no need for the "not span" check), and probably won't be a bottleneck unless we get very fancy with out attribute storage, at which point we'll want to change this anyway.I'm a bit unsure what you mean for this one. How would you structure these conditionals instead?
Like this I think:
I guess the last for loop could be written with
std::transform
too. Not sure about that though.@ -0,0 +118,4 @@
else if (buffer.is_span() && (is_same || is_compatible)) {
Span<USDT> data = buffer.get_internal_span().cast<USDT>();
usd_data.assign(data.begin(), data.end());
This seems fine, with so much copying going on we're probably more memory bound anyway, so multithreading might not help so much.
@ -30,3 +36,3 @@
namespace blender::io::usd {
#pragma optimize("", off)
Temporary?
Yes, was completely temporary for local debugging and removed now.
@ -357,0 +449,4 @@
}
}
else {
write_generic_data(curves, attribute_id, meta_data, usd_curves);
Use
this->
to access class methodsThanks for the look!
Yes, there would probably be 4(?) uses of the file. Mesh, Curves, Point Clouds, and the Shape reader (if the common reader stuff is merged in here too)
I think I found another, simpler solution while trying this out.
@deadpin I will review this PR in the next couple of days. My apologies for the delay.
The most recent update to the PR now brings in the code for our Readers and commonizes it.
I have not tried this for Curves/PointClouds yet to see how well the API works in another example, but it works for the Meshes and has test coverage as of yesterday for it.
Along the way it lost logging to Reports, which I feel was always a bit weird since it can be so verbose. It would also be odd now that this is low-level common code shared among the object types. I do think that some code paths could warrent a CLOG output though, which would be fine, but that means we should probably move the templates into a .cc file somehow so we can use CLOG there...
The API set looks like:
copy_primvar_to_blender_attribute
copy_primvar_to_blender_buffer
convert_usd_type_to_blender
copy_blender_attribute_to_primvar
copy_blender_buffer_to_primvar
convert_blender_type_to_usd
The
attribute
functions contain the big switch statement which sets up the appropriate typed calls to the "buffer" functions.The
buffer
functions do the actual copying, as efficiently as possible. They'll effectively memcpy for types that are layout compatible between Blender and USD i.e. float vs. float, or float3 vs. GfVec3 etc.The
type
functions switch between Blender and USD type names as appropriate.These names are a little verbose and I'm not married to them. Anything with symmetry would work. Perhaps we could append
attr
to the outer namspace and use something like:@ -0,0 +246,4 @@
template<typename USDT, typename BlenderT>
void copy_primvar_to_blender_buffer(const pxr::UsdGeomPrimvar &primvar,
const pxr::UsdTimeCode timecode,
const blender::OffsetIndices<int> face_indices,
blender::
unnecessary here I think? Also I'd go with justfaces
instead offace_indices
which makes me think of an array of actual indices into the mesh faces arrays@ -0,0 +291,4 @@
if (usd_data.size() == attribute.size()) {
if constexpr (is_same || is_compatible) {
const Span<USDT> src(usd_data.data(), usd_data.size());
attribute.copy_from(src.cast<BlenderT>());
For creating Blender attributes in this
is_same || is_compatible
case, there's one potential optimization that might be worth thinking about at this point, creating attributes with implicitly shared data.With implicit sharing, the custom data layer
data
pointer could just point to theVtArray
if theVtArray
could be owned by something likeMEMFreeImplicitSharing
.To allow that optimization in the future it might be necessary to potentially delay creating the attribute until we know whether the buffer can be reused. Or not, maybe that gives you an idea.
The code looks good and works well in my tests.
I don't feel strongly about whether to move functions to a
usd_attribute_utils.cc
file. I would be inclined to leave the current implementation as-is and move the code to a .cc file later if needed, but I wouldn't object if you want to move it now, either.WIP: USD: Add common Blender attribute to USD primvar utilitiesto USD: Add common Blender attribute to USD primvar utilitiesAlright, this PR should be ready to go now in case folks here want to take a final look. Main changes since last time are the removal of the Curve* items which will come in separately since it's net-new functionality and addressing feedback/cleanup.
I'm still open to naming/namespace related changes if the raw function names are problematic in any way.
The latest changes look good to me. I also preformed some basic testing and the code seems to work as expected. Thank you for the updates!
Looking at this again I noticed all of the important entry points aren't templated. And the inline functions are quite large. So I think it would make sense to put the implementations in
.cc
file. Other than that it looks great.Moved the non-templates to an implementation file. Let's see if the build bot agrees with this all now.
@blender-bot build
@blender-bot build
@blender-bot build