[Bf-blender-cvs] [1813c23df29] usd-importer-T81257: UsdPreviewSurface shader network import.

Michael A. Kowalski noreply at git.blender.org
Sun Nov 22 04:11:58 CET 2020


Commit: 1813c23df29a4632392e42853d2106e539744df4
Author: Michael A. Kowalski
Date:   Sat Nov 21 22:07:52 2020 -0500
Branches: usd-importer-T81257
https://developer.blender.org/rB1813c23df29a4632392e42853d2106e539744df4

UsdPreviewSurface shader network import.

Added experimental code to import UsdPreviewSurface shaders
as Blender Principled BSDF node networks.

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

M	source/blender/editors/io/io_usd.c
M	source/blender/io/usd/import/usd_material_importer.cc
M	source/blender/io/usd/import/usd_material_importer.h
M	source/blender/io/usd/usd.h

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

diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index ab40321e318..09452d46ced 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -281,6 +281,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
 
   const float light_intensity_scale = RNA_float_get(op->ptr, "light_intensity_scale");
 
+  const bool import_usdpreview = RNA_boolean_get(op->ptr, "import_usdpreview");
+
   /* Switch out of edit mode to avoid being stuck in it (T54326). */
   Object *obedit = CTX_data_edit_object(C);
   if (obedit) {
@@ -293,7 +295,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
                                    scale,
                                    debug,
                                    use_instancing,
-                                   light_intensity_scale};
+                                   light_intensity_scale,
+                                   import_usdpreview};
 
   bool ok = USD_import(C, filename, &params, as_background_job);
 
@@ -322,6 +325,7 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op)
   box = uiLayoutBox(layout);
   uiItemL(box, IFACE_("Experimental"), ICON_NONE);
   uiItemR(box, ptr, "use_instancing", 0, NULL, ICON_NONE);
+  uiItemR(box, ptr, "import_usdpreview", 0, NULL, ICON_NONE);
 }
 
 void WM_OT_usd_import(wmOperatorType *ot)
@@ -383,6 +387,13 @@ void WM_OT_usd_import(wmOperatorType *ot)
                 "Value by which to scale the intensity of imported lights",
                 0.0001f,
                 1000.0f);
+
+  RNA_def_boolean(
+      ot->srna,
+      "import_usdpreview",
+      false,
+      "Import UsdPreviewSurface",
+      "When checked, convert UsdPreviewSurface shaders to Principled BSD shader networks.");
 }
 
 #endif /* WITH_USD */
diff --git a/source/blender/io/usd/import/usd_material_importer.cc b/source/blender/io/usd/import/usd_material_importer.cc
index b347cdd488d..82741274eea 100644
--- a/source/blender/io/usd/import/usd_material_importer.cc
+++ b/source/blender/io/usd/import/usd_material_importer.cc
@@ -19,32 +19,131 @@
 
 #include "usd_material_importer.h"
 
+#include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
 
+#include "BKE_image.h"
 #include "BKE_lib_id.h"
 #include "BKE_main.h"
 #include "BKE_material.h"
 #include "BKE_mesh.h"
+#include "BKE_node.h"
 #include "BKE_object.h"
 
+#include "BLI_listbase.h"
+#include "BLI_math_vector.h"
+#include "BLI_string.h"
 
+#include <pxr/base/gf/vec3f.h>
 
 #include <iostream>
+#include <vector>
 
