[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, ¶ms, 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