USD: Rename active UV Map to "st" by default
This was previously attempted in #109518 and reverted in #112234. Now do both the changes in the mesh and material export, and make it an option in USD export. Hydra always renamed to "st" and continues to do it. Fix #122800: Missing textures with MaterialX materials Pull Request: https://projects.blender.org/blender/blender/pulls/123326
This commit is contained in:
committed by
Brecht Van Lommel
parent
dfd9f9066b
commit
eaeb8ba8cd
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -19,8 +19,6 @@ namespace blender::io::usd {
|
||||
|
||||
class USDHierarchyIterator;
|
||||
|
||||
using ExportImageFunction = std::function<std::string(Main *, Scene *, Image *, ImageUser *)>;
|
||||
|
||||
struct USDExporterContext {
|
||||
Main *bmain;
|
||||
Depsgraph *depsgraph;
|
||||
@@ -35,7 +33,7 @@ struct USDExporterContext {
|
||||
std::function<pxr::UsdTimeCode()> get_time_code;
|
||||
const USDExportParams &export_params;
|
||||
std::string export_file_path;
|
||||
ExportImageFunction export_image_fn;
|
||||
std::function<std::string(Main *, Scene *, Image *, ImageUser *)> export_image_fn;
|
||||
};
|
||||
|
||||
} // namespace blender::io::usd
|
||||
|
||||
@@ -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<NodeShaderUVMap *>(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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<float2> buffer = *mesh->attributes().lookup<float2>(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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,15 +16,17 @@ struct Main;
|
||||
struct Material;
|
||||
struct Scene;
|
||||
|
||||
class ExportImageFunction;
|
||||
|
||||
namespace blender::nodes::materialx {
|
||||
|
||||
using ExportImageFunction = std::function<std::string(Main *, Scene *, Image *, ImageUser *)>;
|
||||
struct ExportParams {
|
||||
std::function<std::string(Main *, Scene *, Image *, ImageUser *)> 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
|
||||
|
||||
@@ -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<bNode *>(from_node), link->fromsock);
|
||||
return data.result;
|
||||
}
|
||||
|
||||
@@ -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<class T> 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(); \
|
||||
}
|
||||
|
||||
|
||||
@@ -142,10 +142,10 @@ NODE_SHADER_MATERIALX_BEGIN
|
||||
NodeTexEnvironment *tex_env = static_cast<NodeTexEnvironment *>(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);
|
||||
|
||||
@@ -190,10 +190,10 @@ NODE_SHADER_MATERIALX_BEGIN
|
||||
NodeTexImage *tex_image = static_cast<NodeTexImage *>(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);
|
||||
|
||||
@@ -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<NodeShaderUVMap *>(node_->storage);
|
||||
NodeItem res = texcoord_node(NodeItem::Type::Vector2, attr->uv_map);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user