-namespace blender::io::usd {
+namespace usdtokens {
 
-USDMaterialImporter::USDMaterialImporter(const USDImporterContext &context, Main *bmain)
-  : context_(context)
-  , bmain_(bmain)
+// Parameter names
+static const pxr::TfToken a("a", pxr::TfToken::Immortal);
+static const pxr::TfToken b("b", pxr::TfToken::Immortal);
+static const pxr::TfToken clearcoat("clearcoat", pxr::TfToken::Immortal);
+static const pxr::TfToken clearcoatRoughness("clearcoatRoughness", pxr::TfToken::Immortal);
+static const pxr::TfToken diffuseColor("diffuseColor", pxr::TfToken::Immortal);
+static const pxr::TfToken emissiveColor("emissiveColor", pxr::TfToken::Immortal);
+static const pxr::TfToken file("file", pxr::TfToken::Immortal);
+static const pxr::TfToken g("g", pxr::TfToken::Immortal);
+static const pxr::TfToken ior("ior", pxr::TfToken::Immortal);
+static const pxr::TfToken metallic("metallic", pxr::TfToken::Immortal);
+static const pxr::TfToken normal("normal", pxr::TfToken::Immortal);
+static const pxr::TfToken occlusion("occlusion", pxr::TfToken::Immortal);
+static const pxr::TfToken opacity("opacity", pxr::TfToken::Immortal);
+static const pxr::TfToken r("r", pxr::TfToken::Immortal);
+static const pxr::TfToken result("result", pxr::TfToken::Immortal);
+static const pxr::TfToken rgb("rgb", pxr::TfToken::Immortal);
+static const pxr::TfToken rgba("rgba", pxr::TfToken::Immortal);
+static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal);
+static const pxr::TfToken specularColor("specularColor", pxr::TfToken::Immortal);
+static const pxr::TfToken st("st", pxr::TfToken::Immortal);
+static const pxr::TfToken varname("varname", pxr::TfToken::Immortal);
+
+// USD shader names.
+static const pxr::TfToken UsdPreviewSurface("UsdPreviewSurface", pxr::TfToken::Immortal);
+static const pxr::TfToken UsdPrimvarReader_float2("UsdPrimvarReader_float2",
+                                                  pxr::TfToken::Immortal);
+static const pxr::TfToken UsdUVTexture("UsdUVTexture", pxr::TfToken::Immortal);
+}  // namespace usdtokens
+
+static bNode *add_node(const bContext *C, bNodeTree *ntree, int type, float locx, float locy)
+{
+  bNode *new_node = nodeAddStaticNode(C, ntree, type);
+
+  if (new_node) {
+    new_node->locx = locx;
+    new_node->locy = locy;
+  }
+
+  return new_node;
+}
+
+static void link_nodes(
+    bNodeTree *ntree, bNode *source, const char *sock_out, bNode *dest, const char *sock_in)
+{
+  bNodeSocket *source_socket = nodeFindSocket(source, SOCK_OUT, sock_out);
+
+  if (!source_socket) {
+    std::cerr << "PROGRAMMER ERROR: Couldn't find output socket " << sock_out << std::endl;
+    return;
+  }
+
+  bNodeSocket *dest_socket = nodeFindSocket(dest, SOCK_IN, sock_in);
+
+  if (!dest_socket) {
+    std::cerr << "PROGRAMMER ERROR: Couldn't find input socket " << sock_in << std::endl;
+    return;
+  }
+
+  nodeAddLink(ntree, source, source_socket, dest, dest_socket);
+}
+
+static pxr::UsdShadeShader get_source_shader(const pxr::UsdShadeConnectableAPI &source,
+                                             pxr::TfToken in_shader_id)
 {
+  if (source && source.IsShader()) {
+    pxr::UsdShadeShader source_shader(source.GetPrim());
+    if (source_shader) {
+      pxr::TfToken shader_id;
+      if (source_shader.GetShaderId(&shader_id) && shader_id == in_shader_id) {
+        return source_shader;
+      }
+    }
+  }
+  return pxr::UsdShadeShader();
 }
 
