Merge branch 'blender-v4.1-release'

This commit is contained in:
Jesse Yurkovich 2024-02-15 16:55:12 -08:00
commit 551b846bcd
4 changed files with 40 additions and 41 deletions

View File

@ -55,6 +55,7 @@ import pxr.Gf as Gf
import pxr.Sdf as Sdf
import pxr.Usd as Usd
import pxr.UsdShade as UsdShade
import textwrap
class USDHookExample(bpy.types.USDHook):

View File

@ -9,11 +9,10 @@
#include <boost/python/call_method.hpp>
#include <boost/python/class.hpp>
#include <boost/python/import.hpp>
#include <boost/python/object.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/to_python_converter.hpp>
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
#include "BKE_report.hh"
@ -22,49 +21,52 @@
#include "RNA_types.hh"
#include "bpy_rna.h"
#include "WM_api.hh"
#include "WM_types.hh"
#include <list>
#include <memory>
using namespace boost;
namespace blender::io::usd {
using USDHookList = std::list<USDHook *>;
using USDHookList = std::list<std::unique_ptr<USDHook>>;
/* USD hook type declarations */
static USDHookList g_usd_hooks;
void USD_register_hook(USDHook *hook)
static USDHookList &hook_list()
{
if (std::find(g_usd_hooks.begin(), g_usd_hooks.end(), hook) != g_usd_hooks.end()) {
static USDHookList hooks{};
return hooks;
}
void USD_register_hook(std::unique_ptr<USDHook> hook)
{
if (USD_find_hook_name(hook->idname)) {
/* The hook is already in the list. */
return;
}
/* Add hook type to the list. */
g_usd_hooks.push_back(hook);
hook_list().push_back(std::move(hook));
}
void USD_unregister_hook(USDHook *hook)
{
g_usd_hooks.remove(hook);
hook_list().remove_if(
[hook](const std::unique_ptr<USDHook> &item) { return item.get() == hook; });
}
USDHook *USD_find_hook_name(const char name[])
USDHook *USD_find_hook_name(const char idname[])
{
/* sanity checks */
if (g_usd_hooks.empty() || (name == nullptr) || (name[0] == 0)) {
if (hook_list().empty() || (idname == nullptr) || (idname[0] == 0)) {
return nullptr;
}
USDHookList::iterator hook_iter = std::find_if(
g_usd_hooks.begin(), g_usd_hooks.end(), [name](USDHook *hook) {
return STREQ(hook->idname, name);
hook_list().begin(), hook_list().end(), [idname](const std::unique_ptr<USDHook> &item) {
return STREQ(item->idname, idname);
});
return (hook_iter == g_usd_hooks.end()) ? nullptr : *hook_iter;
return (hook_iter == hook_list().end()) ? nullptr : hook_iter->get();
}
/* Convert PointerRNA to a PyObject*. */
@ -136,7 +138,7 @@ void register_hook_converters()
static bool registered = false;
/* No need to register if there are no hooks. */
if (g_usd_hooks.empty()) {
if (hook_list().empty()) {
return;
}
@ -196,22 +198,22 @@ class USDHookInvoker {
/* Attempt to call the function, if defined by the registered hooks. */
void call() const
{
if (g_usd_hooks.empty()) {
if (hook_list().empty()) {
return;
}
PyGILState_STATE gilstate = PyGILState_Ensure();
/* 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()) {
USDHookList::const_iterator hook_iter = hook_list().begin();
while (hook_iter != hook_list().end()) {
/* XXX: Not sure if this is necessary:
* Advance the iterator before invoking the callback, to guard
* against the unlikely error where the hook is de-registered in
* the callback. This would prevent a crash due to the iterator
* getting invalidated. */
USDHook *hook = *hook_iter;
USDHook *hook = hook_iter->get();
++hook_iter;
if (!hook->rna_ext.data) {
@ -329,7 +331,7 @@ class OnImportInvoker : public USDHookInvoker {
void call_export_hooks(pxr::UsdStageRefPtr stage, Depsgraph *depsgraph, ReportList *reports)
{
if (g_usd_hooks.empty()) {
if (hook_list().empty()) {
return;
}
@ -342,7 +344,7 @@ void call_material_export_hooks(pxr::UsdStageRefPtr stage,
pxr::UsdShadeMaterial &usd_material,
ReportList *reports)
{
if (g_usd_hooks.empty()) {
if (hook_list().empty()) {
return;
}
@ -352,7 +354,7 @@ void call_material_export_hooks(pxr::UsdStageRefPtr stage,
void call_import_hooks(pxr::UsdStageRefPtr stage, ReportList *reports)
{
if (g_usd_hooks.empty()) {
if (hook_list().empty()) {
return;
}

View File

@ -204,13 +204,12 @@ struct USDHook {
ExtensionRNA rna_ext;
};
void USD_register_hook(USDHook *hook);
void USD_register_hook(std::unique_ptr<USDHook> hook);
/**
* Remove the given entry from the list of registered hooks.
* Note that this does not free the allocated memory for the
* hook instance, so a separate call to `MEM_freeN(hook)` is required.
* Remove the given entry from the list of registered hooks and
* free the allocated memory for the hook instance.
*/
void USD_unregister_hook(USDHook *hook);
USDHook *USD_find_hook_name(const char name[]);
USDHook *USD_find_hook_name(const char idname[]);
}; // namespace blender::io::usd

View File

@ -46,8 +46,6 @@ static bool rna_USDHook_unregister(Main * /*bmain*/, StructRNA *type)
/* unlink Blender-side data */
USD_unregister_hook(hook);
MEM_freeN(hook);
return true;
}
@ -60,8 +58,7 @@ static StructRNA *rna_USDHook_register(Main *bmain,
StructFreeFunc free)
{
const char *error_prefix = "Registering USD hook class:";
USDHook dummy_hook = {{0}};
USDHook *hook;
USDHook dummy_hook{};
/* setup dummy type info to store static properties in */
PointerRNA dummy_hook_ptr = RNA_pointer_create(nullptr, &RNA_USDHook, &dummy_hook);
@ -82,8 +79,7 @@ static StructRNA *rna_USDHook_register(Main *bmain,
}
/* check if we have registered this hook before, and remove it */
hook = USD_find_hook_name(dummy_hook.idname);
if (hook) {
if (USDHook *hook = USD_find_hook_name(dummy_hook.idname)) {
BKE_reportf(reports,
RPT_INFO,
"%s '%s', bl_idname '%s' has been registered before, unregistering previous",
@ -105,23 +101,24 @@ static StructRNA *rna_USDHook_register(Main *bmain,
}
/* create a new KeyingSetInfo type */
hook = static_cast<USDHook *>(MEM_mallocN(sizeof(USDHook), "python USD hook"));
memcpy(hook, &dummy_hook, sizeof(USDHook));
auto hook = std::make_unique<USDHook>();
*hook = dummy_hook;
/* set RNA-extensions info */
hook->rna_ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, hook->idname, &RNA_USDHook);
hook->rna_ext.data = data;
hook->rna_ext.call = call;
hook->rna_ext.free = free;
RNA_struct_blender_type_set(hook->rna_ext.srna, hook);
RNA_struct_blender_type_set(hook->rna_ext.srna, hook.get());
/* add and register with other info as needed */
USD_register_hook(hook);
StructRNA *srna = hook->rna_ext.srna;
USD_register_hook(std::move(hook));
WM_main_add_notifier(NC_WINDOW, nullptr);
/* return the struct-rna added */
return hook->rna_ext.srna;
return srna;
}
#else