USD: basic support for on_import USD hooks
Added support for defining an on_import() function in bpy.types.USDHook subclasses. If on_import() is defined on a given USD hook, it will be invoked in import_endjob(). The implementation closely follows the existing design of export hooks. USDHook.on_import() takes as an argument an instance of an internally defined USDSceneImportContext class which provides an accessor to the USD stage. Also updated the USDHook documentation with an example on_import() callback implementation. Pull Request: https://projects.blender.org/blender/blender/pulls/117822
This commit is contained in:
parent
a3183fb95f
commit
ecbf3385c5
@ -3,9 +3,9 @@ USD Hook Example
|
||||
++++++++++++++++
|
||||
|
||||
This example shows an implementation of ``USDHook`` to extend USD
|
||||
export functionalty.
|
||||
export and import functionalty.
|
||||
|
||||
One may optionally define one or both of the following callback functions
|
||||
One may optionally define any or all of the following callback functions
|
||||
in the ``USDHook`` subclass.
|
||||
|
||||
Hook function ``on_export()`` is called before the USD export finalizes,
|
||||
@ -31,13 +31,21 @@ USD stage to be saved.
|
||||
Note that the target USD material might already have connected shaders created by the USD exporter or
|
||||
by other material export hooks.
|
||||
|
||||
The hook functions should return ``True`` on success or ``False`` if the operation was bypasssed or
|
||||
Hook function ``on_import()`` is called after the USD import finalizes. This function takes
|
||||
as an argument an instance of an internally defined class ``USDSceneImportContext`` which provides the
|
||||
following accessors to the scene data:
|
||||
|
||||
- ``get_stage()`` returns the USD stage which was imported.
|
||||
|
||||
The hook functions should return ``True`` on success or ``False`` if the operation was bypassed or
|
||||
otherwise failed to complete. Exceptions raised by these functions will be reported in Blender, with
|
||||
the exception details printed to the console.
|
||||
|
||||
The ``USDHookExample`` class in this example impements an ``on_export()`` function to add custom data to
|
||||
the stage's root layer and an ``on_material_export()`` function to create a simple ``MaterialX`` shader
|
||||
on the USD material.
|
||||
The ``USDHookExample`` class in this example impements the fllowing functions:
|
||||
|
||||
- ``on_export()`` function to add custom data to the stage's root layer.
|
||||
- ``on_material_export()`` function to create a simple ``MaterialX`` shader on the givne USD material.
|
||||
- ``on_import()`` function to create a text object to display the stage's custom layer data.
|
||||
|
||||
"""
|
||||
|
||||
@ -96,6 +104,45 @@ class USDHookExample(bpy.types.USDHook):
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def on_import(import_context):
|
||||
""" Create a text object to display the stage's custom data.
|
||||
"""
|
||||
stage = import_context.get_stage()
|
||||
|
||||
if stage is None:
|
||||
return False
|
||||
|
||||
# Get the custom data.
|
||||
rootLayer = stage.GetRootLayer()
|
||||
customData = rootLayer.customLayerData
|
||||
|
||||
# Create a text object to display the stage path
|
||||
# and custom data dictionary entries.
|
||||
|
||||
bpy.ops.object.text_add()
|
||||
ob = bpy.context.view_layer.objects.active
|
||||
|
||||
if (ob is None) or (ob.data is None):
|
||||
return False
|
||||
|
||||
ob.name = "layer_data"
|
||||
ob.data.name = "layer_data"
|
||||
|
||||
# The stage root path is the first line.
|
||||
text = rootLayer.realPath
|
||||
|
||||
# Append key/value strings, enforcing text wrapping.
|
||||
for item in customData.items():
|
||||
print(item)
|
||||
text += '\n'
|
||||
line = str(item[0]) + ': ' + str(item[1])
|
||||
text += textwrap.fill(line, width=80)
|
||||
|
||||
ob.data.body = text
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(USDHookExample)
|
||||
|
@ -255,8 +255,8 @@ pxr::UsdStageRefPtr export_to_stage(const USDExportParams ¶ms,
|
||||
/* For restoring the current frame after exporting animation is done. */
|
||||
const int orig_frame = scene->r.cfra;
|
||||
|
||||
/* Ensure Python types for invoking export hooks are registered. */
|
||||
register_export_hook_converters();
|
||||
/* Ensure Python types for invoking hooks are registered. */
|
||||
register_hook_converters();
|
||||
|
||||
usd_stage->SetMetadata(pxr::UsdGeomTokens->upAxis, pxr::VtValue(pxr::UsdGeomTokens->z));
|
||||
ensure_root_prim(usd_stage, params);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "IO_types.hh"
|
||||
#include "usd.h"
|
||||
#include "usd_hierarchy_iterator.h"
|
||||
#include "usd_hook.h"
|
||||
#include "usd_reader_geom.h"
|
||||
#include "usd_reader_prim.h"
|
||||
#include "usd_reader_stage.h"
|
||||
@ -451,6 +452,11 @@ static void import_endjob(void *customdata)
|
||||
if (data->params.import_materials && data->params.import_all_materials) {
|
||||
data->archive->fake_users_for_unused_materials();
|
||||
}
|
||||
|
||||
/* Ensure Python types for invoking hooks are registered. */
|
||||
register_hook_converters();
|
||||
|
||||
call_import_hooks(data->archive->stage(), data->params.worker_status->reports);
|
||||
}
|
||||
|
||||
WM_set_locked_interface(data->wm, false);
|
||||
|
@ -102,6 +102,21 @@ struct USDSceneExportContext {
|
||||
PointerRNA depsgraph_ptr;
|
||||
};
|
||||
|
||||
/* Encapsulate arguments for scene import. */
|
||||
struct USDSceneImportContext {
|
||||
|
||||
USDSceneImportContext() {}
|
||||
|
||||
USDSceneImportContext(pxr::UsdStageRefPtr in_stage) : stage(in_stage) {}
|
||||
|
||||
pxr::UsdStageRefPtr get_stage()
|
||||
{
|
||||
return stage;
|
||||
}
|
||||
|
||||
pxr::UsdStageRefPtr stage;
|
||||
};
|
||||
|
||||
/* Encapsulate arguments for material export. */
|
||||
struct USDMaterialExportContext {
|
||||
USDMaterialExportContext() {}
|
||||
@ -116,7 +131,7 @@ struct USDMaterialExportContext {
|
||||
pxr::UsdStageRefPtr stage;
|
||||
};
|
||||
|
||||
void register_export_hook_converters()
|
||||
void register_hook_converters()
|
||||
{
|
||||
static bool registered = false;
|
||||
|
||||
@ -150,6 +165,9 @@ void register_export_hook_converters()
|
||||
python::class_<USDMaterialExportContext>("USDMaterialExportContext")
|
||||
.def("get_stage", &USDMaterialExportContext::get_stage);
|
||||
|
||||
python::class_<USDSceneImportContext>("USDSceneImportContext")
|
||||
.def("get_stage", &USDSceneImportContext::get_stage);
|
||||
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
|
||||
@ -287,6 +305,28 @@ class OnMaterialExportInvoker : public USDHookInvoker {
|
||||
}
|
||||
};
|
||||
|
||||
class OnImportInvoker : public USDHookInvoker {
|
||||
private:
|
||||
USDSceneImportContext hook_context_;
|
||||
|
||||
public:
|
||||
OnImportInvoker(pxr::UsdStageRefPtr stage, ReportList *reports) : hook_context_(stage)
|
||||
{
|
||||
reports_ = reports;
|
||||
}
|
||||
|
||||
protected:
|
||||
const char *function_name() const override
|
||||
{
|
||||
return "on_import";
|
||||
}
|
||||
|
||||
void call_hook(PyObject *hook_obj) const override
|
||||
{
|
||||
python::call_method<bool>(hook_obj, function_name(), hook_context_);
|
||||
}
|
||||
};
|
||||
|
||||
void call_export_hooks(pxr::UsdStageRefPtr stage, Depsgraph *depsgraph, ReportList *reports)
|
||||
{
|
||||
if (g_usd_hooks.empty()) {
|
||||
@ -310,4 +350,14 @@ void call_material_export_hooks(pxr::UsdStageRefPtr stage,
|
||||
on_material_export.call();
|
||||
}
|
||||
|
||||
void call_import_hooks(pxr::UsdStageRefPtr stage, ReportList *reports)
|
||||
{
|
||||
if (g_usd_hooks.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
OnImportInvoker on_import(stage, reports);
|
||||
on_import.call();
|
||||
}
|
||||
|
||||
} // namespace blender::io::usd
|
||||
|
@ -16,8 +16,9 @@ struct USDExportParams;
|
||||
|
||||
namespace blender::io::usd {
|
||||
|
||||
/** Ensure classes and type converters necessary for invoking export hook are registered. */
|
||||
void register_export_hook_converters();
|
||||
/** Ensure classes and type converters necessary for invoking import and export hooks
|
||||
* are registered. */
|
||||
void register_hook_converters();
|
||||
|
||||
/** Call the 'on_export' chaser function defined in the registered USDHook classes. */
|
||||
void call_export_hooks(pxr::UsdStageRefPtr stage, Depsgraph *depsgraph, ReportList *reports);
|
||||
@ -28,4 +29,7 @@ void call_material_export_hooks(pxr::UsdStageRefPtr stage,
|
||||
pxr::UsdShadeMaterial &usd_material,
|
||||
ReportList *reports);
|
||||
|
||||
/** Call the 'on_import' chaser function defined in the registered USDHook classes. */
|
||||
void call_import_hooks(pxr::UsdStageRefPtr stage, ReportList *reports);
|
||||
|
||||
} // namespace blender::io::usd
|
||||
|
Loading…
Reference in New Issue
Block a user