diff --git a/hydra_storm/__init__.py b/hydra_storm/__init__.py index 41fcbee99..3625b9c40 100644 --- a/hydra_storm/__init__.py +++ b/hydra_storm/__init__.py @@ -20,16 +20,18 @@ bl_info = { } -from . import engine, properties, ui +from . import engine, properties, ui, preferences def register(): engine.register() properties.register() ui.register() + preferences.register() def unregister(): + preferences.unregister() ui.unregister() properties.unregister() engine.unregister() diff --git a/hydra_storm/engine.py b/hydra_storm/engine.py index 99dd764ec..93e463cd3 100644 --- a/hydra_storm/engine.py +++ b/hydra_storm/engine.py @@ -3,10 +3,13 @@ # -from pathlib import Path - import bpy import bpy_hydra +import _bpy_hydra + +from pxr import Usd + +from .preferences import addon_preferences class StormHydraRenderEngine(bpy_hydra.HydraRenderEngine): @@ -19,6 +22,17 @@ class StormHydraRenderEngine(bpy_hydra.HydraRenderEngine): delegate_id = 'HdStormRendererPlugin' + def __init__(self): + self._usd_stage = None + + def _sync_usd_stage(self): + preferences = addon_preferences() + dev = bpy.context.scene.hydra_storm.dev + if preferences.dev_tools and not self._usd_stage and dev.render_usd and dev.usd_file: + self._usd_stage = Usd.Stage.Open(dev.usd_file) + if self._usd_stage: + _bpy_hydra.engine_sync_usd(self.engine_ptr, self._usd_stage) + def get_render_settings(self, engine_type): settings = bpy.context.scene.hydra_storm.viewport if engine_type == 'VIEWPORT' else \ bpy.context.scene.hydra_storm.final @@ -30,6 +44,14 @@ class StormHydraRenderEngine(bpy_hydra.HydraRenderEngine): 'maxLights': settings.max_lights, } + def update(self, data, depsgraph): + super().update(data, depsgraph) + self._sync_usd_stage() + + def view_update(self, context, depsgraph): + super().view_update(context, depsgraph) + self._sync_usd_stage() + register, unregister = bpy.utils.register_classes_factory(( StormHydraRenderEngine, diff --git a/hydra_storm/preferences.py b/hydra_storm/preferences.py new file mode 100644 index 000000000..001072a80 --- /dev/null +++ b/hydra_storm/preferences.py @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright 2022, AMD + +import bpy + + +class AddonPreferences(bpy.types.AddonPreferences): + bl_idname = 'hydra_storm' + + dev_tools: bpy.props.BoolProperty( + name="Developer Tools", + description="Enable developer tools", + default=False, + ) + + def draw(self, context): + layout = self.layout + layout.prop(self, "dev_tools") + + +def addon_preferences(): + return bpy.context.preferences.addons['hydra_storm'].preferences + + +register, unregister = bpy.utils.register_classes_factory([ + AddonPreferences, +]) diff --git a/hydra_storm/properties.py b/hydra_storm/properties.py index ad29a5c40..1cbd78663 100644 --- a/hydra_storm/properties.py +++ b/hydra_storm/properties.py @@ -50,14 +50,29 @@ class RenderProperties(bpy.types.PropertyGroup): ) +class DevProperties(bpy.types.PropertyGroup): + render_usd: bpy.props.BoolProperty( + name="Render USD", + description="Render USD file with Blender scene", + default=False, + ) + usd_file: bpy.props.StringProperty( + name="USD File", + description="Select USD file to render", + subtype='FILE_PATH', + ) + + class SceneProperties(Properties): type = bpy.types.Scene final: bpy.props.PointerProperty(type=RenderProperties) viewport: bpy.props.PointerProperty(type=RenderProperties) + dev: bpy.props.PointerProperty(type=DevProperties) register, unregister = bpy.utils.register_classes_factory(( RenderProperties, + DevProperties, SceneProperties, )) diff --git a/hydra_storm/ui.py b/hydra_storm/ui.py index 68ce9d1e9..fc9e3ecb2 100644 --- a/hydra_storm/ui.py +++ b/hydra_storm/ui.py @@ -6,6 +6,7 @@ import bpy from .engine import StormHydraRenderEngine +from .preferences import addon_preferences class Panel(bpy.types.Panel): @@ -25,7 +26,7 @@ class Panel(bpy.types.Panel): class STORM_HYDRA_RENDER_PT_final(Panel): """Final render delegate and settings""" bl_idname = 'STORM_HYDRA_RENDER_PT_final' - bl_label = "Storm Final Settings" + bl_label = "Final Render Settings" def draw(self, context): layout = self.layout @@ -37,25 +38,19 @@ class STORM_HYDRA_RENDER_PT_final(Panel): layout.prop(settings, 'max_lights') -class FinalPanel(bpy.types.Panel): +class STORM_HYDRA_RENDER_PT_volume_final(bpy.types.Panel): bl_parent_id = STORM_HYDRA_RENDER_PT_final.bl_idname + bl_label = "Volume Raymarching" bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_options = {'DEFAULT_CLOSED'} - def settings(self, context): - return context.scene.hydra_storm.final - - -class STORM_HYDRA_RENDER_PT_volume_final(FinalPanel): - bl_label = "Volume Raymarching" - def draw(self, context): layout = self.layout layout.use_property_split = True layout.use_property_decorate = False - settings = self.settings(context) + settings = context.scene.hydra_storm.final col = layout.column(align=True) col.prop(settings, "volume_raymarching_step_size", text="Step Size") @@ -69,7 +64,7 @@ class STORM_HYDRA_RENDER_PT_volume_final(FinalPanel): class STORM_HYDRA_RENDER_PT_viewport(Panel): """Viewport render delegate and settings""" bl_idname = 'STORM_HYDRA_RENDER_PT_viewport' - bl_label = "Storm Viewport Settings" + bl_label = "Viewport Render Settings" def draw(self, context): layout = self.layout @@ -81,25 +76,19 @@ class STORM_HYDRA_RENDER_PT_viewport(Panel): layout.prop(settings, 'max_lights') -class ViewportPanel(bpy.types.Panel): +class STORM_HYDRA_RENDER_PT_volume_viewport(bpy.types.Panel): bl_parent_id = STORM_HYDRA_RENDER_PT_viewport.bl_idname + bl_label = "Volume Raymarching" bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_options = {'DEFAULT_CLOSED'} - def settings(self, context): - return context.scene.hydra_storm.viewport - - -class STORM_HYDRA_RENDER_PT_volume_viewport(ViewportPanel): - bl_label = "Volume Raymarching" - def draw(self, context): layout = self.layout layout.use_property_split = True layout.use_property_decorate = False - settings = self.settings(context) + settings = context.scene.hydra_storm.viewport col = layout.column(align=True) col.prop(settings, "volume_raymarching_step_size", text="Step Size") @@ -108,9 +97,7 @@ class STORM_HYDRA_RENDER_PT_volume_viewport(ViewportPanel): class STORM_HYDRA_LIGHT_PT_light(Panel): - """ - Physical light sources - """ + """Physical light sources""" bl_label = "Light" bl_context = 'data' @@ -162,11 +149,33 @@ class STORM_HYDRA_LIGHT_PT_light(Panel): main_col.prop(light, 'size') +class STORM_HYDRA_RENDER_PT_dev(Panel): + """Final render delegate and settings""" + bl_label = "Dev" + + @classmethod + def poll(cls, context): + return super().poll(context) and addon_preferences().dev_tools + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + dev = context.scene.hydra_storm.dev + col = layout.column() + col.prop(dev, 'render_usd') + row = col.row() + row.enabled = dev.render_usd + row.prop(dev, 'usd_file') + + register_classes, unregister_classes = bpy.utils.register_classes_factory(( STORM_HYDRA_RENDER_PT_final, STORM_HYDRA_RENDER_PT_volume_final, STORM_HYDRA_RENDER_PT_viewport, STORM_HYDRA_RENDER_PT_volume_viewport, + STORM_HYDRA_RENDER_PT_dev, STORM_HYDRA_LIGHT_PT_light, ))