forked from blender/blender
Add scene setting to export through either Hydra or USD, for debugging #65
@ -950,6 +950,25 @@ class RENDER_PT_simplify_greasepencil(RenderButtonsPanel, Panel, GreasePencilSim
|
|||||||
bl_options = {'DEFAULT_CLOSED'}
|
bl_options = {'DEFAULT_CLOSED'}
|
||||||
|
|
||||||
|
|
||||||
|
class RENDER_PT_hydra_debug(RenderButtonsPanel, Panel):
|
||||||
|
bl_label = "Hydra Debug"
|
||||||
|
bl_options = {'DEFAULT_CLOSED'}
|
||||||
|
bl_order = 200
|
||||||
|
COMPAT_ENGINES = {'HYDRA_STORM'}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
prefs = context.preferences
|
||||||
|
return (context.engine in cls.COMPAT_ENGINES) and prefs.view.show_developer_ui
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.use_property_split = True
|
||||||
|
|
||||||
|
hydra = context.scene.hydra
|
||||||
|
layout.prop(hydra, "export_method")
|
||||||
|
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
RENDER_PT_context,
|
RENDER_PT_context,
|
||||||
RENDER_PT_eevee_sampling,
|
RENDER_PT_eevee_sampling,
|
||||||
@ -985,6 +1004,7 @@ classes = (
|
|||||||
RENDER_PT_opengl_color,
|
RENDER_PT_opengl_color,
|
||||||
RENDER_PT_opengl_options,
|
RENDER_PT_opengl_options,
|
||||||
RENDER_PT_opengl_film,
|
RENDER_PT_opengl_film,
|
||||||
|
RENDER_PT_hydra_debug,
|
||||||
RENDER_PT_color_management,
|
RENDER_PT_color_management,
|
||||||
RENDER_PT_color_management_curves,
|
RENDER_PT_color_management_curves,
|
||||||
RENDER_PT_simplify,
|
RENDER_PT_simplify,
|
||||||
|
@ -93,6 +93,7 @@ set(SRC
|
|||||||
intern/usd_reader_volume.cc
|
intern/usd_reader_volume.cc
|
||||||
intern/usd_reader_xform.cc
|
intern/usd_reader_xform.cc
|
||||||
|
|
||||||
|
usd.hh
|
||||||
usd.h
|
usd.h
|
||||||
|
|
||||||
intern/usd_asset_utils.h
|
intern/usd_asset_utils.h
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
#include "usd.h"
|
#include "usd.h"
|
||||||
|
#include "usd.hh"
|
||||||
#include "usd_hierarchy_iterator.h"
|
#include "usd_hierarchy_iterator.h"
|
||||||
|
|
||||||
#include <pxr/base/plug/registry.h>
|
#include <pxr/base/plug/registry.h>
|
||||||
@ -198,67 +199,41 @@ static bool perform_usdz_conversion(const ExportJobData *data)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void export_startjob(void *customdata,
|
static pxr::UsdStageRefPtr export_to_stage(const USDExportParams ¶ms,
|
||||||
/* Cannot be const, this function implements wm_jobs_start_callback.
|
Depsgraph *depsgraph,
|
||||||
* NOLINTNEXTLINE: readability-non-const-parameter. */
|
const char *filepath,
|
||||||
bool *stop,
|
bool *stop,
|
||||||
bool *do_update,
|
bool *do_update,
|
||||||
float *progress)
|
float *progress)
|
||||||
{
|
{
|
||||||
ExportJobData *data = static_cast<ExportJobData *>(customdata);
|
pxr::UsdStageRefPtr usd_stage = pxr::UsdStage::CreateNew(filepath);
|
||||||
data->export_ok = false;
|
|
||||||
data->start_time = timeit::Clock::now();
|
|
||||||
|
|
||||||
G.is_rendering = true;
|
|
||||||
if (data->wm) {
|
|
||||||
WM_set_locked_interface(data->wm, true);
|
|
||||||
}
|
|
||||||
G.is_break = false;
|
|
||||||
|
|
||||||
/* Construct the depsgraph for exporting. */
|
|
||||||
Scene *scene = DEG_get_input_scene(data->depsgraph);
|
|
||||||
if (data->params.visible_objects_only) {
|
|
||||||
DEG_graph_build_from_view_layer(data->depsgraph);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DEG_graph_build_for_all_objects(data->depsgraph);
|
|
||||||
}
|
|
||||||
BKE_scene_graph_update_tagged(data->depsgraph, data->bmain);
|
|
||||||
|
|
||||||
*progress = 0.0f;
|
|
||||||
*do_update = true;
|
|
||||||
|
|
||||||
/* For restoring the current frame after exporting animation is done. */
|
|
||||||
const int orig_frame = scene->r.cfra;
|
|
||||||
|
|
||||||
pxr::UsdStageRefPtr usd_stage = pxr::UsdStage::CreateNew(data->unarchived_filepath);
|
|
||||||
if (!usd_stage) {
|
if (!usd_stage) {
|
||||||
/* This happens when the USD JSON files cannot be found. When that happens,
|
return usd_stage;
|
||||||
* the USD library doesn't know it has the functionality to write USDA and
|
|
||||||
* USDC files, and creating a new UsdStage fails. */
|
|
||||||
WM_reportf(RPT_ERROR,
|
|
||||||
"USD Export: unable to find suitable USD plugin to write %s",
|
|
||||||
data->unarchived_filepath);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usd_stage->SetMetadata(pxr::UsdGeomTokens->upAxis, pxr::VtValue(pxr::UsdGeomTokens->z));
|
Scene *scene = DEG_get_input_scene(depsgraph);
|
||||||
|
Main *bmain = DEG_get_bmain(depsgraph);
|
||||||
|
|
||||||
usd_stage->SetMetadata(pxr::UsdGeomTokens->metersPerUnit, double(scene->unit.scale_length));
|
usd_stage->SetMetadata(pxr::UsdGeomTokens->metersPerUnit, double(scene->unit.scale_length));
|
||||||
usd_stage->GetRootLayer()->SetDocumentation(std::string("Blender v") +
|
usd_stage->GetRootLayer()->SetDocumentation(std::string("Blender v") +
|
||||||
BKE_blender_version_string());
|
BKE_blender_version_string());
|
||||||
|
|
||||||
/* Set up the stage for animated data. */
|
/* Set up the stage for animated data. */
|
||||||
if (data->params.export_animation) {
|
if (params.export_animation) {
|
||||||
usd_stage->SetTimeCodesPerSecond(FPS);
|
usd_stage->SetTimeCodesPerSecond(FPS);
|
||||||
usd_stage->SetStartTimeCode(scene->r.sfra);
|
usd_stage->SetStartTimeCode(scene->r.sfra);
|
||||||
usd_stage->SetEndTimeCode(scene->r.efra);
|
usd_stage->SetEndTimeCode(scene->r.efra);
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_root_prim(usd_stage, data->params);
|
/* For restoring the current frame after exporting animation is done. */
|
||||||
|
const int orig_frame = scene->r.cfra;
|
||||||
|
|
||||||
USDHierarchyIterator iter(data->bmain, data->depsgraph, usd_stage, data->params);
|
usd_stage->SetMetadata(pxr::UsdGeomTokens->upAxis, pxr::VtValue(pxr::UsdGeomTokens->z));
|
||||||
|
ensure_root_prim(usd_stage, params);
|
||||||
|
|
||||||
if (data->params.export_animation) {
|
USDHierarchyIterator iter(bmain, depsgraph, usd_stage, params);
|
||||||
|
|
||||||
|
if (params.export_animation) {
|
||||||
/* Writing the animated frames is not 100% of the work, but it's our best guess. */
|
/* Writing the animated frames is not 100% of the work, but it's our best guess. */
|
||||||
float progress_per_frame = 1.0f / std::max(1, (scene->r.efra - scene->r.sfra + 1));
|
float progress_per_frame = 1.0f / std::max(1, (scene->r.efra - scene->r.sfra + 1));
|
||||||
|
|
||||||
@ -270,15 +245,19 @@ static void export_startjob(void *customdata,
|
|||||||
/* Update the scene for the next frame to render. */
|
/* Update the scene for the next frame to render. */
|
||||||
scene->r.cfra = int(frame);
|
scene->r.cfra = int(frame);
|
||||||
scene->r.subframe = frame - scene->r.cfra;
|
scene->r.subframe = frame - scene->r.cfra;
|
||||||
BKE_scene_graph_update_for_newframe(data->depsgraph);
|
BKE_scene_graph_update_for_newframe(depsgraph);
|
||||||
|
|
||||||
iter.set_export_frame(frame);
|
iter.set_export_frame(frame);
|
||||||
iter.iterate_and_write();
|
iter.iterate_and_write();
|
||||||
|
|
||||||
|
if (progress) {
|
||||||
*progress += progress_per_frame;
|
*progress += progress_per_frame;
|
||||||
|
}
|
||||||
|
if (do_update) {
|
||||||
*do_update = true;
|
*do_update = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
/* If we're not animating, a single iteration over all objects is enough. */
|
/* If we're not animating, a single iteration over all objects is enough. */
|
||||||
iter.iterate_and_write();
|
iter.iterate_and_write();
|
||||||
@ -296,14 +275,65 @@ static void export_startjob(void *customdata,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
usd_stage->GetRootLayer()->Save();
|
|
||||||
|
|
||||||
/* Finish up by going back to the keyframe that was current before we started. */
|
/* Finish up by going back to the keyframe that was current before we started. */
|
||||||
if (scene->r.cfra != orig_frame) {
|
if (scene->r.cfra != orig_frame) {
|
||||||
scene->r.cfra = orig_frame;
|
scene->r.cfra = orig_frame;
|
||||||
BKE_scene_graph_update_for_newframe(data->depsgraph);
|
BKE_scene_graph_update_for_newframe(depsgraph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return usd_stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxr::UsdStageRefPtr export_to_stage(const USDExportParams ¶ms,
|
||||||
|
Depsgraph *depsgraph,
|
||||||
|
const char *filepath)
|
||||||
|
{
|
||||||
|
return export_to_stage(params, depsgraph, filepath, nullptr, nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void export_startjob(void *customdata,
|
||||||
|
/* Cannot be const, this function implements wm_jobs_start_callback.
|
||||||
|
* NOLINTNEXTLINE: readability-non-const-parameter. */
|
||||||
|
bool *stop,
|
||||||
|
bool *do_update,
|
||||||
|
float *progress)
|
||||||
|
{
|
||||||
|
ExportJobData *data = static_cast<ExportJobData *>(customdata);
|
||||||
|
data->export_ok = false;
|
||||||
|
data->start_time = timeit::Clock::now();
|
||||||
|
|
||||||
|
G.is_rendering = true;
|
||||||
|
if (data->wm) {
|
||||||
|
WM_set_locked_interface(data->wm, true);
|
||||||
|
}
|
||||||
|
G.is_break = false;
|
||||||
|
|
||||||
|
/* Construct the depsgraph for exporting. */
|
||||||
|
if (data->params.visible_objects_only) {
|
||||||
|
DEG_graph_build_from_view_layer(data->depsgraph);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEG_graph_build_for_all_objects(data->depsgraph);
|
||||||
|
}
|
||||||
|
BKE_scene_graph_update_tagged(data->depsgraph, data->bmain);
|
||||||
|
|
||||||
|
*progress = 0.0f;
|
||||||
|
*do_update = true;
|
||||||
|
|
||||||
|
pxr::UsdStageRefPtr usd_stage = export_to_stage(
|
||||||
|
data->params, data->depsgraph, data->unarchived_filepath, stop, do_update, progress);
|
||||||
|
if (!usd_stage) {
|
||||||
|
/* This happens when the USD JSON files cannot be found. When that happens,
|
||||||
|
* the USD library doesn't know it has the functionality to write USDA and
|
||||||
|
* USDC files, and creating a new UsdStage fails. */
|
||||||
|
WM_reportf(RPT_ERROR,
|
||||||
|
"USD Export: unable to find suitable USD plugin to write %s",
|
||||||
|
data->unarchived_filepath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
usd_stage->GetRootLayer()->Save();
|
||||||
|
|
||||||
if (data->targets_usdz()) {
|
if (data->targets_usdz()) {
|
||||||
bool usd_conversion_success = perform_usdz_conversion(data);
|
bool usd_conversion_success = perform_usdz_conversion(data);
|
||||||
if (!usd_conversion_success) {
|
if (!usd_conversion_success) {
|
||||||
|
18
source/blender/io/usd/usd.hh
Normal file
18
source/blender/io/usd/usd.hh
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pxr/usd/usd/stage.h>
|
||||||
|
|
||||||
|
struct Depsgraph;
|
||||||
|
struct USDExportParams;
|
||||||
|
|
||||||
|
namespace blender::io::usd {
|
||||||
|
|
||||||
|
pxr::UsdStageRefPtr export_to_stage(const USDExportParams ¶ms,
|
||||||
|
Depsgraph *depsgraph,
|
||||||
|
const char *filepath);
|
||||||
|
|
||||||
|
};
|
@ -227,6 +227,11 @@
|
|||||||
SCE_EEVEE_SSR_HALF_RESOLUTION | SCE_EEVEE_SHADOW_SOFT, \
|
SCE_EEVEE_SSR_HALF_RESOLUTION | SCE_EEVEE_SHADOW_SOFT, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define _DNA_DEFAULT_SceneHydra \
|
||||||
|
{ \
|
||||||
|
.export_method = SCE_HYDRA_EXPORT_HYDRA, \
|
||||||
|
}
|
||||||
|
|
||||||
#define _DNA_DEFAULT_Scene \
|
#define _DNA_DEFAULT_Scene \
|
||||||
{ \
|
{ \
|
||||||
.cursor = _DNA_DEFAULT_View3DCursor, \
|
.cursor = _DNA_DEFAULT_View3DCursor, \
|
||||||
@ -240,6 +245,8 @@
|
|||||||
.safe_areas = _DNA_DEFAULT_DisplaySafeAreas, \
|
.safe_areas = _DNA_DEFAULT_DisplaySafeAreas, \
|
||||||
\
|
\
|
||||||
.eevee = _DNA_DEFAULT_SceneEEVEE, \
|
.eevee = _DNA_DEFAULT_SceneEEVEE, \
|
||||||
|
\
|
||||||
|
.hydra = _DNA_DEFAULT_SceneHydra, \
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
@ -1883,6 +1883,11 @@ typedef struct SceneGpencil {
|
|||||||
char _pad[4];
|
char _pad[4];
|
||||||
} SceneGpencil;
|
} SceneGpencil;
|
||||||
|
|
||||||
|
typedef struct SceneHydra {
|
||||||
|
int export_method;
|
||||||
|
int _pad0;
|
||||||
|
} SceneHydra;
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
@ -2029,6 +2034,7 @@ typedef struct Scene {
|
|||||||
struct SceneDisplay display;
|
struct SceneDisplay display;
|
||||||
struct SceneEEVEE eevee;
|
struct SceneEEVEE eevee;
|
||||||
struct SceneGpencil grease_pencil_settings;
|
struct SceneGpencil grease_pencil_settings;
|
||||||
|
struct SceneHydra hydra;
|
||||||
} Scene;
|
} Scene;
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
@ -2830,6 +2836,13 @@ enum {
|
|||||||
SCE_DISPLAY_AA_SAMPLES_32 = 32,
|
SCE_DISPLAY_AA_SAMPLES_32 = 32,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** #SceneHydra->export_method */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SCE_HYDRA_EXPORT_HYDRA = 0,
|
||||||
|
SCE_HYDRA_EXPORT_USD = 1,
|
||||||
|
};
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -1197,6 +1197,11 @@ static char *rna_SceneGpencil_path(const PointerRNA * /*ptr*/)
|
|||||||
return BLI_strdup("grease_pencil_settings");
|
return BLI_strdup("grease_pencil_settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *rna_SceneHydra_path(const PointerRNA * /*ptr*/)
|
||||||
|
{
|
||||||
|
return BLI_strdup("hydra");
|
||||||
|
}
|
||||||
|
|
||||||
static int rna_RenderSettings_stereoViews_skip(CollectionPropertyIterator *iter, void * /*data*/)
|
static int rna_RenderSettings_stereoViews_skip(CollectionPropertyIterator *iter, void * /*data*/)
|
||||||
{
|
{
|
||||||
ListBaseIterator *internal = &iter->internal.listbase;
|
ListBaseIterator *internal = &iter->internal.listbase;
|
||||||
@ -7974,6 +7979,36 @@ static void rna_def_scene_gpencil(BlenderRNA *brna)
|
|||||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
|
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rna_def_scene_hydra(BlenderRNA *brna)
|
||||||
|
{
|
||||||
|
StructRNA *srna;
|
||||||
|
PropertyRNA *prop;
|
||||||
|
|
||||||
|
static const EnumPropertyItem hydra_export_method_items[] = {
|
||||||
|
{SCE_HYDRA_EXPORT_HYDRA,
|
||||||
|
"HYDRA",
|
||||||
|
0,
|
||||||
|
"Hydra",
|
||||||
|
"Fast interactive editing through native Hydra integration"},
|
||||||
|
{SCE_HYDRA_EXPORT_USD,
|
||||||
|
"USD",
|
||||||
|
0,
|
||||||
|
"USD",
|
||||||
|
"Export scene through USD file, for accurate comparison with USD file export"},
|
||||||
|
{0, nullptr, 0, nullptr, nullptr},
|
||||||
|
};
|
||||||
|
|
||||||
|
srna = RNA_def_struct(brna, "SceneHydra", nullptr);
|
||||||
|
RNA_def_struct_path_func(srna, "rna_SceneHydra_path");
|
||||||
|
RNA_def_struct_ui_text(srna, "Scene Hydra", "Scene Hydra render engine settings");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "export_method", PROP_ENUM, PROP_NONE);
|
||||||
|
RNA_def_property_enum_items(prop, hydra_export_method_items);
|
||||||
|
RNA_def_property_ui_text(
|
||||||
|
prop, "Export Method", "How to export the Blender scene to the Hydra render engine");
|
||||||
|
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void RNA_def_scene(BlenderRNA *brna)
|
void RNA_def_scene(BlenderRNA *brna)
|
||||||
{
|
{
|
||||||
StructRNA *srna;
|
StructRNA *srna;
|
||||||
@ -8467,6 +8502,11 @@ void RNA_def_scene(BlenderRNA *brna)
|
|||||||
RNA_def_property_struct_type(prop, "SceneGpencil");
|
RNA_def_property_struct_type(prop, "SceneGpencil");
|
||||||
RNA_def_property_ui_text(prop, "Grease Pencil", "Grease Pencil settings for the scene");
|
RNA_def_property_ui_text(prop, "Grease Pencil", "Grease Pencil settings for the scene");
|
||||||
|
|
||||||
|
/* Hydra */
|
||||||
|
prop = RNA_def_property(srna, "hydra", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_struct_type(prop, "SceneHydra");
|
||||||
|
RNA_def_property_ui_text(prop, "Hydra", "Hydra settings for the scene");
|
||||||
|
|
||||||
/* Nestled Data. */
|
/* Nestled Data. */
|
||||||
/* *** Non-Animated *** */
|
/* *** Non-Animated *** */
|
||||||
RNA_define_animate_sdna(false);
|
RNA_define_animate_sdna(false);
|
||||||
@ -8485,6 +8525,7 @@ void RNA_def_scene(BlenderRNA *brna)
|
|||||||
rna_def_display_safe_areas(brna);
|
rna_def_display_safe_areas(brna);
|
||||||
rna_def_scene_display(brna);
|
rna_def_scene_display(brna);
|
||||||
rna_def_scene_eevee(brna);
|
rna_def_scene_eevee(brna);
|
||||||
|
rna_def_scene_hydra(brna);
|
||||||
rna_def_view_layer_aov(brna);
|
rna_def_view_layer_aov(brna);
|
||||||
rna_def_view_layer_lightgroup(brna);
|
rna_def_view_layer_lightgroup(brna);
|
||||||
rna_def_view_layer_eevee(brna);
|
rna_def_view_layer_eevee(brna);
|
||||||
|
@ -42,6 +42,7 @@ set(INC
|
|||||||
../../depsgraph
|
../../depsgraph
|
||||||
../../blenkernel
|
../../blenkernel
|
||||||
../../imbuf
|
../../imbuf
|
||||||
|
../../io/usd
|
||||||
../../gpu
|
../../gpu
|
||||||
../../gpu/intern
|
../../gpu/intern
|
||||||
../../python/intern
|
../../python/intern
|
||||||
@ -90,30 +91,33 @@ set(SRC
|
|||||||
simple_light_task_delegate.cc
|
simple_light_task_delegate.cc
|
||||||
simple_light_task_delegate.h
|
simple_light_task_delegate.h
|
||||||
|
|
||||||
scene_delegate/blender_scene_delegate.h
|
|
||||||
scene_delegate/blender_scene_delegate.cc
|
scene_delegate/blender_scene_delegate.cc
|
||||||
scene_delegate/id.h
|
scene_delegate/blender_scene_delegate.h
|
||||||
scene_delegate/id.cc
|
|
||||||
scene_delegate/object.h
|
|
||||||
scene_delegate/object.cc
|
|
||||||
scene_delegate/material.h
|
|
||||||
scene_delegate/material.cc
|
|
||||||
scene_delegate/mesh.h
|
|
||||||
scene_delegate/mesh.cc
|
|
||||||
scene_delegate/curves.h
|
|
||||||
scene_delegate/curves.cc
|
scene_delegate/curves.cc
|
||||||
scene_delegate/mtlx_hydra_adapter.h
|
scene_delegate/curves.h
|
||||||
scene_delegate/mtlx_hydra_adapter.cc
|
scene_delegate/id.cc
|
||||||
scene_delegate/light.h
|
scene_delegate/id.h
|
||||||
scene_delegate/light.cc
|
|
||||||
scene_delegate/world.h
|
|
||||||
scene_delegate/world.cc
|
|
||||||
scene_delegate/instancer.h
|
|
||||||
scene_delegate/instancer.cc
|
|
||||||
scene_delegate/image.h
|
|
||||||
scene_delegate/image.cc
|
scene_delegate/image.cc
|
||||||
scene_delegate/volume.h
|
scene_delegate/image.h
|
||||||
|
scene_delegate/instancer.cc
|
||||||
|
scene_delegate/instancer.h
|
||||||
|
scene_delegate/light.cc
|
||||||
|
scene_delegate/light.h
|
||||||
|
scene_delegate/material.cc
|
||||||
|
scene_delegate/material.h
|
||||||
|
scene_delegate/mesh.cc
|
||||||
|
scene_delegate/mesh.h
|
||||||
|
scene_delegate/mtlx_hydra_adapter.cc
|
||||||
|
scene_delegate/mtlx_hydra_adapter.h
|
||||||
|
scene_delegate/object.cc
|
||||||
|
scene_delegate/object.h
|
||||||
|
scene_delegate/settings.h
|
||||||
|
scene_delegate/usd_scene_delegate.cc
|
||||||
|
scene_delegate/usd_scene_delegate.hh
|
||||||
scene_delegate/volume.cc
|
scene_delegate/volume.cc
|
||||||
|
scene_delegate/volume.h
|
||||||
|
scene_delegate/world.cc
|
||||||
|
scene_delegate/world.h
|
||||||
)
|
)
|
||||||
|
|
||||||
blender_add_lib(bf_render_hydra "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
blender_add_lib(bf_render_hydra "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||||
|
@ -9,8 +9,11 @@
|
|||||||
#include <pxr/usd/usdGeom/tokens.h>
|
#include <pxr/usd/usdGeom/tokens.h>
|
||||||
|
|
||||||
#include "BLI_path_util.h"
|
#include "BLI_path_util.h"
|
||||||
|
|
||||||
#include "GPU_context.h"
|
#include "GPU_context.h"
|
||||||
|
|
||||||
|
#include "DEG_depsgraph_query.h"
|
||||||
|
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
|
|
||||||
namespace blender::render::hydra {
|
namespace blender::render::hydra {
|
||||||
@ -47,8 +50,6 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
|
|||||||
render_index_.reset(pxr::HdRenderIndex::New(render_delegate_.Get(), hd_drivers));
|
render_index_.reset(pxr::HdRenderIndex::New(render_delegate_.Get(), hd_drivers));
|
||||||
free_camera_delegate_ = std::make_unique<pxr::HdxFreeCameraSceneDelegate>(
|
free_camera_delegate_ = std::make_unique<pxr::HdxFreeCameraSceneDelegate>(
|
||||||
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("freeCamera"));
|
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("freeCamera"));
|
||||||
scene_delegate_ = std::make_unique<BlenderSceneDelegate>(
|
|
||||||
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), this);
|
|
||||||
render_task_delegate_ = std::make_unique<RenderTaskDelegate>(
|
render_task_delegate_ = std::make_unique<RenderTaskDelegate>(
|
||||||
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask"));
|
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask"));
|
||||||
if (render_delegate_name == "HdStormRendererPlugin") {
|
if (render_delegate_name == "HdStormRendererPlugin") {
|
||||||
@ -62,21 +63,44 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
|
|||||||
|
|
||||||
void Engine::sync(Depsgraph *depsgraph, bContext *context)
|
void Engine::sync(Depsgraph *depsgraph, bContext *context)
|
||||||
{
|
{
|
||||||
scene_delegate_->populate(depsgraph, context);
|
const Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::sync_usd(pxr::UsdStageRefPtr stage)
|
if (scene->hydra.export_method == SCE_HYDRA_EXPORT_HYDRA) {
|
||||||
{
|
/* Fast path. */
|
||||||
if (!usd_delegate_) {
|
usd_scene_delegate_.reset();
|
||||||
usd_delegate_ = std::make_unique<pxr::UsdImagingDelegate>(
|
|
||||||
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("usd"));
|
if (!hydra_scene_delegate_) {
|
||||||
|
pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene");
|
||||||
|
hydra_scene_delegate_ = std::make_unique<BlenderSceneDelegate>(
|
||||||
|
render_index_.get(), scene_path, scene_delegate_settings_);
|
||||||
|
}
|
||||||
|
hydra_scene_delegate_->populate(depsgraph, context);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Slow USD export for reference. */
|
||||||
|
if (hydra_scene_delegate_) {
|
||||||
|
/* Freeing the Hydra scene delegate crashes as something internal to USD
|
||||||
|
* still holds a pointer to it, only clear it instead. */
|
||||||
|
hydra_scene_delegate_->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!usd_scene_delegate_) {
|
||||||
|
pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("usd_scene");
|
||||||
|
usd_scene_delegate_ = std::make_unique<USDSceneDelegate>(
|
||||||
|
render_index_.get(), scene_path, scene_delegate_settings_);
|
||||||
|
}
|
||||||
|
usd_scene_delegate_->populate(depsgraph, context);
|
||||||
}
|
}
|
||||||
usd_delegate_->Populate(stage->GetPseudoRoot());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::set_sync_setting(const std::string &key, const pxr::VtValue &val)
|
void Engine::set_sync_setting(const std::string &key, const pxr::VtValue &val)
|
||||||
{
|
{
|
||||||
scene_delegate_->set_setting(key, val);
|
if (key == "MaterialXFilenameKey") {
|
||||||
|
scene_delegate_settings_.mx_filename_key = pxr::TfToken(val.Get<std::string>());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scene_delegate_settings_.render_tokens.add_overwrite(pxr::TfToken(key), val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::set_render_setting(const std::string &key, const pxr::VtValue &val)
|
void Engine::set_render_setting(const std::string &key, const pxr::VtValue &val)
|
||||||
|
@ -18,9 +18,11 @@
|
|||||||
#include "CLG_log.h"
|
#include "CLG_log.h"
|
||||||
|
|
||||||
#include "render_task_delegate.h"
|
#include "render_task_delegate.h"
|
||||||
#include "scene_delegate/blender_scene_delegate.h"
|
|
||||||
#include "simple_light_task_delegate.h"
|
#include "simple_light_task_delegate.h"
|
||||||
|
|
||||||
|
#include "scene_delegate/blender_scene_delegate.h"
|
||||||
|
#include "scene_delegate/usd_scene_delegate.hh"
|
||||||
|
|
||||||
namespace blender::render::hydra {
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
extern struct CLG_LogRef *LOG_RENDER_HYDRA;
|
extern struct CLG_LogRef *LOG_RENDER_HYDRA;
|
||||||
@ -31,7 +33,6 @@ class Engine {
|
|||||||
virtual ~Engine() = default;
|
virtual ~Engine() = default;
|
||||||
|
|
||||||
void sync(Depsgraph *depsgraph, bContext *context);
|
void sync(Depsgraph *depsgraph, bContext *context);
|
||||||
void sync_usd(pxr::UsdStageRefPtr stage);
|
|
||||||
virtual void render(Depsgraph *depsgraph) = 0;
|
virtual void render(Depsgraph *depsgraph) = 0;
|
||||||
|
|
||||||
void set_sync_setting(const std::string &key, const pxr::VtValue &val);
|
void set_sync_setting(const std::string &key, const pxr::VtValue &val);
|
||||||
@ -42,18 +43,21 @@ class Engine {
|
|||||||
protected:
|
protected:
|
||||||
float renderer_percent_done();
|
float renderer_percent_done();
|
||||||
|
|
||||||
RenderEngine *bl_engine_;
|
RenderEngine *bl_engine_ = nullptr;
|
||||||
|
|
||||||
/* The order is important due to deletion order */
|
/* The order is important due to deletion order */
|
||||||
pxr::HgiUniquePtr hgi_;
|
pxr::HgiUniquePtr hgi_;
|
||||||
pxr::HdDriver hgi_driver_;
|
pxr::HdDriver hgi_driver_;
|
||||||
pxr::HdPluginRenderDelegateUniqueHandle render_delegate_;
|
pxr::HdPluginRenderDelegateUniqueHandle render_delegate_;
|
||||||
std::unique_ptr<pxr::HdRenderIndex> render_index_;
|
std::unique_ptr<pxr::HdRenderIndex> render_index_;
|
||||||
std::unique_ptr<BlenderSceneDelegate> scene_delegate_;
|
|
||||||
|
SceneDelegateSettings scene_delegate_settings_;
|
||||||
|
std::unique_ptr<BlenderSceneDelegate> hydra_scene_delegate_;
|
||||||
|
std::unique_ptr<USDSceneDelegate> usd_scene_delegate_;
|
||||||
|
|
||||||
std::unique_ptr<RenderTaskDelegate> render_task_delegate_;
|
std::unique_ptr<RenderTaskDelegate> render_task_delegate_;
|
||||||
std::unique_ptr<pxr::HdxFreeCameraSceneDelegate> free_camera_delegate_;
|
std::unique_ptr<pxr::HdxFreeCameraSceneDelegate> free_camera_delegate_;
|
||||||
std::unique_ptr<SimpleLightTaskDelegate> simple_light_task_delegate_;
|
std::unique_ptr<SimpleLightTaskDelegate> simple_light_task_delegate_;
|
||||||
std::unique_ptr<pxr::UsdImagingDelegate> usd_delegate_;
|
|
||||||
std::unique_ptr<pxr::HdEngine> engine_;
|
std::unique_ptr<pxr::HdEngine> engine_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -148,14 +148,21 @@ void FinalEngineGPU::render(Depsgraph *depsgraph)
|
|||||||
GPU_framebuffer_bind(framebuffer);
|
GPU_framebuffer_bind(framebuffer);
|
||||||
|
|
||||||
float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
pxr::VtValue world_color = scene_delegate_->GetLightParamValue(
|
|
||||||
scene_delegate_->GetDelegateID().AppendElementString("World"), pxr::HdLightTokens->color);
|
/* Workaround Storm rendering with transparent background. Does not currently work for
|
||||||
|
* USD, and should probably be optional depending on the Blender film transparency setting. */
|
||||||
|
if (hydra_scene_delegate_ && render_delegate_name == "HdStormRendererPlugin") {
|
||||||
|
pxr::VtValue world_color = hydra_scene_delegate_->GetLightParamValue(
|
||||||
|
hydra_scene_delegate_->GetDelegateID().AppendElementString("World"),
|
||||||
|
pxr::HdLightTokens->color);
|
||||||
if (!world_color.IsEmpty()) {
|
if (!world_color.IsEmpty()) {
|
||||||
auto &c = world_color.Get<pxr::GfVec3f>();
|
auto &c = world_color.Get<pxr::GfVec3f>();
|
||||||
clear_color[0] = c[0];
|
clear_color[0] = c[0];
|
||||||
clear_color[1] = c[1];
|
clear_color[1] = c[1];
|
||||||
clear_color[2] = c[2];
|
clear_color[2] = c[2];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GPU_framebuffer_clear_color_depth(framebuffer, clear_color, 1.0f);
|
GPU_framebuffer_clear_color_depth(framebuffer, clear_color, 1.0f);
|
||||||
|
|
||||||
/* Important: we have to create and bind at least one Vertex Array Object (VAO) before render
|
/* Important: we have to create and bind at least one Vertex Array Object (VAO) before render
|
||||||
|
@ -123,24 +123,6 @@ static PyObject *engine_sync_func(PyObject * /*self*/, PyObject *args)
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *engine_sync_usd_func(PyObject * /*self*/, PyObject *args)
|
|
||||||
{
|
|
||||||
PyObject *pyengine, *pystage;
|
|
||||||
if (!PyArg_ParseTuple(args, "OO", &pyengine, &pystage)) {
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine);
|
|
||||||
|
|
||||||
boost::python::extract<pxr::UsdStageRefPtr> extract(pystage);
|
|
||||||
pxr::UsdStagePtr stage = extract();
|
|
||||||
|
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA, 2, "Engine %p", engine);
|
|
||||||
engine->sync_usd(stage);
|
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *engine_render_func(PyObject * /*self*/, PyObject *args)
|
static PyObject *engine_render_func(PyObject * /*self*/, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *pyengine, *pydepsgraph;
|
PyObject *pyengine, *pydepsgraph;
|
||||||
@ -253,7 +235,6 @@ static PyMethodDef methods[] = {
|
|||||||
{"engine_create", engine_create_func, METH_VARARGS, ""},
|
{"engine_create", engine_create_func, METH_VARARGS, ""},
|
||||||
{"engine_free", engine_free_func, METH_VARARGS, ""},
|
{"engine_free", engine_free_func, METH_VARARGS, ""},
|
||||||
{"engine_sync", engine_sync_func, METH_VARARGS, ""},
|
{"engine_sync", engine_sync_func, METH_VARARGS, ""},
|
||||||
{"engine_sync_usd", engine_sync_usd_func, METH_VARARGS, ""},
|
|
||||||
{"engine_render", engine_render_func, METH_VARARGS, ""},
|
{"engine_render", engine_render_func, METH_VARARGS, ""},
|
||||||
{"engine_view_draw", engine_view_draw_func, METH_VARARGS, ""},
|
{"engine_view_draw", engine_view_draw_func, METH_VARARGS, ""},
|
||||||
{"engine_set_sync_setting", engine_set_sync_setting_func, METH_VARARGS, ""},
|
{"engine_set_sync_setting", engine_set_sync_setting_func, METH_VARARGS, ""},
|
||||||
|
@ -28,8 +28,8 @@ bool BlenderSceneDelegate::ShadingSettings::operator==(const ShadingSettings &ot
|
|||||||
|
|
||||||
BlenderSceneDelegate::BlenderSceneDelegate(pxr::HdRenderIndex *parent_index,
|
BlenderSceneDelegate::BlenderSceneDelegate(pxr::HdRenderIndex *parent_index,
|
||||||
pxr::SdfPath const &delegate_id,
|
pxr::SdfPath const &delegate_id,
|
||||||
Engine *engine)
|
const SceneDelegateSettings &settings)
|
||||||
: HdSceneDelegate(parent_index, delegate_id), engine(engine)
|
: HdSceneDelegate(parent_index, delegate_id), settings(settings)
|
||||||
{
|
{
|
||||||
instancer_data_ = std::make_unique<InstancerData>(this, instancer_prim_id());
|
instancer_data_ = std::make_unique<InstancerData>(this, instancer_prim_id());
|
||||||
}
|
}
|
||||||
@ -259,16 +259,6 @@ void BlenderSceneDelegate::clear()
|
|||||||
view3d = nullptr;
|
view3d = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlenderSceneDelegate::set_setting(const std::string &key, const pxr::VtValue &val)
|
|
||||||
{
|
|
||||||
if (key == "MaterialXFilenameKey") {
|
|
||||||
settings.mx_filename_key = pxr::TfToken(val.Get<std::string>());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
settings.render_tokens.add_overwrite(pxr::TfToken(key), val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pxr::SdfPath BlenderSceneDelegate::prim_id(ID *id, const char *prefix) const
|
pxr::SdfPath BlenderSceneDelegate::prim_id(ID *id, const char *prefix) const
|
||||||
{
|
{
|
||||||
/* Making id of object in form like <prefix>_<pointer in 16 hex digits format> */
|
/* Making id of object in form like <prefix>_<pointer in 16 hex digits format> */
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "light.h"
|
#include "light.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
#include "settings.h"
|
||||||
#include "volume.h"
|
#include "volume.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
|
|
||||||
@ -34,11 +35,6 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
|||||||
friend MaterialData; /* has access to objects and instancers */
|
friend MaterialData; /* has access to objects and instancers */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct Settings {
|
|
||||||
pxr::TfToken mx_filename_key;
|
|
||||||
Map<pxr::TfToken, pxr::VtValue> render_tokens;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ShadingSettings {
|
struct ShadingSettings {
|
||||||
bool use_scene_lights = true;
|
bool use_scene_lights = true;
|
||||||
bool use_scene_world = true;
|
bool use_scene_world = true;
|
||||||
@ -51,7 +47,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
|||||||
|
|
||||||
BlenderSceneDelegate(pxr::HdRenderIndex *parent_index,
|
BlenderSceneDelegate(pxr::HdRenderIndex *parent_index,
|
||||||
pxr::SdfPath const &delegate_id,
|
pxr::SdfPath const &delegate_id,
|
||||||
Engine *engine);
|
const SceneDelegateSettings &settings);
|
||||||
~BlenderSceneDelegate() override = default;
|
~BlenderSceneDelegate() override = default;
|
||||||
|
|
||||||
/* Delegate methods */
|
/* Delegate methods */
|
||||||
@ -77,14 +73,12 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
|||||||
|
|
||||||
void populate(Depsgraph *depsgraph, bContext *context);
|
void populate(Depsgraph *depsgraph, bContext *context);
|
||||||
void clear();
|
void clear();
|
||||||
void set_setting(const std::string &key, const pxr::VtValue &val);
|
|
||||||
|
|
||||||
Depsgraph *depsgraph = nullptr;
|
Depsgraph *depsgraph = nullptr;
|
||||||
bContext *context = nullptr;
|
bContext *context = nullptr;
|
||||||
View3D *view3d = nullptr;
|
View3D *view3d = nullptr;
|
||||||
Scene *scene = nullptr;
|
Scene *scene = nullptr;
|
||||||
Engine *engine;
|
const SceneDelegateSettings &settings;
|
||||||
Settings settings;
|
|
||||||
ShadingSettings shading_settings;
|
ShadingSettings shading_settings;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -19,7 +19,7 @@ namespace blender::render::hydra {
|
|||||||
static std::string get_cache_file(const std::string &file_name, bool mkdir = true)
|
static std::string get_cache_file(const std::string &file_name, bool mkdir = true)
|
||||||
{
|
{
|
||||||
char dir_path[FILE_MAX];
|
char dir_path[FILE_MAX];
|
||||||
BLI_path_join(dir_path, sizeof(dir_path), BKE_tempdir_session(), "hydra_image_cache");
|
BLI_path_join(dir_path, sizeof(dir_path), BKE_tempdir_session(), "hydra", "image_cache");
|
||||||
if (mkdir) {
|
if (mkdir) {
|
||||||
BLI_dir_create_recursive(dir_path);
|
BLI_dir_create_recursive(dir_path);
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ pxr::VtValue LightData::get_data(pxr::TfToken const &key) const
|
|||||||
return pxr::VtValue(it->second);
|
return pxr::VtValue(it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxr::VtValue *ret_ptr = scene_delegate_->settings.render_tokens.lookup_ptr(key);
|
const pxr::VtValue *ret_ptr = scene_delegate_->settings.render_tokens.lookup_ptr(key);
|
||||||
if (ret_ptr) {
|
if (ret_ptr) {
|
||||||
return *ret_ptr;
|
return *ret_ptr;
|
||||||
}
|
}
|
||||||
|
17
source/blender/render/hydra/scene_delegate/settings.h
Normal file
17
source/blender/render/hydra/scene_delegate/settings.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0
|
||||||
|
* Copyright 2011-2023 Blender Foundation */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pxr/base/tf/token.h>
|
||||||
|
|
||||||
|
#include "BLI_map.hh"
|
||||||
|
|
||||||
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
|
struct SceneDelegateSettings {
|
||||||
|
pxr::TfToken mx_filename_key;
|
||||||
|
Map<pxr::TfToken, pxr::VtValue> render_tokens;
|
||||||
|
};
|
||||||
|
|
||||||
|
}; // namespace blender::render::hydra
|
@ -0,0 +1,79 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0
|
||||||
|
* Copyright 2011-2022 Blender Foundation */
|
||||||
|
|
||||||
|
#include "usd_scene_delegate.hh"
|
||||||
|
|
||||||
|
#include "BLI_fileops.h"
|
||||||
|
#include "BLI_path_util.h"
|
||||||
|
#include "BLI_string.h"
|
||||||
|
|
||||||
|
#include "BKE_appdir.h"
|
||||||
|
|
||||||
|
#include "DEG_depsgraph_query.h"
|
||||||
|
|
||||||
|
#include "usd.h"
|
||||||
|
#include "usd.hh"
|
||||||
|
|
||||||
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
|
USDSceneDelegate::USDSceneDelegate(pxr::HdRenderIndex *render_index,
|
||||||
|
pxr::SdfPath const &delegate_id,
|
||||||
|
const SceneDelegateSettings &settings)
|
||||||
|
: render_index_(render_index), delegate_id_(delegate_id), settings_(settings)
|
||||||
|
{
|
||||||
|
/* Temporary directory to write any additional files to, like image or VDB files. */
|
||||||
|
char unique_name[FILE_MAXFILE];
|
||||||
|
BLI_snprintf(unique_name, sizeof(unique_name), "%p", this);
|
||||||
|
|
||||||
|
char dir_path[FILE_MAX];
|
||||||
|
BLI_path_join(
|
||||||
|
dir_path, sizeof(dir_path), BKE_tempdir_session(), "usd_scene_delegate", unique_name);
|
||||||
|
BLI_dir_create_recursive(dir_path);
|
||||||
|
|
||||||
|
char file_path[FILE_MAX];
|
||||||
|
BLI_path_join(file_path, sizeof(file_path), dir_path, "scene.usdc");
|
||||||
|
|
||||||
|
temp_dir_ = dir_path;
|
||||||
|
temp_file_ = file_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
USDSceneDelegate::~USDSceneDelegate()
|
||||||
|
{
|
||||||
|
BLI_delete(temp_dir_.c_str(), true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void USDSceneDelegate::populate(Depsgraph *depsgraph, bContext * /*context*/)
|
||||||
|
{
|
||||||
|
/* TODO: implement MaterialX support in USD exporter. */
|
||||||
|
const bool use_materialx = !settings_.mx_filename_key.IsEmpty();
|
||||||
|
(void)use_materialx;
|
||||||
|
|
||||||
|
USDExportParams params = {};
|
||||||
|
params.export_hair = true;
|
||||||
|
params.export_uvmaps = true;
|
||||||
|
params.export_normals = true;
|
||||||
|
params.export_materials = true;
|
||||||
|
params.selected_objects_only = false;
|
||||||
|
params.visible_objects_only = true;
|
||||||
|
params.use_instancing = true;
|
||||||
|
params.evaluation_mode = DEG_get_mode(depsgraph);
|
||||||
|
params.generate_preview_surface = true;
|
||||||
|
params.export_textures = true;
|
||||||
|
params.overwrite_textures = true;
|
||||||
|
params.relative_paths = true;
|
||||||
|
|
||||||
|
/* Create clean directory for export. */
|
||||||
|
BLI_delete(temp_dir_.c_str(), true, true);
|
||||||
|
BLI_dir_create_recursive(temp_dir_.c_str());
|
||||||
|
|
||||||
|
/* Free previous delegate and stage first to save memory. */
|
||||||
|
delegate_.reset();
|
||||||
|
stage_.Reset();
|
||||||
|
|
||||||
|
/* Convert depsgraph to stage + aditional file in temp directory. */
|
||||||
|
stage_ = io::usd::export_to_stage(params, depsgraph, temp_file_.c_str());
|
||||||
|
delegate_ = std::make_unique<pxr::UsdImagingDelegate>(render_index_, delegate_id_);
|
||||||
|
delegate_->Populate(stage_->GetPseudoRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::render::hydra
|
@ -0,0 +1,38 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0
|
||||||
|
* Copyright 2023 Blender Foundation */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pxr/imaging/hd/renderIndex.h>
|
||||||
|
#include <pxr/usdImaging/usdImaging/delegate.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
struct Depsgraph;
|
||||||
|
struct bContext;
|
||||||
|
|
||||||
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
|
/* Populate Hydra render index using USD file export, for testing. */
|
||||||
|
class USDSceneDelegate {
|
||||||
|
pxr::HdRenderIndex *render_index_;
|
||||||
|
pxr::SdfPath const delegate_id_;
|
||||||
|
pxr::UsdStageRefPtr stage_;
|
||||||
|
std::unique_ptr<pxr::UsdImagingDelegate> delegate_;
|
||||||
|
const SceneDelegateSettings &settings_;
|
||||||
|
|
||||||
|
std::string temp_dir_;
|
||||||
|
std::string temp_file_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
USDSceneDelegate(pxr::HdRenderIndex *render_index,
|
||||||
|
pxr::SdfPath const &delegate_id,
|
||||||
|
const SceneDelegateSettings &settings_);
|
||||||
|
~USDSceneDelegate();
|
||||||
|
|
||||||
|
void populate(Depsgraph *depsgraph, bContext *context);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace blender::render::hydra
|
Loading…
Reference in New Issue
Block a user