diff --git a/pype/plugins/global/publish/collect_assumed_destination.py b/pype/plugins/global/publish/collect_assumed_destination.py index 4f9d180843..fa6a3d9423 100644 --- a/pype/plugins/global/publish/collect_assumed_destination.py +++ b/pype/plugins/global/publish/collect_assumed_destination.py @@ -9,7 +9,7 @@ class CollectAssumedDestination(pyblish.api.ContextPlugin): label = "Collect Assumed Destination" order = pyblish.api.CollectorOrder + 0.498 - exclude_families = ["clip", "trackItem"] + exclude_families = ["clip"] def process(self, context): for instance in context: diff --git a/pype/plugins/global/publish/collect_presets.py b/pype/plugins/global/publish/collect_presets.py new file mode 100644 index 0000000000..8edf9797de --- /dev/null +++ b/pype/plugins/global/publish/collect_presets.py @@ -0,0 +1,14 @@ +from pyblish import api +from pypeapp import config + + +class CollectPresets(api.ContextPlugin): + """Collect Presets.""" + + order = api.CollectorOrder + label = "Collect Presets" + + def process(self, context): + context.data["presets"] = config.get_presets() + self.log.info(context.data["presets"]) + return diff --git a/pype/plugins/nukestudio/publish/validate_resolved_paths.py b/pype/plugins/nukestudio/_unused/validate_resolved_paths.py similarity index 100% rename from pype/plugins/nukestudio/publish/validate_resolved_paths.py rename to pype/plugins/nukestudio/_unused/validate_resolved_paths.py diff --git a/pype/plugins/nukestudio/publish/validate_task.py b/pype/plugins/nukestudio/_unused/validate_task.py similarity index 100% rename from pype/plugins/nukestudio/publish/validate_task.py rename to pype/plugins/nukestudio/_unused/validate_task.py diff --git a/pype/plugins/nukestudio/publish/collectTags.py b/pype/plugins/nukestudio/publish/collectTags.py deleted file mode 100644 index 5137a9f22f..0000000000 --- a/pype/plugins/nukestudio/publish/collectTags.py +++ /dev/null @@ -1,14 +0,0 @@ -from pyblish import api - - -class CollectTrackItemTags(api.InstancePlugin): - """Collect Tags from selected track items.""" - - order = api.CollectorOrder - label = "Collect Tags" - hosts = ["nukestudio"] - - def process(self, instance): - instance.data["tags"] = instance.data["item"].tags() - self.log.info(instance.data["tags"]) - return diff --git a/pype/plugins/nukestudio/publish/collect.py b/pype/plugins/nukestudio/publish/collect_clips.py similarity index 68% rename from pype/plugins/nukestudio/publish/collect.py rename to pype/plugins/nukestudio/publish/collect_clips.py index de6b2b3fca..69ec4814e9 100644 --- a/pype/plugins/nukestudio/publish/collect.py +++ b/pype/plugins/nukestudio/publish/collect_clips.py @@ -1,28 +1,14 @@ from pyblish import api -class CollectFramerate(api.ContextPlugin): - """Collect framerate from selected sequence.""" - order = api.CollectorOrder - label = "Collect Framerate" - hosts = ["nukestudio"] - - def process(self, context): - for item in context.data.get("selection", []): - context.data["framerate"] = item.sequence().framerate().toFloat() - return - - -class CollectTrackItems(api.ContextPlugin): +class CollectClips(api.ContextPlugin): """Collect all Track items selection.""" order = api.CollectorOrder - label = "Collect Track Items" + label = "Collect Clips" hosts = ["nukestudio"] def process(self, context): - import os - data = {} for item in context.data.get("selection", []): self.log.info("__ item: {}".format(item)) @@ -43,13 +29,13 @@ class CollectTrackItems(api.ContextPlugin): } for key, value in data.items(): - + family = "clip" context.create_instance( name=key, - subset="trackItem", + subset="{0}{1}".format(family, 'Default'), asset=value["item"].name(), item=value["item"], - family="trackItem", + family=family, tasks=value["tasks"], startFrame=value["startFrame"], endFrame=value["endFrame"], diff --git a/pype/plugins/nukestudio/publish/collect_framerate.py b/pype/plugins/nukestudio/publish/collect_framerate.py new file mode 100644 index 0000000000..822be8fb9b --- /dev/null +++ b/pype/plugins/nukestudio/publish/collect_framerate.py @@ -0,0 +1,13 @@ +from pyblish import api + +class CollectFramerate(api.ContextPlugin): + """Collect framerate from selected sequence.""" + + order = api.CollectorOrder + label = "Collect Framerate" + hosts = ["nukestudio"] + + def process(self, context): + for item in context.data.get("selection", []): + context.data["framerate"] = item.sequence().framerate().toFloat() + return diff --git a/pype/plugins/nukestudio/publish/collect_hierarchy_context.py b/pype/plugins/nukestudio/publish/collect_hierarchy_context.py new file mode 100644 index 0000000000..b421d31f79 --- /dev/null +++ b/pype/plugins/nukestudio/publish/collect_hierarchy_context.py @@ -0,0 +1,72 @@ +import pyblish.api +from avalon import api + + +class CollectHierarchyContext(pyblish.api.ContextPlugin): + """Collecting hierarchy context from `parents` and `hierarchy` data + present in `clip` family instances coming from the request json data file + + It will add `hierarchical_context` into each instance for integrate + plugins to be able to create needed parents for the context if they + don't exist yet + """ + + label = "Collect Hierarchy Context" + order = pyblish.api.CollectorOrder + 0.1 + + def update_dict(self, ex_dict, new_dict): + for key in ex_dict: + if key in new_dict and isinstance(ex_dict[key], dict): + new_dict[key] = self.update_dict(ex_dict[key], new_dict[key]) + else: + new_dict[key] = ex_dict[key] + return new_dict + + def process(self, context): + json_data = context.data.get("jsonData", None) + temp_context = {} + for instance in json_data['instances']: + if instance['family'] in 'projectfile': + continue + + in_info = {} + name = instance['name'] + # suppose that all instances are Shots + in_info['entity_type'] = 'Shot' + + instance_pyblish = [ + i for i in context.data["instances"] if i.data['asset'] in name][0] + in_info['custom_attributes'] = { + 'fend': instance_pyblish.data['endFrame'], + 'fstart': instance_pyblish.data['startFrame'], + 'fps': instance_pyblish.data['fps'] + } + + in_info['tasks'] = instance['tasks'] + + parents = instance.get('parents', []) + + actual = {name: in_info} + + for parent in reversed(parents): + next_dict = {} + parent_name = parent["entityName"] + next_dict[parent_name] = {} + next_dict[parent_name]["entity_type"] = parent["entityType"] + next_dict[parent_name]["childs"] = actual + actual = next_dict + + temp_context = self.update_dict(temp_context, actual) + self.log.debug(temp_context) + + # TODO: 100% sure way of get project! Will be Name or Code? + project_name = api.Session["AVALON_PROJECT"] + final_context = {} + final_context[project_name] = {} + final_context[project_name]['entity_type'] = 'Project' + final_context[project_name]['childs'] = temp_context + + # adding hierarchy context to instance + context.data["hierarchyContext"] = final_context + self.log.debug("context.data[hierarchyContext] is: {}".format( + context.data["hierarchyContext"])) diff --git a/pype/plugins/nukestudio/publish/collect_metadata.py b/pype/plugins/nukestudio/publish/collect_metadata.py new file mode 100644 index 0000000000..23d36ba4a2 --- /dev/null +++ b/pype/plugins/nukestudio/publish/collect_metadata.py @@ -0,0 +1,30 @@ +from pyblish import api + + +class CollectClipMetadata(api.InstancePlugin): + """Collect Metadata from selected track items.""" + + order = api.CollectorOrder + 0.01 + label = "Collect Metadata" + hosts = ["nukestudio"] + + def process(self, instance): + item = instance.data["item"] + ti_metadata = self.metadata_to_string(dict(item.metadata())) + ms_metadata = self.metadata_to_string( + dict(item.source().mediaSource().metadata())) + + instance.data["clipMetadata"] = ti_metadata + instance.data["mediaSourceMetadata"] = ms_metadata + + self.log.info(instance.data["clipMetadata"]) + self.log.info(instance.data["mediaSourceMetadata"]) + return + + def metadata_to_string(self, metadata): + data = dict() + for k, v in metadata.items(): + if v not in ["-", ""]: + data[str(k)] = v + + return data diff --git a/pype/plugins/nukestudio/publish/collect_subsets.py b/pype/plugins/nukestudio/publish/collect_subsets.py new file mode 100644 index 0000000000..b27a718f49 --- /dev/null +++ b/pype/plugins/nukestudio/publish/collect_subsets.py @@ -0,0 +1,45 @@ +from pyblish import api + + +class CollectClipSubsets(api.InstancePlugin): + """Collect Subsets from selected Clips, Tags, Preset.""" + + order = api.CollectorOrder + 0.01 + label = "Collect Subsets" + hosts = ["nukestudio"] + families = ['clip'] + + def process(self, instance): + tags = instance.data.get('tags', None) + presets = instance.context.data['presets'][ + instance.context.data['host']] + if tags: + self.log.info(tags) + + if presets: + self.log.info(presets) + + # get presets and tags + # iterate tags and get task family + # iterate tags and get host family + # iterate tags and get handles family + + instance = instance.context.create_instance(instance_name) + + instance.data.update({ + "subset": subset_name, + "stagingDir": staging_dir, + "task": task, + "representation": ext[1:], + "host": host, + "asset": asset_name, + "label": label, + "name": name, + # "hierarchy": hierarchy, + # "parents": parents, + "family": family, + "families": [families, 'ftrack'], + "publish": True, + # "files": files_list + }) + instances.append(instance) diff --git a/pype/plugins/nukestudio/publish/collect_tags.py b/pype/plugins/nukestudio/publish/collect_tags.py new file mode 100644 index 0000000000..9ae34d415f --- /dev/null +++ b/pype/plugins/nukestudio/publish/collect_tags.py @@ -0,0 +1,30 @@ +from pyblish import api + + +class CollectClipTags(api.InstancePlugin): + """Collect Tags from selected track items.""" + + order = api.CollectorOrder + label = "Collect Tags" + hosts = ["nukestudio"] + families = ['clip'] + + def process(self, instance): + tags = instance.data["item"].tags() + + tags_d = [] + if tags: + for t in tags: + tag_data = { + "name": t.name(), + "object": t, + "metadata": t.metadata(), + "inTime": t.inTime(), + "outTime": t.outTime(), + } + tags_d.append(tag_data) + + instance.data["tags"] = tags_d + + self.log.info(instance.data["tags"]) + return diff --git a/pype/plugins/nukestudio/publish/integrate_assumed_destination.py b/pype/plugins/nukestudio/publish/integrate_assumed_destination.py new file mode 100644 index 0000000000..c1936994e4 --- /dev/null +++ b/pype/plugins/nukestudio/publish/integrate_assumed_destination.py @@ -0,0 +1,132 @@ +import pyblish.api +import os + +from avalon import io, api + + +class IntegrateAssumedDestination(pyblish.api.InstancePlugin): + """Generate the assumed destination path where the file will be stored""" + + label = "Integrate Assumed Destination" + order = pyblish.api.IntegratorOrder - 0.05 + families = ["clip", "projectfile"] + + def process(self, instance): + + self.create_destination_template(instance) + + template_data = instance.data["assumedTemplateData"] + # template = instance.data["template"] + + anatomy = instance.context.data['anatomy'] + # template = anatomy.publish.path + anatomy_filled = anatomy.format(template_data) + mock_template = anatomy_filled.publish.path + + # For now assume resources end up in a "resources" folder in the + # published folder + mock_destination = os.path.join(os.path.dirname(mock_template), + "resources") + + # Clean the path + mock_destination = os.path.abspath(os.path.normpath(mock_destination)) + + # Define resource destination and transfers + resources = instance.data.get("resources", list()) + transfers = instance.data.get("transfers", list()) + for resource in resources: + + # Add destination to the resource + source_filename = os.path.basename(resource["source"]) + destination = os.path.join(mock_destination, source_filename) + + # Force forward slashes to fix issue with software unable + # to work correctly with backslashes in specific scenarios + # (e.g. escape characters in PLN-151 V-Ray UDIM) + destination = destination.replace("\\", "/") + + resource['destination'] = destination + + # Collect transfers for the individual files of the resource + # e.g. all individual files of a cache or UDIM textures. + files = resource['files'] + for fsrc in files: + fname = os.path.basename(fsrc) + fdest = os.path.join(mock_destination, fname) + transfers.append([fsrc, fdest]) + + instance.data["resources"] = resources + instance.data["transfers"] = transfers + + def create_destination_template(self, instance): + """Create a filepath based on the current data available + + Example template: + {root}/{project}/{silo}/{asset}/publish/{subset}/v{version:0>3}/ + {subset}.{representation} + Args: + instance: the instance to publish + + Returns: + file path (str) + """ + + # get all the stuff from the database + subset_name = instance.data["subset"] + self.log.info(subset_name) + asset_name = instance.data["asset"] + project_name = api.Session["AVALON_PROJECT"] + + project = io.find_one({"type": "project", + "name": project_name}, + projection={"config": True, "data": True}) + + template = project["config"]["template"]["publish"] + # anatomy = instance.context.data['anatomy'] + + asset = io.find_one({"type": "asset", + "name": asset_name, + "parent": project["_id"]}) + + assert asset, ("No asset found by the name '{}' " + "in project '{}'".format(asset_name, project_name)) + silo = asset['silo'] + + subset = io.find_one({"type": "subset", + "name": subset_name, + "parent": asset["_id"]}) + + # assume there is no version yet, we start at `1` + version = None + version_number = 1 + if subset is not None: + version = io.find_one({"type": "version", + "parent": subset["_id"]}, + sort=[("name", -1)]) + + # if there is a subset there ought to be version + if version is not None: + version_number += version["name"] + + if instance.data.get('version'): + version_number = int(instance.data.get('version')) + + hierarchy = asset['data']['parents'] + if hierarchy: + # hierarchy = os.path.sep.join(hierarchy) + hierarchy = os.path.join(*hierarchy) + + template_data = {"root": api.Session["AVALON_PROJECTS"], + "project": {"name": project_name, + "code": project['data']['code']}, + "silo": silo, + "family": instance.data['family'], + "asset": asset_name, + "subset": subset_name, + "version": version_number, + "hierarchy": hierarchy, + "representation": "TEMP"} + + instance.data["assumedTemplateData"] = template_data + self.log.info(template_data) + instance.data["template"] = template diff --git a/pype/plugins/nukestudio/publish/integrate_ftrack_component_overwrite.py b/pype/plugins/nukestudio/publish/integrate_ftrack_component_overwrite.py new file mode 100644 index 0000000000..047fd8462c --- /dev/null +++ b/pype/plugins/nukestudio/publish/integrate_ftrack_component_overwrite.py @@ -0,0 +1,21 @@ +import pyblish.api + + +class IntegrateFtrackComponentOverwrite(pyblish.api.InstancePlugin): + """ + Set `component_overwrite` to True on all instances `ftrackComponentsList` + """ + + order = pyblish.api.IntegratorOrder + 0.49 + label = 'Overwrite ftrack created versions' + families = ["clip"] + optional = True + active = False + + def process(self, instance): + component_list = instance.data['ftrackComponentsList'] + + for cl in component_list: + cl['component_overwrite'] = True + self.log.debug('Component {} overwriting'.format( + cl['component_data']['name'])) diff --git a/pype/plugins/nukestudio/publish/integrate_hierarchy_avalon.py b/pype/plugins/nukestudio/publish/integrate_hierarchy_avalon.py new file mode 100644 index 0000000000..0f7fdb20d3 --- /dev/null +++ b/pype/plugins/nukestudio/publish/integrate_hierarchy_avalon.py @@ -0,0 +1,140 @@ +import pyblish.api +from avalon import io + + +class IntegrateHierarchyToAvalon(pyblish.api.ContextPlugin): + """ + Create entities in ftrack based on collected data from premiere + + """ + + order = pyblish.api.IntegratorOrder - 0.1 + label = 'Integrate Hierarchy To Avalon' + families = ['clip'] + + def process(self, context): + if "hierarchyContext" not in context.data: + return + + self.db = io + if not self.db.Session: + self.db.install() + + input_data = context.data["hierarchyContext"] + self.import_to_avalon(input_data) + + def import_to_avalon(self, input_data, parent=None): + + for name in input_data: + self.log.info('input_data[name]: {}'.format(input_data[name])) + entity_data = input_data[name] + entity_type = entity_data['entity_type'] + + data = {} + # Process project + if entity_type.lower() == 'project': + entity = self.db.find_one({'type': 'project'}) + # TODO: should be in validator? + assert (entity is not None), "Didn't find project in DB" + + # get data from already existing project + for key, value in entity.get('data', {}).items(): + data[key] = value + + self.av_project = entity + # Raise error if project or parent are not set + elif self.av_project is None or parent is None: + raise AssertionError( + "Collected items are not in right order!" + ) + # Else process assset + else: + entity = self.db.find_one({'type': 'asset', 'name': name}) + # Create entity if doesn't exist + if entity is None: + if self.av_project['_id'] == parent['_id']: + silo = None + elif parent['silo'] is None: + silo = parent['name'] + else: + silo = parent['silo'] + entity = self.create_avalon_asset(name, silo) + self.log.info('entity: {}'.format(entity)) + self.log.info('data: {}'.format(entity.get('data', {}))) + self.log.info('____1____') + data['entityType'] = entity_type + # TASKS + tasks = entity_data.get('tasks', []) + if tasks is not None or len(tasks) > 0: + data['tasks'] = tasks + parents = [] + visualParent = None + data = input_data[name] + if self.av_project['_id'] != parent['_id']: + visualParent = parent['_id'] + parents.extend(parent.get('data', {}).get('parents', [])) + parents.append(parent['name']) + data['visualParent'] = visualParent + data['parents'] = parents + + self.db.update_many( + {'_id': entity['_id']}, + {'$set': { + 'data': data, + }}) + + entity = self.db.find_one({'type': 'asset', 'name': name}) + self.log.info('entity: {}'.format(entity)) + self.log.info('data: {}'.format(entity.get('data', {}))) + self.log.info('____2____') + + # Else get data from already existing + else: + self.log.info('entity: {}'.format(entity)) + self.log.info('data: {}'.format(entity.get('data', {}))) + self.log.info('________') + for key, value in entity.get('data', {}).items(): + data[key] = value + + data['entityType'] = entity_type + # TASKS + tasks = entity_data.get('tasks', []) + if tasks is not None or len(tasks) > 0: + data['tasks'] = tasks + parents = [] + visualParent = None + # do not store project's id as visualParent (silo asset) + + if self.av_project['_id'] != parent['_id']: + visualParent = parent['_id'] + parents.extend(parent.get('data', {}).get('parents', [])) + parents.append(parent['name']) + data['visualParent'] = visualParent + data['parents'] = parents + + # CUSTOM ATTRIBUTES + for k, val in entity_data.get('custom_attributes', {}).items(): + data[k] = val + + # Update entity data with input data + self.db.update_many( + {'_id': entity['_id']}, + {'$set': { + 'data': data, + }}) + + if 'childs' in entity_data: + self.import_to_avalon(entity_data['childs'], entity) + + def create_avalon_asset(self, name, silo): + item = { + 'schema': 'avalon-core:asset-2.0', + 'name': name, + 'silo': silo, + 'parent': self.av_project['_id'], + 'type': 'asset', + 'data': {} + } + entity_id = self.db.insert_one(item).inserted_id + + return self.db.find_one({'_id': entity_id}) diff --git a/pype/plugins/nukestudio/publish/integrate_hierarchy_ftrack.py b/pype/plugins/nukestudio/publish/integrate_hierarchy_ftrack.py new file mode 100644 index 0000000000..d6d03e9722 --- /dev/null +++ b/pype/plugins/nukestudio/publish/integrate_hierarchy_ftrack.py @@ -0,0 +1,155 @@ +import pyblish.api + + +class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin): + """ + Create entities in ftrack based on collected data from premiere + Example of entry data: + { + "ProjectXS": { + "entity_type": "Project", + "custom_attributes": { + "fps": 24,... + }, + "tasks": [ + "Compositing", + "Lighting",... *task must exist as task type in project schema* + ], + "childs": { + "sq01": { + "entity_type": "Sequence", + ... + } + } + } + } + """ + + order = pyblish.api.IntegratorOrder + label = 'Integrate Hierarchy To Ftrack' + families = ["clip"] + optional = False + + def process(self, context): + self.context = context + if "hierarchyContext" not in context.data: + return + + self.ft_project = None + self.session = context.data["ftrackSession"] + + input_data = context.data["hierarchyContext"] + + # adding ftrack types from presets + ftrack_types = context.data['ftrackTypes'] + + self.import_to_ftrack(input_data, ftrack_types) + + def import_to_ftrack(self, input_data, ftrack_types, parent=None): + for entity_name in input_data: + entity_data = input_data[entity_name] + entity_type = entity_data['entity_type'].capitalize() + + if entity_type.lower() == 'project': + query = 'Project where full_name is "{}"'.format(entity_name) + entity = self.session.query(query).one() + self.ft_project = entity + self.task_types = self.get_all_task_types(entity) + + elif self.ft_project is None or parent is None: + raise AssertionError( + "Collected items are not in right order!" + ) + + # try to find if entity already exists + else: + query = '{} where name is "{}" and parent_id is "{}"'.format( + entity_type, entity_name, parent['id'] + ) + try: + entity = self.session.query(query).one() + except Exception: + entity = None + + # Create entity if not exists + if entity is None: + entity = self.create_entity( + name=entity_name, + type=entity_type, + parent=parent + ) + # self.log.info('entity: {}'.format(dict(entity))) + # CUSTOM ATTRIBUTES + custom_attributes = entity_data.get('custom_attributes', []) + instances = [ + i for i in self.context.data["instances"] if i.data['asset'] in entity['name']] + for key in custom_attributes: + assert (key in entity['custom_attributes']), ( + 'Missing custom attribute') + + entity['custom_attributes'][key] = custom_attributes[key] + for instance in instances: + instance.data['ftrackShotId'] = entity['id'] + + self.session.commit() + + # TASKS + tasks = entity_data.get('tasks', []) + existing_tasks = [] + tasks_to_create = [] + for child in entity['children']: + if child.entity_type.lower() == 'task': + existing_tasks.append(child['name']) + # existing_tasks.append(child['type']['name']) + + for task in tasks: + if task in existing_tasks: + print("Task {} already exists".format(task)) + continue + tasks_to_create.append(task) + + for task in tasks_to_create: + self.create_task( + name=task, + task_type=ftrack_types[task], + parent=entity + ) + self.session.commit() + + if 'childs' in entity_data: + self.import_to_ftrack( + entity_data['childs'], ftrack_types, entity) + + def get_all_task_types(self, project): + tasks = {} + proj_template = project['project_schema'] + temp_task_types = proj_template['_task_type_schema']['types'] + + for type in temp_task_types: + if type['name'] not in tasks: + tasks[type['name']] = type + + return tasks + + def create_task(self, name, task_type, parent): + task = self.session.create('Task', { + 'name': name, + 'parent': parent + }) + # TODO not secured!!! - check if task_type exists + self.log.info(task_type) + self.log.info(self.task_types) + task['type'] = self.task_types[task_type] + + self.session.commit() + + return task + + def create_entity(self, name, type, parent): + entity = self.session.create(type, { + 'name': name, + 'parent': parent + }) + self.session.commit() + + return entity diff --git a/pype/plugins/nukestudio/publish/validate_names.py b/pype/plugins/nukestudio/publish/validate_names.py index 169febd764..52382e545d 100644 --- a/pype/plugins/nukestudio/publish/validate_names.py +++ b/pype/plugins/nukestudio/publish/validate_names.py @@ -10,7 +10,7 @@ class ValidateNames(api.InstancePlugin): """ order = api.ValidatorOrder - families = ["trackItem"] + families = ["clip"] match = api.Exact label = "Names" hosts = ["nukestudio"] @@ -39,4 +39,4 @@ class ValidateNamesFtrack(ValidateNames): """ order = api.ValidatorOrder - families = ["trackItem", "ftrack"] + families = ["clip", "ftrack"] diff --git a/pype/plugins/nukestudio/publish/validate_track_item.py b/pype/plugins/nukestudio/publish/validate_track_item.py index 3fe7a739ce..600bf58938 100644 --- a/pype/plugins/nukestudio/publish/validate_track_item.py +++ b/pype/plugins/nukestudio/publish/validate_track_item.py @@ -1,13 +1,13 @@ from pyblish import api -class ValidateTrackItem(api.InstancePlugin): +class ValidateClip(api.InstancePlugin): """Validate the track item to the sequence. Exact matching to optimize processing. """ order = api.ValidatorOrder - families = ["trackItem"] + families = ["clip"] match = api.Exact label = "Validate Track Item" hosts = ["nukestudio"] @@ -44,14 +44,3 @@ class ValidateTrackItem(api.InstancePlugin): assert sequence.framerate() == source_framerate, msg.format( "framerate", source_framerate, sequence.framerate() ) - -# -# class ValidateTrackItemFtrack(ValidateTrackItem): -# """Validate the track item to the sequence. -# -# Because we are matching the families exactly, we need this plugin to -# accommodate for the ftrack family addition. -# """ -# -# order = api.ValidatorOrder -# families = ["trackItem", "ftrack"] diff --git a/setup/nukestudio/hiero_plugin_path/Templates/SharedTags.hrox b/setup/nukestudio/hiero_plugin_path/Templates/SharedTags.hrox index 4045ea3335..128bde5456 100644 --- a/setup/nukestudio/hiero_plugin_path/Templates/SharedTags.hrox +++ b/setup/nukestudio/hiero_plugin_path/Templates/SharedTags.hrox @@ -1,19 +1,19 @@ - - + + - + 2 70 0 0 13 - + - - + + @@ -23,10 +23,10 @@ - + - - + + @@ -37,8 +37,8 @@ - - + + @@ -49,8 +49,8 @@ - - + + @@ -61,8 +61,8 @@ - - + + @@ -73,8 +73,8 @@ - - + + @@ -85,8 +85,8 @@ - - + + @@ -97,8 +97,8 @@ - - + + @@ -109,8 +109,8 @@ - - + + @@ -121,8 +121,8 @@ - - + + @@ -133,8 +133,8 @@ - - + + @@ -145,8 +145,8 @@ - - + + @@ -157,8 +157,8 @@ - - + + @@ -169,8 +169,8 @@ - - + + @@ -181,8 +181,8 @@ - - + + @@ -199,10 +199,10 @@ 0 0 - + - - + + @@ -214,8 +214,8 @@ - - + + @@ -227,8 +227,8 @@ - - + + @@ -240,8 +240,8 @@ - - + + @@ -253,8 +253,8 @@ - - + + @@ -268,8 +268,8 @@ - - + + @@ -283,8 +283,8 @@ - - + + @@ -298,8 +298,8 @@ - - + + @@ -313,8 +313,8 @@ - - + + @@ -328,8 +328,8 @@ - - + + @@ -343,8 +343,8 @@ - - + + @@ -358,8 +358,8 @@ - - + + @@ -373,8 +373,8 @@ - - + + @@ -392,47 +392,51 @@ 0 0 - + - - + + + - - + + + - - + + + - - + + + @@ -457,9 +461,9 @@ 0 0 2 - - - + + +