[Bf-blender-cvs] [c85c52f2ce4] master: USD Preview Surface material export.

Michael Kowalski noreply at git.blender.org
Thu Jan 27 15:54:31 CET 2022


Commit: c85c52f2ce478ab0e30c5e93fd5a5cb812db232f
Author: Michael Kowalski
Date:   Thu Jan 27 15:43:14 2022 +0100
Branches: master
https://developer.blender.org/rBc85c52f2ce478ab0e30c5e93fd5a5cb812db232f

USD Preview Surface material export.

Add `USD Preview Surface From Nodes` export option, to convert a
Principled BSDF material node network to an approximate USD Preview
Surface shader representation. If this option is disabled, the original
material export behavior is maintained, where viewport setting are saved
to the Preview Surface shader.

Also added the following options for texture export.

  - `Export Textures`: If converting Preview Surface, export textures
    referenced by shader nodes to a 'textures' directory which is a
    sibling of the USD file.
  - `Overwrite Textures`: Allow overwriting existing texture files when
    exporting textures (this option is off by default).
  - `Relative Texture Paths`:  Make texture asset paths relative to the
    USD.

The entry point for the new functionality is
`create_usd_preview_surface_material()`, called from
`USDAbstractWriter::ensure_usd_material()`.  The material conversion
currently handles a small subset of Blender shading nodes,
`BSDF_DIFFUSE`, `BSDF_PRINCIPLED`, `TEX_IMAGE` and `UVMAP`.

Texture export is handled by copying texture files from their original
location to a `textures` folder in the same directory as the USD.
In-memory and packed textures are saved directly to the textures folder.

This patch is based, in part, on code in Tangent Animation's USD
exporter branch.

Reviewed By: sybren, HooglyBoogly

Differential Revision: https://developer.blender.org/D13647

===================================================================

M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/intern/customdata.cc
M	source/blender/blenlib/BLI_path_util.h
M	source/blender/blenlib/intern/path_util.c
M	source/blender/editors/io/io_usd.c
M	source/blender/io/usd/CMakeLists.txt
M	source/blender/io/usd/intern/usd_writer_abstract.cc
M	source/blender/io/usd/intern/usd_writer_abstract.h
A	source/blender/io/usd/intern/usd_writer_material.cc
A	source/blender/io/usd/intern/usd_writer_material.h
M	source/blender/io/usd/intern/usd_writer_mesh.cc
M	source/blender/io/usd/usd.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 00eae2e8e6e..76389b0c66f 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -436,6 +436,12 @@ int CustomData_get_render_layer(const struct CustomData *data, int type);
 int CustomData_get_clone_layer(const struct CustomData *data, int type);
 int CustomData_get_stencil_layer(const struct CustomData *data, int type);
 
+/**
+ * Returns name of the active layer of the given type or NULL
+ * if no such active layer is defined.
+ */
+const char *CustomData_get_active_layer_name(const struct CustomData *data, int type);
+
 /**
  * Copies the data from source to the data element at index in the first layer of type
  * no effect if there is no layer of type.
diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index 5e3beab9b72..02b50027ef9 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -2427,6 +2427,13 @@ int CustomData_get_stencil_layer(const CustomData *data, int type)
   return (layer_index != -1) ? data->layers[layer_index].active_mask : -1;
 }
 
+const char *CustomData_get_active_layer_name(const struct CustomData *data, const int type)
+{
+  /* Get the layer index of the active layer of this type. */
+  const int layer_index = CustomData_get_active_layer_index(data, type);
+  return layer_index < 0 ? NULL : data->layers[layer_index].name;
+}
+
 void CustomData_set_layer_active(CustomData *data, int type, int n)
 {
   for (int i = 0; i < data->totlayer; i++) {
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 658cc0c3825..a2bb8ca47c5 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -380,6 +380,11 @@ void BLI_path_normalize_unc_16(wchar_t *path_16);
 void BLI_path_normalize_unc(char *path_16, int maxlen);
 #endif
 
+/**
+ * Returns true if the given paths are equal.
+ */
+bool BLI_paths_equal(const char *p1, const char *p2);
+
 /**
  * Appends a suffix to the string, fitting it before the extension
  *
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 64bde1193a6..250415c11f9 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -1829,3 +1829,21 @@ void BLI_path_slash_native(char *path)
   BLI_str_replace_char(path + BLI_path_unc_prefix_len(path), ALTSEP, SEP);
 #endif
 }
+
+bool BLI_paths_equal(const char *p1, const char *p2)
+{
+  /* Normalize the paths so we can compare them. */
+  char norm_p1[FILE_MAX];
+  char norm_p2[FILE_MAX];
+
+  BLI_strncpy(norm_p1, p1, sizeof(norm_p1));
+  BLI_strncpy(norm_p2, p2, sizeof(norm_p2));
+
+  BLI_path_slash_native(norm_p1);
+  BLI_path_slash_native(norm_p2);
+
+  BLI_path_normalize(NULL, norm_p1);
+  BLI_path_normalize(NULL, norm_p2);
+
+  return BLI_path_cmp(norm_p1, norm_p2) == 0;
+}
diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index 4e2ccea36ab..49d60ede277 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -131,6 +131,11 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op)
   const bool use_instancing = RNA_boolean_get(op->ptr, "use_instancing");
   const bool evaluation_mode = RNA_enum_get(op->ptr, "evaluation_mode");
 
