mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
Merge branch 'bugfix/houdini-fix-pointcache-alembics' of https://github.com/ynput/OpenPype into enhancement/OP-5600_Houdini-manage-colorspaces-in-review-ROP
This commit is contained in:
commit
ad1097272d
11 changed files with 103 additions and 37 deletions
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
|
@ -35,6 +35,7 @@ body:
|
|||
label: Version
|
||||
description: What version are you running? Look to OpenPype Tray
|
||||
options:
|
||||
- 3.16.2-nightly.1
|
||||
- 3.16.1
|
||||
- 3.16.0
|
||||
- 3.16.0-nightly.2
|
||||
|
|
@ -134,7 +135,6 @@ body:
|
|||
- 3.14.6-nightly.3
|
||||
- 3.14.6-nightly.2
|
||||
- 3.14.6-nightly.1
|
||||
- 3.14.5
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
|
|
|
|||
|
|
@ -32,12 +32,16 @@ RUN yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.n
|
|||
wget \
|
||||
gcc \
|
||||
zlib-devel \
|
||||
pcre-devel \
|
||||
perl-core \
|
||||
bzip2 \
|
||||
bzip2-devel \
|
||||
readline-devel \
|
||||
sqlite sqlite-devel \
|
||||
openssl-devel \
|
||||
openssl-libs \
|
||||
openssl11-devel \
|
||||
openssl11-libs \
|
||||
tk-devel libffi-devel \
|
||||
patchelf \
|
||||
automake \
|
||||
|
|
@ -71,7 +75,12 @@ RUN echo 'export PATH="$HOME/.pyenv/bin:$PATH"'>> $HOME/.bashrc \
|
|||
&& echo 'eval "$(pyenv init -)"' >> $HOME/.bashrc \
|
||||
&& echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc \
|
||||
&& echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc
|
||||
RUN source $HOME/.bashrc && pyenv install ${OPENPYPE_PYTHON_VERSION}
|
||||
RUN source $HOME/.bashrc \
|
||||
&& export CPPFLAGS="-I/usr/include/openssl11" \
|
||||
&& export LDFLAGS="-L/usr/lib64/openssl11 -lssl -lcrypto" \
|
||||
&& export PATH=/usr/local/openssl/bin:$PATH \
|
||||
&& export LD_LIBRARY_PATH=/usr/local/openssl/lib:$LD_LIBRARY_PATH \
|
||||
&& pyenv install ${OPENPYPE_PYTHON_VERSION}
|
||||
|
||||
COPY . /opt/openpype/
|
||||
RUN rm -rf /openpype/.poetry || echo "No Poetry installed yet."
|
||||
|
|
@ -93,12 +102,13 @@ RUN source $HOME/.bashrc \
|
|||
RUN source $HOME/.bashrc \
|
||||
&& ./tools/fetch_thirdparty_libs.sh
|
||||
|
||||
RUN echo 'export PYTHONPATH="/opt/openpype/vendor/python:$PYTHONPATH"'>> $HOME/.bashrc
|
||||
RUN source $HOME/.bashrc \
|
||||
&& bash ./tools/build.sh
|
||||
|
||||
RUN cp /usr/lib64/libffi* ./build/exe.linux-x86_64-3.9/lib \
|
||||
&& cp /usr/lib64/libssl* ./build/exe.linux-x86_64-3.9/lib \
|
||||
&& cp /usr/lib64/libcrypto* ./build/exe.linux-x86_64-3.9/lib \
|
||||
&& cp /usr/lib64/openssl11/libssl* ./build/exe.linux-x86_64-3.9/lib \
|
||||
&& cp /usr/lib64/openssl11/libcrypto* ./build/exe.linux-x86_64-3.9/lib \
|
||||
&& cp /root/.pyenv/versions/${OPENPYPE_PYTHON_VERSION}/lib/libpython* ./build/exe.linux-x86_64-3.9/lib \
|
||||
&& cp /usr/lib64/libxcb* ./build/exe.linux-x86_64-3.9/vendor/python/PySide2/Qt/lib
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,29 @@ LOG_WARNING = 1
|
|||
LOG_ERROR = 3
|
||||
|
||||
|
||||
def sanitize_long_path(path):
|
||||
"""Sanitize long paths (260 characters) when on Windows.
|
||||
|
||||
Long paths are not capatible with ZipFile or reading a file, so we can
|
||||
shorten the path to use.
|
||||
|
||||
Args:
|
||||
path (str): path to either directory or file.
|
||||
|
||||
Returns:
|
||||
str: sanitized path
|
||||
"""
|
||||
if platform.system().lower() != "windows":
|
||||
return path
|
||||
path = os.path.abspath(path)
|
||||
|
||||
if path.startswith("\\\\"):
|
||||
path = "\\\\?\\UNC\\" + path[2:]
|
||||
else:
|
||||
path = "\\\\?\\" + path
|
||||
return path
|
||||
|
||||
|
||||
def sha256sum(filename):
|
||||
"""Calculate sha256 for content of the file.
|
||||
|
||||
|
|
@ -54,6 +77,13 @@ def sha256sum(filename):
|
|||
return h.hexdigest()
|
||||
|
||||
|
||||
class ZipFileLongPaths(ZipFile):
|
||||
def _extract_member(self, member, targetpath, pwd):
|
||||
return ZipFile._extract_member(
|
||||
self, member, sanitize_long_path(targetpath), pwd
|
||||
)
|
||||
|
||||
|
||||
class OpenPypeVersion(semver.VersionInfo):
|
||||
"""Class for storing information about OpenPype version.
|
||||
|
||||
|
|
@ -780,7 +810,7 @@ class BootstrapRepos:
|
|||
def _create_openpype_zip(self, zip_path: Path, openpype_path: Path) -> None:
|
||||
"""Pack repositories and OpenPype into zip.
|
||||
|
||||
We are using :mod:`zipfile` instead :meth:`shutil.make_archive`
|
||||
We are using :mod:`ZipFile` instead :meth:`shutil.make_archive`
|
||||
because we need to decide what file and directories to include in zip
|
||||
and what not. They are determined by :attr:`zip_filter` on file level
|
||||
and :attr:`openpype_filter` on top level directory in OpenPype
|
||||
|
|
@ -834,7 +864,7 @@ class BootstrapRepos:
|
|||
|
||||
checksums.append(
|
||||
(
|
||||
sha256sum(file.as_posix()),
|
||||
sha256sum(sanitize_long_path(file.as_posix())),
|
||||
file.resolve().relative_to(openpype_root)
|
||||
)
|
||||
)
|
||||
|
|
@ -958,7 +988,9 @@ class BootstrapRepos:
|
|||
if platform.system().lower() == "windows":
|
||||
file_name = file_name.replace("/", "\\")
|
||||
try:
|
||||
current = sha256sum((path / file_name).as_posix())
|
||||
current = sha256sum(
|
||||
sanitize_long_path((path / file_name).as_posix())
|
||||
)
|
||||
except FileNotFoundError:
|
||||
return False, f"Missing file [ {file_name} ]"
|
||||
|
||||
|
|
@ -1270,7 +1302,7 @@ class BootstrapRepos:
|
|||
|
||||
# extract zip there
|
||||
self._print("Extracting zip to destination ...")
|
||||
with ZipFile(version.path, "r") as zip_ref:
|
||||
with ZipFileLongPaths(version.path, "r") as zip_ref:
|
||||
zip_ref.extractall(destination)
|
||||
|
||||
self._print(f"Installed as {version.path.stem}")
|
||||
|
|
@ -1386,7 +1418,7 @@ class BootstrapRepos:
|
|||
|
||||
# extract zip there
|
||||
self._print("extracting zip to destination ...")
|
||||
with ZipFile(openpype_version.path, "r") as zip_ref:
|
||||
with ZipFileLongPaths(openpype_version.path, "r") as zip_ref:
|
||||
self._progress_callback(75)
|
||||
zip_ref.extractall(destination)
|
||||
self._progress_callback(100)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class CreateRedshiftProxy(plugin.HoudiniCreator):
|
|||
instance_node = hou.node(instance.get("instance_node"))
|
||||
|
||||
parms = {
|
||||
"RS_archive_file": '$HIP/pyblish/`{}.$F4.rs'.format(subset_name),
|
||||
"RS_archive_file": '$HIP/pyblish/{}.$F4.rs'.format(subset_name),
|
||||
}
|
||||
|
||||
if self.selected_nodes:
|
||||
|
|
|
|||
|
|
@ -17,5 +17,5 @@ class CollectPointcacheType(pyblish.api.InstancePlugin):
|
|||
def process(self, instance):
|
||||
if instance.data["creator_identifier"] == "io.openpype.creators.houdini.bgeo": # noqa: E501
|
||||
instance.data["families"] += ["bgeo"]
|
||||
elif instance.data["creator_identifier"] == "io.openpype.creators.houdini.alembic": # noqa: E501
|
||||
elif instance.data["creator_identifier"] == "io.openpype.creators.houdini.pointcache": # noqa: E501
|
||||
instance.data["families"] += ["abc"]
|
||||
|
|
|
|||
|
|
@ -47,10 +47,6 @@ class CollectDeadlinePools(pyblish.api.InstancePlugin,
|
|||
if instance.data["secondaryPool"] == "-":
|
||||
instance.data["secondaryPool"] = None
|
||||
|
||||
self.log.info("prima::{}".format(instance.data["primaryPool"]))
|
||||
self.log.info(
|
||||
"secondaryPool::{}".format(instance.data["secondaryPool"]))
|
||||
|
||||
@classmethod
|
||||
def get_attribute_defs(cls):
|
||||
# TODO: Preferably this would be an enum for the user
|
||||
|
|
|
|||
|
|
@ -84,6 +84,13 @@ class ProjectProxyFilter(QtCore.QSortFilterProxyModel):
|
|||
super(ProjectProxyFilter, self).__init__(*args, **kwargs)
|
||||
self._filter_default = False
|
||||
|
||||
def lessThan(self, left, right):
|
||||
if left.data(PROJECT_NAME_ROLE) is None:
|
||||
return True
|
||||
if right.data(PROJECT_NAME_ROLE) is None:
|
||||
return False
|
||||
return super(ProjectProxyFilter, self).lessThan(left, right)
|
||||
|
||||
def set_filter_default(self, enabled=True):
|
||||
"""Set if filtering of default item is enabled."""
|
||||
if enabled == self._filter_default:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
from qtpy import QtCore, QtWidgets
|
||||
|
||||
from openpype.tools.utils.lib import checkstate_int_to_enum
|
||||
from openpype.tools.utils.lib import (
|
||||
checkstate_int_to_enum,
|
||||
checkstate_enum_to_int,
|
||||
)
|
||||
from openpype.tools.utils.constants import (
|
||||
CHECKED_INT,
|
||||
UNCHECKED_INT,
|
||||
ITEM_IS_USER_TRISTATE,
|
||||
)
|
||||
|
||||
|
||||
class ComboItemDelegate(QtWidgets.QStyledItemDelegate):
|
||||
|
|
@ -107,9 +115,9 @@ class MultiSelectionComboBox(QtWidgets.QComboBox):
|
|||
return
|
||||
|
||||
if state == QtCore.Qt.Unchecked:
|
||||
new_state = QtCore.Qt.Checked
|
||||
new_state = CHECKED_INT
|
||||
else:
|
||||
new_state = QtCore.Qt.Unchecked
|
||||
new_state = UNCHECKED_INT
|
||||
|
||||
elif event.type() == QtCore.QEvent.KeyPress:
|
||||
# TODO: handle QtCore.Qt.Key_Enter, Key_Return?
|
||||
|
|
@ -117,15 +125,15 @@ class MultiSelectionComboBox(QtWidgets.QComboBox):
|
|||
# toggle the current items check state
|
||||
if (
|
||||
index_flags & QtCore.Qt.ItemIsUserCheckable
|
||||
and index_flags & QtCore.Qt.ItemIsTristate
|
||||
and index_flags & ITEM_IS_USER_TRISTATE
|
||||
):
|
||||
new_state = QtCore.Qt.CheckState((int(state) + 1) % 3)
|
||||
new_state = (checkstate_enum_to_int(state) + 1) % 3
|
||||
|
||||
elif index_flags & QtCore.Qt.ItemIsUserCheckable:
|
||||
if state != QtCore.Qt.Checked:
|
||||
new_state = QtCore.Qt.Checked
|
||||
new_state = CHECKED_INT
|
||||
else:
|
||||
new_state = QtCore.Qt.Unchecked
|
||||
new_state = UNCHECKED_INT
|
||||
|
||||
if new_state is not None:
|
||||
model.setData(current_index, new_state, QtCore.Qt.CheckStateRole)
|
||||
|
|
@ -180,9 +188,9 @@ class MultiSelectionComboBox(QtWidgets.QComboBox):
|
|||
for idx in range(self.count()):
|
||||
value = self.itemData(idx, role=QtCore.Qt.UserRole)
|
||||
if value in values:
|
||||
check_state = QtCore.Qt.Checked
|
||||
check_state = CHECKED_INT
|
||||
else:
|
||||
check_state = QtCore.Qt.Unchecked
|
||||
check_state = UNCHECKED_INT
|
||||
self.setItemData(idx, check_state, QtCore.Qt.CheckStateRole)
|
||||
|
||||
def value(self):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
from qtpy import QtCore, QtGui, QtWidgets
|
||||
from openpype.tools.utils.lib import checkstate_int_to_enum
|
||||
from openpype.tools.utils.lib import (
|
||||
checkstate_int_to_enum,
|
||||
checkstate_enum_to_int,
|
||||
)
|
||||
from openpype.tools.utils.constants import (
|
||||
CHECKED_INT,
|
||||
UNCHECKED_INT,
|
||||
ITEM_IS_USER_TRISTATE,
|
||||
)
|
||||
|
||||
|
||||
class ComboItemDelegate(QtWidgets.QStyledItemDelegate):
|
||||
|
|
@ -30,7 +38,7 @@ class MultiSelectionComboBox(QtWidgets.QComboBox):
|
|||
QtCore.Qt.Key_PageDown,
|
||||
QtCore.Qt.Key_PageUp,
|
||||
QtCore.Qt.Key_Home,
|
||||
QtCore.Qt.Key_End
|
||||
QtCore.Qt.Key_End,
|
||||
}
|
||||
|
||||
top_bottom_padding = 2
|
||||
|
|
@ -127,25 +135,25 @@ class MultiSelectionComboBox(QtWidgets.QComboBox):
|
|||
return
|
||||
|
||||
if state == QtCore.Qt.Unchecked:
|
||||
new_state = QtCore.Qt.Checked
|
||||
new_state = CHECKED_INT
|
||||
else:
|
||||
new_state = QtCore.Qt.Unchecked
|
||||
new_state = UNCHECKED_INT
|
||||
|
||||
elif event.type() == QtCore.QEvent.KeyPress:
|
||||
# TODO: handle QtCore.Qt.Key_Enter, Key_Return?
|
||||
if event.key() == QtCore.Qt.Key_Space:
|
||||
# toggle the current items check state
|
||||
if (
|
||||
index_flags & QtCore.Qt.ItemIsUserCheckable
|
||||
and index_flags & QtCore.Qt.ItemIsTristate
|
||||
and index_flags & ITEM_IS_USER_TRISTATE
|
||||
):
|
||||
new_state = QtCore.Qt.CheckState((int(state) + 1) % 3)
|
||||
new_state = (checkstate_enum_to_int(state) + 1) % 3
|
||||
|
||||
elif index_flags & QtCore.Qt.ItemIsUserCheckable:
|
||||
# toggle the current items check state
|
||||
if state != QtCore.Qt.Checked:
|
||||
new_state = QtCore.Qt.Checked
|
||||
new_state = CHECKED_INT
|
||||
else:
|
||||
new_state = QtCore.Qt.Unchecked
|
||||
new_state = UNCHECKED_INT
|
||||
|
||||
if new_state is not None:
|
||||
model.setData(current_index, new_state, QtCore.Qt.CheckStateRole)
|
||||
|
|
@ -249,7 +257,6 @@ class MultiSelectionComboBox(QtWidgets.QComboBox):
|
|||
QtWidgets.QStyle.SC_ComboBoxArrow
|
||||
)
|
||||
total_width = option.rect.width() - btn_rect.width()
|
||||
font_metricts = self.fontMetrics()
|
||||
|
||||
line = 0
|
||||
self.lines = {line: []}
|
||||
|
|
@ -305,9 +312,9 @@ class MultiSelectionComboBox(QtWidgets.QComboBox):
|
|||
for idx in range(self.count()):
|
||||
value = self.itemData(idx, role=QtCore.Qt.UserRole)
|
||||
if value in values:
|
||||
check_state = QtCore.Qt.Checked
|
||||
check_state = CHECKED_INT
|
||||
else:
|
||||
check_state = QtCore.Qt.Unchecked
|
||||
check_state = UNCHECKED_INT
|
||||
self.setItemData(idx, check_state, QtCore.Qt.CheckStateRole)
|
||||
self.update_size_hint()
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,12 @@ UNCHECKED_INT = getattr(QtCore.Qt.Unchecked, "value", 0)
|
|||
PARTIALLY_CHECKED_INT = getattr(QtCore.Qt.PartiallyChecked, "value", 1)
|
||||
CHECKED_INT = getattr(QtCore.Qt.Checked, "value", 2)
|
||||
|
||||
# Checkbox state
|
||||
try:
|
||||
ITEM_IS_USER_TRISTATE = QtCore.Qt.ItemIsUserTristate
|
||||
except AttributeError:
|
||||
ITEM_IS_USER_TRISTATE = QtCore.Qt.ItemIsTristate
|
||||
|
||||
DEFAULT_PROJECT_LABEL = "< Default >"
|
||||
PROJECT_NAME_ROLE = QtCore.Qt.UserRole + 101
|
||||
PROJECT_IS_ACTIVE_ROLE = QtCore.Qt.UserRole + 102
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring Pype version."""
|
||||
__version__ = "3.16.1"
|
||||
__version__ = "3.16.2-nightly.1"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue