Skip to content

Commit

Permalink
OP-2053 - merge develop
Browse files Browse the repository at this point in the history
  • Loading branch information
kalisp committed Dec 14, 2021
2 parents 621118c + ca7a92b commit 1cbcdba
Show file tree
Hide file tree
Showing 189 changed files with 722 additions and 295 deletions.
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## [3.7.0-nightly.6](https://github.com/pypeclub/OpenPype/tree/HEAD)
## [3.7.0-nightly.7](https://github.com/pypeclub/OpenPype/tree/HEAD)

[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.6.4...HEAD)

Expand Down Expand Up @@ -30,6 +30,7 @@
- General: Reduce vendor imports [\#2305](https://github.com/pypeclub/OpenPype/pull/2305)
- Tools: Cleanup of unused classes [\#2304](https://github.com/pypeclub/OpenPype/pull/2304)
- Project Manager: Added ability to delete project [\#2298](https://github.com/pypeclub/OpenPype/pull/2298)
- Ftrack: Synchronize input links [\#2287](https://github.com/pypeclub/OpenPype/pull/2287)
- Nuke: extract baked review videos presets [\#2248](https://github.com/pypeclub/OpenPype/pull/2248)

**🐛 Bug fixes**
Expand Down Expand Up @@ -93,7 +94,6 @@
- Tools: Assets widget [\#2265](https://github.com/pypeclub/OpenPype/pull/2265)
- SceneInventory: Choose loader in asset switcher [\#2262](https://github.com/pypeclub/OpenPype/pull/2262)
- Style: New fonts in OpenPype style [\#2256](https://github.com/pypeclub/OpenPype/pull/2256)
- Tools: SceneInventory in OpenPype [\#2255](https://github.com/pypeclub/OpenPype/pull/2255)
- Tools: Tasks widget [\#2251](https://github.com/pypeclub/OpenPype/pull/2251)
- Tools: Creator in OpenPype [\#2244](https://github.com/pypeclub/OpenPype/pull/2244)

Expand Down Expand Up @@ -121,8 +121,8 @@

**🚀 Enhancements**

- Tools: SceneInventory in OpenPype [\#2255](https://github.com/pypeclub/OpenPype/pull/2255)
- Tools: Subset manager in OpenPype [\#2243](https://github.com/pypeclub/OpenPype/pull/2243)
- General: Skip module directories without init file [\#2239](https://github.com/pypeclub/OpenPype/pull/2239)

**🐛 Bug fixes**

Expand Down
5 changes: 4 additions & 1 deletion Dockerfile.centos7
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ RUN yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.n
ncurses \
ncurses-devel \
qt5-qtbase-devel \
xcb-util-wm \
xcb-util-renderutil \
&& yum clean all

# we need to build our own patchelf
Expand Down Expand Up @@ -92,7 +94,8 @@ RUN source $HOME/.bashrc \
RUN cp /usr/lib64/libffi* ./build/exe.linux-x86_64-3.7/lib \
&& cp /usr/lib64/libssl* ./build/exe.linux-x86_64-3.7/lib \
&& cp /usr/lib64/libcrypto* ./build/exe.linux-x86_64-3.7/lib \
&& cp /root/.pyenv/versions/${OPENPYPE_PYTHON_VERSION}/lib/libpython* ./build/exe.linux-x86_64-3.7/lib
&& cp /root/.pyenv/versions/${OPENPYPE_PYTHON_VERSION}/lib/libpython* ./build/exe.linux-x86_64-3.7/lib \
&& cp /usr/lib64/libxcb* ./build/exe.linux-x86_64-3.7/vendor/python/PySide2/Qt/lib

RUN cd /opt/openpype \
rm -rf ./vendor/bin
17 changes: 15 additions & 2 deletions openpype/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,22 @@ def run(script):
"--pyargs",
help="Run tests from package",
default=None)
def runtests(folder, mark, pyargs):
@click.option("-t",
"--test_data_folder",
help="Unzipped directory path of test file",
default=None)
@click.option("-s",
"--persist",
help="Persist test DB and published files after test end",
default=None)
@click.option("-a",
"--app_variant",
help="Provide specific app variant for test, empty for latest",
default=None)
def runtests(folder, mark, pyargs, test_data_folder, persist, app_variant):
"""Run all automatic tests after proper initialization via start.py"""
PypeCommands().run_tests(folder, mark, pyargs)
PypeCommands().run_tests(folder, mark, pyargs, test_data_folder,
persist, app_variant)


@main.command()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ def process(self, instance):
staging_dir = instance.data["stagingDir"]
self.log.info("staging_dir::{}".format(staging_dir))

stub.render(staging_dir)

# pull file name from Render Queue Output module
render_q = stub.get_render_info()
stub.render(staging_dir)
if not render_q:
raise ValueError("No file extension set in Render Queue")
_, ext = os.path.splitext(os.path.basename(render_q.file_name))
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions openpype/hosts/flame/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def _sync_utility_scripts(env=None):

fsd_paths = [os.path.join(
HOST_DIR,
"api",
"utility_scripts"
)]

Expand Down
2 changes: 1 addition & 1 deletion openpype/hosts/flame/hooks/pre_flame_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class FlamePrelaunch(PreLaunchHook):
flame_python_exe = "/opt/Autodesk/python/2021/bin/python2.7"

wtc_script_path = os.path.join(
opflame.HOST_DIR, "scripts", "wiretap_com.py")
opflame.HOST_DIR, "api", "scripts", "wiretap_com.py")

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand Down
54 changes: 36 additions & 18 deletions openpype/hosts/maya/plugins/load/load_image_plane.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ def __init__(self, cameras):
self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint)

self.camera = None
self.static_image_plane = False
self.show_in_all_views = False

self.widgets = {
"label": QtWidgets.QLabel("Select camera for image plane."),
"list": QtWidgets.QListWidget(),
"staticImagePlane": QtWidgets.QCheckBox(),
"showInAllViews": QtWidgets.QCheckBox(),
"warning": QtWidgets.QLabel("No cameras selected!"),
"buttons": QtWidgets.QWidget(),
"okButton": QtWidgets.QPushButton("Ok"),
Expand All @@ -31,6 +35,9 @@ def __init__(self, cameras):
for camera in cameras:
self.widgets["list"].addItem(camera)

self.widgets["staticImagePlane"].setText("Make Image Plane Static")
self.widgets["showInAllViews"].setText("Show Image Plane in All Views")

# Build buttons.
layout = QtWidgets.QHBoxLayout(self.widgets["buttons"])
layout.addWidget(self.widgets["okButton"])
Expand All @@ -40,6 +47,8 @@ def __init__(self, cameras):
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.widgets["label"])
layout.addWidget(self.widgets["list"])
layout.addWidget(self.widgets["staticImagePlane"])
layout.addWidget(self.widgets["showInAllViews"])
layout.addWidget(self.widgets["buttons"])
layout.addWidget(self.widgets["warning"])

Expand All @@ -54,6 +63,8 @@ def on_ok_pressed(self):
if self.camera is None:
self.widgets["warning"].setVisible(True)
return
self.show_in_all_views = self.widgets["showInAllViews"].isChecked()
self.static_image_plane = self.widgets["staticImagePlane"].isChecked()

self.close()

Expand All @@ -65,15 +76,15 @@ def on_cancel_pressed(self):
class ImagePlaneLoader(api.Loader):
"""Specific loader of plate for image planes on selected camera."""

families = ["plate", "render"]
families = ["image", "plate", "render"]
label = "Load imagePlane."
representations = ["mov", "exr", "preview", "png"]
icon = "image"
color = "orange"

def load(self, context, name, namespace, data):
def load(self, context, name, namespace, data, options=None):
import pymel.core as pm

new_nodes = []
image_plane_depth = 1000
asset = context['asset']['name']
Expand All @@ -85,17 +96,23 @@ def load(self, context, name, namespace, data):

# Get camera from user selection.
camera = None
default_cameras = [
"frontShape", "perspShape", "sideShape", "topShape"
]
cameras = [
x for x in pm.ls(type="camera") if x.name() not in default_cameras
]
camera_names = {x.getParent().name(): x for x in cameras}
camera_names["Create new camera."] = "create_camera"
window = CameraWindow(camera_names.keys())
window.exec_()
camera = camera_names[window.camera]
is_static_image_plane = None
is_in_all_views = None
if data:
camera = pm.PyNode(data.get("camera"))
is_static_image_plane = data.get("static_image_plane")
is_in_all_views = data.get("in_all_views")

if not camera:
cameras = pm.ls(type="camera")
camera_names = {x.getParent().name(): x for x in cameras}
camera_names["Create new camera."] = "create_camera"
window = CameraWindow(camera_names.keys())
window.exec_()
camera = camera_names[window.camera]

is_static_image_plane = window.static_image_plane
is_in_all_views = window.show_in_all_views

if camera == "create_camera":
camera = pm.createNode("camera")
Expand All @@ -111,13 +128,14 @@ def load(self, context, name, namespace, data):

# Create image plane
image_plane_transform, image_plane_shape = pm.imagePlane(
camera=camera, showInAllViews=False
fileName=context["representation"]["data"]["path"],
camera=camera, showInAllViews=is_in_all_views
)
image_plane_shape.depth.set(image_plane_depth)

image_plane_shape.imageName.set(
context["representation"]["data"]["path"]
)
if is_static_image_plane:
image_plane_shape.detach()
image_plane_transform.setRotation(camera.getRotation())

start_frame = pm.playbackOptions(q=True, min=True)
end_frame = pm.playbackOptions(q=True, max=True)
Expand Down
2 changes: 2 additions & 0 deletions openpype/hosts/maya/plugins/publish/collect_look.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,8 @@ def collect_attributes_changed(self, instance):
if not cmds.attributeQuery(attr, node=node, exists=True):
continue
attribute = "{}.{}".format(node, attr)
if cmds.getAttr(attribute, type=True) == "message":
continue
node_attributes[attr] = cmds.getAttr(attribute)

attributes.append({"name": node,
Expand Down
9 changes: 7 additions & 2 deletions openpype/hosts/maya/plugins/publish/collect_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,14 +224,19 @@ def process(self, context):
# append full path
full_exp_files = []
aov_dict = {}

default_render_file = context.data.get('project_settings')\
.get('maya')\
.get('create')\
.get('CreateRender')\
.get('default_render_image_folder')
# replace relative paths with absolute. Render products are
# returned as list of dictionaries.
publish_meta_path = None
for aov in exp_files:
full_paths = []
for file in aov[aov.keys()[0]]:
full_path = os.path.join(workspace, "renders", file)
full_path = os.path.join(workspace, default_render_file,
file)
full_path = full_path.replace("\\", "/")
full_paths.append(full_path)
publish_meta_path = os.path.dirname(full_path)
Expand Down
19 changes: 16 additions & 3 deletions openpype/hosts/maya/plugins/publish/validate_render_image_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,24 @@ class ValidateRenderImageRule(pyblish.api.InstancePlugin):

def process(self, instance):

assert get_file_rule("images") == "renders", (
"Workspace's `images` file rule must be set to: renders"
default_render_file = self.get_default_render_image_folder(instance)

assert get_file_rule("images") == default_render_file, (
"Workspace's `images` file rule must be set to: {}".format(
default_render_file
)
)

@classmethod
def repair(cls, instance):
pm.workspace.fileRules["images"] = "renders"
default = cls.get_default_render_image_folder(instance)
pm.workspace.fileRules["images"] = default
pm.system.Workspace.save()

@staticmethod
def get_default_render_image_folder(instance):
return instance.context.data.get('project_settings')\
.get('maya') \
.get('create') \
.get('CreateRender') \
.get('default_render_image_folder')
13 changes: 7 additions & 6 deletions openpype/hosts/nuke/plugins/publish/extract_render_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@ def process(self, instance):
self.log.info("Start frame: {}".format(first_frame))
self.log.info("End frame: {}".format(last_frame))

# write node url might contain nuke's ctl expressin
# as [python ...]/path...
path = node["file"].evaluate()

# Ensure output directory exists.
directory = os.path.dirname(node["file"].value())
if not os.path.exists(directory):
os.makedirs(directory)
out_dir = os.path.dirname(path)
if not os.path.exists(out_dir):
os.makedirs(out_dir)

# Render frames
nuke.execute(
Expand All @@ -58,15 +62,12 @@ def process(self, instance):
if "slate" in families:
first_frame += 1

path = node['file'].value()
out_dir = os.path.dirname(path)
ext = node["file_type"].value()

if "representations" not in instance.data:
instance.data["representations"] = []

collected_frames = os.listdir(out_dir)

if len(collected_frames) == 1:
repre = {
'name': ext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ def process(self, instance):

if not repre.get("files"):
msg = ("no frames were collected, "
"you need to render them")
"you need to render them.\n"
"Check properties of write node (group) and"
"select 'Local' option in 'Publish' dropdown.")
self.log.error(msg)
raise ValidationException(msg)

Expand Down
2 changes: 2 additions & 0 deletions openpype/lib/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,8 @@ def __init__(self, application, executable, **data):
# subprocess.Popen launch arguments (first argument in constructor)
self.launch_args = executable.as_args()
self.launch_args.extend(application.arguments)
if self.data.get("app_args"):
self.launch_args.extend(self.data.pop("app_args"))

# Handle launch environemtns
env = self.data.pop("env", None)
Expand Down
10 changes: 8 additions & 2 deletions openpype/lib/avalon_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,13 +508,18 @@ def get_workdir_data(project_doc, asset_doc, task_name, host_name):
Returns:
dict: Data prepared for filling workdir template.
"""
hierarchy = "/".join(asset_doc["data"]["parents"])

task_type = asset_doc['data']['tasks'].get(task_name, {}).get('type')

project_task_types = project_doc["config"]["tasks"]
task_code = project_task_types.get(task_type, {}).get("short_name")

asset_parents = asset_doc["data"]["parents"]
hierarchy = "/".join(asset_parents)

parent_name = project_doc["name"]
if asset_parents:
parent_name = asset_parents[-1]

data = {
"project": {
"name": project_doc["name"],
Expand All @@ -526,6 +531,7 @@ def get_workdir_data(project_doc, asset_doc, task_name, host_name):
"short": task_code,
},
"asset": asset_doc["name"],
"parent": parent_name,
"app": host_name,
"user": getpass.getuser(),
"hierarchy": hierarchy,
Expand Down
1 change: 0 additions & 1 deletion openpype/lib/path_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,6 @@ def _get_local_sync_dirmap(self, project_settings):
mapping = {}

if not project_settings["global"]["sync_server"]["enabled"]:
log.debug("Site Sync not enabled")
return mapping

from openpype.settings.lib import get_site_local_overrides
Expand Down
Loading

0 comments on commit 1cbcdba

Please sign in to comment.