Merge branch 'develop' into hotfix/nuke-publish-fixes

This commit is contained in:
Jakub Jezek 2019-11-06 14:36:24 +01:00
commit fe918b1bd6
17 changed files with 154 additions and 34 deletions

View file

@ -1,6 +1,47 @@
# Pype changelog #
Welcome to pype changelog
## 2.3.0 ##
_release date: 6 Oct 2019_
**new**:
- _(maya)_ support for yeti rigs and yeti caches
- _(maya)_ validator for comparing arbitrary attributes against ftrack
- _(pype)_ burnins can now show current date and time
- _(muster)_ pools can now be set in render globals in maya
- _(pype)_ Rest API has been implemented in beta stage
- _(nuke)_ LUT loader has been added
- _(pype)_ rudimentary user module has been added as preparation for user management
- _(pype)_ a simple logging GUI has been added to pype tray
- _(nuke)_ nuke can now bake input process into mov
- _(maya)_ imported models now have selection handle displayed by defaulting
- _(avalon)_ it's is now possible to load multiple assets at once using loader
- _(maya)_ added ability to automatically connect yeti rig to a mesh upon loading
**changed**:
- _(ftrack)_ event server now runs two parallel processes and is able to keep queue of events to process.
- _(nuke)_ task name is now added to all rendered subsets
- _(pype)_ adding more families to standalone publisher
- _(pype)_ standalone publisher now uses pyblish-lite
- _(pype)_ standalone publisher can now create review quicktimes
- _(ftrack)_ queries to ftrack were sped up
- _(ftrack)_ multiple ftrack action have been deprecated
- _(avalon)_ avalon upstream has been updated to 5.5.0
- _(nukestudio)_ published transforms can now be animated
-
**fix**:
- _(maya)_ fps popup button didn't work in some cases
- _(maya)_ geometry instances and references in maya were losing shader assignments
- _(muster)_ muster rendering templates were not working correctly
- _(maya)_ arnold tx texture conversion wasn't respecting colorspace set by the artist
- _(pype)_ problems with avalon db sync
- _(maya)_ ftrack was rounding FPS making it inconsistent
- _(pype)_ wrong icon names in Creator
- _(maya)_ scene inventory wasn't showing anything if representation was removed from database after it's been loaded to the scene
- _(nukestudio)_ multiple bugs squashed
- _(loader)_ loader was taking long time to show all the loading action when first launcher in maya
## 2.2.0 ##
_release date: 8 Sept 2019_

View file

@ -9,7 +9,7 @@ from pypeapp import config
import logging
log = logging.getLogger(__name__)
__version__ = "2.1.0"
__version__ = "2.3.0"
PACKAGE_DIR = os.path.dirname(__file__)
PLUGINS_DIR = os.path.join(PACKAGE_DIR, "plugins")

View file

@ -101,6 +101,8 @@ class Sync_to_Avalon(BaseEvent):
avalon_project = result['project']
except Exception as e:
session.reset() # reset session to clear it
message = str(e)
title = 'Hey You! Unknown Error has been raised! (*look below*)'
ftrack_message = (

View file

@ -20,7 +20,8 @@ class ThumbnailEvents(BaseEvent):
if parent.get('thumbnail') and not task.get('thumbnail'):
task['thumbnail'] = parent['thumbnail']
self.log.info('>>> Updated thumbnail on [ %s/%s ]'.format(
parent['name'], task['name']))
parent['name'], task['name']
))
# Update task thumbnail from published version
# if (entity['entityType'] == 'assetversion' and
@ -32,18 +33,24 @@ class ThumbnailEvents(BaseEvent):
version = session.get('AssetVersion', entity['entityId'])
thumbnail = version.get('thumbnail')
task = version['task']
if thumbnail:
task['thumbnail'] = thumbnail
task['parent']['thumbnail'] = thumbnail
self.log.info('>>> Updating thumbnail for task and shot\
[ {} ]'.format(task['name']))
parent = version['asset']['parent']
task = version['task']
parent['thumbnail_id'] = version['thumbnail_id']
if parent.entity_type.lower() == "project":
name = parent["full_name"]
else:
name = parent["name"]
msg = '>>> Updating thumbnail for shot [ {} ]'.format(name)
if task:
task['thumbnail_id'] = version['thumbnail_id']
msg += " and task [ {} ]".format(task["name"])
self.log.info(msg)
session.commit()
pass
def register(session, plugins_presets):
'''Register plugin. Called when used as an plugin.'''

