From eaece961470a11de3518ca32a6eaa9ef45cd9515 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Wed, 15 Mar 2023 15:50:38 +0200 Subject: [PATCH 1/2] BLEN-368: Fixes in hydra.py Renamed hydra.py -> bpy_hydra.py. Renamed internal py module _hydra -> _bpy_hydra.py Removed Exception catch in export_mtlx() --- .../modules/{hydra.py => bpy_hydra.py} | 26 +++++++------------ source/blender/python/intern/bpy_interface.c | 6 ++--- source/blender/render/hydra/python.cc | 4 +-- .../render/hydra/scene_delegate/material.cc | 13 +++++++--- 4 files changed, 24 insertions(+), 25 deletions(-) rename release/scripts/modules/{hydra.py => bpy_hydra.py} (64%) diff --git a/release/scripts/modules/hydra.py b/release/scripts/modules/bpy_hydra.py similarity index 64% rename from release/scripts/modules/hydra.py rename to release/scripts/modules/bpy_hydra.py index a44c2d68954f..1c9bb2db1be7 100644 --- a/release/scripts/modules/hydra.py +++ b/release/scripts/modules/bpy_hydra.py @@ -3,16 +3,13 @@ # -import traceback - import bpy -import _hydra +import _bpy_hydra -from _hydra import register_plugins, get_render_plugins +from _bpy_hydra import register_plugins, get_render_plugins class HydraRenderEngine(bpy.types.RenderEngine): - bl_use_preview = True bl_use_shading_nodes_custom = False delegate_id = '' @@ -22,11 +19,11 @@ class HydraRenderEngine(bpy.types.RenderEngine): if not self.engine_ptr: return - _hydra.engine_free(self.engine_ptr) + _bpy_hydra.engine_free(self.engine_ptr) @classmethod def register(cls): - _hydra.init() + _bpy_hydra.init() @classmethod def unregister(cls): @@ -42,25 +39,25 @@ class HydraRenderEngine(bpy.types.RenderEngine): def render(self, depsgraph): engine_type = 'PREVIEW' if self.is_preview else 'FINAL' - self.engine_ptr = _hydra.engine_create(self.as_pointer(), engine_type, self.delegate_id) + self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), engine_type, self.delegate_id) delegate_settings = self.get_delegate_settings(engine_type) - _hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), bpy.context.as_pointer(), delegate_settings) - _hydra.engine_render(self.engine_ptr, depsgraph.as_pointer()) + _bpy_hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), bpy.context.as_pointer(), delegate_settings) + _bpy_hydra.engine_render(self.engine_ptr, depsgraph.as_pointer()) # viewport render def view_update(self, context, depsgraph): if not self.engine_ptr: - self.engine_ptr = _hydra.engine_create(self.as_pointer(), 'VIEWPORT', self.delegate_id) + self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), 'VIEWPORT', self.delegate_id) delegate_settings = self.get_delegate_settings('VIEWPORT') - _hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), context.as_pointer(), delegate_settings) + _bpy_hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), context.as_pointer(), delegate_settings) def view_draw(self, context, depsgraph): if not self.engine_ptr: return - _hydra.engine_view_draw(self.engine_ptr, depsgraph.as_pointer(), context.as_pointer()) + _bpy_hydra.engine_view_draw(self.engine_ptr, depsgraph.as_pointer(), context.as_pointer()) def export_mtlx(material_name): @@ -79,7 +76,4 @@ def export_mtlx(material_name): except ImportError: print("ERROR: no MaterialX addon available") - except Exception as e: - print("ERROR:", e, traceback.format_exc()) - return "" diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 7ac8b93d3b8b..64f6b2f982a5 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -256,8 +256,8 @@ static PyObject *CCL_initPython(void) #endif #ifdef WITH_HYDRA -/* defined in USD Hydra module */ -extern PyObject *Hydra_initPython(void); +/* defined in render_hydra module */ +extern PyObject *BPyInit_hydra(void); #endif static struct _inittab bpy_internal_modules[] = { @@ -290,7 +290,7 @@ static struct _inittab bpy_internal_modules[] = { {"gpu", BPyInit_gpu}, {"idprop", BPyInit_idprop}, #ifdef WITH_HYDRA - {"_hydra", Hydra_initPython}, + {"_bpy_hydra", BPyInit_hydra}, #endif {NULL, NULL}, }; diff --git a/source/blender/render/hydra/python.cc b/source/blender/render/hydra/python.cc index 61d8ededeb3e..c8530d58c44a 100644 --- a/source/blender/render/hydra/python.cc +++ b/source/blender/render/hydra/python.cc @@ -266,7 +266,7 @@ static PyMethodDef methods[] = { static struct PyModuleDef module = { PyModuleDef_HEAD_INIT, - "_hydra", + "_bpy_hydra", "Hydra render API", -1, methods, @@ -282,7 +282,7 @@ static struct PyModuleDef module = { extern "C" { #endif -PyObject *Hydra_initPython(void) +PyObject *BPyInit_hydra(void) { PyObject *mod = PyModule_Create(&blender::render::hydra::module); return mod; diff --git a/source/blender/render/hydra/scene_delegate/material.cc b/source/blender/render/hydra/scene_delegate/material.cc index d32b634708cd..c4988558c4c9 100644 --- a/source/blender/render/hydra/scene_delegate/material.cc +++ b/source/blender/render/hydra/scene_delegate/material.cc @@ -74,14 +74,19 @@ void MaterialData::export_mtlx() gstate = PyGILState_Ensure(); PyObject *module, *dict, *func, *result; - module = PyImport_ImportModule("hydra"); + module = PyImport_ImportModule("bpy_hydra"); dict = PyModule_GetDict(module); func = PyDict_GetItemString(dict, "export_mtlx"); result = PyObject_CallFunction(func, "s", name().c_str()); - std::string path = PyUnicode_AsUTF8(result); - - Py_DECREF(result); + std::string path; + if (result) { + path = PyUnicode_AsUTF8(result); + Py_DECREF(result); + } + else { + PyErr_Print(); + } Py_DECREF(module); PyGILState_Release(gstate); -- 2.30.2 From ba6de9a2def5ed2f704bd8a0e0ee2ca0ed22ceb6 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Wed, 15 Mar 2023 18:27:17 +0200 Subject: [PATCH 2/2] Added documentation for HydraRenderEngine with example. Changed export_mtlx to use material RNA object. --- release/scripts/modules/bpy_hydra.py | 45 ++++++++++++++++--- source/blender/render/hydra/CMakeLists.txt | 2 + .../render/hydra/scene_delegate/material.cc | 13 +++++- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/release/scripts/modules/bpy_hydra.py b/release/scripts/modules/bpy_hydra.py index 1c9bb2db1be7..fc5700992293 100644 --- a/release/scripts/modules/bpy_hydra.py +++ b/release/scripts/modules/bpy_hydra.py @@ -1,7 +1,40 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright 2011-2022 Blender Foundation +# SPDX-License-Identifier: GPL-2.0-or-later -# +""" +Implementation of class `HydraRenderEngine`. + +Render Blender addon with Hydra render delegate should inherit `HydraRenderEngine`. +Example: +``` +import bpy_hydra + +class CustomHydraRenderEngine(HydraRenderEngine): + bl_idname = 'CustomHydraRenderEngine' + bl_label = "Hydra: Custom" + bl_info = "Hydra Custom render delegate" + + delegate_id = 'HdCustomRendererPlugin' + + @classmethod + def register(cls): + super().register() + + bpy_hydra.register_plugins(["/path/to/plugin")], ["/additional/system/path")]) + + def get_delegate_settings(self, engine_type): + return { + 'setting1': 1, + 'setting2': "2", + } +``` +""" + +__all__ = ( + "HydraRenderEngine", + "export_mtlx", + "register_plugins", + "get_render_plugins", +) import bpy import _bpy_hydra @@ -10,6 +43,8 @@ from _bpy_hydra import register_plugins, get_render_plugins class HydraRenderEngine(bpy.types.RenderEngine): + """ Render addon with Hydra render delegate should inherit this class """ + bl_use_shading_nodes_custom = False delegate_id = '' @@ -60,11 +95,11 @@ class HydraRenderEngine(bpy.types.RenderEngine): _bpy_hydra.engine_view_draw(self.engine_ptr, depsgraph.as_pointer(), context.as_pointer()) -def export_mtlx(material_name): +def export_mtlx(material): + """ Exports material to .mtlx file. It is called from Blender source code. """ try: import materialx.utils as mx_utils - material = bpy.data.materials[material_name] doc = mx_utils.export(material, None) if not doc: return "" diff --git a/source/blender/render/hydra/CMakeLists.txt b/source/blender/render/hydra/CMakeLists.txt index 91f300f78ac3..4f69734ced6d 100644 --- a/source/blender/render/hydra/CMakeLists.txt +++ b/source/blender/render/hydra/CMakeLists.txt @@ -34,7 +34,9 @@ set(INC ../../gpu ../../gpu/opengl ../../gpu/intern + ../../python/intern .. + ${CMAKE_BINARY_DIR}/source/blender/makesrna/intern ) set(INC_SYS diff --git a/source/blender/render/hydra/scene_delegate/material.cc b/source/blender/render/hydra/scene_delegate/material.cc index c4988558c4c9..464d42ac4579 100644 --- a/source/blender/render/hydra/scene_delegate/material.cc +++ b/source/blender/render/hydra/scene_delegate/material.cc @@ -12,6 +12,10 @@ #include "BKE_lib_id.h" #include "BKE_material.h" +#include "MEM_guardedalloc.h" +#include "RNA_blender_cpp.h" +#include "bpy_rna.h" + #include "blender_scene_delegate.h" #include "material.h" #include "mtlx_hydra_adapter.h" @@ -77,7 +81,14 @@ void MaterialData::export_mtlx() module = PyImport_ImportModule("bpy_hydra"); dict = PyModule_GetDict(module); func = PyDict_GetItemString(dict, "export_mtlx"); - result = PyObject_CallFunction(func, "s", name().c_str()); + + PointerRNA materialptr; + RNA_pointer_create(NULL, &RNA_Material, id, &materialptr); + PyObject *material = pyrna_struct_CreatePyObject(&materialptr); + + result = PyObject_CallFunction(func, "O", material); + + Py_DECREF(material); std::string path; if (result) { -- 2.30.2