[Bf-blender-cvs] [cbff81ac9b4] temp-usd-prev-export2: USD Preview Surface export code reorganization.

Michael Kowalski noreply at git.blender.org
Tue Dec 28 06:13:52 CET 2021


Commit: cbff81ac9b4a859ea0fa4644348032a192822bfd
Author: Michael Kowalski
Date:   Sun Dec 26 21:06:00 2021 -0500
Branches: temp-usd-prev-export2
https://developer.blender.org/rBcbff81ac9b4a859ea0fa4644348032a192822bfd

USD Preview Surface export code reorganization.

Re-ordered the code to place high-level functions first in the
file and the lower-level/helper functions later (per suggestion
by Sybren in his review).  Also removed declarartions of
helper functions from the header, as these can be static for now.
Some additional minor cleanup to formatting and comments.

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

M	source/blender/io/usd/intern/usd_writer_material.cc
M	source/blender/io/usd/intern/usd_writer_material.h

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

diff --git a/source/blender/io/usd/intern/usd_writer_material.cc b/source/blender/io/usd/intern/usd_writer_material.cc
index f33110ceb60..a011559dfe0 100644
--- a/source/blender/io/usd/intern/usd_writer_material.cc
+++ b/source/blender/io/usd/intern/usd_writer_material.cc
@@ -82,6 +82,282 @@ static const pxr::TfToken UVMap("UVMap", pxr::TfToken::Immortal);
 
 namespace blender::io::usd {
 
+/* Static function forward declarations. */
+static pxr::UsdShadeShader create_usd_preview_shader(const USDExporterContext &usd_export_context,
+                                                     pxr::UsdShadeMaterial &material,
+                                                     const char *name,
+                                                     int type);
+static pxr::UsdShadeShader create_usd_preview_shader(const USDExporterContext &usd_export_context,
+                                                     pxr::UsdShadeMaterial &material,
+                                                     bNode *node);
+static void export_texture(bNode *node, const pxr::UsdStageRefPtr stage, const bool allow_overwrite=false);
+static bNode *get_bsdf_node(Material *material);
+static std::string get_node_tex_image_filepath(bNode *node);
+static std::string get_node_tex_image_filepath(bNode *node,
+                                               const pxr::UsdStageRefPtr stage,
+                                               const USDExportParams &export_params);
+static std::string get_texture_filepath(const std::string &in_path,
+                                        const pxr::UsdStageRefPtr stage,
+                                        const USDExportParams &export_params);
+static bNode *traverse_channel(bNodeSocket *input, short target_type = SH_NODE_TEX_IMAGE);
+
+
+void create_usd_preview_surface_material(const USDExporterContext &usd_export_context,
+                                         Material *material,
+                                         pxr::UsdShadeMaterial &usd_material,
+                                         const std::string &default_uv)
+{
+  /* Define a 'preview' scope beneath the material which will contain the preview shaders. */
+  pxr::UsdGeomScope::Define(usd_export_context.stage,
+    usd_material.GetPath().AppendChild(usdtokens::preview));
+
+  pxr::TfToken default_uv_sampler = default_uv.empty() ? cyclestokens::UVMap :
+    pxr::TfToken(default_uv);
+
+  /* We only handle the first instance of either principled or
+    * diffuse bsdf nodes in the material's node tree, because
+    * USD Preview Surface has no concept of layering materials. */
+  bNode *node = get_bsdf_node(material);
+  if (!node) {
+    return;
+  }
+
+  pxr::UsdShadeShader preview_surface = create_usd_preview_shader(
+    usd_export_context, usd_material, node);
+
+  /* Set the preview surface inputs. */
+  LISTBASE_FOREACH(bNodeSocket *, sock, &node->inputs) {
+    bNode *input_node = nullptr;
+    pxr::UsdShadeShader created_shader;
+
+    if (STREQ(sock->name, "Base Color") || STREQ(sock->name, "Color")) {
+
+      input_node = traverse_channel(sock);
+      if (input_node) {
+        /* Create connection. */
+        created_shader = create_usd_preview_shader(usd_export_context, usd_material, input_node);
+        preview_surface.CreateInput(usdtokens::diffuse_color, pxr::SdfValueTypeNames->Float3)
+          .ConnectToSource(created_shader, usdtokens::rgb);
+      }
+      else {
+        /* Set hardcoded value. */
+        bNodeSocketValueRGBA *socket_data = (bNodeSocketValueRGBA *)sock->default_value;
+        preview_surface.CreateInput(usdtokens::diffuse_color, pxr::SdfValueTypeNames->Float3)
+          .Set(pxr::VtValue(pxr::GfVec3f(
+            socket_data->value[0], socket_data->value[1], socket_data->value[2])));
+      }
+    }
+    else if (STREQ(sock->name, "Roughness")) {
+
+      input_node = traverse_channel(sock);
+      if (input_node) {
+        /* Create connection. */
+        created_shader = create_usd_preview_shader(usd_export_context, usd_material, input_node);
+        preview_surface.CreateInput(usdtokens::roughness, pxr::SdfValueTypeNames->Float)
+          .ConnectToSource(created_shader, usdtokens::r);
+      }
+      else {
+        /* Set hardcoded value. */
+        bNodeSocketValueFloat *socket_data = (bNodeSocketValueFloat *)sock->default_value;
+        preview_surface.CreateInput(usdtokens::roughness, pxr::SdfValueTypeNames->Float)
+          .Set(pxr::VtValue(socket_data->value));
+      }
+    }
+    else if (STREQ(sock->name, "Metallic")) {
+
+      input_node = traverse_channel(sock);
+      if (input_node) {
+        /* Create connection. */
+        created_shader = create_usd_preview_shader(usd_export_context, usd_material, input_node);
+        preview_surface.CreateInput(usdtokens::metallic, pxr::SdfValueTypeNames->Float)
+          .ConnectToSource(created_shader, usdtokens::r);
+      }
+      else {
+        /* Set hardcoded value. */
+        bNodeSocketValueFloat *socket_data = (bNodeSocketValueFloat *)sock->default_value;
+        preview_surface.CreateInput(usdtokens::metallic, pxr::SdfValueTypeNames->Float)
+          .Set(pxr::VtValue(socket_data->value));
+      }
+    }
+    else if (STREQ(sock->name, "Specular")) {
+
+      input_node = traverse_channel(sock);
+      if (input_node) {
+        /* Create connection. */
+        created_shader = create_usd_preview_shader(usd_export_context, usd_material, input_node);
+        preview_surface.CreateInput(usdtokens::specular, pxr::SdfValueTypeNames->Float)
+          .ConnectToSource(created_shader, usdtokens::r);
+      }
+      else {
+        /* Set hardcoded value. */
+        bNodeSocketValueFloat *socket_data = (bNodeSocketValueFloat *)sock->default_value;
+        preview_surface.CreateInput(usdtokens::specular, pxr::SdfValueTypeNames->Float)
+          .Set(pxr::VtValue(socket_data->value));
+      }
+    }
+    else if (STREQ(sock->name, "Alpha")) {
+
+      input_node = traverse_channel(sock);
+      if (input_node) {
+        /* Create connection. */
+        created_shader = create_usd_preview_shader(usd_export_context, usd_material, input_node);
+        preview_surface.CreateInput(usdtokens::opacity, pxr::SdfValueTypeNames->Float)
+          .ConnectToSource(created_shader, usdtokens::r);
+      }
+      else {
+        /* Set hardcoded value. */
+        bNodeSocketValueFloat *socket_data = (bNodeSocketValueFloat *)sock->default_value;
+        preview_surface.CreateInput(usdtokens::opacity, pxr::SdfValueTypeNames->Float)
+          .Set(pxr::VtValue(socket_data->value));
+      }
+    }
+    else if (STREQ(sock->name, "IOR")) {
+
+      input_node = traverse_channel(sock);
+      if (input_node) {
+        /* Create connection. */
+        created_shader = create_usd_preview_shader(usd_export_context, usd_material, input_node);
+        preview_surface.CreateInput(usdtokens::ior, pxr::SdfValueTypeNames->Float)
+          .ConnectToSource(created_shader, usdtokens::r);
+      }
+      else {
+        /* Set hardcoded value. */
+        bNodeSocketValueFloat *socket_data = (bNodeSocketValueFloat *)sock->default_value;
+        preview_surface.CreateInput(usdtokens::ior, pxr::SdfValueTypeNames->Float)
+          .Set(pxr::VtValue(socket_data->value));
+      }
+    }
+    else if (STREQ(sock->name, "Normal")) {
+
+      input_node = traverse_channel(sock);
+      if (input_node) {
+        created_shader = create_usd_preview_shader(usd_export_context, usd_material, input_node);
+        preview_surface.CreateInput(usdtokens::normal, pxr::SdfValueTypeNames->Float3)
+          .ConnectToSource(created_shader, usdtokens::rgb);
+      }
+      /* We don't handle hardcoded value. */
+    }
+    else if (STREQ(sock->name, "Clearcoat")) {
+
+      input_node = traverse_channel(sock);
+      if (input_node) {
+        /* Create connection. */
+        created_shader = create_usd_preview_shader(usd_export_context, usd_material, input_node);
+        preview_surface.CreateInput(usdtokens::clearcoat, pxr::SdfValueTypeNames->Float)
+          .ConnectToSource(created_shader, usdtokens::r);
+      }
+      else {
+        /* Set hardcoded value. */
+        bNodeSocketValueFloat *socket_data = (bNodeSocketValueFloat *)sock->default_value;
+        preview_surface.CreateInput(usdtokens::clearcoat, pxr::SdfValueTypeNames->Float)
+          .Set(pxr::VtValue(socket_data->value));
+      }
+    }
+    else if (STREQ(sock->name, "Clearcoat Roughness")) {
+
+      input_node = traverse_channel(sock);
+      if (input_node) {
+        /* Create connection. */
+        created_shader = create_usd_preview_shader(usd_export_context, usd_material, input_node);
+        preview_surface.CreateInput(usdtokens::clearcoatRoughness, pxr::SdfValueTypeNames->Float)
+          .ConnectToSource(created_shader, usdtokens::r);
+      }
+      else {
+        /* Set hardcoded value. */
+        bNodeSocketValueFloat *socket_data = (bNodeSocketValueFloat *)sock->default_value;
+        preview_surface.CreateInput(usdtokens::clearcoatRoughness, pxr::SdfValueTypeNames->Float)
+          .Set(pxr::VtValue(socket_data->value));
+      }
+    }
+
+    /* If any input texture node has been found, export the texture, if necessary,
+      * and look for a connected uv node. */
+    if (created_shader && input_node && input_node->type == SH_NODE_TEX_IMAGE) {
+
+      if (usd_export_context.export_params.export_textures) {
+        export_texture(input_node,
+          usd_export_context.stage,
+          usd_export_context.export_params.overwrite_textures);
+      }
+
+      bool found_uv_node = false;
+
+      /* Find UV input to the texture node. */
+      LISTBASE_FOREACH(bNodeSocket *, input_node_sock, &input_node->inputs) {
+
+        if (!input_node_sock || !input_node_sock->link ||
+          !STREQ(input_node_sock->name, "Vector")) {
+          continue;
+        }
+
+        bNode *uv_node = traverse_channel(input_node_sock, SH_NODE_UVMAP);
+
+        if (uv_node == NULL) {
+          continue;
+        }
+
+        pxr::UsdShadeShader uv_shader = create_usd_preview_shader(
+          usd_export_context, usd_material, uv_node);
+        if (!uv_shader.GetPrim().IsValid(

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list