mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge remote-tracking branch 'origin/2.x/develop' into feature/harmony-refactor
This commit is contained in:
commit
53e5e0c33c
9 changed files with 319 additions and 56 deletions
7
.github/weekly-digest.yml
vendored
Normal file
7
.github/weekly-digest.yml
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Configuration for weekly-digest - https://github.com/apps/weekly-digest
|
||||
publishDay: sun
|
||||
canPublishIssues: true
|
||||
canPublishPullRequests: true
|
||||
canPublishContributors: true
|
||||
canPublishStargazers: true
|
||||
canPublishCommits: true
|
||||
167
CHANGELOG.md
167
CHANGELOG.md
|
|
@ -1,6 +1,169 @@
|
|||
# Changelog
|
||||
|
||||
## [2.12.0](https://github.com/pypeclub/pype/tree/2.12.0) (2020-09-09)
|
||||
## [2.13.1](https://github.com/pypeclub/pype/tree/2.13.1) (2020-10-23)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/pype/compare/2.13.0...2.13.1)
|
||||
|
||||
**Enhancements:**
|
||||
|
||||
- move maya look assigner to pype menu [\#292](https://github.com/pypeclub/pype/issues/292)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Layer name is not propagating to metadata in Photoshop [\#654](https://github.com/pypeclub/pype/issues/654)
|
||||
- Loader in Photoshop fails with "can't set attribute" [\#650](https://github.com/pypeclub/pype/issues/650)
|
||||
- Hiero: Review video file adding one frame to the end [\#659](https://github.com/pypeclub/pype/issues/659)
|
||||
|
||||
## [2.13.0](https://github.com/pypeclub/pype/tree/2.13.0) (2020-10-18)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.5...2.13.0)
|
||||
|
||||
**Enhancements:**
|
||||
|
||||
- Deadline Output Folder [\#636](https://github.com/pypeclub/pype/issues/636)
|
||||
- Nuke Camera Loader [\#565](https://github.com/pypeclub/pype/issues/565)
|
||||
- Deadline publish job shows publishing output folder [\#649](https://github.com/pypeclub/pype/pull/649)
|
||||
- Get latest version in lib [\#642](https://github.com/pypeclub/pype/pull/642)
|
||||
- Improved publishing of multiple representation from SP [\#638](https://github.com/pypeclub/pype/pull/638)
|
||||
- Launch TvPaint shot work file from within Ftrack [\#631](https://github.com/pypeclub/pype/pull/631)
|
||||
- Add mp4 support for RV action. [\#628](https://github.com/pypeclub/pype/pull/628)
|
||||
- Maya: allow renders to have version synced with workfile [\#618](https://github.com/pypeclub/pype/pull/618)
|
||||
- Renaming nukestudio host folder to hiero [\#617](https://github.com/pypeclub/pype/pull/617)
|
||||
- Harmony: More efficient publishing [\#615](https://github.com/pypeclub/pype/pull/615)
|
||||
- Ftrack server action improvement [\#608](https://github.com/pypeclub/pype/pull/608)
|
||||
- Deadline user defaults to pype username if present [\#607](https://github.com/pypeclub/pype/pull/607)
|
||||
- Standalone publisher now has icon [\#606](https://github.com/pypeclub/pype/pull/606)
|
||||
- Nuke render write targeting knob improvement [\#603](https://github.com/pypeclub/pype/pull/603)
|
||||
- Animated pyblish gui [\#602](https://github.com/pypeclub/pype/pull/602)
|
||||
- Maya: Deadline - make use of asset dependencies optional [\#591](https://github.com/pypeclub/pype/pull/591)
|
||||
- Nuke: Publishing, loading and updating alembic cameras [\#575](https://github.com/pypeclub/pype/pull/575)
|
||||
- Maya: add look assigner to pype menu even if scriptsmenu is not available [\#573](https://github.com/pypeclub/pype/pull/573)
|
||||
- Store task types in the database [\#572](https://github.com/pypeclub/pype/pull/572)
|
||||
- Maya: Tiled EXRs to scanline EXRs render option [\#512](https://github.com/pypeclub/pype/pull/512)
|
||||
- Fusion basic integration [\#452](https://github.com/pypeclub/pype/pull/452)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Burnin script did not propagate ffmpeg output [\#640](https://github.com/pypeclub/pype/issues/640)
|
||||
- Pyblish-pype spacer in terminal wasn't transparent [\#646](https://github.com/pypeclub/pype/pull/646)
|
||||
- Lib subprocess without logger [\#645](https://github.com/pypeclub/pype/pull/645)
|
||||
- Nuke: prevent crash if we only have single frame in sequence [\#644](https://github.com/pypeclub/pype/pull/644)
|
||||
- Burnin script logs better output [\#641](https://github.com/pypeclub/pype/pull/641)
|
||||
- Missing audio on farm submission. [\#639](https://github.com/pypeclub/pype/pull/639)
|
||||
- review from imagesequence error [\#633](https://github.com/pypeclub/pype/pull/633)
|
||||
- Hiero: wrong order of fps clip instance data collecting [\#627](https://github.com/pypeclub/pype/pull/627)
|
||||
- Add source for review instances. [\#625](https://github.com/pypeclub/pype/pull/625)
|
||||
- Task processing in event sync [\#623](https://github.com/pypeclub/pype/pull/623)
|
||||
- sync to avalon doesn t remove renamed task [\#619](https://github.com/pypeclub/pype/pull/619)
|
||||
- Intent publish setting wasn't working with default value [\#562](https://github.com/pypeclub/pype/pull/562)
|
||||
- Maya: Updating a look where the shader name changed, leaves the geo without a shader [\#514](https://github.com/pypeclub/pype/pull/514)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Audio file existence check [\#614](https://github.com/pypeclub/pype/pull/614)
|
||||
- Avalon module without Qt [\#581](https://github.com/pypeclub/pype/pull/581)
|
||||
- Ftrack module without Qt [\#577](https://github.com/pypeclub/pype/pull/577)
|
||||
|
||||
## [2.12.5](https://github.com/pypeclub/pype/tree/2.12.5) (2020-10-14)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.4...2.12.5)
|
||||
|
||||
**Enhancements:**
|
||||
|
||||
- Launch TvPaint shot work file from within Ftrack [\#629](https://github.com/pypeclub/pype/issues/629)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Harmony: Disable application launch logic [\#637](https://github.com/pypeclub/pype/pull/637)
|
||||
|
||||
## [2.12.4](https://github.com/pypeclub/pype/tree/2.12.4) (2020-10-08)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.3...2.12.4)
|
||||
|
||||
**Enhancements:**
|
||||
|
||||
- convert nukestudio to hiero host [\#616](https://github.com/pypeclub/pype/issues/616)
|
||||
- Fusion basic integration [\#451](https://github.com/pypeclub/pype/issues/451)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Sync to avalon doesn't remove renamed task [\#605](https://github.com/pypeclub/pype/issues/605)
|
||||
- NukeStudio: FPS collecting into clip instances [\#624](https://github.com/pypeclub/pype/pull/624)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- NukeStudio: small fixes [\#622](https://github.com/pypeclub/pype/pull/622)
|
||||
- NukeStudio: broken order of plugins [\#620](https://github.com/pypeclub/pype/pull/620)
|
||||
|
||||
## [2.12.3](https://github.com/pypeclub/pype/tree/2.12.3) (2020-10-06)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.2...2.12.3)
|
||||
|
||||
**Enhancements:**
|
||||
|
||||
- Nuke Publish Camera [\#567](https://github.com/pypeclub/pype/issues/567)
|
||||
- Harmony: open xstage file no matter of its name [\#526](https://github.com/pypeclub/pype/issues/526)
|
||||
- Stop integration of unwanted data [\#387](https://github.com/pypeclub/pype/issues/387)
|
||||
- Move avalon-launcher functionality to pype [\#229](https://github.com/pypeclub/pype/issues/229)
|
||||
- avalon workfiles api [\#214](https://github.com/pypeclub/pype/issues/214)
|
||||
- Store task types [\#180](https://github.com/pypeclub/pype/issues/180)
|
||||
- Avalon Mongo Connection split [\#136](https://github.com/pypeclub/pype/issues/136)
|
||||
- nk camera workflow [\#71](https://github.com/pypeclub/pype/issues/71)
|
||||
- Hiero integration added [\#590](https://github.com/pypeclub/pype/pull/590)
|
||||
- Anatomy instance data collection is substantially faster for many instances [\#560](https://github.com/pypeclub/pype/pull/560)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- test issue [\#596](https://github.com/pypeclub/pype/issues/596)
|
||||
- Harmony: empty scene contamination [\#583](https://github.com/pypeclub/pype/issues/583)
|
||||
- Edit publishing in SP doesn't respect shot selection for publishing [\#542](https://github.com/pypeclub/pype/issues/542)
|
||||
- Pathlib breaks compatibility with python2 hosts [\#281](https://github.com/pypeclub/pype/issues/281)
|
||||
- Updating a look where the shader name changed leaves the geo without a shader [\#237](https://github.com/pypeclub/pype/issues/237)
|
||||
- Better error handling [\#84](https://github.com/pypeclub/pype/issues/84)
|
||||
- Harmony: function signature [\#609](https://github.com/pypeclub/pype/pull/609)
|
||||
- Nuke: gizmo publishing error [\#594](https://github.com/pypeclub/pype/pull/594)
|
||||
- Harmony: fix clashing namespace of called js functions [\#584](https://github.com/pypeclub/pype/pull/584)
|
||||
- Maya: fix maya scene type preset exception [\#569](https://github.com/pypeclub/pype/pull/569)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Nuke Gizmo publishing [\#597](https://github.com/pypeclub/pype/issues/597)
|
||||
- nuke gizmo publishing error [\#592](https://github.com/pypeclub/pype/issues/592)
|
||||
- Publish EDL [\#579](https://github.com/pypeclub/pype/issues/579)
|
||||
- Publish render from SP [\#576](https://github.com/pypeclub/pype/issues/576)
|
||||
- rename ftrack custom attribute group to `pype` [\#184](https://github.com/pypeclub/pype/issues/184)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- NKS small fixes [\#587](https://github.com/pypeclub/pype/pull/587)
|
||||
- Standalone publisher editorial plugins interfering [\#580](https://github.com/pypeclub/pype/pull/580)
|
||||
|
||||
## [2.12.2](https://github.com/pypeclub/pype/tree/2.12.2) (2020-09-25)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.1...2.12.2)
|
||||
|
||||
**Enhancements:**
|
||||
|
||||
- pype config GUI [\#241](https://github.com/pypeclub/pype/issues/241)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Harmony: Saving heavy scenes will crash [\#507](https://github.com/pypeclub/pype/issues/507)
|
||||
- Extract review a representation name with `\*\_burnin` [\#388](https://github.com/pypeclub/pype/issues/388)
|
||||
- Hierarchy data was not considering active isntances [\#551](https://github.com/pypeclub/pype/pull/551)
|
||||
|
||||
## [2.12.1](https://github.com/pypeclub/pype/tree/2.12.1) (2020-09-15)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.0...2.12.1)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Pype: changelog.md is outdated [\#503](https://github.com/pypeclub/pype/issues/503)
|
||||
- dependency security alert ! [\#484](https://github.com/pypeclub/pype/issues/484)
|
||||
- Maya: RenderSetup is missing update [\#106](https://github.com/pypeclub/pype/issues/106)
|
||||
- \<pyblish plugin\> extract effects creates new instance [\#78](https://github.com/pypeclub/pype/issues/78)
|
||||
|
||||
## [2.12.0](https://github.com/pypeclub/pype/tree/2.12.0) (2020-09-10)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/pype/compare/2.11.8...2.12.0)
|
||||
|
||||
|
|
@ -16,13 +179,13 @@
|
|||
- Properly containerize image plane loads. [\#434](https://github.com/pypeclub/pype/pull/434)
|
||||
- Option to keep the review files. [\#426](https://github.com/pypeclub/pype/pull/426)
|
||||
- Isolate view on instance members. [\#425](https://github.com/pypeclub/pype/pull/425)
|
||||
- ftrack group is bcw compatible [\#418](https://github.com/pypeclub/pype/pull/418)
|
||||
- Maya: Publishing of tile renderings on Deadline [\#398](https://github.com/pypeclub/pype/pull/398)
|
||||
- Feature/little bit better logging gui [\#383](https://github.com/pypeclub/pype/pull/383)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Maya: Fix tile order for Draft Tile Assembler [\#511](https://github.com/pypeclub/pype/pull/511)
|
||||
- NukeStudio: Fix comment tag collection and integration. [\#508](https://github.com/pypeclub/pype/pull/508)
|
||||
- Remove extra dash [\#501](https://github.com/pypeclub/pype/pull/501)
|
||||
- Fix: strip dot from repre names in single frame renders [\#498](https://github.com/pypeclub/pype/pull/498)
|
||||
- Better handling of destination during integrating [\#485](https://github.com/pypeclub/pype/pull/485)
|
||||
|
|
|
|||
|
|
@ -22,8 +22,9 @@ class PhotoshopServerStub():
|
|||
def open(self, path):
|
||||
"""
|
||||
Open file located at 'path' (local).
|
||||
:param path: <string> file path locally
|
||||
:return: None
|
||||
Args:
|
||||
path(string): file path locally
|
||||
Returns: None
|
||||
"""
|
||||
self.websocketserver.call(self.client.call
|
||||
('Photoshop.open', path=path)
|
||||
|
|
@ -32,9 +33,10 @@ class PhotoshopServerStub():
|
|||
def read(self, layer, layers_meta=None):
|
||||
"""
|
||||
Parses layer metadata from Headline field of active document
|
||||
:param layer: <namedTuple Layer("id":XX, "name":"YYY")
|
||||
:param layers_meta: full list from Headline (for performance in loops)
|
||||
:return:
|
||||
Args:
|
||||
layer: <namedTuple Layer("id":XX, "name":"YYY")
|
||||
layers_meta: full list from Headline (for performance in loops)
|
||||
Returns:
|
||||
"""
|
||||
if layers_meta is None:
|
||||
layers_meta = self.get_layers_metadata()
|
||||
|
|
@ -44,22 +46,26 @@ class PhotoshopServerStub():
|
|||
def imprint(self, layer, data, all_layers=None, layers_meta=None):
|
||||
"""
|
||||
Save layer metadata to Headline field of active document
|
||||
:param layer: <namedTuple> Layer("id": XXX, "name":'YYY')
|
||||
:param data: <string> json representation for single layer
|
||||
:param all_layers: <list of namedTuples> - for performance, could be
|
||||
Args:
|
||||
layer (namedtuple): Layer("id": XXX, "name":'YYY')
|
||||
data(string): json representation for single layer
|
||||
all_layers (list of namedtuples): for performance, could be
|
||||
injected for usage in loop, if not, single call will be
|
||||
triggered
|
||||
:param layers_meta: <string> json representation from Headline
|
||||
layers_meta(string): json representation from Headline
|
||||
(for performance - provide only if imprint is in
|
||||
loop - value should be same)
|
||||
:return: None
|
||||
Returns: None
|
||||
"""
|
||||
if not layers_meta:
|
||||
layers_meta = self.get_layers_metadata()
|
||||
# json.dumps writes integer values in a dictionary to string, so
|
||||
# anticipating it here.
|
||||
if str(layer.id) in layers_meta and layers_meta[str(layer.id)]:
|
||||
layers_meta[str(layer.id)].update(data)
|
||||
if data:
|
||||
layers_meta[str(layer.id)].update(data)
|
||||
else:
|
||||
layers_meta.pop(str(layer.id))
|
||||
else:
|
||||
layers_meta[str(layer.id)] = data
|
||||
|
||||
|
|
@ -83,7 +89,7 @@ class PhotoshopServerStub():
|
|||
"""
|
||||
Returns JSON document with all(?) layers in active document.
|
||||
|
||||
:return: <list of namedtuples>
|
||||
Returns: <list of namedtuples>
|
||||
Format of tuple: { 'id':'123',
|
||||
'name': 'My Layer 1',
|
||||
'type': 'GUIDE'|'FG'|'BG'|'OBJ'
|
||||
|
|
@ -97,8 +103,9 @@ class PhotoshopServerStub():
|
|||
def get_layers_in_layers(self, layers):
|
||||
"""
|
||||
Return all layers that belong to layers (might be groups).
|
||||
:param layers: <list of namedTuples>
|
||||
:return: <list of namedTuples>
|
||||
Args:
|
||||
layers <list of namedTuples>:
|
||||
Returns: <list of namedTuples>
|
||||
"""
|
||||
all_layers = self.get_layers()
|
||||
ret = []
|
||||
|
|
@ -116,7 +123,7 @@ class PhotoshopServerStub():
|
|||
def create_group(self, name):
|
||||
"""
|
||||
Create new group (eg. LayerSet)
|
||||
:return: <namedTuple Layer("id":XX, "name":"YYY")>
|
||||
Returns: <namedTuple Layer("id":XX, "name":"YYY")>
|
||||
"""
|
||||
ret = self.websocketserver.call(self.client.call
|
||||
('Photoshop.create_group',
|
||||
|
|
@ -128,7 +135,7 @@ class PhotoshopServerStub():
|
|||
def group_selected_layers(self, name):
|
||||
"""
|
||||
Group selected layers into new LayerSet (eg. group)
|
||||
:return: <json representation of Layer>
|
||||
Returns: <json representation of Layer>
|
||||
"""
|
||||
res = self.websocketserver.call(self.client.call
|
||||
('Photoshop.group_selected_layers',
|
||||
|
|
@ -139,7 +146,7 @@ class PhotoshopServerStub():
|
|||
def get_selected_layers(self):
|
||||
"""
|
||||
Get a list of actually selected layers
|
||||
:return: <list of Layer('id':XX, 'name':"YYY")>
|
||||
Returns: <list of Layer('id':XX, 'name':"YYY")>
|
||||
"""
|
||||
res = self.websocketserver.call(self.client.call
|
||||
('Photoshop.get_selected_layers'))
|
||||
|
|
@ -147,9 +154,10 @@ class PhotoshopServerStub():
|
|||
|
||||
def select_layers(self, layers):
|
||||
"""
|
||||
Selecte specified layers in Photoshop
|
||||
:param layers: <list of Layer('id':XX, 'name':"YYY")>
|
||||
:return: None
|
||||
Selects specified layers in Photoshop by its ids
|
||||
Args:
|
||||
layers: <list of Layer('id':XX, 'name':"YYY")>
|
||||
Returns: None
|
||||
"""
|
||||
layer_ids = [layer.id for layer in layers]
|
||||
|
||||
|
|
@ -161,7 +169,7 @@ class PhotoshopServerStub():
|
|||
def get_active_document_full_name(self):
|
||||
"""
|
||||
Returns full name with path of active document via ws call
|
||||
:return: <string> full path with name
|
||||
Returns(string): full path with name
|
||||
"""
|
||||
res = self.websocketserver.call(
|
||||
self.client.call('Photoshop.get_active_document_full_name'))
|
||||
|
|
@ -171,7 +179,7 @@ class PhotoshopServerStub():
|
|||
def get_active_document_name(self):
|
||||
"""
|
||||
Returns just a name of active document via ws call
|
||||
:return: <string> file name
|
||||
Returns(string): file name
|
||||
"""
|
||||
res = self.websocketserver.call(self.client.call
|
||||
('Photoshop.get_active_document_name'))
|
||||
|
|
@ -181,7 +189,7 @@ class PhotoshopServerStub():
|
|||
def is_saved(self):
|
||||
"""
|
||||
Returns true if no changes in active document
|
||||
:return: <boolean>
|
||||
Returns: <boolean>
|
||||
"""
|
||||
return self.websocketserver.call(self.client.call
|
||||
('Photoshop.is_saved'))
|
||||
|
|
@ -189,7 +197,7 @@ class PhotoshopServerStub():
|
|||
def save(self):
|
||||
"""
|
||||
Saves active document
|
||||
:return: None
|
||||
Returns: None
|
||||
"""
|
||||
self.websocketserver.call(self.client.call
|
||||
('Photoshop.save'))
|
||||
|
|
@ -197,10 +205,11 @@ class PhotoshopServerStub():
|
|||
def saveAs(self, image_path, ext, as_copy):
|
||||
"""
|
||||
Saves active document to psd (copy) or png or jpg
|
||||
:param image_path: <string> full local path
|
||||
:param ext: <string psd|jpg|png>
|
||||
:param as_copy: <boolean>
|
||||
:return: None
|
||||
Args:
|
||||
image_path(string): full local path
|
||||
ext: <string psd|jpg|png>
|
||||
as_copy: <boolean>
|
||||
Returns: None
|
||||
"""
|
||||
self.websocketserver.call(self.client.call
|
||||
('Photoshop.saveAs',
|
||||
|
|
@ -211,9 +220,10 @@ class PhotoshopServerStub():
|
|||
def set_visible(self, layer_id, visibility):
|
||||
"""
|
||||
Set layer with 'layer_id' to 'visibility'
|
||||
:param layer_id: <int>
|
||||
:param visibility: <true - set visible, false - hide>
|
||||
:return: None
|
||||
Args:
|
||||
layer_id: <int>
|
||||
visibility: <true - set visible, false - hide>
|
||||
Returns: None
|
||||
"""
|
||||
self.websocketserver.call(self.client.call
|
||||
('Photoshop.set_visible',
|
||||
|
|
@ -224,7 +234,7 @@ class PhotoshopServerStub():
|
|||
"""
|
||||
Reads layers metadata from Headline from active document in PS.
|
||||
(Headline accessible by File > File Info)
|
||||
:return: <string> - json documents
|
||||
Returns(string): - json documents
|
||||
"""
|
||||
layers_data = {}
|
||||
res = self.websocketserver.call(self.client.call('Photoshop.read'))
|
||||
|
|
@ -234,22 +244,26 @@ class PhotoshopServerStub():
|
|||
pass
|
||||
return layers_data
|
||||
|
||||
def import_smart_object(self, path):
|
||||
def import_smart_object(self, path, layer_name):
|
||||
"""
|
||||
Import the file at `path` as a smart object to active document.
|
||||
|
||||
Args:
|
||||
path (str): File path to import.
|
||||
layer_name (str): Unique layer name to differentiate how many times
|
||||
same smart object was loaded
|
||||
"""
|
||||
res = self.websocketserver.call(self.client.call
|
||||
('Photoshop.import_smart_object',
|
||||
path=path))
|
||||
path=path, name=layer_name))
|
||||
|
||||
return self._to_records(res).pop()
|
||||
|
||||
def replace_smart_object(self, layer, path):
|
||||
def replace_smart_object(self, layer, path, layer_name):
|
||||
"""
|
||||
Replace the smart object `layer` with file at `path`
|
||||
layer_name (str): Unique layer name to differentiate how many times
|
||||
same smart object was loaded
|
||||
|
||||
Args:
|
||||
layer (namedTuple): Layer("id":XX, "name":"YY"..).
|
||||
|
|
@ -257,8 +271,18 @@ class PhotoshopServerStub():
|
|||
"""
|
||||
self.websocketserver.call(self.client.call
|
||||
('Photoshop.replace_smart_object',
|
||||
layer=layer,
|
||||
path=path))
|
||||
layer_id=layer.id,
|
||||
path=path, name=layer_name))
|
||||
|
||||
def delete_layer(self, layer_id):
|
||||
"""
|
||||
Deletes specific layer by it's id.
|
||||
Args:
|
||||
layer_id (int): id of layer to delete
|
||||
"""
|
||||
self.websocketserver.call(self.client.call
|
||||
('Photoshop.delete_layer',
|
||||
layer_id=layer_id))
|
||||
|
||||
def close(self):
|
||||
self.client.close()
|
||||
|
|
@ -267,8 +291,8 @@ class PhotoshopServerStub():
|
|||
"""
|
||||
Converts string json representation into list of named tuples for
|
||||
dot notation access to work.
|
||||
:return: <list of named tuples>
|
||||
:param res: <string> - json representation
|
||||
Returns: <list of named tuples>
|
||||
res(string): - json representation
|
||||
"""
|
||||
try:
|
||||
layers_data = json.loads(res)
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin):
|
|||
'''
|
||||
|
||||
label = "Collect Hierarchy Context"
|
||||
order = pyblish.api.CollectorOrder + 0.102
|
||||
order = pyblish.api.CollectorOrder + 0.103
|
||||
|
||||
def update_dict(self, ex_dict, new_dict):
|
||||
for key in ex_dict:
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ class CollectPlatesData(api.InstancePlugin):
|
|||
"frameEnd": instance.data["sourceOut"] - instance.data["sourceIn"] + 1,
|
||||
'step': 1,
|
||||
'fps': instance.context.data["fps"],
|
||||
'tags': ["preview"],
|
||||
'tags': ["review"],
|
||||
'name': "preview",
|
||||
'ext': "mov",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,14 +133,24 @@ class ExtractReviewCutUp(pype.api.Extractor):
|
|||
"{ffprobe_path} -i \"{full_input_path}\" -show_streams "
|
||||
"-select_streams a -loglevel error"
|
||||
).format(**locals())
|
||||
|
||||
self.log.debug("ffprob_cmd: {}".format(ffprob_cmd))
|
||||
audio_check_output = pype.api.subprocess(ffprob_cmd)
|
||||
self.log.debug(
|
||||
"audio_check_output: {}".format(audio_check_output))
|
||||
|
||||
# Fix one frame difference
|
||||
""" TODO: this is just work-around for issue:
|
||||
https://github.com/pypeclub/pype/issues/659
|
||||
"""
|
||||
frame_duration_extend = 1
|
||||
if audio_check_output:
|
||||
frame_duration_extend = 0
|
||||
|
||||
# translate frame to sec
|
||||
start_sec = float(frame_start) / fps
|
||||
duration_sec = float(frame_end - frame_start + 1) / fps
|
||||
duration_sec = float(
|
||||
(frame_end - frame_start) + frame_duration_extend) / fps
|
||||
|
||||
empty_add = None
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
from avalon import api, photoshop
|
||||
import os
|
||||
import re
|
||||
|
||||
stub = photoshop.stub()
|
||||
|
||||
|
|
@ -13,10 +15,13 @@ class ImageLoader(api.Loader):
|
|||
representations = ["*"]
|
||||
|
||||
def load(self, context, name=None, namespace=None, data=None):
|
||||
layer_name = self._get_unique_layer_name(context["asset"]["name"],
|
||||
name)
|
||||
with photoshop.maintained_selection():
|
||||
layer = stub.import_smart_object(self.fname)
|
||||
layer = stub.import_smart_object(self.fname, layer_name)
|
||||
|
||||
self[:] = [layer]
|
||||
namespace = namespace or layer_name
|
||||
|
||||
return photoshop.containerise(
|
||||
name,
|
||||
|
|
@ -27,11 +32,25 @@ class ImageLoader(api.Loader):
|
|||
)
|
||||
|
||||
def update(self, container, representation):
|
||||
""" Switch asset or change version """
|
||||
layer = container.pop("layer")
|
||||
|
||||
context = representation.get("context", {})
|
||||
|
||||
namespace_from_container = re.sub(r'_\d{3}$', '',
|
||||
container["namespace"])
|
||||
layer_name = "{}_{}".format(context["asset"], context["subset"])
|
||||
# switching assets
|
||||
if namespace_from_container != layer_name:
|
||||
layer_name = self._get_unique_layer_name(context["asset"],
|
||||
context["subset"])
|
||||
else: # switching version - keep same name
|
||||
layer_name = container["namespace"]
|
||||
|
||||
path = api.get_representation_path(representation)
|
||||
with photoshop.maintained_selection():
|
||||
stub.replace_smart_object(
|
||||
layer, api.get_representation_path(representation)
|
||||
layer, path, layer_name
|
||||
)
|
||||
|
||||
stub.imprint(
|
||||
|
|
@ -39,7 +58,36 @@ class ImageLoader(api.Loader):
|
|||
)
|
||||
|
||||
def remove(self, container):
|
||||
container["layer"].Delete()
|
||||
"""
|
||||
Removes element from scene: deletes layer + removes from Headline
|
||||
Args:
|
||||
container (dict): container to be removed - used to get layer_id
|
||||
"""
|
||||
layer = container.pop("layer")
|
||||
stub.imprint(layer, {})
|
||||
stub.delete_layer(layer.id)
|
||||
|
||||
def switch(self, container, representation):
|
||||
self.update(container, representation)
|
||||
|
||||
def _get_unique_layer_name(self, asset_name, subset_name):
|
||||
"""
|
||||
Gets all layer names and if 'name' is present in them, increases
|
||||
suffix by 1 (eg. creates unique layer name - for Loader)
|
||||
Args:
|
||||
name (string): in format asset_subset
|
||||
|
||||
Returns:
|
||||
(string): name_00X (without version)
|
||||
"""
|
||||
name = "{}_{}".format(asset_name, subset_name)
|
||||
names = {}
|
||||
for layer in stub.get_layers():
|
||||
layer_name = re.sub(r'_\d{3}$', '', layer.name)
|
||||
if layer_name in names.keys():
|
||||
names[layer_name] = names[layer_name] + 1
|
||||
else:
|
||||
names[layer_name] = 1
|
||||
occurrences = names.get(name, 0)
|
||||
|
||||
return "{}_{:0>3d}".format(name, occurrences + 1)
|
||||
|
|
|
|||
|
|
@ -20,12 +20,22 @@ class ActionDelegate(QtWidgets.QStyledItemDelegate):
|
|||
if not is_group:
|
||||
return
|
||||
|
||||
extender_width = int(option.decorationSize.width() / 2)
|
||||
extender_height = int(option.decorationSize.height() / 2)
|
||||
grid_size = option.widget.gridSize()
|
||||
x_offset = int(
|
||||
(grid_size.width() / 2)
|
||||
- (option.rect.width() / 2)
|
||||
)
|
||||
item_x = option.rect.x() - x_offset
|
||||
|
||||
tenth_width = int(grid_size.width() / 10)
|
||||
tenth_height = int(grid_size.height() / 10)
|
||||
|
||||
extender_width = tenth_width * 2
|
||||
extender_height = tenth_height * 2
|
||||
|
||||
exteder_rect = QtCore.QRectF(
|
||||
option.rect.x() + (option.rect.width() / 10),
|
||||
option.rect.y() + (option.rect.height() / 10),
|
||||
item_x + tenth_width,
|
||||
option.rect.y() + tenth_height,
|
||||
extender_width,
|
||||
extender_height
|
||||
)
|
||||
|
|
@ -38,13 +48,14 @@ class ActionDelegate(QtWidgets.QStyledItemDelegate):
|
|||
painter.drawPath(path)
|
||||
|
||||
divider = (2 * self.extender_lines) + 1
|
||||
line_height = extender_height / divider
|
||||
line_width = extender_width - (extender_width / 5)
|
||||
pos_x = exteder_rect.x() + extender_width / 10
|
||||
extender_offset = int(extender_width / 6)
|
||||
line_height = round(extender_height / divider)
|
||||
line_width = extender_width - (extender_offset * 2) + 1
|
||||
pos_x = exteder_rect.x() + extender_offset
|
||||
pos_y = exteder_rect.y() + line_height
|
||||
for _ in range(self.extender_lines):
|
||||
line_rect = QtCore.QRectF(
|
||||
pos_x, pos_y, line_width, round(line_height)
|
||||
pos_x, pos_y, line_width, line_height
|
||||
)
|
||||
painter.fillRect(line_rect, self.extender_fg)
|
||||
pos_y += 2 * line_height
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
__version__ = "2.12.3"
|
||||
__version__ = "2.13.0"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue