Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[usdImagingGL,usdview] Add support to set the OCIO display, view, and colorspace #1491

Merged
merged 1 commit into from
Nov 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions pxr/usdImaging/usdImagingGL/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,8 @@ UsdImagingGLEngine::RenderBatch(

_PrepareRender(params);

SetColorCorrectionSettings(params.colorCorrectionMode);
SetColorCorrectionSettings(params.colorCorrectionMode, params.ocioDisplay,
params.ocioView, params.ocioColorSpace, params.ocioLook);

// XXX App sets the clear color via 'params' instead of setting up Aovs
// that has clearColor in their descriptor. So for now we must pass this
Expand Down Expand Up @@ -1185,7 +1186,11 @@ UsdImagingGLEngine::RestartRenderer()
//----------------------------------------------------------------------------
void
UsdImagingGLEngine::SetColorCorrectionSettings(
TfToken const& id)
TfToken const& colorCorrectionMode,
TfToken const& ocioDisplay,
TfToken const& ocioView,
TfToken const& ocioColorSpace,
TfToken const& ocioLook)
{
if (ARCH_UNLIKELY(_legacyImpl)) {
return;
Expand All @@ -1198,7 +1203,11 @@ UsdImagingGLEngine::SetColorCorrectionSettings(
TF_VERIFY(_taskController);

HdxColorCorrectionTaskParams hdParams;
hdParams.colorCorrectionMode = id;
hdParams.colorCorrectionMode = colorCorrectionMode;
hdParams.displayOCIO = ocioDisplay.GetString();
hdParams.viewOCIO = ocioView.GetString();
hdParams.colorspaceOCIO = ocioColorSpace.GetString();
hdParams.looksOCIO = ocioLook.GetString();
_taskController->SetColorCorrectionParams(hdParams);
}

Expand Down
6 changes: 5 additions & 1 deletion pxr/usdImaging/usdImagingGL/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,11 @@ class UsdImagingGLEngine
/// Set \p id to one of the HdxColorCorrectionTokens.
USDIMAGINGGL_API
void SetColorCorrectionSettings(
TfToken const& id);
TfToken const& ccType,
TfToken const& ocioDisplay = {},
TfToken const& ocioView = {},
TfToken const& ocioColorSpace = {},
TfToken const& ocioLook = {});

/// @}

Expand Down
9 changes: 9 additions & 0 deletions pxr/usdImaging/usdImagingGL/renderParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,12 @@ class UsdImagingGLRenderParams
bool enableUsdDrawModes;
GfVec4f clearColor;
TfToken colorCorrectionMode;
// Optional OCIO color setings, only valid when colorCorrectionMode==HdxColorCorrectionTokens->openColorIO
int lut3dSizeOCIO;
TfToken ocioDisplay;
TfToken ocioView;
TfToken ocioColorSpace;
TfToken ocioLook;

inline UsdImagingGLRenderParams();

Expand Down Expand Up @@ -168,6 +173,10 @@ UsdImagingGLRenderParams::operator==(const UsdImagingGLRenderParams &other)
&& enableUsdDrawModes == other.enableUsdDrawModes
&& clearColor == other.clearColor
&& colorCorrectionMode == other.colorCorrectionMode
&& ocioDisplay == other.ocioDisplay
&& ocioView == other.ocioView
&& ocioColorSpace == other.ocioColorSpace
&& ocioLook == other.ocioLook
&& lut3dSizeOCIO == other.lut3dSizeOCIO;
}

