MaterialX: Implement export of Input nodes #20

Merged
Bogdan Nagirniak merged 26 commits from Vasyl-Pidhirskyi/blender:BLEN-530 into matx-export-material 2023-09-15 19:55:37 +02:00
21 changed files with 116 additions and 122 deletions
Showing only changes of commit b06e2e9da5 - Show all commits

View File

@ -376,6 +376,8 @@ NodeItem NodeItem::convert(Type to_type) const
switch (to_type) {
case Type::Vector4:
return convert(Type::Vector3).convert(Type::Vector4);
case Type::Vector3:
return convert(Type::Vector3);
case Type::Color3:
return convert(Type::Vector3).convert(Type::Color3);
case Type::Color4:
@ -388,12 +390,20 @@ NodeItem NodeItem::convert(Type to_type) const
switch (to_type) {
case Type::Color4:
return convert(Type::Color3).convert(Type::Color4);
case Type::Color3:
return convert(Type::Color3);
case Type::Vector4:
return convert(Type::Vector4);
case Type::Vector2:
return convert(Type::Vector2);
default:
break;
}
break;
case Type::Vector4:
switch (to_type) {
case Type::Vector3:
return convert(Type::Vector3);
case Type::Vector2:
return convert(Type::Vector3).convert(Type::Vector2);
case Type::Color3:
@ -408,6 +418,8 @@ NodeItem NodeItem::convert(Type to_type) const
return convert(Type::Vector3).convert(Type::Vector2);
case Type::Vector4:
return convert(Type::Vector3).convert(Type::Vector4);
case Type::Vector3:
return convert(Type::Vector3);
default:
break;
}

View File

@ -73,12 +73,12 @@ NodeItem NodeParser::create_node(const std::string &category, NodeItem::Type typ
NodeItem NodeParser::get_input_default(const std::string &name, NodeItem::Type to_type)
{
return get_input_default(node_->input_by_identifier(name), to_type);
return get_default(node_->input_by_identifier(name), to_type);
}
NodeItem NodeParser::get_input_default(int index, NodeItem::Type to_type)
{
return get_input_default(node_->input_socket(index), to_type);
return get_default(node_->input_socket(index), to_type);
}
NodeItem NodeParser::get_input_link(const std::string &name, NodeItem::Type to_type)
@ -101,14 +101,14 @@ NodeItem NodeParser::get_input_value(int index, NodeItem::Type to_type)
return get_input_value(node_->input_socket(index), to_type);
}
NodeItem NodeParser::get_output_default(const std::string &name)
NodeItem NodeParser::get_output_default(const std::string &name, NodeItem::Type to_type)
{
return get_output_default(node_->output_by_identifier(name));
return get_default(node_->output_by_identifier(name), to_type);
}
NodeItem NodeParser::get_output_default(int index)
NodeItem NodeParser::get_output_default(int index, NodeItem::Type to_type)
{
return get_output_default(node_->output_socket(index));
return get_default(node_->output_socket(index), to_type);
}
NodeItem NodeParser::empty() const
@ -116,29 +116,19 @@ NodeItem NodeParser::empty() const
return NodeItem(graph_);
}
NodeItem NodeParser::texcoord_node()
NodeItem NodeParser::texcoord_node(NodeItem::Type data_type)
{
NodeItem res = empty();
res.node = graph_->getNode(TEXCOORD_NODE_NAME);
std::string name = TEXCOORD_NODE_NAME + "_" + NodeItem::type(data_type);
res.node = graph_->getNode(name);
if (!res.node) {
res = create_node("texcoord", NodeItem::Type::Vector2);
res.node->setName(TEXCOORD_NODE_NAME);
res = create_node("texcoord", data_type);
res.node->setName(name);
}
return res;
}
NodeItem NodeParser::get_input_default(const bNodeSocket &socket, NodeItem::Type to_type)
{
NodeItem res = get_value_default(socket);
return res.convert(to_type);
}
NodeItem NodeParser::get_output_default(const bNodeSocket &socket)
{
return get_value_default(socket);
}
NodeItem NodeParser::get_value_default(const bNodeSocket &socket)
NodeItem NodeParser::get_default(const bNodeSocket &socket, NodeItem::Type to_type)
{
NodeItem res = empty();
switch (socket.type) {
@ -163,7 +153,7 @@ NodeItem NodeParser::get_value_default(const bNodeSocket &socket)
CLOG_WARN(LOG_MATERIALX_SHADER, "Unsupported socket type: %d", socket.type);
}
}
return res;
return res.convert(to_type);
}
NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to_type)
@ -201,7 +191,7 @@ NodeItem NodeParser::get_input_value(const bNodeSocket &socket, NodeItem::Type t
{
NodeItem res = get_input_link(socket, to_type);
if (!res) {
res = get_input_default(socket, to_type);
res = get_default(socket, to_type);
}
return res;
}

View File

@ -42,20 +42,18 @@ class NodeParser {
NodeItem create_node(const std::string &category, NodeItem::Type type);
NodeItem get_input_default(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_default(int index, NodeItem::Type to_type);
NodeItem get_output_default(const std::string &name);
NodeItem get_output_default(int index);
NodeItem get_output_default(const std::string &name, NodeItem::Type to_type);
NodeItem get_output_default(int index, NodeItem::Type to_type);
NodeItem get_input_link(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_link(int index, NodeItem::Type to_type);
NodeItem get_input_value(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_value(int index, NodeItem::Type to_type);
NodeItem empty() const;
template<class T> NodeItem val(const T &data) const;
NodeItem texcoord_node();
NodeItem texcoord_node(NodeItem::Type data_type = NodeItem::Type::Vector2);
private:
NodeItem get_input_default(const bNodeSocket &socket, NodeItem::Type to_type);
NodeItem get_output_default(const bNodeSocket &socket);
NodeItem get_value_default(const bNodeSocket &socket);
NodeItem get_default(const bNodeSocket &socket, NodeItem::Type to_type);
NodeItem get_input_link(const bNodeSocket &socket, NodeItem::Type to_type);
NodeItem get_input_value(const bNodeSocket &socket, NodeItem::Type to_type);
BogdanNagirniak marked this conversation as resolved Outdated

use one function here instead of 3 get_default(const bNodeSocket &socket, NodeItem::Type to_type)

use one function here instead of 3 `get_default(const bNodeSocket &socket, NodeItem::Type to_type)`
};

View File

@ -56,6 +56,7 @@ static void node_shader_init_ambient_occlusion(bNodeTree * /*ntree*/, bNode *nod
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: observed crash while rendering MaterialX_v1_38_6::ExceptionShaderGenError */
/*
@ -64,12 +65,9 @@ NODE_SHADER_MATERIALX_BEGIN
* res.set_input("coneangle", val(90.0f));
* res.set_input("maxdistance", maxdistance);
*/
BogdanNagirniak marked this conversation as resolved
Review
NodeItem color = get_input_value("Color", NodeItem::Type::Color4);
NodeItem res = color;
``` NodeItem color = get_input_value("Color", NodeItem::Type::Color4); NodeItem res = color; ```
NodeItem res = val(MaterialX::Color4(1.0f, 0.0f, 1.0f, 1.0f));
if (STREQ(socket_out_->name, "AO")) {
res = res.extract(3);
}
return res;
return get_output_default(socket_out_->name, NodeItem::Type::Any);
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_ambient_occlusion_cc

View File

@ -78,22 +78,14 @@ static int node_shader_gpu_attribute(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: some outputs expected be implemented within the next iteration (see nodedef
* <geompropvalue>) */
BogdanNagirniak marked this conversation as resolved
Review

Start with NodeItem res = empty(); add check if (STREQ(socket_out_->name, "Color"))

Start with `NodeItem res = empty();` add check `if (STREQ(socket_out_->name, "Color"))`
NodeItem res = val(MaterialX::Color4(1.0f, 0.0f, 1.0f, 1.0f));
if (STREQ(socket_out_->name, "Vector")) {
res = val(MaterialX::Vector3(1.0f, 1.0f, 1.0f));
}
if (STREQ(socket_out_->name, "Factor")) {
res = res.extract(3);
}
if (STREQ(socket_out_->name, "Alpha")) {
res = res.extract(3);
}
return res;
return get_output_default(socket_out_->name, NodeItem::Type::Any);
}
#endif
BogdanNagirniak marked this conversation as resolved Outdated

else if

`else if`
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_attribute_cc

View File

@ -40,11 +40,12 @@ static int gpu_shader_bevel(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
BogdanNagirniak marked this conversation as resolved
Review

NOTE instead TODO if there is no implementation in MatX. No need 1.38.6, just in MaterialX

`NOTE` instead `TODO` if there is no implementation in MatX. No need 1.38.6, just `in MaterialX`
/* TODO: This node doesn't have an implementation in MaterialX 1.38.6.*/
return val(MaterialX::Vector3(1.0f, 1.0f, 1.0f));
;
/* NOTE: This node doesn't have an implementation in MaterialX.*/
BogdanNagirniak marked this conversation as resolved Outdated

return get_input_link("Normal", NodeItem::Type::Vector3);

`return get_input_link("Normal", NodeItem::Type::Vector3);`
return get_input_link("Normal", NodeItem::Type::Vector3);
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_bevel_cc

View File

@ -27,17 +27,12 @@ static int gpu_shader_camera(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: This node doesn't have an implementation in MaterialX 1.38.6.*/
NodeItem res = val(MaterialX::Vector3(1.0f, 1.0f, 1.0f));
if (STREQ(socket_out_->name, "View Z Depth")) {
res = res.extract(2);
}
if (STREQ(socket_out_->name, "View Distance")) {
res = res.extract(2);
}
return res;
/* NOTE: This node doesn't have an implementation in MaterialX.*/
return get_output_default(socket_out_->name, NodeItem::Type::Any);
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_camera_cc

View File

@ -27,11 +27,13 @@ static int node_shader_gpu_fresnel(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: some outputs expected be implemented within the next iteration (see nodedef
* <artistic_ior>) */
return get_input_value("IOR", NodeItem::Type::Float);
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_fresnel_cc

View File

@ -59,30 +59,30 @@ static int node_shader_gpu_geometry(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: Partially implemented, some nodes don't have an implementation in MaterialX 1.38.6.*/
CLG_LogRef *LOG_MATERIALX_SHADER = materialx::LOG_MATERIALX_SHADER;
/* NOTE: Some outputs don't have an implementation in MaterialX.*/
NodeItem res = empty();
const char *output_name = socket_out_->name;
std::string name = socket_out_->name;
BogdanNagirniak marked this conversation as resolved
Review

maybe std::string name = socket_out_->name ?

maybe std::string name = socket_out_->name ?
if (STREQ(output_name, "Position")) {
if (name == "Position"){
res = create_node("position", NodeItem::Type::Vector3);
res.set_input("space", val(std::string("world")));
}
if (STREQ(output_name, "Normal")) {
else if (name =="Normal"){
res = create_node("normal", NodeItem::Type::Vector3);
res.set_input("space", val(std::string("world")));
}
if (STREQ(output_name, "Tangent")) {
else if (ELEM(name, "Tangent", "True Normal")) {
res = create_node("tangent", NodeItem::Type::Vector3);
res.set_input("space", val(std::string("world")));
}
else {
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented output %s", output_name);
res = get_output_default(name, NodeItem::Type::Any);
}
return res;
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_geometry_cc

View File

@ -30,14 +30,12 @@ static int node_shader_gpu_hair_info(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: This node doesn't have an implementation in MaterialX 1.38.6.*/
NodeItem res = val(MaterialX::Vector3(1.0f, 1.0f, 1.0f));
if (!STREQ(socket_out_->name, "Tangent Normal")) {
res = res.extract(2);
}
return res;
/* NOTE: This node doesn't have an implementation in MaterialX.*/
return get_output_default(socket_out_->name, NodeItem::Type::Any);
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_hair_info_cc

View File

@ -28,11 +28,13 @@ static int node_shader_gpu_layer_weight(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: some outputs expected be implemented partially within the next iteration (see nodedef
* <artistic_ior>) */
return val(1.0f);
return get_input_link("Blend", NodeItem::Type::Float);
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_layer_weight_cc

View File

@ -31,22 +31,19 @@ static int node_shader_gpu_object_info(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: Partially implemented, some nodes don't have an implementation in MaterialX 1.38.6.
* some outputs expected be implemented within the next iteration*/
CLG_LogRef *LOG_MATERIALX_SHADER = materialx::LOG_MATERIALX_SHADER;
/* NOTE: Some outputs don't have an implementation in MaterialX.*/
NodeItem res = empty();
const char *output_name = socket_out_->name;
std::string name = socket_out_->name;
if (STREQ(output_name, "Location")) {
if (name == "Location") {
res = create_node("position", NodeItem::Type::Vector3);
res.set_input("space", val(std::string("world")));
}
/* TODO: This node doesn't have an implementation in MaterialX 1.38.6.
/* TODO: This node doesn't have an implementation in MaterialX.
* It's added in MaterialX 1.38.8. Uncomment this code after switching to 1.38.8.
* if (STREQ(output_name, "Random")) {
* if (name=="Random") {
* res = create_node("randomfloat", NodeItem::Type::Float);
* res.set_input("in", val(0.0));
* res.set_input("min", val(0.0));
@ -54,10 +51,11 @@ NODE_SHADER_MATERIALX_BEGIN
* res.set_input("seed", val(0));
*}*/
else {
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented output %s", output_name);
res = get_output_default(name, NodeItem::Type::Any);
}
return res;
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_object_info_cc

View File

@ -35,17 +35,12 @@ static int gpu_shader_particle_info(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: This node doesn't have an implementation in MaterialX 1.38.6.*/
NodeItem res = val(MaterialX::Vector3(1.0f, 1.0f, 1.0f));
if (STREQ(socket_out_->name, "Index") || STREQ(socket_out_->name, "Random") ||
STREQ(socket_out_->name, "Age") || STREQ(socket_out_->name, "Lifetime") ||
STREQ(socket_out_->name, "Size"))
{
res = res.extract(2);
}
return res;
/* NOTE: This node doesn't have an implementation in MaterialX.*/
return get_output_default(socket_out_->name, NodeItem::Type::Any);
BogdanNagirniak marked this conversation as resolved Outdated

use std::string name = socket_out_->name and ELEM(name, ....)

use `std::string name = socket_out_->name` and `ELEM(name, ....)`
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_particle_info_cc

View File

@ -23,14 +23,12 @@ static int node_shader_gpu_point_info(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: This node doesn't have an implementation in MaterialX 1.38.6.*/
NodeItem res = val(MaterialX::Vector3(1.0f, 1.0f, 1.0f));
if (STREQ(socket_out_->name, "Radius") || STREQ(socket_out_->name, "Random")) {
res = res.extract(2);
}
return res;
/* NOTE: This node doesn't have an implementation in MaterialX.*/
return get_output_default(socket_out_->name, NodeItem::Type::Any);
}
#endif
NODE_SHADER_MATERIALX_END
BogdanNagirniak marked this conversation as resolved
Review

I think return get_output_default can be used here

I think `return get_output_default` can be used here
} // namespace blender::nodes::node_shader_point_info_cc

View File

@ -27,11 +27,13 @@ static int gpu_shader_rgb(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
NodeItem res = create_node("constant", NodeItem::Type::Color4);
res.set_input("value", get_output_default("Color"));
res.set_input("value", get_output_default("Color", NodeItem::Type::Color4));
return res;
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_rgb_cc

View File

@ -87,10 +87,12 @@ static int node_shader_gpu_tangent(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: This node doesn't have an implementation in MaterialX 1.38.6.*/
return val(MaterialX::Vector3(1.0f, 1.0f, 1.0f));
/* TODO: This node doesn't have an implementation in MaterialX.*/
return get_output_default(socket_out_->name, NodeItem::Type::Vector3);;
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_tangent_cc

View File

@ -72,24 +72,30 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: Partially implemented, some nodes don't have an implementation in MaterialX 1.38.6.
* some outputs expected be implemented within the next iteration*/
/* NOTE: Some outputs don't have an implementation in MaterialX.*/
BogdanNagirniak marked this conversation as resolved Outdated

This node I think has to be implemented in this PR

This node I think has to be implemented in this PR
NodeItem res = empty();
std::string name = socket_out_->name;
CLG_LogRef *LOG_MATERIALX_SHADER = materialx::LOG_MATERIALX_SHADER;
NodeItem res = val(MaterialX::Vector2(1.0f, 1.0f));
const char *output_name = socket_out_->name;
if (STREQ(output_name, "UV")) {
res = texcoord_node();
if (ELEM(name, "Generated", "UV")) {
res = texcoord_node(NodeItem::Type::Vector3);
}
else if (name == "Normal") {
res = create_node("normal", NodeItem::Type::Vector3);
res.set_input("space", val(std::string("world")));
}
else if (name == "Object") {
res = create_node("position", NodeItem::Type::Vector3);
res.set_input("space", val(std::string("world")));
}
else {
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented output %s", output_name);
res = get_output_default(name, NodeItem::Type::Any);
}
return res;
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_tex_coord_cc

View File

@ -68,10 +68,14 @@ static int node_shader_gpu_uvmap(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
BogdanNagirniak marked this conversation as resolved
Review

I think it is implemented here, use NOTE that other properties of node are unsupported

I think it is implemented here, use NOTE that other properties of node are unsupported
/* TODO: Partially implemented*/
return texcoord_node();
/* NODE: "From Instances" not implemented
* UV selection not implemented
*/
return texcoord_node(NodeItem::Type::Vector3);
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_uvmap_cc

View File

@ -39,11 +39,13 @@ static void sh_node_value_build_multi_function(NodeMultiFunctionBuilder &builder
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
NodeItem res = create_node("constant", NodeItem::Type::Float);
res.set_input("value", get_output_default("Value"));
res.set_input("value", get_output_default("Value", NodeItem::Type::Float));
return res;
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_value_cc

View File

@ -68,16 +68,13 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: some output expected be implemented within the next iteration (see nodedef
* <geomcolor>)*/
BogdanNagirniak marked this conversation as resolved
Review

start from empty()

start from empty()
NodeItem res = val(MaterialX::Color4(1.0f, 0.0f, 1.0f, 1.0f));
if (STREQ(socket_out_->name, "Alpha")) {
res = res.extract(3);
}
return res;
return get_output_default(socket_out_->name, NodeItem::Type::Any);
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_vertex_color_cc

View File

@ -41,10 +41,12 @@ static int node_shader_gpu_wireframe(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: This node doesn't have an implementation in MaterialX 1.38.6.*/
return val(1.0f);
/* NOTE: This node doesn't have an implementation in MaterialX.*/
return get_output_default(socket_out_->name, NodeItem::Type::Float);
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_wireframe_cc