forked from blender/blender
Add possibility to render USD file for testing purposes #49
@ -1,62 +1,21 @@
|
|||||||
/* SPDX-License-Identifier: Apache-2.0
|
/* SPDX-License-Identifier: Apache-2.0
|
||||||
* Copyright 2011-2022 Blender Foundation */
|
* Copyright 2011-2022 Blender Foundation */
|
||||||
|
|
||||||
#include "DEG_depsgraph_query.h"
|
|
||||||
|
|
||||||
#include "BLI_timer.h"
|
|
||||||
#include "camera.h"
|
|
||||||
#include "preview_engine.h"
|
#include "preview_engine.h"
|
||||||
|
|
||||||
namespace blender::render::hydra {
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
const double LIFETIME = 180.0;
|
|
||||||
|
|
||||||
std::unique_ptr<PreviewEngine> PreviewEngine::instance_;
|
|
||||||
|
|
||||||
PreviewEngine *PreviewEngine::create(RenderEngine *bl_engine,
|
|
||||||
const std::string &render_delegate_name)
|
|
||||||
{
|
|
||||||
if (!instance_) {
|
|
||||||
instance_ = std::make_unique<PreviewEngine>(bl_engine, render_delegate_name);
|
|
||||||
}
|
|
||||||
else if (instance_->render_delegate_name != render_delegate_name) {
|
|
||||||
instance_->render_delegate_->Stop();
|
|
||||||
instance_ = std::make_unique<PreviewEngine>(bl_engine, render_delegate_name);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
instance_->bl_engine_ = bl_engine;
|
|
||||||
}
|
|
||||||
|
|
||||||
instance_->scene_delegate_->clear();
|
|
||||||
|
|
||||||
if (BLI_timer_is_registered((uintptr_t)&instance_)) {
|
|
||||||
/* Unregister timer while PreviewEngine is working */
|
|
||||||
BLI_timer_unregister((uintptr_t)&instance_);
|
|
||||||
}
|
|
||||||
|
|
||||||
return instance_.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PreviewEngine::free()
|
|
||||||
{
|
|
||||||
instance_->render_delegate_->Stop();
|
|
||||||
|
|
||||||
/* Register timer for schedule free PreviewEngine instance */
|
|
||||||
BLI_timer_register((uintptr_t)&instance_, free_instance, nullptr, nullptr, LIFETIME, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PreviewEngine::render(Depsgraph *depsgraph)
|
void PreviewEngine::render(Depsgraph *depsgraph)
|
||||||
{
|
{
|
||||||
prepare_for_render(depsgraph);
|
prepare_for_render(depsgraph);
|
||||||
|
|
||||||
std::vector<float> &pixels = render_images_["Combined"];
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Release the GIL before calling into hydra, in case any hydra plugins call into python. */
|
/* Release the GIL before calling into hydra, in case any hydra plugins call into python. */
|
||||||
pxr::TF_PY_ALLOW_THREADS_IN_SCOPE();
|
pxr::TF_PY_ALLOW_THREADS_IN_SCOPE();
|
||||||
engine_->Execute(render_index_.get(), &tasks_);
|
engine_->Execute(render_index_.get(), &tasks_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<float> &pixels = render_images_["Combined"];
|
||||||
while (true) {
|
while (true) {
|
||||||
if (RE_engine_test_break(bl_engine_)) {
|
if (RE_engine_test_break(bl_engine_)) {
|
||||||
break;
|
break;
|
||||||
@ -74,18 +33,6 @@ void PreviewEngine::render(Depsgraph *depsgraph)
|
|||||||
update_render_result(pixels);
|
update_render_result(pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
double PreviewEngine::free_instance(uintptr_t uuid, void *user_data)
|
|
||||||
{
|
|
||||||
if (!instance_->render_task_delegate_->is_converged()) {
|
|
||||||
/* Restart timer if render isn't completed */
|
|
||||||
return LIFETIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA, 2, "");
|
|
||||||
instance_ = nullptr;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PreviewEngine::update_render_result(std::vector<float> &pixels)
|
void PreviewEngine::update_render_result(std::vector<float> &pixels)
|
||||||
{
|
{
|
||||||
RenderResult *result = RE_engine_begin_result(
|
RenderResult *result = RE_engine_begin_result(
|
||||||
|
@ -9,19 +9,12 @@ namespace blender::render::hydra {
|
|||||||
|
|
||||||
class PreviewEngine : public FinalEngine {
|
class PreviewEngine : public FinalEngine {
|
||||||
public:
|
public:
|
||||||
static PreviewEngine *create(RenderEngine *bl_engine, const std::string &render_delegate_name);
|
using FinalEngine::FinalEngine;
|
||||||
static void free();
|
|
||||||
|
|
||||||
void render(Depsgraph *depsgraph) override;
|
void render(Depsgraph *depsgraph) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using FinalEngine::FinalEngine;
|
|
||||||
static double free_instance(uintptr_t uuid, void *user_data);
|
|
||||||
|
|
||||||
void update_render_result(std::vector<float> &pixels);
|
void update_render_result(std::vector<float> &pixels);
|
||||||
|
|
||||||
/* Singleton class instance */
|
|
||||||
static std::unique_ptr<PreviewEngine> instance_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
@ -114,7 +114,7 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args)
|
|||||||
engine = new ViewportEngine(bl_engine, render_delegate_id);
|
engine = new ViewportEngine(bl_engine, render_delegate_id);
|
||||||
}
|
}
|
||||||
else if (STREQ(engine_type, "PREVIEW")) {
|
else if (STREQ(engine_type, "PREVIEW")) {
|
||||||
engine = PreviewEngine::create(bl_engine, render_delegate_id);
|
engine = new PreviewEngine(bl_engine, render_delegate_id);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) {
|
if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) {
|
||||||
@ -137,13 +137,7 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine);
|
Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine);
|
||||||
PreviewEngine *preview_engine = dynamic_cast<PreviewEngine *>(engine);
|
delete engine;
|
||||||
if (preview_engine) {
|
|
||||||
PreviewEngine::free();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
delete engine;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA, 2, "Engine %016llx", engine);
|
CLOG_INFO(LOG_RENDER_HYDRA, 2, "Engine %016llx", engine);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -211,14 +211,14 @@ void BlenderSceneDelegate::populate(Depsgraph *deps, bContext *cont)
|
|||||||
|
|
||||||
void BlenderSceneDelegate::clear()
|
void BlenderSceneDelegate::clear()
|
||||||
{
|
{
|
||||||
for (auto &it : objects_) {
|
for (auto &obj_data : objects_.values()) {
|
||||||
it.second->remove();
|
obj_data->remove();
|
||||||
}
|
}
|
||||||
for (auto &it : instancers_) {
|
for (auto &i_data : instancers_.values()) {
|
||||||
it.second->remove();
|
i_data->remove();
|
||||||
}
|
}
|
||||||
for (auto &it : materials_) {
|
for (auto &mat_data : materials_.values()) {
|
||||||
it.second->remove();
|
mat_data->remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
objects_.clear();
|
objects_.clear();
|
||||||
@ -269,9 +269,9 @@ pxr::SdfPath BlenderSceneDelegate::world_prim_id() const
|
|||||||
ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) const
|
ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) const
|
||||||
{
|
{
|
||||||
pxr::SdfPath p_id = (id.GetName().find("SM_") == 0) ? id.GetParentPath() : id;
|
pxr::SdfPath p_id = (id.GetName().find("SM_") == 0) ? id.GetParentPath() : id;
|
||||||
auto it = objects_.find(p_id);
|
auto obj_data = objects_.lookup_ptr(p_id);
|
||||||
if (it != objects_.end()) {
|
if (obj_data) {
|
||||||
return it->second.get();
|
return obj_data->get();
|
||||||
}
|
}
|
||||||
InstancerData *i_data = instancer_data(p_id, true);
|
InstancerData *i_data = instancer_data(p_id, true);
|
||||||
if (i_data) {
|
if (i_data) {
|
||||||
@ -297,11 +297,11 @@ LightData *BlenderSceneDelegate::light_data(pxr::SdfPath const &id) const
|
|||||||
|
|
||||||
MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) const
|
MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) const
|
||||||
{
|
{
|
||||||
auto it = materials_.find(id);
|
auto mat_data = materials_.lookup_ptr(id);
|
||||||
if (it == materials_.end()) {
|
if (!mat_data) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return it->second.get();
|
return mat_data->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id, bool child_id) const
|
InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id, bool child_id) const
|
||||||
@ -322,9 +322,9 @@ InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id, bool
|
|||||||
p_id = id;
|
p_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = instancers_.find(p_id);
|
auto i_data = instancers_.lookup_ptr(p_id);
|
||||||
if (it != instancers_.end()) {
|
if (i_data) {
|
||||||
return it->second.get();
|
return i_data->get();
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -349,7 +349,7 @@ void BlenderSceneDelegate::update_objects(Object *object)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
objects_[id] = ObjectData::create(this, object, id);
|
objects_.add_new(id, ObjectData::create(this, object, id));
|
||||||
obj_data = object_data(id);
|
obj_data = object_data(id);
|
||||||
obj_data->update_parent();
|
obj_data->update_parent();
|
||||||
obj_data->init();
|
obj_data->init();
|
||||||
@ -359,8 +359,8 @@ void BlenderSceneDelegate::update_objects(Object *object)
|
|||||||
void BlenderSceneDelegate::update_instancers(Object *object)
|
void BlenderSceneDelegate::update_instancers(Object *object)
|
||||||
{
|
{
|
||||||
/* Check object inside instancers */
|
/* Check object inside instancers */
|
||||||
for (auto &it : instancers_) {
|
for (auto &i_data : instancers_.values()) {
|
||||||
it.second->check_update(object);
|
i_data->check_update(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxr::SdfPath id = instancer_prim_id(object);
|
pxr::SdfPath id = instancer_prim_id(object);
|
||||||
@ -369,7 +369,7 @@ void BlenderSceneDelegate::update_instancers(Object *object)
|
|||||||
if ((object->transflag & OB_DUPLI) == 0) {
|
if ((object->transflag & OB_DUPLI) == 0) {
|
||||||
/* Object isn't instancer anymore and should be removed */
|
/* Object isn't instancer anymore and should be removed */
|
||||||
i_data->remove();
|
i_data->remove();
|
||||||
instancers_.erase(id);
|
instancers_.remove(id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,8 +386,7 @@ void BlenderSceneDelegate::update_instancers(Object *object)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
instancers_[id] = std::make_unique<InstancerData>(this, object, id);
|
i_data = instancers_.lookup_or_add(id, std::make_unique<InstancerData>(this, object, id)).get();
|
||||||
i_data = instancer_data(id);
|
|
||||||
i_data->init();
|
i_data->init();
|
||||||
i_data->insert();
|
i_data->insert();
|
||||||
}
|
}
|
||||||
@ -524,7 +523,7 @@ void BlenderSceneDelegate::add_new_objects()
|
|||||||
void BlenderSceneDelegate::remove_unused_objects()
|
void BlenderSceneDelegate::remove_unused_objects()
|
||||||
{
|
{
|
||||||
/* Get available objects */
|
/* Get available objects */
|
||||||
std::set<std::string> available_objects;
|
Set<std::string> available_objects;
|
||||||
|
|
||||||
DEGObjectIterSettings settings = {0};
|
DEGObjectIterSettings settings = {0};
|
||||||
settings.depsgraph = depsgraph;
|
settings.depsgraph = depsgraph;
|
||||||
@ -542,67 +541,66 @@ void BlenderSceneDelegate::remove_unused_objects()
|
|||||||
object)
|
object)
|
||||||
{
|
{
|
||||||
if (ObjectData::is_supported(object)) {
|
if (ObjectData::is_supported(object)) {
|
||||||
available_objects.insert(object_prim_id(object).GetName());
|
available_objects.add(object_prim_id(object).GetName());
|
||||||
}
|
}
|
||||||
available_objects.insert(instancer_prim_id(object).GetName());
|
available_objects.add(instancer_prim_id(object).GetName());
|
||||||
}
|
}
|
||||||
ITER_END;
|
ITER_END;
|
||||||
|
|
||||||
/* Remove unused instancers */
|
/* Remove unused instancers */
|
||||||
for (auto it = instancers_.begin(); it != instancers_.end(); ++it) {
|
instancers_.remove_if([&](auto item) {
|
||||||
if (available_objects.find(it->first.GetName()) != available_objects.end()) {
|
bool ret = !available_objects.contains(item.key.GetName());
|
||||||
/* Remove objects from instancers */
|
if (ret) {
|
||||||
it->second->check_remove(available_objects);
|
item.value->remove();
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
it->second->remove();
|
else {
|
||||||
instancers_.erase(it);
|
item.value->check_remove(available_objects);
|
||||||
it = instancers_.begin();
|
}
|
||||||
}
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
/* Remove unused objects */
|
/* Remove unused objects */
|
||||||
for (auto it = objects_.begin(); it != objects_.end(); ++it) {
|
objects_.remove_if([&](auto item) {
|
||||||
if (available_objects.find(it->first.GetName()) != available_objects.end()) {
|
bool ret = !available_objects.contains(item.key.GetName());
|
||||||
continue;
|
if (ret) {
|
||||||
|
item.value->remove();
|
||||||
}
|
}
|
||||||
it->second->remove();
|
return ret;
|
||||||
objects_.erase(it);
|
});
|
||||||
it = objects_.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove unused materials */
|
/* Remove unused materials */
|
||||||
std::set<pxr::SdfPath> available_materials;
|
Set<pxr::SdfPath> available_materials;
|
||||||
for (auto &it : objects_) {
|
for (auto &val : objects_.values()) {
|
||||||
MeshData *m_data = dynamic_cast<MeshData *>(it.second.get());
|
MeshData *m_data = dynamic_cast<MeshData *>(val.get());
|
||||||
if (m_data) {
|
if (m_data) {
|
||||||
m_data->available_materials(available_materials);
|
m_data->available_materials(available_materials);
|
||||||
}
|
}
|
||||||
CurvesData *c_data = dynamic_cast<CurvesData *>(it.second.get());
|
CurvesData *c_data = dynamic_cast<CurvesData *>(val.get());
|
||||||
if (c_data) {
|
if (c_data) {
|
||||||
c_data->available_materials(available_materials);
|
c_data->available_materials(available_materials);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto &it : instancers_) {
|
for (auto &val : instancers_.values()) {
|
||||||
it.second->available_materials(available_materials);
|
val->available_materials(available_materials);
|
||||||
}
|
}
|
||||||
for (auto it = materials_.begin(); it != materials_.end(); ++it) {
|
|
||||||
if (available_materials.find(it->first) != available_materials.end()) {
|
materials_.remove_if([&](auto item) {
|
||||||
continue;
|
bool ret = !available_materials.contains(item.key);
|
||||||
|
if (ret) {
|
||||||
|
item.value->remove();
|
||||||
}
|
}
|
||||||
it->second->remove();
|
return ret;
|
||||||
materials_.erase(it);
|
});
|
||||||
it = materials_.begin();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlenderSceneDelegate::update_visibility()
|
void BlenderSceneDelegate::update_visibility()
|
||||||
{
|
{
|
||||||
/* Updating visibility of existing objects/instancers */
|
/* Updating visibility of existing objects/instancers */
|
||||||
for (auto &it : objects_) {
|
for (auto &val : objects_.values()) {
|
||||||
it.second->update_visibility();
|
val->update_visibility();
|
||||||
}
|
}
|
||||||
for (auto &it : instancers_) {
|
for (auto &val : instancers_.values()) {
|
||||||
it.second->update_visibility();
|
val->update_visibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add objects/instancers which were invisible before and not added yet */
|
/* Add objects/instancers which were invisible before and not added yet */
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "CLG_log.h"
|
#include "CLG_log.h"
|
||||||
|
|
||||||
|
#include "BLI_set.hh"
|
||||||
#include "curves.h"
|
#include "curves.h"
|
||||||
#include "instancer.h"
|
#include "instancer.h"
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
|
@ -134,10 +134,10 @@ pxr::SdfPath CurvesData::material_id() const
|
|||||||
return mat_data_->prim_id;
|
return mat_data_->prim_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CurvesData::available_materials(std::set<pxr::SdfPath> &paths) const
|
void CurvesData::available_materials(Set<pxr::SdfPath> &paths) const
|
||||||
{
|
{
|
||||||
if (mat_data_ && !mat_data_->prim_id.IsEmpty()) {
|
if (mat_data_ && !mat_data_->prim_id.IsEmpty()) {
|
||||||
paths.insert(mat_data_->prim_id);
|
paths.add(mat_data_->prim_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +199,8 @@ void CurvesData::write_material()
|
|||||||
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
|
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
|
||||||
mat_data_ = scene_delegate_->material_data(p_id);
|
mat_data_ = scene_delegate_->material_data(p_id);
|
||||||
if (!mat_data_) {
|
if (!mat_data_) {
|
||||||
scene_delegate_->materials_[p_id] = std::make_unique<MaterialData>(scene_delegate_, mat, p_id);
|
scene_delegate_->materials_.add_new(
|
||||||
|
p_id, std::make_unique<MaterialData>(scene_delegate_, mat, p_id));
|
||||||
mat_data_ = scene_delegate_->material_data(p_id);
|
mat_data_ = scene_delegate_->material_data(p_id);
|
||||||
mat_data_->init();
|
mat_data_->init();
|
||||||
mat_data_->insert();
|
mat_data_->insert();
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "BKE_duplilist.h"
|
#include "BKE_duplilist.h"
|
||||||
#include "DNA_Curves_types.h"
|
#include "DNA_Curves_types.h"
|
||||||
|
|
||||||
|
#include "BLI_set.hh"
|
||||||
#include "material.h"
|
#include "material.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ class CurvesData : public ObjectData {
|
|||||||
pxr::HdBasisCurvesTopology curves_topology(pxr::SdfPath const &id) const;
|
pxr::HdBasisCurvesTopology curves_topology(pxr::SdfPath const &id) const;
|
||||||
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
|
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
|
||||||
pxr::SdfPath material_id() const;
|
pxr::SdfPath material_id() const;
|
||||||
void available_materials(std::set<pxr::SdfPath> &paths) const;
|
void available_materials(Set<pxr::SdfPath> &paths) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void write_curves(Curves *curves);
|
void write_curves(Curves *curves);
|
||||||
|
@ -7,8 +7,16 @@
|
|||||||
#include <pxr/base/vt/value.h>
|
#include <pxr/base/vt/value.h>
|
||||||
#include <pxr/usd/sdf/path.h>
|
#include <pxr/usd/sdf/path.h>
|
||||||
|
|
||||||
|
#include "BLI_hash.hh"
|
||||||
#include "DNA_ID.h"
|
#include "DNA_ID.h"
|
||||||
|
|
||||||
|
template<> struct blender::DefaultHash<pxr::SdfPath> {
|
||||||
|
uint64_t operator()(const pxr::SdfPath &value) const
|
||||||
|
{
|
||||||
|
return pxr::SdfPath::Hash()(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
namespace blender::render::hydra {
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
class BlenderSceneDelegate;
|
class BlenderSceneDelegate;
|
||||||
|
@ -74,14 +74,14 @@ void InstancerData::insert()
|
|||||||
void InstancerData::remove()
|
void InstancerData::remove()
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
|
||||||
for (auto &it : mesh_instances_) {
|
for (auto &m_inst : mesh_instances_.values()) {
|
||||||
it.second.data->remove();
|
m_inst.data->remove();
|
||||||
}
|
}
|
||||||
scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id);
|
scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id);
|
||||||
|
|
||||||
for (auto &it : light_instances_) {
|
for (auto &l_inst : light_instances_.values()) {
|
||||||
it.second.transforms.clear();
|
l_inst.transforms.clear();
|
||||||
update_light_instance(it.second);
|
update_light_instance(l_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,17 +118,17 @@ bool InstancerData::update_visibility()
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
auto &change_tracker = scene_delegate_->GetRenderIndex().GetChangeTracker();
|
auto &change_tracker = scene_delegate_->GetRenderIndex().GetChangeTracker();
|
||||||
change_tracker.MarkInstancerDirty(prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
change_tracker.MarkInstancerDirty(prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
||||||
for (auto &it : mesh_instances_) {
|
for (auto &m_inst : mesh_instances_.values()) {
|
||||||
it.second.data->visible = visible;
|
m_inst.data->visible = visible;
|
||||||
for (auto &p : it.second.data->submesh_paths()) {
|
for (auto &p : m_inst.data->submesh_paths()) {
|
||||||
change_tracker.MarkRprimDirty(p, pxr::HdChangeTracker::DirtyVisibility);
|
change_tracker.MarkRprimDirty(p, pxr::HdChangeTracker::DirtyVisibility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char name[16];
|
char name[16];
|
||||||
for (auto &it : light_instances_) {
|
for (auto &l_inst : light_instances_.values()) {
|
||||||
for (int i = 0; i < it.second.count; ++i) {
|
for (int i = 0; i < l_inst.count; ++i) {
|
||||||
snprintf(name, 16, "L_%08x", i);
|
snprintf(name, 16, "L_%08x", i);
|
||||||
change_tracker.MarkRprimDirty(it.second.data->prim_id.AppendElementString(name),
|
change_tracker.MarkRprimDirty(l_inst.data->prim_id.AppendElementString(name),
|
||||||
pxr::HdChangeTracker::DirtyVisibility);
|
pxr::HdChangeTracker::DirtyVisibility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,8 +179,8 @@ ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const
|
|||||||
pxr::SdfPathVector InstancerData::prototypes() const
|
pxr::SdfPathVector InstancerData::prototypes() const
|
||||||
{
|
{
|
||||||
pxr::SdfPathVector paths;
|
pxr::SdfPathVector paths;
|
||||||
for (auto &it : mesh_instances_) {
|
for (auto &m_inst : mesh_instances_.values()) {
|
||||||
for (auto &p : it.second.data->submesh_paths()) {
|
for (auto &p : m_inst.data->submesh_paths()) {
|
||||||
paths.push_back(p);
|
paths.push_back(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +194,7 @@ void InstancerData::check_update(Object *object)
|
|||||||
if (m_inst) {
|
if (m_inst) {
|
||||||
if (!is_instance_visible(object)) {
|
if (!is_instance_visible(object)) {
|
||||||
m_inst->data->remove();
|
m_inst->data->remove();
|
||||||
mesh_instances_.erase(path);
|
mesh_instances_.remove(path);
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||||
prim_id, pxr::HdChangeTracker::AllDirty);
|
prim_id, pxr::HdChangeTracker::AllDirty);
|
||||||
return;
|
return;
|
||||||
@ -215,7 +215,7 @@ void InstancerData::check_update(Object *object)
|
|||||||
if (!is_instance_visible(object)) {
|
if (!is_instance_visible(object)) {
|
||||||
l_inst->transforms.clear();
|
l_inst->transforms.clear();
|
||||||
update_light_instance(*l_inst);
|
update_light_instance(*l_inst);
|
||||||
light_instances_.erase(path);
|
light_instances_.remove(path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +243,7 @@ void InstancerData::check_update(Object *object)
|
|||||||
|
|
||||||
if (do_write_instances) {
|
if (do_write_instances) {
|
||||||
write_instances();
|
write_instances();
|
||||||
if (!mesh_instances_.empty()) {
|
if (!mesh_instances_.is_empty()) {
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||||
prim_id, pxr::HdChangeTracker::AllDirty);
|
prim_id, pxr::HdChangeTracker::AllDirty);
|
||||||
}
|
}
|
||||||
@ -251,40 +251,39 @@ void InstancerData::check_update(Object *object)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstancerData::check_remove(std::set<std::string> &available_objects)
|
void InstancerData::check_remove(Set<std::string> &available_objects)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
for (auto it = mesh_instances_.begin(); it != mesh_instances_.end(); ++it) {
|
|
||||||
if (available_objects.find(it->first.GetName()) != available_objects.end()) {
|
mesh_instances_.remove_if([&](auto item) {
|
||||||
continue;
|
bool res = !available_objects.contains(item.key.GetName());
|
||||||
}
|
if (res) {
|
||||||
it->second.data->remove();
|
item.value.data->remove();
|
||||||
mesh_instances_.erase(it);
|
ret = true;
|
||||||
it = mesh_instances_.begin();
|
};
|
||||||
ret = true;
|
return res;
|
||||||
}
|
});
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
write_instances();
|
write_instances();
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||||
prim_id, pxr::HdChangeTracker::AllDirty);
|
prim_id, pxr::HdChangeTracker::AllDirty);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it = light_instances_.begin(); it != light_instances_.end(); ++it) {
|
light_instances_.remove_if([&](auto item) {
|
||||||
if (available_objects.find(it->first.GetName()) != available_objects.end()) {
|
bool res = !available_objects.contains(item.key.GetName());
|
||||||
continue;
|
if (res) {
|
||||||
}
|
item.value.transforms.clear();
|
||||||
it->second.transforms.clear();
|
update_light_instance(item.value);
|
||||||
update_light_instance(it->second);
|
};
|
||||||
|
return res;
|
||||||
light_instances_.erase(it);
|
});
|
||||||
it = light_instances_.begin();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstancerData::available_materials(std::set<pxr::SdfPath> &paths) const
|
void InstancerData::available_materials(Set<pxr::SdfPath> &paths) const
|
||||||
{
|
{
|
||||||
for (auto &it : mesh_instances_) {
|
for (auto &m_inst : mesh_instances_.values()) {
|
||||||
((MeshData *)it.second.data.get())->available_materials(paths);
|
((MeshData *)m_inst.data.get())->available_materials(paths);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,8 +296,8 @@ void InstancerData::update_as_parent()
|
|||||||
|
|
||||||
void InstancerData::update_double_sided(MaterialData *mat_data)
|
void InstancerData::update_double_sided(MaterialData *mat_data)
|
||||||
{
|
{
|
||||||
for (auto &it : mesh_instances_) {
|
for (auto &m_inst : mesh_instances_.values()) {
|
||||||
it.second.data->update_double_sided(mat_data);
|
m_inst.data->update_double_sided(mat_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,11 +342,11 @@ int InstancerData::light_prim_id_index(pxr::SdfPath const &id) const
|
|||||||
void InstancerData::write_instances()
|
void InstancerData::write_instances()
|
||||||
{
|
{
|
||||||
mesh_transforms_.clear();
|
mesh_transforms_.clear();
|
||||||
for (auto &it : mesh_instances_) {
|
for (auto &m_inst : mesh_instances_.values()) {
|
||||||
it.second.indices.clear();
|
m_inst.indices.clear();
|
||||||
}
|
}
|
||||||
for (auto &it : light_instances_) {
|
for (auto &l_inst : light_instances_.values()) {
|
||||||
it.second.transforms.clear();
|
l_inst.transforms.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBase *lb = object_duplilist(
|
ListBase *lb = object_duplilist(
|
||||||
@ -362,7 +361,7 @@ void InstancerData::write_instances()
|
|||||||
if (ob->type == OB_LAMP) {
|
if (ob->type == OB_LAMP) {
|
||||||
LightInstance *inst = light_instance(p_id);
|
LightInstance *inst = light_instance(p_id);
|
||||||
if (!inst) {
|
if (!inst) {
|
||||||
inst = &light_instances_[p_id];
|
inst = &light_instances_.lookup_or_add_default(p_id);
|
||||||
inst->data = std::make_unique<LightData>(scene_delegate_, ob, p_id);
|
inst->data = std::make_unique<LightData>(scene_delegate_, ob, p_id);
|
||||||
inst->data->init();
|
inst->data->init();
|
||||||
}
|
}
|
||||||
@ -372,7 +371,7 @@ void InstancerData::write_instances()
|
|||||||
else {
|
else {
|
||||||
MeshInstance *inst = mesh_instance(p_id);
|
MeshInstance *inst = mesh_instance(p_id);
|
||||||
if (!inst) {
|
if (!inst) {
|
||||||
inst = &mesh_instances_[p_id];
|
inst = &mesh_instances_.lookup_or_add_default(p_id);
|
||||||
inst->data = std::make_unique<MeshData>(scene_delegate_, ob, p_id);
|
inst->data = std::make_unique<MeshData>(scene_delegate_, ob, p_id);
|
||||||
inst->data->init();
|
inst->data->init();
|
||||||
inst->data->insert();
|
inst->data->insert();
|
||||||
@ -385,23 +384,19 @@ void InstancerData::write_instances()
|
|||||||
free_object_duplilist(lb);
|
free_object_duplilist(lb);
|
||||||
|
|
||||||
/* Remove mesh intances without indices */
|
/* Remove mesh intances without indices */
|
||||||
for (auto it = mesh_instances_.begin(); it != mesh_instances_.end(); ++it) {
|
mesh_instances_.remove_if([&](auto item) {
|
||||||
if (!it->second.indices.empty()) {
|
bool res = item.value.indices.empty();
|
||||||
continue;
|
if (res) {
|
||||||
|
item.value.data->remove();
|
||||||
}
|
}
|
||||||
it->second.data->remove();
|
return res;
|
||||||
mesh_instances_.erase(it);
|
});
|
||||||
it = mesh_instances_.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update light intances and remove instances without transforms */
|
/* Update light intances and remove instances without transforms */
|
||||||
for (auto it = light_instances_.begin(); it != light_instances_.end(); ++it) {
|
light_instances_.remove_if([&](auto item) {
|
||||||
update_light_instance(it->second);
|
update_light_instance(item.value);
|
||||||
if (it->second.transforms.empty()) {
|
return item.value.transforms.empty();
|
||||||
light_instances_.erase(it);
|
});
|
||||||
it = light_instances_.begin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstancerData::update_light_instance(LightInstance &inst)
|
void InstancerData::update_light_instance(LightInstance &inst)
|
||||||
@ -461,20 +456,22 @@ void InstancerData::update_light_instance(LightInstance &inst)
|
|||||||
|
|
||||||
InstancerData::MeshInstance *InstancerData::mesh_instance(pxr::SdfPath const &id) const
|
InstancerData::MeshInstance *InstancerData::mesh_instance(pxr::SdfPath const &id) const
|
||||||
{
|
{
|
||||||
auto it = mesh_instances_.find(id.GetPathElementCount() == 4 ? id.GetParentPath() : id);
|
auto m_inst = mesh_instances_.lookup_ptr(id.GetPathElementCount() == 4 ? id.GetParentPath() :
|
||||||
if (it == mesh_instances_.end()) {
|
id);
|
||||||
|
if (!m_inst) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return const_cast<MeshInstance *>(&it->second);
|
return const_cast<MeshInstance *>(m_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
InstancerData::LightInstance *InstancerData::light_instance(pxr::SdfPath const &id) const
|
InstancerData::LightInstance *InstancerData::light_instance(pxr::SdfPath const &id) const
|
||||||
{
|
{
|
||||||
auto it = light_instances_.find(id.GetPathElementCount() == 4 ? id.GetParentPath() : id);
|
auto l_inst = light_instances_.lookup_ptr(id.GetPathElementCount() == 4 ? id.GetParentPath() :
|
||||||
if (it == light_instances_.end()) {
|
id);
|
||||||
|
if (!l_inst) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return const_cast<LightInstance *>(&it->second);
|
return const_cast<LightInstance *>(l_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "BKE_duplilist.h"
|
#include "BKE_duplilist.h"
|
||||||
|
#include "BLI_map.hh"
|
||||||
|
#include "BLI_set.hh"
|
||||||
|
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
@ -41,8 +43,8 @@ class InstancerData : public ObjectData {
|
|||||||
ObjectData *object_data(pxr::SdfPath const &id) const;
|
ObjectData *object_data(pxr::SdfPath const &id) const;
|
||||||
pxr::SdfPathVector prototypes() const;
|
pxr::SdfPathVector prototypes() const;
|
||||||
void check_update(Object *object);
|
void check_update(Object *object);
|
||||||
void check_remove(std::set<std::string> &available_objects);
|
void check_remove(Set<std::string> &available_objects);
|
||||||
void available_materials(std::set<pxr::SdfPath> &paths) const;
|
void available_materials(Set<pxr::SdfPath> &paths) const;
|
||||||
void update_as_parent();
|
void update_as_parent();
|
||||||
void update_double_sided(MaterialData *mat_data);
|
void update_double_sided(MaterialData *mat_data);
|
||||||
|
|
||||||
@ -56,12 +58,11 @@ class InstancerData : public ObjectData {
|
|||||||
MeshInstance *mesh_instance(pxr::SdfPath const &id) const;
|
MeshInstance *mesh_instance(pxr::SdfPath const &id) const;
|
||||||
LightInstance *light_instance(pxr::SdfPath const &id) const;
|
LightInstance *light_instance(pxr::SdfPath const &id) const;
|
||||||
|
|
||||||
pxr::TfHashMap<pxr::SdfPath, MeshInstance, pxr::SdfPath::Hash> mesh_instances_;
|
Map<pxr::SdfPath, MeshInstance> mesh_instances_;
|
||||||
pxr::TfHashMap<pxr::SdfPath, LightInstance, pxr::SdfPath::Hash> light_instances_;
|
Map<pxr::SdfPath, LightInstance> light_instances_;
|
||||||
pxr::VtMatrix4dArray mesh_transforms_;
|
pxr::VtMatrix4dArray mesh_transforms_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using InstancerDataMap =
|
using InstancerDataMap = Map<pxr::SdfPath, std::unique_ptr<InstancerData>>;
|
||||||
pxr::TfHashMap<pxr::SdfPath, std::unique_ptr<InstancerData>, pxr::SdfPath::Hash>;
|
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
@ -60,14 +60,14 @@ void MaterialData::update()
|
|||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id,
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id,
|
||||||
pxr::HdMaterial::AllDirty);
|
pxr::HdMaterial::AllDirty);
|
||||||
if (prev_double_sided != double_sided) {
|
if (prev_double_sided != double_sided) {
|
||||||
for (auto &it : scene_delegate_->objects_) {
|
for (auto &obj_data : scene_delegate_->objects_.values()) {
|
||||||
MeshData *m_data = dynamic_cast<MeshData *>(it.second.get());
|
MeshData *m_data = dynamic_cast<MeshData *>(obj_data.get());
|
||||||
if (m_data) {
|
if (m_data) {
|
||||||
m_data->update_double_sided(this);
|
m_data->update_double_sided(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto &it : scene_delegate_->instancers_) {
|
for (auto &i_data : scene_delegate_->instancers_.values()) {
|
||||||
it.second->update_double_sided(this);
|
i_data->update_double_sided(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <pxr/usd/sdf/assetPath.h>
|
#include <pxr/usd/sdf/assetPath.h>
|
||||||
#include <pxr/usd/sdf/path.h>
|
#include <pxr/usd/sdf/path.h>
|
||||||
|
|
||||||
|
#include "BLI_map.hh"
|
||||||
#include "DNA_material_types.h"
|
#include "DNA_material_types.h"
|
||||||
|
|
||||||
#include "id.h"
|
#include "id.h"
|
||||||
@ -37,7 +38,6 @@ class MaterialData : public IdData {
|
|||||||
pxr::VtValue material_network_map_;
|
pxr::VtValue material_network_map_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using MaterialDataMap =
|
using MaterialDataMap = Map<pxr::SdfPath, std::unique_ptr<MaterialData>>;
|
||||||
pxr::TfHashMap<pxr::SdfPath, std::unique_ptr<MaterialData>, pxr::SdfPath::Hash>;
|
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
@ -173,11 +173,11 @@ void MeshData::update_double_sided(MaterialData *mat_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshData::available_materials(std::set<pxr::SdfPath> &paths) const
|
void MeshData::available_materials(Set<pxr::SdfPath> &paths) const
|
||||||
{
|
{
|
||||||
for (auto &sm : submeshes_) {
|
for (auto &sm : submeshes_) {
|
||||||
if (sm.mat_data && !sm.mat_data->prim_id.IsEmpty()) {
|
if (sm.mat_data && !sm.mat_data->prim_id.IsEmpty()) {
|
||||||
paths.insert(sm.mat_data->prim_id);
|
paths.add(sm.mat_data->prim_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,15 +301,14 @@ void MeshData::write_materials()
|
|||||||
m.mat_data = nullptr;
|
m.mat_data = nullptr;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
|
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
|
||||||
m.mat_data = scene_delegate_->material_data(p_id);
|
m.mat_data = scene_delegate_->materials_
|
||||||
if (!m.mat_data) {
|
.lookup_or_add(p_id,
|
||||||
scene_delegate_->materials_[p_id] = std::make_unique<MaterialData>(
|
std::make_unique<MaterialData>(scene_delegate_, mat, p_id))
|
||||||
scene_delegate_, mat, p_id);
|
.get();
|
||||||
m.mat_data = scene_delegate_->material_data(p_id);
|
m.mat_data->init();
|
||||||
m.mat_data->init();
|
m.mat_data->insert();
|
||||||
m.mat_data->insert();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <pxr/imaging/hd/sceneDelegate.h>
|
#include <pxr/imaging/hd/sceneDelegate.h>
|
||||||
|
|
||||||
#include "BKE_duplilist.h"
|
#include "BKE_duplilist.h"
|
||||||
|
#include "BLI_set.hh"
|
||||||
|
|
||||||
#include "material.h"
|
#include "material.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
@ -39,7 +40,7 @@ class MeshData : public ObjectData {
|
|||||||
pxr::SdfPath material_id(pxr::SdfPath const &id) const;
|
pxr::SdfPath material_id(pxr::SdfPath const &id) const;
|
||||||
bool double_sided(pxr::SdfPath const &id) const;
|
bool double_sided(pxr::SdfPath const &id) const;
|
||||||
void update_double_sided(MaterialData *mat_data);
|
void update_double_sided(MaterialData *mat_data);
|
||||||
void available_materials(std::set<pxr::SdfPath> &paths) const;
|
void available_materials(Set<pxr::SdfPath> &paths) const;
|
||||||
pxr::SdfPathVector submesh_paths() const;
|
pxr::SdfPathVector submesh_paths() const;
|
||||||
|
|
||||||
pxr::HdCullStyle cull_style = pxr::HdCullStyleBackUnlessDoubleSided;
|
pxr::HdCullStyle cull_style = pxr::HdCullStyleBackUnlessDoubleSided;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <pxr/base/gf/matrix4d.h>
|
#include <pxr/base/gf/matrix4d.h>
|
||||||
|
|
||||||
#include "BKE_layer.h"
|
#include "BKE_layer.h"
|
||||||
|
#include "BLI_map.hh"
|
||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
|
|
||||||
#include "id.h"
|
#include "id.h"
|
||||||
@ -36,8 +37,7 @@ class ObjectData : public IdData {
|
|||||||
Object *parent_ = nullptr;
|
Object *parent_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
using ObjectDataMap =
|
using ObjectDataMap = Map<pxr::SdfPath, std::unique_ptr<ObjectData>>;
|
||||||
pxr::TfHashMap<pxr::SdfPath, std::unique_ptr<ObjectData>, pxr::SdfPath::Hash>;
|
|
||||||
|
|
||||||
pxr::GfMatrix4d gf_matrix_from_transform(float m[4][4]);
|
pxr::GfMatrix4d gf_matrix_from_transform(float m[4][4]);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user