Expand Down
5 changes: 4 additions & 1 deletion pxr/usdImaging/usdImagingGL/wrapRenderParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ wrapRenderParams()
.def_readwrite("enableUsdDrawModes", &Params::enableUsdDrawModes)
.def_readwrite("colorCorrectionMode", &Params::colorCorrectionMode)
.def_readwrite("clearColor", &Params::clearColor)
.def_readwrite("lut3dSizeOCIO", &Params::lut3dSizeOCIO)
.def_readwrite("ocioDisplay", &Params::ocioDisplay)
.def_readwrite("ocioView", &Params::ocioView)
.def_readwrite("ocioColorSpace", &Params::ocioColorSpace)
.def_readwrite("ocioLook", &Params::ocioLook)
;
}
64 changes: 61 additions & 3 deletions pxr/usdImaging/usdviewq/appController.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
from .settings2 import StateSource
from .usdviewApi import UsdviewApi
from .rootDataModel import RootDataModel, ChangeNotice
from .viewSettingsDataModel import ViewSettingsDataModel
from .viewSettingsDataModel import ViewSettingsDataModel, OCIOSettings
from . import plugin
from .pythonInterpreter import Myconsole

Expand Down Expand Up @@ -650,6 +650,7 @@ def __init__(self, parserData, resolverContextFn):
self._ui.actionOpenColorIO)
for action in self._colorCorrectionActions:
self._ui.colorCorrectionActionGroup.addAction(action)
self._ocioSettings, self._ocioMenu = None, None

# XXX This should be a validator in ViewSettingsDataModel.
if self._dataModel.viewSettings.renderMode not in RenderModes:
Expand Down Expand Up @@ -942,7 +943,7 @@ def __init__(self, parserData, resolverContextFn):
self._ui.renderModeActionGroup.triggered.connect(self._changeRenderMode)

self._ui.colorCorrectionActionGroup.triggered.connect(
self._changeColorCorrection)
lambda mode: self._changeColorCorrection(str(mode.text())))

self._ui.pickModeActionGroup.triggered.connect(self._changePickMode)

Expand Down Expand Up @@ -1671,6 +1672,63 @@ def _configureColorManagement(self):
UsdImagingGL.Engine.IsColorCorrectionCapable())
self._ui.menuColorCorrection.setEnabled(enableMenu)

try:
import PyOpenColorIO as OCIO
config = OCIO.GetCurrentConfig()
ocioMenu = QtWidgets.QMenu('OpenColorIO')
colorSpaceMenu = QtWidgets.QMenu('ColorSpace')
#looksMenu = QtWidgets.QMenu('Looks')
colorSpaceMap = {}

def addAction(menu, name):
action = menu.addAction(name)
action.setCheckable(True)
return action

def setColorSpace(action):
if self._ocioSettings._colorSpace:
self._ocioSettings._colorSpace.setChecked(False)
self._ocioSettings._colorSpace = action
self._changeColorCorrection(ColorCorrectionModes.OPENCOLORIO)
self._refreshColorCorrectionModeMenu()
self._dataModel.viewSettings.setOCIOConfig(action.text())

def setOCIO(action):
if self._ocioSettings._view:
self._ocioSettings._view.setChecked(False)
self._ocioSettings._display, self._ocioSettings._view = action.parent(), action
# Reset the colorspace to the display & view default
display = self._ocioSettings._display.title()
view = self._ocioSettings._view.text()
colorSpace = config.getDisplayColorSpaceName(display, view)
self._dataModel.viewSettings.setOCIOConfig(colorSpace, display, view)
# This will handle the UI / menu updates
colorSpaceMap[colorSpace].trigger()

for d in config.getDisplays():
displayMenu = QtWidgets.QMenu(d)
for v in config.getViews(d):
a = addAction(displayMenu, v)
a.triggered[bool].connect(lambda _, action=a: setOCIO(action))
ocioMenu.addMenu(displayMenu)

for cs in config.getColorSpaces():
colorSpace = cs.getName()
a = addAction(colorSpaceMenu, colorSpace)
colorSpaceMap[colorSpace] = a
a.triggered[bool].connect(lambda _, action=a: setColorSpace(action))

# for lk in config.getLooks():
# addAction(looksMenu, lk)

ocioMenu.addMenu(colorSpaceMenu)
#ocioMenu.addMenu(looksMenu)
self._ui.menuColorCorrection.addMenu(ocioMenu)
self._ocioSettings, self._ocioMenu = OCIOSettings(None), ocioMenu

except ImportError:
return

