From f095e0683efac1ff969c63b77d6b6a564c21e54d Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Fri, 10 Feb 2023 17:01:45 +0300 Subject: [PATCH 01/11] BLEN-335: Export environment light --- source/blender/render/hydra/CMakeLists.txt | 3 + .../sceneDelegate/blenderSceneDelegate.cc | 74 +++++++++-- .../sceneDelegate/blenderSceneDelegate.h | 4 + .../render/hydra/sceneDelegate/world.cc | 116 ++++++++++++++++++ .../render/hydra/sceneDelegate/world.h | 51 ++++++++ 5 files changed, 240 insertions(+), 8 deletions(-) create mode 100644 source/blender/render/hydra/sceneDelegate/world.cc create mode 100644 source/blender/render/hydra/sceneDelegate/world.h diff --git a/source/blender/render/hydra/CMakeLists.txt b/source/blender/render/hydra/CMakeLists.txt index ff779fe5e1a5..d27c31872424 100644 --- a/source/blender/render/hydra/CMakeLists.txt +++ b/source/blender/render/hydra/CMakeLists.txt @@ -20,6 +20,7 @@ set(INC ../../../../intern/guardedalloc ../../makesdna ../../makesrna + ../../nodes ../../blenlib ../../depsgraph ../../blenkernel @@ -66,6 +67,8 @@ set(SRC sceneDelegate/scene.cc sceneDelegate/material.h sceneDelegate/material.cc + sceneDelegate/world.h + sceneDelegate/world.cc ) set(LIB diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc index 7fd1c829c768..a33ce2c721d4 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc @@ -50,10 +50,32 @@ void BlenderSceneDelegate::update_material(Material *material) } } +void BlenderSceneDelegate::add_world(View3DShading &view3DShading, World &world) +{ + SdfPath world_light_id = world_id(&view3DShading); + + LOG(INFO) << "Add world: " << world_light_id; + + if (world_data.shading != &view3DShading || world_data.world != &world) { + world_data = WorldData(&view3DShading, &world); + GetRenderIndex().InsertSprim(HdPrimTypeTokens->domeLight, this, world_light_id); + } + else { + world_data.update_world(); + GetRenderIndex().GetChangeTracker().MarkSprimDirty(world_light_id, HdLight::AllDirty); + } +} + bool BlenderSceneDelegate::GetVisible(SdfPath const &id) { ObjectData *obj_data = object_data(id); - LOG(INFO) << "GetVisible: " << id.GetAsString() << " " << obj_data->is_visible(); + LOG(INFO) << "GetVisible: " << id.GetAsString(); + + HdRenderIndex &index = GetRenderIndex(); + + if (index.GetSprim(HdPrimTypeTokens->domeLight, id)) { + return true; + } return obj_data->is_visible(); } @@ -207,6 +229,15 @@ SdfPath BlenderSceneDelegate::material_id(Material *material) return GetDelegateID().AppendElementString(str); } +SdfPath BlenderSceneDelegate::world_id(View3DShading *view3DShading) +{ + /* Making id of material in form like M_. Example: + * W_000002074e812088 */ + char str[32]; + snprintf(str, 32, "W_%016llx", (uint64_t)view3DShading); + return GetDelegateID().AppendElementString(str); +} + bool BlenderSceneDelegate::supported_object(Object *object) { return object->type == OB_MESH || @@ -229,6 +260,10 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, View3D *v3d) /* Export initial objects */ update_collection(); + World *world = (World *)b_depsgraph->scene().world().ptr.data; + + add_world(view3d->shading, *world); + is_populated = true; return; } @@ -277,6 +312,12 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, View3D *v3d) } continue; } + + if (id.is_a(&RNA_World)) { + World *world = (World *)b_depsgraph->scene().world().ptr.data; + add_world(view3d->shading, *world); + continue; + } } if (do_update_collection) { @@ -397,6 +438,12 @@ GfMatrix4d BlenderSceneDelegate::GetTransform(SdfPath const& id) { LOG(INFO) << "GetTransform: " << id.GetAsString(); + HdRenderIndex &index = GetRenderIndex(); + + if (index.GetSprim(HdPrimTypeTokens->domeLight, id)) { + return GfMatrix4d().SetIdentity(); + } + return objects[id].transform(); } @@ -404,14 +451,25 @@ VtValue BlenderSceneDelegate::GetLightParamValue(SdfPath const& id, TfToken cons { LOG(INFO) << "GetLightParamValue: " << id.GetAsString() << " [" << key.GetString() << "]"; VtValue ret; - ObjectData *obj_data = object_data(id); - if (obj_data) { - if (obj_data->has_data(key)) { - ret = obj_data->get_data(key); + + HdRenderIndex &index = GetRenderIndex(); + + if (index.GetSprim(HdPrimTypeTokens->domeLight, id)) { + if (world_data.has_data(key)) { + ret = world_data.get_data(key); } - else if (key == HdLightTokens->exposure) { - // TODO: temporary value, it should be delivered through Python UI - ret = 1.0f; + } + else { + + ObjectData *obj_data = object_data(id); + if (obj_data) { + if (obj_data->has_data(key)) { + ret = obj_data->get_data(key); + } + else if (key == HdLightTokens->exposure) { + // TODO: temporary value, it should be delivered through Python UI + ret = 1.0f; + } } } return ret; diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h index 77867f2f5c06..a24ef0531945 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h @@ -15,6 +15,7 @@ #include "RNA_blender_cpp.h" #include "object.h" +#include "world.h" using namespace pxr; @@ -49,6 +50,8 @@ private: void update_material(Material *material); void update_collection(); void update_visibility(); + void add_world(View3DShading &view3DShading, World &world); + SdfPath world_id(View3DShading *view3DShading); private: BL::Depsgraph *b_depsgraph; @@ -56,6 +59,7 @@ private: bool is_populated; ObjectDataMap objects; MaterialDataMap materials; + WorldData world_data; }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/world.cc b/source/blender/render/hydra/sceneDelegate/world.cc new file mode 100644 index 000000000000..d92b95564c01 --- /dev/null +++ b/source/blender/render/hydra/sceneDelegate/world.cc @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#include +#include +#include +#include +#include + +#include "DNA_node_types.h" + +#include "BKE_node.h" +#include "BKE_node_runtime.hh" +#include "NOD_shader.h" + +#include "world.h" + +/* TODO : add tftoken "transparency" and RPR specific? */ + +using namespace pxr; + +namespace blender::render::hydra { + +WorldData::WorldData() + : shading(nullptr), + world(nullptr) +{ +} + +WorldData::WorldData(View3DShading *shading, World *world) + : shading(shading), + world(world) +{ + set_as_world(); +} + +std::string WorldData::name() +{ + return ""; +} + +int WorldData::type() +{ + //return object->type; + return 0; +} + +TfToken WorldData::prim_type() +{ + return HdPrimTypeTokens->domeLight; +} + +GfMatrix4d WorldData::transform() +{ + return GfMatrix4d(); +} + +VtValue &WorldData::get_data(TfToken const &key) +{ + return data[key]; +} + +bool WorldData::has_data(TfToken const &key) +{ + return data.find(key) != data.end(); +} + +void WorldData::update_world() +{ + set_as_world(); +} + +void WorldData::set_as_world() +{ + if (world->use_nodes) { + + bNode *output_node = ntreeShaderOutputNode(world->nodetree, SHD_OUTPUT_ALL); + bNodeSocket input_socket = output_node->input_by_identifier("Surface"); + bNodeLink const *link = input_socket.directly_linked_links()[0]; + bNode *input_node = link->fromnode; + + bNodeSocket color_input = input_node->input_by_identifier("Color"); + bNodeSocket strength_input = input_node->input_by_identifier("Strength"); + + float const *color = color_input.default_value_typed(); + float const *strength = strength_input.default_value_typed(); + + data[HdLightTokens->intensity] = strength[1]; + data[HdLightTokens->exposure] = 1.0f; + data[HdLightTokens->color] = GfVec3f(color[0], color[1], color[2]); + + //blender::Span world_nodes = world->nodetree->nodes_by_type("ShaderNodeOutputWorld"); + } + else { + data[HdLightTokens->intensity] = 1.0f; + data[HdLightTokens->exposure] = world->exposure; + data[HdLightTokens->color] = GfVec3f( + world->horr, + world->horg, + world->horb + ); + } +} + +void WorldData::set_as_shading() +{ + data[HdLightTokens->intensity] = 1.0f; + data[HdLightTokens->exposure] = 1.0f; + data[HdLightTokens->color] = GfVec3f( + shading->single_color[0], + shading->single_color[1], + shading->single_color[2] + ); +} + +} // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/world.h b/source/blender/render/hydra/sceneDelegate/world.h new file mode 100644 index 000000000000..ec5e40cdaab2 --- /dev/null +++ b/source/blender/render/hydra/sceneDelegate/world.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#pragma once + +#include + +#include +#include +#include +#include "pxr/base/tf/staticTokens.h" + +#include "DNA_view3d_types.h" +#include "DNA_world_types.h" + +namespace blender::render::hydra { + +class WorldData { +public: + WorldData(); + WorldData(View3DShading *shading, World *world); + + std::string name(); + int type(); + pxr::TfToken prim_type(); + pxr::GfMatrix4d transform(); + + pxr::VtValue &get_data(pxr::TfToken const &key); + template + const T &get_data(pxr::TfToken const &key); + bool has_data(pxr::TfToken const &key); + void update_world(); + + View3DShading *shading; + World *world; + + private: + + std::map data; + + void set_as_world(); + void set_as_shading(); +}; + +template +const T &WorldData::get_data(pxr::TfToken const &key) +{ + return get_data(key).Get(); +} + +} // namespace blender::render::hydra -- 2.30.2 From 572de8eb34a50a6ce3754d28e0ccd348d752e14e Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Fri, 10 Feb 2023 19:48:49 +0300 Subject: [PATCH 02/11] fixed update added image setting --- .../sceneDelegate/blenderSceneDelegate.cc | 6 +++ .../render/hydra/sceneDelegate/world.cc | 54 +++++++++++++++++-- .../render/hydra/sceneDelegate/world.h | 2 + 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc index a33ce2c721d4..b7c824e53df5 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc @@ -318,6 +318,12 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, View3D *v3d) add_world(view3d->shading, *world); continue; } + + if (id.is_a(&RNA_ShaderNodeTree)) { + World *world = (World *)b_depsgraph->scene().world().ptr.data; + add_world(view3d->shading, *world); + continue; + } } if (do_update_collection) { diff --git a/source/blender/render/hydra/sceneDelegate/world.cc b/source/blender/render/hydra/sceneDelegate/world.cc index d92b95564c01..b379ff15f490 100644 --- a/source/blender/render/hydra/sceneDelegate/world.cc +++ b/source/blender/render/hydra/sceneDelegate/world.cc @@ -8,16 +8,18 @@ #include #include "DNA_node_types.h" - #include "BKE_node.h" #include "BKE_node_runtime.hh" +#include "BKE_image.h" #include "NOD_shader.h" +#include "BLI_path_util.h" #include "world.h" -/* TODO : add tftoken "transparency" and RPR specific? */ +/* TODO : add custom tftoken "transparency"? */ using namespace pxr; +using namespace std; namespace blender::render::hydra { @@ -72,6 +74,8 @@ void WorldData::update_world() void WorldData::set_as_world() { + data.clear(); + if (world->use_nodes) { bNode *output_node = ntreeShaderOutputNode(world->nodetree, SHD_OUTPUT_ALL); @@ -82,13 +86,21 @@ void WorldData::set_as_world() bNodeSocket color_input = input_node->input_by_identifier("Color"); bNodeSocket strength_input = input_node->input_by_identifier("Strength"); - float const *color = color_input.default_value_typed(); float const *strength = strength_input.default_value_typed(); - + float const *color = color_input.default_value_typed(); data[HdLightTokens->intensity] = strength[1]; data[HdLightTokens->exposure] = 1.0f; data[HdLightTokens->color] = GfVec3f(color[0], color[1], color[2]); + if (!color_input.directly_linked_links().is_empty()) { + bNode *color_input_node = color_input.directly_linked_links()[0]->fromnode; + if (color_input_node->type == SH_NODE_TEX_IMAGE) { + data[HdLightTokens->textureFile] = SdfAssetPath( + "C:\\Users\\user\\Desktop\\WUH6nAqWDDk.jpg", + "C:\\Users\\user\\Desktop\\WUH6nAqWDDk.jpg"); // get_image_filepath(color_input_node); + } + } + //blender::Span world_nodes = world->nodetree->nodes_by_type("ShaderNodeOutputWorld"); } else { @@ -113,4 +125,38 @@ void WorldData::set_as_shading() ); } +string WorldData::get_image_filepath(const bNode *tex_node) +{ + if (!tex_node) { + return ""; + } + Image *tex_image = reinterpret_cast(tex_node->id); + if (!tex_image || !BKE_image_has_filepath(tex_image)) { + return ""; + } + + if (BKE_image_has_packedfile(tex_image)) { + /* Put image in the same directory as the .MTL file. */ + const char *filename = BLI_path_slash_rfind(tex_image->filepath) + 1; + fprintf(stderr, + "Packed image found:'%s'. Unpack and place the image in the same " + "directory as the .MTL file.\n", + filename); + return filename; + } + + char path[FILE_MAX]; + BLI_strncpy(path, tex_image->filepath, FILE_MAX); + + if (tex_image->source == IMA_SRC_SEQUENCE) { + char head[FILE_MAX], tail[FILE_MAX]; + ushort numlen; + int framenr = static_cast(tex_node->storage)->iuser.framenr; + BLI_path_sequence_decode(path, head, tail, &numlen); + BLI_path_sequence_encode(path, head, tail, numlen, framenr); + } + + return path; +}; + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/world.h b/source/blender/render/hydra/sceneDelegate/world.h index ec5e40cdaab2..132641455bbf 100644 --- a/source/blender/render/hydra/sceneDelegate/world.h +++ b/source/blender/render/hydra/sceneDelegate/world.h @@ -6,6 +6,7 @@ #include #include +#include #include #include #include "pxr/base/tf/staticTokens.h" @@ -40,6 +41,7 @@ public: void set_as_world(); void set_as_shading(); + std::string get_image_filepath(const bNode *tex_node); }; template -- 2.30.2 From a9dbaa120746a08402255f7427010c72f6cf9d04 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Mon, 13 Feb 2023 12:43:30 +0300 Subject: [PATCH 03/11] refactoring --- .../hydra/sceneDelegate/blenderSceneDelegate.cc | 14 +++++++------- .../hydra/sceneDelegate/blenderSceneDelegate.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc index b7c824e53df5..5cba06e3e6a1 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc @@ -50,14 +50,14 @@ void BlenderSceneDelegate::update_material(Material *material) } } -void BlenderSceneDelegate::add_world(View3DShading &view3DShading, World &world) +void BlenderSceneDelegate::add_world(View3DShading *view3DShading, World *world) { - SdfPath world_light_id = world_id(&view3DShading); + SdfPath world_light_id = world_id(view3DShading); LOG(INFO) << "Add world: " << world_light_id; - if (world_data.shading != &view3DShading || world_data.world != &world) { - world_data = WorldData(&view3DShading, &world); + if (world_data.shading != view3DShading || world_data.world != world) { + world_data = WorldData(view3DShading, world); GetRenderIndex().InsertSprim(HdPrimTypeTokens->domeLight, this, world_light_id); } else { @@ -262,7 +262,7 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, View3D *v3d) World *world = (World *)b_depsgraph->scene().world().ptr.data; - add_world(view3d->shading, *world); + add_world(&view3d->shading, world); is_populated = true; return; @@ -315,13 +315,13 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, View3D *v3d) if (id.is_a(&RNA_World)) { World *world = (World *)b_depsgraph->scene().world().ptr.data; - add_world(view3d->shading, *world); + add_world(&view3d->shading, world); continue; } if (id.is_a(&RNA_ShaderNodeTree)) { World *world = (World *)b_depsgraph->scene().world().ptr.data; - add_world(view3d->shading, *world); + add_world(&view3d->shading, world); continue; } } diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h index a24ef0531945..0959fa678bcd 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h @@ -50,7 +50,7 @@ private: void update_material(Material *material); void update_collection(); void update_visibility(); - void add_world(View3DShading &view3DShading, World &world); + void add_world(View3DShading *view3DShading, World *world); SdfPath world_id(View3DShading *view3DShading); private: -- 2.30.2 From 64afaac703a83a66b43b34d384d50da5ad0f13e5 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Mon, 13 Feb 2023 16:44:14 +0300 Subject: [PATCH 04/11] implemented working image caching --- source/blender/render/hydra/finalEngine.cc | 2 +- .../sceneDelegate/blenderSceneDelegate.cc | 7 +- .../sceneDelegate/blenderSceneDelegate.h | 3 +- .../render/hydra/sceneDelegate/world.cc | 68 +++++++------------ .../render/hydra/sceneDelegate/world.h | 4 +- source/blender/render/hydra/viewportEngine.cc | 2 +- 6 files changed, 37 insertions(+), 49 deletions(-) diff --git a/source/blender/render/hydra/finalEngine.cc b/source/blender/render/hydra/finalEngine.cc index 081dbf79435c..96d30a058fc2 100644 --- a/source/blender/render/hydra/finalEngine.cc +++ b/source/blender/render/hydra/finalEngine.cc @@ -23,7 +23,7 @@ void FinalEngine::sync(BL::Depsgraph &b_depsgraph, BL::Context &b_context, pxr:: { sceneDelegate = std::make_unique(renderIndex.get(), SdfPath::AbsoluteRootPath().AppendElementString("scene")); - sceneDelegate->Populate(b_depsgraph); + sceneDelegate->Populate(b_depsgraph, b_context); for (auto const& setting : renderSettings) { renderDelegate->SetRenderSetting(setting.first, setting.second); diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc index 5cba06e3e6a1..2dd1273329dc 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc @@ -57,7 +57,7 @@ void BlenderSceneDelegate::add_world(View3DShading *view3DShading, World *world) LOG(INFO) << "Add world: " << world_light_id; if (world_data.shading != view3DShading || world_data.world != world) { - world_data = WorldData(view3DShading, world); + world_data = WorldData(view3DShading, world, b_context); GetRenderIndex().InsertSprim(HdPrimTypeTokens->domeLight, this, world_light_id); } else { @@ -249,12 +249,13 @@ bool BlenderSceneDelegate::supported_object(Object *object) object->type == OB_MBALL; } -void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, View3D *v3d) +void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, BL::Context &b_cont) { LOG(INFO) << "Populate " << is_populated; - view3d = v3d; + view3d = (View3D *)b_cont.space_data().ptr.data;; b_depsgraph = &b_deps; + b_context = &b_cont; if (!is_populated) { /* Export initial objects */ diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h index 0959fa678bcd..31ce5c41f0e2 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h @@ -26,7 +26,7 @@ public: BlenderSceneDelegate(HdRenderIndex* renderIndex, SdfPath const &delegateId); ~BlenderSceneDelegate() override = default; - void Populate(BL::Depsgraph &b_deps, View3D *v3d = nullptr); + void Populate(BL::Depsgraph &b_deps, BL::Context &b_context); // delegate methods HdMeshTopology GetMeshTopology(SdfPath const& id) override; @@ -55,6 +55,7 @@ private: private: BL::Depsgraph *b_depsgraph; + BL::Context *b_context; View3D *view3d; bool is_populated; ObjectDataMap objects; diff --git a/source/blender/render/hydra/sceneDelegate/world.cc b/source/blender/render/hydra/sceneDelegate/world.cc index b379ff15f490..4ce4ae119862 100644 --- a/source/blender/render/hydra/sceneDelegate/world.cc +++ b/source/blender/render/hydra/sceneDelegate/world.cc @@ -8,9 +8,12 @@ #include #include "DNA_node_types.h" +#include "DNA_windowmanager_types.h" +#include "BKE_context.h" #include "BKE_node.h" #include "BKE_node_runtime.hh" #include "BKE_image.h" +#include "BKE_image_save.h" #include "NOD_shader.h" #include "BLI_path_util.h" @@ -29,9 +32,10 @@ WorldData::WorldData() { } -WorldData::WorldData(View3DShading *shading, World *world) +WorldData::WorldData(View3DShading *shading, World *world, BL::Context *b_context) : shading(shading), - world(world) + world(world), + b_context(b_context) { set_as_world(); } @@ -95,13 +99,28 @@ void WorldData::set_as_world() if (!color_input.directly_linked_links().is_empty()) { bNode *color_input_node = color_input.directly_linked_links()[0]->fromnode; if (color_input_node->type == SH_NODE_TEX_IMAGE) { - data[HdLightTokens->textureFile] = SdfAssetPath( - "C:\\Users\\user\\Desktop\\WUH6nAqWDDk.jpg", - "C:\\Users\\user\\Desktop\\WUH6nAqWDDk.jpg"); // get_image_filepath(color_input_node); + NodeTexImage *tex = static_cast(color_input_node->storage); + Image *ima = (Image *)color_input_node->id; + ReportList reports; + ImageSaveOptions opts; + Main *bmain = CTX_data_main((bContext *)b_context->ptr.data); + if (BKE_image_save_options_init(&opts, + bmain, + (Scene *)b_context->scene().ptr.data, + ima, + &tex->iuser, + true, + false)) { + STRNCPY(opts.filepath, "C:\\Users\\user\\Downloads\\test\\123_false.png"); + opts.im_format.imtype = R_IMF_IMTYPE_TIFF; + BKE_image_save(&reports, bmain, ima, &tex->iuser, &opts); + + data[HdLightTokens->textureFile] = SdfAssetPath( + "C:\\Users\\user\\Desktop\\WUH6nAqWDDk.jpg", + "C:\\Users\\user\\Desktop\\WUH6nAqWDDk.jpg"); + } } } - - //blender::Span world_nodes = world->nodetree->nodes_by_type("ShaderNodeOutputWorld"); } else { data[HdLightTokens->intensity] = 1.0f; @@ -124,39 +143,4 @@ void WorldData::set_as_shading() shading->single_color[2] ); } - -string WorldData::get_image_filepath(const bNode *tex_node) -{ - if (!tex_node) { - return ""; - } - Image *tex_image = reinterpret_cast(tex_node->id); - if (!tex_image || !BKE_image_has_filepath(tex_image)) { - return ""; - } - - if (BKE_image_has_packedfile(tex_image)) { - /* Put image in the same directory as the .MTL file. */ - const char *filename = BLI_path_slash_rfind(tex_image->filepath) + 1; - fprintf(stderr, - "Packed image found:'%s'. Unpack and place the image in the same " - "directory as the .MTL file.\n", - filename); - return filename; - } - - char path[FILE_MAX]; - BLI_strncpy(path, tex_image->filepath, FILE_MAX); - - if (tex_image->source == IMA_SRC_SEQUENCE) { - char head[FILE_MAX], tail[FILE_MAX]; - ushort numlen; - int framenr = static_cast(tex_node->storage)->iuser.framenr; - BLI_path_sequence_decode(path, head, tail, &numlen); - BLI_path_sequence_encode(path, head, tail, numlen, framenr); - } - - return path; -}; - } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/world.h b/source/blender/render/hydra/sceneDelegate/world.h index 132641455bbf..48b86156ba84 100644 --- a/source/blender/render/hydra/sceneDelegate/world.h +++ b/source/blender/render/hydra/sceneDelegate/world.h @@ -13,13 +13,14 @@ #include "DNA_view3d_types.h" #include "DNA_world_types.h" +#include "RNA_blender_cpp.h" namespace blender::render::hydra { class WorldData { public: WorldData(); - WorldData(View3DShading *shading, World *world); + WorldData(View3DShading *shading, World *world, BL::Context *b_context); std::string name(); int type(); @@ -34,6 +35,7 @@ public: View3DShading *shading; World *world; + BL::Context *b_context; private: diff --git a/source/blender/render/hydra/viewportEngine.cc b/source/blender/render/hydra/viewportEngine.cc index 5a05513b0a30..b4d4039d67fe 100644 --- a/source/blender/render/hydra/viewportEngine.cc +++ b/source/blender/render/hydra/viewportEngine.cc @@ -545,7 +545,7 @@ void ViewportEngine::sync(BL::Depsgraph &b_depsgraph, BL::Context &b_context, px SdfPath::AbsoluteRootPath().AppendElementString("scene")); } View3D *view3d = (View3D *)b_context.space_data().ptr.data; - sceneDelegate->Populate(b_depsgraph, view3d); + sceneDelegate->Populate(b_depsgraph, b_context); for (auto const& setting : renderSettings) { renderDelegate->SetRenderSetting(setting.first, setting.second); -- 2.30.2 From ab425edc35299eb0c54f9261ec9f6771a44b394d Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Mon, 13 Feb 2023 19:31:24 +0300 Subject: [PATCH 05/11] fully functional-ed image caching --- .../sceneDelegate/blenderSceneDelegate.cc | 5 +- .../render/hydra/sceneDelegate/world.cc | 61 +++++++++++++------ 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc index 2dd1273329dc..21961b0c7992 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc @@ -56,7 +56,8 @@ void BlenderSceneDelegate::add_world(View3DShading *view3DShading, World *world) LOG(INFO) << "Add world: " << world_light_id; - if (world_data.shading != view3DShading || world_data.world != world) { + if (world_data.shading != view3DShading || world_data.world != world || + world_data.b_context != b_context) { world_data = WorldData(view3DShading, world, b_context); GetRenderIndex().InsertSprim(HdPrimTypeTokens->domeLight, this, world_light_id); } @@ -253,7 +254,7 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, BL::Context &b_cont) { LOG(INFO) << "Populate " << is_populated; - view3d = (View3D *)b_cont.space_data().ptr.data;; + view3d = (View3D *)b_cont.space_data().ptr.data; b_depsgraph = &b_deps; b_context = &b_cont; diff --git a/source/blender/render/hydra/sceneDelegate/world.cc b/source/blender/render/hydra/sceneDelegate/world.cc index 4ce4ae119862..01f93c5d1c44 100644 --- a/source/blender/render/hydra/sceneDelegate/world.cc +++ b/source/blender/render/hydra/sceneDelegate/world.cc @@ -1,19 +1,24 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ + +#include + #include #include #include #include #include +#include "BKE_context.h" #include "DNA_node_types.h" #include "DNA_windowmanager_types.h" -#include "BKE_context.h" + #include "BKE_node.h" #include "BKE_node_runtime.hh" #include "BKE_image.h" #include "BKE_image_save.h" +#include "BKE_appdir.h" #include "NOD_shader.h" #include "BLI_path_util.h" @@ -95,32 +100,52 @@ void WorldData::set_as_world() data[HdLightTokens->intensity] = strength[1]; data[HdLightTokens->exposure] = 1.0f; data[HdLightTokens->color] = GfVec3f(color[0], color[1], color[2]); - + PyGILState_STATE gilstate; + gilstate = PyGILState_Ensure(); if (!color_input.directly_linked_links().is_empty()) { bNode *color_input_node = color_input.directly_linked_links()[0]->fromnode; if (color_input_node->type == SH_NODE_TEX_IMAGE) { NodeTexImage *tex = static_cast(color_input_node->storage); Image *ima = (Image *)color_input_node->id; - ReportList reports; - ImageSaveOptions opts; - Main *bmain = CTX_data_main((bContext *)b_context->ptr.data); - if (BKE_image_save_options_init(&opts, - bmain, - (Scene *)b_context->scene().ptr.data, - ima, - &tex->iuser, - true, - false)) { - STRNCPY(opts.filepath, "C:\\Users\\user\\Downloads\\test\\123_false.png"); - opts.im_format.imtype = R_IMF_IMTYPE_TIFF; - BKE_image_save(&reports, bmain, ima, &tex->iuser, &opts); + if (ima) { + ReportList reports; + ImageSaveOptions opts; + Main *bmain = CTX_data_main((bContext *)b_context->ptr.data); + if (BKE_image_save_options_init(&opts, + bmain, + CTX_data_scene((bContext *)b_context->ptr.data), + ima, + &tex->iuser, + false, + false)) { + char tempfile[FILE_MAX]; + string image_name; - data[HdLightTokens->textureFile] = SdfAssetPath( - "C:\\Users\\user\\Desktop\\WUH6nAqWDDk.jpg", - "C:\\Users\\user\\Desktop\\WUH6nAqWDDk.jpg"); + if (ima->source == IMA_SRC_GENERATED) { + image_name = strcat((ima->id.name + 2), ".png"); + } + else { + image_name = ima->filepath == NULL ? + std::filesystem::path(ima->filepath).filename().string() : + ima->id.name + 2; + } + + BLI_path_join(tempfile, + sizeof(tempfile), + BKE_tempdir_session(), + image_name.c_str()); + STRNCPY(opts.filepath, tempfile); + opts.im_format.imtype = R_IMF_IMTYPE_PNG; + + if (BKE_image_save(&reports, bmain, ima, &tex->iuser, &opts)) { + data[HdLightTokens->textureFile] = SdfAssetPath(tempfile, tempfile); + } + BKE_image_save_options_free(&opts); + } } } } + PyGILState_Release(gilstate); } else { data[HdLightTokens->intensity] = 1.0f; -- 2.30.2 From acc23adaafb151ebb66ef365f82d3a28da433a65 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Tue, 14 Feb 2023 13:39:22 +0300 Subject: [PATCH 06/11] fix image renaming --- source/blender/render/hydra/sceneDelegate/world.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/blender/render/hydra/sceneDelegate/world.cc b/source/blender/render/hydra/sceneDelegate/world.cc index 01f93c5d1c44..8fe8b3f4c7bd 100644 --- a/source/blender/render/hydra/sceneDelegate/world.cc +++ b/source/blender/render/hydra/sceneDelegate/world.cc @@ -100,17 +100,18 @@ void WorldData::set_as_world() data[HdLightTokens->intensity] = strength[1]; data[HdLightTokens->exposure] = 1.0f; data[HdLightTokens->color] = GfVec3f(color[0], color[1], color[2]); - PyGILState_STATE gilstate; - gilstate = PyGILState_Ensure(); + if (!color_input.directly_linked_links().is_empty()) { bNode *color_input_node = color_input.directly_linked_links()[0]->fromnode; if (color_input_node->type == SH_NODE_TEX_IMAGE) { NodeTexImage *tex = static_cast(color_input_node->storage); Image *ima = (Image *)color_input_node->id; + if (ima) { ReportList reports; ImageSaveOptions opts; Main *bmain = CTX_data_main((bContext *)b_context->ptr.data); + if (BKE_image_save_options_init(&opts, bmain, CTX_data_scene((bContext *)b_context->ptr.data), @@ -122,7 +123,7 @@ void WorldData::set_as_world() string image_name; if (ima->source == IMA_SRC_GENERATED) { - image_name = strcat((ima->id.name + 2), ".png"); + image_name.append(ima->id.name + 2).append(".png"); } else { image_name = ima->filepath == NULL ? @@ -136,7 +137,8 @@ void WorldData::set_as_world() image_name.c_str()); STRNCPY(opts.filepath, tempfile); opts.im_format.imtype = R_IMF_IMTYPE_PNG; - + opts.save_copy = true; + if (BKE_image_save(&reports, bmain, ima, &tex->iuser, &opts)) { data[HdLightTokens->textureFile] = SdfAssetPath(tempfile, tempfile); } @@ -145,7 +147,6 @@ void WorldData::set_as_world() } } } - PyGILState_Release(gilstate); } else { data[HdLightTokens->intensity] = 1.0f; -- 2.30.2 From 3a348ff5c3f70ad1c3afde83acad0329890b16e1 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Tue, 14 Feb 2023 17:09:07 +0300 Subject: [PATCH 07/11] move image caching to utils.h fixed domelight transform for HdRPR --- .../sceneDelegate/blenderSceneDelegate.cc | 12 +++- .../render/hydra/sceneDelegate/world.cc | 63 ++++++------------ .../render/hydra/sceneDelegate/world.h | 6 +- source/blender/render/hydra/utils.cc | 65 ++++++++++++++++--- source/blender/render/hydra/utils.h | 9 +++ 5 files changed, 98 insertions(+), 57 deletions(-) diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc index 21961b0c7992..5ab96b68c82a 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc @@ -3,8 +3,10 @@ #include #include +#include #include #include +#include #include "glog/logging.h" @@ -449,7 +451,15 @@ GfMatrix4d BlenderSceneDelegate::GetTransform(SdfPath const& id) HdRenderIndex &index = GetRenderIndex(); if (index.GetSprim(HdPrimTypeTokens->domeLight, id)) { - return GfMatrix4d().SetIdentity(); + GfMatrix4d transform = world_data.transform(); + if (world_data.has_data(UsdLuxTokens->orientToStageUpAxis)) { + transform *= GfMatrix4d(GfRotation(GfVec3d(1.0, 0.0, 0.0), -90), GfVec3d()); + } + if (index.GetRenderDelegate()->GetRendererDisplayName() == "RPR") { + transform *= GfMatrix4d(GfRotation(GfVec3d(1.0, 0.0, 0.0), -180), GfVec3d()); + transform *= GfMatrix4d(GfRotation(GfVec3d(0.0, 0.0, 1.0), 90.0), GfVec3d()); + } + return transform; } return objects[id].transform(); diff --git a/source/blender/render/hydra/sceneDelegate/world.cc b/source/blender/render/hydra/sceneDelegate/world.cc index 8fe8b3f4c7bd..ef3b1663d3cf 100644 --- a/source/blender/render/hydra/sceneDelegate/world.cc +++ b/source/blender/render/hydra/sceneDelegate/world.cc @@ -17,12 +17,10 @@ #include "BKE_node.h" #include "BKE_node_runtime.hh" #include "BKE_image.h" -#include "BKE_image_save.h" -#include "BKE_appdir.h" #include "NOD_shader.h" -#include "BLI_path_util.h" #include "world.h" +#include "../utils.h" /* TODO : add custom tftoken "transparency"? */ @@ -32,15 +30,16 @@ using namespace std; namespace blender::render::hydra { WorldData::WorldData() - : shading(nullptr), - world(nullptr) + : b_context(nullptr), + shading(nullptr), + world(nullptr) { } WorldData::WorldData(View3DShading *shading, World *world, BL::Context *b_context) - : shading(shading), - world(world), - b_context(b_context) + : b_context(b_context), + shading(shading), + world(world) { set_as_world(); } @@ -63,7 +62,7 @@ TfToken WorldData::prim_type() GfMatrix4d WorldData::transform() { - return GfMatrix4d(); + return GfMatrix4d().SetIdentity(); } VtValue &WorldData::get_data(TfToken const &key) @@ -85,8 +84,9 @@ void WorldData::set_as_world() { data.clear(); - if (world->use_nodes) { + data[UsdLuxTokens->orientToStageUpAxis] = true; + if (world->use_nodes) { bNode *output_node = ntreeShaderOutputNode(world->nodetree, SHD_OUTPUT_ALL); bNodeSocket input_socket = output_node->input_by_identifier("Surface"); bNodeLink const *link = input_socket.directly_linked_links()[0]; @@ -105,44 +105,19 @@ void WorldData::set_as_world() bNode *color_input_node = color_input.directly_linked_links()[0]->fromnode; if (color_input_node->type == SH_NODE_TEX_IMAGE) { NodeTexImage *tex = static_cast(color_input_node->storage); - Image *ima = (Image *)color_input_node->id; + Image *image = (Image *)color_input_node->id; + + if (image) { + Main *bmain = CTX_data_main((bContext *)b_context->ptr.data); + Scene *scene = CTX_data_scene((bContext *)b_context->ptr.data); - if (ima) { ReportList reports; ImageSaveOptions opts; - Main *bmain = CTX_data_main((bContext *)b_context->ptr.data); + opts.im_format.imtype = R_IMF_IMTYPE_PNG; - if (BKE_image_save_options_init(&opts, - bmain, - CTX_data_scene((bContext *)b_context->ptr.data), - ima, - &tex->iuser, - false, - false)) { - char tempfile[FILE_MAX]; - string image_name; - - if (ima->source == IMA_SRC_GENERATED) { - image_name.append(ima->id.name + 2).append(".png"); - } - else { - image_name = ima->filepath == NULL ? - std::filesystem::path(ima->filepath).filename().string() : - ima->id.name + 2; - } - - BLI_path_join(tempfile, - sizeof(tempfile), - BKE_tempdir_session(), - image_name.c_str()); - STRNCPY(opts.filepath, tempfile); - opts.im_format.imtype = R_IMF_IMTYPE_PNG; - opts.save_copy = true; - - if (BKE_image_save(&reports, bmain, ima, &tex->iuser, &opts)) { - data[HdLightTokens->textureFile] = SdfAssetPath(tempfile, tempfile); - } - BKE_image_save_options_free(&opts); + string cached_image_path = cache_image(bmain, scene, image, &tex->iuser, &opts, &reports); + if (!cached_image_path.empty()) { + data[HdLightTokens->textureFile] = SdfAssetPath(cached_image_path, cached_image_path); } } } diff --git a/source/blender/render/hydra/sceneDelegate/world.h b/source/blender/render/hydra/sceneDelegate/world.h index 48b86156ba84..3e56fa99aafc 100644 --- a/source/blender/render/hydra/sceneDelegate/world.h +++ b/source/blender/render/hydra/sceneDelegate/world.h @@ -33,17 +33,15 @@ public: bool has_data(pxr::TfToken const &key); void update_world(); + BL::Context *b_context; View3DShading *shading; World *world; - BL::Context *b_context; - - private: + private: std::map data; void set_as_world(); void set_as_shading(); - std::string get_image_filepath(const bNode *tex_node); }; template diff --git a/source/blender/render/hydra/utils.cc b/source/blender/render/hydra/utils.cc index c46a461737e6..060faa94fc3e 100644 --- a/source/blender/render/hydra/utils.cc +++ b/source/blender/render/hydra/utils.cc @@ -2,9 +2,18 @@ * Copyright 2011-2022 Blender Foundation */ #include +#include + +#include + +#include "BKE_appdir.h" +#include "BKE_image_save.h" +#include "BLI_string.h" +#include "BLI_path_util.h" #include "utils.h" +using namespace pxr; using namespace std; namespace blender::render::hydra { @@ -14,23 +23,63 @@ string formatDuration(chrono::milliseconds millisecs) stringstream ss; bool neg = millisecs < 0ms; if (neg) - millisecs = -millisecs; + millisecs = -millisecs; auto m = chrono::duration_cast(millisecs); millisecs -= m; auto s = chrono::duration_cast(millisecs); millisecs -= s; if (neg) - ss << "-"; + ss << "-"; if (m < 10min) - ss << "0"; + ss << "0"; ss << to_string(m / 1min) << ":"; if (s < 10s) - ss << "0"; - ss << to_string(s/1s) << ":"; + ss << "0"; + ss << to_string(s / 1s) << ":"; if (millisecs < 10ms) - ss << "0"; - ss << to_string(millisecs/1ms/10); + ss << "0"; + ss << to_string(millisecs / 1ms / 10); return ss.str(); } -} // namespace blender::render::hydra +string cache_image(Main *bmain, + Scene *scene, + Image *image, + ImageUser *iuser, + ImageSaveOptions *opts, + ReportList *reports) +{ + const string default_format = ".png"; + + char tempfile[FILE_MAX]; + + if (!BKE_image_save_options_init(opts, bmain, scene, image, iuser, true, false)) { + BKE_image_save_options_free(opts); + return ""; + } + + string image_name; + + if (image->source == IMA_SRC_GENERATED) { + image_name = TfMakeValidIdentifier(image_name.append(image->id.name + 2)); + } + else { + image_name = image->filepath == NULL ? image->filepath : image->id.name + 2; + image_name = std::filesystem::path(image_name).filename().replace_extension().string(); + image_name = TfMakeValidIdentifier(image_name); + } + + image_name.append(default_format); + + BLI_path_join(tempfile, sizeof(tempfile), BKE_tempdir_session(), image_name.c_str()); + STRNCPY(opts->filepath, tempfile); + + if (BKE_image_save(reports, bmain, image, iuser, opts)) { + BKE_image_save_options_free(opts); + return tempfile; + }; + + BKE_image_save_options_free(opts); + return ""; +} +} // namespace blender::render::hydra diff --git a/source/blender/render/hydra/utils.h b/source/blender/render/hydra/utils.h index da1d932718a9..5bdfb90a52b2 100644 --- a/source/blender/render/hydra/utils.h +++ b/source/blender/render/hydra/utils.h @@ -6,8 +6,17 @@ #include #include +#include "BKE_image.h" +#include "BKE_image_save.h" + namespace blender::render::hydra { std::string formatDuration(std::chrono::milliseconds secs); +std::string cache_image(Main *bmain, + Scene *scene, + Image *image, + ImageUser *iuser, + ImageSaveOptions *opts, + ReportList *reports); } // namespace blender::render::hydra -- 2.30.2 From c811af052d6d0e5e94c54a49770f792fe3472ab3 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Tue, 14 Feb 2023 17:48:12 +0300 Subject: [PATCH 08/11] added is_visible() --- .../render/hydra/sceneDelegate/blenderSceneDelegate.cc | 2 +- source/blender/render/hydra/sceneDelegate/world.cc | 5 +++++ source/blender/render/hydra/sceneDelegate/world.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc index 5ab96b68c82a..119d2b2e8593 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc @@ -77,7 +77,7 @@ bool BlenderSceneDelegate::GetVisible(SdfPath const &id) HdRenderIndex &index = GetRenderIndex(); if (index.GetSprim(HdPrimTypeTokens->domeLight, id)) { - return true; + return world_data.is_visible(); } return obj_data->is_visible(); diff --git a/source/blender/render/hydra/sceneDelegate/world.cc b/source/blender/render/hydra/sceneDelegate/world.cc index ef3b1663d3cf..0729acc4d144 100644 --- a/source/blender/render/hydra/sceneDelegate/world.cc +++ b/source/blender/render/hydra/sceneDelegate/world.cc @@ -80,6 +80,11 @@ void WorldData::update_world() set_as_world(); } +bool WorldData::is_visible() +{ + return true; +} + void WorldData::set_as_world() { data.clear(); diff --git a/source/blender/render/hydra/sceneDelegate/world.h b/source/blender/render/hydra/sceneDelegate/world.h index 3e56fa99aafc..7f88919b0ae3 100644 --- a/source/blender/render/hydra/sceneDelegate/world.h +++ b/source/blender/render/hydra/sceneDelegate/world.h @@ -32,6 +32,7 @@ public: const T &get_data(pxr::TfToken const &key); bool has_data(pxr::TfToken const &key); void update_world(); + bool is_visible(); BL::Context *b_context; View3DShading *shading; -- 2.30.2 From 4bb870a306c38e499861e5b46f91fc191a5bb6a2 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Tue, 14 Feb 2023 18:08:33 +0300 Subject: [PATCH 09/11] refactoring --- .../render/hydra/sceneDelegate/blenderSceneDelegate.cc | 7 +++---- .../render/hydra/sceneDelegate/blenderSceneDelegate.h | 4 ++-- source/blender/render/hydra/sceneDelegate/world.cc | 6 +++++- source/blender/render/hydra/utils.cc | 3 ++- source/blender/render/hydra/viewportEngine.cc | 1 - 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc index 119d2b2e8593..ad8e6bef83d8 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc @@ -54,7 +54,7 @@ void BlenderSceneDelegate::update_material(Material *material) void BlenderSceneDelegate::add_world(View3DShading *view3DShading, World *world) { - SdfPath world_light_id = world_id(view3DShading); + SdfPath world_light_id = world_id(b_context); LOG(INFO) << "Add world: " << world_light_id; @@ -232,12 +232,12 @@ SdfPath BlenderSceneDelegate::material_id(Material *material) return GetDelegateID().AppendElementString(str); } -SdfPath BlenderSceneDelegate::world_id(View3DShading *view3DShading) +SdfPath BlenderSceneDelegate::world_id(BL::Context *b_context) { /* Making id of material in form like M_. Example: * W_000002074e812088 */ char str[32]; - snprintf(str, 32, "W_%016llx", (uint64_t)view3DShading); + snprintf(str, 32, "W_%016llx", (uint64_t)b_context); return GetDelegateID().AppendElementString(str); } @@ -265,7 +265,6 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, BL::Context &b_cont) update_collection(); World *world = (World *)b_depsgraph->scene().world().ptr.data; - add_world(&view3d->shading, world); is_populated = true; diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h index 31ce5c41f0e2..9b7069edf150 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h @@ -43,15 +43,15 @@ private: MaterialData *material_data(SdfPath const &id); SdfPath object_id(Object *object); SdfPath material_id(Material *material); + SdfPath world_id(BL::Context *b_context); bool supported_object(Object *object); void add_update_object(Object *object, bool geometry, bool transform, bool shading); void set_material(ObjectData &obj_data); void update_material(Material *material); + void add_world(View3DShading *view3DShading, World *world); void update_collection(); void update_visibility(); - void add_world(View3DShading *view3DShading, World *world); - SdfPath world_id(View3DShading *view3DShading); private: BL::Depsgraph *b_depsgraph; diff --git a/source/blender/render/hydra/sceneDelegate/world.cc b/source/blender/render/hydra/sceneDelegate/world.cc index 0729acc4d144..aeac16041e5f 100644 --- a/source/blender/render/hydra/sceneDelegate/world.cc +++ b/source/blender/render/hydra/sceneDelegate/world.cc @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ - #include #include @@ -95,6 +94,10 @@ void WorldData::set_as_world() bNode *output_node = ntreeShaderOutputNode(world->nodetree, SHD_OUTPUT_ALL); bNodeSocket input_socket = output_node->input_by_identifier("Surface"); bNodeLink const *link = input_socket.directly_linked_links()[0]; + if (!link) { + return; + } + bNode *input_node = link->fromnode; bNodeSocket color_input = input_node->input_by_identifier("Color"); @@ -149,4 +152,5 @@ void WorldData::set_as_shading() shading->single_color[2] ); } + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/utils.cc b/source/blender/render/hydra/utils.cc index 060faa94fc3e..dd6a335174a8 100644 --- a/source/blender/render/hydra/utils.cc +++ b/source/blender/render/hydra/utils.cc @@ -81,5 +81,6 @@ string cache_image(Main *bmain, BKE_image_save_options_free(opts); return ""; -} +} + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/viewportEngine.cc b/source/blender/render/hydra/viewportEngine.cc index b4d4039d67fe..52f50c125ea7 100644 --- a/source/blender/render/hydra/viewportEngine.cc +++ b/source/blender/render/hydra/viewportEngine.cc @@ -544,7 +544,6 @@ void ViewportEngine::sync(BL::Depsgraph &b_depsgraph, BL::Context &b_context, px sceneDelegate = std::make_unique(renderIndex.get(), SdfPath::AbsoluteRootPath().AppendElementString("scene")); } - View3D *view3d = (View3D *)b_context.space_data().ptr.data; sceneDelegate->Populate(b_depsgraph, b_context); for (auto const& setting : renderSettings) { -- 2.30.2 From 6b3e6a83ce1e07c0409dc1077fdcf715f2ebac68 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Thu, 16 Feb 2023 15:06:41 +0300 Subject: [PATCH 10/11] refactoring, fix review comments --- .../sceneDelegate/blenderSceneDelegate.cc | 71 ++++++-------- .../sceneDelegate/blenderSceneDelegate.h | 6 +- .../render/hydra/sceneDelegate/world.cc | 97 +++++++------------ .../render/hydra/sceneDelegate/world.h | 14 +-- 4 files changed, 71 insertions(+), 117 deletions(-) diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc index ad8e6bef83d8..70d7c7323db7 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc @@ -6,18 +6,20 @@ #include #include #include -#include #include "glog/logging.h" #include "blenderSceneDelegate.h" #include "object.h" +using namespace std; + namespace blender::render::hydra { BlenderSceneDelegate::BlenderSceneDelegate(HdRenderIndex* parentIndex, SdfPath const& delegateID) : HdSceneDelegate(parentIndex, delegateID), b_depsgraph(nullptr), + b_context(nullptr), view3d(nullptr), is_populated(false) { @@ -52,21 +54,22 @@ void BlenderSceneDelegate::update_material(Material *material) } } -void BlenderSceneDelegate::add_world(View3DShading *view3DShading, World *world) +void BlenderSceneDelegate::add_update_world(World *world) { - SdfPath world_light_id = world_id(b_context); + SdfPath world_light_id = world_id(); LOG(INFO) << "Add world: " << world_light_id; - if (world_data.shading != view3DShading || world_data.world != world || - world_data.b_context != b_context) { - world_data = WorldData(view3DShading, world, b_context); - GetRenderIndex().InsertSprim(HdPrimTypeTokens->domeLight, this, world_light_id); - } - else { - world_data.update_world(); - GetRenderIndex().GetChangeTracker().MarkSprimDirty(world_light_id, HdLight::AllDirty); + if (!world) { + world_data.reset(); + GetRenderIndex().RemoveSprim(HdPrimTypeTokens->domeLight, world_light_id); + + return; } + + world_data = make_unique(world, (bContext *)b_context->ptr.data); + GetRenderIndex().InsertSprim(HdPrimTypeTokens->domeLight, this, world_light_id); + GetRenderIndex().GetChangeTracker().MarkSprimDirty(world_light_id, HdLight::AllDirty); } bool BlenderSceneDelegate::GetVisible(SdfPath const &id) @@ -76,8 +79,8 @@ bool BlenderSceneDelegate::GetVisible(SdfPath const &id) HdRenderIndex &index = GetRenderIndex(); - if (index.GetSprim(HdPrimTypeTokens->domeLight, id)) { - return world_data.is_visible(); + if (id == world_id()) { + return world_data->is_visible(); } return obj_data->is_visible(); @@ -232,13 +235,9 @@ SdfPath BlenderSceneDelegate::material_id(Material *material) return GetDelegateID().AppendElementString(str); } -SdfPath BlenderSceneDelegate::world_id(BL::Context *b_context) +SdfPath BlenderSceneDelegate::world_id() { - /* Making id of material in form like M_. Example: - * W_000002074e812088 */ - char str[32]; - snprintf(str, 32, "W_%016llx", (uint64_t)b_context); - return GetDelegateID().AppendElementString(str); + return GetDelegateID().AppendElementString("World"); } bool BlenderSceneDelegate::supported_object(Object *object) @@ -265,7 +264,7 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, BL::Context &b_cont) update_collection(); World *world = (World *)b_depsgraph->scene().world().ptr.data; - add_world(&view3d->shading, world); + add_update_world(world); is_populated = true; return; @@ -310,6 +309,8 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, BL::Context &b_cont) } if (id.is_a(&RNA_Scene)) { + World *world = (World *)b_depsgraph->scene().world().ptr.data; + add_update_world(world); if (!update.is_updated_geometry() && !update.is_updated_transform() && !update.is_updated_shading()) { do_update_visibility = true; } @@ -318,13 +319,13 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, BL::Context &b_cont) if (id.is_a(&RNA_World)) { World *world = (World *)b_depsgraph->scene().world().ptr.data; - add_world(&view3d->shading, world); + add_update_world(world); continue; } if (id.is_a(&RNA_ShaderNodeTree)) { World *world = (World *)b_depsgraph->scene().world().ptr.data; - add_world(&view3d->shading, world); + add_update_world(world); continue; } } @@ -449,16 +450,8 @@ GfMatrix4d BlenderSceneDelegate::GetTransform(SdfPath const& id) HdRenderIndex &index = GetRenderIndex(); - if (index.GetSprim(HdPrimTypeTokens->domeLight, id)) { - GfMatrix4d transform = world_data.transform(); - if (world_data.has_data(UsdLuxTokens->orientToStageUpAxis)) { - transform *= GfMatrix4d(GfRotation(GfVec3d(1.0, 0.0, 0.0), -90), GfVec3d()); - } - if (index.GetRenderDelegate()->GetRendererDisplayName() == "RPR") { - transform *= GfMatrix4d(GfRotation(GfVec3d(1.0, 0.0, 0.0), -180), GfVec3d()); - transform *= GfMatrix4d(GfRotation(GfVec3d(0.0, 0.0, 1.0), 90.0), GfVec3d()); - } - return transform; + if (id == world_id()) { + return world_data->transform(index.GetRenderDelegate()->GetRendererDisplayName()); } return objects[id].transform(); @@ -471,13 +464,7 @@ VtValue BlenderSceneDelegate::GetLightParamValue(SdfPath const& id, TfToken cons HdRenderIndex &index = GetRenderIndex(); - if (index.GetSprim(HdPrimTypeTokens->domeLight, id)) { - if (world_data.has_data(key)) { - ret = world_data.get_data(key); - } - } - else { - + if (index.HasRprim(id)) { ObjectData *obj_data = object_data(id); if (obj_data) { if (obj_data->has_data(key)) { @@ -489,6 +476,12 @@ VtValue BlenderSceneDelegate::GetLightParamValue(SdfPath const& id, TfToken cons } } } + else if (id == world_id()) { + if (world_data->has_data(key)) { + ret = world_data->get_data(key); + } + } + return ret; } diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h index 9b7069edf150..ea244055be46 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h @@ -43,13 +43,13 @@ private: MaterialData *material_data(SdfPath const &id); SdfPath object_id(Object *object); SdfPath material_id(Material *material); - SdfPath world_id(BL::Context *b_context); + SdfPath world_id(); bool supported_object(Object *object); void add_update_object(Object *object, bool geometry, bool transform, bool shading); void set_material(ObjectData &obj_data); void update_material(Material *material); - void add_world(View3DShading *view3DShading, World *world); + void add_update_world(World *world); void update_collection(); void update_visibility(); @@ -60,7 +60,7 @@ private: bool is_populated; ObjectDataMap objects; MaterialDataMap materials; - WorldData world_data; + std::unique_ptr world_data; }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/world.cc b/source/blender/render/hydra/sceneDelegate/world.cc index aeac16041e5f..3c2981192a0e 100644 --- a/source/blender/render/hydra/sceneDelegate/world.cc +++ b/source/blender/render/hydra/sceneDelegate/world.cc @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -30,61 +31,13 @@ namespace blender::render::hydra { WorldData::WorldData() : b_context(nullptr), - shading(nullptr), world(nullptr) { } -WorldData::WorldData(View3DShading *shading, World *world, BL::Context *b_context) +WorldData::WorldData(World *world, bContext *b_context) : b_context(b_context), - shading(shading), world(world) -{ - set_as_world(); -} - -std::string WorldData::name() -{ - return ""; -} - -int WorldData::type() -{ - //return object->type; - return 0; -} - -TfToken WorldData::prim_type() -{ - return HdPrimTypeTokens->domeLight; -} - -GfMatrix4d WorldData::transform() -{ - return GfMatrix4d().SetIdentity(); -} - -VtValue &WorldData::get_data(TfToken const &key) -{ - return data[key]; -} - -bool WorldData::has_data(TfToken const &key) -{ - return data.find(key) != data.end(); -} - -void WorldData::update_world() -{ - set_as_world(); -} - -bool WorldData::is_visible() -{ - return true; -} - -void WorldData::set_as_world() { data.clear(); @@ -116,8 +69,8 @@ void WorldData::set_as_world() Image *image = (Image *)color_input_node->id; if (image) { - Main *bmain = CTX_data_main((bContext *)b_context->ptr.data); - Scene *scene = CTX_data_scene((bContext *)b_context->ptr.data); + Main *bmain = CTX_data_main(b_context); + Scene *scene = CTX_data_scene(b_context); ReportList reports; ImageSaveOptions opts; @@ -134,23 +87,39 @@ void WorldData::set_as_world() else { data[HdLightTokens->intensity] = 1.0f; data[HdLightTokens->exposure] = world->exposure; - data[HdLightTokens->color] = GfVec3f( - world->horr, - world->horg, - world->horb - ); + data[HdLightTokens->color] = GfVec3f(world->horr, world->horg, world->horb); } } -void WorldData::set_as_shading() +GfMatrix4d WorldData::transform(string renderer_name) { - data[HdLightTokens->intensity] = 1.0f; - data[HdLightTokens->exposure] = 1.0f; - data[HdLightTokens->color] = GfVec3f( - shading->single_color[0], - shading->single_color[1], - shading->single_color[2] - ); + GfMatrix4d transform = GfMatrix4d().SetIdentity(); + + if (has_data(UsdLuxTokens->orientToStageUpAxis)) { + transform *= GfMatrix4d(GfRotation(GfVec3d(1.0, 0.0, 0.0), -90), GfVec3d()); + } + /* TODO : do this check via RenderSettings*/ + if (renderer_name == "RPR") { + transform *= GfMatrix4d(GfRotation(GfVec3d(1.0, 0.0, 0.0), -180), GfVec3d()); + transform *= GfMatrix4d(GfRotation(GfVec3d(0.0, 0.0, 1.0), 90.0), GfVec3d()); + } + + return transform; +} + +VtValue &WorldData::get_data(TfToken const &key) +{ + return data[key]; +} + +bool WorldData::has_data(TfToken const &key) +{ + return data.find(key) != data.end(); +} + +bool WorldData::is_visible() +{ + return true; } } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/world.h b/source/blender/render/hydra/sceneDelegate/world.h index 7f88919b0ae3..a49c4f958efe 100644 --- a/source/blender/render/hydra/sceneDelegate/world.h +++ b/source/blender/render/hydra/sceneDelegate/world.h @@ -13,36 +13,28 @@ #include "DNA_view3d_types.h" #include "DNA_world_types.h" -#include "RNA_blender_cpp.h" namespace blender::render::hydra { class WorldData { public: WorldData(); - WorldData(View3DShading *shading, World *world, BL::Context *b_context); + WorldData(World *world, bContext *b_context); - std::string name(); - int type(); pxr::TfToken prim_type(); - pxr::GfMatrix4d transform(); + pxr::GfMatrix4d transform(std::string renderer_name); pxr::VtValue &get_data(pxr::TfToken const &key); template const T &get_data(pxr::TfToken const &key); bool has_data(pxr::TfToken const &key); - void update_world(); bool is_visible(); - BL::Context *b_context; - View3DShading *shading; + bContext *b_context; World *world; private: std::map data; - - void set_as_world(); - void set_as_shading(); }; template -- 2.30.2 From 2a3828de4108e0797e1b3837752c1bdd45354815 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Fri, 17 Feb 2023 14:00:54 +0300 Subject: [PATCH 11/11] fix review comments --- .../sceneDelegate/blenderSceneDelegate.cc | 32 ++++++++++--------- .../render/hydra/sceneDelegate/world.cc | 4 +-- .../render/hydra/sceneDelegate/world.h | 2 +- source/blender/render/hydra/utils.cc | 22 +++++++------ 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc index 70d7c7323db7..d1668b8c9bac 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc @@ -61,15 +61,19 @@ void BlenderSceneDelegate::add_update_world(World *world) LOG(INFO) << "Add world: " << world_light_id; if (!world) { - world_data.reset(); + world_data = nullptr; GetRenderIndex().RemoveSprim(HdPrimTypeTokens->domeLight, world_light_id); - return; } - world_data = make_unique(world, (bContext *)b_context->ptr.data); - GetRenderIndex().InsertSprim(HdPrimTypeTokens->domeLight, this, world_light_id); - GetRenderIndex().GetChangeTracker().MarkSprimDirty(world_light_id, HdLight::AllDirty); + if (!world_data) { + world_data = make_unique(world, (bContext *)b_context->ptr.data); + GetRenderIndex().InsertSprim(HdPrimTypeTokens->domeLight, this, world_light_id); + } + else { + world_data = make_unique(world, (bContext *)b_context->ptr.data); + GetRenderIndex().GetChangeTracker().MarkSprimDirty(world_light_id, HdLight::AllDirty); + } } bool BlenderSceneDelegate::GetVisible(SdfPath const &id) @@ -464,16 +468,14 @@ VtValue BlenderSceneDelegate::GetLightParamValue(SdfPath const& id, TfToken cons HdRenderIndex &index = GetRenderIndex(); - if (index.HasRprim(id)) { - ObjectData *obj_data = object_data(id); - if (obj_data) { - if (obj_data->has_data(key)) { - ret = obj_data->get_data(key); - } - else if (key == HdLightTokens->exposure) { - // TODO: temporary value, it should be delivered through Python UI - ret = 1.0f; - } + ObjectData *obj_data = object_data(id); + if (obj_data) { + if (obj_data->has_data(key)) { + ret = obj_data->get_data(key); + } + else if (key == HdLightTokens->exposure) { + // TODO: temporary value, it should be delivered through Python UI + ret = 1.0f; } } else if (id == world_id()) { diff --git a/source/blender/render/hydra/sceneDelegate/world.cc b/source/blender/render/hydra/sceneDelegate/world.cc index 3c2981192a0e..2accd814d821 100644 --- a/source/blender/render/hydra/sceneDelegate/world.cc +++ b/source/blender/render/hydra/sceneDelegate/world.cc @@ -47,7 +47,7 @@ WorldData::WorldData(World *world, bContext *b_context) bNode *output_node = ntreeShaderOutputNode(world->nodetree, SHD_OUTPUT_ALL); bNodeSocket input_socket = output_node->input_by_identifier("Surface"); bNodeLink const *link = input_socket.directly_linked_links()[0]; - if (!link) { + if (input_socket.directly_linked_links().is_empty()) { return; } @@ -91,7 +91,7 @@ WorldData::WorldData(World *world, bContext *b_context) } } -GfMatrix4d WorldData::transform(string renderer_name) +GfMatrix4d WorldData::transform(string const &renderer_name) { GfMatrix4d transform = GfMatrix4d().SetIdentity(); diff --git a/source/blender/render/hydra/sceneDelegate/world.h b/source/blender/render/hydra/sceneDelegate/world.h index a49c4f958efe..b61d5b4824a0 100644 --- a/source/blender/render/hydra/sceneDelegate/world.h +++ b/source/blender/render/hydra/sceneDelegate/world.h @@ -22,7 +22,7 @@ public: WorldData(World *world, bContext *b_context); pxr::TfToken prim_type(); - pxr::GfMatrix4d transform(std::string renderer_name); + pxr::GfMatrix4d transform(std::string const &renderer_name); pxr::VtValue &get_data(pxr::TfToken const &key); template diff --git a/source/blender/render/hydra/utils.cc b/source/blender/render/hydra/utils.cc index 881c68398ed9..37ad5807a418 100644 --- a/source/blender/render/hydra/utils.cc +++ b/source/blender/render/hydra/utils.cc @@ -15,7 +15,6 @@ #include "utils.h" -using namespace pxr; using namespace std; using namespace pxr; @@ -34,22 +33,27 @@ string format_duration(chrono::milliseconds millisecs) { stringstream ss; bool neg = millisecs < 0ms; - if (neg) + if (neg) { millisecs = -millisecs; + } auto m = chrono::duration_cast(millisecs); millisecs -= m; auto s = chrono::duration_cast(millisecs); millisecs -= s; - if (neg) + if (neg) { ss << "-"; - if (m < 10min) + } + if (m < 10min) { ss << "0"; + } ss << to_string(m / 1min) << ":"; - if (s < 10s) + if (s < 10s) { ss << "0"; + } ss << to_string(s / 1s) << ":"; - if (millisecs < 10ms) + if (millisecs < 10ms) { ss << "0"; + } ss << to_string(millisecs / 1ms / 10); return ss.str(); } @@ -86,13 +90,13 @@ string cache_image(Main *bmain, BLI_path_join(tempfile, sizeof(tempfile), BKE_tempdir_session(), image_name.c_str()); STRNCPY(opts->filepath, tempfile); - if (BKE_image_save(reports, bmain, image, iuser, opts)) { + if (!BKE_image_save(reports, bmain, image, iuser, opts)) { BKE_image_save_options_free(opts); - return tempfile; + return ""; }; BKE_image_save_options_free(opts); - return ""; + return tempfile; } } // namespace blender::render::hydra -- 2.30.2