View file

@ -533,7 +533,9 @@ if __name__ == "__main__":
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
if hasattr(signal, "SIGKILL"):
signal.signal(signal.SIGKILL, signal_handler)
try:
signal.signal(signal.SIGKILL, signal_handler)
except OSError:
pass
sys.exit(main(sys.argv))

View file

@ -47,7 +47,8 @@ if __name__ == "__main__":
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
if hasattr(signal, "SIGKILL"):
try:
signal.signal(signal.SIGKILL, signal_handler)
except OSError:
pass
sys.exit(main(sys.argv))

View file

@ -112,7 +112,8 @@ if __name__ == "__main__":
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
if hasattr(signal, "SIGKILL"):
try:
signal.signal(signal.SIGKILL, signal_handler)
except OSError:
pass
sys.exit(main(sys.argv))

View file

@ -94,7 +94,8 @@ if __name__ == "__main__":
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
if hasattr(signal, "SIGKILL"):
try:
signal.signal(signal.SIGKILL, signal_handler)
except OSError:
pass
sys.exit(main(sys.argv))

View file

@ -963,7 +963,7 @@ class BuildWorkfile(WorkfileSettings):
def process(self,
regex_filter=None,
version=None,
representations=["exr", "dpx", "lutJson"]):
representations=["exr", "dpx", "lutJson", "mov", "preview"]):
"""
A short description.
@ -1020,6 +1020,8 @@ class BuildWorkfile(WorkfileSettings):
version=version,
representations=representations)
log.info("__ subsets: `{}`".format(subsets))
nodes_backdrop = list()
for name, subset in subsets.items():

View file

@ -1,7 +1,6 @@
from avalon import api
import pype.maya.plugin
import os
import pymel.core as pm
from pypeapp import config
@ -70,6 +69,7 @@ class AssProxyLoader(pype.maya.plugin.ReferenceLoader):
import os
from maya import cmds
import pymel.core as pm
node = container["objectName"]

View file

@ -2,7 +2,6 @@ from avalon import api
import pype.maya.plugin
import os
from pypeapp import config
import pymel.core as pm
reload(config)

View file

@ -1,5 +1,3 @@
import pymel.core as pc
from avalon import api
from Qt import QtWidgets
@ -14,6 +12,8 @@ class ImagePlaneLoader(api.Loader):
color = "orange"
def load(self, context, name, namespace, data):
import pymel.core as pc
new_nodes = []
image_plane_depth = 1000

View file

@ -1,8 +1,6 @@
import pype.maya.plugin
import os
from pypeapp import config
import pymel.core as pm
reload(config)
import pype.maya.plugin
reload(pype.maya.plugin)
@ -20,9 +18,10 @@ class ReferenceLoader(pype.maya.plugin.ReferenceLoader):
color = "orange"
def process_reference(self, context, name, namespace, data):
import maya.cmds as cmds
from avalon import maya
import pymel.core as pm
try:
family = context["representation"]["context"]["family"]

View file

@ -1,9 +1,17 @@
import pype.maya.plugin
import os
from collections import defaultdict
from pypeapp import config
import pype.maya.plugin
from pype.maya import lib
class YetiRigLoader(pype.maya.plugin.ReferenceLoader):
"""
This loader will load Yeti rig. You can select something in scene and if it
has same ID as mesh published with rig, their shapes will be linked
together.
"""
families = ["yetiRig"]
representations = ["ma"]
@ -18,6 +26,32 @@ class YetiRigLoader(pype.maya.plugin.ReferenceLoader):
import maya.cmds as cmds
from avalon import maya
# get roots of selected hierarchies
selected_roots = []
for sel in cmds.ls(sl=True, long=True):
selected_roots.append(sel.split("|")[1])
# get all objects under those roots
selected_hierarchy = []
for root in selected_roots:
selected_hierarchy.append(cmds.listRelatives(
root,
allDescendents=True) or [])
# flatten the list and filter only shapes
shapes_flat = []
for root in selected_hierarchy:
shapes = cmds.ls(root, long=True, type="mesh") or []
for shape in shapes:
shapes_flat.append(shape)
# create dictionary of cbId and shape nodes
scene_lookup = defaultdict(list)
for node in shapes_flat:
cb_id = lib.get_id(node)
scene_lookup[cb_id] = node
# load rig
with maya.maintained_selection():
nodes = cmds.file(self.fname,
namespace=namespace,
@ -26,6 +60,20 @@ class YetiRigLoader(pype.maya.plugin.ReferenceLoader):
groupReference=True,
groupName="{}:{}".format(namespace, name))
# for every shape node we've just loaded find matching shape by its
# cbId in selection. If found outMesh of scene shape will connect to
# inMesh of loaded shape.
for destination_node in nodes:
source_node = scene_lookup[lib.get_id(destination_node)]
if source_node:
self.log.info("found: {}".format(source_node))
self.log.info(
"creating connection to {}".format(destination_node))
cmds.connectAttr("{}.outMesh".format(source_node),
"{}.inMesh".format(destination_node),
force=True)
groupName = "{}:{}".format(namespace, name)
presets = config.get_presets(project=os.environ['AVALON_PROJECT'])
@ -38,6 +86,4 @@ class YetiRigLoader(pype.maya.plugin.ReferenceLoader):
c[0], c[1], c[2])
self[:] = nodes
self.log.info("Yeti Rig Connection Manager will be available soon")
return nodes

View file

@ -126,6 +126,18 @@ class ExtractYetiRig(pype.api.Extractor):
with open(settings_path, "w") as fp:
json.dump(settings, fp, ensure_ascii=False)
# add textures to transfers
if 'transfers' not in instance.data:
instance.data['transfers'] = []
for resource in instance.data.get('resources', []):
for file in resource['files']:
src = file
dst = os.path.join(image_search_path, os.path.basename(file))
instance.data['transfers'].append([src, dst])
self.log.info("adding transfer {} -> {}". format(src, dst))
# Ensure the imageSearchPath is being remapped to the publish folder
attr_value = {"%s.imageSearchPath" % n: str(image_search_path) for
n in yeti_nodes}

View file

@ -196,12 +196,14 @@ class CollectPlatesData(api.InstancePlugin):
thumb_file = head + ".png"
thumb_path = os.path.join(staging_dir, thumb_file)
thumb_frame = instance.data["sourceIn"] + ((instance.data["sourceOut"] - instance.data["sourceIn"])/2)
thumbnail = item.thumbnail(instance.data["sourceIn"]).save(
thumbnail = item.thumbnail(thumb_frame).save(
thumb_path,
format='png'
)
self.log.debug("__ thumbnail: {}".format(thumbnail))
self.log.debug("__ sourceIn: `{}`".format(instance.data["sourceIn"]))
self.log.debug("__ thumbnail: `{}`, frame: `{}`".format(thumbnail, thumb_frame))
thumb_representation = {
'files': thumb_file,

View file

@ -106,7 +106,6 @@ class CollectReviews(api.InstancePlugin):
def create_thumbnail(self, instance):
item = instance.data["item"]
source_in = instance.data["sourceIn"]
source_path = instance.data["sourcePath"]
source_file = os.path.basename(source_path)
@ -119,11 +118,17 @@ class CollectReviews(api.InstancePlugin):
thumb_file = head + ".png"
thumb_path = os.path.join(staging_dir, thumb_file)
self.log.debug("__ thumb_path: {}".format(thumb_path))
self.log.debug("__ source_in: {}".format(source_in))
thumbnail = item.thumbnail(source_in).save(
thumb_frame = instance.data["sourceIn"] + ((instance.data["sourceOut"] - instance.data["sourceIn"])/2)
thumbnail = item.thumbnail(thumb_frame).save(
thumb_path,
format='png'
)
self.log.debug("__ sourceIn: `{}`".format(instance.data["sourceIn"]))
self.log.debug("__ thumbnail: `{}`, frame: `{}`".format(thumbnail, thumb_frame))
self.log.debug("__ thumbnail: {}".format(thumbnail))
thumb_representation = {