Skip to content

Commit

Permalink
[Automated] Merged develop into main
Browse files Browse the repository at this point in the history
  • Loading branch information
ynbot authored Dec 15, 2021
2 parents ea03444 + 373217b commit 39bddac
Show file tree
Hide file tree
Showing 200 changed files with 1,204 additions and 281 deletions.
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
27 changes: 27 additions & 0 deletions openpype/hosts/aftereffects/plugins/publish/closeAE.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
"""Close AE after publish. For Webpublishing only."""
import pyblish.api

from avalon import aftereffects


class CloseAE(pyblish.api.ContextPlugin):
"""Close AE after publish. For Webpublishing only.
"""

order = pyblish.api.IntegratorOrder + 14
label = "Close AE"
optional = True
active = True

hosts = ["aftereffects"]
targets = ["remotepublish"]

def process(self, context):
self.log.info("CloseAE")

stub = aftereffects.stub()
self.log.info("Shutting down AE")
stub.save()
stub.close()
self.log.info("AE closed")
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class CollectCurrentFile(pyblish.api.ContextPlugin):
"""Inject the current working file into context"""

order = pyblish.api.CollectorOrder - 0.5
order = pyblish.api.CollectorOrder - 0.49
label = "Current File"
hosts = ["aftereffects"]

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import os
import re
import pyblish.api

from avalon import aftereffects


class CollectExtensionVersion(pyblish.api.ContextPlugin):
""" Pulls and compares version of installed extension.
It is recommended to use same extension as in provided Openpype code.
Please use Anastasiy’s Extension Manager or ZXPInstaller to update
extension in case of an error.
You can locate extension.zxp in your installed Openpype code in
`repos/avalon-core/avalon/aftereffects`
"""
# This technically should be a validator, but other collectors might be
# impacted with usage of obsolete extension, so collector that runs first
# was chosen
order = pyblish.api.CollectorOrder - 0.5
label = "Collect extension version"
hosts = ["aftereffects"]

optional = True
active = True

def process(self, context):
installed_version = aftereffects.stub().get_extension_version()

if not installed_version:
raise ValueError("Unknown version, probably old extension")

manifest_url = os.path.join(os.path.dirname(aftereffects.__file__),
"extension", "CSXS", "manifest.xml")

if not os.path.exists(manifest_url):
self.log.debug("Unable to locate extension manifest, not checking")
return

expected_version = None
with open(manifest_url) as fp:
content = fp.read()
found = re.findall(r'(ExtensionBundleVersion=")([0-9\.]+)(")',
content)
if found:
expected_version = found[0][1]

if expected_version != installed_version:
msg = (
"Expected version '{}' found '{}'\n Please update"
" your installed extension, it might not work properly."
).format(expected_version, installed_version)

raise ValueError(msg)
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ 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
2 changes: 1 addition & 1 deletion openpype/hosts/blender/hooks/pre_pyside_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def execute(self):

def inner_execute(self):
# Get blender's python directory
version_regex = re.compile(r"^2\.[0-9]{2}$")
version_regex = re.compile(r"^[2-3]\.[0-9]+$")

executable = self.launch_context.executable.executable_path
if os.path.basename(executable).lower() != "blender.exe":
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
Loading

0 comments on commit 39bddac

Please sign in to comment.