Blender V4.3
io/usd/hydra/material.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "material.hh"
6#include "usd_private.hh"
7
8#include <Python.h>
9#include <unicodeobject.h>
10
11#include <pxr/base/tf/stringUtils.h>
12#include <pxr/imaging/hd/material.h>
13#include <pxr/imaging/hd/renderDelegate.h>
14#include <pxr/imaging/hd/tokens.h>
15#include <pxr/usdImaging/usdImaging/materialParamUtils.h>
16
17#ifdef WITH_MATERIALX
18# include <pxr/usd/usdMtlx/reader.h>
19# include <pxr/usd/usdMtlx/utils.h>
20#endif
21
22#include "MEM_guardedalloc.h"
23
24#include "BKE_lib_id.hh"
25#include "BKE_material.h"
26
27#include "RNA_access.hh"
28#include "RNA_prototypes.hh"
29#include "RNA_types.hh"
30
32
33#include "bpy_rna.hh"
34
36#include "image.hh"
37
40
41#ifdef WITH_MATERIALX
43
45#endif
46
47using namespace blender::io::usd;
48
49namespace blender::io::hydra {
50
52 const Material *material,
53 pxr::SdfPath const &prim_id)
54 : IdData(scene_delegate, &material->id, prim_id)
55{
56}
57
59{
60 ID_LOGN(1, "");
61 double_sided = (((Material *)id)->blend_flag & MA_BL_CULL_BACKFACE) == 0;
62 material_network_map_ = pxr::VtValue();
63
64 /* Create temporary in memory stage. */
65 pxr::UsdStageRefPtr stage = pxr::UsdStage::CreateInMemory();
66 pxr::UsdTimeCode time = pxr::UsdTimeCode::Default();
67 auto get_time_code = [time]() { return time; };
68 pxr::SdfPath material_library_path("/_materials");
69 pxr::SdfPath material_path = material_library_path.AppendChild(
70 pxr::TfToken(prim_id.GetElementString()));
71
72 /* Create USD export content to reuse USD file export code. */
73 USDExportParams export_params;
74 export_params.relative_paths = false;
75 export_params.export_textures = false; /* Don't copy all textures, is slow. */
77
80 stage,
81 material_library_path,
82 get_time_code,
83 export_params,
86 /* Create USD material. */
87 pxr::UsdShadeMaterial usd_material;
88#ifdef WITH_MATERIALX
90 blender::nodes::materialx::ExportParams materialx_export_params{
91 cache_or_get_image_file, "st", "UVMap"};
92 std::string material_name = pxr::TfMakeValidIdentifier(id->name);
93 MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx(
94 scene_delegate_->depsgraph, (Material *)id, material_name, materialx_export_params);
95 pxr::UsdMtlxRead(doc, stage);
96
97 /* Logging stage: creating lambda stage_str() to not call stage->ExportToString()
98 * if log won't be printed. */
99 auto stage_str = [&stage]() {
100 std::string str;
101 stage->ExportToString(&str);
102 return str;
103 };
104 ID_LOGN(2, "Stage:\n%s", stage_str().c_str());
105
106 if (pxr::UsdPrim materials = stage->GetPrimAtPath(pxr::SdfPath("/MaterialX/Materials"))) {
107 pxr::UsdPrimSiblingRange children = materials.GetChildren();
108 if (!children.empty()) {
109 usd_material = pxr::UsdShadeMaterial(*children.begin());
110 }
111 }
112 }
113 else
114#endif
115 {
116 usd_material = usd::create_usd_material(
117 export_context, material_path, (Material *)id, "st", nullptr);
118 }
119
120 /* Convert USD material to Hydra material network map, adapted for render delegate. */
121 const pxr::HdRenderDelegate *render_delegate =
122 scene_delegate_->GetRenderIndex().GetRenderDelegate();
123 const pxr::TfTokenVector contextVector = render_delegate->GetMaterialRenderContexts();
124 pxr::TfTokenVector shaderSourceTypes = render_delegate->GetShaderSourceTypes();
125
126 pxr::HdMaterialNetworkMap network_map;
127
128 if (pxr::UsdShadeShader surface = usd_material.ComputeSurfaceSource(contextVector)) {
129 pxr::UsdImagingBuildHdMaterialNetworkFromTerminal(surface.GetPrim(),
130 pxr::HdMaterialTerminalTokens->surface,
131 shaderSourceTypes,
132 contextVector,
133 &network_map,
134 time);
135 }
136
137 material_network_map_ = pxr::VtValue(network_map);
138}
139
141{
142 ID_LOGN(1, "");
143 scene_delegate_->GetRenderIndex().InsertSprim(
144 pxr::HdPrimTypeTokens->material, scene_delegate_, prim_id);
145}
146
148{
149 ID_LOG(1, "");
150 scene_delegate_->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->material, prim_id);
151}
152
154{
155 ID_LOGN(1, "");
156 bool prev_double_sided = double_sided;
157 init();
158 scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id,
159 pxr::HdMaterial::AllDirty);
160 if (prev_double_sided != double_sided) {
161 for (auto &obj_data : scene_delegate_->objects_.values()) {
162 MeshData *m_data = dynamic_cast<MeshData *>(obj_data.get());
163 if (m_data) {
164 m_data->update_double_sided(this);
165 }
166 }
167 scene_delegate_->instancer_data_->update_double_sided(this);
168 }
169}
170
171pxr::VtValue MaterialData::get_data(pxr::TfToken const & /*key*/) const
172{
173 return pxr::VtValue();
174}
175
177{
178 return material_network_map_;
179}
180
181pxr::HdCullStyle MaterialData::cull_style() const
182{
183 return double_sided ? pxr::HdCullStyle::HdCullStyleNothing : pxr::HdCullStyle::HdCullStyleBack;
184}
185
186} // namespace blender::io::hydra
General operations, lookup, etc. for materials.
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
@ MA_BL_CULL_BACKFACE
Read Guarded memory(de)allocation.
btAlignedObjectArray< btScalar > m_data
ValueIterator values() const
Definition BLI_map.hh:846
pxr::SdfPath prim_id
Definition id.hh:36
HydraSceneDelegate * scene_delegate_
Definition id.hh:39
MaterialData(HydraSceneDelegate *scene_delegate, const Material *material, pxr::SdfPath const &prim_id)
pxr::VtValue get_data(pxr::TfToken const &key) const override
double time
EvaluationStage stage
Definition deg_eval.cc:83
#define str(s)
#define ID_LOG(level, msg,...)
Definition id.hh:53
#define ID_LOGN(level, msg,...)
Definition id.hh:56
std::string cache_or_get_image_file(Main *bmain, Scene *scene, Image *image, ImageUser *iuser)
std::string image_cache_file_path()
pxr::UsdShadeMaterial create_usd_material(const USDExporterContext &usd_export_context, pxr::SdfPath usd_path, Material *material, const std::string &active_uvmap_name, ReportList *reports)
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material, const std::string &material_name, const ExportParams &export_params)
enum eEvaluationMode evaluation_mode
Definition usd.hh:146