Skip to content

Commit eabf4ba

Browse files
authored
Merge pull request #3988 from Autodesk/barbalt/lights/EMSUSD-1518-include-all
EMSUSD-1518 As an artist, I want the ability to determine whether a collection includes all objects by default or not
2 parents 08d3ba6 + cccc766 commit eabf4ba

File tree

11 files changed

+640
-15
lines changed

11 files changed

+640
-15
lines changed

lib/mayaUsd/resources/ae/CMakeLists.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,30 @@ foreach(_SUBDIR ${MAYAUSD_AE_TEMPLATES})
3737
endforeach()
3838

3939
install(FILES __init__.py DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/python/${PROJECT_NAME})
40+
41+
# Install shared components
42+
43+
if(MAYA_APP_VERSION VERSION_GREATER_EQUAL 2023)
44+
foreach(_SUBDIR ${MAYAUSD_AE_TEMPLATES})
45+
install(FILES
46+
${_SUBDIR}/lightCustomControl.py
47+
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/python/ufe_ae/usd/nodes/${_SUBDIR}
48+
)
49+
endforeach()
50+
51+
set(MAYAUSD_SHARED_COMPONENTS usd-shared-components/src/python/usdSharedComponents)
52+
install(FILES
53+
${MAYAUSD_SHARED_COMPONENTS}/collection/__init__.py
54+
${MAYAUSD_SHARED_COMPONENTS}/collection/widget.py
55+
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/python/usd_shared_components/collection/
56+
)
57+
58+
install(FILES
59+
${MAYAUSD_SHARED_COMPONENTS}/common/__init__.py
60+
${MAYAUSD_SHARED_COMPONENTS}/common/list.py
61+
${MAYAUSD_SHARED_COMPONENTS}/common/persistentStorage.py
62+
${MAYAUSD_SHARED_COMPONENTS}/common/resizable.py
63+
${MAYAUSD_SHARED_COMPONENTS}/common/theme.py
64+
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/python/usd_shared_components/common/
65+
)
66+
endif()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Shared common components for USD plugins for 3dsMax and Maya
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
from ..common.list import StringList
2+
from ..common.resizable import Resizable
3+
4+
try:
5+
from PySide6.QtWidgets import QWidget, QVBoxLayout
6+
except ImportError:
7+
from PySide2.QtWidgets import QWidget, QVBoxLayout # type: ignore
8+
9+
from pxr import Usd
10+
11+
class CollectionWidget(QWidget):
12+
def __init__(self, collection: Usd.CollectionAPI = None, parent: QWidget = None):
13+
super(CollectionWidget, self).__init__(parent)
14+
15+
self._collection: Usd.CollectionAPI = collection
16+
17+
includes = []
18+
excludes = []
19+
shouldIncludeAll = False
20+
21+
if self._collection is not None:
22+
includeRootAttribute = self._collection.GetIncludeRootAttr()
23+
if includeRootAttribute.IsAuthored():
24+
shouldIncludeAll = self._collection.GetIncludeRootAttr().Get()
25+
26+
for p in self._collection.GetIncludesRel().GetTargets():
27+
includes.append(p.pathString)
28+
for p in self._collection.GetExcludesRel().GetTargets():
29+
excludes.append(p.pathString)
30+
31+
self.mainLayout = QVBoxLayout(self)
32+
self.mainLayout.setContentsMargins(0,0,0,0)
33+
34+
self._include = StringList( includes, "Include", "Include all", self)
35+
self._include.cbIncludeAll.setChecked(shouldIncludeAll)
36+
self._include.cbIncludeAll.stateChanged.connect(self.onIncludeAllToggle)
37+
self._resizableInclude = Resizable(self._include, "USD_Light_Linking", "IncludeListHeight", self)
38+
39+
self.mainLayout.addWidget(self._resizableInclude)
40+
41+
self._exclude = StringList( excludes, "Exclude", "", self)
42+
self._resizableExclude = Resizable(self._exclude, "USD_Light_Linking", "ExcludeListHeight", self)
43+
44+
self.mainLayout.addWidget(self._resizableExclude)
45+
self.mainLayout.addStretch(1)
46+
47+
def onIncludeAllToggle(self):
48+
self._collection.GetIncludeRootAttr().Set(self._include.cbIncludeAll.isChecked())
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Shared common components for USD plugins for 3dsMax and Maya
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
from typing import Sequence, Union
2+
from .theme import Theme
3+
4+
try:
5+
from PySide6.QtCore import (
6+
QModelIndex,
7+
QPersistentModelIndex,
8+
QSize,
9+
QStringListModel,
10+
Qt,
11+
Signal,
12+
)
13+
from PySide6.QtGui import QPainter
14+
from PySide6.QtWidgets import QStyleOptionViewItem, QStyledItemDelegate, QListView, QLabel, QVBoxLayout, QHBoxLayout, QWidget, QCheckBox
15+
except:
16+
from PySide2.QtCore import (
17+
QModelIndex,
18+
QPersistentModelIndex,
19+
QSize,
20+
QStringListModel,
21+
Qt,
22+
Signal,
23+
)
24+
from PySide2.QtGui import QPainter # type: ignore
25+
from PySide2.QtWidgets import QStyleOptionViewItem, QStyledItemDelegate, QListView, QLabel, QVBoxLayout, QHBoxLayout, QWidget, QCheckBox # type: ignore
26+
27+
class _StringList(QListView):
28+
selectedItemsChanged = Signal()
29+
30+
class Delegate(QStyledItemDelegate):
31+
def __init__(self, model: QStringListModel, parent=None):
32+
super(_StringList.Delegate, self).__init__(parent)
33+
self._model = model
34+
35+
def sizeHint(self, option: QStyleOptionViewItem, index: Union[QModelIndex, QPersistentModelIndex]):
36+
s: int = Theme.instance().uiScaled(24)
37+
return QSize(s, s)
38+
39+
def paint(self, painter: QPainter, option: QStyleOptionViewItem, index: Union[QModelIndex, QPersistentModelIndex]):
40+
s: str = self._model.data(index, Qt.DisplayRole)
41+
Theme.instance().paintStringListEntry(painter, option.rect, s)
42+
43+
def __init__(self, items: Sequence[str] = [], parent=None):
44+
super(_StringList, self).__init__(parent)
45+
self._model = QStringListModel(items, self)
46+
self.setModel(self._model)
47+
48+
self.setUniformItemSizes(True)
49+
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
50+
self.setTextElideMode(Qt.TextElideMode.ElideMiddle)
51+
self.setSelectionBehavior(QListView.SelectRows)
52+
self.setSelectionMode(QListView.MultiSelection)
53+
self.setContentsMargins(0,0,0,0)
54+
55+
self.selectionModel().selectionChanged.connect(lambda: self.selectedItemsChanged.emit())
56+
57+
def drawFrame(self, painter: QPainter):
58+
pass
59+
60+
@property
61+
def items(self) -> Sequence[str]:
62+
return self._model.stringList
63+
64+
@items.setter
65+
def items(self, items: Sequence[str]):
66+
self._model.setStringList(items)
67+
68+
@property
69+
def selectedItems(self) -> Sequence[str]:
70+
return [index.data(Qt.DisplayRole) for index in self.selectedIndexes()]
71+
72+
73+
class StringList(QWidget):
74+
75+
def __init__(self, items: Sequence[str] = [], headerTitle: str = "", toggleTitle: str = "", parent=None):
76+
super().__init__()
77+
self.list = _StringList(items, self)
78+
79+
layout = QVBoxLayout(self)
80+
LEFT_RIGHT_MARGINS = 2
81+
layout.setContentsMargins(LEFT_RIGHT_MARGINS, 0, LEFT_RIGHT_MARGINS, 0)
82+
83+
headerWidget = QWidget(self)
84+
headerLayout = QHBoxLayout(headerWidget)
85+
86+
titleLabel = QLabel(headerTitle, self)
87+
headerLayout.addWidget(titleLabel)
88+
headerLayout.addStretch(1)
89+
headerLayout.setContentsMargins(0,0,0,0)
90+
91+
# only add the check box on the header if there's a label
92+
if toggleTitle != None and toggleTitle != "":
93+
self.cbIncludeAll = QCheckBox(toggleTitle, self)
94+
self.cbIncludeAll.setCheckable(True)
95+
headerLayout.addWidget(self.cbIncludeAll)
96+
97+
headerWidget.setLayout(headerLayout)
98+
99+
layout.addWidget(headerWidget)
100+
layout.addWidget(self.list)
101+
102+
self.setLayout(layout)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
try:
2+
from PySide6.QtCore import QSettings
3+
except:
4+
from PySide2.QtCore import QSettings # type: ignore
5+
6+
7+
class PersistentStorage(object):
8+
_instance = None
9+
10+
def __init__(self):
11+
raise RuntimeError("Call instance() instead")
12+
13+
@classmethod
14+
def instance(cls):
15+
if cls._instance is None:
16+
cls._instance = cls.__new__(cls)
17+
return cls._instance
18+
19+
@classmethod
20+
def injectInstance(cls, persistentStorage):
21+
cls._instance = persistentStorage
22+
23+
def _settings(self) -> QSettings:
24+
return QSettings("settings.ini", QSettings.IniFormat)
25+
26+
def set(self, group: str, key: str, value: object):
27+
settings: QSettings = self._settings()
28+
settings.beginGroup(group)
29+
settings.setValue(key, value)
30+
settings.endGroup()
31+
settings.sync()
32+
33+
def get(self, group: str, key: str, default: object = None) -> object:
34+
settings: QSettings = self._settings()
35+
settings.beginGroup(group)
36+
return settings.value(key, default, type=type(default))

0 commit comments

Comments
 (0)