forked from blender/blender
Code improvements + Mix node #30
@ -36,6 +36,7 @@
|
||||
#include "intern/usd_exporter_context.h"
|
||||
#include "intern/usd_writer_material.h"
|
||||
#ifdef WITH_MATERIALX
|
||||
# include "shader/materialx/node_parser.h"
|
||||
# include "shader/materialx/material.h"
|
||||
#endif
|
||||
namespace blender::io::hydra {
|
||||
@ -79,7 +80,7 @@ void MaterialData::init()
|
||||
#ifdef WITH_MATERIALX
|
||||
if (scene_delegate_->use_materialx) {
|
||||
MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx(
|
||||
scene_delegate_->depsgraph, (Material *)id);
|
||||
scene_delegate_->depsgraph, (Material *)id, cache_or_get_image_file);
|
||||
pxr::UsdMtlxRead(doc, stage);
|
||||
|
||||
/* Logging stage: creating lambda stage_str() to not call stage->ExportToString()
|
||||
|
@ -22,13 +22,6 @@ set(INC
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
if(WITH_HYDRA)
|
||||
list(APPEND INC
|
||||
../../io/usd
|
||||
)
|
||||
add_definitions(-DWITH_HYDRA)
|
||||
endif()
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
|
@ -32,8 +32,14 @@ NodeItem GroupNodeParser::compute()
|
||||
#endif
|
||||
|
||||
NodeItem out =
|
||||
GroupOutputNodeParser(
|
||||
graph, depsgraph_, material_, node_out, socket_out_, NodeItem::Type::Any, this)
|
||||
GroupOutputNodeParser(graph,
|
||||
depsgraph_,
|
||||
material_,
|
||||
node_out,
|
||||
socket_out_,
|
||||
NodeItem::Type::Any,
|
||||
this,
|
||||
export_image_fn_)
|
||||
.compute_full();
|
||||
|
||||
#ifdef USE_MATERIALX_NODEGRAPH
|
||||
|
@ -54,7 +54,9 @@ class DefaultMaterialNodeParser : public NodeParser {
|
||||
}
|
||||
};
|
||||
|
||||
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material)
|
||||
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph,
|
||||
Material *material,
|
||||
ExportImageFunction export_image_fn)
|
||||
{
|
||||
CLOG_INFO(LOG_MATERIALX_SHADER, 0, "Material: %s", material->id.name);
|
||||
|
||||
@ -63,19 +65,36 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater
|
||||
material->nodetree->ensure_topology_cache();
|
||||
bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL);
|
||||
if (output_node) {
|
||||
NodeParserData data = {
|
||||
doc.get(), depsgraph, material, NodeItem::Type::Material, nullptr, NodeItem(doc.get())};
|
||||
NodeParserData data = {doc.get(),
|
||||
depsgraph,
|
||||
material,
|
||||
NodeItem::Type::Material,
|
||||
nullptr,
|
||||
NodeItem(doc.get()),
|
||||
export_image_fn};
|
||||
output_node->typeinfo->materialx_fn(&data, output_node, nullptr);
|
||||
}
|
||||
else {
|
||||
DefaultMaterialNodeParser(
|
||||
doc.get(), depsgraph, material, nullptr, nullptr, NodeItem::Type::Material, nullptr)
|
||||
DefaultMaterialNodeParser(doc.get(),
|
||||
depsgraph,
|
||||
material,
|
||||
nullptr,
|
||||
nullptr,
|
||||
NodeItem::Type::Material,
|
||||
nullptr,
|
||||
export_image_fn)
|
||||
.compute_error();
|
||||
}
|
||||
}
|
||||
else {
|
||||
DefaultMaterialNodeParser(
|
||||
doc.get(), depsgraph, material, nullptr, nullptr, NodeItem::Type::Material, nullptr)
|
||||
DefaultMaterialNodeParser(doc.get(),
|
||||
depsgraph,
|
||||
material,
|
||||
nullptr,
|
||||
nullptr,
|
||||
NodeItem::Type::Material,
|
||||
nullptr,
|
||||
export_image_fn)
|
||||
.compute();
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,12 @@
|
||||
struct Depsgraph;
|
||||
struct Material;
|
||||
|
||||
class ExportImageFunction;
|
||||
|
||||
namespace blender::nodes::materialx {
|
||||
|
||||
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material);
|
||||
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph,
|
||||
Material *material,
|
||||
ExportImageFunction export_image_fn);
|
||||
|
||||
} // namespace blender::nodes::materialx
|
||||
|
@ -20,14 +20,16 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph,
|
||||
const bNode *node,
|
||||
const bNodeSocket *socket_out,
|
||||
NodeItem::Type to_type,
|
||||
GroupNodeParser *group_parser)
|
||||
GroupNodeParser *group_parser,
|
||||
ExportImageFunction export_image_fn)
|
||||
: graph_(graph),
|
||||
depsgraph_(depsgraph),
|
||||
material_(material),
|
||||
node_(node),
|
||||
socket_out_(socket_out),
|
||||
to_type_(to_type),
|
||||
group_parser_(group_parser)
|
||||
group_parser_(group_parser),
|
||||
export_image_fn_(export_image_fn)
|
||||
{
|
||||
}
|
||||
|
||||
@ -212,13 +214,25 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to
|
||||
}
|
||||
|
||||
if (from_node->is_group()) {
|
||||
return GroupNodeParser(
|
||||
graph_, depsgraph_, material_, from_node, link->fromsock, to_type, group_parser_)
|
||||
return GroupNodeParser(graph_,
|
||||
depsgraph_,
|
||||
material_,
|
||||
from_node,
|
||||
link->fromsock,
|
||||
to_type,
|
||||
group_parser_,
|
||||
export_image_fn_)
|
||||
.compute_full();
|
||||
}
|
||||
if (from_node->is_group_input()) {
|
||||
return GroupInputNodeParser(
|
||||
graph_, depsgraph_, material_, from_node, link->fromsock, to_type, group_parser_)
|
||||
return GroupInputNodeParser(graph_,
|
||||
depsgraph_,
|
||||
material_,
|
||||
from_node,
|
||||
link->fromsock,
|
||||
to_type,
|
||||
group_parser_,
|
||||
export_image_fn_)
|
||||
.compute_full();
|
||||
}
|
||||
|
||||
@ -230,7 +244,8 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to
|
||||
return empty();
|
||||
}
|
||||
|
||||
NodeParserData data = {graph_, depsgraph_, material_, to_type, group_parser_, empty()};
|
||||
NodeParserData data = {
|
||||
graph_, depsgraph_, material_, to_type, group_parser_, empty(), export_image_fn_};
|
||||
from_node->typeinfo->materialx_fn(&data, const_cast<bNode *>(from_node), link->fromsock);
|
||||
return data.result;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ extern struct CLG_LogRef *LOG_MATERIALX_SHADER;
|
||||
|
||||
class GroupNodeParser;
|
||||
|
||||
using ExportImageFunction = std::function<std::string(Main *,Scene *, Image *, ImageUser *)>;
|
||||
|
||||
/**
|
||||
* This is base abstraction class for parsing Blender nodes into MaterialX nodes.
|
||||
* NodeParser::compute() should be overrided in child classes.
|
||||
@ -31,6 +33,7 @@ class NodeParser {
|
||||
const bNodeSocket *socket_out_;
|
||||
NodeItem::Type to_type_;
|
||||
GroupNodeParser *group_parser_;
|
||||
ExportImageFunction export_image_fn_;
|
||||
|
||||
public:
|
||||
NodeParser(MaterialX::GraphElement *graph,
|
||||
@ -39,7 +42,8 @@ class NodeParser {
|
||||
const bNode *node,
|
||||
const bNodeSocket *socket_out,
|
||||
NodeItem::Type to_type,
|
||||
GroupNodeParser *group_parser);
|
||||
GroupNodeParser *group_parser,
|
||||
ExportImageFunction export_image_fn);
|
||||
virtual ~NodeParser() = default;
|
||||
|
||||
virtual NodeItem compute() = 0;
|
||||
@ -99,6 +103,7 @@ struct NodeParserData {
|
||||
NodeItem::Type to_type;
|
||||
GroupNodeParser *group_parser;
|
||||
NodeItem result;
|
||||
ExportImageFunction export_image_fn;
|
||||
};
|
||||
|
||||
#define NODE_SHADER_MATERIALX_BEGIN \
|
||||
@ -119,7 +124,14 @@ struct NodeParserData {
|
||||
{ \
|
||||
materialx::NodeParserData *d = reinterpret_cast<materialx::NodeParserData *>(data); \
|
||||
d->result = MaterialXNodeParser( \
|
||||
d->graph, d->depsgraph, d->material, node, out, d->to_type, d->group_parser) \
|
||||
d->graph, \
|
||||
d->depsgraph, \
|
||||
d->material, \
|
||||
node, \
|
||||
out, \
|
||||
d->to_type, \
|
||||
d->group_parser, \
|
||||
d->export_image_fn) \
|
||||
.compute_full(); \
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,6 @@
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
|
||||
#include "hydra/image.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
namespace blender::nodes::node_shader_tex_environment_cc {
|
||||
@ -142,13 +140,13 @@ NODE_SHADER_MATERIALX_BEGIN
|
||||
}
|
||||
|
||||
NodeTexEnvironment *tex_env = static_cast<NodeTexEnvironment *>(node_->storage);
|
||||
Scene *scene = DEG_get_input_scene(depsgraph_);
|
||||
Main *bmain = DEG_get_bmain(depsgraph_);
|
||||
|
||||
/* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file contains
|
||||
* pretty general code, so could be moved from bf_usd project. */
|
||||
std::string image_path = io::hydra::cache_or_get_image_file(
|
||||
bmain, scene, image, &tex_env->iuser);
|
||||
std::string image_path = image->id.name;
|
||||
if (export_image_fn_) {
|
||||
Scene *scene = DEG_get_input_scene(depsgraph_);
|
||||
Main *bmain = DEG_get_bmain(depsgraph_);
|
||||
image_path = export_image_fn_(bmain, scene, image, &tex_env->iuser);
|
||||
}
|
||||
|
||||
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
|
||||
if (!vector) {
|
||||
|
@ -11,8 +11,6 @@
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
|
||||
#include "hydra/image.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
namespace blender::nodes::node_shader_tex_image_cc {
|
||||
@ -191,13 +189,13 @@ NODE_SHADER_MATERIALX_BEGIN
|
||||
Image *image = (Image *)node_->id;
|
||||
if (image) {
|
||||
NodeTexImage *tex_image = static_cast<NodeTexImage *>(node_->storage);
|
||||
Scene *scene = DEG_get_input_scene(depsgraph_);
|
||||
Main *bmain = DEG_get_bmain(depsgraph_);
|
||||
|
||||
/* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file
|
||||
* contains pretty general code, so could be moved from bf_usd project. */
|
||||
std::string image_path = io::hydra::cache_or_get_image_file(
|
||||
bmain, scene, image, &tex_image->iuser);
|
||||
std::string image_path = image->id.name;
|
||||
if (export_image_fn_) {
|
||||
Scene *scene = DEG_get_input_scene(depsgraph_);
|
||||
Main *bmain = DEG_get_bmain(depsgraph_);
|
||||
image_path = export_image_fn_(bmain, scene, image, &tex_image->iuser);
|
||||
}
|
||||
|
||||
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
|
||||
if (!vector) {
|
||||
|
Loading…
Reference in New Issue
Block a user