matx-code-improvements #8

Merged
Bogdan Nagirniak merged 6 commits from BogdanNagirniak/blender:matx-code-improvements into matx-export-material 2023-09-04 10:10:09 +02:00
7 changed files with 47 additions and 43 deletions
Showing only changes of commit 87a61b8edf - Show all commits

View File

@ -17,42 +17,22 @@ namespace blender::nodes::materialx {
CLG_LOGREF_DECLARE_GLOBAL(LOG_MATERIALX_SHADER, "materialx.shader");
static void export_nodegraph(MaterialX::GraphElement *graph,
Depsgraph *depsgraph,
Material *material)
{
material->nodetree->ensure_topology_cache();
bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL);
OutputMaterialNodeParser parser(graph, depsgraph, material, output_node);
parser.compute();
}
static void create_standard_surface(MaterialX::GraphElement *graph, Material *material)
{
MaterialX::NodePtr standard_surface = graph->addNode(
"standard_surface", MaterialX::EMPTY_STRING, "surfaceshader");
standard_surface->addInput("base", "float")->setValue(1.0);
standard_surface->addInput("base_color", "color3")
->setValue(MaterialX::Color3(material->r, material->g, material->b));
MaterialX::NodePtr surfacematerial = graph->addNode(
"surfacematerial", MaterialX::EMPTY_STRING, "material");
surfacematerial->addInput(standard_surface->getType(), standard_surface->getType())
->setNodeName(standard_surface->getName());
}
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material)
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph,
Material *material,
const std::string &socket_name)
{
CLOG_INFO(LOG_MATERIALX_SHADER, 0, "Material: %s", material->id.name);
MaterialX::DocumentPtr doc = MaterialX::createDocument();
if (material->use_nodes) {
export_nodegraph(doc.get(), depsgraph, material);
material->nodetree->ensure_topology_cache();
bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL);
OutputMaterialNodeParser(doc.get(), depsgraph, material, output_node).compute(socket_name);
}
else {
create_standard_surface(doc.get(), material);
OutputMaterialNodeParser(doc.get(), depsgraph, material, nullptr).compute_default();
}
CLOG_INFO(LOG_MATERIALX_SHADER,
2,
"Material: %s\n%s",

View File

@ -15,6 +15,8 @@ namespace blender::nodes::materialx {
extern struct CLG_LogRef *LOG_MATERIALX_SHADER;
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material);
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph,
Material *material,
const std::string &socket_name = "Surface");
} // namespace blender::nodes::materialx

View File

@ -79,6 +79,11 @@ void NodeItem::add_output(const std::string &name, const std::string &mx_type)
node->addOutput(name, mx_type);
}
void NodeItem::set_name(const std::string &name)
{
node->setName(MaterialX::createValidName(name));
}
NodeItem::operator bool() const
{
return value || node;

View File

@ -33,6 +33,7 @@ class NodeItem {
const MaterialX::NodePtr node,
const std::string &output_name = "");
void add_output(const std::string &name, const std::string &mx_type);
void set_name(const std::string &name);
operator bool() const;
NodeItem operator+(const NodeItem &other) const;

View File

@ -105,13 +105,12 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket)
from_node = link->fromnode;
}
/* Getting required NodeParser object */
/* Computing from_node with required NodeParser object */
#define CASE_NODE_TYPE(type, T) \
case type: \
parser = std::make_unique<T>(graph, depsgraph, material, from_node, link->fromsock); \
res = T(graph, depsgraph, material, from_node, link->fromsock).compute_full(); \
break;
std::unique_ptr<NodeParser> parser;
switch (from_node->typeinfo->type) {
CASE_NODE_TYPE(SH_NODE_BSDF_PRINCIPLED, BSDFPrincipledNodeParser)
CASE_NODE_TYPE(SH_NODE_INVERT, InvertNodeParser)
@ -130,7 +129,6 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket)
return res;
}
res = parser->compute_full();
return res;
}
@ -148,7 +146,9 @@ NodeItem NodeParser::compute_full()
CLOG_INFO(LOG_MATERIALX_SHADER, 1, "Node: %s [%d]", node->name, node->typeinfo->type);
NodeItem res = compute();
if (res.node) {
res.node->setName(MaterialX::createValidName(std::string(node->name) + "." + socket_out->name));
res.set_name(node->output_sockets().size() == 1 ?
std::string(node->name) :
std::string(node->name) + "_" + socket_out->name);
}
return res;
}

View File

@ -15,18 +15,34 @@ OutputMaterialNodeParser::OutputMaterialNodeParser(MaterialX::GraphElement *grap
NodeItem OutputMaterialNodeParser::compute()
{
NodeItem node = empty();
NodeItem surface = get_input_link("Surface");
if (surface) {
node = create_node("surfacematerial", "material");
node.set_input("surfaceshader", surface);
return empty();
}
return node;
NodeItem OutputMaterialNodeParser::compute(const std::string &socket_name)
{
NodeItem surface = empty();
if (node) {
surface = get_input_link(socket_name);
}
else {
surface = create_node("standard_surface", "surfaceshader");
surface.set_input("base_color", value(MaterialX::Color3(1.0f, 0.0f, 1.0f)));
}
NodeItem res = create_node("surfacematerial", "material");
res.set_name("Material");
res.set_input("surfaceshader", surface);
return res;
}
NodeItem OutputMaterialNodeParser::compute_default()
{
return empty();
NodeItem surface = create_node("standard_surface", "surfaceshader");
surface.set_input("base_color", value(MaterialX::Color3(material->r, material->g, material->b)));
NodeItem res = create_node("surfacematerial", "material");
res.set_name("Material");
res.set_input("surfaceshader", surface);
return res;
}
} // namespace blender::nodes::materialx

View File

@ -14,8 +14,8 @@ class OutputMaterialNodeParser : public NodeParser {
const Depsgraph *depsgraph,
const Material *material,
const bNode *node);
NodeItem compute() override;
NodeItem compute(const std::string &socket_name);
NodeItem compute_default();
};