[Bf-blender-cvs] [cdef135f6f6] master: USD import: Support importing USDZ.
Michael Kowalski
noreply at git.blender.org
Fri Jan 27 00:10:10 CET 2023
Commit: cdef135f6f651c669f526a931a3cfd996d1e8cbd
Author: Michael Kowalski
Date: Thu Jan 26 18:08:45 2023 -0500
Branches: master
https://developer.blender.org/rBcdef135f6f651c669f526a931a3cfd996d1e8cbd
USD import: Support importing USDZ.
This addressed feature request T99811.
Added the following features to fully support importing USDZ archives:
- Added .usdz to the list of supported extensions.
- Added new USD import options to copy textures from USDZ archives. The
textures may be imported as packed data (the default) or to a directory
on disk.
- Extended the USD material import logic to handle package-relative texture
assets paths by invoking the USD asset resolver to copy the textures from
the USDZ archive to a directory on disk. When importing in Packed mode,
the textures are first saved to Blender's temporary session directory
prior to packing.
The new USD import options are
- Import Textures: Behavior when importing textures from a USDZ archive
- Textures Directory: Path to the directory where imported textures will
be copied
- File Name Collision: Behavior when the name of an imported texture file
conflicts with an existing file
Import Textures menu options:
- None: Don't import textures
- Packed: Import textures as packed data (the default)
- Copy: Copy files to Textures Directory
File Name Collision menu options:
- Use Existing: If a file with the same name already exists, use that
instead of copying (the default)
- Overwrite: Overwrite existing files
Reviewed by: Bastien
Differential Revision: https://developer.blender.org/D17074
===================================================================
M release/scripts/startup/bl_ui/space_topbar.py
M source/blender/blenkernel/intern/cachefile.c
M source/blender/editors/io/io_usd.c
M source/blender/editors/space_file/filelist.cc
M source/blender/io/usd/CMakeLists.txt
A source/blender/io/usd/intern/usd_asset_utils.cc
A source/blender/io/usd/intern/usd_asset_utils.h
M source/blender/io/usd/intern/usd_reader_material.cc
M source/blender/io/usd/usd.h
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py
index 97f8a1bfad1..50bb1e42602 100644
--- a/release/scripts/startup/bl_ui/space_topbar.py
+++ b/release/scripts/startup/bl_ui/space_topbar.py
@@ -468,7 +468,7 @@ class TOPBAR_MT_file_import(Menu):
self.layout.operator("wm.alembic_import", text="Alembic (.abc)")
if bpy.app.build_options.usd:
self.layout.operator(
- "wm.usd_import", text="Universal Scene Description (.usd, .usdc, .usda)")
+ "wm.usd_import", text="Universal Scene Description (.usd*)")
if bpy.app.build_options.io_gpencil:
self.layout.operator("wm.gpencil_import_svg", text="SVG as Grease Pencil")
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index 5d19db323f8..5968a6b7296 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -366,7 +366,7 @@ void BKE_cachefile_eval(Main *bmain, Depsgraph *depsgraph, CacheFile *cache_file
}
#endif
#ifdef WITH_USD
- if (BLI_path_extension_check_glob(filepath, "*.usd;*.usda;*.usdc")) {
+ if (BLI_path_extension_check_glob(filepath, "*.usd;*.usda;*.usdc;*.usdz")) {
cache_file->type = CACHEFILE_TYPE_USD;
cache_file->handle = USD_create_handle(bmain, filepath, &cache_file->object_paths);
BLI_strncpy(cache_file->handle_filepath, filepath, FILE_MAX);
diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index 99d4e84cfd4..e6426732584 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -72,6 +72,23 @@ const EnumPropertyItem rna_enum_usd_mtl_name_collision_mode_items[] = {
{0, NULL, 0, NULL, NULL},
};
+const EnumPropertyItem rna_enum_usd_tex_import_mode_items[] = {
+ {USD_TEX_IMPORT_NONE, "IMPORT_NONE", 0, "None", "Don't import textures"},
+ {USD_TEX_IMPORT_PACK, "IMPORT_PACK", 0, "Packed", "Import textures as packed data"},
+ {USD_TEX_IMPORT_COPY, "IMPORT_COPY", 0, "Copy", "Copy files to Textures Directory"},
+ {0, NULL, 0, NULL, NULL},
+};
+
+const EnumPropertyItem rna_enum_usd_tex_name_collision_mode_items[] = {
+ {USD_TEX_NAME_COLLISION_USE_EXISTING,
+ "USE_EXISTING",
+ 0,
+ "Use Existing",
+ "If a file with the same name already exists, use that instead of copying"},
+ {USD_TEX_NAME_COLLISION_OVERWRITE, "OVERWRITE", 0, "Overwrite", "Overwrite existing files"},
+ {0, NULL, 0, NULL, NULL},
+};
+
/* Stored in the wmOperator's customdata field to indicate it should run as a background job.
* This is set when the operator is invoked, and not set when it is only executed. */
enum { AS_BACKGROUND_JOB = 1 };
@@ -405,6 +422,14 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
const bool validate_meshes = false;
const bool use_instancing = false;
+ const eUSDTexImportMode import_textures_mode = RNA_enum_get(op->ptr, "import_textures_mode");
+
+ char import_textures_dir[FILE_MAXDIR];
+ RNA_string_get(op->ptr, "import_textures_dir", import_textures_dir);
+
+ const eUSDTexNameCollisionMode tex_name_collision_mode = RNA_enum_get(op->ptr,
+ "tex_name_collision_mode");
+
struct USDImportParams params = {.scale = scale,
.is_sequence = is_sequence,
.set_frame_range = set_frame_range,
@@ -430,9 +455,12 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
.set_material_blend = set_material_blend,
.light_intensity_scale = light_intensity_scale,
.mtl_name_collision_mode = mtl_name_collision_mode,
+ .import_textures_mode = import_textures_mode,
+ .tex_name_collision_mode = tex_name_collision_mode,
.import_all_materials = import_all_materials};
STRNCPY(params.prim_path_mask, prim_path_mask);
+ STRNCPY(params.import_textures_dir, import_textures_dir);
const bool ok = USD_import(C, filename, ¶ms, as_background_job);
@@ -490,6 +518,18 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op)
uiItemR(row, ptr, "set_material_blend", 0, NULL, ICON_NONE);
uiLayoutSetEnabled(row, RNA_boolean_get(ptr, "import_usd_preview"));
uiItemR(col, ptr, "mtl_name_collision_mode", 0, NULL, ICON_NONE);
+
+ box = uiLayoutBox(layout);
+ col = uiLayoutColumn(box, true);
+ uiItemR(col, ptr, "import_textures_mode", 0, NULL, ICON_NONE);
+ bool copy_textures = RNA_enum_get(op->ptr, "import_textures_mode") == USD_TEX_IMPORT_COPY;
+ row = uiLayoutRow(col, true);
+ uiItemR(row, ptr, "import_textures_dir", 0, NULL, ICON_NONE);
+ uiLayoutSetEnabled(row, copy_textures);
+ row = uiLayoutRow(col, true);
+ uiItemR(row, ptr, "tex_name_collision_mode", 0, NULL, ICON_NONE);
+ uiLayoutSetEnabled(row, copy_textures);
+ uiLayoutSetEnabled(col, RNA_boolean_get(ptr, "import_materials"));
}
void WM_OT_usd_import(struct wmOperatorType *ot)
@@ -622,6 +662,28 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
USD_MTL_NAME_COLLISION_MAKE_UNIQUE,
"Material Name Collision",
"Behavior when the name of an imported material conflicts with an existing material");
+
+ RNA_def_enum(ot->srna,
+ "import_textures_mode",
+ rna_enum_usd_tex_import_mode_items,
+ USD_TEX_IMPORT_PACK,
+ "Import Textures",
+ "Behavior when importing textures from a USDZ archive");
+
+ RNA_def_string(ot->srna,
+ "import_textures_dir",
+ "//textures/",
+ FILE_MAXDIR,
+ "Textures Directory",
+ "Path to the directory where imported textures will be copied ");
+
+ RNA_def_enum(
+ ot->srna,
+ "tex_name_collision_mode",
+ rna_enum_usd_tex_name_collision_mode_items,
+ USD_TEX_NAME_COLLISION_USE_EXISTING,
+ "File Name Collision",
+ "Behavior when the name of an imported texture file conflicts with an existing file");
}
#endif /* WITH_USD */
diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc
index 57a4c5c052a..73de74ddaf6 100644
--- a/source/blender/editors/space_file/filelist.cc
+++ b/source/blender/editors/space_file/filelist.cc
@@ -2667,7 +2667,7 @@ int ED_path_extension_type(const char *path)
if (BLI_path_extension_check(path, ".abc")) {
return FILE_TYPE_ALEMBIC;
}
- if (BLI_path_extension_check_n(path, ".usd", ".usda", ".usdc", nullptr)) {
+ if (BLI_path_extension_check_n(path, ".usd", ".usda", ".usdc", ".usdz", nullptr)) {
return FILE_TYPE_USD;
}
if (BLI_path_extension_check(path, ".vdb")) {
diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt
index 862bd41c087..b123eb251ab 100644
--- a/source/blender/io/usd/CMakeLists.txt
+++ b/source/blender/io/usd/CMakeLists.txt
@@ -60,6 +60,7 @@ set(INC_SYS
)
set(SRC
+ intern/usd_asset_utils.cc
intern/usd_capi_export.cc
intern/usd_capi_import.cc
intern/usd_common.cc
@@ -88,6 +89,7 @@ set(SRC
usd.h
+ intern/usd_asset_utils.h
intern/usd_common.h
intern/usd_exporter_context.h
intern/usd_hierarchy_iterator.h
diff --git a/source/blender/io/usd/intern/usd_asset_utils.cc b/source/blender/io/usd/intern/usd_asset_utils.cc
new file mode 100644
index 00000000000..550d318cd94
--- /dev/null
+++ b/source/blender/io/usd/intern/usd_asset_utils.cc
@@ -0,0 +1,301 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2023 NVIDIA Corportation. All rights reserved. */
+
+#include "usd_asset_utils.h"
+
+#include <pxr/usd/ar/asset.h>
+#include <pxr/usd/ar/packageUtils.h>
+#include <pxr/usd/ar/resolver.h>
+#include <pxr/usd/ar/writableAsset.h>
+
+#include "BKE_main.h"
+
+#include "BLI_fileops.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+static const char UDIM_PATTERN[] = "<UDIM>";
+static const char UDIM_PATTERN2[] = "%3CUDIM%3E";
+
+/* Maximum range of UDIM tiles, per the
+ * UsdPreviewSurface specifications. See
+ * https://graphics.pixar.com/usd/release/spec_usdpreviewsurface.html#texture-reader
+ */
+static const int UDIM_START_TILE = 1001;
+static const int UDIM_END_TILE = 1100;
+
+namespace blender::io::usd {
+
+/* The following is copied from _SplitUdimPattern() in
+ * USD library source file materialParamsUtils.cpp.
+ * Split a udim file path such as /someDir/myFile.<UDIM>.exr into a
+ * prefix (/someDir/myFile.) and suffix (.exr). */
+static std::pair<std::string, std::string> split_udim_pattern(const std::string &path)
+{
+ static const std::vector<std::string> patterns = {UDIM_PATTERN, UDIM_PATTERN2};
+
+ for (const std::string &pattern : patterns) {
+ const std::string::size_type pos = path.find(pattern);
+ if (pos != std::string::npos) {
+ return {path.substr(0, pos), path.substr(pos + pattern.size())};
+ }
+ }
+
+ return {std::string(), std::string()};
+}
+
+/* Return the asset file base name, with special handling of
+ * package relative paths. */
+static std::string get_asset_base_name(const char *src_path)
+{
+ char base_name[FILE_MAXFILE];
+
+ if (pxr::ArIsPackageRelativePath(src_path)) {
+ std::pair<std::string, std::string> split = pxr::ArSplitPackageRelativePathInner(src_path);
+ if (split.second.empty()) {
+ WM_reportf(RPT_WARNING,
+ "%s: Couldn't determine package-relative file name from path %s",
+ __func__,
+ src_path);
+ return src_path;
+ }
+ BLI_split_file_part(split.second.c_str(), base_name, sizeof(base_name));
+ }
+ else {
+ BLI_split_file_part(src_path, base_name, sizeof(base_name));
+ }
+
+ return base_name;
+}
+
+/* Copy an asset to a destination directory. */
+static std::string copy_asset_to_directory(const char *src_path,
+ const char *dest_dir_path,
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list