USD export: prototype invoking Python chasers #108823

Merged
Michael Kowalski merged 35 commits from makowalski/blender:test-usd-export-chaser into main 2023-08-07 23:02:54 +02:00
3 changed files with 74 additions and 20 deletions
Showing only changes of commit 808ca68414 - Show all commits

View File

@ -297,6 +297,7 @@ static void export_startjob(void *customdata,
}
}
register_export_hook_converters();
call_export_hooks(usd_stage, data->depsgraph);
usd_stage->GetRootLayer()->Save();

View File

@ -6,6 +6,9 @@
#include <boost/python/object.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/class.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/to_python_converter.hpp>
#include "BLI_listbase.h"
@ -57,6 +60,71 @@ USDHook *USD_find_hook_name(const char name[])
namespace blender::io::usd {
/* Convert PointerRNA to a PyObject*. */
struct PointerRNAToPython {
static PyObject *convert(const PointerRNA &pRNA)
{
return pyrna_struct_CreatePyObject(const_cast<PointerRNA*>(&pRNA));
}
};
/* Encapsulate arguments for scene export. */
struct USDSceneExportContext {
USDSceneExportContext() : depsgraph_ptr({})
{
}
USDSceneExportContext(pxr::UsdStageRefPtr in_stage, Depsgraph *depsgraph) : stage(in_stage)
{
RNA_pointer_create(NULL, &RNA_Depsgraph, depsgraph, &depsgraph_ptr);
}
pxr::UsdStageRefPtr GetStage()
{
return stage;
}
const PointerRNA &GetDepsgraph()
{
return depsgraph_ptr;
}
pxr::UsdStageRefPtr stage;
PointerRNA depsgraph_ptr;
};
void register_export_hook_converters()
{
static bool registered = false;
/* No need to register if there are no hooks. */
if (g_usd_hooks.empty()) {
return;
}
if (registered) {
return;
}
registered = true;
PyGILState_STATE gilstate = PyGILState_Ensure();
python::to_python_converter<PointerRNA, PointerRNAToPython>();
python::class_<USDSceneExportContext>("USDSceneExportContext")
.def("GetStage", &USDSceneExportContext::GetStage)
.def("GetDepsgraph",
&USDSceneExportContext::GetDepsgraph,
python::return_value_policy<python::return_by_value>())
;
PyGILState_Release(gilstate);
}
void call_export_hooks(pxr::UsdStageRefPtr stage, Depsgraph *depsgraph)
{
@ -69,9 +137,6 @@ void call_export_hooks(pxr::UsdStageRefPtr stage, Depsgraph *depsgraph)
/* The chaser function name. */
const char *func_name = "on_export";
PointerRNA depsgraph_ptr;
PyObject *depsgraph_obj = nullptr;
/* Iterate over the hooks and invoke the hook function, if it's defined. */
USDHookList::const_iterator hook_iter = g_usd_hooks.begin();
while (hook_iter != g_usd_hooks.end()) {
@ -95,22 +160,11 @@ void call_export_hooks(pxr::UsdStageRefPtr stage, Depsgraph *depsgraph)
continue;
}
if (!depsgraph_obj) {
RNA_pointer_create(NULL, &RNA_Depsgraph, depsgraph, &depsgraph_ptr);
depsgraph_obj = pyrna_struct_CreatePyObject(&depsgraph_ptr);
}
USDSceneExportContext hook_context(stage, depsgraph);
if (!depsgraph_obj) {
continue;
}
/* Invoke the chaser. Additional arguments could be
* provided, e.g., a dictionary mapping Blender objects
* to USD prims. */
python::call_method<void>(hook_obj,
func_name,
python::object(python::handle<>(depsgraph_obj)),
stage);
hook_context);
}
catch (...) {
if (PyErr_Occurred()) {
@ -119,10 +173,6 @@ void call_export_hooks(pxr::UsdStageRefPtr stage, Depsgraph *depsgraph)
}
}
if (depsgraph_obj) {
Py_DECREF(depsgraph_obj);
}
PyGILState_Release(gilstate);
}

View File

@ -11,6 +11,9 @@ struct USDExportParams;
namespace blender::io::usd {
/* Ensure classes and type converters necessary for invoking export hook are registered. */
void register_export_hook_converters();
/* Call the 'on_export' chaser function defined in the registred USDHook classes. */
void call_export_hooks(pxr::UsdStageRefPtr stage, Depsgraph *depsgraph);