[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, &params, 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