18 #include <pxr/base/gf/vec3f.h>
19 #include <pxr/usd/usdShade/material.h>
20 #include <pxr/usd/usdShade/shader.h>
28 static const pxr::TfToken
a(
"a", pxr::TfToken::Immortal);
29 static const pxr::TfToken
b(
"b", pxr::TfToken::Immortal);
30 static const pxr::TfToken
clearcoat(
"clearcoat", pxr::TfToken::Immortal);
32 static const pxr::TfToken
diffuseColor(
"diffuseColor", pxr::TfToken::Immortal);
33 static const pxr::TfToken
emissiveColor(
"emissiveColor", pxr::TfToken::Immortal);
34 static const pxr::TfToken
file(
"file", pxr::TfToken::Immortal);
35 static const pxr::TfToken
g(
"g", pxr::TfToken::Immortal);
36 static const pxr::TfToken
ior(
"ior", pxr::TfToken::Immortal);
37 static const pxr::TfToken
metallic(
"metallic", pxr::TfToken::Immortal);
38 static const pxr::TfToken
normal(
"normal", pxr::TfToken::Immortal);
39 static const pxr::TfToken
occlusion(
"occlusion", pxr::TfToken::Immortal);
40 static const pxr::TfToken
opacity(
"opacity", pxr::TfToken::Immortal);
41 static const pxr::TfToken
opacityThreshold(
"opacityThreshold", pxr::TfToken::Immortal);
42 static const pxr::TfToken
r(
"r", pxr::TfToken::Immortal);
43 static const pxr::TfToken
result(
"result", pxr::TfToken::Immortal);
44 static const pxr::TfToken
rgb(
"rgb", pxr::TfToken::Immortal);
45 static const pxr::TfToken
rgba(
"rgba", pxr::TfToken::Immortal);
46 static const pxr::TfToken
roughness(
"roughness", pxr::TfToken::Immortal);
47 static const pxr::TfToken
sourceColorSpace(
"sourceColorSpace", pxr::TfToken::Immortal);
48 static const pxr::TfToken
specularColor(
"specularColor", pxr::TfToken::Immortal);
49 static const pxr::TfToken
st(
"st", pxr::TfToken::Immortal);
50 static const pxr::TfToken
varname(
"varname", pxr::TfToken::Immortal);
53 static const pxr::TfToken
raw(
"raw", pxr::TfToken::Immortal);
54 static const pxr::TfToken
RAW(
"RAW", pxr::TfToken::Immortal);
59 pxr::TfToken::Immortal);
60 static const pxr::TfToken
UsdUVTexture(
"UsdUVTexture", pxr::TfToken::Immortal);
70 new_node->
locx = locx;
71 new_node->
locy = locy;
84 std::cerr <<
"PROGRAMMER ERROR: Couldn't find output socket " << sock_out << std::endl;
91 std::cerr <<
"PROGRAMMER ERROR: Couldn't find input socket " << sock_in << std::endl;
110 if (opacity_input.HasConnectedSource()) {
115 if (opacity_input.GetAttr().HasAuthoredValue() && opacity_input.GetAttr().Get(&val)) {
116 float opacity = val.Get<
float>();
128 float default_value = 0.0f)
131 return default_value;
136 if (!opacity_threshold_input) {
137 return default_value;
141 if (opacity_threshold_input.GetAttr().HasAuthoredValue() &&
142 opacity_threshold_input.GetAttr().Get(&val)) {
143 return val.Get<
float>();
146 return default_value;
152 return pxr::TfToken();
157 if (!color_space_input) {
158 return pxr::TfToken();
161 pxr::VtValue color_space_val;
162 if (color_space_input.Get(&color_space_val) && color_space_val.IsHolding<pxr::TfToken>()) {
163 return color_space_val.Get<pxr::TfToken>();
166 return pxr::TfToken();
173 pxr::UsdShadeShader &r_preview_surface)
179 if (pxr::UsdShadeShader surf_shader = usd_material.ComputeSurfaceSource()) {
181 pxr::TfToken shader_id;
183 r_preview_surface = surf_shader;
195 if (!(mtl && usd_preview)) {
201 if (diffuse_color_input.GetAttr().HasAuthoredValue() &&
202 diffuse_color_input.GetAttr().Get(&val) && val.IsHolding<pxr::GfVec3f>()) {
203 pxr::GfVec3f
color = val.UncheckedGet<pxr::GfVec3f>();
212 if (metallic_input.GetAttr().HasAuthoredValue() && metallic_input.GetAttr().Get(&val) &&
213 val.IsHolding<
float>()) {
220 if (roughness_input.GetAttr().HasAuthoredValue() && roughness_input.GetAttr().Get(&val) &&
221 val.IsHolding<
float>()) {
234 void compute_node_loc(
const int column,
float *r_locx,
float *r_locy, NodePlacementContext *r_ctx)
236 if (!(r_locx && r_locy && r_ctx)) {
240 (*r_locx) = r_ctx->origx - column * r_ctx->horizontal_step;
242 if (column >= r_ctx->column_offsets.size()) {
243 r_ctx->column_offsets.push_back(0.0f);
246 (*r_locy) = r_ctx->origy - r_ctx->column_offsets[column];
250 r_ctx->column_offsets[column] += r_ctx->vertical_step + 10.0f;
256 : params_(
params), bmain_(bmain)
262 if (!(
bmain_ && usd_material)) {
266 std::string mtl_name = usd_material.GetPrim().GetName().GetString();
274 pxr::UsdShadeShader usd_preview;
289 const pxr::UsdShadeShader &usd_shader)
const
291 if (!(
bmain_ && mtl && usd_shader)) {
307 std::cerr <<
"ERROR: Couldn't create SH_NODE_BSDF_PRINCIPLED node for USD shader "
308 << usd_shader.GetPath() << std::endl;
316 std::cerr <<
"ERROR: Couldn't create SH_NODE_OUTPUT_MATERIAL node for USD shader "
317 << usd_shader.GetPath() << std::endl;
336 if (opacity_threshold > 0.0f) {
349 const pxr::UsdShadeShader &usd_shader)
const
386 if (pxr::UsdShadeInput clearcoat_roughness_input = usd_shader.GetInput(
389 clearcoat_roughness_input, principled,
"Clearcoat Roughness",
ntree, column, &
context);
396 if (pxr::UsdShadeInput ior_input = usd_shader.GetInput(
usdtokens::ior)) {
407 const char *dest_socket_name,
412 if (!(usd_input && dest_node && r_ctx)) {
416 if (usd_input.HasConnectedSource()) {
426 std::cerr <<
"ERROR: couldn't get destination node socket " << dest_socket_name << std::endl;
431 if (!usd_input.Get(&val)) {
432 std::cerr <<
"ERROR: couldn't get value for usd shader input "
433 << usd_input.GetPrim().GetPath() << std::endl;
437 switch (sock->
type) {
439 if (val.IsHolding<
float>()) {
442 else if (val.IsHolding<pxr::GfVec3f>()) {
443 pxr::GfVec3f v3f = val.UncheckedGet<pxr::GfVec3f>();
444 float average = (v3f[0] + v3f[1] + v3f[2]) / 3.0f;
449 if (val.IsHolding<pxr::GfVec3f>()) {
450 pxr::GfVec3f v3f = val.UncheckedGet<pxr::GfVec3f>();
455 if (val.IsHolding<pxr::GfVec3f>()) {
456 pxr::GfVec3f v3f = val.UncheckedGet<pxr::GfVec3f>();
459 else if (val.IsHolding<pxr::GfVec2f>()) {
460 pxr::GfVec2f v2f = val.UncheckedGet<pxr::GfVec2f>();
465 std::cerr <<
"WARNING: unexpected type " << sock->
idname <<
" for destination node socket "
466 << dest_socket_name << std::endl;
474 const char *dest_socket_name,
479 if (!(usd_input && dest_node && dest_socket_name &&
ntree && r_ctx)) {
483 pxr::UsdShadeConnectableAPI source;
484 pxr::TfToken source_name;
485 pxr::UsdShadeAttributeType source_type;
487 usd_input.GetConnectedSource(&source, &source_name, &source_type);
489 if (!(source && source.GetPrim().IsA<pxr::UsdShadeShader>())) {
493 pxr::UsdShadeShader source_shader(source.GetPrim());
495 if (!source_shader) {
499 pxr::TfToken shader_id;
500 if (!source_shader.GetShaderId(&shader_id)) {
501 std::cerr <<
"ERROR: couldn't get shader id for source shader "
502 << source_shader.GetPrim().GetPath() << std::endl;
509 if (strcmp(dest_socket_name,
"Normal") == 0) {
514 compute_node_loc(column + 1, &locx, &locy, r_ctx);
526 source_shader, source_name, normal_map,
"Color",
ntree, column + 2, r_ctx);
530 source_shader, source_name, dest_node, dest_socket_name,
ntree, column + 1, r_ctx);
535 source_shader, source_name, dest_node, dest_socket_name,
ntree, column + 1, r_ctx);
540 const pxr::TfToken &usd_source_name,
542 const char *dest_socket_name,
547 if (!usd_shader || !dest_node || !
ntree || !dest_socket_name || !
bmain_ || !r_ctx) {
553 compute_node_loc(column, &locx, &locy, r_ctx);
559 std::cerr <<
"ERROR: Couldn't create SH_NODE_TEX_IMAGE for node input " << dest_socket_name
570 std::string source_socket_name = usd_source_name ==
usdtokens::a ?
"Alpha" :
"Color";
572 link_nodes(
ntree, tex_image, source_socket_name.c_str(), dest_node, dest_socket_name);
575 if (pxr::UsdShadeInput st_input = usd_shader.GetInput(
usdtokens::st)) {
581 bNode *tex_image)
const
591 std::cerr <<
"WARNING: Couldn't get file input for USD shader " << usd_shader.GetPath()
596 pxr::VtValue file_val;
597 if (!file_input.Get(&file_val) || !file_val.IsHolding<pxr::SdfAssetPath>()) {
598 std::cerr <<
"WARNING: Couldn't get file input value for USD shader " << usd_shader.GetPath()
603 const pxr::SdfAssetPath &asset_path = file_val.Get<pxr::SdfAssetPath>();
604 std::string file_path = asset_path.GetResolvedPath();
605 if (file_path.empty()) {
606 std::cerr <<
"WARNING: Couldn't resolve image asset '" << asset_path
607 <<
"' for Texture Image node." << std::endl;
611 const char *im_file = file_path.c_str();
614 std::cerr <<
"WARNING: Couldn't open image file '" << im_file <<
"' for Texture Image node."
628 if (color_space.IsEmpty()) {
629 color_space = file_input.GetAttr().GetColorSpace();
638 const pxr::UsdShadeShader &usd_shader,
639 const pxr::TfToken & ,
641 const char *dest_socket_name,
646 if (!usd_shader || !dest_node || !
ntree || !dest_socket_name || !
bmain_ || !r_ctx) {
652 compute_node_loc(column, &locx, &locy, r_ctx);
658 std::cerr <<
"ERROR: Couldn't create SH_NODE_UVMAP for node input " << dest_socket_name
666 pxr::VtValue varname_val;
667 if (varname_input.Get(&varname_val) && varname_val.IsHolding<pxr::TfToken>()) {
668 std::string
varname = varname_val.Get<pxr::TfToken>().GetString();
struct Image * BKE_image_load_exists(struct Main *bmain, const char *filepath)
void id_us_min(struct ID *id)
General operations, lookup, etc. for materials.
struct Material * BKE_material_add(struct Main *bmain, const char *name)
#define SH_NODE_BSDF_PRINCIPLED
#define SH_NODE_OUTPUT_MATERIAL
struct bNodeLink * nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock)
struct bNodeSocket * nodeFindSocket(const struct bNode *node, eNodeSocketInOut in_out, const char *identifier)
struct bNodeTree * ntreeAddTree(struct Main *bmain, const char *name, const char *idname)
struct bNode * nodeAddStaticNode(const struct bContext *C, struct bNodeTree *ntree, int type)
void nodeSetActive(struct bNodeTree *ntree, struct bNode *node)
void BKE_ntree_update_main_tree(struct Main *bmain, struct bNodeTree *ntree, struct NodeTreeUpdateExtraParams *params)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define STRNCPY(dst, src)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block SH_NODE_TEX_IMAGE
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value SH_NODE_NORMAL_MAP
Material * add_material(const pxr::UsdShadeMaterial &usd_material) const
void set_node_input(const pxr::UsdShadeInput &usd_input, bNode *dest_node, const char *dest_socket_name, bNodeTree *ntree, int column, NodePlacementContext *r_ctx) const
USDMaterialReader(const USDImportParams ¶ms, Main *bmain)
void convert_usd_primvar_reader_float2(const pxr::UsdShadeShader &usd_shader, const pxr::TfToken &usd_source_name, bNode *dest_node, const char *dest_socket_name, bNodeTree *ntree, int column, NodePlacementContext *r_ctx) const
void convert_usd_uv_texture(const pxr::UsdShadeShader &usd_shader, const pxr::TfToken &usd_source_name, bNode *dest_node, const char *dest_socket_name, bNodeTree *ntree, int column, NodePlacementContext *r_ctx) const
void import_usd_preview(Material *mtl, const pxr::UsdShadeShader &usd_shader) const
void follow_connection(const pxr::UsdShadeInput &usd_input, bNode *dest_node, const char *dest_socket_name, bNodeTree *ntree, int column, NodePlacementContext *r_ctx) const
void load_tex_image(const pxr::UsdShadeShader &usd_shader, bNode *tex_image) const
void set_principled_node_inputs(bNode *principled_node, bNodeTree *ntree, const pxr::UsdShadeShader &usd_shader) const
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img") .image(3
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_device_inline float average(const float2 &a)
static const pxr::TfToken st("st", pxr::TfToken::Immortal)
static const pxr::TfToken opacity("opacity", pxr::TfToken::Immortal)
static const pxr::TfToken UsdPreviewSurface("UsdPreviewSurface", pxr::TfToken::Immortal)
static const pxr::TfToken sourceColorSpace("sourceColorSpace", pxr::TfToken::Immortal)
static const pxr::TfToken clearcoat("clearcoat", pxr::TfToken::Immortal)
static const pxr::TfToken varname("varname", pxr::TfToken::Immortal)
static const pxr::TfToken emissiveColor("emissiveColor", pxr::TfToken::Immortal)
static const pxr::TfToken RAW("RAW", pxr::TfToken::Immortal)
static const pxr::TfToken r("r", pxr::TfToken::Immortal)
static const pxr::TfToken UsdUVTexture("UsdUVTexture", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken ior("ior", pxr::TfToken::Immortal)
static const pxr::TfToken rgba("rgba", pxr::TfToken::Immortal)
static const pxr::TfToken result("result", pxr::TfToken::Immortal)
static const pxr::TfToken raw("raw", pxr::TfToken::Immortal)
static const pxr::TfToken g("g", pxr::TfToken::Immortal)
static const pxr::TfToken occlusion("occlusion", pxr::TfToken::Immortal)
static const pxr::TfToken clearcoatRoughness("clearcoatRoughness", pxr::TfToken::Immortal)
static const pxr::TfToken file("file", pxr::TfToken::Immortal)
static const pxr::TfToken opacityThreshold("opacityThreshold", pxr::TfToken::Immortal)
static const pxr::TfToken normal("normal", pxr::TfToken::Immortal)
static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal)
static const pxr::TfToken metallic("metallic", pxr::TfToken::Immortal)
static const pxr::TfToken diffuseColor("diffuseColor", pxr::TfToken::Immortal)
static const pxr::TfToken rgb("rgb", pxr::TfToken::Immortal)
static const pxr::TfToken specularColor("specularColor", pxr::TfToken::Immortal)
static const pxr::TfToken a("a", pxr::TfToken::Immortal)
static const pxr::TfToken UsdPrimvarReader_float2("UsdPrimvarReader_float2", pxr::TfToken::Immortal)
struct bNodeTree * nodetree
static float get_opacity_threshold(const pxr::UsdShadeShader &usd_shader, float default_value=0.0f)
static pxr::TfToken get_source_color_space(const pxr::UsdShadeShader &usd_shader)
static bool needs_blend(const pxr::UsdShadeShader &usd_shader)
static bool get_usd_preview_surface(const pxr::UsdShadeMaterial &usd_material, pxr::UsdShadeShader &r_preview_surface)
static void link_nodes(bNodeTree *ntree, bNode *source, const char *sock_out, bNode *dest, const char *sock_in)
static void set_viewport_material_props(Material *mtl, const pxr::UsdShadeShader &usd_preview)
static bNode * add_node(const bContext *C, bNodeTree *ntree, const int type, const float locx, const float locy)