Hydra: export USD preview surface for materials

Sharing code with USD export, as a step towards making Hydra and USD more
consistent. Upcoming USD hooks will provide more control over material
export rather than always using preview surface.

Ref #110765

Pull Request: https://projects.blender.org/blender/blender/pulls/110836
This commit is contained in:
Brecht Van Lommel
2023-08-05 14:49:10 +02:00
parent 8ff98504ea
commit 03530d3d48
4 changed files with 71 additions and 7 deletions

View File

@@ -21,16 +21,22 @@
namespace blender::io::hydra {
static std::string get_cache_file(const std::string &file_name, bool mkdir = true)
std::string image_cache_file_path()
{
char dir_path[FILE_MAX];
BLI_path_join(dir_path, sizeof(dir_path), BKE_tempdir_session(), "hydra", "image_cache");
return dir_path;
}
static std::string get_cache_file(const std::string &file_name, bool mkdir = true)
{
std::string dir_path = image_cache_file_path();
if (mkdir) {
BLI_dir_create_recursive(dir_path);
BLI_dir_create_recursive(dir_path.c_str());
}
char file_path[FILE_MAX];
BLI_path_join(file_path, sizeof(file_path), dir_path, file_name.c_str());
BLI_path_join(file_path, sizeof(file_path), dir_path.c_str(), file_name.c_str());
return file_path;
}

View File

@@ -13,6 +13,8 @@ struct ImageUser;
namespace blender::io::hydra {
std::string image_cache_file_path();
std::string cache_or_get_image_file(Main *bmain, Scene *Scene, Image *image, ImageUser *iuser);
std::string cache_image_color(float color[4]);

View File

@@ -10,6 +10,7 @@
#include <pxr/imaging/hd/material.h>
#include <pxr/imaging/hd/renderDelegate.h>
#include <pxr/imaging/hd/tokens.h>
#include <pxr/usdImaging/usdImaging/materialParamUtils.h>
#include "MEM_guardedalloc.h"
@@ -20,16 +21,22 @@
#include "RNA_prototypes.h"
#include "RNA_types.h"
#include "DEG_depsgraph_query.h"
#include "bpy_rna.h"
#include "hydra_scene_delegate.h"
#include "image.h"
#include "intern/usd_exporter_context.h"
#include "intern/usd_writer_material.h"
namespace blender::io::hydra {
MaterialData::MaterialData(HydraSceneDelegate *scene_delegate,
const Material *material,
pxr::SdfPath const &prim_id)
: IdData(scene_delegate, (const ID *)material, prim_id)
: IdData(scene_delegate, &material->id, prim_id)
{
}
@@ -37,6 +44,51 @@ void MaterialData::init()
{
ID_LOGN(1, "");
double_sided = (((Material *)id)->blend_flag & MA_BL_CULL_BACKFACE) == 0;
material_network_map_ = pxr::VtValue();
/* Create temporary in memory stage. */
pxr::UsdStageRefPtr stage = pxr::UsdStage::CreateInMemory();
pxr::UsdTimeCode time = pxr::UsdTimeCode::Default();
pxr::SdfPath material_library_path("/_materials");
pxr::SdfPath material_path = material_library_path.AppendChild(
pxr::TfToken(prim_id.GetElementString()));
/* Create USD export content to reuse USD file export code. */
USDExportParams export_params;
export_params.relative_paths = false;
export_params.export_textures = false; /* Don't copy all textures, is slow. */
export_params.evaluation_mode = DEG_get_mode(scene_delegate_->depsgraph);
usd::USDExporterContext export_context{scene_delegate_->bmain,
scene_delegate_->depsgraph,
stage,
material_library_path,
time,
export_params,
image_cache_file_path()};
/* Create USD material. */
pxr::UsdShadeMaterial usd_material = usd::create_usd_material(
export_context, material_path, (Material *)id, "st");
/* Convert USD material to Hydra material network map, adapted for render delegate. */
const pxr::HdRenderDelegate *render_delegate =
scene_delegate_->GetRenderIndex().GetRenderDelegate();
const pxr::TfTokenVector contextVector = render_delegate->GetMaterialRenderContexts();
pxr::TfTokenVector shaderSourceTypes = render_delegate->GetShaderSourceTypes();
pxr::HdMaterialNetworkMap network_map;
if (pxr::UsdShadeShader surface = usd_material.ComputeSurfaceSource(contextVector)) {
pxr::UsdImagingBuildHdMaterialNetworkFromTerminal(surface.GetPrim(),
pxr::HdMaterialTerminalTokens->surface,
shaderSourceTypes,
contextVector,
&network_map,
time);
}
material_network_map_ = pxr::VtValue(network_map);
}
void MaterialData::insert()
@@ -77,7 +129,7 @@ pxr::VtValue MaterialData::get_data(pxr::TfToken const & /* key */) const
pxr::VtValue MaterialData::get_material_resource() const
{
return pxr::VtValue();
return material_network_map_;
}
pxr::HdCullStyle MaterialData::cull_style() const

View File

@@ -17,6 +17,12 @@
namespace blender::io::hydra {
class MaterialData : public IdData {
public:
bool double_sided = true;
private:
pxr::VtValue material_network_map_;
public:
MaterialData(HydraSceneDelegate *scene_delegate,
const Material *material,
@@ -30,8 +36,6 @@ class MaterialData : public IdData {
pxr::VtValue get_data(pxr::TfToken const &key) const override;
pxr::VtValue get_material_resource() const;
pxr::HdCullStyle cull_style() const;
bool double_sided = true;
};
using MaterialDataMap = Map<pxr::SdfPath, std::unique_ptr<MaterialData>>;