-USDMaterialImporter::~USDMaterialImporter()
+namespace blender::io::usd {
+
+namespace {
+
+void compute_node_loc(
+    int column, float node_height, float &r_locx, float &r_locy, NodePlacementContext &r_ctx)
 {
+  r_locx = r_ctx.origx - column * r_ctx.horizontal_step;
+
+  if (column >= r_ctx.column_offsets.size()) {
+    r_ctx.column_offsets.push_back(0.0f);
+  }
+
+  r_locy = r_ctx.origy - r_ctx.column_offsets[column];
+
+  r_ctx.column_offsets[column] += node_height + 10.0f;
 }
 
+}  // namespace
+
+USDMaterialImporter::USDMaterialImporter(const USDImporterContext &context, Main *bmain)
+    : context_(context), bmain_(bmain)
+{
+}
 
 Material *USDMaterialImporter::add_material(const pxr::UsdShadeMaterial &usd_material) const
 {
@@ -54,7 +153,320 @@ Material *USDMaterialImporter::add_material(const pxr::UsdShadeMaterial &usd_mat
 
   std::string mtl_name = usd_material.GetPrim().GetName().GetString().c_str();
 
-  return BKE_material_add(bmain_, mtl_name.c_str());
+  /* Create the material. */
+  Material *mtl = BKE_material_add(bmain_, mtl_name.c_str());
+
+  /* Optionally, create shader nodes to represent a UsdPreviewSurface. */
+  if (context_.import_params.import_usdpreview) {
+    import_usd_preview(mtl, usd_material);
+  }
+
+  return mtl;
+}
+
+/* Convert a UsdPreviewSurface shader network to Blender nodes.
+ * The logic doesn't yet handle converting arbitrary prim var reader nodes. */
+
+void USDMaterialImporter::import_usd_preview(Material *mtl,
+                                             const pxr::UsdShadeMaterial &usd_material) const
+{
+  if (!usd_material) {
+    return;
+  }
+
+  /* Get the surface shader. */
+  pxr::UsdShadeShader surf_shader = usd_material.ComputeSurfaceSource();
+
+  if (surf_shader) {
+    /* Check if we have a UsdPreviewSurface shader. */
+    pxr::TfToken shader_id;
+    if (surf_shader.GetShaderId(&shader_id) && shader_id == usdtokens::UsdPreviewSurface) {
+      import_usd_preview(mtl, surf_shader);
+    }
+  }
+}
+
+/* Create the Principled BSDF shader node network. */
+void USDMaterialImporter::import_usd_preview(Material *mtl,
+                                             const pxr::UsdShadeShader &usd_shader) const
+{
+  if (!(bmain_ && mtl && usd_shader)) {
+    return;
+  }
+
+  /* Create the Material's node tree containing the principled
+   *  and output shader. */
+
+  bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", "ShaderNodeTree");
+  mtl->nodetree = ntree;
+  mtl->use_nodes = true;
+
+  bNode *principled = add_node(NULL, ntree, SH_NODE_BSDF_PRINCIPLED, 0.0f, 300.0f);
+
+  if (!principled) {
+    std::cerr << "ERROR: Couldn't create SH_NODE_BSDF_PRINCIPLED node for USD shader "
+              << usd_shader.GetPath() << std::endl;
+    return;
+  }
+
+  bNode *output = add_node(NULL, ntree, SH_NODE_OUTPUT_MATERIAL, 300.0f, 300.0f);
+
+  if (!output) {
+    std::cerr << "ERROR: Couldn't create SH_NODE_OUTPUT_MATERIAL node for USD shader "
+              << usd_shader.GetPath() << std::endl;
+    return;
+  }
+
+  link_nodes(ntree, principled, "BSDF", output, "Surface");
+
+  /* Set up the principled shader inputs. */
+
+  /* The following keep track of the locations for adding
+   * input nodes. */
+
+  NodePlacementContext context(0.0f, 300.0);
+  int column = 0;
+
+  /* Set the principled shader inputs. */
+
+  if (pxr::UsdShadeInput diffuse_input = usd_shader.GetInput(usdtokens::diffuseColor)) {
+    set_node_input(diffuse_input, principled, "Base Color", ntree, column, context);
+  }
+
+  if (pxr::UsdShadeInput emissive_input = usd_shader.GetInput(usdtokens::emissiveColor)) {
+    set_node_input(emissive_input, principled, "Emission", ntree, column, context);
+  }
+
+  if (pxr::UsdShadeInput specular_input = usd_shader.GetInput(usdtokens::specularColor)) {
+    set_node_input(specular_input, principled, "Specular", ntree, column, context);
+  }
+
+  if (pxr::UsdShadeInput metallic_input = usd_shader.GetInput(usdtokens::metallic)) {
+    ;
+    set_node_input(metallic_input, principled, "Metallic", ntree, column, context);
+  }
+
+  if (pxr::UsdShadeInput roughness_input = usd_shader.GetInput(usdtokens::roughness)) {
+    set_node_input(roughne

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list