USD: Import and export custom properties #118938
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#118938
Loading…
Reference in New Issue
No description provided.
Delete Branch "CharlesWardlaw/blender:feature/custom_properties"
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?
Adding support for converting between Blender custom properties and
USD user-defined custom attributes. Custom attributes on Xforms, many
data types, and materials are all supported for round-tripping.
Please see the USD attributes documentation for more information on custom attributes.
Properties are exported with a userProperties: namespace for simple
filtering in external apps. This namespace is stripped on import,
but other namespace are allowed to persist.
An "Import Attributes" parameter has been added with options "None" (do not import
attributes), "User" (import attributes in the 'userProperties' namespace only), "All custom"
(import all USD custom attributes, the default).
An "Export Custom Properties" export option has been added.
The property conversion code handles float, double, string and bool types, as well as
tuples of size 2, 3 and 4. Note that USD quaternions and arrays of arbitrary length are
not yet supported.
There is currently no attempt to set the Blender property subtype based on the USD
type "role" (e.g., specifying Color or XYZ vector subtypes). This can be addressed in
future work.
In addition to exporting custom properties, the original Blender object and data names
are now saved as USD custom string attributes "userProperties:blenderName:object" and
"userProperties:blenderName:data", respectively, on the corresponding USD prims. This
feature is enabled with the "Author Blender Name" export option.
If a Blender custom string property is named "displayName", it's handled in a special way on
export in that its value is used to set the USD prim's "displayName" metadata.
Testing
The attached
custom_attr.usda
file contains custom attributes of typeasset
,string
,bool
,int
,double
,float
andhalf
and tuples of various sizes, types and roles (e.g., colors, vectors and texture coordinates) which should successfully import as Blender custom properties of subtype "Plain Data".181ad1abcc
to3dacbcd3e5
USD: Added the ability to import and export custom properties. Xforms, many data types, and materials are all supported for round-tripping.to USD: Import and export custom propertiesPer discussion with @CharlesWardlaw, I'm extending the current implementation to handle a wider range of USD attribute types. I will mark the pull request as WIP until I've completed these changes.
USD: Import and export custom propertiesto WIP: USD: Import and export custom propertiesAdded support for bool, asset, half and arbitrary tuple types on import and bool type on export.
@ -241,2 +241,4 @@
object_ = BKE_object_add_only_object(bmain, OB_MESH, name_.c_str());
object_->data = mesh;
set_props(&object_->id, prim_, use_parent_xform());
I noticed that this call to
set_props()
increate_object()
here and in the other reader implementations can cause a bug, in that ifuse_parent_xform()
evaluates to false then the prim properties are duplicated on both the object and its data. E.g., if you load thecustom_attr.usda
you can see the duplicated properties.I think the solution is to combine the functionality currently in
USDPrimReader::read_object_data()
andUSDPrimReaader::set_props()
into a single function and call it fromUSDXformReader::read_object_data()
.I will commit this fix shortly.
@ -164,0 +167,4 @@
void set_props(ID *id,
const pxr::UsdPrim &prim,
const bool use_parent = false,
std::optional<double> motionSampleTime = std::nullopt);
IMHO, using
std::optional
here and elsewhere might not be necessary as it can be easily replaced with parameterpxr::UsdTimeCode motionSampleTime = pxr::UsdTimeCode::Default()
. I'll make this change, but am certainly open to discussing this and we can change it back if necessary.WIP: USD: Import and export custom propertiesto USD: Import and export custom properties@deadpin I just removed the WIP tag, as I believe this PR is now ready for review.
@CharlesWardlaw I'm done with the revisions I had in mind and have a couple of questions/comments. I welcome your feedback. Thanks!
@ -214,1 +236,4 @@
relative_paths,
add_properties_namespace,
export_custom_properties,
author_blender_name,
I don't believe 'add_properties_namespace' and 'author_blender_name' are actually exposed in the UI. I wonder if they should be. For example, I can imagine cases where automatically adding the 'userProperties' namespace might not be desirable, so maybe this behavior should be optional. I'm open to other opinions about this, of course.
Actually, I thought that all custom DCC properties should be namespaced under
userProperties
- so in that sense we should just always do it? Are there really cases they shouldn't be?https://openusd.org/release/glossary.html?highlight=userproperties#user-properties
Looks like
author_blender_name
is exposed in the UI though.Ah,
author_blender_name
is there, indeed. Not sure how my text search missed it. Thanks for the correction.You're right that adding the
userProperties
namespace is standard, but I do recall seeing some cases where it wasn't used. Also, we allow importing custom attributes without this namespace.Regardless, I don't think this is a big issue, so probably leaving the current behavior as is would be fine. In that case, we should maybe remove the
add_properties_namespace
option from the code altogether. I can go either way on this.I'll resolve this conversation as I'm fine with always adding the namespace.
It would be cleaner if we remove the
add_properties_namespace
option if it's always true, but I don't feel strongly about this.@ -833,0 +890,4 @@
"attr_import_mode",
rna_enum_usd_attr_import_mode_items,
USD_ATTR_IMPORT_ALL,
"Import Attributes",
I wonder whether we should rename this "Import Custom Attributes" to make it very clear that this only applies to custom attributes and not primvars. Likewise, maybe the related enums should have "custom" in the name (e.g., rename USD_ATTR_IMPORT_NONE to USD_CUSTOM_ATTR_IMPORT_NONE). But am open to feedback on this, as maybe this is already clear.
Maybe "Import Custom Properties" since "attributes" can mean something else in Blender terminology?
Yes, I think "import Custom Properties" is good.
I'm fine with either "Import Custom Properties" or "Import Custom Attributes". I don't feel strongly about either option.
Let's go with "Properties" in general since that is the term used in Blender for these and since they'll end up as "userProperties" inside the USD file itself.
@blender-bot build
@blender-bot build
Seems to work pretty well! I'll run through a bit more round-trip tests tonight. I think the biggest piece of feedback is about the
displayName
processing and the boilerplate checks inside the writers.@ -9,0 +10,4 @@
#include "usd.hh"
#include "WM_types.hh"
Seems like using "DNA_object_types.h" instead of "WM_types.hh" would be more apropriate.
@ -9,0 +15,4 @@
#include <pxr/usd/sdf/path.h>
#include <pxr/usd/usd/prim.h>
#include <optional>
Unused
@ -16,6 +16,7 @@
#include <pxr/usd/sdf/path.h>
#include <pxr/usd/usd/prim.h>
#include <optional>
Can get rid of this one now too.
@ -0,0 +8,4 @@
#include <iostream>
#include "BLI_utildefines.h"
Both iostream and utildefines are unused.
@ -0,0 +181,4 @@
if (attr_names.size() > 2 && is_user_prop && attr_names[1] == "blenderName") {
/* Skip the deprecated userProperties:blenderName namespace attribs. */
continue;
How can they be deprecated already when we just added them? This seems to prevent the newly added
author_blender_name
option from working I think.What are we hoping to achieve with the
blenderName:object
andblenderName:data
properties to begin with?That comment is not accurate, as the properties are not deprecated, as you say. I think this was just an oversight.
An immediate use for these properties could be in the USD export hook, to help map USD prims back to original Blender object names. We might also at some point use these properties to restore original Blender object names on import, though we are not doing so now. Also, such names could be useful in a pipeline, if it matters what the original object names were.
I'm not sure it makes sense to create custom properties with such names on import in Blender, since that doesn't seem useful in and of itself, but I could be wrong.
I think there are arguments in both directions. On import, Blender might mangle names and by having the original name metadata be round-trippable, we at least preserve the ability for external tools to track changes despite scene names being different.
I've removed the comment. I believe it was referring to something internal to the original implementation that we changed while testing.
Oh, I see. We're writing those names out but not explicitly doing anything internally to use them when read back in (at least today). I misunderstood and thought that we'd re-assign the actual blender object and data names ourselves during import based on these properties.
@ -42,8 +43,109 @@ static std::string get_mesh_active_uvlayer_name(const Object *ob)
return name ? name : "";
}
template<typename VECT>
Nit: I'd at least use
USDT
here, instead of VECT, as we use that term elsewhere and it helps to know that we should be feeding a USD type in here.@ -168,0 +297,4 @@
}
if (id.properties) {
write_user_properties(prim, (IDProperty *)id.properties, timecode);
Nit: The cast to IDProperty * is redundant
@ -168,0 +315,4 @@
const StringRef displayName_identifier = "displayName";
IDProperty *prop;
Can declare
prop
inside the for loop@ -70,0 +73,4 @@
void write_user_properties(pxr::UsdPrim &prim,
IDProperty *properties,
pxr::UsdTimeCode = pxr::UsdTimeCode::Default());
Both of the new methods can be
const
and can take inprim
as a const reference.@ -100,0 +100,4 @@
if (usd_export_context_.export_params.export_custom_properties && camera) {
auto prim = usd_camera.GetPrim();
write_id_properties(prim, camera->id, timecode);
The
write_id_properties
function already checks the export params for other criteria, can the check forexport_custom_properties
be moved inside there so all these callers don't have to have boilerplate checks? Similarly, checkingcamera
isn't useful here because we would have died already if camera is null. The same applies for the other writers I think.I addressed the call sites-- this made the code a bit more concise. Thanks for the suggestion.
"namespace" not "deadspace" 🤣
I'm approving this pull request now, as I'll be out all of next week.
There are a couple of minor questions in
io_usd.cc
:add_properties_namespace
option if it's always true.Import Attributes
option is renamedImport Custom Attributes
orImport Custom Properties
.However, I don't feel strongly as to how these questions are resolved, so I'll leave that up to @deadpin and @CharlesWardlaw to decide on whether to follow up on these points.
@ -168,0 +282,4 @@
return;
}
if (!id.properties) {
This conditional should be removed. It's checked below and it prevents data_name from being written e.g. for the default cube.
Looks all good from what I can see.
@blender-bot build