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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>>;
|
||||
|
||||
Reference in New Issue
Block a user