diff --git a/source/blender/editors/io/io_usd.cc b/source/blender/editors/io/io_usd.cc index 413e6bbdfb5..77dc20ecc20 100644 --- a/source/blender/editors/io/io_usd.cc +++ b/source/blender/editors/io/io_usd.cc @@ -216,6 +216,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op) const bool export_animation = RNA_boolean_get(op->ptr, "export_animation"); const bool export_hair = RNA_boolean_get(op->ptr, "export_hair"); const bool export_uvmaps = RNA_boolean_get(op->ptr, "export_uvmaps"); + const bool rename_uvmaps = RNA_boolean_get(op->ptr, "rename_uvmaps"); const bool export_mesh_colors = RNA_boolean_get(op->ptr, "export_mesh_colors"); const bool export_normals = RNA_boolean_get(op->ptr, "export_normals"); const bool export_materials = RNA_boolean_get(op->ptr, "export_materials"); @@ -276,6 +277,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op) export_animation, export_hair, export_uvmaps, + rename_uvmaps, export_normals, export_mesh_colors, export_materials, @@ -376,6 +378,7 @@ static void wm_usd_export_draw(bContext *C, wmOperator *op) { uiLayout *col = uiLayoutColumn(panel, false); uiItemR(col, ptr, "export_uvmaps", UI_ITEM_NONE, nullptr, ICON_NONE); + uiItemR(col, ptr, "rename_uvmaps", UI_ITEM_NONE, nullptr, ICON_NONE); uiItemR(col, ptr, "export_normals", UI_ITEM_NONE, nullptr, ICON_NONE); uiItemR(col, ptr, "triangulate_meshes", UI_ITEM_NONE, nullptr, ICON_NONE); @@ -540,6 +543,11 @@ void WM_OT_usd_export(wmOperatorType *ot) ot->srna, "export_hair", false, "Hair", "Export hair particle systems as USD curves"); RNA_def_boolean( ot->srna, "export_uvmaps", true, "UV Maps", "Include all mesh UV maps in the export"); + RNA_def_boolean(ot->srna, + "rename_uvmaps", + true, + "Rename UV Maps", + "Rename active render UV map to \"st\" to match USD conventions"); RNA_def_boolean(ot->srna, "export_mesh_colors", true, diff --git a/source/blender/io/usd/hydra/material.cc b/source/blender/io/usd/hydra/material.cc index e04b5bc2c53..2f331965df8 100644 --- a/source/blender/io/usd/hydra/material.cc +++ b/source/blender/io/usd/hydra/material.cc @@ -86,9 +86,11 @@ void MaterialData::init() pxr::UsdShadeMaterial usd_material; #ifdef WITH_MATERIALX if (scene_delegate_->use_materialx) { + blender::nodes::materialx::ExportParams materialx_export_params{ + cache_or_get_image_file, "st", "UVMap"}; std::string material_name = pxr::TfMakeValidIdentifier(id->name); MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx( - scene_delegate_->depsgraph, (Material *)id, material_name, cache_or_get_image_file); + scene_delegate_->depsgraph, (Material *)id, material_name, materialx_export_params); pxr::UsdMtlxRead(doc, stage); /* Logging stage: creating lambda stage_str() to not call stage->ExportToString() diff --git a/source/blender/io/usd/intern/usd_exporter_context.hh b/source/blender/io/usd/intern/usd_exporter_context.hh index 7fc4485d852..7f106d84bf1 100644 --- a/source/blender/io/usd/intern/usd_exporter_context.hh +++ b/source/blender/io/usd/intern/usd_exporter_context.hh @@ -19,8 +19,6 @@ namespace blender::io::usd { class USDHierarchyIterator; -using ExportImageFunction = std::function; - struct USDExporterContext { Main *bmain; Depsgraph *depsgraph; @@ -35,7 +33,7 @@ struct USDExporterContext { std::function get_time_code; const USDExportParams &export_params; std::string export_file_path; - ExportImageFunction export_image_fn; + std::function export_image_fn; }; } // namespace blender::io::usd diff --git a/source/blender/io/usd/intern/usd_writer_material.cc b/source/blender/io/usd/intern/usd_writer_material.cc index cf9f970ec77..dcc24b71b1d 100644 --- a/source/blender/io/usd/intern/usd_writer_material.cc +++ b/source/blender/io/usd/intern/usd_writer_material.cc @@ -95,11 +95,6 @@ static const pxr::TfToken translation("translation", pxr::TfToken::Immortal); static const pxr::TfToken rotation("rotation", pxr::TfToken::Immortal); } // namespace usdtokens -/* Cycles specific tokens. */ -namespace cyclestokens { -static const std::string UVMap("UVMap"); -} // namespace cyclestokens - namespace blender::io::usd { /* Preview surface input specification. */ @@ -127,7 +122,7 @@ static void create_uv_input(const USDExporterContext &usd_export_context, bNodeSocket *input_socket, pxr::UsdShadeMaterial &usd_material, pxr::UsdShadeInput &usd_input, - const std::string &default_uv, + const std::string &active_uvmap_name, ReportList *reports); static void export_texture(const USDExporterContext &usd_export_context, bNode *node); static bNode *find_bsdf_node(Material *material); @@ -156,16 +151,13 @@ void create_input(pxr::UsdShadeShader &shader, static void create_usd_preview_surface_material(const USDExporterContext &usd_export_context, Material *material, pxr::UsdShadeMaterial &usd_material, - const std::string &default_uv, + const std::string &active_uvmap_name, ReportList *reports) { if (!material) { return; } - /* Default map when creating UV primvar reader shaders. */ - std::string default_uv_sampler = default_uv.empty() ? cyclestokens::UVMap : default_uv; - /* We only handle the first instance of either principled or * diffuse bsdf nodes in the material's node tree, because * USD Preview Surface has no concept of layering materials. */ @@ -303,7 +295,7 @@ static void create_usd_preview_surface_material(const USDExporterContext &usd_ex pxr::SdfValueTypeNames->Float2)) { create_uv_input( - usd_export_context, socket, usd_material, st_input, default_uv_sampler, reports); + usd_export_context, socket, usd_material, st_input, active_uvmap_name, reports); } } @@ -460,7 +452,7 @@ static void create_uvmap_shader(const USDExporterContext &usd_export_context, bNodeLink *uvmap_link, pxr::UsdShadeMaterial &usd_material, pxr::UsdShadeInput &usd_input, - const std::string &default_uv, + const std::string &active_uvmap_name, ReportList *reports) { @@ -478,13 +470,16 @@ static void create_uvmap_shader(const USDExporterContext &usd_export_context, return; } - std::string uv_name = default_uv; + std::string uv_name = active_uvmap_name; if (uv_node && uv_node->storage) { NodeShaderUVMap *shader_uv_map = static_cast(uv_node->storage); - /* We need to make valid here because actual uv primvar has been. */ - uv_name = make_safe_name(shader_uv_map->uv_map, - usd_export_context.export_params.allow_unicode); + uv_name = shader_uv_map->uv_map; } + if (usd_export_context.export_params.rename_uvmaps && uv_name == active_uvmap_name) { + uv_name = usdtokens::st; + } + /* We need to make valid, same as was done when exporting UV primvar. */ + uv_name = make_safe_name(uv_name, usd_export_context.export_params.allow_unicode); uv_shader.CreateInput(usdtokens::varname, pxr::SdfValueTypeNames->String).Set(uv_name); usd_input.ConnectToSource(uv_shader.ConnectableAPI(), usdtokens::result); @@ -494,7 +489,7 @@ static void create_transform2d_shader(const USDExporterContext &usd_export_conte bNodeLink *mapping_link, pxr::UsdShadeMaterial &usd_material, pxr::UsdShadeInput &usd_input, - const std::string &default_uv, + const std::string &uvmap_name, ReportList *reports) { @@ -509,7 +504,7 @@ static void create_transform2d_shader(const USDExporterContext &usd_export_conte if (mapping_node->custom1 != TEXMAP_TYPE_POINT) { if (bNodeSocket *socket = bke::nodeFindSocket(mapping_node, SOCK_IN, "Vector")) { - create_uv_input(usd_export_context, socket, usd_material, usd_input, default_uv, reports); + create_uv_input(usd_export_context, socket, usd_material, usd_input, uvmap_name, reports); } return; } @@ -573,7 +568,7 @@ static void create_transform2d_shader(const USDExporterContext &usd_export_conte if (pxr::UsdShadeInput in_input = transform2d_shader.CreateInput( usdtokens::in, pxr::SdfValueTypeNames->Float2)) { - create_uv_input(usd_export_context, socket, usd_material, in_input, default_uv, reports); + create_uv_input(usd_export_context, socket, usd_material, in_input, uvmap_name, reports); } } } @@ -582,7 +577,7 @@ static void create_uv_input(const USDExporterContext &usd_export_context, bNodeSocket *input_socket, pxr::UsdShadeMaterial &usd_material, pxr::UsdShadeInput &usd_input, - const std::string &default_uv, + const std::string &active_uvmap_name, ReportList *reports) { if (!(usd_material && usd_input)) { @@ -590,8 +585,11 @@ static void create_uv_input(const USDExporterContext &usd_export_context, } if (bNodeLink *mapping_link = traverse_channel(input_socket, SH_NODE_MAPPING)) { + /* Use either "st" or active UV map name from mesh, depending if it was renamed. */ + std::string uvmap_name = (usd_export_context.export_params.rename_uvmaps) ? usdtokens::st : + active_uvmap_name; create_transform2d_shader( - usd_export_context, mapping_link, usd_material, usd_input, default_uv, reports); + usd_export_context, mapping_link, usd_material, usd_input, uvmap_name, reports); return; } @@ -599,7 +597,7 @@ static void create_uv_input(const USDExporterContext &usd_export_context, /* Note that uvmap_link might be null, but create_uv_shader() can handle this case. */ create_uvmap_shader( - usd_export_context, uvmap_link, usd_material, usd_input, default_uv, reports); + usd_export_context, uvmap_link, usd_material, usd_input, active_uvmap_name, reports); } /* Generate a file name for an in-memory image that doesn't have a @@ -1168,22 +1166,27 @@ static pxr::SdfPath reflow_materialx_paths(pxr::SdfPath input_path, static void create_usd_materialx_material(const USDExporterContext &usd_export_context, pxr::SdfPath usd_path, Material *material, + const std::string &active_uvmap_name, pxr::UsdShadeMaterial &usd_material) { + blender::nodes::materialx::ExportParams export_params = { + /* We want to re-use the same MaterialX document generation code as used by the renderer. + * While the graph is traversed, we also want it to export the textures out. */ + (usd_export_context.export_image_fn) ? usd_export_context.export_image_fn : + std::bind(materialx_export_image, + usd_export_context, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + std::placeholders::_4), + /* Active UV map name to use for default texture coordinates. */ + (usd_export_context.export_params.rename_uvmaps) ? "st" : active_uvmap_name, + active_uvmap_name, + }; - /* We want to re-use the same MaterialX document generation code as used by the renderer. - * While the graph is traversed, we also want it to export the textures out. */ - ExportImageFunction export_image_fn = (usd_export_context.export_image_fn) ? - usd_export_context.export_image_fn : - std::bind(materialx_export_image, - usd_export_context, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3, - std::placeholders::_4); std::string material_name = usd_path.GetElementString(); MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx( - usd_export_context.depsgraph, material, material_name, export_image_fn); + usd_export_context.depsgraph, material, material_name, export_params); /* We want to merge the MaterialX graph under the same Material as the USDPreviewSurface * This allows for the same material assignment to have two levels of complexity so other @@ -1352,7 +1355,7 @@ static void create_usd_materialx_material(const USDExporterContext &usd_export_c pxr::UsdShadeMaterial create_usd_material(const USDExporterContext &usd_export_context, pxr::SdfPath usd_path, Material *material, - const std::string &active_uv, + const std::string &active_uvmap_name, ReportList *reports) { pxr::UsdShadeMaterial usd_material = pxr::UsdShadeMaterial::Define(usd_export_context.stage, @@ -1360,7 +1363,7 @@ pxr::UsdShadeMaterial create_usd_material(const USDExporterContext &usd_export_c if (material->use_nodes && usd_export_context.export_params.generate_preview_surface) { create_usd_preview_surface_material( - usd_export_context, material, usd_material, active_uv, reports); + usd_export_context, material, usd_material, active_uvmap_name, reports); } else { create_usd_viewport_material(usd_export_context, material, usd_material); @@ -1368,7 +1371,8 @@ pxr::UsdShadeMaterial create_usd_material(const USDExporterContext &usd_export_c #ifdef WITH_MATERIALX if (material->use_nodes && usd_export_context.export_params.generate_materialx_network) { - create_usd_materialx_material(usd_export_context, usd_path, material, usd_material); + create_usd_materialx_material( + usd_export_context, usd_path, material, active_uvmap_name, usd_material); } #endif diff --git a/source/blender/io/usd/intern/usd_writer_material.hh b/source/blender/io/usd/intern/usd_writer_material.hh index 1a2e5bfe0bc..018311afeaa 100644 --- a/source/blender/io/usd/intern/usd_writer_material.hh +++ b/source/blender/io/usd/intern/usd_writer_material.hh @@ -24,7 +24,7 @@ struct USDExportParams; pxr::UsdShadeMaterial create_usd_material(const USDExporterContext &usd_export_context, pxr::SdfPath usd_path, Material *material, - const std::string &active_uv, + const std::string &active_uvmap_name, ReportList *reports); /* Returns a USDPreviewSurface token name for a given Blender shader Socket name, diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index 58e63956a5a..461e0aaf9e8 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -153,11 +153,11 @@ void USDGenericMeshWriter::write_custom_data(const Object *obj, { const bke::AttributeAccessor attributes = mesh->attributes(); - char *active_set_name = nullptr; + char *active_uvmap_name = nullptr; const int active_uv_set_index = CustomData_get_render_layer_index(&mesh->corner_data, CD_PROP_FLOAT2); if (active_uv_set_index != -1) { - active_set_name = mesh->corner_data.layers[active_uv_set_index].name; + active_uvmap_name = mesh->corner_data.layers[active_uv_set_index].name; } attributes.for_all( @@ -196,7 +196,7 @@ void USDGenericMeshWriter::write_custom_data(const Object *obj, /* UV Data. */ if (meta_data.domain == bke::AttrDomain::Corner && meta_data.data_type == CD_PROP_FLOAT2) { if (usd_export_context_.export_params.export_uvmaps) { - this->write_uv_data(mesh, usd_mesh, attribute_id, active_set_name); + this->write_uv_data(mesh, usd_mesh, attribute_id, active_uvmap_name); } } @@ -275,7 +275,7 @@ void USDGenericMeshWriter::write_generic_data(const Mesh *mesh, void USDGenericMeshWriter::write_uv_data(const Mesh *mesh, pxr::UsdGeomMesh usd_mesh, const bke::AttributeIDRef &attribute_id, - const char * /*active_set_name*/) + const char *active_uvmap_name) { const VArray buffer = *mesh->attributes().lookup(attribute_id, bke::AttrDomain::Corner); @@ -283,9 +283,18 @@ void USDGenericMeshWriter::write_uv_data(const Mesh *mesh, return; } + /* Optionally rename active UV map to "st", to follow USD conventions + * and better work with MaterialX shader nodes. */ + const blender::StringRef name = usd_export_context_.export_params.rename_uvmaps && + active_uvmap_name && + (blender::StringRef(active_uvmap_name) == + attribute_id.name()) ? + "st" : + attribute_id.name(); + const pxr::UsdTimeCode timecode = get_export_time_code(); const pxr::TfToken pv_name( - make_safe_name(attribute_id.name(), usd_export_context_.export_params.allow_unicode)); + make_safe_name(name, usd_export_context_.export_params.allow_unicode)); const pxr::UsdGeomPrimvarsAPI pv_api = pxr::UsdGeomPrimvarsAPI(usd_mesh); pxr::UsdGeomPrimvar pv_uv = pv_api.CreatePrimvar( diff --git a/source/blender/io/usd/usd.hh b/source/blender/io/usd/usd.hh index d64855fa3cc..d7b2fb7c3e2 100644 --- a/source/blender/io/usd/usd.hh +++ b/source/blender/io/usd/usd.hh @@ -99,6 +99,7 @@ struct USDExportParams { bool export_animation = false; bool export_hair = true; bool export_uvmaps = true; + bool rename_uvmaps = true; bool export_normals = true; bool export_mesh_colors = true; bool export_materials = true; diff --git a/source/blender/nodes/shader/materialx/group_nodes.cc b/source/blender/nodes/shader/materialx/group_nodes.cc index 297e328b50e..c67d3204f39 100644 --- a/source/blender/nodes/shader/materialx/group_nodes.cc +++ b/source/blender/nodes/shader/materialx/group_nodes.cc @@ -19,10 +19,10 @@ GroupNodeParser::GroupNodeParser(MaterialX::GraphElement *graph, const bNodeSocket *socket_out, NodeItem::Type to_type, GroupNodeParser *group_parser, - ExportImageFunction export_image_fn, + ExportParams export_params, bool use_group_default) : NodeParser( - graph, depsgraph, material, node, socket_out, to_type, group_parser, export_image_fn), + graph, depsgraph, material, node, socket_out, to_type, group_parser, export_params), use_group_default_(use_group_default) { } @@ -56,7 +56,7 @@ NodeItem GroupNodeParser::compute() socket_out_, to_type_, this, - export_image_fn_, + export_params_, use_group_default_) .compute_full(); diff --git a/source/blender/nodes/shader/materialx/group_nodes.h b/source/blender/nodes/shader/materialx/group_nodes.h index 1277436a94a..72c3776aef4 100644 --- a/source/blender/nodes/shader/materialx/group_nodes.h +++ b/source/blender/nodes/shader/materialx/group_nodes.h @@ -28,7 +28,7 @@ class GroupNodeParser : public NodeParser { const bNodeSocket *socket_out, NodeItem::Type to_type, GroupNodeParser *group_parser, - ExportImageFunction export_image_fn, + ExportParams export_params, bool use_group_default); NodeItem compute() override; NodeItem compute_full() override; diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index d9449278cdc..222c3ebb8b2 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -52,7 +52,7 @@ class DefaultMaterialNodeParser : public NodeParser { MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material, const std::string &material_name, - ExportImageFunction export_image_fn) + const ExportParams &export_params) { CLOG_INFO(LOG_MATERIALX_SHADER, 0, "Material: %s", material->id.name); @@ -69,7 +69,7 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, NodeItem::Type::Material, nullptr, NodeItem(doc.get()), - export_image_fn}; + export_params}; output_node->typeinfo->materialx_fn(&data, output_node, nullptr); output_item = data.result; } @@ -81,7 +81,7 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, nullptr, NodeItem::Type::Material, nullptr, - export_image_fn) + export_params) .compute_error(); } } @@ -93,7 +93,7 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, nullptr, NodeItem::Type::Material, nullptr, - export_image_fn) + export_params) .compute(); } diff --git a/source/blender/nodes/shader/materialx/material.h b/source/blender/nodes/shader/materialx/material.h index 4ee90246adb..c84f4cf1775 100644 --- a/source/blender/nodes/shader/materialx/material.h +++ b/source/blender/nodes/shader/materialx/material.h @@ -16,15 +16,17 @@ struct Main; struct Material; struct Scene; -class ExportImageFunction; - namespace blender::nodes::materialx { -using ExportImageFunction = std::function; +struct ExportParams { + std::function image_fn; + std::string new_active_uvmap_name; + std::string original_active_uvmap_name; +}; MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material, const std::string &material_name, - ExportImageFunction export_image_fn); + const ExportParams &export_params); } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/node_parser.cc b/source/blender/nodes/shader/materialx/node_parser.cc index 01961e5dd95..49ffb955ada 100644 --- a/source/blender/nodes/shader/materialx/node_parser.cc +++ b/source/blender/nodes/shader/materialx/node_parser.cc @@ -25,7 +25,7 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph, const bNodeSocket *socket_out, NodeItem::Type to_type, GroupNodeParser *group_parser, - ExportImageFunction export_image_fn) + const ExportParams &export_params) : graph_(graph), depsgraph_(depsgraph), material_(material), @@ -33,7 +33,7 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph, socket_out_(socket_out), to_type_(to_type), group_parser_(group_parser), - export_image_fn_(export_image_fn) + export_params_(export_params) { } @@ -170,7 +170,7 @@ NodeItem NodeParser::empty() const return NodeItem(graph_); } -NodeItem NodeParser::texcoord_node(NodeItem::Type type) +NodeItem NodeParser::texcoord_node(NodeItem::Type type, const std::string &attribute_name) { BLI_assert(ELEM(type, NodeItem::Type::Vector2, NodeItem::Type::Vector3)); std::string name = TEXCOORD_NODE_NAME; @@ -180,7 +180,18 @@ NodeItem NodeParser::texcoord_node(NodeItem::Type type) NodeItem res = empty(); res.node = graph_->getNode(name); if (!res.node) { - res = create_node("texcoord", type); + /* TODO: Use "Pref" generated texture coordinates for 3D, but needs + * work in USD and Hydra mesh export. */ + const bool is_active_uvmap = attribute_name == "" || + attribute_name == export_params_.original_active_uvmap_name; + if (export_params_.new_active_uvmap_name == "st" && is_active_uvmap) { + res = create_node("texcoord", type); + } + else { + const std::string &geomprop = (is_active_uvmap) ? export_params_.new_active_uvmap_name : + attribute_name; + res = create_node("geompropvalue", type, {{"geomprop", val(geomprop)}}); + } res.node->setName(name); } return res; @@ -249,7 +260,7 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, link->fromsock, to_type, group_parser_, - export_image_fn_, + export_params_, use_group_default) .compute_full(); } @@ -261,7 +272,7 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, link->fromsock, to_type, group_parser_, - export_image_fn_, + export_params_, use_group_default) .compute_full(); } @@ -275,7 +286,7 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, } NodeParserData data = { - graph_, depsgraph_, material_, to_type, group_parser_, empty(), export_image_fn_}; + graph_, depsgraph_, material_, to_type, group_parser_, empty(), export_params_}; from_node->typeinfo->materialx_fn(&data, const_cast(from_node), link->fromsock); return data.result; } diff --git a/source/blender/nodes/shader/materialx/node_parser.h b/source/blender/nodes/shader/materialx/node_parser.h index 893cc557355..45b775fdb65 100644 --- a/source/blender/nodes/shader/materialx/node_parser.h +++ b/source/blender/nodes/shader/materialx/node_parser.h @@ -32,7 +32,7 @@ class NodeParser { const bNodeSocket *socket_out_; NodeItem::Type to_type_; GroupNodeParser *group_parser_; - ExportImageFunction export_image_fn_; + ExportParams export_params_; public: NodeParser(MaterialX::GraphElement *graph, @@ -42,7 +42,7 @@ class NodeParser { const bNodeSocket *socket_out, NodeItem::Type to_type, GroupNodeParser *group_parser, - ExportImageFunction export_image_fn); + const ExportParams &export_params); virtual ~NodeParser() = default; virtual NodeItem compute() = 0; @@ -66,7 +66,8 @@ class NodeParser { NodeItem get_input_value(int index, NodeItem::Type to_type); NodeItem empty() const; template NodeItem val(const T &data) const; - NodeItem texcoord_node(NodeItem::Type type = NodeItem::Type::Vector2); + NodeItem texcoord_node(NodeItem::Type type = NodeItem::Type::Vector2, + const std::string &attribute_name = ""); private: NodeItem get_default(const bNodeSocket &socket, NodeItem::Type to_type); @@ -104,7 +105,7 @@ struct NodeParserData { NodeItem::Type to_type; GroupNodeParser *group_parser; NodeItem result; - ExportImageFunction export_image_fn; + ExportParams export_params; }; #define NODE_SHADER_MATERIALX_BEGIN \ @@ -131,7 +132,7 @@ struct NodeParserData { out, \ d->to_type, \ d->group_parser, \ - d->export_image_fn) \ + d->export_params) \ .compute_full(); \ } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc index b016e23c8d2..bd7073865f7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc @@ -142,10 +142,10 @@ NODE_SHADER_MATERIALX_BEGIN NodeTexEnvironment *tex_env = static_cast(node_->storage); std::string image_path = image->id.name; - if (export_image_fn_) { + if (export_params_.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); + image_path = export_params_.image_fn(bmain, scene, image, &tex_env->iuser); } NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc index 3eec26be7b9..77a659bdd74 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc @@ -190,10 +190,10 @@ NODE_SHADER_MATERIALX_BEGIN NodeTexImage *tex_image = static_cast(node_->storage); std::string image_path = image->id.name; - if (export_image_fn_) { + if (export_params_.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); + image_path = export_params_.image_fn(bmain, scene, image, &tex_image->iuser); } NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2); diff --git a/source/blender/nodes/shader/nodes/node_shader_uvmap.cc b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc index 47350608f35..67de8a8e7b9 100644 --- a/source/blender/nodes/shader/nodes/node_shader_uvmap.cc +++ b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc @@ -76,10 +76,9 @@ static int node_shader_gpu_uvmap(GPUMaterial *mat, NODE_SHADER_MATERIALX_BEGIN #ifdef WITH_MATERIALX { - /* NODE: "From Instances" not implemented - * UV selection not implemented - */ - NodeItem res = texcoord_node(); + /* NODE: "From Instances" not implemented */ + NodeShaderUVMap *attr = static_cast(node_->storage); + NodeItem res = texcoord_node(NodeItem::Type::Vector2, attr->uv_map); return res; } #endif