diff --git a/pype/ftrack/actions/action_syncToAvalon.py b/pype/ftrack/actions/action_syncToAvalon.py index c354f2332d..cad43684c9 100644 --- a/pype/ftrack/actions/action_syncToAvalon.py +++ b/pype/ftrack/actions/action_syncToAvalon.py @@ -219,7 +219,7 @@ class SyncToAvalon(BaseAction): }) elif self.avalon_project['name'] != entity['full_name']: - raise ValueError('You can\'t change name {} to {}, avalon DB won\'t work properly!'.format(avalon_asset['name'], name)) + raise ValueError('You can\'t change name {} to {}, avalon DB won\'t work properly!'.format(self.avalon_project['name'], name)) data = ftrack_utils.get_data(self, entity, session,self.custom_attributes) @@ -235,7 +235,7 @@ class SyncToAvalon(BaseAction): if self.ca_mongoid in entity['custom_attributes']: entity['custom_attributes'][self.ca_mongoid] = str(self.projectId) else: - self.log.error("Custom attribute for <{}> is not created.".format(entity['name'])) + self.log.error('Custom attribute for "{}" is not created.'.format(entity['name'])) return ## ----- ASSETS ------ @@ -271,15 +271,12 @@ class SyncToAvalon(BaseAction): self.log.debug("Asset {} - created".format(name)) # Raise error if it seems to be different ent. with same name - else: - aD = avalon_asset['data'] - # check_attr = ['parents', 'ftrackId', 'visualParent'] - if (avalon_asset['data']['parents'] != data['parents'] or - avalon_asset['silo'] != silo): + elif (avalon_asset['data']['parents'] != data['parents'] or + avalon_asset['silo'] != silo): raise ValueError('In Avalon DB already exists entity with name "{0}"'.format(name)) elif avalon_asset['name'] != entity['name']: - raise ValueError('You can\'t change name {} to {}, avalon DB won\'t work properly - please create new asset'.format(avalon_asset['name'], name)) + raise ValueError('You can\'t change name {} to {}, avalon DB won\'t work properly - please set name back'.format(avalon_asset['name'], name)) elif avalon_asset['silo'] != silo or avalon_asset['data']['parents'] != data['parents']: old_path = "/".join(avalon_asset['data']['parents']) new_path = "/".join(data['parents']) diff --git a/pype/ftrack/events/event_sync_to_avalon.py b/pype/ftrack/events/event_sync_to_avalon.py new file mode 100644 index 0000000000..0ed231c625 --- /dev/null +++ b/pype/ftrack/events/event_sync_to_avalon.py @@ -0,0 +1,225 @@ +import os +import sys +import re +import ftrack_api +from ftrack_event_handler import BaseEvent +from pype import lib +from avalon import io, inventory +from avalon.vendor import toml +from bson.objectid import ObjectId +from pype.ftrack import ftrack_utils + +class Sync_to_Avalon(BaseEvent): + + def launch(self, session, entities, event): + + self.ca_mongoid = 'avalon_mongo_id' + # If mongo_id textfield has changed: RETURN! + # - infinite loop + for ent in event['data']['entities']: + if 'keys' in ent: + if self.ca_mongoid in ent['keys']: + return + self.proj = None + + # get project + for entity in entities: + try: + base_proj = entity['link'][0] + except: + continue + self.proj = session.get(base_proj['type'], base_proj['id']) + break + + # check if project is set to auto-sync + if (self.proj is None or + 'avalon_auto_sync' not in self.proj['custom_attributes'] or + self.proj['custom_attributes']['avalon_auto_sync'] is False): + return + + # check if project have Custom Attribute 'avalon_mongo_id' + if self.ca_mongoid not in self.proj['custom_attributes']: + message = "Custom attribute '{}' for 'Project' is not created or don't have set permissions for API".format(self.ca_mongoid) + self.log.warning(message) + self.show_message(event, message, False) + return + + self.projectId = self.proj['custom_attributes'][self.ca_mongoid] + + os.environ["AVALON_PROJECT"] = self.proj['full_name'] + + # get avalon project if possible + io.install() + try: + self.avalon_project = io.find_one({"_id": ObjectId(self.projectId)}) + except: + self.avalon_project = None + + importEntities = [] + if self.avalon_project is None: + self.avalon_project = io.find_one({"type": "project", "name": self.proj["full_name"]}) + if self.avalon_project is None: + importEntities.append(self.proj) + else: + self.projectId = self.avalon_project['_id'] + + io.uninstall() + + for entity in entities: + if entity.entity_type.lower() in ['task']: + entity = entity['parent'] + + try: + mongo_id = entity['custom_attributes'][self.ca_mongoid] + except: + message = "Custom attribute '{}' for '{}' is not created or don't have set permissions for API".format(self.ca_mongoid, entity.entity_type) + self.log.warning(message) + self.show_message(event, message, False) + return + + if entity not in importEntities: + importEntities.append(entity) + + if len(importEntities) < 1: + return + + self.setAvalonAttributes() + + io.install() + try: + for entity in importEntities: + self.importToAvalon(session, entity) + session.commit() + + except ValueError as ve: + message = str(ve) + self.show_message(event, message, False) + self.log.warning(message) + + except Exception as e: + message = str(e) + ftrack_message = "SyncToAvalon event ended with unexpected error please check log file for more information." + self.show_message(event, ftrack_message, False) + self.log.error(message) + + io.uninstall() + + return + + def importToAvalon(self, session, entity): + if self.ca_mongoid not in entity['custom_attributes']: + raise ValueError("Custom attribute '{}' for '{}' is not created or don't have set permissions for API".format(self.ca_mongoid, entity['name'])) + + ftrack_utils.avalon_check_name(entity) + + entity_type = entity.entity_type + + if entity_type in ['Project']: + type = 'project' + name = entity['full_name'] + config = ftrack_utils.get_config(entity) + template = lib.get_avalon_project_template_schema() + + if self.avalon_project is None: + inventory.save(name, config, template) + self.avalon_project = io.find_one({'type': 'project', 'name': name}) + + elif self.avalon_project['name'] != name: + raise ValueError('You can\'t change name {} to {}, avalon DB won\'t work properly!'.format(self.avalon_project['name'], name)) + + self.projectId = self.avalon_project['_id'] + + data = ftrack_utils.get_data(self, entity, session,self.custom_attributes) + + io.update_many( + {"_id": ObjectId(self.projectId)}, + {'$set':{ + 'name':name, + 'config':config, + 'data':data, + }}) + + entity['custom_attributes'][self.ca_mongoid] = str(self.projectId) + + return + + if self.avalon_project is None: + self.importToAvalon(session, self.proj) + + data = ftrack_utils.get_data(self, entity, session,self.custom_attributes) + + # return if entity is silo + if len(data['parents']) == 0: + return + else: + silo = data['parents'][0] + + name = entity['name'] + + os.environ["AVALON_ASSET"] = name + os.environ['AVALON_SILO'] = silo + + avalon_asset = None + # existence of this custom attr is already checked + mongo_id = entity['custom_attributes'][self.ca_mongoid] + + if mongo_id is not "": + avalon_asset = io.find_one({'_id': ObjectId(mongo_id)}) + + if avalon_asset is None: + avalon_asset = io.find_one({'type': 'asset', 'name': name}) + if avalon_asset is None: + mongo_id = inventory.create_asset(name, silo, data, ObjectId(self.projectId)) + # Raise error if it seems to be different ent. with same name + elif (avalon_asset['data']['parents'] != data['parents'] or + avalon_asset['silo'] != silo): + raise ValueError('In Avalon DB already exists entity with name "{0}"'.format(name)) + elif avalon_asset['name'] != entity['name']: + raise ValueError('You can\'t change name {} to {}, avalon DB won\'t work properly - please set name back'.format(avalon_asset['name'], name)) + elif avalon_asset['silo'] != silo or avalon_asset['data']['parents'] != data['parents']: + old_path = "/".join(avalon_asset['data']['parents']) + new_path = "/".join(data['parents']) + raise ValueError('You can\'t move with entities. Entity "{}" was moved from "{}" to "{}" , avalon DB won\'t work properly'.format(avalon_asset['name'], old_path, new_path)) + + + io.update_many( + {"_id": ObjectId(mongo_id)}, + {'$set':{ + 'name':name, + 'silo':silo, + 'data':data, + 'parent': ObjectId(self.projectId)}}) + + entity['custom_attributes'][self.ca_mongoid] = str(mongo_id) + + def setAvalonAttributes(self): + self.custom_attributes = [] + all_avalon_attr = self.session.query('CustomAttributeGroup where name is "avalon"').one() + for cust_attr in all_avalon_attr['custom_attribute_configurations']: + if 'avalon_' not in cust_attr['key']: + self.custom_attributes.append(cust_attr) + + def _translate_event(self, session, event): + exceptions = ['assetversion', 'job', 'user', 'reviewsessionobject', 'timer', 'socialfeed', 'timelog'] + _selection = event['data'].get('entities',[]) + + _entities = list() + for entity in _selection: + if entity['entityType'] in exceptions: + continue + _entities.append( + ( + session.get(self._get_entity_type(entity), entity.get('entityId')) + ) + ) + + return [_entities, event] + +def register(session, **kw): + '''Register plugin. Called when used as an plugin.''' + + if not isinstance(session, ftrack_api.session.Session): + return + + event = Sync_to_Avalon(session) + event.register() diff --git a/pype/ftrack/events/event_test.py b/pype/ftrack/events/event_test.py new file mode 100644 index 0000000000..128e1ad197 --- /dev/null +++ b/pype/ftrack/events/event_test.py @@ -0,0 +1,25 @@ +import os +import sys +import re +import ftrack_api +from ftrack_event_handler import BaseEvent +from app import api + +class Test_Event(BaseEvent): + + def launch(self, session, entities, event): + + '''just a testing event''' + + # self.log.info(event) + + return True + + +def register(session, **kw): + '''Register plugin. Called when used as an plugin.''' + if not isinstance(session, ftrack_api.session.Session): + return + + event = Test_Event(session) + event.register() diff --git a/pype/ftrack/events/ftrack_event_handler.py b/pype/ftrack/events/ftrack_event_handler.py new file mode 100644 index 0000000000..a440d93fc4 --- /dev/null +++ b/pype/ftrack/events/ftrack_event_handler.py @@ -0,0 +1,154 @@ +# :coding: utf-8 +# :copyright: Copyright (c) 2017 ftrack +import os +import logging +import getpass +# import platform +import ftrack_api +import toml +from avalon import io, lib, pipeline +from avalon import session as sess +import acre + +from app.api import ( + Templates, + Logger +) + + +class BaseEvent(object): + '''Custom Event base class + + BaseEvent is based on ftrack.update event + - get entities from event + + If want to use different event base + - override register and *optional _translate_event method + + ''' + + def __init__(self, session): + '''Expects a ftrack_api.Session instance''' + + self.log = Logger.getLogger(self.__class__.__name__) + + self._session = session + + @property + def session(self): + '''Return current session.''' + return self._session + + def register(self): + '''Registers the event, subscribing the the discover and launch topics.''' + self.session.event_hub.subscribe('topic=ftrack.update', self._launch) + + self.log.info("Event '{}' - Registered successfully".format(self.__class__.__name__)) + + def _translate_event(self, session, event): + '''Return *event* translated structure to be used with the API.''' + _selection = event['data'].get('entities',[]) + + _entities = list() + for entity in _selection: + if entity['entityType'] in ['socialfeed']: + continue + _entities.append( + ( + session.get(self._get_entity_type(entity), entity.get('entityId')) + ) + ) + + return [ + _entities, + event + ] + + def _get_entity_type(self, entity): + '''Return translated entity type tht can be used with API.''' + # Get entity type and make sure it is lower cased. Most places except + # the component tab in the Sidebar will use lower case notation. + entity_type = entity.get('entityType').replace('_', '').lower() + + for schema in self.session.schemas: + alias_for = schema.get('alias_for') + + if ( + alias_for and isinstance(alias_for, str) and + alias_for.lower() == entity_type + ): + return schema['id'] + + for schema in self.session.schemas: + if schema['id'].lower() == entity_type: + return schema['id'] + + raise ValueError( + 'Unable to translate entity type: {0}.'.format(entity_type) + ) + + def _launch(self, event): + + self.session.reset() + + args = self._translate_event( + self.session, event + ) + + self.launch( + self.session, *args + ) + + return + + def launch(self, session, entities, event): + '''Callback method for the custom action. + + return either a bool ( True if successful or False if the action failed ) + or a dictionary with they keys `message` and `success`, the message should be a + string and will be displayed as feedback to the user, success should be a bool, + True if successful or False if the action failed. + + *session* is a `ftrack_api.Session` instance + + *entities* is a list of tuples each containing the entity type and the entity id. + If the entity is a hierarchical you will always get the entity + type TypedContext, once retrieved through a get operation you + will have the "real" entity type ie. example Shot, Sequence + or Asset Build. + + *event* the unmodified original event + + ''' + raise NotImplementedError() + + def show_message(self, event, input_message, result = False): + """ + Shows message to user who triggered event + - event - just source of user id + - input_message - message that is shown to user + - result - changes color of message (based on ftrack settings) + - True = Violet + - False = Red + """ + if not isinstance(result, bool): + result = False + + try: + message = str(input_message) + except: + return + + user_id = event['source']['user']['id'] + self.session.event_hub.publish( + ftrack_api.event.base.Event( + topic='ftrack.action.trigger-user-interface', + data=dict( + type='message', + success=result, + message=message + ), + target='applicationId=ftrack.client.web and user.id="{0}"'.format(user_id) + ), + on_error='ignore' + ) diff --git a/pype/ftrack/events/file_version_statuses.py b/pype/ftrack/events/old/file_version_statuses.py similarity index 100% rename from pype/ftrack/events/file_version_statuses.py rename to pype/ftrack/events/old/file_version_statuses.py diff --git a/pype/ftrack/events/new_task_update.py b/pype/ftrack/events/old/new_task_update.py similarity index 100% rename from pype/ftrack/events/new_task_update.py rename to pype/ftrack/events/old/new_task_update.py diff --git a/pype/ftrack/events/radio_buttons.py b/pype/ftrack/events/old/radio_buttons.py similarity index 100% rename from pype/ftrack/events/radio_buttons.py rename to pype/ftrack/events/old/radio_buttons.py diff --git a/pype/ftrack/events/thumbnail_updates.py b/pype/ftrack/events/old/thumbnail_updates.py similarity index 100% rename from pype/ftrack/events/thumbnail_updates.py rename to pype/ftrack/events/old/thumbnail_updates.py diff --git a/pype/ftrack/events/version_to_task_status.py b/pype/ftrack/events/old/version_to_task_status.py similarity index 100% rename from pype/ftrack/events/version_to_task_status.py rename to pype/ftrack/events/old/version_to_task_status.py diff --git a/pype/ftrack/events/test_event.py b/pype/ftrack/events/test_event.py deleted file mode 100644 index 3be53492d4..0000000000 --- a/pype/ftrack/events/test_event.py +++ /dev/null @@ -1,28 +0,0 @@ -# import ftrack_api as local session -import ftrack_api -from utils import print_entity_head -# -session = ftrack_api.Session() - -# ---------------------------------- - - -def test_event(event): - '''just a testing event''' - - # start of event procedure ---------------------------------- - for entity in event['data'].get('entities', []): - if entity['entityType'] == 'task' and entity['action'] == 'update': - - print "\n\nevent script: {}".format(__file__) - print_entity_head.print_entity_head(entity, session) - - # for k in task.keys(): - # print k, task[k] - # print '\n' - # print task['assignments'] - - for e in entity.keys(): - print '{0}: {1}'.format(e, entity[e]) - - # end of event procedure ---------------------------------- diff --git a/pype/ftrack/ftrack_utils.py b/pype/ftrack/ftrack_utils.py index 66d739829b..caaeb6c707 100644 --- a/pype/ftrack/ftrack_utils.py +++ b/pype/ftrack/ftrack_utils.py @@ -62,7 +62,7 @@ def get_data(parent, entity, session, custom_attributes): for parent in parents: parentId = io.find_one({'type': 'asset', 'name': parName})['_id'] if parent['parent'].entity_type != 'project' and parentId is None: - parent.importToAvalon(parent) + parent.importToAvalon(session, parent) parentId = io.find_one({'type': 'asset', 'name': parName})['_id'] hierarchy = os.path.sep.join(folderStruct) diff --git a/pype/nuke/__init__.py b/pype/nuke/__init__.py index 83235edc29..1a892c4187 100644 --- a/pype/nuke/__init__.py +++ b/pype/nuke/__init__.py @@ -3,7 +3,7 @@ import sys from avalon import api as avalon from pyblish import api as pyblish -from .. import api as pype +from .. import api from pype.nuke import menu @@ -15,12 +15,12 @@ import nuke # removing logger handler created in avalon_core for name, handler in [(handler.get_name(), handler) - for handler in pype.Logger.logging.root.handlers[:]]: + for handler in api.Logger.logging.root.handlers[:]]: if "pype" not in str(name).lower(): - pype.Logger.logging.root.removeHandler(handler) + api.Logger.logging.root.removeHandler(handler) -log = pype.Logger.getLogger(__name__, "nuke") +log = api.Logger.getLogger(__name__, "nuke") AVALON_CONFIG = os.getenv("AVALON_CONFIG", "pype") @@ -37,7 +37,7 @@ self = sys.modules[__name__] self.nLogger = None -class NukeHandler(pype.Logger.logging.Handler): +class NukeHandler(api.Logger.logging.Handler): ''' Nuke Handler - emits logs into nuke's script editor. warning will emit nuke.warning() @@ -45,7 +45,7 @@ class NukeHandler(pype.Logger.logging.Handler): ''' def __init__(self): - pype.Logger.logging.Handler.__init__(self) + api.Logger.logging.Handler.__init__(self) self.set_name("Pype_Nuke_Handler") def emit(self, record): @@ -65,11 +65,11 @@ class NukeHandler(pype.Logger.logging.Handler): nuke_handler = NukeHandler() if nuke_handler.get_name() \ not in [handler.get_name() - for handler in pype.Logger.logging.root.handlers[:]]: - pype.Logger.logging.getLogger().addHandler(nuke_handler) + for handler in api.Logger.logging.root.handlers[:]]: + api.Logger.logging.getLogger().addHandler(nuke_handler) if not self.nLogger: - self.nLogger = pype.Logger + self.nLogger = api.Logger def reload_config(): @@ -86,8 +86,6 @@ def reload_config(): "app.api", "{}.api".format(AVALON_CONFIG), "{}.templates".format(AVALON_CONFIG), - "{}.nuke".format(AVALON_CONFIG), - "{}.nuke.lib".format(AVALON_CONFIG), "{}.nuke.templates".format(AVALON_CONFIG), "{}.nuke.menu".format(AVALON_CONFIG) ): @@ -100,7 +98,8 @@ def reload_config(): def install(): - pype.fill_avalon_workdir() + + api.fill_avalon_workdir() reload_config() log.info("Registering Nuke plug-ins..") @@ -128,7 +127,7 @@ def install(): menu.install() # load data from templates - pype.load_data_from_templates() + api.load_data_from_templates() def uninstall(): @@ -140,7 +139,7 @@ def uninstall(): pyblish.deregister_callback("instanceToggled", on_pyblish_instance_toggled) # reset data from templates - pype.reset_data_from_templates() + api.reset_data_from_templates() def on_pyblish_instance_toggled(instance, old_value, new_value): diff --git a/pype/nuke/lib.py b/pype/nuke/lib.py index af0284bfae..8971a43714 100644 --- a/pype/nuke/lib.py +++ b/pype/nuke/lib.py @@ -2,6 +2,7 @@ import sys from collections import OrderedDict from pprint import pprint from avalon.vendor.Qt import QtGui +from avalon import api, io import avalon.nuke import pype.api as pype import nuke @@ -99,57 +100,6 @@ def add_rendering_knobs(node): return node -def update_frame_range(start, end, root=None): - """Set Nuke script start and end frame range - - Args: - start (float, int): start frame - end (float, int): end frame - root (object, Optional): root object from nuke's script - - Returns: - None - - """ - - knobs = { - "first_frame": start, - "last_frame": end - } - - with avalon.nuke.viewer_update_and_undo_stop(): - for key, value in knobs.items(): - if root: - root[key].setValue(value) - else: - nuke.root()[key].setValue(value) - - -def get_additional_data(container): - """Get Nuke's related data for the container - - Args: - container(dict): the container found by the ls() function - - Returns: - dict - """ - - node = container["_tool"] - tile_color = node['tile_color'].value() - if tile_color is None: - return {} - - hex = '%08x' % tile_color - rgba = [ - float(int(hex[0:2], 16)) / 255.0, - float(int(hex[2:4], 16)) / 255.0, - float(int(hex[4:6], 16)) / 255.0 - ] - - return {"color": QtGui.QColor().fromRgbF(rgba[0], rgba[1], rgba[2])} - - def set_viewers_colorspace(viewer): assert isinstance(viewer, dict), log.error( "set_viewers_colorspace(): argument should be dictionary") @@ -245,6 +195,111 @@ def get_avalon_knob_data(node): return None return data + +def reset_resolution(): + """Set resolution to project resolution.""" + log.info("Reseting resolution") + project = io.find_one({"type": "project"}) + asset = api.Session["AVALON_ASSET"] + asset = io.find_one({"name": asset, "type": "asset"}) + + try: + width = asset["data"].get("resolution_width", 1920) + height = asset["data"].get("resolution_height", 1080) + pixel_aspect = asset["data"].get("pixel_aspect", 1) + bbox = asset["data"].get("crop", "0.0.1920.1080") + + try: + x, y, r, t = bbox.split(".") + except Exception as e: + x = 0 + y = 0 + r = width + t = height + log.error("{}: {} \nFormat:Crop need to be set with dots, example: " + "0.0.1920.1080, /nSetting to default".format(__name__, e)) + + except KeyError: + log.warning( + "No resolution information found for \"{0}\".".format( + project["name"] + ) + ) + return + + used_formats = list() + for f in nuke.formats(): + if project["name"] in str(f.name()): + used_formats.append(f) + else: + format_name = project["name"] + "_1" + + crnt_fmt_str = "" + if used_formats: + check_format = used_formats[-1] + format_name = "{}_{}".format( + project["name"], + int(used_formats[-1].name()[-1])+1 + ) + log.info( + "Format exists: {}. " + "Will create new: {}...".format( + used_formats[-1].name(), + format_name) + ) + crnt_fmt_kargs = { + "width": (check_format.width()), + "height": (check_format.height()), + "x": int(check_format.x()), + "y": int(check_format.y()), + "r": int(check_format.r()), + "t": int(check_format.t()), + "pixel_aspect": float(check_format.pixelAspect()) + } + crnt_fmt_str = make_format_string(**crnt_fmt_kargs) + log.info("crnt_fmt_str: {}".format(crnt_fmt_str)) + + new_fmt_kargs = { + "width": int(width), + "height": int(height), + "x": int(x), + "y": int(y), + "r": int(r), + "t": int(t), + "pixel_aspect": float(pixel_aspect), + "project_name": format_name + } + + new_fmt_str = make_format_string(**new_fmt_kargs) + log.info("new_fmt_str: {}".format(new_fmt_str)) + + if new_fmt_str not in crnt_fmt_str: + make_format(frm_str=new_fmt_str, + project_name=new_fmt_kargs["project_name"]) + + log.info("Format is set") + + +def make_format_string(**args): + format_str = ( + "{width} " + "{height} " + "{x} " + "{y} " + "{r} " + "{t} " + "{pixel_aspect:.2f}".format(**args) + ) + return format_str + + +def make_format(**args): + log.info("Format does't exist, will create: \n{}".format(args)) + nuke.addFormat("{frm_str} " + "{project_name}".format(**args)) + nuke.root()["format"].setValue("{project_name}".format(**args)) + + # TODO: bellow functions are wip and needs to be check where they are used # ------------------------------------ diff --git a/pype/nuke/menu.py b/pype/nuke/menu.py index 97e2432e16..1fb38e389d 100644 --- a/pype/nuke/menu.py +++ b/pype/nuke/menu.py @@ -5,8 +5,17 @@ from pype.nuke import lib def install(): + menubar = nuke.menu("Nuke") menu = menubar.findItem(Session["AVALON_LABEL"]) - menu.addSeparator() - menu.addCommand("Set colorspace...", lib.set_colorspace) + # replace reset resolution from avalon core to pype's + name = "Reset Resolution" + rm_item = [(i, item) + for i, item in enumerate(menu.items()) + if name in item.name()][0] + menu.removeItem(rm_item[1].name()) + menu.addCommand(rm_item[1].name(), lib.reset_resolution, index=rm_item[0]) + + # add colorspace menu item + menu.addCommand("Set colorspace...", lib.set_colorspace, index=rm_item[0]+1) diff --git a/pype/utils/__init__.py b/pype/utils/__init__.py index 318d875f60..e69de29bb2 100644 --- a/pype/utils/__init__.py +++ b/pype/utils/__init__.py @@ -1,98 +0,0 @@ -from .lib import * - - -def load_capture_preset(path): - import capture_gui - import capture - - path = path - preset = capture_gui.lib.load_json(path) - print preset - - options = dict() - - # CODEC - id = 'Codec' - for key in preset[id]: - options[str(key)] = preset[id][key] - - # GENERIC - id = 'Generic' - for key in preset[id]: - if key.startswith('isolate'): - pass - # options['isolate'] = preset[id][key] - else: - options[str(key)] = preset[id][key] - - # RESOLUTION - id = 'Resolution' - options['height'] = preset[id]['height'] - options['width'] = preset[id]['width'] - - # DISPLAY OPTIONS - id = 'Display Options' - disp_options = {} - for key in preset['Display Options']: - if key.startswith('background'): - disp_options[key] = preset['Display Options'][key] - else: - disp_options['displayGradient'] = True - - options['display_options'] = disp_options - - # VIEWPORT OPTIONS - temp_options = {} - id = 'Renderer' - for key in preset[id]: - temp_options[str(key)] = preset[id][key] - - temp_options2 = {} - id = 'Viewport Options' - light_options = {0: "default", - 1: 'all', - 2: 'selected', - 3: 'flat', - 4: 'nolights'} - for key in preset[id]: - if key == 'high_quality': - temp_options2['multiSampleEnable'] = True - temp_options2['multiSampleCount'] = 4 - temp_options2['textureMaxResolution'] = 512 - temp_options2['enableTextureMaxRes'] = True - - if key == 'alphaCut': - temp_options2['transparencyAlgorithm'] = 5 - temp_options2['transparencyQuality'] = 1 - - if key == 'headsUpDisplay': - temp_options['headsUpDisplay'] = True - - if key == 'displayLights': - temp_options[str(key)] = light_options[preset[id][key]] - else: - temp_options[str(key)] = preset[id][key] - - for key in ['override_viewport_options', 'high_quality', 'alphaCut']: - temp_options.pop(key, None) - - options['viewport_options'] = temp_options - options['viewport2_options'] = temp_options2 - - # use active sound track - scene = capture.parse_active_scene() - options['sound'] = scene['sound'] - cam_options = dict() - cam_options['overscan'] = 1.0 - cam_options['displayFieldChart'] = False - cam_options['displayFilmGate'] = False - cam_options['displayFilmOrigin'] = False - cam_options['displayFilmPivot'] = False - cam_options['displayGateMask'] = False - cam_options['displayResolution'] = False - cam_options['displaySafeAction'] = False - cam_options['displaySafeTitle'] = False - - # options['display_options'] = temp_options - - return options diff --git a/pype/utils/lib.py b/pype/utils/lib.py index 8fdc1a4455..8b7be1a3fe 100644 --- a/pype/utils/lib.py +++ b/pype/utils/lib.py @@ -105,3 +105,99 @@ def filter_instances(context, plugin): instances = pyblish.api.instances_by_plugin(allInstances, plugin) return instances + +def load_capture_preset(path): + import capture_gui + import capture + + path = path + preset = capture_gui.lib.load_json(path) + print preset + + options = dict() + + # CODEC + id = 'Codec' + for key in preset[id]: + options[str(key)] = preset[id][key] + + # GENERIC + id = 'Generic' + for key in preset[id]: + if key.startswith('isolate'): + pass + # options['isolate'] = preset[id][key] + else: + options[str(key)] = preset[id][key] + + # RESOLUTION + id = 'Resolution' + options['height'] = preset[id]['height'] + options['width'] = preset[id]['width'] + + # DISPLAY OPTIONS + id = 'Display Options' + disp_options = {} + for key in preset['Display Options']: + if key.startswith('background'): + disp_options[key] = preset['Display Options'][key] + else: + disp_options['displayGradient'] = True + + options['display_options'] = disp_options + + # VIEWPORT OPTIONS + temp_options = {} + id = 'Renderer' + for key in preset[id]: + temp_options[str(key)] = preset[id][key] + + temp_options2 = {} + id = 'Viewport Options' + light_options = {0: "default", + 1: 'all', + 2: 'selected', + 3: 'flat', + 4: 'nolights'} + for key in preset[id]: + if key == 'high_quality': + temp_options2['multiSampleEnable'] = True + temp_options2['multiSampleCount'] = 4 + temp_options2['textureMaxResolution'] = 512 + temp_options2['enableTextureMaxRes'] = True + + if key == 'alphaCut': + temp_options2['transparencyAlgorithm'] = 5 + temp_options2['transparencyQuality'] = 1 + + if key == 'headsUpDisplay': + temp_options['headsUpDisplay'] = True + + if key == 'displayLights': + temp_options[str(key)] = light_options[preset[id][key]] + else: + temp_options[str(key)] = preset[id][key] + + for key in ['override_viewport_options', 'high_quality', 'alphaCut']: + temp_options.pop(key, None) + + options['viewport_options'] = temp_options + options['viewport2_options'] = temp_options2 + + # use active sound track + scene = capture.parse_active_scene() + options['sound'] = scene['sound'] + cam_options = dict() + cam_options['overscan'] = 1.0 + cam_options['displayFieldChart'] = False + cam_options['displayFilmGate'] = False + cam_options['displayFilmOrigin'] = False + cam_options['displayFilmPivot'] = False + cam_options['displayGateMask'] = False + cam_options['displayResolution'] = False + cam_options['displaySafeAction'] = False + cam_options['displaySafeTitle'] = False + + # options['display_options'] = temp_options + + return options