USD: Improved Texture Coordinate Translation (UsdTransform2d) #114821
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
Code Documentation
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
4 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#114821
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "CharlesWardlaw/blender:feature/port_mapping_to_main"
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?
UsdTransform2d was previously ignored, and the material read would stop when it found these nodes. This resulted in many surfaces having their textures mapped incorrectly when imported into Blender, and worse, resulted in the loss of that data when round-tripping back out of Blender.
This patch (mostly the work of @makowalski) adds support for the Transform 2D node and also ensures that the wrap modes are similarly written correctly.
Attached are files demonstrating the differences. On import before the patch:
Shader graph after the patch:
Exports are similarly handled.
@ -64,0 +69,4 @@
static const pxr::TfToken clamp("clamp", pxr::TfToken::Immortal);
static const pxr::TfToken repeat("repeat", pxr::TfToken::Immortal);
static const pxr::TfToken wrapS("wrapS", pxr::TfToken::Immortal);
static const pxr::TfToken wrapT("wrapT", pxr::TfToken::Immortal);
These wrap mode values don't seem to be used in the reader.
Good catch-- on the port I missed a function. Thanks!
@ -329,0 +367,4 @@
{
bNodeSocket *sock = nodeFindSocket(node, SOCK_IN, identifier);
if (!sock) {
WM_reportf(RPT_ERROR,
We shouldn't use
WM_reportf
any longer. Such reports were changed as part ofb684864561
last month. All calls to WM_reportf in this PR will have to change.In addition, these kind of 'refined' detailed messages are better suited for
CLOG
output thanBKE_report
.Reports should be considered as high-level information that is important to be printed to the user in the UI. More technical details should rather use the logging system, to avoid spamming users with hundreds of messages that they will not read (or even actually see).
This is also something that needs to be addresses in the whole USD IO area of Blender, but would be good to get it for new code at least. :)
I'm happy to make any changes you like here, but the new BKE_report thing introduces many intrusive changes that are in my opinion unnecessary.
We're now passing a ReportList pointer through a LOT of functions-- is this the best solution? Was a central logging store considered, where BKE_reportf's first parameter would be an std::string log name or some sort of integer handle that looks up the ReportList from a central place instead? This seems to be how most logging systems work, and wouldn't preclude doing a pre-write lock on a per-log basis to get around threading issues.
If that's not a possibility, why are we passing a pointer as opposed to passing a ReportList structure or class by reference?
@mont29 I'd appreciate a more specific idea on CLOG vs BKE_report-- When we've spammed users in the past, we've corrected the issues to reduce spam by fixing or adding features. I'd rather have people annoyed by printouts than have them unaware of the reason why a file imported incorrectly, but I will defer to your guidance.
@ -703,0 +792,4 @@
if (pxr::UsdShadeInput scale_input = get_input(usd_shader, usdtokens::scale)) {
pxr::VtValue val;
if (scale_input.Get(&val) && val.CanCast<pxr::GfVec2f>()) {
pxr::GfVec2f scale_val = val.Cast<pxr::GfVec2f>().UncheckedGet<pxr::GfVec2f>();
As someone new to the USD API, I've noticed there's like 5 different coding conventions when it comes to getting values:
Is it possible to choose just 1 style? In what situations are the Casts necessary? Can
UncheckedGet
always be used since we verify in some form first?God, casts are necessary all over the place. >_<;
One example is something like GfVec3f -- that could also be stored as GfVec3d, GfVec3i, or GfVec3h. Going from float to doubles makes sense, but the other two are less useful / used and don't convert automatically. So, if you want a GfVec3f out but the value is stored as one of the others, you need to cast.
I don't know about one style over the others; I feel like sometimes it works one way, and sometimes it works another way. I'll defer to @makowalski on this.
I agree casts are often necessary, because in practice one finds that attributes are not always consistently authored, or for backward compatibility when the USD specification has changed. That said, we can perhaps open a separate task to review the existing USD import code and decide on a more consistent convention throughout.
@ -77,0 +80,4 @@
static const pxr::TfToken repeat("repeat", pxr::TfToken::Immortal);
static const pxr::TfToken wrapS("wrapS", pxr::TfToken::Immortal);
static const pxr::TfToken wrapT("wrapT", pxr::TfToken::Immortal);
static const pxr::TfToken emissiveColor("emissiveColor", pxr::TfToken::Immortal);
There is another "emissiveColor" token name defined above already.
@ -82,0 +98,4 @@
static const pxr::TfToken attribute("attribute", pxr::TfToken::Immortal);
static const pxr::TfToken bsdf("bsdf", pxr::TfToken::Immortal);
static const pxr::TfToken closure("closure", pxr::TfToken::Immortal);
static const pxr::TfToken vector("vector", pxr::TfToken::Immortal);
These newly added usdtokens don't seem to be used either? Everything from cycles down to vector.
UVMap is used, but I removed the rest.
@ -166,2 +206,2 @@
if (!input_link &&
((bNodeSocketValueFloat *)emission_strength_sock->default_value)->value == 0.0f) {
if (!emission_strength_sock) {
This seems like another case where we'd, maybe, want to know we didn't find the socket? In general not being able to find a socket for one of our own nodes is totally an error on our part, nothing the user can do about it, but we don't have a "Retail assert" right now so tracing is the only option... I'm torn between a) silently continuing, b) tracing and continuing, or c) just use a Debug assert for folks running debug and crash with null-ref in retail.
This kind of missing socket stuff occurs either with broken .blend files or, sometimes, when loading stuff between versions and upgrades or downgrades don't work 100%. I don't think normal users who stick to official releases will hit something like this.
The version of Blender we publish through our launcher, however, is constantly running on top of main. We at times ingest bugs that are the result of refactors or other upstream changes, but are not always able to ingest the subsequent fixes as quickly.
I am 200% against allowing the application to get into a crash state knowingly, especially when a simple pointer check can avoid this. I feel it's better for the user to have bad behavior and recover from it than to suddenly be unable to open a file and lose all the data contained within.
I'm happy to add a report print here if you like.
@ -382,0 +465,4 @@
usdtokens::scale, pxr::SdfValueTypeNames->Float2))
{
pxr::GfVec2f scale_val(scale[0], scale[1]);
if (!scale_input.Set(scale_val)) {
Is checking for success during
.Set
really necessary for these and the ones below? Other .Set calls don't seem to check and these aren't completely untrusted inputs that would fail I think.Spoke with Michael and we agree-- we can remove the checks here, as the block is only opened on successful param creation.
@ -511,0 +642,4 @@
static pxr::TfToken get_node_tex_image_wrap(bNode *node)
{
if (node->type != SH_NODE_TEX_IMAGE) {
std::cout << "get_node_tex_image_wrap() called with unexpected type.\n";
Leftover debug trace?
Let's move the 'report' topic outisde of comments.
WM_report
This API is intrinsically not threadsafe, therefore using it in any code called from
wmJob
execution callback (or any other thread) is a mistake per se.It usually won't give too bad effects, except when code starts spamming tens (if not hundreds) of reports, like USD I/O code can easily do currently with relatively complex files. So use new system, with
BKE_report
and passing around reportlists.And yes, I would love to get this reportlist storage better centralized, but there is no 'universal' USD I/O context available everywhere from USD code currently, at least I could not find anything like that. Could be a good more general refactor to implement at some point though.
CLOG vs. Report
Reports are shown to user, typically as pop-ups + temporary text in the header, in the UI. So there should be a very limited amount of these (ideally only one for a whole USD I/O operation e.g.), synthesizing the issues to report.
Then user can look at the console for the detailed info, generated by CLOG (warnings and errors are always printed out to console, regardless of the
--log-level
value).Also not (yet) ideal, I would consider the Blendfile reading code a fairly good example:
BlendFileReadReport
).file_read_reports_finalize()
) (which also uses a mix of reports and clog btw).CLOG
inreadfile.cc
code itself for all kind of detailed immediate info, including reports, warnings and just debugging data.I get the issues you were trying to solve for sure-- it's the intrusive requirement to pass around the ReportList that I'm bumping on here.
Why not "register" handles to specific lists and use that handle instead of forcing the modification of every function signature down the stack?
Not sure what you mean here? The reportlist is stored in
USDExportParams
/USDImportParams
(via thewmJobWorkerStatus *worker_status
member), so that it's available as much as possible in USD IO code. Again, afaik there is no universal data shared/accessible to all USD IO code currently.I Chose the
Params
structs as they seem to be the most widely shared among the codebase currently, arguably this is not the best place to put this job status data though. I would much rather see something like theUSDExporterContext
made available to the whole exporter code, and then store thewmJobWorkerStatus
data in it (and have something similar for the importer as well).And I kinda fail to see the point of this discussion in this PR honestly, this is the current system and way to go. You're much welcome to suggest a better system in a dedicated design task obviously.
This looks good from my side now. Spot checked functionality with the provided repro as well as the Intel Moore's Lane demo asset and confirmed that we're now getting Mapping nodes added as appropriate.
@CharlesWardlaw If it's not too much trouble, could your run
make format
on the code, please?@blender-bot build
@blender-bot build
@blender-bot build
This looks good. I've also verified that the mapping node IO works with the attached TextureWrapModes.usdz file. Thank you, Charles.
@blender-bot build