[Bf-blender-cvs] [5f74fc980d4] usd-importer-T81257-merge: USD Import: USD Preview conversion.

makowalski noreply at git.blender.org
Fri Mar 5 22:00:39 CET 2021


Commit: 5f74fc980d486621c59a352fa68f8e646f434f85
Author: makowalski
Date:   Fri Mar 5 15:53:54 2021 -0500
Branches: usd-importer-T81257-merge
https://developer.blender.org/rB5f74fc980d486621c59a352fa68f8e646f434f85

USD Import: USD Preview conversion.

Added experimental Import USD Preview option to convert
UsdPreviewSurface shaders to Principled BSD shader networks,
for an approximate preview.  Added new USDMaterialReader
class, which implements this feature.  Also added a
Set Material Blend option to automatically set the material
blend method based on the UsdPreviewSurface shader's opacity
and opacityThreshold inputs.  Finally, updated the logic so that
no materials will be imported if the Materials option is
not checked.

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

M	source/blender/editors/io/io_usd.c
M	source/blender/io/usd/CMakeLists.txt
A	source/blender/io/usd/intern/usd_reader_material.cc
A	source/blender/io/usd/intern/usd_reader_material.h
M	source/blender/io/usd/intern/usd_reader_mesh.cc
M	source/blender/io/usd/intern/usd_reader_mesh.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 145d6f2a57c..d5f379c8381 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -313,6 +313,9 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
 
   const bool use_instancing = RNA_boolean_get(op->ptr, "use_instancing");
 
+  const bool import_usd_preview = RNA_boolean_get(op->ptr, "import_usd_preview");
+  const bool set_material_blend = RNA_boolean_get(op->ptr, "set_material_blend");
+
   int offset = 0;
   int sequence_len = 1;
 
@@ -355,6 +358,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
       import_render,
       import_visible_only,
       use_instancing,
+      import_usd_preview,
+      set_material_blend,
   };
 
   bool ok = USD_import(C, filename, &params, as_background_job);
@@ -443,6 +448,8 @@ 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_usd_preview", 0, NULL, ICON_NONE);
+  uiItemR(box, ptr, "set_material_blend", 0, NULL, ICON_NONE);
 }
 
 void WM_OT_usd_import(struct wmOperatorType *ot)
@@ -593,6 +600,21 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
       "Instancing",
       "When checked, USD scenegraph instances are imported as collection instances in Blender.  "
       "Note that point instancers are not yet handled by this option");
+
+  RNA_def_boolean(
+      ot->srna,
+      "import_usd_preview",
+      false,
+      "Import USD Preview",
+      "When checked, convert UsdPreviewSurface shaders to Principled BSD shader networks.");
+
+  RNA_def_boolean(ot->srna,
+                  "set_material_blend",
+                  false,
+                  "Set Material Blend",
+                  "When checked and if the Import Usd Preview option is enabled, "
+                  "the material blend method will automatically be set based on the "
+                  "shader's opacity and opacityThreshold inputs");
 }
 
 #endif /* WITH_USD */
diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt
index 70a1045be85..94565b5e52f 100644
--- a/source/blender/io/usd/CMakeLists.txt
+++ b/source/blender/io/usd/CMakeLists.txt
@@ -70,6 +70,7 @@ set(SRC
   intern/usd_reader_geom.cc
   intern/usd_reader_instance.cc
   intern/usd_reader_light.cc
+  intern/usd_reader_material.cc
   intern/usd_reader_mesh.cc
   intern/usd_reader_nurbs.cc
   intern/usd_reader_prim.cc
@@ -95,6 +96,7 @@ set(SRC
   intern/usd_reader_geom.h
   intern/usd_reader_instance.h
   intern/usd_reader_light.h
+  intern/usd_reader_material.h
   intern/usd_reader_mesh.h
   intern/usd_reader_nurbs.h
   intern/usd_reader_prim.h
diff --git a/source/blender/io/usd/intern/usd_reader_material.cc b/source/blender/io/usd/intern/usd_reader_material.cc
new file mode 100644
index 00000000000..8a8f5506ba1
--- /dev/null
+++ b/source/blender/io/usd/intern/usd_reader_material.cc
@@ -0,0 +1,577 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "usd_reader_material.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 usdtokens {
+
+// 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 opacityThreshold("opacityThreshold", 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);
+
+// Color space names
+static const pxr::TfToken raw("raw", pxr::TfToken::Immortal);
+static const pxr::TfToken RAW("RAW", 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();
+}
+
+// Returns true if the given shader may have opacity < 1.0, based
+// on heuristics.  Also returns the shader's opacityThreshold input
+// in r_opacity_threshold, if this input has an authored value.
+static bool needs_blend(const pxr::UsdShadeShader &usd_shader, float &r_opacity_threshold)
+{
+  if (!usd_shader) {
+    return false;
+  }
+
+  bool needs_blend = false;
+
+  if (pxr::UsdShadeInput opacity_input = usd_shader.GetInput(usdtokens::opacity)) {
+
+    if (opacity_input.HasConnectedSource()) {
+      needs_blend = true;
+    }
+    else {
+      pxr::VtValue val;
+      if (opacity_input.GetAttr().HasAuthoredValue() && opacity_input.GetAttr().Get(&val)) {
+        float opacity = val.Get<float>();
+        needs_blend = opacity < 1.0f;
+      }
+    }
+  }
+
+  if (pxr::UsdShadeInput opacity_threshold_input = usd_shader.GetInput(
+          usdtokens::opacityThreshold)) {
+
+    pxr::VtValue val;
+    if (opacity_threshold_input.GetAttr().HasAuthoredValue() &&
+        opacity_threshold_input.GetAttr().Get(&val)) {
+      r_opacity_threshold = val.Get<float>();
+    }
+  }
+
+  return needs_blend;
+}
+
+namespace blender::io::usd {
+
+namespace {
+
+// Compute the x- and y-coordinates for placing a new node in an unoccupied region of
+// the column with the given index.  Returns the coordinates in r_locx and r_locy and
+// updates the column-occupancy information in r_ctx.
+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];
+
+  // Record the y-offset of the occupied region in
+  // the column, including padding.
+  r_ctx.column_offsets[column] += node_height + 10.0f;
+}
+
+}  // namespace
+
+ USDMaterialReader::USDMaterialReader(const USDImportParams &params, Main *bmain)
+     : m_params(params), bmain_(bmain)
+ {
+ }
+
+ Material *USDMaterialReader::add_material(const pxr::UsdShadeMaterial &usd_material) const
+ {
+   if (!(bmain_ && usd_material)) {
+     return nullptr;
+   }
+
+   std::string mtl_name = usd_material.GetPrim().GetName().GetString().c_str();
+
+   /* Create the material.

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list