forked from blender/blender
MaterialX: make caching image in MaterialX independent from bf_usd
project
#31
@ -36,6 +36,7 @@
|
|||||||
#include "intern/usd_exporter_context.h"
|
#include "intern/usd_exporter_context.h"
|
||||||
#include "intern/usd_writer_material.h"
|
#include "intern/usd_writer_material.h"
|
||||||
#ifdef WITH_MATERIALX
|
#ifdef WITH_MATERIALX
|
||||||
|
# include "shader/materialx/node_parser.h"
|
||||||
# include "shader/materialx/material.h"
|
# include "shader/materialx/material.h"
|
||||||
#endif
|
#endif
|
||||||
namespace blender::io::hydra {
|
namespace blender::io::hydra {
|
||||||
@ -79,7 +80,7 @@ void MaterialData::init()
|
|||||||
#ifdef WITH_MATERIALX
|
#ifdef WITH_MATERIALX
|
||||||
if (scene_delegate_->use_materialx) {
|
if (scene_delegate_->use_materialx) {
|
||||||
MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_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);
|
pxr::UsdMtlxRead(doc, stage);
|
||||||
|
|
||||||
/* Logging stage: creating lambda stage_str() for not to call stage->ExportToString()
|
/* Logging stage: creating lambda stage_str() for not to call stage->ExportToString()
|
||||||
|
@ -32,8 +32,14 @@ NodeItem GroupNodeParser::compute()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
NodeItem out =
|
NodeItem out =
|
||||||
GroupOutputNodeParser(
|
GroupOutputNodeParser(graph,
|
||||||
graph, depsgraph_, material_, node_out, socket_out_, NodeItem::Type::Any, this)
|
depsgraph_,
|
||||||
|
material_,
|
||||||
|
node_out,
|
||||||
|
socket_out_,
|
||||||
|
NodeItem::Type::Any,
|
||||||
|
this,
|
||||||
|
export_image_fn_)
|
||||||
.compute_full();
|
.compute_full();
|
||||||
|
|
||||||
#ifdef USE_MATERIALX_NODEGRAPH
|
#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);
|
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();
|
material->nodetree->ensure_topology_cache();
|
||||||
bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL);
|
bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL);
|
||||||
if (output_node) {
|
if (output_node) {
|
||||||
NodeParserData data = {
|
NodeParserData data = {doc.get(),
|
||||||
doc.get(), depsgraph, material, NodeItem::Type::Material, nullptr, NodeItem(doc.get())};
|
depsgraph,
|
||||||
|
material,
|
||||||
|
NodeItem::Type::Material,
|
||||||
|
nullptr,
|
||||||
|
NodeItem(doc.get()),
|
||||||
|
export_image_fn};
|
||||||
output_node->typeinfo->materialx_fn(&data, output_node, nullptr);
|
output_node->typeinfo->materialx_fn(&data, output_node, nullptr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DefaultMaterialNodeParser(
|
DefaultMaterialNodeParser(doc.get(),
|
||||||
doc.get(), depsgraph, material, nullptr, nullptr, NodeItem::Type::Material, nullptr)
|
depsgraph,
|
||||||
|
material,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
NodeItem::Type::Material,
|
||||||
|
nullptr,
|
||||||
|
export_image_fn)
|
||||||
.compute_error();
|
.compute_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DefaultMaterialNodeParser(
|
DefaultMaterialNodeParser(doc.get(),
|
||||||
doc.get(), depsgraph, material, nullptr, nullptr, NodeItem::Type::Material, nullptr)
|
depsgraph,
|
||||||
|
material,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
NodeItem::Type::Material,
|
||||||
|
nullptr,
|
||||||
|
export_image_fn)
|
||||||
.compute();
|
.compute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,8 +9,12 @@
|
|||||||
struct Depsgraph;
|
struct Depsgraph;
|
||||||
struct Material;
|
struct Material;
|
||||||
|
|
||||||
|
class ExportImageFunction;
|
||||||
|
|
||||||
namespace blender::nodes::materialx {
|
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
|
} // namespace blender::nodes::materialx
|
||||||
|
@ -20,14 +20,16 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph,
|
|||||||
const bNode *node,
|
const bNode *node,
|
||||||
const bNodeSocket *socket_out,
|
const bNodeSocket *socket_out,
|
||||||
NodeItem::Type to_type,
|
NodeItem::Type to_type,
|
||||||
GroupNodeParser *group_parser)
|
GroupNodeParser *group_parser,
|
||||||
|
ExportImageFunction export_image_fn)
|
||||||
: graph_(graph),
|
: graph_(graph),
|
||||||
depsgraph_(depsgraph),
|
depsgraph_(depsgraph),
|
||||||
material_(material),
|
material_(material),
|
||||||
node_(node),
|
node_(node),
|
||||||
socket_out_(socket_out),
|
socket_out_(socket_out),
|
||||||
to_type_(to_type),
|
to_type_(to_type),
|
||||||
group_parser_(group_parser)
|
group_parser_(group_parser),
|
||||||
|
export_image_fn_(export_image_fn)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,13 +209,25 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (from_node->is_group()) {
|
if (from_node->is_group()) {
|
||||||
return GroupNodeParser(
|
return GroupNodeParser(graph_,
|
||||||
graph_, depsgraph_, material_, from_node, link->fromsock, to_type, group_parser_)
|
depsgraph_,
|
||||||
|
material_,
|
||||||
|
from_node,
|
||||||
|
link->fromsock,
|
||||||
|
to_type,
|
||||||
|
group_parser_,
|
||||||
|
export_image_fn_)
|
||||||
.compute_full();
|
.compute_full();
|
||||||
}
|
}
|
||||||
if (from_node->is_group_input()) {
|
if (from_node->is_group_input()) {
|
||||||
return GroupInputNodeParser(
|
return GroupInputNodeParser(graph_,
|
||||||
graph_, depsgraph_, material_, from_node, link->fromsock, to_type, group_parser_)
|
depsgraph_,
|
||||||
|
material_,
|
||||||
|
from_node,
|
||||||
|
link->fromsock,
|
||||||
|
to_type,
|
||||||
|
group_parser_,
|
||||||
|
export_image_fn_)
|
||||||
.compute_full();
|
.compute_full();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +239,8 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to
|
|||||||
return empty();
|
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);
|
from_node->typeinfo->materialx_fn(&data, const_cast<bNode *>(from_node), link->fromsock);
|
||||||
return data.result;
|
return data.result;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,10 @@ namespace blender::nodes::materialx {
|
|||||||
extern struct CLG_LogRef *LOG_MATERIALX_SHADER;
|
extern struct CLG_LogRef *LOG_MATERIALX_SHADER;
|
||||||
|
|
||||||
class GroupNodeParser;
|
class GroupNodeParser;
|
||||||
|
typedef std::string (*ExportImageFunction)(Main *bmain,
|
||||||
|
Scene *Scene,
|
||||||
|
Image *image,
|
||||||
|
ImageUser *iuser);
|
||||||
|
|
||||||
class NodeParser {
|
class NodeParser {
|
||||||
protected:
|
protected:
|
||||||
@ -27,6 +31,7 @@ class NodeParser {
|
|||||||
const bNodeSocket *socket_out_;
|
const bNodeSocket *socket_out_;
|
||||||
NodeItem::Type to_type_;
|
NodeItem::Type to_type_;
|
||||||
GroupNodeParser *group_parser_;
|
GroupNodeParser *group_parser_;
|
||||||
|
ExportImageFunction export_image_fn_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NodeParser(MaterialX::GraphElement *graph,
|
NodeParser(MaterialX::GraphElement *graph,
|
||||||
@ -35,7 +40,8 @@ class NodeParser {
|
|||||||
const bNode *node,
|
const bNode *node,
|
||||||
const bNodeSocket *socket_out,
|
const bNodeSocket *socket_out,
|
||||||
NodeItem::Type to_type,
|
NodeItem::Type to_type,
|
||||||
GroupNodeParser *group_parser);
|
GroupNodeParser *group_parser,
|
||||||
|
ExportImageFunction export_image_fn);
|
||||||
virtual ~NodeParser() = default;
|
virtual ~NodeParser() = default;
|
||||||
|
|
||||||
virtual NodeItem compute() = 0;
|
virtual NodeItem compute() = 0;
|
||||||
@ -82,6 +88,7 @@ struct NodeParserData {
|
|||||||
NodeItem::Type to_type;
|
NodeItem::Type to_type;
|
||||||
GroupNodeParser *group_parser;
|
GroupNodeParser *group_parser;
|
||||||
NodeItem result;
|
NodeItem result;
|
||||||
|
ExportImageFunction export_image_fn;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NODE_SHADER_MATERIALX_BEGIN \
|
#define NODE_SHADER_MATERIALX_BEGIN \
|
||||||
@ -102,7 +109,14 @@ struct NodeParserData {
|
|||||||
{ \
|
{ \
|
||||||
materialx::NodeParserData *d = reinterpret_cast<materialx::NodeParserData *>(data); \
|
materialx::NodeParserData *d = reinterpret_cast<materialx::NodeParserData *>(data); \
|
||||||
d->result = MaterialXNodeParser( \
|
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(); \
|
.compute_full(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,10 +145,9 @@ NODE_SHADER_MATERIALX_BEGIN
|
|||||||
Scene *scene = DEG_get_input_scene(depsgraph_);
|
Scene *scene = DEG_get_input_scene(depsgraph_);
|
||||||
Main *bmain = DEG_get_bmain(depsgraph_);
|
Main *bmain = DEG_get_bmain(depsgraph_);
|
||||||
|
|
||||||
/* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file contains
|
std::string image_path = export_image_fn_ ?
|
||||||
* pretty general code, so could be moved from bf_usd project. */
|
export_image_fn_(bmain, scene, image, &tex_env->iuser) :
|
||||||
std::string image_path = io::hydra::cache_or_get_image_file(
|
image->id.name;
|
||||||
bmain, scene, image, &tex_env->iuser);
|
|
||||||
|
|
||||||
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
|
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
|
||||||
if (!vector) {
|
if (!vector) {
|
||||||
|
@ -194,10 +194,9 @@ NODE_SHADER_MATERIALX_BEGIN
|
|||||||
Scene *scene = DEG_get_input_scene(depsgraph_);
|
Scene *scene = DEG_get_input_scene(depsgraph_);
|
||||||
Main *bmain = DEG_get_bmain(depsgraph_);
|
Main *bmain = DEG_get_bmain(depsgraph_);
|
||||||
|
|
||||||
/* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file
|
std::string image_path = export_image_fn_ ?
|
||||||
* contains pretty general code, so could be moved from bf_usd project. */
|
export_image_fn_(bmain, scene, image, &tex_image->iuser) :
|
||||||
std::string image_path = io::hydra::cache_or_get_image_file(
|
image->id.name;
|
||||||
bmain, scene, image, &tex_image->iuser);
|
|
||||||
|
|
||||||
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
|
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
|
||||||
if (!vector) {
|
if (!vector) {
|
||||||
|
Loading…
Reference in New Issue
Block a user