# Topology-dependent UI changes
def _reloadVaryingUI(self):

Expand Down Expand Up @@ -2369,7 +2427,7 @@ def _changeRenderMode(self, mode):
self._dataModel.viewSettings.renderMode = str(mode.text())

def _changeColorCorrection(self, mode):
self._dataModel.viewSettings.colorCorrectionMode = str(mode.text())
self._dataModel.viewSettings.colorCorrectionMode = mode

def _changePickMode(self, mode):
self._dataModel.viewSettings.pickMode = str(mode.text())
Expand Down
9 changes: 8 additions & 1 deletion pxr/usdImaging/usdviewq/stageView.py
Original file line number Diff line number Diff line change
Expand Up @@ -1452,9 +1452,16 @@ def renderSinglePass(self, renderMode, renderSelHighlights):
self._renderParams.highlight = renderSelHighlights
self._renderParams.enableSceneMaterials = self._dataModel.viewSettings.enableSceneMaterials
self._renderParams.enableSceneLights = self._dataModel.viewSettings.enableSceneLights
self._renderParams.colorCorrectionMode = self._dataModel.viewSettings.colorCorrectionMode
self._renderParams.clearColor = Gf.Vec4f(self._dataModel.viewSettings.clearColor)

ccMode = self._dataModel.viewSettings.colorCorrectionMode
self._renderParams.colorCorrectionMode = ccMode
self._renderParams.ocioDisplay, self._renderParams.ocioView, self._renderParams.ocioColorSpace = \
(self._dataModel.viewSettings.ocioConfig.display,
self._dataModel.viewSettings.ocioConfig.view,
self._dataModel.viewSettings.ocioConfig.colorSpace) if ccMode == ColorCorrectionModes.OPENCOLORIO else \
('','','')

pseudoRoot = self._dataModel.stage.GetPseudoRoot()

renderer.SetSelectionColor(self._dataModel.viewSettings.highlightColor)
Expand Down
37 changes: 37 additions & 0 deletions pxr/usdImaging/usdviewq/viewSettingsDataModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,25 @@ def wrapper(self, *args, **kwargs):
self.signalSettingChanged.emit()
return wrapper

"""Class to hold OCIO display, view, and colorSpace settings.
The underlying data is somewhat opaque (for view it is strings, but
for an app-controler it may be the Qt object)
"""
class OCIOSettings():
def __init__(self, dflt=None):
self._display, self._view, self._colorSpace = dflt, dflt, dflt

@property
def display(self):
return self._display

@property
def view(self):
return self._view

@property
def colorSpace(self):
return self._colorSpace

class ViewSettingsDataModel(QtCore.QObject, StateSource):
"""Data model containing settings related to the rendered view of a USD
Expand Down Expand Up @@ -110,6 +129,7 @@ def __init__(self, rootDataModel, parent):
self._renderMode = self.stateProperty("renderMode", default=RenderModes.SMOOTH_SHADED)
self._freeCameraFOV = self.stateProperty("freeCameraFOV", default=60.0)
self._colorCorrectionMode = self.stateProperty("colorCorrectionMode", default=ColorCorrectionModes.SRGB)
self._ocioSettings = OCIOSettings('')
self._pickMode = self.stateProperty("pickMode", default=PickModes.PRIMS)

# We need to store the trinary selHighlightMode state here,
Expand Down Expand Up @@ -311,6 +331,23 @@ def colorCorrectionMode(self):
def colorCorrectionMode(self, value):
self._colorCorrectionMode = value

@property
def ocioConfig(self):
return self._colorCorrectionMode

@property
def ocioConfig(self):
return self._ocioSettings

def setOCIOConfig(self, colorSpace=None, display=None, view=None):
if display:
assert view, 'Cannot set a display without a view'
self._ocioSettings._display = display
self._ocioSettings._view = view
if colorSpace:
self._ocioSettings._colorSpace = colorSpace
self.colorCorrectionMode = ColorCorrectionModes.OPENCOLORIO

@property
def pickMode(self):
return self._pickMode
Expand Down