T99807: Add support for exporting to USDZ #104556
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#104556
Loading…
Reference in New Issue
No description provided.
Delete Branch "SonnyCampbell_Unity/blender:unity/T99807-usdz-refactor"
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?
Historical patch review here: https://archive.blender.org/developer/D15623
This change will add the default .usdz export capability. There is a separate UsdUtilsCreateNewARKitUsdzPackage capability for exporting usdz for iOS devices that will be implemented in a follow up patch as it will require some more small UI changes.
The importer already supports usdz so no change is required other than updating the text in menu to match the updated exporter text.
On export, we must first create a .usd/a/c file and then covert it to .usdz. We are required to do a weird change of directory because of a quirk with the USD conversion to usdz. If an absolute filepath is passed into the UsdUtilsCreateNewUsdzPackage function, the usd files inside the usdz archive will have the same directory structure, i.e. if I try to create a file at C:\code\BlenderProjects\file.usdz, when I create the usdz file inside it will have the structure \code\BlenderProjects\file.usdc.
This is counteracted by setting the current working directory to the temporary session directory where I create both the usdc and usdz files, and just passing the file name to UsdUtilsCreateNewUsdzPackage without any filepath. Once the usdz file is created I copy it out to the intended directory.
63b9a57f8b
This patch also contains the changes from #104525 because it is dependent on the logic to change working directory.
I spoke to Dhruv about the last comment in https://archive.blender.org/developer/D15623 as I was unable to replicate the behaviour he was getting, so it is something we will investigate going forward.
Nice work, just some minor nags.
@ -49,0 +51,4 @@
const char *export_filepath() const
{
if (strlen(usdz_filepath) > 0) {
No need to count all the characters when all you want to know is "empty or not". Use either
usdz_filepath[0]
orBLI_strnlen(usdz_filepath, 1) > 0
.This is utterly incorrect,
usdz_filepath
is alwaystrue
by definition... you want to checkusdz_filepath[0] != '\0'
here...But that whole function can simply be
return usdz_filepath[0] != '\0';
I think the null terminator always evaluates to false.
So if you have an empty string with
usdz_filepath[0] = '\0'
thenif(usdz_filepath[0])
will evaluate to false.The check for
if(usdz_filepath)
is to make sure that theusdz_filepath
has been initialised.Though maybe your way is more explicit and there's less possibility for confusion?
Though yeah I just did a check and it looks like the
if(usdz_filepath)
is unnecessary so I'll remove it.@ -59,0 +90,4 @@
pxr::UsdUtilsCreateNewUsdzPackage(pxr::SdfAssetPath(usdc_file), usdz_file);
BLI_change_working_dir(original_working_dir);
char usdz_temp_dirfile[FILE_MAX];
What is a dirfile? I think a term like "full path" would be better than "dirfile".
@ -59,0 +102,4 @@
return false;
}
}
result = BLI_rename(usdz_temp_dirfile, data->usdz_filepath);
Is it guaranteed that the temp "dirfile" is on the same filesystem as
usdz_filepath
? Have you tested with them being on different filesystems?@ -159,19 +218,50 @@ static void export_startjob(void *customdata,
BKE_scene_graph_update_for_newframe(data->depsgraph);
}
if (strlen(data->usdz_filepath) > 0) {
Same as above about counting all the characters.
Now that this logic is used here as well, I actually think that this shows this code is sitting at the wrong abstraction level. What is being queried here is "should this output USD or USDZ?", and the fact that that distinction is made by whether
usdz_filepath
is empty or not is an implementation detail.Something like
bool ExportJobData::targets_usdz() { return usdz_filepath[0]; }
would solve both problems.@ -160,2 +219,4 @@
}
if (strlen(data->usdz_filepath) > 0) {
if (!perform_usdz_conversion(data)) {
This could just be an
&&
in the sameif
.As a personal preference I prefer to have functions that actually do logic outside of
if()
conditions as I find it can be quite easy to miss, so I've moved it to the line above and stored the result in a variable that gets checked.I can do it like you suggest if you wish, but I find it much more readable this way.
@ -166,1 +234,4 @@
static void export_endjob_usdz_cleanup(const ExportJobData *data)
{
if (!BLI_exists(data->unarchived_filepath)) {
Why should this not clean up anything if
unarchived_filepath
is missing? Wouldn't it be prudent to always eraseusdc_temp_dir
?usdc_temp_dir
is the directory that containsdata->unarchived_filepath
, so if there is nodata->unarchived_filepath
there shouldn't be anything to delete.This is basically so that we don't try to delete anything when there shouldn't be anything there to delete in the first place.
@ -185,1 +275,4 @@
/* To create a usdz file, we must first create a .usd/a/c file and then covert it to .usdz. The
* temporary files will be created in Blender's temporary session storage. The .usdz file will then
* copied to job->usdz_filepath. */
This is not what the code above is doing -- it's moving, not copying.
@ -186,0 +292,4 @@
MEM_freeN(usdc_file);
}
static void set_job_filepath(const char *filepath, blender::io::usd::ExportJobData *job)
Most setters have the parameter order to mimick
thing = value
, so are in the formsetter(thing, value)
. Swap the two parameters here.@ -0,0 +62,4 @@
BKE_tempdir_init(temp_dir);
const std::string &test_assets_dir = blender::tests::flags_test_asset_dir();
BLI_path_join(output_filename, FILE_MAX, test_assets_dir.c_str(), "usd/output_новый.usdz");
👍 for testing with unicode characters.
Using the assets dir is not that great, though -- same as in #104525. Since this code already uses
BKE_tempdir_init()
, you can useBKE_tempdir_base();
andstd::tmpnam()
to generate a name that's guaranteed to be unique.@ -0,0 +73,4 @@
if (BLI_exists(output_filename)) {
BLI_delete(output_filename, false, false);
BLI_delete(temp_dir, true, true);
Why not always delete
temp_dir
, regardless of whetheroutput_filenaem
exists or not?@ -0,0 +86,4 @@
}
/* File sanity check. */
EXPECT_EQ(BLI_listbase_count(&bfile->main->objects), 4);
Use
ASSERT_EQ
for such checks. That will stop the test from continuing when it fails.@ -0,0 +91,4 @@
USDExportParams params{};
bool result = USD_export(context, output_filename, ¶ms, false);
EXPECT_TRUE(result);
Add some logging to this and the following EXPECT calls. When the test fails, it should be clear why it failed. You can do something like:
If this particular test fails, the rest of the test is useless (it will all fail), so this one can be replaced with
ASSERT_TRUE
.Nice work, just some minor nags.
@blender-bot build
@blender-bot build
Issues noted below are fairly bad (as in, obvious mistakes and potential source of bugs), would be good to check at compiler warnings when building...
Hopefully these are the only serious ones, will fix them (since it's trivial) as part of the commit.
For the rest tests are passing and feature looks good, so time to finalize this patch.
@ -59,0 +93,4 @@
BLI_split_file_part(data->usdz_filepath, usdz_file, FILE_MAX);
char original_working_dir[FILE_MAX];
BLI_current_working_dir(original_working_dir, FILE_MAX);
This line and the one above are not properly using the API, which expect you to use the returned char pointer.
@ -0,0 +56,4 @@
}
char original_wd[FILE_MAX];
BLI_current_working_dir(original_wd, FILE_MAX);
Same issue as noted above regarding not using return value from
BLI_current_working_dir()
.Realised the
usdz_export_test.blend
test blend file hasn't been uploaded yet.Committed as
54f672cbfa
from PR #105185.Pull request closed