diff --git a/openpype/plugins/publish/collect_frame_range_asset_entity.py b/openpype/plugins/publish/collect_frame_range_asset_entity.py new file mode 100644 index 0000000000..ce744e2daf --- /dev/null +++ b/openpype/plugins/publish/collect_frame_range_asset_entity.py @@ -0,0 +1,42 @@ +import pyblish.api +from openpype.pipeline import OptionalPyblishPluginMixin + + +class CollectFrameDataFromAssetEntity(pyblish.api.InstancePlugin, + OptionalPyblishPluginMixin): + """Collect Frame Range data From Asset Entity + + Frame range data will only be collected if the keys + are not yet collected for the instance. + """ + + order = pyblish.api.CollectorOrder + 0.3 + label = "Collect Frame Data From Asset Entity" + families = ["plate", "pointcache", + "vdbcache", "online", + "render"] + hosts = ["traypublisher"] + optional = True + + def process(self, instance): + if not self.is_active(instance.data): + return + missing_keys = [] + for key in ( + "fps", + "frameStart", + "frameEnd", + "handleStart", + "handleEnd" + ): + if key not in instance.data: + missing_keys.append(key) + keys_set = [] + for key in missing_keys: + asset_data = instance.data["assetEntity"]["data"] + if key in asset_data: + instance.data[key] = asset_data[key] + keys_set.append(key) + if keys_set: + self.log.debug(f"Frame range data {keys_set} " + "has been collected from asset entity.") diff --git a/openpype/plugins/publish/collect_sequence_frame_data.py b/openpype/plugins/publish/collect_sequence_frame_data.py new file mode 100644 index 0000000000..c200b245e9 --- /dev/null +++ b/openpype/plugins/publish/collect_sequence_frame_data.py @@ -0,0 +1,53 @@ +import pyblish.api +import clique + + +class CollectSequenceFrameData(pyblish.api.InstancePlugin): + """Collect Sequence Frame Data + If the representation includes files with frame numbers, + then set `frameStart` and `frameEnd` for the instance to the + start and end frame respectively + """ + + order = pyblish.api.CollectorOrder + 0.2 + label = "Collect Sequence Frame Data" + families = ["plate", "pointcache", + "vdbcache", "online", + "render"] + hosts = ["traypublisher"] + + def process(self, instance): + frame_data = self.get_frame_data_from_repre_sequence(instance) + if not frame_data: + # if no dict data skip collecting the frame range data + return + for key, value in frame_data.items(): + if key not in instance.data: + instance.data[key] = value + self.log.debug(f"Collected Frame range data '{key}':{value} ") + + def get_frame_data_from_repre_sequence(self, instance): + repres = instance.data.get("representations") + if repres: + first_repre = repres[0] + if "ext" not in first_repre: + self.log.warning("Cannot find file extension" + " in representation data") + return + + files = first_repre["files"] + collections, remainder = clique.assemble(files) + if not collections: + # No sequences detected and we can't retrieve + # frame range + self.log.debug( + "No sequences detected in the representation data." + " Skipping collecting frame range data.") + return + collection = collections[0] + repres_frames = list(collection.indexes) + + return { + "frameStart": repres_frames[0], + "frameEnd": repres_frames[-1], + } diff --git a/openpype/settings/defaults/project_settings/traypublisher.json b/openpype/settings/defaults/project_settings/traypublisher.json index 4c2c2f1391..dda958ebcd 100644 --- a/openpype/settings/defaults/project_settings/traypublisher.json +++ b/openpype/settings/defaults/project_settings/traypublisher.json @@ -329,6 +329,11 @@ } }, "publish": { + "CollectFrameDataFromAssetEntity": { + "enabled": true, + "optional": true, + "active": true + }, "ValidateFrameRange": { "enabled": true, "optional": true, diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json b/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json index e75e2887db..184fc657be 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json @@ -349,6 +349,10 @@ "type": "schema_template", "name": "template_validate_plugin", "template_data": [ + { + "key": "CollectFrameDataFromAssetEntity", + "label": "Collect frame range from asset entity" + }, { "key": "ValidateFrameRange", "label": "Validate frame range"