forked from blender/blender
Support more AOVs #78
54
doc/python_api/examples/bpy.types.HydraRenderEngine.py
Normal file
54
doc/python_api/examples/bpy.types.HydraRenderEngine.py
Normal file
@ -0,0 +1,54 @@
|
||||
"""
|
||||
Base class for integrating USD Hydra based renderers.
|
||||
|
||||
USD Hydra Based Renderer
|
||||
++++++++++++++++++++++++
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
class CustomHydraRenderEngine(bpy.types.HydraRenderEngine):
|
||||
# Identifier and name in the user interface.
|
||||
bl_idname = "CUSTOM_HYDRA_RENDERER"
|
||||
bl_label = "Custom Hydra Renderer"
|
||||
|
||||
# Name of the render plugin.
|
||||
bl_delegate_id = "HdCustomRendererPlugin"
|
||||
|
||||
# Register path to plugin.
|
||||
@classmethod
|
||||
def register(cls):
|
||||
super().register()
|
||||
|
||||
import pxr
|
||||
pxr.Plug.Registry().RegisterPlugins(['/path/to/plugin'])
|
||||
|
||||
# Render settings that will be passed to the delegate.
|
||||
def get_render_settings(self, engine_type):
|
||||
return {
|
||||
'myBoolean': True,
|
||||
'myValue': 8,
|
||||
}
|
||||
|
||||
# Settings used by the synchronization process.
|
||||
def get_sync_settings(self, engine_type):
|
||||
return {
|
||||
'MaterialXFilenameKey': "MaterialXFilename",
|
||||
}
|
||||
|
||||
# RenderEngine methods for update, render and draw are implemented in
|
||||
# HydraRenderEngine. Optionally extra work can be done before or after
|
||||
# by implementing the methods like this.
|
||||
def update(self, data, depsgraph):
|
||||
super().update(data, depsgraph)
|
||||
# Do extra work here
|
||||
|
||||
# Registration
|
||||
def register():
|
||||
bpy.utils.register_class(CustomHydraRenderEngine)
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(CustomHydraRenderEngine)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
@ -1,155 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Implementation of class `HydraRenderEngine`.
|
||||
|
||||
Render Blender addon with Hydra render delegate should inherit `HydraRenderEngine`.
|
||||
Example:
|
||||
```
|
||||
import bpy_hydra
|
||||
|
||||
class CustomHydraRenderEngine(HydraRenderEngine):
|
||||
bl_idname = 'CustomHydraRenderEngine'
|
||||
bl_label = "Hydra: Custom"
|
||||
bl_info = "Hydra Custom render delegate"
|
||||
|
||||
delegate_id = 'HdCustomRendererPlugin'
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
super().register()
|
||||
|
||||
bpy_hydra.register_plugins(["/path/to/plugin")])
|
||||
|
||||
def get_sync_settings(self, engine_type):
|
||||
return {
|
||||
'MaterialXFilenameKey': "MaterialXFilename",
|
||||
}
|
||||
|
||||
def get_render_settings(self, engine_type):
|
||||
return {
|
||||
'enableTinyPrimCulling': True,
|
||||
'maxLights': 8,
|
||||
'aov:Depth': "depth",
|
||||
}
|
||||
|
||||
def update_render_passes(self, scene, render_layer):
|
||||
if render_layer.use_pass_z:
|
||||
self.register_pass(scene, render_layer, 'Depth', 1, 'Z', 'VALUE')
|
||||
```
|
||||
"""
|
||||
|
||||
__all__ = (
|
||||
"HydraRenderEngine",
|
||||
"export_mtlx",
|
||||
"register_plugins",
|
||||
)
|
||||
|
||||
import os
|
||||
import platform
|
||||
from pathlib import Path
|
||||
|
||||
import bpy
|
||||
import _bpy_hydra
|
||||
|
||||
from _bpy_hydra import register_plugins
|
||||
|
||||
|
||||
class HydraRenderEngine(bpy.types.RenderEngine):
|
||||
""" Render addon with Hydra render delegate should inherit this class """
|
||||
|
||||
bl_use_shading_nodes_custom = False
|
||||
|
||||
delegate_id = ''
|
||||
engine_ptr = None
|
||||
|
||||
def __del__(self):
|
||||
if not self.engine_ptr:
|
||||
return
|
||||
|
||||
_bpy_hydra.engine_free(self.engine_ptr)
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
root_folder = "blender.shared" if platform.system() == 'Windows' else "lib"
|
||||
os.environ['PXR_MTLX_STDLIB_SEARCH_PATHS'] = os.pathsep.join([
|
||||
str(Path(bpy.app.binary_path).parent / f"{root_folder}/materialx/libraries"),
|
||||
os.environ.get('PXR_MTLX_STDLIB_SEARCH_PATHS', "")])
|
||||
|
||||
@classmethod
|
||||
def unregister(cls):
|
||||
pass
|
||||
|
||||
def get_sync_settings(self, engine_type):
|
||||
"""
|
||||
Provide settings for Blender scene delegate. Available settings:
|
||||
`MaterialXFilenameKey` - if provided then MaterialX file will be provided directly to render delegate
|
||||
without converting to HdMaterialNetwork
|
||||
"""
|
||||
return {}
|
||||
|
||||
def get_render_settings(self, engine_type):
|
||||
"""
|
||||
Provide render settings for render delegate. List of settings should be available in render delegate
|
||||
documentation or in `pxr.UsdImagingGL.Engine.GetRendererSettingsList()`
|
||||
"""
|
||||
return {}
|
||||
|
||||
# final render
|
||||
def _update(self, depsgraph):
|
||||
"""This function is preferable to override in child classes instead of update()"""
|
||||
engine_type = 'PREVIEW' if self.is_preview else 'FINAL'
|
||||
self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), engine_type, self.delegate_id)
|
||||
if not self.engine_ptr:
|
||||
return
|
||||
|
||||
for key, val in self.get_sync_settings(engine_type).items():
|
||||
_bpy_hydra.engine_set_sync_setting(self.engine_ptr, key, val)
|
||||
|
||||
_bpy_hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), bpy.context.as_pointer())
|
||||
|
||||
def update(self, data, depsgraph):
|
||||
# If bl_use_gpu_context is true, this function is ignored and render() is used
|
||||
if not self.bl_use_gpu_context:
|
||||
self._update(depsgraph)
|
||||
|
||||
def render(self, depsgraph):
|
||||
if self.bl_use_gpu_context:
|
||||
self._update(depsgraph)
|
||||
|
||||
if not self.engine_ptr:
|
||||
return
|
||||
|
||||
for key, val in self.get_render_settings('PREVIEW' if self.is_preview else 'FINAL').items():
|
||||
_bpy_hydra.engine_set_render_setting(self.engine_ptr, key, val)
|
||||
|
||||
_bpy_hydra.engine_render(self.engine_ptr, depsgraph.as_pointer())
|
||||
|
||||
# viewport render
|
||||
def view_update(self, context, depsgraph):
|
||||
if not self.engine_ptr:
|
||||
self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), 'VIEWPORT', self.delegate_id)
|
||||
if not self.engine_ptr:
|
||||
return
|
||||
|
||||
for key, val in self.get_sync_settings('VIEWPORT').items():
|
||||
_bpy_hydra.engine_set_sync_setting(self.engine_ptr, key, val)
|
||||
|
||||
_bpy_hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), context.as_pointer())
|
||||
|
||||
for key, val in self.get_render_settings('VIEWPORT').items():
|
||||
_bpy_hydra.engine_set_render_setting(self.engine_ptr, key, val)
|
||||
|
||||
def view_draw(self, context, depsgraph):
|
||||
if not self.engine_ptr:
|
||||
return
|
||||
|
||||
_bpy_hydra.engine_view_draw(self.engine_ptr, depsgraph.as_pointer(), context.as_pointer())
|
||||
|
||||
def update_render_passes(self, scene, render_layer):
|
||||
""" Register supported AOVs for render. Must be overridden in child classes. """
|
||||
pass
|
||||
|
||||
def export_mtlx(material):
|
||||
""" Exports material to .mtlx file. It is called from Blender source code. """
|
||||
try:
|
||||
|
@ -935,10 +935,6 @@ class PropertyGroup(StructRNA, metaclass=RNAMetaPropGroup):
|
||||
__slots__ = ()
|
||||
|
||||
|
||||
class RenderEngine(StructRNA, metaclass=RNAMeta):
|
||||
__slots__ = ()
|
||||
|
||||
|
||||
class KeyingSetInfo(StructRNA, metaclass=RNAMeta):
|
||||
__slots__ = ()
|
||||
|
||||
@ -1249,3 +1245,86 @@ class GeometryNode(NodeInternal):
|
||||
@classmethod
|
||||
def poll(cls, ntree):
|
||||
return ntree.bl_idname == 'GeometryNodeTree'
|
||||
|
||||
|
||||
class RenderEngine(StructRNA, metaclass=RNAMeta):
|
||||
__slots__ = ()
|
||||
|
||||
|
||||
class HydraRenderEngine(RenderEngine):
|
||||
__slots__ = ()
|
||||
|
||||
bl_use_shading_nodes_custom = False
|
||||
bl_delegate_id = 'HdStormRendererPlugin'
|
||||
|
||||
def __init__(self):
|
||||
self.engine_ptr = None
|
||||
|
||||
def __del__(self):
|
||||
if hasattr(self, 'engine_ptr'):
|
||||
if self.engine_ptr:
|
||||
import _bpy_hydra
|
||||
_bpy_hydra.engine_free(self.engine_ptr)
|
||||
|
||||
def get_sync_settings(self, engine_type: str):
|
||||
"""
|
||||
Provide settings for Blender scene export. Available settings:
|
||||
`MaterialXFilenameKey` - if provided then MaterialX file will be provided directly to render delegate
|
||||
without converting to HdMaterialNetwork
|
||||
"""
|
||||
return {}
|
||||
|
||||
def get_render_settings(self, engine_type: str):
|
||||
"""
|
||||
Provide render settings for `HdRenderDelegate`.
|
||||
"""
|
||||
return {}
|
||||
|
||||
# Final render.
|
||||
def update(self, data, depsgraph):
|
||||
import _bpy_hydra
|
||||
import bpy
|
||||
|
||||
engine_type = 'PREVIEW' if self.is_preview else 'FINAL'
|
||||
if not self.engine_ptr:
|
||||
self.engine_ptr = _bpy_hydra.engine_create(self, engine_type, self.bl_delegate_id)
|
||||
if not self.engine_ptr:
|
||||
return
|
||||
|
||||
for key, val in self.get_sync_settings(engine_type).items():
|
||||
_bpy_hydra.engine_set_sync_setting(self.engine_ptr, key, val)
|
||||
|
||||
_bpy_hydra.engine_update(self.engine_ptr, depsgraph, bpy.context)
|
||||
|
||||
for key, val in self.get_render_settings('PREVIEW' if self.is_preview else 'FINAL').items():
|
||||
_bpy_hydra.engine_set_render_setting(self.engine_ptr, key, val)
|
||||
|
||||
def render(self, depsgraph):
|
||||
if not self.engine_ptr:
|
||||
return
|
||||
|
||||
import _bpy_hydra
|
||||
_bpy_hydra.engine_render(self.engine_ptr, depsgraph)
|
||||
|
||||
# Viewport render.
|
||||
def view_update(self, context, depsgraph):
|
||||
import _bpy_hydra
|
||||
if not self.engine_ptr:
|
||||
self.engine_ptr = _bpy_hydra.engine_create(self, 'VIEWPORT', self.bl_delegate_id)
|
||||
if not self.engine_ptr:
|
||||
return
|
||||
|
||||
for key, val in self.get_sync_settings('VIEWPORT').items():
|
||||
_bpy_hydra.engine_set_sync_setting(self.engine_ptr, key, val)
|
||||
|
||||
_bpy_hydra.engine_update(self.engine_ptr, depsgraph, context)
|
||||
|
||||
for key, val in self.get_render_settings('VIEWPORT').items():
|
||||
_bpy_hydra.engine_set_render_setting(self.engine_ptr, key, val)
|
||||
|
||||
def view_draw(self, context, depsgraph):
|
||||
if not self.engine_ptr:
|
||||
return
|
||||
|
||||
import _bpy_hydra
|
||||
_bpy_hydra.engine_view_draw(self.engine_ptr, depsgraph, context)
|
||||
|
@ -38,7 +38,11 @@ materialx_libs_dir = os.path.abspath(os.path.join(shared_lib_dir, "materialx", "
|
||||
materialx_libs_env = os.getenv("MATERIALX_SEARCH_PATH")
|
||||
if materialx_libs_env is None:
|
||||
os.environ["MATERIALX_SEARCH_PATH"] = materialx_libs_dir
|
||||
elif sys.platform == "win32":
|
||||
os.environ["MATERIALX_SEARCH_PATH"] = materialx_libs_dir + ";" + materialx_libs_env
|
||||
else:
|
||||
os.environ["MATERIALX_SEARCH_PATH"] = materialx_libs_dir + ":" + materialx_libs_env
|
||||
os.environ["MATERIALX_SEARCH_PATH"] = materialx_libs_env + os.pathsep + materialx_libs_dir
|
||||
|
||||
materialx_libs_env = os.getenv("PXR_MTLX_STDLIB_SEARCH_PATHS")
|
||||
if materialx_libs_env is None:
|
||||
os.environ["PXR_MTLX_STDLIB_SEARCH_PATHS"] = materialx_libs_dir
|
||||
else:
|
||||
os.environ["PXR_MTLX_STDLIB_SEARCH_PATHS"] = materialx_libs_env + os.pathsep + materialx_libs_dir
|
||||
|
@ -14,6 +14,17 @@ if(WIN32)
|
||||
endif()
|
||||
add_definitions(-DBOOST_ALL_NO_LIB)
|
||||
|
||||
# Precompiled Linux libs are made with GCC, and USD uses some extensions
|
||||
# which lead to an incompatible ABI for Clang. Using those extensions with
|
||||
# Clang as well works around the issue.
|
||||
if(UNIX AND NOT APPLE)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
if(EXISTS ${LIBDIR})
|
||||
add_definitions(-DARCH_HAS_GNU_STL_EXTENSIONS)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# USD headers use deprecated TBB headers, silence warning.
|
||||
add_definitions(-DTBB_SUPPRESS_DEPRECATED_MESSAGES=1)
|
||||
|
||||
@ -53,8 +64,13 @@ set(INC
|
||||
../../editors/include
|
||||
../../imbuf
|
||||
../../makesrna
|
||||
../../nodes
|
||||
../../python/intern
|
||||
../../windowmanager
|
||||
../../../../intern/utfconv
|
||||
../../../../intern/clog
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
@ -124,6 +140,41 @@ set(SRC
|
||||
intern/usd_reader_xform.h
|
||||
)
|
||||
|
||||
if(WITH_HYDRA)
|
||||
list(APPEND SRC
|
||||
hydra/camera.cc
|
||||
hydra/curves.cc
|
||||
hydra/hydra_scene_delegate.cc
|
||||
hydra/id.cc
|
||||
hydra/image.cc
|
||||
hydra/instancer.cc
|
||||
hydra/light.cc
|
||||
hydra/material.cc
|
||||
hydra/mesh.cc
|
||||
hydra/object.cc
|
||||
hydra/usd_scene_delegate.cc
|
||||
hydra/volume.cc
|
||||
hydra/volume_modifier.cc
|
||||
hydra/world.cc
|
||||
|
||||
hydra/camera.h
|
||||
hydra/curves.h
|
||||
hydra/hydra_scene_delegate.h
|
||||
hydra/id.h
|
||||
hydra/image.h
|
||||
hydra/instancer.h
|
||||
hydra/light.h
|
||||
hydra/material.h
|
||||
hydra/mesh.h
|
||||
hydra/object.h
|
||||
hydra/settings.h
|
||||
hydra/usd_scene_delegate.h
|
||||
hydra/volume.h
|
||||
hydra/volume_modifier.h
|
||||
hydra/world.h
|
||||
)
|
||||
endif()
|
||||
|
||||
set(LIB
|
||||
PRIVATE bf::blenkernel
|
||||
PRIVATE bf::blenlib
|
||||
@ -151,8 +202,16 @@ if(WITH_OPENVDB)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_MATERIALX)
|
||||
add_definitions(-DWITH_MATERIALX)
|
||||
list(APPEND LIB MaterialXCore)
|
||||
endif()
|
||||
|
||||
blender_add_lib(bf_usd "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
||||
# RNA_prototypes.h
|
||||
add_dependencies(bf_usd bf_rna)
|
||||
|
||||
if(COMMAND target_precompile_headers)
|
||||
target_precompile_headers(bf_usd PRIVATE intern/usd_precomp.h)
|
||||
endif()
|
||||
|
@ -1,24 +1,23 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "camera.h"
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "camera.h"
|
||||
#include "scene_delegate/object.h"
|
||||
#include "hydra/object.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
CameraData::CameraData(bContext *context)
|
||||
CameraData::CameraData(View3D *v3d, ARegion *region)
|
||||
{
|
||||
View3D *view3d = CTX_wm_view3d(context);
|
||||
RegionView3D *region_data = (RegionView3D *)CTX_wm_region_data(context);
|
||||
ARegion *region = CTX_wm_region(context);
|
||||
RegionView3D *region_data = (RegionView3D *)region->regiondata;
|
||||
|
||||
/* This constant was found experimentally, didn't find such option in
|
||||
* context.view3d or context.region_data. */
|
||||
float VIEWPORT_SENSOR_SIZE = 72.0;
|
||||
/* TODO: refactor use BKE_camera_params API. */
|
||||
float VIEWPORT_SENSOR_SIZE = DEFAULT_SENSOR_WIDTH * 2.0f;
|
||||
|
||||
pxr::GfVec2i res(region->winx, region->winy);
|
||||
float ratio = (float)res[0] / res[1];
|
||||
@ -27,9 +26,9 @@ CameraData::CameraData(bContext *context)
|
||||
switch (region_data->persp) {
|
||||
case RV3D_PERSP: {
|
||||
mode_ = CAM_PERSP;
|
||||
clip_range_ = pxr::GfRange1f(view3d->clip_start, view3d->clip_end);
|
||||
clip_range_ = pxr::GfRange1f(v3d->clip_start, v3d->clip_end);
|
||||
lens_shift_ = pxr::GfVec2f(0.0, 0.0);
|
||||
focal_length_ = view3d->lens;
|
||||
focal_length_ = v3d->lens;
|
||||
|
||||
if (ratio > 1.0) {
|
||||
sensor_size_ = pxr::GfVec2f(VIEWPORT_SENSOR_SIZE, VIEWPORT_SENSOR_SIZE / ratio);
|
||||
@ -44,8 +43,8 @@ CameraData::CameraData(bContext *context)
|
||||
mode_ = CAM_ORTHO;
|
||||
lens_shift_ = pxr::GfVec2f(0.0f, 0.0f);
|
||||
|
||||
float o_size = region_data->dist * VIEWPORT_SENSOR_SIZE / view3d->lens;
|
||||
float o_depth = view3d->clip_end;
|
||||
float o_size = region_data->dist * VIEWPORT_SENSOR_SIZE / v3d->lens;
|
||||
float o_depth = v3d->clip_end;
|
||||
|
||||
clip_range_ = pxr::GfRange1f(-o_depth * 0.5, o_depth * 0.5);
|
||||
|
||||
@ -60,7 +59,7 @@ CameraData::CameraData(bContext *context)
|
||||
|
||||
case RV3D_CAMOB: {
|
||||
pxr::GfMatrix4d mat = transform_;
|
||||
*this = CameraData(view3d->camera, res, pxr::GfVec4f(0, 0, 1, 1));
|
||||
*this = CameraData(v3d->camera, res, pxr::GfVec4f(0, 0, 1, 1));
|
||||
transform_ = mat;
|
||||
|
||||
/* This formula was taken from previous plugin with corresponded comment.
|
||||
@ -141,7 +140,7 @@ CameraData::CameraData(Object *camera_obj, pxr::GfVec2i res, pxr::GfVec4f tile)
|
||||
lens_shift_[1] / t_size[1] + (t_pos[1] + t_size[1] * 0.5 - 0.5) / t_size[1]);
|
||||
|
||||
switch (camera->type) {
|
||||
case CAM_PERSP:
|
||||
case CAM_PERSP: {
|
||||
focal_length_ = camera->lens;
|
||||
|
||||
switch (camera->sensor_fit) {
|
||||
@ -165,8 +164,9 @@ CameraData::CameraData(Object *camera_obj, pxr::GfVec2i res, pxr::GfVec4f tile)
|
||||
}
|
||||
sensor_size_ = pxr::GfVec2f(sensor_size_[0] * t_size[0], sensor_size_[1] * t_size[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAM_ORTHO:
|
||||
case CAM_ORTHO: {
|
||||
focal_length_ = 0.0f;
|
||||
switch (camera->sensor_fit) {
|
||||
case CAMERA_SENSOR_FIT_VERT:
|
||||
@ -189,8 +189,9 @@ CameraData::CameraData(Object *camera_obj, pxr::GfVec2i res, pxr::GfVec4f tile)
|
||||
}
|
||||
ortho_size_ = pxr::GfVec2f(ortho_size_[0] * t_size[0], ortho_size_[1] * t_size[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAM_PANO:
|
||||
case CAM_PANO: {
|
||||
/* TODO: Recheck parameters for PANO camera */
|
||||
focal_length_ = camera->lens;
|
||||
|
||||
@ -214,10 +215,14 @@ CameraData::CameraData(Object *camera_obj, pxr::GfVec2i res, pxr::GfVec4f tile)
|
||||
break;
|
||||
}
|
||||
sensor_size_ = pxr::GfVec2f(sensor_size_[0] * t_size[0], sensor_size_[1] * t_size[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
default: {
|
||||
focal_length_ = camera->lens;
|
||||
sensor_size_ = pxr::GfVec2f(camera->sensor_y * ratio, camera->sensor_y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,4 +280,4 @@ pxr::GfCamera CameraData::gf_camera(pxr::GfVec4f tile)
|
||||
return gf_camera;
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,27 +1,20 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <tuple>
|
||||
|
||||
#include <pxr/base/gf/camera.h>
|
||||
#include <pxr/base/gf/vec2f.h>
|
||||
|
||||
#include "BKE_context.h"
|
||||
struct ARegion;
|
||||
struct Object;
|
||||
struct View3D;
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
class CameraData {
|
||||
public:
|
||||
CameraData(bContext *context);
|
||||
CameraData(Object *camera_obj, pxr::GfVec2i res, pxr::GfVec4f tile);
|
||||
|
||||
pxr::GfCamera gf_camera();
|
||||
pxr::GfCamera gf_camera(pxr::GfVec4f tile);
|
||||
|
||||
private:
|
||||
int mode_;
|
||||
pxr::GfRange1f clip_range_;
|
||||
@ -31,6 +24,13 @@ class CameraData {
|
||||
pxr::GfVec2f lens_shift_;
|
||||
pxr::GfVec2f ortho_size_;
|
||||
std::tuple<float, float, int> dof_data_;
|
||||
|
||||
public:
|
||||
CameraData(View3D *v3d, ARegion *region);
|
||||
CameraData(Object *camera_obj, pxr::GfVec2i res, pxr::GfVec4f tile);
|
||||
|
||||
pxr::GfCamera gf_camera();
|
||||
pxr::GfCamera gf_camera(pxr::GfVec4f tile);
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,5 +1,7 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "curves.h"
|
||||
|
||||
#include <pxr/base/gf/vec2f.h>
|
||||
#include <pxr/imaging/hd/tokens.h>
|
||||
@ -7,11 +9,11 @@
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_material.h"
|
||||
|
||||
#include "blender_scene_delegate.h"
|
||||
#include "hydra_scene_delegate.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
CurvesData::CurvesData(BlenderSceneDelegate *scene_delegate,
|
||||
CurvesData::CurvesData(HydraSceneDelegate *scene_delegate,
|
||||
Object *object,
|
||||
pxr::SdfPath const &prim_id)
|
||||
: ObjectData(scene_delegate, object, prim_id)
|
||||
@ -178,4 +180,4 @@ void CurvesData::write_uv_maps(Curves *curves)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,23 +1,33 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pxr/base/vt/array.h>
|
||||
#include <pxr/imaging/hd/sceneDelegate.h>
|
||||
|
||||
#include "BKE_duplilist.h"
|
||||
#include "DNA_curves_types.h"
|
||||
|
||||
#include "BLI_set.hh"
|
||||
|
||||
#include "BKE_duplilist.h"
|
||||
|
||||
#include "material.h"
|
||||
#include "object.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
class CurvesData : public ObjectData {
|
||||
private:
|
||||
pxr::VtIntArray curve_vertex_counts_;
|
||||
pxr::VtVec3fArray vertices_;
|
||||
pxr::VtVec2fArray uvs_;
|
||||
pxr::VtFloatArray widths_;
|
||||
|
||||
MaterialData *mat_data_ = nullptr;
|
||||
|
||||
public:
|
||||
CurvesData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||
CurvesData(HydraSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||
|
||||
void init() override;
|
||||
void insert() override;
|
||||
@ -37,13 +47,6 @@ class CurvesData : public ObjectData {
|
||||
private:
|
||||
void write_curves(Curves *curves);
|
||||
void write_uv_maps(Curves *curves);
|
||||
|
||||
pxr::VtIntArray curve_vertex_counts_;
|
||||
pxr::VtVec3fArray vertices_;
|
||||
pxr::VtVec2fArray uvs_;
|
||||
pxr::VtFloatArray widths_;
|
||||
|
||||
MaterialData *mat_data_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,19 +1,21 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "hydra_scene_delegate.h"
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#include "BLI_set.hh"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "blender_scene_delegate.h"
|
||||
#include "BLI_set.hh"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
namespace blender::io::hydra {
|
||||
|
||||
CLG_LOGREF_DECLARE_GLOBAL(LOG_RENDER_HYDRA_SCENE, "render.hydra.scene");
|
||||
|
||||
bool BlenderSceneDelegate::ShadingSettings::operator==(const ShadingSettings &other)
|
||||
bool HydraSceneDelegate::ShadingSettings::operator==(const ShadingSettings &other)
|
||||
{
|
||||
bool ret = use_scene_lights == other.use_scene_lights &&
|
||||
use_scene_world == other.use_scene_world;
|
||||
@ -26,34 +28,34 @@ bool BlenderSceneDelegate::ShadingSettings::operator==(const ShadingSettings &ot
|
||||
return ret;
|
||||
}
|
||||
|
||||
BlenderSceneDelegate::BlenderSceneDelegate(pxr::HdRenderIndex *parent_index,
|
||||
pxr::SdfPath const &delegate_id,
|
||||
const SceneDelegateSettings &settings)
|
||||
HydraSceneDelegate::HydraSceneDelegate(pxr::HdRenderIndex *parent_index,
|
||||
pxr::SdfPath const &delegate_id,
|
||||
const HydraDelegateSettings &settings)
|
||||
: HdSceneDelegate(parent_index, delegate_id), settings(settings)
|
||||
{
|
||||
instancer_data_ = std::make_unique<InstancerData>(this, instancer_prim_id());
|
||||
}
|
||||
|
||||
pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id)
|
||||
pxr::HdMeshTopology HydraSceneDelegate::GetMeshTopology(pxr::SdfPath const &id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||
MeshData *m_data = mesh_data(id);
|
||||
return m_data->mesh_topology(id);
|
||||
return m_data->topology(id);
|
||||
}
|
||||
|
||||
pxr::HdBasisCurvesTopology BlenderSceneDelegate::GetBasisCurvesTopology(pxr::SdfPath const &id)
|
||||
pxr::HdBasisCurvesTopology HydraSceneDelegate::GetBasisCurvesTopology(pxr::SdfPath const &id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||
CurvesData *c_data = curves_data(id);
|
||||
return c_data->topology();
|
||||
};
|
||||
|
||||
pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id)
|
||||
pxr::GfMatrix4d HydraSceneDelegate::GetTransform(pxr::SdfPath const &id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||
InstancerData *i_data = instancer_data(id, true);
|
||||
if (i_data) {
|
||||
return i_data->get_transform(id);
|
||||
return i_data->transform(id);
|
||||
}
|
||||
ObjectData *obj_data = object_data(id);
|
||||
if (obj_data) {
|
||||
@ -65,7 +67,7 @@ pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id)
|
||||
return pxr::GfMatrix4d();
|
||||
}
|
||||
|
||||
pxr::VtValue BlenderSceneDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key)
|
||||
pxr::VtValue HydraSceneDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %s", id.GetText(), key.GetText());
|
||||
ObjectData *obj_data = object_data(id);
|
||||
@ -83,8 +85,8 @@ pxr::VtValue BlenderSceneDelegate::Get(pxr::SdfPath const &id, pxr::TfToken cons
|
||||
return pxr::VtValue();
|
||||
}
|
||||
|
||||
pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id,
|
||||
pxr::TfToken const &key)
|
||||
pxr::VtValue HydraSceneDelegate::GetLightParamValue(pxr::SdfPath const &id,
|
||||
pxr::TfToken const &key)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %s", id.GetText(), key.GetText());
|
||||
LightData *l_data = light_data(id);
|
||||
@ -94,7 +96,7 @@ pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id,
|
||||
return pxr::VtValue();
|
||||
}
|
||||
|
||||
pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors(
|
||||
pxr::HdPrimvarDescriptorVector HydraSceneDelegate::GetPrimvarDescriptors(
|
||||
pxr::SdfPath const &id, pxr::HdInterpolation interpolation)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %d", id.GetText(), interpolation);
|
||||
@ -113,7 +115,7 @@ pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors(
|
||||
return pxr::HdPrimvarDescriptorVector();
|
||||
}
|
||||
|
||||
pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id)
|
||||
pxr::SdfPath HydraSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", rprim_id.GetText());
|
||||
ObjectData *obj_data = object_data(rprim_id);
|
||||
@ -123,7 +125,7 @@ pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id)
|
||||
return pxr::SdfPath();
|
||||
}
|
||||
|
||||
pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id)
|
||||
pxr::VtValue HydraSceneDelegate::GetMaterialResource(pxr::SdfPath const &id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||
MaterialData *mat_data = material_data(id);
|
||||
@ -133,7 +135,7 @@ pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id)
|
||||
return pxr::VtValue();
|
||||
}
|
||||
|
||||
bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id)
|
||||
bool HydraSceneDelegate::GetVisible(pxr::SdfPath const &id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||
if (id == world_prim_id()) {
|
||||
@ -146,51 +148,51 @@ bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id)
|
||||
return object_data(id)->visible;
|
||||
}
|
||||
|
||||
bool BlenderSceneDelegate::GetDoubleSided(pxr::SdfPath const &id)
|
||||
bool HydraSceneDelegate::GetDoubleSided(pxr::SdfPath const &id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||
return mesh_data(id)->double_sided(id);
|
||||
}
|
||||
|
||||
pxr::HdCullStyle BlenderSceneDelegate::GetCullStyle(pxr::SdfPath const &id)
|
||||
pxr::HdCullStyle HydraSceneDelegate::GetCullStyle(pxr::SdfPath const &id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||
return mesh_data(id)->cull_style(id);
|
||||
}
|
||||
|
||||
pxr::SdfPath BlenderSceneDelegate::GetInstancerId(pxr::SdfPath const &prim_id)
|
||||
pxr::SdfPath HydraSceneDelegate::GetInstancerId(pxr::SdfPath const &prim_id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", prim_id.GetText());
|
||||
InstancerData *i_data = instancer_data(prim_id, true);
|
||||
if (i_data) {
|
||||
if (i_data && mesh_data(prim_id)) {
|
||||
return i_data->prim_id;
|
||||
}
|
||||
return pxr::SdfPath();
|
||||
}
|
||||
|
||||
pxr::SdfPathVector BlenderSceneDelegate::GetInstancerPrototypes(pxr::SdfPath const &instancer_id)
|
||||
pxr::SdfPathVector HydraSceneDelegate::GetInstancerPrototypes(pxr::SdfPath const &instancer_id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", instancer_id.GetText());
|
||||
InstancerData *i_data = instancer_data(instancer_id);
|
||||
return i_data->prototypes();
|
||||
}
|
||||
|
||||
pxr::VtIntArray BlenderSceneDelegate::GetInstanceIndices(pxr::SdfPath const &instancer_id,
|
||||
pxr::SdfPath const &prototype_id)
|
||||
pxr::VtIntArray HydraSceneDelegate::GetInstanceIndices(pxr::SdfPath const &instancer_id,
|
||||
pxr::SdfPath const &prototype_id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %s", instancer_id.GetText(), prototype_id.GetText());
|
||||
InstancerData *i_data = instancer_data(instancer_id);
|
||||
return i_data->indices(prototype_id);
|
||||
}
|
||||
|
||||
pxr::GfMatrix4d BlenderSceneDelegate::GetInstancerTransform(pxr::SdfPath const &instancer_id)
|
||||
pxr::GfMatrix4d HydraSceneDelegate::GetInstancerTransform(pxr::SdfPath const &instancer_id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", instancer_id.GetText());
|
||||
InstancerData *i_data = instancer_data(instancer_id);
|
||||
return i_data->get_transform(instancer_id);
|
||||
return i_data->transform(instancer_id);
|
||||
}
|
||||
|
||||
pxr::HdVolumeFieldDescriptorVector BlenderSceneDelegate::GetVolumeFieldDescriptors(
|
||||
pxr::HdVolumeFieldDescriptorVector HydraSceneDelegate::GetVolumeFieldDescriptors(
|
||||
pxr::SdfPath const &volume_id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", volume_id.GetText());
|
||||
@ -198,14 +200,14 @@ pxr::HdVolumeFieldDescriptorVector BlenderSceneDelegate::GetVolumeFieldDescripto
|
||||
return v_data->field_descriptors();
|
||||
}
|
||||
|
||||
void BlenderSceneDelegate::populate(Depsgraph *deps, bContext *cont)
|
||||
void HydraSceneDelegate::populate(Depsgraph *deps, View3D *v3d)
|
||||
{
|
||||
bool is_populated = depsgraph != nullptr;
|
||||
|
||||
depsgraph = deps;
|
||||
context = cont;
|
||||
bmain = DEG_get_bmain(deps);
|
||||
scene = DEG_get_input_scene(depsgraph);
|
||||
view3d = CTX_wm_view3d(context);
|
||||
view3d = v3d;
|
||||
|
||||
if (is_populated) {
|
||||
check_updates();
|
||||
@ -218,7 +220,7 @@ void BlenderSceneDelegate::populate(Depsgraph *deps, bContext *cont)
|
||||
}
|
||||
}
|
||||
|
||||
void BlenderSceneDelegate::clear()
|
||||
void HydraSceneDelegate::clear()
|
||||
{
|
||||
for (auto &obj_data : objects_.values()) {
|
||||
obj_data->remove();
|
||||
@ -231,12 +233,12 @@ void BlenderSceneDelegate::clear()
|
||||
materials_.clear();
|
||||
|
||||
depsgraph = nullptr;
|
||||
context = nullptr;
|
||||
bmain = nullptr;
|
||||
scene = nullptr;
|
||||
view3d = nullptr;
|
||||
}
|
||||
|
||||
pxr::SdfPath BlenderSceneDelegate::prim_id(ID *id, const char *prefix) const
|
||||
pxr::SdfPath HydraSceneDelegate::prim_id(ID *id, const char *prefix) const
|
||||
{
|
||||
/* Making id of object in form like <prefix>_<pointer in 16 hex digits format> */
|
||||
char name[32];
|
||||
@ -244,27 +246,27 @@ pxr::SdfPath BlenderSceneDelegate::prim_id(ID *id, const char *prefix) const
|
||||
return GetDelegateID().AppendElementString(name);
|
||||
}
|
||||
|
||||
pxr::SdfPath BlenderSceneDelegate::object_prim_id(Object *object) const
|
||||
pxr::SdfPath HydraSceneDelegate::object_prim_id(Object *object) const
|
||||
{
|
||||
return prim_id((ID *)object, "O");
|
||||
}
|
||||
|
||||
pxr::SdfPath BlenderSceneDelegate::material_prim_id(Material *mat) const
|
||||
pxr::SdfPath HydraSceneDelegate::material_prim_id(Material *mat) const
|
||||
{
|
||||
return prim_id((ID *)mat, "M");
|
||||
}
|
||||
|
||||
pxr::SdfPath BlenderSceneDelegate::instancer_prim_id() const
|
||||
pxr::SdfPath HydraSceneDelegate::instancer_prim_id() const
|
||||
{
|
||||
return GetDelegateID().AppendElementString("Instancer");
|
||||
}
|
||||
|
||||
pxr::SdfPath BlenderSceneDelegate::world_prim_id() const
|
||||
pxr::SdfPath HydraSceneDelegate::world_prim_id() const
|
||||
{
|
||||
return GetDelegateID().AppendElementString("World");
|
||||
}
|
||||
|
||||
ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) const
|
||||
ObjectData *HydraSceneDelegate::object_data(pxr::SdfPath const &id) const
|
||||
{
|
||||
if (id == world_prim_id()) {
|
||||
return world_data_.get();
|
||||
@ -285,27 +287,27 @@ ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MeshData *BlenderSceneDelegate::mesh_data(pxr::SdfPath const &id) const
|
||||
MeshData *HydraSceneDelegate::mesh_data(pxr::SdfPath const &id) const
|
||||
{
|
||||
return dynamic_cast<MeshData *>(object_data(id));
|
||||
}
|
||||
|
||||
CurvesData *BlenderSceneDelegate::curves_data(pxr::SdfPath const &id) const
|
||||
CurvesData *HydraSceneDelegate::curves_data(pxr::SdfPath const &id) const
|
||||
{
|
||||
return dynamic_cast<CurvesData *>(object_data(id));
|
||||
}
|
||||
|
||||
VolumeData *BlenderSceneDelegate::volume_data(pxr::SdfPath const &id) const
|
||||
VolumeData *HydraSceneDelegate::volume_data(pxr::SdfPath const &id) const
|
||||
{
|
||||
return dynamic_cast<VolumeData *>(object_data(id));
|
||||
}
|
||||
|
||||
LightData *BlenderSceneDelegate::light_data(pxr::SdfPath const &id) const
|
||||
LightData *HydraSceneDelegate::light_data(pxr::SdfPath const &id) const
|
||||
{
|
||||
return dynamic_cast<LightData *>(object_data(id));
|
||||
}
|
||||
|
||||
MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) const
|
||||
MaterialData *HydraSceneDelegate::material_data(pxr::SdfPath const &id) const
|
||||
{
|
||||
auto mat_data = materials_.lookup_ptr(id);
|
||||
if (!mat_data) {
|
||||
@ -314,7 +316,7 @@ MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) const
|
||||
return mat_data->get();
|
||||
}
|
||||
|
||||
InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id, bool child_id) const
|
||||
InstancerData *HydraSceneDelegate::instancer_data(pxr::SdfPath const &id, bool child_id) const
|
||||
{
|
||||
pxr::SdfPath p_id;
|
||||
if (child_id) {
|
||||
@ -338,7 +340,7 @@ InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id, bool
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BlenderSceneDelegate::update_world()
|
||||
void HydraSceneDelegate::update_world()
|
||||
{
|
||||
if (!world_data_) {
|
||||
if (!shading_settings.use_scene_world || (shading_settings.use_scene_world && scene->world)) {
|
||||
@ -358,7 +360,7 @@ void BlenderSceneDelegate::update_world()
|
||||
}
|
||||
}
|
||||
|
||||
void BlenderSceneDelegate::check_updates()
|
||||
void HydraSceneDelegate::check_updates()
|
||||
{
|
||||
bool do_update_collection = false;
|
||||
bool do_update_world = false;
|
||||
@ -427,7 +429,7 @@ void BlenderSceneDelegate::check_updates()
|
||||
}
|
||||
}
|
||||
|
||||
void BlenderSceneDelegate::update_collection()
|
||||
void HydraSceneDelegate::update_collection()
|
||||
{
|
||||
Set<std::string> available_objects;
|
||||
|
||||
@ -449,17 +451,21 @@ void BlenderSceneDelegate::update_collection()
|
||||
object)
|
||||
{
|
||||
if (data.dupli_object_current) {
|
||||
instancer_data_->update_instance(data.dupli_parent, data.dupli_object_current);
|
||||
DupliObject *dupli = data.dupli_object_current;
|
||||
if (!ObjectData::is_supported(dupli->ob) ||
|
||||
!ObjectData::is_visible(this, data.dupli_parent, OB_VISIBLE_INSTANCES) ||
|
||||
(!shading_settings.use_scene_lights && object->type == OB_LAMP))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
instancer_data_->update_instance(data.dupli_parent, dupli);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ObjectData::is_supported(object)) {
|
||||
continue;
|
||||
}
|
||||
if (!ObjectData::is_visible(this, object)) {
|
||||
continue;
|
||||
}
|
||||
if (!shading_settings.use_scene_lights && object->type == OB_LAMP) {
|
||||
if (!ObjectData::is_supported(object) || !ObjectData::is_visible(this, object) ||
|
||||
(!shading_settings.use_scene_lights && object->type == OB_LAMP))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -515,7 +521,7 @@ void BlenderSceneDelegate::update_collection()
|
||||
});
|
||||
}
|
||||
|
||||
bool BlenderSceneDelegate::set_light_shading_settings()
|
||||
bool HydraSceneDelegate::set_light_shading_settings()
|
||||
{
|
||||
if (!view3d) {
|
||||
return false;
|
||||
@ -525,7 +531,7 @@ bool BlenderSceneDelegate::set_light_shading_settings()
|
||||
return !(shading_settings == prev_settings);
|
||||
}
|
||||
|
||||
bool BlenderSceneDelegate::set_world_shading_settings()
|
||||
bool HydraSceneDelegate::set_world_shading_settings()
|
||||
{
|
||||
if (!view3d) {
|
||||
return false;
|
||||
@ -538,4 +544,4 @@ bool BlenderSceneDelegate::set_world_shading_settings()
|
||||
return !(shading_settings == prev_settings);
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,13 +1,13 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pxr/base/gf/vec2f.h>
|
||||
#include <pxr/imaging/hd/sceneDelegate.h>
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BLI_map.hh"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
#include "CLG_log.h"
|
||||
@ -22,13 +22,18 @@
|
||||
#include "volume_modifier.h"
|
||||
#include "world.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
struct Depsgraph;
|
||||
struct Main;
|
||||
struct Scene;
|
||||
struct View3D;
|
||||
|
||||
namespace blender::io::hydra {
|
||||
|
||||
extern struct CLG_LogRef *LOG_RENDER_HYDRA_SCENE;
|
||||
|
||||
class Engine;
|
||||
|
||||
class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
||||
class HydraSceneDelegate : public pxr::HdSceneDelegate {
|
||||
friend ObjectData; /* has access to materials */
|
||||
friend MaterialData; /* has access to objects and instancers */
|
||||
|
||||
@ -43,10 +48,24 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
||||
bool operator==(const ShadingSettings &other);
|
||||
};
|
||||
|
||||
BlenderSceneDelegate(pxr::HdRenderIndex *parent_index,
|
||||
pxr::SdfPath const &delegate_id,
|
||||
const SceneDelegateSettings &settings);
|
||||
~BlenderSceneDelegate() override = default;
|
||||
Depsgraph *depsgraph = nullptr;
|
||||
View3D *view3d = nullptr;
|
||||
Main *bmain = nullptr;
|
||||
Scene *scene = nullptr;
|
||||
const HydraDelegateSettings &settings;
|
||||
ShadingSettings shading_settings;
|
||||
|
||||
private:
|
||||
ObjectDataMap objects_;
|
||||
MaterialDataMap materials_;
|
||||
std::unique_ptr<InstancerData> instancer_data_;
|
||||
std::unique_ptr<WorldData> world_data_;
|
||||
|
||||
public:
|
||||
HydraSceneDelegate(pxr::HdRenderIndex *parent_index,
|
||||
pxr::SdfPath const &delegate_id,
|
||||
const HydraDelegateSettings &settings);
|
||||
~HydraSceneDelegate() override = default;
|
||||
|
||||
/* Delegate methods */
|
||||
pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override;
|
||||
@ -69,16 +88,9 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
||||
pxr::HdVolumeFieldDescriptorVector GetVolumeFieldDescriptors(
|
||||
pxr::SdfPath const &volume_id) override;
|
||||
|
||||
void populate(Depsgraph *depsgraph, bContext *context);
|
||||
void populate(Depsgraph *depsgraph, View3D *v3d);
|
||||
void clear();
|
||||
|
||||
Depsgraph *depsgraph = nullptr;
|
||||
bContext *context = nullptr;
|
||||
View3D *view3d = nullptr;
|
||||
Scene *scene = nullptr;
|
||||
const SceneDelegateSettings &settings;
|
||||
ShadingSettings shading_settings;
|
||||
|
||||
private:
|
||||
pxr::SdfPath prim_id(ID *id, const char *prefix) const;
|
||||
pxr::SdfPath object_prim_id(Object *object) const;
|
||||
@ -99,11 +111,6 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
||||
void update_collection();
|
||||
bool set_light_shading_settings();
|
||||
bool set_world_shading_settings();
|
||||
|
||||
ObjectDataMap objects_;
|
||||
MaterialDataMap materials_;
|
||||
std::unique_ptr<InstancerData> instancer_data_;
|
||||
std::unique_ptr<WorldData> world_data_;
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
15
source/blender/io/usd/hydra/id.cc
Normal file
15
source/blender/io/usd/hydra/id.cc
Normal file
@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "id.h"
|
||||
|
||||
#include "BKE_lib_id.h"
|
||||
|
||||
namespace blender::io::hydra {
|
||||
|
||||
IdData::IdData(HydraSceneDelegate *scene_delegate, ID *id, pxr::SdfPath const &prim_id)
|
||||
: id(id), prim_id(prim_id), scene_delegate_(scene_delegate)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace blender::io::hydra
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -7,9 +7,10 @@
|
||||
#include <pxr/base/vt/value.h>
|
||||
#include <pxr/usd/sdf/path.h>
|
||||
|
||||
#include "BLI_hash.hh"
|
||||
#include "DNA_ID.h"
|
||||
|
||||
#include "BLI_hash.hh"
|
||||
|
||||
template<> struct blender::DefaultHash<pxr::SdfPath> {
|
||||
uint64_t operator()(const pxr::SdfPath &value) const
|
||||
{
|
||||
@ -24,13 +25,20 @@ template<> struct blender::DefaultHash<pxr::TfToken> {
|
||||
}
|
||||
};
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
class BlenderSceneDelegate;
|
||||
class HydraSceneDelegate;
|
||||
|
||||
class IdData {
|
||||
public:
|
||||
IdData(BlenderSceneDelegate *scene_delegate, ID *id, pxr::SdfPath const &prim_id);
|
||||
ID *id;
|
||||
pxr::SdfPath prim_id;
|
||||
|
||||
protected:
|
||||
HydraSceneDelegate *scene_delegate_;
|
||||
|
||||
public:
|
||||
IdData(HydraSceneDelegate *scene_delegate, ID *id, pxr::SdfPath const &prim_id);
|
||||
virtual ~IdData() = default;
|
||||
|
||||
virtual void init() = 0;
|
||||
@ -39,12 +47,6 @@ class IdData {
|
||||
virtual void update() = 0;
|
||||
|
||||
virtual pxr::VtValue get_data(pxr::TfToken const &key) const = 0;
|
||||
|
||||
ID *id;
|
||||
pxr::SdfPath prim_id;
|
||||
|
||||
protected:
|
||||
BlenderSceneDelegate *scene_delegate_;
|
||||
};
|
||||
|
||||
#define ID_LOG(level, msg, ...) \
|
||||
@ -58,4 +60,4 @@ class IdData {
|
||||
id ? id->name : "", \
|
||||
##__VA_ARGS__);
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,20 +1,24 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "image.h"
|
||||
|
||||
#include <pxr/imaging/hio/imageRegistry.h>
|
||||
|
||||
#include "BKE_appdir.h"
|
||||
#include "BKE_image_format.h"
|
||||
#include "BKE_image_save.h"
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#include "BKE_appdir.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_image_format.h"
|
||||
#include "BKE_image_save.h"
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "blender_scene_delegate.h"
|
||||
#include "image.h"
|
||||
#include "hydra_scene_delegate.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
static std::string get_cache_file(const std::string &file_name, bool mkdir = true)
|
||||
{
|
||||
@ -29,16 +33,12 @@ static std::string get_cache_file(const std::string &file_name, bool mkdir = tru
|
||||
return file_path;
|
||||
}
|
||||
|
||||
static std::string cache_image_file(Image *image,
|
||||
bContext *context,
|
||||
ImageUser *iuser,
|
||||
bool check_exist)
|
||||
static std::string cache_image_file(
|
||||
Main *bmain, Scene *scene, Image *image, ImageUser *iuser, bool check_exist)
|
||||
{
|
||||
std::string file_path;
|
||||
Main *main = CTX_data_main(context);
|
||||
Scene *scene = CTX_data_scene(context);
|
||||
ImageSaveOptions opts;
|
||||
if (BKE_image_save_options_init(&opts, main, scene, image, iuser, false, false)) {
|
||||
if (BKE_image_save_options_init(&opts, bmain, scene, image, iuser, false, false)) {
|
||||
char file_name[32];
|
||||
const char *r_ext = BLI_path_extension_or_end(image->id.name);
|
||||
if (!pxr::HioImageRegistry::GetInstance().IsSupportedImageFile(image->id.name)) {
|
||||
@ -55,7 +55,7 @@ static std::string cache_image_file(Image *image,
|
||||
|
||||
opts.save_copy = true;
|
||||
STRNCPY(opts.filepath, file_path.c_str());
|
||||
if (BKE_image_save(nullptr, main, image, iuser, &opts)) {
|
||||
if (BKE_image_save(nullptr, bmain, image, iuser, &opts)) {
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s -> %s", image->id.name, file_path.c_str());
|
||||
}
|
||||
else {
|
||||
@ -67,23 +67,22 @@ static std::string cache_image_file(Image *image,
|
||||
return file_path;
|
||||
}
|
||||
|
||||
std::string cache_or_get_image_file(Image *image, bContext *context, ImageUser *iuser)
|
||||
std::string cache_or_get_image_file(Main *bmain, Scene *scene, Image *image, ImageUser *iuser)
|
||||
{
|
||||
std::string file_path;
|
||||
if (image->source == IMA_SRC_GENERATED) {
|
||||
file_path = cache_image_file(image, context, iuser, false);
|
||||
file_path = cache_image_file(bmain, scene, image, iuser, false);
|
||||
}
|
||||
else if (BKE_image_has_packedfile(image)) {
|
||||
file_path = cache_image_file(image, context, iuser, true);
|
||||
file_path = cache_image_file(bmain, scene, image, iuser, true);
|
||||
}
|
||||
else {
|
||||
Main *main = CTX_data_main(context);
|
||||
char str[FILE_MAX];
|
||||
BKE_image_user_file_path_ex(main, iuser, image, str, false, true);
|
||||
BKE_image_user_file_path_ex(bmain, iuser, image, str, false, true);
|
||||
file_path = str;
|
||||
|
||||
if (!pxr::HioImageRegistry::GetInstance().IsSupportedImageFile(file_path)) {
|
||||
file_path = cache_image_file(image, context, iuser, true);
|
||||
file_path = cache_image_file(bmain, scene, image, iuser, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +95,7 @@ std::string cache_image_color(float color[4])
|
||||
char name[128];
|
||||
snprintf(name,
|
||||
sizeof(name),
|
||||
"color_%02x%02x%02x.hdr",
|
||||
"color_%02d%02d%02d.hdr",
|
||||
int(color[0] * 255),
|
||||
int(color[1] * 255),
|
||||
int(color[2] * 255));
|
||||
@ -121,4 +120,4 @@ std::string cache_image_color(float color[4])
|
||||
return file_path;
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
18
source/blender/io/usd/hydra/image.h
Normal file
18
source/blender/io/usd/hydra/image.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
struct Main;
|
||||
struct Scene;
|
||||
struct Image;
|
||||
struct ImageUser;
|
||||
|
||||
namespace blender::io::hydra {
|
||||
|
||||
std::string cache_or_get_image_file(Main *bmain, Scene *Scene, Image *image, ImageUser *iuser);
|
||||
std::string cache_image_color(float color[4]);
|
||||
|
||||
} // namespace blender::io::hydra
|
286
source/blender/io/usd/hydra/instancer.cc
Normal file
286
source/blender/io/usd/hydra/instancer.cc
Normal file
@ -0,0 +1,286 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "instancer.h"
|
||||
|
||||
#include <pxr/base/gf/vec2f.h>
|
||||
#include <pxr/imaging/hd/light.h>
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "hydra_scene_delegate.h"
|
||||
|
||||
namespace blender::io::hydra {
|
||||
|
||||
InstancerData::InstancerData(HydraSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id)
|
||||
: IdData(scene_delegate, nullptr, prim_id)
|
||||
{
|
||||
}
|
||||
|
||||
void InstancerData::init() {}
|
||||
|
||||
void InstancerData::insert() {}
|
||||
|
||||
void InstancerData::remove()
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s", prim_id.GetText());
|
||||
for (auto &m_inst : mesh_instances_.values()) {
|
||||
m_inst.data->remove();
|
||||
}
|
||||
if (!mesh_instances_.is_empty()) {
|
||||
scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id);
|
||||
}
|
||||
mesh_instances_.clear();
|
||||
|
||||
for (auto &l_inst : nonmesh_instances_.values()) {
|
||||
l_inst.transforms.clear();
|
||||
update_nonmesh_instance(l_inst);
|
||||
}
|
||||
nonmesh_instances_.clear();
|
||||
}
|
||||
|
||||
void InstancerData::update() {}
|
||||
|
||||
pxr::VtValue InstancerData::get_data(pxr::TfToken const &key) const
|
||||
{
|
||||
ID_LOG(3, "%s", key.GetText());
|
||||
if (key == pxr::HdInstancerTokens->instanceTransform) {
|
||||
return pxr::VtValue(mesh_transforms_);
|
||||
}
|
||||
return pxr::VtValue();
|
||||
}
|
||||
|
||||
pxr::GfMatrix4d InstancerData::transform(pxr::SdfPath const &id) const
|
||||
{
|
||||
NonmeshInstance *nm_inst = nonmesh_instance(id);
|
||||
if (nm_inst) {
|
||||
return nm_inst->transforms[nonmesh_prim_id_index(id)];
|
||||
}
|
||||
|
||||
/* Mesh instance transform must be identity */
|
||||
return pxr::GfMatrix4d(1.0);
|
||||
}
|
||||
|
||||
pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(
|
||||
pxr::HdInterpolation interpolation) const
|
||||
{
|
||||
pxr::HdPrimvarDescriptorVector primvars;
|
||||
if (interpolation == pxr::HdInterpolationInstance) {
|
||||
primvars.emplace_back(
|
||||
pxr::HdInstancerTokens->instanceTransform, interpolation, pxr::HdPrimvarRoleTokens->none);
|
||||
}
|
||||
return primvars;
|
||||
}
|
||||
|
||||
pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const
|
||||
{
|
||||
return mesh_instance(id)->indices;
|
||||
}
|
||||
|
||||
ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const
|
||||
{
|
||||
MeshInstance *m_inst = mesh_instance(id);
|
||||
if (m_inst) {
|
||||
return m_inst->data.get();
|
||||
}
|
||||
NonmeshInstance *nm_inst = nonmesh_instance(id);
|
||||
if (nm_inst) {
|
||||
return nm_inst->data.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
pxr::SdfPathVector InstancerData::prototypes() const
|
||||
{
|
||||
pxr::SdfPathVector paths;
|
||||
for (auto &m_inst : mesh_instances_.values()) {
|
||||
for (auto &p : m_inst.data->submesh_paths()) {
|
||||
paths.push_back(p);
|
||||
}
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
void InstancerData::available_materials(Set<pxr::SdfPath> &paths) const
|
||||
{
|
||||
for (auto &m_inst : mesh_instances_.values()) {
|
||||
m_inst.data->available_materials(paths);
|
||||
}
|
||||
for (auto &l_inst : nonmesh_instances_.values()) {
|
||||
l_inst.data->available_materials(paths);
|
||||
}
|
||||
}
|
||||
|
||||
void InstancerData::update_double_sided(MaterialData *mat_data)
|
||||
{
|
||||
for (auto &m_inst : mesh_instances_.values()) {
|
||||
m_inst.data->update_double_sided(mat_data);
|
||||
}
|
||||
}
|
||||
|
||||
void InstancerData::pre_update()
|
||||
{
|
||||
mesh_transforms_.clear();
|
||||
for (auto &m_inst : mesh_instances_.values()) {
|
||||
m_inst.indices.clear();
|
||||
}
|
||||
for (auto &l_inst : nonmesh_instances_.values()) {
|
||||
l_inst.transforms.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void InstancerData::update_instance(Object * /* parent_ob */, DupliObject *dupli)
|
||||
{
|
||||
Object *object = dupli->ob;
|
||||
pxr::SdfPath p_id = object_prim_id(object);
|
||||
if (ObjectData::is_mesh(object)) {
|
||||
MeshInstance *m_inst = mesh_instance(p_id);
|
||||
if (!m_inst) {
|
||||
m_inst = &mesh_instances_.lookup_or_add_default(p_id);
|
||||
m_inst->data = std::make_unique<MeshData>(scene_delegate_, object, p_id);
|
||||
m_inst->data->init();
|
||||
m_inst->data->insert();
|
||||
}
|
||||
else {
|
||||
m_inst->data->update();
|
||||
}
|
||||
ID_LOG(2, "Mesh %s %d", m_inst->data->id->name, (int)mesh_transforms_.size());
|
||||
m_inst->indices.push_back(mesh_transforms_.size());
|
||||
mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat));
|
||||
}
|
||||
else {
|
||||
NonmeshInstance *nm_inst = nonmesh_instance(p_id);
|
||||
if (!nm_inst) {
|
||||
nm_inst = &nonmesh_instances_.lookup_or_add_default(p_id);
|
||||
nm_inst->data = ObjectData::create(scene_delegate_, object, p_id);
|
||||
}
|
||||
ID_LOG(2, "Light %s %d", nm_inst->data->id->name, (int)nm_inst->transforms.size());
|
||||
nm_inst->transforms.push_back(gf_matrix_from_transform(dupli->mat));
|
||||
}
|
||||
}
|
||||
|
||||
void InstancerData::post_update()
|
||||
{
|
||||
/* Remove mesh intances without indices */
|
||||
mesh_instances_.remove_if([&](auto item) {
|
||||
bool res = item.value.indices.empty();
|
||||
if (res) {
|
||||
item.value.data->remove();
|
||||
}
|
||||
return res;
|
||||
});
|
||||
|
||||
/* Update light intances and remove instances without transforms */
|
||||
for (auto &l_inst : nonmesh_instances_.values()) {
|
||||
update_nonmesh_instance(l_inst);
|
||||
}
|
||||
nonmesh_instances_.remove_if([&](auto item) { return item.value.transforms.empty(); });
|
||||
|
||||
/* Insert/remove/update instancer in RenderIndex */
|
||||
pxr::HdRenderIndex &index = scene_delegate_->GetRenderIndex();
|
||||
if (mesh_instances_.is_empty()) {
|
||||
/* Important: removing instancer when nonmesh_instances_ are empty too */
|
||||
if (index.HasInstancer(prim_id) && nonmesh_instances_.is_empty()) {
|
||||
index.RemoveInstancer(prim_id);
|
||||
ID_LOG(1, "Remove instancer");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (index.HasInstancer(prim_id)) {
|
||||
index.GetChangeTracker().MarkInstancerDirty(prim_id, pxr::HdChangeTracker::AllDirty);
|
||||
ID_LOG(1, "Update instancer");
|
||||
}
|
||||
else {
|
||||
index.InsertInstancer(scene_delegate_, prim_id);
|
||||
ID_LOG(1, "Insert instancer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pxr::SdfPath InstancerData::object_prim_id(Object *object) const
|
||||
{
|
||||
/* Making id of object in form like <prefix>_<pointer in 16 hex digits format> */
|
||||
char name[32];
|
||||
snprintf(name, sizeof(name), "O_%p", object);
|
||||
return prim_id.AppendElementString(name);
|
||||
}
|
||||
|
||||
pxr::SdfPath InstancerData::nonmesh_prim_id(pxr::SdfPath const &prim_id, int index) const
|
||||
{
|
||||
char name[16];
|
||||
snprintf(name, sizeof(name), "NM_%08d", index);
|
||||
return prim_id.AppendElementString(name);
|
||||
}
|
||||
|
||||
int InstancerData::nonmesh_prim_id_index(pxr::SdfPath const &id) const
|
||||
{
|
||||
int index;
|
||||
sscanf(id.GetName().c_str(), "NM_%d", &index);
|
||||
return index;
|
||||
}
|
||||
|
||||
void InstancerData::update_nonmesh_instance(NonmeshInstance &nm_inst)
|
||||
{
|
||||
ObjectData *obj_data = nm_inst.data.get();
|
||||
pxr::SdfPath prev_id = nm_inst.data->prim_id;
|
||||
int i;
|
||||
|
||||
/* Remove old light instances */
|
||||
while (nm_inst.count > nm_inst.transforms.size()) {
|
||||
--nm_inst.count;
|
||||
obj_data->prim_id = nonmesh_prim_id(prev_id, nm_inst.count);
|
||||
obj_data->remove();
|
||||
}
|
||||
|
||||
/* Update current light instances */
|
||||
LightData *l_data = dynamic_cast<LightData *>(obj_data);
|
||||
if (l_data && l_data->prim_type((Light *)((Object *)l_data->id)->data) != l_data->prim_type_) {
|
||||
/* Special case: recreate instances when prim_type was changed */
|
||||
for (i = 0; i < nm_inst.count; ++i) {
|
||||
obj_data->prim_id = nonmesh_prim_id(prev_id, i);
|
||||
obj_data->remove();
|
||||
}
|
||||
l_data->init();
|
||||
for (i = 0; i < nm_inst.count; ++i) {
|
||||
obj_data->prim_id = nonmesh_prim_id(prev_id, i);
|
||||
obj_data->insert();
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < nm_inst.count; ++i) {
|
||||
obj_data->prim_id = nonmesh_prim_id(prev_id, i);
|
||||
obj_data->update();
|
||||
}
|
||||
}
|
||||
|
||||
/* Add new light instances */
|
||||
while (nm_inst.count < nm_inst.transforms.size()) {
|
||||
obj_data->prim_id = nonmesh_prim_id(prev_id, nm_inst.count);
|
||||
obj_data->insert();
|
||||
++nm_inst.count;
|
||||
}
|
||||
|
||||
obj_data->prim_id = prev_id;
|
||||
}
|
||||
|
||||
InstancerData::MeshInstance *InstancerData::mesh_instance(pxr::SdfPath const &id) const
|
||||
{
|
||||
auto m_inst = mesh_instances_.lookup_ptr(id.GetPathElementCount() == 4 ? id.GetParentPath() :
|
||||
id);
|
||||
if (!m_inst) {
|
||||
return nullptr;
|
||||
}
|
||||
return const_cast<MeshInstance *>(m_inst);
|
||||
}
|
||||
|
||||
InstancerData::NonmeshInstance *InstancerData::nonmesh_instance(pxr::SdfPath const &id) const
|
||||
{
|
||||
auto nm_inst = nonmesh_instances_.lookup_ptr(id.GetPathElementCount() == 4 ? id.GetParentPath() :
|
||||
id);
|
||||
if (!nm_inst) {
|
||||
return nullptr;
|
||||
}
|
||||
return const_cast<NonmeshInstance *>(nm_inst);
|
||||
}
|
||||
|
||||
} // namespace blender::io::hydra
|
@ -1,16 +1,14 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BKE_duplilist.h"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_set.hh"
|
||||
|
||||
#include "light.h"
|
||||
#include "mesh.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
class InstancerData : public IdData {
|
||||
struct MeshInstance {
|
||||
@ -18,15 +16,19 @@ class InstancerData : public IdData {
|
||||
pxr::VtIntArray indices;
|
||||
};
|
||||
|
||||
struct LightInstance {
|
||||
std::unique_ptr<LightData> data;
|
||||
struct NonmeshInstance {
|
||||
std::unique_ptr<ObjectData> data;
|
||||
pxr::VtMatrix4dArray transforms;
|
||||
int count = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
Map<pxr::SdfPath, MeshInstance> mesh_instances_;
|
||||
Map<pxr::SdfPath, NonmeshInstance> nonmesh_instances_;
|
||||
pxr::VtMatrix4dArray mesh_transforms_;
|
||||
|
||||
public:
|
||||
InstancerData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id);
|
||||
static bool is_instance_supported(Object *object);
|
||||
InstancerData(HydraSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id);
|
||||
|
||||
void init() override;
|
||||
void insert() override;
|
||||
@ -34,7 +36,7 @@ class InstancerData : public IdData {
|
||||
void update() override;
|
||||
|
||||
pxr::VtValue get_data(pxr::TfToken const &key) const override;
|
||||
pxr::GfMatrix4d get_transform(pxr::SdfPath const &id) const;
|
||||
pxr::GfMatrix4d transform(pxr::SdfPath const &id) const;
|
||||
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
|
||||
pxr::VtIntArray indices(pxr::SdfPath const &id) const;
|
||||
ObjectData *object_data(pxr::SdfPath const &id) const;
|
||||
@ -54,15 +56,11 @@ class InstancerData : public IdData {
|
||||
|
||||
private:
|
||||
pxr::SdfPath object_prim_id(Object *object) const;
|
||||
pxr::SdfPath light_prim_id(LightInstance const &inst, int index) const;
|
||||
int light_prim_id_index(pxr::SdfPath const &id) const;
|
||||
void update_light_instance(LightInstance &inst);
|
||||
pxr::SdfPath nonmesh_prim_id(pxr::SdfPath const &prim_id, int index) const;
|
||||
int nonmesh_prim_id_index(pxr::SdfPath const &id) const;
|
||||
void update_nonmesh_instance(NonmeshInstance &inst);
|
||||
MeshInstance *mesh_instance(pxr::SdfPath const &id) const;
|
||||
LightInstance *light_instance(pxr::SdfPath const &id) const;
|
||||
|
||||
Map<pxr::SdfPath, MeshInstance> mesh_instances_;
|
||||
Map<pxr::SdfPath, LightInstance> light_instances_;
|
||||
pxr::VtMatrix4dArray mesh_transforms_;
|
||||
NonmeshInstance *nonmesh_instance(pxr::SdfPath const &id) const;
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,21 +1,21 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include "light.h"
|
||||
|
||||
#include <pxr/imaging/hd/light.h>
|
||||
#include <pxr/imaging/hd/tokens.h>
|
||||
#include <pxr/usd/usdLux/tokens.h>
|
||||
|
||||
#include "BLI_math_rotation.h"
|
||||
#include "DNA_light_types.h"
|
||||
|
||||
#include "blender_scene_delegate.h"
|
||||
#include "light.h"
|
||||
#include "BLI_math_rotation.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
#include "hydra_scene_delegate.h"
|
||||
|
||||
LightData::LightData(BlenderSceneDelegate *scene_delegate,
|
||||
namespace blender::io::hydra {
|
||||
|
||||
LightData::LightData(HydraSceneDelegate *scene_delegate,
|
||||
Object *object,
|
||||
pxr::SdfPath const &prim_id)
|
||||
: ObjectData(scene_delegate, object, prim_id)
|
||||
@ -179,4 +179,4 @@ pxr::TfToken LightData::prim_type(Light *light)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,9 +1,9 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pxr/base/tf/hashmap.h"
|
||||
#include <pxr/base/tf/hashmap.h>
|
||||
#include <pxr/usd/sdf/assetPath.h>
|
||||
#include <pxr/usd/sdf/path.h>
|
||||
|
||||
@ -11,15 +11,19 @@
|
||||
|
||||
#include "object.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
class InstancerData;
|
||||
|
||||
class LightData : public ObjectData {
|
||||
friend InstancerData;
|
||||
|
||||
protected:
|
||||
std::map<pxr::TfToken, pxr::VtValue> data_;
|
||||
pxr::TfToken prim_type_;
|
||||
|
||||
public:
|
||||
LightData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||
LightData(HydraSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||
|
||||
void init() override;
|
||||
void insert() override;
|
||||
@ -30,9 +34,6 @@ class LightData : public ObjectData {
|
||||
|
||||
protected:
|
||||
pxr::TfToken prim_type(Light *light);
|
||||
|
||||
std::map<pxr::TfToken, pxr::VtValue> data_;
|
||||
pxr::TfToken prim_type_;
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,5 +1,7 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "material.h"
|
||||
|
||||
#include <Python.h>
|
||||
#include <unicodeobject.h>
|
||||
@ -8,21 +10,38 @@
|
||||
#include <pxr/imaging/hd/renderDelegate.h>
|
||||
#include <pxr/imaging/hd/tokens.h>
|
||||
|
||||
#ifdef WITH_MATERIALX
|
||||
# include <pxr/base/arch/fileSystem.h>
|
||||
|
||||
# include <pxr/usd/ar/resolver.h>
|
||||
# include <pxr/usd/ar/resolverContextBinder.h>
|
||||
# include <pxr/usd/ar/resolverScopedCache.h>
|
||||
|
||||
# include <pxr/usd/usdMtlx/reader.h>
|
||||
# include <pxr/usd/usdMtlx/utils.h>
|
||||
|
||||
# include <pxr/usd/usdShade/material.h>
|
||||
# include <pxr/usd/usdShade/shader.h>
|
||||
|
||||
# include <pxr/usdImaging/usdImaging/materialParamUtils.h>
|
||||
#endif
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_material.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "RNA_blender_cpp.h"
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_prototypes.h"
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "bpy_rna.h"
|
||||
|
||||
#include "../engine.h"
|
||||
#include "blender_scene_delegate.h"
|
||||
#include "material.h"
|
||||
#include "mtlx_hydra_adapter.h"
|
||||
#include "hydra_scene_delegate.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
MaterialData::MaterialData(BlenderSceneDelegate *scene_delegate,
|
||||
MaterialData::MaterialData(HydraSceneDelegate *scene_delegate,
|
||||
Material *material,
|
||||
pxr::SdfPath const &prim_id)
|
||||
: IdData(scene_delegate, (ID *)material, prim_id)
|
||||
@ -152,6 +171,64 @@ void MaterialData::export_mtlx()
|
||||
ID_LOGN(1, "mtlx=%s", mtlx_path_.GetResolvedPath().c_str());
|
||||
}
|
||||
|
||||
#ifdef WITH_MATERIALX
|
||||
static void hdmtlx_convert_to_materialnetworkmap(std::string const &mtlx_path,
|
||||
pxr::TfTokenVector const &shader_source_types,
|
||||
pxr::TfTokenVector const &render_contexts,
|
||||
pxr::HdMaterialNetworkMap *out)
|
||||
{
|
||||
if (mtlx_path.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string basePath = pxr::TfGetPathName(mtlx_path);
|
||||
|
||||
pxr::ArResolver &resolver = pxr::ArGetResolver();
|
||||
const pxr::ArResolverContext context = resolver.CreateDefaultContextForAsset(mtlx_path);
|
||||
pxr::ArResolverContextBinder binder(context);
|
||||
pxr::ArResolverScopedCache resolver_cache;
|
||||
|
||||
std::string mtlxName = pxr::TfGetBaseName(mtlx_path);
|
||||
std::string stage_id = pxr::TfStringPrintf(
|
||||
"%s%s%s.usda", basePath.c_str(), ARCH_PATH_SEP, mtlxName.c_str());
|
||||
pxr::UsdStageRefPtr stage = pxr::UsdStage::CreateInMemory(stage_id, context);
|
||||
|
||||
try {
|
||||
MaterialX::DocumentPtr doc = pxr::UsdMtlxReadDocument(mtlx_path);
|
||||
pxr::UsdMtlxRead(doc, stage);
|
||||
}
|
||||
catch (MaterialX::ExceptionFoundCycle &x) {
|
||||
Tf_PostErrorHelper(pxr::TF_CALL_CONTEXT,
|
||||
pxr::TF_DIAGNOSTIC_RUNTIME_ERROR_TYPE,
|
||||
"MaterialX cycle found: %s\n",
|
||||
x.what());
|
||||
return;
|
||||
}
|
||||
catch (MaterialX::Exception &x) {
|
||||
Tf_PostErrorHelper(pxr::TF_CALL_CONTEXT,
|
||||
pxr::TF_DIAGNOSTIC_RUNTIME_ERROR_TYPE,
|
||||
"MaterialX error: %s\n",
|
||||
x.what());
|
||||
return;
|
||||
}
|
||||
|
||||
if (pxr::UsdPrim materials = stage->GetPrimAtPath(pxr::SdfPath("/MaterialX/Materials"))) {
|
||||
if (pxr::UsdPrimSiblingRange children = materials.GetChildren()) {
|
||||
if (auto material = pxr::UsdShadeMaterial(*children.begin())) {
|
||||
if (pxr::UsdShadeShader mtlx_surface = material.ComputeSurfaceSource(render_contexts)) {
|
||||
UsdImagingBuildHdMaterialNetworkFromTerminal(mtlx_surface.GetPrim(),
|
||||
pxr::HdMaterialTerminalTokens->surface,
|
||||
shader_source_types,
|
||||
render_contexts,
|
||||
out,
|
||||
pxr::UsdTimeCode::Default());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void MaterialData::write_material_network_map()
|
||||
{
|
||||
ID_LOGN(1, "");
|
||||
@ -165,10 +242,12 @@ void MaterialData::write_material_network_map()
|
||||
pxr::TfTokenVector render_contexts = render_delegate->GetMaterialRenderContexts();
|
||||
|
||||
pxr::HdMaterialNetworkMap network_map;
|
||||
#ifdef WITH_MATERIALX
|
||||
hdmtlx_convert_to_materialnetworkmap(
|
||||
mtlx_path_.GetResolvedPath(), shader_source_types, render_contexts, &network_map);
|
||||
#endif
|
||||
|
||||
material_network_map_ = network_map;
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -7,16 +7,21 @@
|
||||
#include <pxr/usd/sdf/assetPath.h>
|
||||
#include <pxr/usd/sdf/path.h>
|
||||
|
||||
#include "BLI_map.hh"
|
||||
#include "DNA_material_types.h"
|
||||
|
||||
#include "BLI_map.hh"
|
||||
|
||||
#include "id.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
class MaterialData : public IdData {
|
||||
private:
|
||||
pxr::SdfAssetPath mtlx_path_;
|
||||
pxr::VtValue material_network_map_;
|
||||
|
||||
public:
|
||||
MaterialData(BlenderSceneDelegate *scene_delegate,
|
||||
MaterialData(HydraSceneDelegate *scene_delegate,
|
||||
Material *material,
|
||||
pxr::SdfPath const &prim_id);
|
||||
|
||||
@ -34,11 +39,8 @@ class MaterialData : public IdData {
|
||||
private:
|
||||
void export_mtlx();
|
||||
void write_material_network_map();
|
||||
|
||||
pxr::SdfAssetPath mtlx_path_;
|
||||
pxr::VtValue material_network_map_;
|
||||
};
|
||||
|
||||
using MaterialDataMap = Map<pxr::SdfPath, std::unique_ptr<MaterialData>>;
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include <pxr/base/gf/vec2f.h>
|
||||
#include <pxr/base/tf/staticTokens.h>
|
||||
@ -9,18 +9,16 @@
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
|
||||
#include "blender_scene_delegate.h"
|
||||
#include "hydra_scene_delegate.h"
|
||||
#include "mesh.h"
|
||||
|
||||
PXR_NAMESPACE_OPEN_SCOPE
|
||||
TF_DEFINE_PRIVATE_TOKENS(tokens_, (st));
|
||||
PXR_NAMESPACE_CLOSE_SCOPE
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
MeshData::MeshData(BlenderSceneDelegate *scene_delegate,
|
||||
Object *object,
|
||||
pxr::SdfPath const &prim_id)
|
||||
MeshData::MeshData(HydraSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id)
|
||||
: ObjectData(scene_delegate, object, prim_id)
|
||||
{
|
||||
}
|
||||
@ -119,7 +117,7 @@ void MeshData::available_materials(Set<pxr::SdfPath> &paths) const
|
||||
}
|
||||
}
|
||||
|
||||
pxr::HdMeshTopology MeshData::mesh_topology(pxr::SdfPath const &id) const
|
||||
pxr::HdMeshTopology MeshData::topology(pxr::SdfPath const &id) const
|
||||
{
|
||||
const SubMesh &sm = submesh(id);
|
||||
return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none,
|
||||
@ -202,14 +200,14 @@ void MeshData::write_materials()
|
||||
pxr::SdfPath MeshData::submesh_prim_id(int index) const
|
||||
{
|
||||
char name[16];
|
||||
snprintf(name, sizeof(name), "SM_%04x", index);
|
||||
snprintf(name, sizeof(name), "SM_%04d", index);
|
||||
return prim_id.AppendElementString(name);
|
||||
}
|
||||
|
||||
const MeshData::SubMesh &MeshData::submesh(pxr::SdfPath const &id) const
|
||||
{
|
||||
int index;
|
||||
sscanf(id.GetName().c_str(), "SM_%x", &index);
|
||||
sscanf(id.GetName().c_str(), "SM_%d", &index);
|
||||
return submeshes_[index];
|
||||
}
|
||||
|
||||
@ -301,4 +299,4 @@ void MeshData::update_prims()
|
||||
submeshes_count_ = submeshes_.size();
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,18 +1,19 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pxr/base/vt/array.h>
|
||||
#include <pxr/imaging/hd/sceneDelegate.h>
|
||||
|
||||
#include "BKE_duplilist.h"
|
||||
#include "BLI_set.hh"
|
||||
|
||||
#include "BKE_duplilist.h"
|
||||
|
||||
#include "material.h"
|
||||
#include "object.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
class MeshData : public ObjectData {
|
||||
struct SubMesh {
|
||||
@ -24,8 +25,13 @@ class MeshData : public ObjectData {
|
||||
MaterialData *mat_data = nullptr;
|
||||
};
|
||||
|
||||
private:
|
||||
pxr::VtVec3fArray vertices_;
|
||||
std::vector<SubMesh> submeshes_;
|
||||
int submeshes_count_ = 0;
|
||||
|
||||
public:
|
||||
MeshData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||
MeshData(HydraSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||
|
||||
void init() override;
|
||||
void insert() override;
|
||||
@ -37,7 +43,7 @@ class MeshData : public ObjectData {
|
||||
pxr::SdfPath material_id(pxr::SdfPath const &id) const override;
|
||||
void available_materials(Set<pxr::SdfPath> &paths) const override;
|
||||
|
||||
pxr::HdMeshTopology mesh_topology(pxr::SdfPath const &id) const;
|
||||
pxr::HdMeshTopology topology(pxr::SdfPath const &id) const;
|
||||
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
|
||||
pxr::HdCullStyle cull_style(pxr::SdfPath const &id) const;
|
||||
bool double_sided(pxr::SdfPath const &id) const;
|
||||
@ -52,10 +58,6 @@ class MeshData : public ObjectData {
|
||||
const SubMesh &submesh(pxr::SdfPath const &id) const;
|
||||
void write_submeshes(Mesh *mesh);
|
||||
void update_prims();
|
||||
|
||||
pxr::VtVec3fArray vertices_;
|
||||
std::vector<SubMesh> submeshes_;
|
||||
int submeshes_count_ = 0;
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,30 +1,29 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "blender_scene_delegate.h"
|
||||
#include "curves.h"
|
||||
#include "hydra_scene_delegate.h"
|
||||
#include "light.h"
|
||||
#include "mesh.h"
|
||||
#include "object.h"
|
||||
#include "volume.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
ObjectData::ObjectData(BlenderSceneDelegate *scene_delegate,
|
||||
ObjectData::ObjectData(HydraSceneDelegate *scene_delegate,
|
||||
Object *object,
|
||||
pxr::SdfPath const &prim_id)
|
||||
: IdData(scene_delegate, (ID *)object, prim_id), transform(pxr::GfMatrix4d(1.0))
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<ObjectData> ObjectData::create(BlenderSceneDelegate *scene_delegate,
|
||||
std::unique_ptr<ObjectData> ObjectData::create(HydraSceneDelegate *scene_delegate,
|
||||
Object *object,
|
||||
pxr::SdfPath const &prim_id)
|
||||
{
|
||||
std::unique_ptr<ObjectData> obj_data;
|
||||
|
||||
switch (object->type) {
|
||||
case OB_MESH:
|
||||
case OB_SURF:
|
||||
@ -73,7 +72,25 @@ bool ObjectData::is_supported(Object *object)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectData::is_visible(BlenderSceneDelegate *scene_delegate, Object *object, int mode)
|
||||
bool ObjectData::is_mesh(Object *object)
|
||||
{
|
||||
switch (object->type) {
|
||||
case OB_MESH:
|
||||
case OB_SURF:
|
||||
case OB_FONT:
|
||||
case OB_CURVES_LEGACY:
|
||||
case OB_MBALL:
|
||||
if (VolumeModifierData::is_volume_modifier(object)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectData::is_visible(HydraSceneDelegate *scene_delegate, Object *object, int mode)
|
||||
{
|
||||
eEvaluationMode deg_mode = DEG_get_mode(scene_delegate->depsgraph);
|
||||
bool ret = BKE_object_visibility(object, deg_mode) & mode;
|
||||
@ -84,7 +101,7 @@ bool ObjectData::is_visible(BlenderSceneDelegate *scene_delegate, Object *object
|
||||
return ret;
|
||||
}
|
||||
|
||||
pxr::VtValue ObjectData::get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const
|
||||
pxr::VtValue ObjectData::get_data(pxr::SdfPath const & /* id */, pxr::TfToken const &key) const
|
||||
{
|
||||
return get_data(key);
|
||||
}
|
||||
@ -94,12 +111,12 @@ pxr::SdfPath ObjectData::material_id() const
|
||||
return pxr::SdfPath();
|
||||
}
|
||||
|
||||
pxr::SdfPath ObjectData::material_id(pxr::SdfPath const &id) const
|
||||
pxr::SdfPath ObjectData::material_id(pxr::SdfPath const & /* id */) const
|
||||
{
|
||||
return material_id();
|
||||
}
|
||||
|
||||
void ObjectData::available_materials(Set<pxr::SdfPath> &paths) const {}
|
||||
void ObjectData::available_materials(Set<pxr::SdfPath> & /* paths */) const {}
|
||||
|
||||
void ObjectData::write_transform()
|
||||
{
|
||||
@ -137,4 +154,4 @@ pxr::GfMatrix4d gf_matrix_from_transform(float m[4][4])
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,31 +1,34 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pxr/base/tf/hashmap.h"
|
||||
#include <pxr/base/gf/matrix4d.h>
|
||||
#include <pxr/base/tf/hashmap.h>
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_set.hh"
|
||||
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_set.hh"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "id.h"
|
||||
#include "material.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
class ObjectData : public IdData {
|
||||
public:
|
||||
ObjectData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||
ObjectData(HydraSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||
|
||||
static std::unique_ptr<ObjectData> create(BlenderSceneDelegate *scene_delegate,
|
||||
static std::unique_ptr<ObjectData> create(HydraSceneDelegate *scene_delegate,
|
||||
Object *object,
|
||||
pxr::SdfPath const &prim_id);
|
||||
static bool is_supported(Object *object);
|
||||
static bool is_visible(BlenderSceneDelegate *scene_delegate,
|
||||
static bool is_mesh(Object *object);
|
||||
static bool is_visible(HydraSceneDelegate *scene_delegate,
|
||||
Object *object,
|
||||
int mode = OB_VISIBLE_SELF);
|
||||
|
||||
@ -48,4 +51,4 @@ using ObjectDataMap = Map<pxr::SdfPath, std::unique_ptr<ObjectData>>;
|
||||
|
||||
pxr::GfMatrix4d gf_matrix_from_transform(float m[4][4]);
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
17
source/blender/io/usd/hydra/settings.h
Normal file
17
source/blender/io/usd/hydra/settings.h
Normal file
@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2023 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pxr/base/tf/token.h>
|
||||
|
||||
#include "BLI_map.hh"
|
||||
|
||||
namespace blender::io::hydra {
|
||||
|
||||
struct HydraDelegateSettings {
|
||||
pxr::TfToken mx_filename_key;
|
||||
Map<pxr::TfToken, pxr::VtValue> render_tokens;
|
||||
};
|
||||
|
||||
}; // namespace blender::io::hydra
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "usd_scene_delegate.hh"
|
||||
#include "usd_scene_delegate.h"
|
||||
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_path_util.h"
|
||||
@ -14,11 +14,11 @@
|
||||
#include "usd.h"
|
||||
#include "usd.hh"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
USDSceneDelegate::USDSceneDelegate(pxr::HdRenderIndex *render_index,
|
||||
pxr::SdfPath const &delegate_id,
|
||||
const SceneDelegateSettings &settings)
|
||||
const HydraDelegateSettings &settings)
|
||||
: render_index_(render_index), delegate_id_(delegate_id), settings_(settings)
|
||||
{
|
||||
/* Temporary directory to write any additional files to, like image or VDB files. */
|
||||
@ -42,7 +42,7 @@ USDSceneDelegate::~USDSceneDelegate()
|
||||
BLI_delete(temp_dir_.c_str(), true, true);
|
||||
}
|
||||
|
||||
void USDSceneDelegate::populate(Depsgraph *depsgraph, bContext * /*context*/)
|
||||
void USDSceneDelegate::populate(Depsgraph *depsgraph)
|
||||
{
|
||||
/* TODO: implement MaterialX support in USD exporter. */
|
||||
const bool use_materialx = !settings_.mx_filename_key.IsEmpty();
|
||||
@ -76,4 +76,4 @@ void USDSceneDelegate::populate(Depsgraph *depsgraph, bContext * /*context*/)
|
||||
delegate_->Populate(stage_->GetPseudoRoot());
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,27 +1,27 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2023 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2023 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <pxr/imaging/hd/renderIndex.h>
|
||||
#include <pxr/usdImaging/usdImaging/delegate.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
struct Depsgraph;
|
||||
struct bContext;
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
/* Populate Hydra render index using USD file export, for testing. */
|
||||
class USDSceneDelegate {
|
||||
private:
|
||||
pxr::HdRenderIndex *render_index_;
|
||||
pxr::SdfPath const delegate_id_;
|
||||
pxr::UsdStageRefPtr stage_;
|
||||
std::unique_ptr<pxr::UsdImagingDelegate> delegate_;
|
||||
const SceneDelegateSettings &settings_;
|
||||
const HydraDelegateSettings &settings_;
|
||||
|
||||
std::string temp_dir_;
|
||||
std::string temp_file_;
|
||||
@ -29,10 +29,10 @@ class USDSceneDelegate {
|
||||
public:
|
||||
USDSceneDelegate(pxr::HdRenderIndex *render_index,
|
||||
pxr::SdfPath const &delegate_id,
|
||||
const SceneDelegateSettings &settings_);
|
||||
const HydraDelegateSettings &settings_);
|
||||
~USDSceneDelegate();
|
||||
|
||||
void populate(Depsgraph *depsgraph, bContext *context);
|
||||
void populate(Depsgraph *depsgraph);
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include <pxr/imaging/hd/bprim.h>
|
||||
#include <pxr/imaging/hd/tokens.h>
|
||||
@ -13,12 +13,12 @@
|
||||
#include "BLI_index_range.hh"
|
||||
#include "DNA_volume_types.h"
|
||||
|
||||
#include "blender_scene_delegate.h"
|
||||
#include "hydra_scene_delegate.h"
|
||||
#include "volume.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
VolumeData::VolumeData(BlenderSceneDelegate *scene_delegate,
|
||||
VolumeData::VolumeData(HydraSceneDelegate *scene_delegate,
|
||||
Object *object,
|
||||
pxr::SdfPath const &prim_id)
|
||||
: ObjectData(scene_delegate, object, prim_id)
|
||||
@ -30,8 +30,7 @@ void VolumeData::init()
|
||||
field_descriptors_.clear();
|
||||
|
||||
Volume *volume = (Volume *)((Object *)this->id)->data;
|
||||
Main *main = CTX_data_main(scene_delegate_->context);
|
||||
if (!BKE_volume_load(volume, main)) {
|
||||
if (!BKE_volume_load(volume, scene_delegate_->bmain)) {
|
||||
return;
|
||||
}
|
||||
filepath_ = BKE_volume_grids_frame_filepath(volume);
|
||||
@ -160,4 +159,4 @@ void VolumeData::write_materials()
|
||||
mat_data_ = get_or_create_material(mat);
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -7,12 +7,16 @@
|
||||
|
||||
#include "object.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
class VolumeData : public ObjectData {
|
||||
protected:
|
||||
std::string filepath_;
|
||||
pxr::HdVolumeFieldDescriptorVector field_descriptors_;
|
||||
MaterialData *mat_data_ = nullptr;
|
||||
|
||||
public:
|
||||
VolumeData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||
VolumeData(HydraSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||
|
||||
void init() override;
|
||||
void insert() override;
|
||||
@ -28,10 +32,6 @@ class VolumeData : public ObjectData {
|
||||
|
||||
protected:
|
||||
void write_materials() override;
|
||||
|
||||
std::string filepath_;
|
||||
pxr::HdVolumeFieldDescriptorVector field_descriptors_;
|
||||
MaterialData *mat_data_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,24 +1,27 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "volume_modifier.h"
|
||||
|
||||
#include <pxr/usdImaging/usdVolImaging/tokens.h>
|
||||
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_volume_types.h"
|
||||
|
||||
#include "blender_scene_delegate.h"
|
||||
#include "volume_modifier.h"
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_modifier.h"
|
||||
|
||||
#include "hydra_scene_delegate.h"
|
||||
|
||||
PXR_NAMESPACE_OPEN_SCOPE
|
||||
TF_DEFINE_PRIVATE_TOKENS(grid_tokens_, (density)(flame)(shadow)(temperature)(velocity));
|
||||
PXR_NAMESPACE_CLOSE_SCOPE
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
VolumeModifierData::VolumeModifierData(BlenderSceneDelegate *scene_delegate,
|
||||
VolumeModifierData::VolumeModifierData(HydraSceneDelegate *scene_delegate,
|
||||
Object *object,
|
||||
pxr::SdfPath const &prim_id)
|
||||
: VolumeData(scene_delegate, object, prim_id)
|
||||
@ -128,4 +131,4 @@ std::string VolumeModifierData::get_cached_file_path(std::string directory, int
|
||||
return file_path;
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -7,12 +7,12 @@
|
||||
|
||||
#include "volume.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
class VolumeModifierData : public VolumeData {
|
||||
|
||||
public:
|
||||
VolumeModifierData(BlenderSceneDelegate *scene_delegate,
|
||||
VolumeModifierData(HydraSceneDelegate *scene_delegate,
|
||||
Object *object,
|
||||
pxr::SdfPath const &prim_id);
|
||||
static bool is_volume_modifier(Object *object);
|
||||
@ -29,4 +29,4 @@ class VolumeModifierData : public VolumeData {
|
||||
FluidModifierData *modifier_;
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include <filesystem>
|
||||
#include "world.h"
|
||||
|
||||
#include <pxr/base/gf/rotation.h>
|
||||
#include <pxr/base/gf/vec2f.h>
|
||||
@ -11,28 +11,28 @@
|
||||
#include <pxr/imaging/hd/tokens.h>
|
||||
#include <pxr/usd/usdLux/tokens.h>
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BLI_math_rotation.h"
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_runtime.hh"
|
||||
#include "BKE_studiolight.h"
|
||||
#include "BLI_math_rotation.h"
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#include "NOD_shader.h"
|
||||
|
||||
#include "../engine.h"
|
||||
#include "blender_scene_delegate.h"
|
||||
#include "hydra_scene_delegate.h"
|
||||
#include "image.h"
|
||||
#include "world.h"
|
||||
|
||||
/* TODO : add custom tftoken "transparency"? */
|
||||
|
||||
/* NOTE: opacity and blur aren't supported by USD */
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
WorldData::WorldData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id)
|
||||
WorldData::WorldData(HydraSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id)
|
||||
: LightData(scene_delegate, nullptr, prim_id)
|
||||
{
|
||||
prim_type_ = pxr::HdPrimTypeTokens->domeLight;
|
||||
@ -79,8 +79,8 @@ void WorldData::init()
|
||||
return;
|
||||
}
|
||||
|
||||
bNodeSocket color_input = input_node->input_by_identifier("Color");
|
||||
bNodeSocket strength_input = input_node->input_by_identifier("Strength");
|
||||
const bNodeSocket &color_input = input_node->input_by_identifier("Color");
|
||||
const bNodeSocket &strength_input = input_node->input_by_identifier("Strength");
|
||||
|
||||
float const *strength = strength_input.default_value_typed<float>();
|
||||
float const *input_color = color_input.default_value_typed<float>();
|
||||
@ -94,7 +94,7 @@ void WorldData::init()
|
||||
Image *image = (Image *)color_input_node->id;
|
||||
if (image) {
|
||||
std::string image_path = cache_or_get_image_file(
|
||||
image, scene_delegate_->context, &tex->iuser);
|
||||
scene_delegate_->bmain, scene_delegate_->scene, image, &tex->iuser);
|
||||
if (!image_path.empty()) {
|
||||
texture_file = pxr::SdfAssetPath(image_path, image_path);
|
||||
}
|
||||
@ -153,4 +153,4 @@ void WorldData::write_transform()
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1,12 +1,12 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "pxr/base/tf/staticTokens.h"
|
||||
#include <pxr/base/gf/matrix4d.h>
|
||||
#include <pxr/base/tf/staticTokens.h>
|
||||
#include <pxr/base/vt/value.h>
|
||||
#include <pxr/usd/sdf/assetPath.h>
|
||||
#include <pxr/usd/sdf/path.h>
|
||||
@ -16,11 +16,13 @@
|
||||
|
||||
#include "light.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
namespace blender::io::hydra {
|
||||
|
||||
class WorldData : public LightData {
|
||||
public:
|
||||
WorldData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id);
|
||||
pxr::GfMatrix4d transform;
|
||||
|
||||
WorldData(HydraSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id);
|
||||
|
||||
void init() override;
|
||||
void update() override;
|
||||
@ -29,4 +31,4 @@ class WorldData : public LightData {
|
||||
void write_transform() override;
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
} // namespace blender::io::hydra
|
@ -1007,6 +1007,14 @@ static void rna_def_render_engine(BlenderRNA *brna)
|
||||
RNA_define_verify_sdna(1);
|
||||
}
|
||||
|
||||
static void rna_def_hydra_render_engine(BlenderRNA *brna)
|
||||
{
|
||||
/* This is implemented in Python. */
|
||||
StructRNA *srna = RNA_def_struct(brna, "HydraRenderEngine", "RenderEngine");
|
||||
RNA_def_struct_sdna(srna, "RenderEngine");
|
||||
RNA_def_struct_ui_text(srna, "Hydra Render Engine", "Base class from USD Hydra based renderers");
|
||||
}
|
||||
|
||||
static void rna_def_render_result(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@ -1235,6 +1243,7 @@ static void rna_def_render_pass(BlenderRNA *brna)
|
||||
void RNA_def_render(BlenderRNA *brna)
|
||||
{
|
||||
rna_def_render_engine(brna);
|
||||
rna_def_hydra_render_engine(brna);
|
||||
rna_def_render_result(brna);
|
||||
rna_def_render_view(brna);
|
||||
rna_def_render_layer(brna);
|
||||
|
@ -1,9 +1,18 @@
|
||||
# SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright 2011-2022 Blender Foundation
|
||||
|
||||
# This suppresses the warning "This file includes at least one deprecated or antiquated
|
||||
# header which may be removed without further notice at a future date", which is caused
|
||||
# by the USD library including <ext/hash_set> on Linux. This has been reported at:
|
||||
# https://github.com/PixarAnimationStudios/USD/issues/1057.
|
||||
if(UNIX AND NOT APPLE)
|
||||
add_definitions(-D_GLIBCXX_PERMIT_BACKWARD_HASH)
|
||||
endif()
|
||||
if(WIN32)
|
||||
add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN -DBOOST_DEBUG_PYTHON)
|
||||
endif()
|
||||
add_definitions(-DBOOST_ALL_NO_LIB)
|
||||
|
||||
# Precompiled Linux libs are made with GCC, and USD uses some extensions
|
||||
# which lead to an incompatible ABI for Clang. Using those extensions with
|
||||
@ -12,7 +21,6 @@ if(UNIX AND NOT APPLE)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
if(EXISTS ${LIBDIR})
|
||||
add_definitions(-DARCH_HAS_GNU_STL_EXTENSIONS)
|
||||
add_cxx_flag("-Wno-deprecated")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@ -20,15 +28,11 @@ endif()
|
||||
# USD headers use deprecated TBB headers, silence warning.
|
||||
add_definitions(-DTBB_SUPPRESS_DEPRECATED_MESSAGES=1)
|
||||
|
||||
add_definitions(${GFLAGS_DEFINES})
|
||||
add_definitions(-DBLENDER_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
|
||||
|
||||
add_definitions(-DBOOST_ALL_NO_LIB)
|
||||
|
||||
if(WIN32)
|
||||
# Some USD library headers trigger the "unreferenced formal parameter" warning alert.
|
||||
# Some USD library headers trigger the "unreferenced formal parameter"
|
||||
# warning alert.
|
||||
# Silence them by restore warn C4100 back to w4
|
||||
remove_cc_flag(/w34100)
|
||||
remove_cc_flag("/w34100")
|
||||
endif()
|
||||
|
||||
set(INC
|
||||
@ -46,8 +50,9 @@ set(INC
|
||||
../../gpu
|
||||
../../gpu/intern
|
||||
../../python/intern
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
..
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna/intern
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
@ -65,64 +70,27 @@ set(LIB
|
||||
${BOOST_LIBRARIES}
|
||||
${USD_LIBRARIES}
|
||||
${TBB_LIBRARIES}
|
||||
bf_usd
|
||||
)
|
||||
|
||||
if(WITH_MATERIALX)
|
||||
add_definitions(-DWITH_MATERIALX)
|
||||
list(APPEND LIB MaterialXCore)
|
||||
endif()
|
||||
|
||||
set(SRC
|
||||
python.cc
|
||||
|
||||
camera.h
|
||||
camera.cc
|
||||
engine.h
|
||||
engine.cc
|
||||
final_engine.h
|
||||
final_engine.cc
|
||||
preview_engine.h
|
||||
light_tasks_delegate.cc
|
||||
preview_engine.cc
|
||||
viewport_engine.h
|
||||
python.cc
|
||||
render_task_delegate.cc
|
||||
viewport_engine.cc
|
||||
|
||||
render_task_delegate.cc
|
||||
render_task_delegate.h
|
||||
light_tasks_delegate.cc
|
||||
engine.h
|
||||
final_engine.h
|
||||
light_tasks_delegate.h
|
||||
|
||||
settings.h
|
||||
|
||||
scene_delegate/blender_scene_delegate.cc
|
||||
scene_delegate/blender_scene_delegate.h
|
||||
scene_delegate/curves.cc
|
||||
scene_delegate/curves.h
|
||||
scene_delegate/id.cc
|
||||
scene_delegate/id.h
|
||||
scene_delegate/image.cc
|
||||
scene_delegate/image.h
|
||||
scene_delegate/instancer.cc
|
||||
scene_delegate/instancer.h
|
||||
scene_delegate/light.cc
|
||||
scene_delegate/light.h
|
||||
scene_delegate/material.cc
|
||||
scene_delegate/material.h
|
||||
scene_delegate/mesh.cc
|
||||
scene_delegate/mesh.h
|
||||
scene_delegate/mtlx_hydra_adapter.cc
|
||||
scene_delegate/mtlx_hydra_adapter.h
|
||||
scene_delegate/object.cc
|
||||
scene_delegate/object.h
|
||||
scene_delegate/usd_scene_delegate.cc
|
||||
scene_delegate/usd_scene_delegate.hh
|
||||
scene_delegate/volume.cc
|
||||
scene_delegate/volume.h
|
||||
scene_delegate/volume_modifier.cc
|
||||
scene_delegate/volume_modifier.h
|
||||
scene_delegate/world.cc
|
||||
scene_delegate/world.h
|
||||
preview_engine.h
|
||||
render_task_delegate.h
|
||||
viewport_engine.h
|
||||
)
|
||||
|
||||
blender_add_lib(bf_render_hydra "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
||||
# RNA_prototypes.h
|
||||
add_dependencies(bf_render_hydra bf_rna)
|
||||
|
@ -1,5 +1,7 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
#include <pxr/base/plug/plugin.h>
|
||||
#include <pxr/base/plug/registry.h>
|
||||
@ -10,18 +12,22 @@
|
||||
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "GPU_context.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "engine.h"
|
||||
#include "RE_engine.h"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
CLG_LOGREF_DECLARE_GLOBAL(LOG_RENDER_HYDRA, "render.hydra");
|
||||
|
||||
Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
|
||||
: render_delegate_name(render_delegate_name), bl_engine_(bl_engine)
|
||||
: render_delegate_name_(render_delegate_name), bl_engine_(bl_engine)
|
||||
{
|
||||
pxr::HdRendererPluginRegistry ®istry = pxr::HdRendererPluginRegistry::GetInstance();
|
||||
|
||||
@ -39,10 +45,10 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
|
||||
|
||||
hd_drivers.push_back(&hgi_driver_);
|
||||
}
|
||||
render_delegate_ = registry.CreateRenderDelegate(pxr::TfToken(render_delegate_name));
|
||||
render_delegate_ = registry.CreateRenderDelegate(pxr::TfToken(render_delegate_name_));
|
||||
|
||||
if (!render_delegate_) {
|
||||
throw std::runtime_error("Cannot create render delegate: " + render_delegate_name);
|
||||
throw std::runtime_error("Cannot create render delegate: " + render_delegate_name_);
|
||||
}
|
||||
|
||||
render_index_.reset(pxr::HdRenderIndex::New(render_delegate_.Get(), hd_drivers));
|
||||
@ -59,7 +65,7 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
|
||||
}
|
||||
render_task_delegate_->set_camera(free_camera_delegate_->GetCameraId());
|
||||
|
||||
if (render_delegate_name == "HdStormRendererPlugin") {
|
||||
if (render_delegate_name_ == "HdStormRendererPlugin") {
|
||||
light_tasks_delegate_ = std::make_unique<LightTasksDelegate>(
|
||||
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("lightTasks"));
|
||||
light_tasks_delegate_->set_camera(free_camera_delegate_->GetCameraId());
|
||||
@ -78,10 +84,10 @@ void Engine::sync(Depsgraph *depsgraph, bContext *context)
|
||||
|
||||
if (!hydra_scene_delegate_) {
|
||||
pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene");
|
||||
hydra_scene_delegate_ = std::make_unique<BlenderSceneDelegate>(
|
||||
hydra_scene_delegate_ = std::make_unique<io::hydra::HydraSceneDelegate>(
|
||||
render_index_.get(), scene_path, scene_delegate_settings_);
|
||||
}
|
||||
hydra_scene_delegate_->populate(depsgraph, context);
|
||||
hydra_scene_delegate_->populate(depsgraph, CTX_wm_view3d(context));
|
||||
}
|
||||
else {
|
||||
/* Slow USD export for reference. */
|
||||
@ -93,10 +99,10 @@ void Engine::sync(Depsgraph *depsgraph, bContext *context)
|
||||
|
||||
if (!usd_scene_delegate_) {
|
||||
pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("usd_scene");
|
||||
usd_scene_delegate_ = std::make_unique<USDSceneDelegate>(
|
||||
usd_scene_delegate_ = std::make_unique<io::hydra::USDSceneDelegate>(
|
||||
render_index_.get(), scene_path, scene_delegate_settings_);
|
||||
}
|
||||
usd_scene_delegate_->populate(depsgraph, context);
|
||||
usd_scene_delegate_->populate(depsgraph);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <pxr/imaging/hd/driver.h>
|
||||
#include <pxr/imaging/hd/engine.h>
|
||||
@ -13,21 +14,46 @@
|
||||
#include <pxr/usd/usd/stage.h>
|
||||
#include <pxr/usdImaging/usdImaging/delegate.h>
|
||||
|
||||
#include "RE_engine.h"
|
||||
|
||||
#include "CLG_log.h"
|
||||
#include "hydra/hydra_scene_delegate.h"
|
||||
#include "hydra/settings.h"
|
||||
#include "hydra/usd_scene_delegate.h"
|
||||
|
||||
#include "light_tasks_delegate.h"
|
||||
#include "render_task_delegate.h"
|
||||
|
||||
#include "scene_delegate/blender_scene_delegate.h"
|
||||
#include "scene_delegate/usd_scene_delegate.hh"
|
||||
struct bContext;
|
||||
struct RenderEngine;
|
||||
struct CLG_LogRef;
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
extern struct CLG_LogRef *LOG_RENDER_HYDRA;
|
||||
|
||||
struct RenderDelegateSettings {
|
||||
Map<std::string, pxr::TfToken> aovs;
|
||||
};
|
||||
|
||||
class Engine {
|
||||
protected:
|
||||
std::string render_delegate_name_;
|
||||
RenderEngine *bl_engine_ = nullptr;
|
||||
|
||||
/* The order is important due to deletion order */
|
||||
pxr::HgiUniquePtr hgi_;
|
||||
pxr::HdDriver hgi_driver_;
|
||||
pxr::HdPluginRenderDelegateUniqueHandle render_delegate_;
|
||||
std::unique_ptr<pxr::HdRenderIndex> render_index_;
|
||||
|
||||
io::hydra::HydraDelegateSettings scene_delegate_settings_;
|
||||
std::unique_ptr<io::hydra::HydraSceneDelegate> hydra_scene_delegate_;
|
||||
std::unique_ptr<io::hydra::USDSceneDelegate> usd_scene_delegate_;
|
||||
|
||||
RenderDelegateSettings render_delegate_settings_;
|
||||
std::unique_ptr<RenderTaskDelegate> render_task_delegate_;
|
||||
std::unique_ptr<pxr::HdxFreeCameraSceneDelegate> free_camera_delegate_;
|
||||
std::unique_ptr<LightTasksDelegate> light_tasks_delegate_;
|
||||
std::unique_ptr<pxr::HdEngine> engine_;
|
||||
|
||||
public:
|
||||
Engine(RenderEngine *bl_engine, const std::string &render_delegate_name);
|
||||
DagerD marked this conversation as resolved
Outdated
|
||||
virtual ~Engine() = default;
|
||||
@ -38,28 +64,8 @@ class Engine {
|
||||
void set_sync_setting(const std::string &key, const pxr::VtValue &val);
|
||||
void set_render_setting(const std::string &key, const pxr::VtValue &val);
|
||||
|
||||
std::string render_delegate_name;
|
||||
|
||||
protected:
|
||||
float renderer_percent_done();
|
||||
|
||||
RenderEngine *bl_engine_ = nullptr;
|
||||
|
||||
/* The order is important due to deletion order */
|
||||
pxr::HgiUniquePtr hgi_;
|
||||
pxr::HdDriver hgi_driver_;
|
||||
pxr::HdPluginRenderDelegateUniqueHandle render_delegate_;
|
||||
std::unique_ptr<pxr::HdRenderIndex> render_index_;
|
||||
|
||||
SceneDelegateSettings scene_delegate_settings_;
|
||||
std::unique_ptr<BlenderSceneDelegate> hydra_scene_delegate_;
|
||||
std::unique_ptr<USDSceneDelegate> usd_scene_delegate_;
|
||||
|
||||
RenderDelegateSettings render_delegate_settings_;
|
||||
std::unique_ptr<RenderTaskDelegate> render_task_delegate_;
|
||||
std::unique_ptr<pxr::HdxFreeCameraSceneDelegate> free_camera_delegate_;
|
||||
std::unique_ptr<LightTasksDelegate> light_tasks_delegate_;
|
||||
std::unique_ptr<pxr::HdEngine> engine_;
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
|
@ -1,18 +1,25 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "final_engine.h"
|
||||
|
||||
#include <pxr/imaging/hd/light.h>
|
||||
#include <pxr/imaging/hd/renderBuffer.h>
|
||||
|
||||
#include "BKE_lib_id.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BLI_timecode.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "BKE_lib_id.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "camera.h"
|
||||
#include "final_engine.h"
|
||||
#include "RE_engine.h"
|
||||
|
||||
#include "hydra/camera.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
@ -21,8 +28,8 @@ void FinalEngine::render(Depsgraph *depsgraph)
|
||||
const Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||
const ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
|
||||
|
||||
char scene_name[MAX_NAME];
|
||||
BKE_id_full_name_get(scene_name, (ID *)scene, 0);
|
||||
char scene_name[MAX_ID_FULL_NAME];
|
||||
BKE_id_full_name_get(scene_name, &scene->id, 0);
|
||||
scene_name_ = scene_name;
|
||||
layer_name_ = view_layer->name;
|
||||
|
||||
@ -37,7 +44,7 @@ void FinalEngine::render(Depsgraph *depsgraph)
|
||||
pxr::GfVec2i image_res(r.xsch * r.size / 100, r.ysch * r.size / 100);
|
||||
resolution_ = pxr::GfVec2i(int(image_res[0] * border[2]), int(image_res[1] * border[3]));
|
||||
pxr::GfCamera camera =
|
||||
CameraData(scene->camera, image_res, pxr::GfVec4f(0, 0, 1, 1)).gf_camera(border);
|
||||
io::hydra::CameraData(scene->camera, image_res, pxr::GfVec4f(0, 0, 1, 1)).gf_camera(border);
|
||||
|
||||
free_camera_delegate_->SetCamera(camera);
|
||||
render_task_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1]));
|
||||
@ -107,19 +114,22 @@ void FinalEngine::notify_status(float progress, const std::string &title, const
|
||||
|
||||
void FinalEngine::update_render_result()
|
||||
{
|
||||
RenderResult *result = RE_engine_begin_result(
|
||||
RenderResult *rr = RE_engine_begin_result(
|
||||
bl_engine_, 0, 0, resolution_[0], resolution_[1], layer_name_.c_str(), nullptr);
|
||||
|
||||
/* TODO: only for the first render layer */
|
||||
RenderLayer *layer = (RenderLayer *)result->layers.first;
|
||||
for (RenderPass *pass = (RenderPass *)layer->passes.first; pass != nullptr; pass = pass->next) {
|
||||
pxr::TfToken *aov_token = render_delegate_settings_.aovs.lookup_ptr(pass->name);
|
||||
if (aov_token) {
|
||||
render_task_delegate_->read_aov(*aov_token, pass->ibuf->float_buffer.data);
|
||||
RenderLayer *rlayer = static_cast<RenderLayer *>(
|
||||
BLI_findstring(&rr->layers, layer_name_.c_str(), offsetof(RenderLayer, name)));
|
||||
|
||||
if (rlayer) {
|
||||
LISTBASE_FOREACH (RenderPass *, rpass, &rlayer->passes) {
|
||||
pxr::TfToken *aov_token = render_delegate_settings_.aovs.lookup_ptr(rpass->name);
|
||||
if (aov_token) {
|
||||
render_task_delegate_->read_aov(*aov_token, rpass->ibuf->float_buffer.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RE_engine_end_result(bl_engine_, result, false, false, false);
|
||||
RE_engine_end_result(bl_engine_, rr, false, false, false);
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -8,6 +8,11 @@
|
||||
namespace blender::render::hydra {
|
||||
|
||||
class FinalEngine : public Engine {
|
||||
protected:
|
||||
std::string scene_name_;
|
||||
std::string layer_name_;
|
||||
pxr::GfVec2i resolution_;
|
||||
|
||||
public:
|
||||
using Engine::Engine;
|
||||
|
||||
@ -16,10 +21,6 @@ class FinalEngine : public Engine {
|
||||
protected:
|
||||
virtual void notify_status(float progress, const std::string &title, const std::string &info);
|
||||
void update_render_result();
|
||||
|
||||
std::string scene_name_;
|
||||
std::string layer_name_;
|
||||
pxr::GfVec2i resolution_;
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "light_tasks_delegate.h"
|
||||
#include "engine.h"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "preview_engine.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
void PreviewEngine::notify_status(float progress,
|
||||
const std::string &title,
|
||||
const std::string &info)
|
||||
void PreviewEngine::notify_status(float /* progress */,
|
||||
const std::string & /* title */,
|
||||
const std::string & /* info */)
|
||||
{
|
||||
/* Empty fucntion */
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,58 +1,30 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include <boost/python/extract.hpp>
|
||||
|
||||
#include <pxr/base/plug/plugin.h>
|
||||
#include <pxr/base/plug/registry.h>
|
||||
#include <pxr/usd/usd/stage.h>
|
||||
#include <pxr/usdImaging/usdImagingGL/engine.h>
|
||||
|
||||
#include "BKE_appdir.h"
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_path_util.h"
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "final_engine.h"
|
||||
#include "preview_engine.h"
|
||||
#include "scene_delegate/image.h"
|
||||
#include "viewport_engine.h"
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include "RE_engine.h"
|
||||
|
||||
#include "bpy_rna.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "RE_engine.h"
|
||||
|
||||
#include "RNA_prototypes.h"
|
||||
|
||||
#include "hydra/image.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
static PyObject *register_plugins_func(PyObject * /*self*/, PyObject *args)
|
||||
template<typename T> T *pyrna_to_pointer(PyObject *pyobject, const StructRNA *rnatype)
|
||||
{
|
||||
PyObject *pyplugin_dirs;
|
||||
if (!PyArg_ParseTuple(args, "O", &pyplugin_dirs)) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
std::vector<std::string> plugin_dirs;
|
||||
PyObject *pyiter, *pyitem;
|
||||
|
||||
pyiter = PyObject_GetIter(pyplugin_dirs);
|
||||
if (pyiter) {
|
||||
while ((pyitem = PyIter_Next(pyiter))) {
|
||||
plugin_dirs.push_back(PyUnicode_AsUTF8(pyitem));
|
||||
Py_DECREF(pyitem);
|
||||
}
|
||||
Py_DECREF(pyiter);
|
||||
}
|
||||
|
||||
pxr::PlugRegistry ®istry = pxr::PlugRegistry::GetInstance();
|
||||
registry.RegisterPlugins(plugin_dirs);
|
||||
|
||||
/* logging */
|
||||
std::stringstream ss;
|
||||
ss << "plugins=[";
|
||||
for (auto &s : plugin_dirs) {
|
||||
ss << s << ", ";
|
||||
}
|
||||
ss << "]";
|
||||
CLOG_INFO(LOG_RENDER_HYDRA, 0, "Register %s", ss.str().c_str());
|
||||
|
||||
Py_RETURN_NONE;
|
||||
const PointerRNA *ptr = pyrna_struct_as_ptr_or_null(pyobject, rnatype);
|
||||
return (ptr) ? static_cast<T *>(ptr->data) : nullptr;
|
||||
}
|
||||
|
||||
static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args)
|
||||
@ -63,7 +35,7 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
RenderEngine *bl_engine = (RenderEngine *)PyLong_AsVoidPtr(pyengine);
|
||||
RenderEngine *bl_engine = pyrna_to_pointer<RenderEngine>(pyengine, &RNA_RenderEngine);
|
||||
|
||||
Engine *engine = nullptr;
|
||||
try {
|
||||
@ -94,23 +66,23 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine);
|
||||
Engine *engine = static_cast<Engine *>(PyLong_AsVoidPtr(pyengine));
|
||||
delete engine;
|
||||
|
||||
CLOG_INFO(LOG_RENDER_HYDRA, 1, "Engine %p", engine);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *engine_sync_func(PyObject * /*self*/, PyObject *args)
|
||||
static PyObject *engine_update_func(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
PyObject *pyengine, *pydepsgraph, *pycontext;
|
||||
if (!PyArg_ParseTuple(args, "OOO", &pyengine, &pydepsgraph, &pycontext)) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine);
|
||||
Depsgraph *depsgraph = (Depsgraph *)PyLong_AsVoidPtr(pydepsgraph);
|
||||
bContext *context = (bContext *)PyLong_AsVoidPtr(pycontext);
|
||||
Engine *engine = static_cast<Engine *>(PyLong_AsVoidPtr(pyengine));
|
||||
Depsgraph *depsgraph = pyrna_to_pointer<Depsgraph>(pydepsgraph, &RNA_Depsgraph);
|
||||
bContext *context = pyrna_to_pointer<bContext>(pycontext, &RNA_Context);
|
||||
|
||||
CLOG_INFO(LOG_RENDER_HYDRA, 2, "Engine %p", engine);
|
||||
engine->sync(depsgraph, context);
|
||||
@ -126,8 +98,8 @@ static PyObject *engine_render_func(PyObject * /*self*/, PyObject *args)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine);
|
||||
Depsgraph *depsgraph = (Depsgraph *)PyLong_AsVoidPtr(pydepsgraph);
|
||||
Engine *engine = static_cast<Engine *>(PyLong_AsVoidPtr(pyengine));
|
||||
Depsgraph *depsgraph = pyrna_to_pointer<Depsgraph>(pydepsgraph, &RNA_Depsgraph);
|
||||
|
||||
CLOG_INFO(LOG_RENDER_HYDRA, 2, "Engine %p", engine);
|
||||
|
||||
@ -146,9 +118,9 @@ static PyObject *engine_view_draw_func(PyObject * /*self*/, PyObject *args)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
ViewportEngine *engine = (ViewportEngine *)PyLong_AsVoidPtr(pyengine);
|
||||
Depsgraph *depsgraph = (Depsgraph *)PyLong_AsVoidPtr(pydepsgraph);
|
||||
bContext *context = (bContext *)PyLong_AsVoidPtr(pycontext);
|
||||
ViewportEngine *engine = static_cast<ViewportEngine *>(PyLong_AsVoidPtr(pyengine));
|
||||
Depsgraph *depsgraph = pyrna_to_pointer<Depsgraph>(pydepsgraph, &RNA_Depsgraph);
|
||||
bContext *context = pyrna_to_pointer<bContext>(pycontext, &RNA_Context);
|
||||
|
||||
CLOG_INFO(LOG_RENDER_HYDRA, 3, "Engine %p", engine);
|
||||
|
||||
@ -186,7 +158,7 @@ static PyObject *engine_set_sync_setting_func(PyObject * /*self*/, PyObject *arg
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine);
|
||||
Engine *engine = static_cast<Engine *>(PyLong_AsVoidPtr(pyengine));
|
||||
|
||||
CLOG_INFO(LOG_RENDER_HYDRA, 3, "Engine %p: %s", engine, key);
|
||||
engine->set_sync_setting(key, get_setting_val(pyval));
|
||||
@ -202,7 +174,7 @@ static PyObject *engine_set_render_setting_func(PyObject * /*self*/, PyObject *a
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine);
|
||||
Engine *engine = static_cast<Engine *>(PyLong_AsVoidPtr(pyengine));
|
||||
|
||||
CLOG_INFO(LOG_RENDER_HYDRA, 3, "Engine %p: %s", engine, key);
|
||||
engine->set_render_setting(key, get_setting_val(pyval));
|
||||
@ -217,19 +189,18 @@ static PyObject *cache_or_get_image_file_func(PyObject * /*self*/, PyObject *arg
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
bContext *context = (bContext *)PyLong_AsVoidPtr(pycontext);
|
||||
Image *image = (Image *)PyLong_AsVoidPtr(pyimage);
|
||||
bContext *context = static_cast<bContext *>(PyLong_AsVoidPtr(pycontext));
|
||||
Image *image = static_cast<Image *>(PyLong_AsVoidPtr(pyimage));
|
||||
|
||||
std::string image_path = cache_or_get_image_file(image, context, nullptr);
|
||||
std::string image_path = io::hydra::cache_or_get_image_file(
|
||||
CTX_data_main(context), CTX_data_scene(context), image, nullptr);
|
||||
return PyUnicode_FromString(image_path.c_str());
|
||||
}
|
||||
|
||||
static PyMethodDef methods[] = {
|
||||
{"register_plugins", register_plugins_func, METH_VARARGS, ""},
|
||||
|
||||
{"engine_create", engine_create_func, METH_VARARGS, ""},
|
||||
{"engine_free", engine_free_func, METH_VARARGS, ""},
|
||||
{"engine_sync", engine_sync_func, METH_VARARGS, ""},
|
||||
{"engine_update", engine_update_func, METH_VARARGS, ""},
|
||||
{"engine_render", engine_render_func, METH_VARARGS, ""},
|
||||
{"engine_view_draw", engine_view_draw_func, METH_VARARGS, ""},
|
||||
{"engine_set_sync_setting", engine_set_sync_setting_func, METH_VARARGS, ""},
|
||||
@ -258,6 +229,8 @@ static struct PyModuleDef module = {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyObject *BPyInit_hydra(void);
|
||||
|
||||
PyObject *BPyInit_hydra(void)
|
||||
{
|
||||
PyObject *mod = PyModule_Create(&blender::render::hydra::module);
|
||||
|
@ -1,8 +1,12 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "render_task_delegate.h"
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
#include "GPU_context.h"
|
||||
|
||||
#include <pxr/imaging/hd/renderBuffer.h>
|
||||
#include <pxr/imaging/hd/renderDelegate.h>
|
||||
#include <pxr/imaging/hdx/renderTask.h>
|
||||
@ -18,13 +22,13 @@ RenderTaskDelegate::RenderTaskDelegate(pxr::HdRenderIndex *parent_index,
|
||||
pxr::SdfPath const &delegate_id)
|
||||
: pxr::HdSceneDelegate(parent_index, delegate_id)
|
||||
{
|
||||
render_task_id_ = GetDelegateID().AppendElementString("renderTask");
|
||||
GetRenderIndex().InsertTask<pxr::HdxRenderTask>(this, render_task_id_);
|
||||
task_id_ = GetDelegateID().AppendElementString("renderTask");
|
||||
GetRenderIndex().InsertTask<pxr::HdxRenderTask>(this, task_id_);
|
||||
|
||||
render_task_params_.enableLighting = true;
|
||||
render_task_params_.alphaThreshold = 0.1f;
|
||||
task_params_.enableLighting = true;
|
||||
task_params_.alphaThreshold = 0.1f;
|
||||
|
||||
CLOG_INFO(LOG_RENDER_HYDRA, 1, "%s", render_task_id_.GetText());
|
||||
CLOG_INFO(LOG_RENDER_HYDRA, 1, "%s", task_id_.GetText());
|
||||
}
|
||||
|
||||
pxr::VtValue RenderTaskDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key)
|
||||
@ -32,7 +36,7 @@ pxr::VtValue RenderTaskDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const
|
||||
CLOG_INFO(LOG_RENDER_HYDRA, 3, "%s, %s", id.GetText(), key.GetText());
|
||||
|
||||
if (key == pxr::HdTokens->params) {
|
||||
return pxr::VtValue(render_task_params_);
|
||||
return pxr::VtValue(task_params_);
|
||||
}
|
||||
if (key == pxr::HdTokens->collection) {
|
||||
return pxr::VtValue(pxr::HdRprimCollection(
|
||||
@ -57,32 +61,32 @@ pxr::HdRenderBufferDescriptor RenderTaskDelegate::GetRenderBufferDescriptor(pxr:
|
||||
|
||||
pxr::HdTaskSharedPtr RenderTaskDelegate::task()
|
||||
{
|
||||
return GetRenderIndex().GetTask(render_task_id_);
|
||||
return GetRenderIndex().GetTask(task_id_);
|
||||
}
|
||||
|
||||
void RenderTaskDelegate::set_camera(pxr::SdfPath const &camera_id)
|
||||
{
|
||||
if (render_task_params_.camera == camera_id) {
|
||||
if (task_params_.camera == camera_id) {
|
||||
return;
|
||||
}
|
||||
render_task_params_.camera = camera_id;
|
||||
GetRenderIndex().GetChangeTracker().MarkTaskDirty(render_task_id_,
|
||||
task_params_.camera = camera_id;
|
||||
GetRenderIndex().GetChangeTracker().MarkTaskDirty(task_id_,
|
||||
pxr::HdChangeTracker::DirtyParams);
|
||||
}
|
||||
|
||||
bool RenderTaskDelegate::is_converged()
|
||||
{
|
||||
return ((pxr::HdxRenderTask *)task().get())->IsConverged();
|
||||
return static_cast<pxr::HdxRenderTask *>(task().get())->IsConverged();
|
||||
}
|
||||
|
||||
void RenderTaskDelegate::set_viewport(pxr::GfVec4d const &viewport)
|
||||
{
|
||||
if (render_task_params_.viewport == viewport) {
|
||||
if (task_params_.viewport == viewport) {
|
||||
return;
|
||||
}
|
||||
auto &render_index = GetRenderIndex();
|
||||
render_task_params_.viewport = viewport;
|
||||
render_index.GetChangeTracker().MarkTaskDirty(render_task_id_,
|
||||
task_params_.viewport = viewport;
|
||||
render_index.GetChangeTracker().MarkTaskDirty(task_id_,
|
||||
pxr::HdChangeTracker::DirtyParams);
|
||||
|
||||
int w = viewport[2] - viewport[0];
|
||||
@ -108,8 +112,8 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
|
||||
return;
|
||||
}
|
||||
|
||||
int w = render_task_params_.viewport[2] - render_task_params_.viewport[0];
|
||||
int h = render_task_params_.viewport[3] - render_task_params_.viewport[1];
|
||||
int w = task_params_.viewport[2] - task_params_.viewport[0];
|
||||
int h = task_params_.viewport[3] - task_params_.viewport[1];
|
||||
render_index.InsertBprim(pxr::HdPrimTypeTokens->renderBuffer, this, buf_id);
|
||||
buffer_descriptors_[buf_id] = pxr::HdRenderBufferDescriptor(
|
||||
pxr::GfVec3i(w, h, 1), aov_desc.format, aov_desc.multiSampled);
|
||||
@ -118,8 +122,8 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
|
||||
binding.aovName = aov_key;
|
||||
binding.renderBufferId = buf_id;
|
||||
binding.aovSettings = aov_desc.aovSettings;
|
||||
render_task_params_.aovBindings.push_back(binding);
|
||||
render_index.GetChangeTracker().MarkTaskDirty(render_task_id_,
|
||||
task_params_.aovBindings.push_back(binding);
|
||||
render_index.GetChangeTracker().MarkTaskDirty(task_id_,
|
||||
pxr::HdChangeTracker::DirtyParams);
|
||||
|
||||
CLOG_INFO(LOG_RENDER_HYDRA, 1, "%s", aov_key.GetText());
|
||||
@ -127,8 +131,8 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
|
||||
|
||||
void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data)
|
||||
{
|
||||
pxr::HdRenderBuffer *buffer = (pxr::HdRenderBuffer *)GetRenderIndex().GetBprim(
|
||||
pxr::HdPrimTypeTokens->renderBuffer, buffer_id(aov_key));
|
||||
pxr::HdRenderBuffer *buffer = static_cast<pxr::HdRenderBuffer *>(
|
||||
GetRenderIndex().GetBprim(pxr::HdPrimTypeTokens->renderBuffer, buffer_id(aov_key)));
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
@ -162,12 +166,12 @@ pxr::SdfPath RenderTaskDelegate::buffer_id(pxr::TfToken const &aov_key) const
|
||||
|
||||
void GPURenderTaskDelegate::set_viewport(pxr::GfVec4d const &viewport)
|
||||
{
|
||||
if (render_task_params_.viewport == viewport) {
|
||||
if (task_params_.viewport == viewport) {
|
||||
return;
|
||||
}
|
||||
auto &render_index = GetRenderIndex();
|
||||
render_task_params_.viewport = viewport;
|
||||
render_index.GetChangeTracker().MarkTaskDirty(render_task_id_,
|
||||
task_params_.viewport = viewport;
|
||||
render_index.GetChangeTracker().MarkTaskDirty(task_id_,
|
||||
pxr::HdChangeTracker::DirtyParams);
|
||||
|
||||
if (tex_color_) {
|
||||
@ -203,8 +207,8 @@ void GPURenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
|
||||
}
|
||||
|
||||
*tex = GPU_texture_create_2d(("tex_render_hydra_" + aov_key.GetString()).c_str(),
|
||||
render_task_params_.viewport[2] - render_task_params_.viewport[0],
|
||||
render_task_params_.viewport[3] - render_task_params_.viewport[1],
|
||||
task_params_.viewport[2] - task_params_.viewport[0],
|
||||
task_params_.viewport[3] - task_params_.viewport[1],
|
||||
1,
|
||||
format,
|
||||
GPU_TEXTURE_USAGE_GENERAL,
|
||||
@ -268,17 +272,21 @@ void GPURenderTaskDelegate::bind()
|
||||
float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
GPU_framebuffer_clear_color_depth(framebuffer_, clear_color, 1.0f);
|
||||
|
||||
/* Important: we have to create and bind at least one Vertex Array Object (VAO) before render
|
||||
* execution: More info at https://open.gl/drawing */
|
||||
if (VAO_ == 0) {
|
||||
glGenVertexArrays(1, &VAO_);
|
||||
/* Workaround missing/buggy VAOs in hgiGL and hdSt. For OpenGL compatibility
|
||||
* profile this is not a problem, but for core profile it is. */
|
||||
if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) {
|
||||
if (VAO_ == 0) {
|
||||
glGenVertexArrays(1, &VAO_);
|
||||
}
|
||||
glBindVertexArray(VAO_);
|
||||
}
|
||||
glBindVertexArray(VAO_);
|
||||
}
|
||||
|
||||
void GPURenderTaskDelegate::unbind()
|
||||
{
|
||||
glDeleteVertexArrays(1, &VAO_);
|
||||
if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) {
|
||||
glDeleteVertexArrays(1, &VAO_);
|
||||
}
|
||||
GPU_framebuffer_free(framebuffer_);
|
||||
GPU_texture_free(tex_color_);
|
||||
GPU_texture_free(tex_depth_);
|
||||
|
@ -1,18 +1,25 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pxr/imaging/hd/sceneDelegate.h>
|
||||
#include <pxr/imaging/hdx/renderSetupTask.h>
|
||||
#include <pxr/imaging/hdx/visualizeAovTask.h>
|
||||
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_texture.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
/* Delegate to create a render task with given camera, viewport and AOVs. */
|
||||
|
||||
class RenderTaskDelegate : public pxr::HdSceneDelegate {
|
||||
protected:
|
||||
pxr::SdfPath task_id_;
|
||||
pxr::HdxRenderTaskParams task_params_;
|
||||
pxr::TfHashMap<pxr::SdfPath, pxr::HdRenderBufferDescriptor, pxr::SdfPath::Hash>
|
||||
buffer_descriptors_;
|
||||
|
||||
public:
|
||||
RenderTaskDelegate(pxr::HdRenderIndex *parent_index, pxr::SdfPath const &delegate_id);
|
||||
~RenderTaskDelegate() override = default;
|
||||
@ -34,14 +41,15 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate {
|
||||
|
||||
protected:
|
||||
pxr::SdfPath buffer_id(pxr::TfToken const &aov_key) const;
|
||||
|
||||
pxr::SdfPath render_task_id_;
|
||||
pxr::HdxRenderTaskParams render_task_params_;
|
||||
pxr::TfHashMap<pxr::SdfPath, pxr::HdRenderBufferDescriptor, pxr::SdfPath::Hash>
|
||||
buffer_descriptors_;
|
||||
};
|
||||
|
||||
class GPURenderTaskDelegate : public RenderTaskDelegate {
|
||||
private:
|
||||
GPUFrameBuffer *framebuffer_ = nullptr;
|
||||
GPUTexture *tex_color_ = nullptr;
|
||||
GPUTexture *tex_depth_ = nullptr;
|
||||
unsigned int VAO_ = 0;
|
||||
|
||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
Looks like aov_task doesn't need. Looks like aov_task doesn't need.
|
||||
public:
|
||||
using RenderTaskDelegate::RenderTaskDelegate;
|
||||
|
||||
@ -51,12 +59,6 @@ class GPURenderTaskDelegate : public RenderTaskDelegate {
|
||||
void read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) override;
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
|
||||
private:
|
||||
GPUFrameBuffer *framebuffer_ = nullptr;
|
||||
GPUTexture *tex_color_ = nullptr;
|
||||
GPUTexture *tex_depth_ = nullptr;
|
||||
unsigned int VAO_ = 0;
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
|
@ -1,15 +0,0 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#include "BKE_lib_id.h"
|
||||
|
||||
#include "id.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
IdData::IdData(BlenderSceneDelegate *scene_delegate, ID *id, pxr::SdfPath const &prim_id)
|
||||
: id(id), prim_id(prim_id), scene_delegate_(scene_delegate)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
@ -1,14 +0,0 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_image.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
std::string cache_or_get_image_file(Image *image, bContext *context, ImageUser *iuser);
|
||||
std::string cache_image_color(float color[4]);
|
||||
|
||||
} // namespace blender::render::hydra
|
@ -1,321 +0,0 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#include <pxr/base/gf/vec2f.h>
|
||||
#include <pxr/imaging/hd/light.h>
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "blender_scene_delegate.h"
|
||||
#include "instancer.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id)
|
||||
: IdData(scene_delegate, nullptr, prim_id)
|
||||
{
|
||||
}
|
||||
|
||||
bool InstancerData::is_instance_supported(Object *object)
|
||||
{
|
||||
switch (object->type) {
|
||||
case OB_MESH:
|
||||
case OB_SURF:
|
||||
case OB_FONT:
|
||||
case OB_CURVES_LEGACY:
|
||||
case OB_MBALL:
|
||||
case OB_LAMP:
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void InstancerData::init() {}
|
||||
|
||||
void InstancerData::insert() {}
|
||||
|
||||
void InstancerData::remove()
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 1, "%s", prim_id.GetText());
|
||||
for (auto &m_inst : mesh_instances_.values()) {
|
||||
m_inst.data->remove();
|
||||
}
|
||||
if (!mesh_instances_.is_empty()) {
|
||||
scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id);
|
||||
}
|
||||
mesh_instances_.clear();
|
||||
|
||||
for (auto &l_inst : light_instances_.values()) {
|
||||
l_inst.transforms.clear();
|
||||
update_light_instance(l_inst);
|
||||
}
|
||||
light_instances_.clear();
|
||||
}
|
||||
|
||||
void InstancerData::update() {}
|
||||
|
||||
pxr::VtValue InstancerData::get_data(pxr::TfToken const &key) const
|
||||
{
|
||||
ID_LOG(3, "%s", key.GetText());
|
||||
if (key == pxr::HdInstancerTokens->instanceTransform) {
|
||||
return pxr::VtValue(mesh_transforms_);
|
||||
}
|
||||
return pxr::VtValue();
|
||||
}
|
||||
|
||||
pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const
|
||||
{
|
||||
LightInstance *l_inst = light_instance(id);
|
||||
if (l_inst) {
|
||||
return l_inst->transforms[light_prim_id_index(id)];
|
||||
}
|
||||
|
||||
/* Mesh instance transform must be identity */
|
||||
return pxr::GfMatrix4d(1.0);
|
||||
}
|
||||
|
||||
pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(
|
||||
pxr::HdInterpolation interpolation) const
|
||||
{
|
||||
pxr::HdPrimvarDescriptorVector primvars;
|
||||
if (interpolation == pxr::HdInterpolationInstance) {
|
||||
primvars.emplace_back(
|
||||
pxr::HdInstancerTokens->instanceTransform, interpolation, pxr::HdPrimvarRoleTokens->none);
|
||||
}
|
||||
return primvars;
|
||||
}
|
||||
|
||||
pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const
|
||||
{
|
||||
return mesh_instance(id)->indices;
|
||||
}
|
||||
|
||||
ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const
|
||||
{
|
||||
MeshInstance *m_inst = mesh_instance(id);
|
||||
if (m_inst) {
|
||||
return m_inst->data.get();
|
||||
}
|
||||
LightInstance *l_inst = light_instance(id);
|
||||
if (l_inst) {
|
||||
return l_inst->data.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
pxr::SdfPathVector InstancerData::prototypes() const
|
||||
{
|
||||
pxr::SdfPathVector paths;
|
||||
for (auto &m_inst : mesh_instances_.values()) {
|
||||
for (auto &p : m_inst.data->submesh_paths()) {
|
||||
paths.push_back(p);
|
||||
}
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
void InstancerData::available_materials(Set<pxr::SdfPath> &paths) const
|
||||
{
|
||||
for (auto &m_inst : mesh_instances_.values()) {
|
||||
((MeshData *)m_inst.data.get())->available_materials(paths);
|
||||
}
|
||||
}
|
||||
|
||||
void InstancerData::update_double_sided(MaterialData *mat_data)
|
||||
{
|
||||
for (auto &m_inst : mesh_instances_.values()) {
|
||||
m_inst.data->update_double_sided(mat_data);
|
||||
}
|
||||
}
|
||||
|
||||
void InstancerData::pre_update()
|
||||
{
|
||||
mesh_transforms_.clear();
|
||||
for (auto &m_inst : mesh_instances_.values()) {
|
||||
m_inst.indices.clear();
|
||||
}
|
||||
for (auto &l_inst : light_instances_.values()) {
|
||||
l_inst.transforms.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void InstancerData::update_instance(Object *parent_ob, DupliObject *dupli)
|
||||
{
|
||||
if (!ObjectData::is_visible(scene_delegate_, parent_ob, OB_VISIBLE_INSTANCES)) {
|
||||
return;
|
||||
}
|
||||
Object *ob = dupli->ob;
|
||||
if (!is_instance_supported(ob)) {
|
||||
return;
|
||||
}
|
||||
if (!scene_delegate_->shading_settings.use_scene_lights && ob->type == OB_LAMP) {
|
||||
return;
|
||||
}
|
||||
|
||||
pxr::SdfPath p_id = object_prim_id(ob);
|
||||
if (ob->type == OB_LAMP) {
|
||||
LightInstance *inst = light_instance(p_id);
|
||||
if (!inst) {
|
||||
inst = &light_instances_.lookup_or_add_default(p_id);
|
||||
inst->data = std::make_unique<LightData>(scene_delegate_, ob, p_id);
|
||||
inst->data->init();
|
||||
}
|
||||
ID_LOG(2, "Light %s %d", inst->data->id->name, (int)inst->transforms.size());
|
||||
inst->transforms.push_back(gf_matrix_from_transform(dupli->mat));
|
||||
}
|
||||
else {
|
||||
MeshInstance *inst = mesh_instance(p_id);
|
||||
if (!inst) {
|
||||
inst = &mesh_instances_.lookup_or_add_default(p_id);
|
||||
inst->data = std::make_unique<MeshData>(scene_delegate_, ob, p_id);
|
||||
inst->data->init();
|
||||
inst->data->insert();
|
||||
}
|
||||
else {
|
||||
inst->data->update();
|
||||
}
|
||||
ID_LOG(2, "Mesh %s %d", inst->data->id->name, (int)mesh_transforms_.size());
|
||||
inst->indices.push_back(mesh_transforms_.size());
|
||||
mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat));
|
||||
}
|
||||
}
|
||||
|
||||
void InstancerData::post_update()
|
||||
{
|
||||
/* Remove mesh intances without indices */
|
||||
mesh_instances_.remove_if([&](auto item) {
|
||||
bool res = item.value.indices.empty();
|
||||
if (res) {
|
||||
item.value.data->remove();
|
||||
}
|
||||
return res;
|
||||
});
|
||||
|
||||
/* Update light intances and remove instances without transforms */
|
||||
for (auto &l_inst : light_instances_.values()) {
|
||||
update_light_instance(l_inst);
|
||||
}
|
||||
light_instances_.remove_if([&](auto item) { return item.value.transforms.empty(); });
|
||||
|
||||
/* Insert/remove/update instancer in RenderIndex */
|
||||
pxr::HdRenderIndex &index = scene_delegate_->GetRenderIndex();
|
||||
if (mesh_instances_.is_empty()) {
|
||||
/* Important: removing instancer when light_instances_ are empty too */
|
||||
if (index.HasInstancer(prim_id) && light_instances_.is_empty()) {
|
||||
index.RemoveInstancer(prim_id);
|
||||
ID_LOG(1, "Remove instancer");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (index.HasInstancer(prim_id)) {
|
||||
index.GetChangeTracker().MarkInstancerDirty(prim_id, pxr::HdChangeTracker::AllDirty);
|
||||
ID_LOG(1, "Update instancer");
|
||||
}
|
||||
else {
|
||||
index.InsertInstancer(scene_delegate_, prim_id);
|
||||
ID_LOG(1, "Insert instancer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pxr::SdfPath InstancerData::object_prim_id(Object *object) const
|
||||
{
|
||||
/* Making id of object in form like <prefix>_<pointer in 16 hex digits format> */
|
||||
char name[32];
|
||||
snprintf(name, sizeof(name), "O_%p", object);
|
||||
return prim_id.AppendElementString(name);
|
||||
}
|
||||
|
||||
pxr::SdfPath InstancerData::light_prim_id(LightInstance const &inst, int index) const
|
||||
{
|
||||
char name[16];
|
||||
snprintf(name, sizeof(name), "L_%08x", index);
|
||||
return inst.data->prim_id.AppendElementString(name);
|
||||
}
|
||||
|
||||
int InstancerData::light_prim_id_index(pxr::SdfPath const &id) const
|
||||
{
|
||||
int index;
|
||||
sscanf(id.GetName().c_str(), "L_%x", &index);
|
||||
return index;
|
||||
}
|
||||
|
||||
void InstancerData::update_light_instance(LightInstance &inst)
|
||||
{
|
||||
auto &render_index = scene_delegate_->GetRenderIndex();
|
||||
LightData &l_data = *inst.data;
|
||||
|
||||
int i;
|
||||
pxr::SdfPath p;
|
||||
|
||||
/* Remove old light instances */
|
||||
while (inst.count > inst.transforms.size()) {
|
||||
--inst.count;
|
||||
p = light_prim_id(inst, inst.count);
|
||||
render_index.RemoveSprim(l_data.prim_type_, p);
|
||||
ID_LOG(2, "Remove %s", p.GetText());
|
||||
}
|
||||
|
||||
/* Update current light instances */
|
||||
if (inst.data->prim_type((Light *)((Object *)l_data.id)->data) != l_data.prim_type_) {
|
||||
/* Recreate instances when prim_type was changed */
|
||||
for (i = 0; i < inst.count; ++i) {
|
||||
p = light_prim_id(inst, i);
|
||||
render_index.RemoveSprim(l_data.prim_type_, p);
|
||||
ID_LOG(2, "Remove %s", p.GetText());
|
||||
}
|
||||
inst.data->init();
|
||||
for (i = 0; i < inst.count; ++i) {
|
||||
p = light_prim_id(inst, i);
|
||||
render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p);
|
||||
ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Update light instances*/
|
||||
pxr::HdDirtyBits bits = pxr::HdLight::DirtyTransform;
|
||||
Object *obj = (Object *)inst.data->id;
|
||||
if (obj->id.recalc & ID_RECALC_GEOMETRY || ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) {
|
||||
l_data.init();
|
||||
bits = pxr::HdLight::AllDirty;
|
||||
}
|
||||
for (i = 0; i < inst.count; ++i) {
|
||||
p = light_prim_id(inst, i);
|
||||
render_index.GetChangeTracker().MarkSprimDirty(p, bits);
|
||||
ID_LOG(2, "Update %s (%s)", p.GetText(), l_data.id->name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add new light instances */
|
||||
while (inst.count < inst.transforms.size()) {
|
||||
p = light_prim_id(inst, inst.count);
|
||||
render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p);
|
||||
ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name);
|
||||
++inst.count;
|
||||
}
|
||||
}
|
||||
|
||||
InstancerData::MeshInstance *InstancerData::mesh_instance(pxr::SdfPath const &id) const
|
||||
{
|
||||
auto m_inst = mesh_instances_.lookup_ptr(id.GetPathElementCount() == 4 ? id.GetParentPath() :
|
||||
id);
|
||||
if (!m_inst) {
|
||||
return nullptr;
|
||||
}
|
||||
return const_cast<MeshInstance *>(m_inst);
|
||||
}
|
||||
|
||||
InstancerData::LightInstance *InstancerData::light_instance(pxr::SdfPath const &id) const
|
||||
{
|
||||
auto l_inst = light_instances_.lookup_ptr(id.GetPathElementCount() == 4 ? id.GetParentPath() :
|
||||
id);
|
||||
if (!l_inst) {
|
||||
return nullptr;
|
||||
}
|
||||
return const_cast<LightInstance *>(l_inst);
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
@ -1,89 +0,0 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include <pxr/base/arch/fileSystem.h>
|
||||
|
||||
#include <pxr/usd/ar/resolver.h>
|
||||
#include <pxr/usd/ar/resolverContextBinder.h>
|
||||
#include <pxr/usd/ar/resolverScopedCache.h>
|
||||
|
||||
#ifdef WITH_MATERIALX
|
||||
# include <pxr/usd/usdMtlx/reader.h>
|
||||
# include <pxr/usd/usdMtlx/utils.h>
|
||||
#endif
|
||||
|
||||
#include <pxr/usd/usdShade/material.h>
|
||||
#include <pxr/usd/usdShade/shader.h>
|
||||
|
||||
#include <pxr/usdImaging/usdImaging/materialParamUtils.h>
|
||||
|
||||
#include <pxr/imaging/hd/material.h>
|
||||
#include <pxr/imaging/hd/tokens.h>
|
||||
|
||||
#include "mtlx_hydra_adapter.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
void hdmtlx_convert_to_materialnetworkmap(std::string const &mtlx_path,
|
||||
pxr::TfTokenVector const &shader_source_types,
|
||||
pxr::TfTokenVector const &render_contexts,
|
||||
pxr::HdMaterialNetworkMap *out)
|
||||
{
|
||||
#ifdef WITH_MATERIALX
|
||||
if (mtlx_path.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string basePath = pxr::TfGetPathName(mtlx_path);
|
||||
|
||||
pxr::ArResolver &resolver = pxr::ArGetResolver();
|
||||
const pxr::ArResolverContext context = resolver.CreateDefaultContextForAsset(mtlx_path);
|
||||
pxr::ArResolverContextBinder binder(context);
|
||||
pxr::ArResolverScopedCache resolver_cache;
|
||||
|
||||
std::string mtlxName = pxr::TfGetBaseName(mtlx_path);
|
||||
std::string stage_id = pxr::TfStringPrintf(
|
||||
"%s%s%s.usda", basePath.c_str(), ARCH_PATH_SEP, mtlxName.c_str());
|
||||
pxr::UsdStageRefPtr stage = pxr::UsdStage::CreateInMemory(stage_id, context);
|
||||
|
||||
try {
|
||||
MaterialX::DocumentPtr doc = pxr::UsdMtlxReadDocument(mtlx_path);
|
||||
pxr::UsdMtlxRead(doc, stage);
|
||||
}
|
||||
catch (MaterialX::ExceptionFoundCycle &x) {
|
||||
Tf_PostErrorHelper(pxr::TF_CALL_CONTEXT,
|
||||
pxr::TF_DIAGNOSTIC_RUNTIME_ERROR_TYPE,
|
||||
"MaterialX cycle found: %s\n",
|
||||
x.what());
|
||||
return;
|
||||
}
|
||||
catch (MaterialX::Exception &x) {
|
||||
Tf_PostErrorHelper(pxr::TF_CALL_CONTEXT,
|
||||
pxr::TF_DIAGNOSTIC_RUNTIME_ERROR_TYPE,
|
||||
"MaterialX error: %s\n",
|
||||
x.what());
|
||||
return;
|
||||
}
|
||||
|
||||
if (pxr::UsdPrim materials = stage->GetPrimAtPath(pxr::SdfPath("/MaterialX/Materials"))) {
|
||||
if (pxr::UsdPrimSiblingRange children = materials.GetChildren()) {
|
||||
if (auto material = pxr::UsdShadeMaterial(*children.begin())) {
|
||||
if (pxr::UsdShadeShader mtlx_surface = material.ComputeSurfaceSource(render_contexts)) {
|
||||
UsdImagingBuildHdMaterialNetworkFromTerminal(mtlx_surface.GetPrim(),
|
||||
pxr::HdMaterialTerminalTokens->surface,
|
||||
shader_source_types,
|
||||
render_contexts,
|
||||
out,
|
||||
pxr::UsdTimeCode::Default());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
UNUSED_VARS(mtlx_path, shader_source_types, render_contexts, out);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
@ -1,16 +0,0 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pxr/base/tf/token.h>
|
||||
#include <pxr/imaging/hd/material.h>
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
void hdmtlx_convert_to_materialnetworkmap(std::string const &mtlx_path,
|
||||
pxr::TfTokenVector const &shader_source_types,
|
||||
pxr::TfTokenVector const &render_contexts,
|
||||
pxr::HdMaterialNetworkMap *out);
|
||||
|
||||
} // namespace blender::render::hydra
|
@ -1,17 +0,0 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2023 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pxr/base/tf/token.h>
|
||||
|
||||
#include "BLI_map.hh"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
struct SceneDelegateSettings {
|
||||
pxr::TfToken mx_filename_key;
|
||||
Map<pxr::TfToken, pxr::VtValue> render_tokens;
|
||||
};
|
||||
|
||||
}; // namespace blender::render::hydra
|
@ -1,23 +1,33 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#include "viewport_engine.h"
|
||||
|
||||
#include <pxr/base/gf/camera.h>
|
||||
#include <pxr/imaging/glf/drawTarget.h>
|
||||
#include <pxr/usd/usdGeom/camera.h>
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_vec_types.h" /* this include must be before BKE_camera.h due to "rctf" type */
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BKE_camera.h"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_timecode.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "GPU_matrix.h"
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "camera.h"
|
||||
#include "viewport_engine.h"
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "GPU_context.h"
|
||||
#include "GPU_matrix.h"
|
||||
|
||||
#include "RE_engine.h"
|
||||
|
||||
#include "hydra/camera.h"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
@ -29,17 +39,18 @@ struct ViewSettings {
|
||||
|
||||
pxr::GfCamera gf_camera();
|
||||
|
||||
CameraData camera_data;
|
||||
io::hydra::CameraData camera_data;
|
||||
|
||||
int screen_width;
|
||||
int screen_height;
|
||||
pxr::GfVec4i border;
|
||||
};
|
||||
|
||||
ViewSettings::ViewSettings(bContext *context) : camera_data(context)
|
||||
ViewSettings::ViewSettings(bContext *context)
|
||||
: camera_data(CTX_wm_view3d(context), CTX_wm_region(context))
|
||||
{
|
||||
View3D *view3d = CTX_wm_view3d(context);
|
||||
RegionView3D *region_data = (RegionView3D *)CTX_wm_region_data(context);
|
||||
RegionView3D *region_data = static_cast<RegionView3D *>(CTX_wm_region_data(context));
|
||||
ARegion *region = CTX_wm_region(context);
|
||||
|
||||
screen_width = region->winx;
|
||||
@ -56,7 +67,7 @@ ViewSettings::ViewSettings(bContext *context) : camera_data(context)
|
||||
Object *camera_obj = scene->camera;
|
||||
|
||||
float camera_points[4][3];
|
||||
BKE_camera_view_frame(scene, (Camera *)camera_obj->data, camera_points);
|
||||
BKE_camera_view_frame(scene, static_cast<Camera *>(camera_obj->data), camera_points);
|
||||
|
||||
float screen_points[4][2];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
@ -175,8 +186,6 @@ void DrawTexture::write_data(int width, int height, const void *data)
|
||||
GPU_RGBA16F,
|
||||
GPU_TEXTURE_USAGE_GENERAL,
|
||||
(float *)data);
|
||||
GPU_texture_filter_mode(texture_, true);
|
||||
GPU_texture_mipmap_mode(texture_, true, true);
|
||||
}
|
||||
|
||||
void DrawTexture::draw(GPUShader *shader, const pxr::GfVec4d &viewport)
|
||||
@ -232,6 +241,14 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context)
|
||||
render_task_delegate_->add_aov(pxr::HdAovTokens->color);
|
||||
}
|
||||
|
||||
/* Workaround missing/buggy VAOs in hgiGL and hdSt. For OpenGL compatibility
|
||||
* profile this is not a problem, but for core profile it is. */
|
||||
GLuint VAO;
|
||||
if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) {
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glBindVertexArray(VAO);
|
||||
}
|
||||
|
||||
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_IMAGE);
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
@ -253,6 +270,10 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context)
|
||||
|
||||
GPU_shader_unbind();
|
||||
|
||||
if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) {
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
}
|
||||
|
||||
if (renderer_percent_done() == 0.0f) {
|
||||
time_begin_ = PIL_check_seconds_timer();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* SPDX-FileCopyrightText: 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -14,6 +14,10 @@
|
||||
namespace blender::render::hydra {
|
||||
|
||||
class DrawTexture {
|
||||
private:
|
||||
GPUTexture *texture_ = nullptr;
|
||||
GPUBatch *batch_;
|
||||
|
||||
public:
|
||||
DrawTexture();
|
||||
~DrawTexture();
|
||||
@ -24,11 +28,13 @@ class DrawTexture {
|
||||
GPUTexture *texture() const;
|
||||
|
||||
private:
|
||||
GPUTexture *texture_ = nullptr;
|
||||
GPUBatch *batch_;
|
||||
};
|
||||
|
||||
class ViewportEngine : public Engine {
|
||||
private:
|
||||
double time_begin_;
|
||||
DrawTexture draw_texture_;
|
||||
|
||||
public:
|
||||
using Engine::Engine;
|
||||
|
||||
@ -37,11 +43,6 @@ class ViewportEngine : public Engine {
|
||||
|
||||
private:
|
||||
void notify_status(const std::string &title, const std::string &info);
|
||||
|
||||
private:
|
||||
double time_begin_;
|
||||
|
||||
DrawTexture draw_texture_;
|
||||
};
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
|
@ -919,9 +919,16 @@ static void engine_render_view_layer(Render *re,
|
||||
|
||||
/* Sync data to engine, within draw lock so scene data can be accessed safely. */
|
||||
if (use_engine) {
|
||||
const bool use_gpu_context = (engine->type->flag & RE_USE_GPU_CONTEXT);
|
||||
if (use_gpu_context) {
|
||||
DRW_render_context_enable(engine->re);
|
||||
}
|
||||
if (engine->type->update) {
|
||||
engine->type->update(engine, re->main, engine->depsgraph);
|
||||
}
|
||||
if (use_gpu_context) {
|
||||
DRW_render_context_disable(engine->re);
|
||||
}
|
||||
}
|
||||
|
||||
if (re->draw_lock) {
|
||||
|
Loading…
Reference in New Issue
Block a user
Move to internal struct
Engine::RenderSettings