+  const bool generate_preview_surface = RNA_boolean_get(op->ptr, "generate_preview_surface");
+  const bool export_textures = RNA_boolean_get(op->ptr, "export_textures");
+  const bool overwrite_textures = RNA_boolean_get(op->ptr, "overwrite_textures");
+  const bool relative_texture_paths = RNA_boolean_get(op->ptr, "relative_texture_paths");
+
   struct USDExportParams params = {
       export_animation,
       export_hair,
@@ -141,6 +146,10 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op)
       visible_objects_only,
       use_instancing,
       evaluation_mode,
+      generate_preview_surface,
+      export_textures,
+      overwrite_textures,
+      relative_texture_paths,
   };
 
   bool ok = USD_export(C, filename, &params, as_background_job);
@@ -172,6 +181,26 @@ static void wm_usd_export_draw(bContext *UNUSED(C), wmOperator *op)
   col = uiLayoutColumn(box, true);
   uiItemR(col, ptr, "evaluation_mode", 0, NULL, ICON_NONE);
 
+  box = uiLayoutBox(layout);
+  col = uiLayoutColumnWithHeading(box, true, IFACE_("Materials"));
+  uiItemR(col, ptr, "generate_preview_surface", 0, NULL, ICON_NONE);
+  const bool export_mtl = RNA_boolean_get(ptr, "export_materials");
+  uiLayoutSetActive(col, export_mtl);
+
+  uiLayout *row = uiLayoutRow(col, true);
+  uiItemR(row, ptr, "export_textures", 0, NULL, ICON_NONE);
+  const bool preview = RNA_boolean_get(ptr, "generate_preview_surface");
+  uiLayoutSetActive(row, export_mtl && preview);
+
+  row = uiLayoutRow(col, true);
+  uiItemR(row, ptr, "overwrite_textures", 0, NULL, ICON_NONE);
+  const bool export_tex = RNA_boolean_get(ptr, "export_textures");
+  uiLayoutSetActive(row, export_mtl && preview && export_tex);
+
+  row = uiLayoutRow(col, true);
+  uiItemR(row, ptr, "relative_texture_paths", 0, NULL, ICON_NONE);
+  uiLayoutSetActive(row, export_mtl && preview);
+
   box = uiLayoutBox(layout);
   uiItemL(box, IFACE_("Experimental"), ICON_NONE);
   uiItemR(box, ptr, "use_instancing", 0, NULL, ICON_NONE);
@@ -249,6 +278,32 @@ void WM_OT_usd_export(struct wmOperatorType *ot)
                "Use Settings for",
                "Determines visibility of objects, modifier settings, and other areas where there "
                "are different settings for viewport and rendering");
+
+  RNA_def_boolean(ot->srna,
+                  "generate_preview_surface",
+                  true,
+                  "To USD Preview Surface",
+                  "Generate an approximate USD Preview Surface shader "
+                  "representation of a Principled BSDF node network");
+
+  RNA_def_boolean(ot->srna,
+                  "export_textures",
+                  true,
+                  "Export Textures",
+                  "If exporting materials, export textures referenced by material nodes "
+                  "to a 'textures' directory in the same directory as the USD file");
+
+  RNA_def_boolean(ot->srna,
+                  "overwrite_textures",
+                  false,
+                  "Overwrite Textures",
+                  "Allow overwriting existing texture files when exporting textures");
+
+  RNA_def_boolean(ot->srna,
+                  "relative_texture_paths",
+                  true,
+                  "Relative Texture Paths",
+                  "Make texture asset paths relative to the USD file");
 }
 
 /* ====== USD Import ====== */
diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt
index 12015bf1698..980f33fffa1 100644
--- a/source/blender/io/usd/CMakeLists.txt
+++ b/source/blender/io/usd/CMakeLists.txt
@@ -64,6 +64,7 @@ set(SRC
   intern/usd_writer_camera.cc
   intern/usd_writer_hair.cc
   intern/usd_writer_light.cc
+  intern/usd_writer_material.cc
   intern/usd_writer_mesh.cc
   intern/usd_writer_metaball.cc
   intern/usd_writer_transform.cc
@@ -89,6 +90,7 @@ set(SRC
   intern/usd_writer_camera.h
   intern/usd_writer_hair.h
   intern/usd_writer_light.h
+  intern/usd_writer_material.h
   intern/usd_writer_mesh.h
   intern/usd_writer_metaball.h
   intern/usd_writer_transform.h
diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc
index 2b5326eb4c1..a358c563c88 100644
--- a/source/blender/io/usd/intern/usd_writer_abstract.cc
+++ b/source/blender/io/usd/intern/usd_writer_abstract.cc
@@ -18,11 +18,15 @@
  */
 #include "usd_writer_abstract.h"
 #include "usd_hierarchy_iterator.h"
+#include "usd_writer_material.h"
 
 #include <pxr/base/tf/stringUtils.h>
 
+#include "BKE_customdata.h"
 #include "BLI_assert.h"
 
+#include "DNA_mesh_types.h"
+
 /* TfToken objects are not cheap to construct, so we do it once. */
 namespace usdtokens {
 /* Materials */
@@ -34,6 +38,19 @@ static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal);
 static const pxr::TfToken surface("surface", pxr::TfToken::Immortal);
 }  // namespace usdtokens
 
+static std::string get_mesh_active_uvlayer_name(const Object *ob)
+{
+  if (!ob || ob->type != OB_MESH || !ob->data) {
+    return "";
+  }
+
+  const Mesh *me = static_cast<Mesh *>(ob->data);
+
+  const char *name = CustomData_get_active_layer_name(&me->ldata, CD_MLOOPUV);
+
+  return name ? name : "";
+}
+
 namespace blender::io::usd {
 
 USDAbstractWriter::USDAbstractWriter(const USDExporterContext &usd_export_context)
@@ -78,7 +95,8 @@ const pxr::SdfPath &USDAbstractWriter::usd_path() const
   return usd_export_context_.usd_path;
 }
 
-pxr::UsdShadeMaterial USDAbstractWriter::ensure_usd_material(Material *material)
+pxr::UsdShadeMaterial USDAbstractWriter::ensure_usd_material(const HierarchyContext &context,
+                                                             Material *material)
 {
   static pxr::SdfPath material_library_path("/_materials");
   pxr::UsdStageRefPtr stage = usd_export_context_.stage;
@@ -92,17 +110,14 @@ pxr::UsdShadeMaterial USDAbstractWriter::ensure_usd_material(Material *material)
   }
   usd_material = pxr::UsdShadeMaterial::Define(stage, usd_path);
 
-  /* Construct the shader. */
-  pxr::SdfPath shader_path = usd_path.AppendChild(usdtokens::preview_shader);
-  pxr::UsdShadeShader shader = pxr::UsdShadeShader::Define(stage, shader_path);
-  shader.CreateIdAttr(pxr::VtValue(usdtokens::preview_surface));
-  shader.CreateInput(usdtokens::diffuse_color, pxr::SdfValueTypeNames->Color3f)
-      .Set(pxr::GfVec3f(material->r, material->g, material->b));
-  shader.CreateInput(usdtokens::roughness, pxr::SdfValueTypeNames->Float).Set(material->roughness);
-  shader.CreateInput(usdtokens::metallic, pxr::SdfValueTypeNames->Float).Set(material->metallic);
-
-  /* Connect the shader and the material together. */
-  usd_material.CreateSurfaceOutput().ConnectToSource(shader, usdtokens::surface);
+  i

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list