mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 08:24:53 +01:00
Merge branch 'develop' into enhancement/AY-7584_Library-Push-to-Current-project
This commit is contained in:
commit
138c9fb987
24 changed files with 116 additions and 28 deletions
|
|
@ -33,6 +33,7 @@ class AddLastWorkfileToLaunchArgs(PreLaunchHook):
|
||||||
"cinema4d",
|
"cinema4d",
|
||||||
"silhouette",
|
"silhouette",
|
||||||
"gaffer",
|
"gaffer",
|
||||||
|
"loki",
|
||||||
}
|
}
|
||||||
launch_types = {LaunchTypes.local}
|
launch_types = {LaunchTypes.local}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ class OCIOEnvHook(PreLaunchHook):
|
||||||
"cinema4d",
|
"cinema4d",
|
||||||
"silhouette",
|
"silhouette",
|
||||||
"gaffer",
|
"gaffer",
|
||||||
|
"loki",
|
||||||
}
|
}
|
||||||
launch_types = set()
|
launch_types = set()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@ import opentimelineio as otio
|
||||||
from opentimelineio import opentime as _ot
|
from opentimelineio import opentime as _ot
|
||||||
|
|
||||||
|
|
||||||
|
# https://github.com/AcademySoftwareFoundation/OpenTimelineIO/issues/1822
|
||||||
|
OTIO_EPSILON = 1e-9
|
||||||
|
|
||||||
|
|
||||||
def otio_range_to_frame_range(otio_range):
|
def otio_range_to_frame_range(otio_range):
|
||||||
start = _ot.to_frames(
|
start = _ot.to_frames(
|
||||||
otio_range.start_time, otio_range.start_time.rate)
|
otio_range.start_time, otio_range.start_time.rate)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import sys
|
||||||
import inspect
|
import inspect
|
||||||
import copy
|
import copy
|
||||||
import warnings
|
import warnings
|
||||||
|
import hashlib
|
||||||
import xml.etree.ElementTree
|
import xml.etree.ElementTree
|
||||||
from typing import TYPE_CHECKING, Optional, Union, List
|
from typing import TYPE_CHECKING, Optional, Union, List
|
||||||
|
|
||||||
|
|
@ -243,32 +244,38 @@ def publish_plugins_discover(
|
||||||
|
|
||||||
for path in paths:
|
for path in paths:
|
||||||
path = os.path.normpath(path)
|
path = os.path.normpath(path)
|
||||||
if not os.path.isdir(path):
|
filenames = []
|
||||||
continue
|
if os.path.isdir(path):
|
||||||
|
filenames.extend(
|
||||||
|
name
|
||||||
|
for name in os.listdir(path)
|
||||||
|
if (
|
||||||
|
os.path.isfile(os.path.join(path, name))
|
||||||
|
and not name.startswith("_")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
filenames.append(os.path.basename(path))
|
||||||
|
path = os.path.dirname(path)
|
||||||
|
|
||||||
for fname in os.listdir(path):
|
dirpath_hash = hashlib.md5(path.encode("utf-8")).hexdigest()
|
||||||
if fname.startswith("_"):
|
for filename in filenames:
|
||||||
continue
|
basename, ext = os.path.splitext(filename)
|
||||||
|
if ext.lower() != ".py":
|
||||||
abspath = os.path.join(path, fname)
|
|
||||||
|
|
||||||
if not os.path.isfile(abspath):
|
|
||||||
continue
|
|
||||||
|
|
||||||
mod_name, mod_ext = os.path.splitext(fname)
|
|
||||||
|
|
||||||
if mod_ext != ".py":
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
filepath = os.path.join(path, filename)
|
||||||
|
module_name = f"{dirpath_hash}.{basename}"
|
||||||
try:
|
try:
|
||||||
module = import_filepath(
|
module = import_filepath(
|
||||||
abspath, mod_name, sys_module_name=mod_name)
|
filepath, module_name, sys_module_name=module_name
|
||||||
|
)
|
||||||
|
|
||||||
except Exception as err: # noqa: BLE001
|
except Exception as err: # noqa: BLE001
|
||||||
# we need broad exception to catch all possible errors.
|
# we need broad exception to catch all possible errors.
|
||||||
result.crashed_file_paths[abspath] = sys.exc_info()
|
result.crashed_file_paths[filepath] = sys.exc_info()
|
||||||
|
|
||||||
log.debug('Skipped: "%s" (%s)', mod_name, err)
|
log.debug('Skipped: "%s" (%s)', filepath, err)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for plugin in pyblish.plugin.plugins_from_module(module):
|
for plugin in pyblish.plugin.plugins_from_module(module):
|
||||||
|
|
@ -354,12 +361,18 @@ def get_plugin_settings(plugin, project_settings, log, category=None):
|
||||||
# Use project settings based on a category name
|
# Use project settings based on a category name
|
||||||
if category:
|
if category:
|
||||||
try:
|
try:
|
||||||
return (
|
output = (
|
||||||
project_settings
|
project_settings
|
||||||
[category]
|
[category]
|
||||||
["publish"]
|
["publish"]
|
||||||
[plugin.__name__]
|
[plugin.__name__]
|
||||||
)
|
)
|
||||||
|
warnings.warn(
|
||||||
|
"Please fill 'settings_category'"
|
||||||
|
f" for plugin '{plugin.__name__}'.",
|
||||||
|
DeprecationWarning
|
||||||
|
)
|
||||||
|
return output
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -384,12 +397,18 @@ def get_plugin_settings(plugin, project_settings, log, category=None):
|
||||||
category_from_file = "core"
|
category_from_file = "core"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return (
|
output = (
|
||||||
project_settings
|
project_settings
|
||||||
[category_from_file]
|
[category_from_file]
|
||||||
[plugin_kind]
|
[plugin_kind]
|
||||||
[plugin.__name__]
|
[plugin.__name__]
|
||||||
)
|
)
|
||||||
|
warnings.warn(
|
||||||
|
"Please fill 'settings_category'"
|
||||||
|
f" for plugin '{plugin.__name__}'.",
|
||||||
|
DeprecationWarning
|
||||||
|
)
|
||||||
|
return output
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
return {}
|
return {}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@ class CleanUp(pyblish.api.InstancePlugin):
|
||||||
"webpublisher",
|
"webpublisher",
|
||||||
"shell"
|
"shell"
|
||||||
]
|
]
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
exclude_families = ["clip"]
|
exclude_families = ["clip"]
|
||||||
optional = True
|
optional = True
|
||||||
active = True
|
active = True
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ class CleanUpFarm(pyblish.api.ContextPlugin):
|
||||||
|
|
||||||
order = pyblish.api.IntegratorOrder + 11
|
order = pyblish.api.IntegratorOrder + 11
|
||||||
label = "Clean Up Farm"
|
label = "Clean Up Farm"
|
||||||
|
|
||||||
|
settings_category = "core"
|
||||||
enabled = True
|
enabled = True
|
||||||
|
|
||||||
# Keep "filesequence" for backwards compatibility of older jobs
|
# Keep "filesequence" for backwards compatibility of older jobs
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin):
|
||||||
order = pyblish.api.CollectorOrder + 0.49
|
order = pyblish.api.CollectorOrder + 0.49
|
||||||
label = "Collect Anatomy Instance data"
|
label = "Collect Anatomy Instance data"
|
||||||
|
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
follow_workfile_version = False
|
follow_workfile_version = False
|
||||||
|
|
||||||
def process(self, context):
|
def process(self, context):
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ class CollectAudio(pyblish.api.ContextPlugin):
|
||||||
"max",
|
"max",
|
||||||
"circuit",
|
"circuit",
|
||||||
]
|
]
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
audio_product_name = "audioMain"
|
audio_product_name = "audioMain"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ class CollectFramesFixDef(
|
||||||
targets = ["local"]
|
targets = ["local"]
|
||||||
hosts = ["nuke"]
|
hosts = ["nuke"]
|
||||||
families = ["render", "prerender"]
|
families = ["render", "prerender"]
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
rewrite_version_enable = False
|
rewrite_version_enable = False
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,10 @@ class CollectSceneVersion(pyblish.api.ContextPlugin):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
order = pyblish.api.CollectorOrder
|
order = pyblish.api.CollectorOrder
|
||||||
label = 'Collect Scene Version'
|
label = "Collect Scene Version"
|
||||||
# configurable in Settings
|
# configurable in Settings
|
||||||
hosts = ["*"]
|
hosts = ["*"]
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
# in some cases of headless publishing (for example webpublisher using PS)
|
# in some cases of headless publishing (for example webpublisher using PS)
|
||||||
# you want to ignore version from name and let integrate use next version
|
# you want to ignore version from name and let integrate use next version
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ class ExtractBurnin(publish.Extractor):
|
||||||
"unreal",
|
"unreal",
|
||||||
"circuit",
|
"circuit",
|
||||||
]
|
]
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
optional = True
|
optional = True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ class ExtractOIIOTranscode(publish.Extractor):
|
||||||
label = "Transcode color spaces"
|
label = "Transcode color spaces"
|
||||||
order = pyblish.api.ExtractorOrder + 0.019
|
order = pyblish.api.ExtractorOrder + 0.019
|
||||||
|
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
optional = True
|
optional = True
|
||||||
|
|
||||||
# Supported extensions
|
# Supported extensions
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ from ayon_core.lib import (
|
||||||
get_ffmpeg_tool_args,
|
get_ffmpeg_tool_args,
|
||||||
run_subprocess
|
run_subprocess
|
||||||
)
|
)
|
||||||
|
from ayon_core.pipeline import editorial
|
||||||
|
|
||||||
|
|
||||||
class ExtractOtioAudioTracks(pyblish.api.ContextPlugin):
|
class ExtractOtioAudioTracks(pyblish.api.ContextPlugin):
|
||||||
|
|
@ -172,6 +173,14 @@ class ExtractOtioAudioTracks(pyblish.api.ContextPlugin):
|
||||||
clip_start = otio_clip.source_range.start_time
|
clip_start = otio_clip.source_range.start_time
|
||||||
fps = clip_start.rate
|
fps = clip_start.rate
|
||||||
conformed_av_start = media_av_start.rescaled_to(fps)
|
conformed_av_start = media_av_start.rescaled_to(fps)
|
||||||
|
|
||||||
|
# Avoid rounding issue on media available range.
|
||||||
|
if clip_start.almost_equal(
|
||||||
|
conformed_av_start,
|
||||||
|
editorial.OTIO_EPSILON
|
||||||
|
):
|
||||||
|
conformed_av_start = clip_start
|
||||||
|
|
||||||
# ffmpeg ignores embedded tc
|
# ffmpeg ignores embedded tc
|
||||||
start = clip_start - conformed_av_start
|
start = clip_start - conformed_av_start
|
||||||
duration = otio_clip.source_range.duration
|
duration = otio_clip.source_range.duration
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,11 @@ from ayon_core.lib import (
|
||||||
get_ffmpeg_tool_args,
|
get_ffmpeg_tool_args,
|
||||||
run_subprocess,
|
run_subprocess,
|
||||||
)
|
)
|
||||||
from ayon_core.pipeline import publish
|
from ayon_core.pipeline import (
|
||||||
|
KnownPublishError,
|
||||||
|
editorial,
|
||||||
|
publish,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ExtractOTIOReview(
|
class ExtractOTIOReview(
|
||||||
|
|
@ -97,8 +101,11 @@ class ExtractOTIOReview(
|
||||||
|
|
||||||
# skip instance if no reviewable data available
|
# skip instance if no reviewable data available
|
||||||
if (
|
if (
|
||||||
not isinstance(otio_review_clips[0], otio.schema.Clip)
|
len(otio_review_clips) == 1
|
||||||
and len(otio_review_clips) == 1
|
and (
|
||||||
|
not isinstance(otio_review_clips[0], otio.schema.Clip)
|
||||||
|
or otio_review_clips[0].media_reference.is_missing_reference
|
||||||
|
)
|
||||||
):
|
):
|
||||||
self.log.warning(
|
self.log.warning(
|
||||||
"Instance `{}` has nothing to process".format(instance))
|
"Instance `{}` has nothing to process".format(instance))
|
||||||
|
|
@ -248,7 +255,7 @@ class ExtractOTIOReview(
|
||||||
|
|
||||||
# Single video way.
|
# Single video way.
|
||||||
# Extraction via FFmpeg.
|
# Extraction via FFmpeg.
|
||||||
else:
|
elif hasattr(media_ref, "target_url"):
|
||||||
path = media_ref.target_url
|
path = media_ref.target_url
|
||||||
# Set extract range from 0 (FFmpeg ignores
|
# Set extract range from 0 (FFmpeg ignores
|
||||||
# embedded timecode).
|
# embedded timecode).
|
||||||
|
|
@ -370,6 +377,13 @@ class ExtractOTIOReview(
|
||||||
|
|
||||||
avl_start = avl_range.start_time
|
avl_start = avl_range.start_time
|
||||||
|
|
||||||
|
# Avoid rounding issue on media available range.
|
||||||
|
if start.almost_equal(
|
||||||
|
avl_start,
|
||||||
|
editorial.OTIO_EPSILON
|
||||||
|
):
|
||||||
|
avl_start = start
|
||||||
|
|
||||||
# An additional gap is required before the available
|
# An additional gap is required before the available
|
||||||
# range to conform source start point and head handles.
|
# range to conform source start point and head handles.
|
||||||
if start < avl_start:
|
if start < avl_start:
|
||||||
|
|
@ -388,6 +402,14 @@ class ExtractOTIOReview(
|
||||||
# (media duration is shorter then clip requirement).
|
# (media duration is shorter then clip requirement).
|
||||||
end_point = start + duration
|
end_point = start + duration
|
||||||
avl_end_point = avl_range.end_time_exclusive()
|
avl_end_point = avl_range.end_time_exclusive()
|
||||||
|
|
||||||
|
# Avoid rounding issue on media available range.
|
||||||
|
if end_point.almost_equal(
|
||||||
|
avl_end_point,
|
||||||
|
editorial.OTIO_EPSILON
|
||||||
|
):
|
||||||
|
avl_end_point = end_point
|
||||||
|
|
||||||
if end_point > avl_end_point:
|
if end_point > avl_end_point:
|
||||||
gap_duration = end_point - avl_end_point
|
gap_duration = end_point - avl_end_point
|
||||||
duration -= gap_duration
|
duration -= gap_duration
|
||||||
|
|
@ -444,7 +466,7 @@ class ExtractOTIOReview(
|
||||||
command = get_ffmpeg_tool_args("ffmpeg")
|
command = get_ffmpeg_tool_args("ffmpeg")
|
||||||
|
|
||||||
input_extension = None
|
input_extension = None
|
||||||
if sequence:
|
if sequence is not None:
|
||||||
input_dir, collection, sequence_fps = sequence
|
input_dir, collection, sequence_fps = sequence
|
||||||
in_frame_start = min(collection.indexes)
|
in_frame_start = min(collection.indexes)
|
||||||
|
|
||||||
|
|
@ -478,7 +500,7 @@ class ExtractOTIOReview(
|
||||||
"-i", input_path
|
"-i", input_path
|
||||||
])
|
])
|
||||||
|
|
||||||
elif video:
|
elif video is not None:
|
||||||
video_path, otio_range = video
|
video_path, otio_range = video
|
||||||
frame_start = otio_range.start_time.value
|
frame_start = otio_range.start_time.value
|
||||||
input_fps = otio_range.start_time.rate
|
input_fps = otio_range.start_time.rate
|
||||||
|
|
@ -496,7 +518,7 @@ class ExtractOTIOReview(
|
||||||
"-i", video_path
|
"-i", video_path
|
||||||
])
|
])
|
||||||
|
|
||||||
elif gap:
|
elif gap is not None:
|
||||||
sec_duration = frames_to_seconds(gap, self.actual_fps)
|
sec_duration = frames_to_seconds(gap, self.actual_fps)
|
||||||
|
|
||||||
# form command for rendering gap files
|
# form command for rendering gap files
|
||||||
|
|
@ -510,6 +532,9 @@ class ExtractOTIOReview(
|
||||||
"-tune", "stillimage"
|
"-tune", "stillimage"
|
||||||
])
|
])
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise KnownPublishError("Sequence, video or gap is required.")
|
||||||
|
|
||||||
if video or sequence:
|
if video or sequence:
|
||||||
command.extend([
|
command.extend([
|
||||||
"-vf", f"scale={self.to_width}:{self.to_height}:flags=lanczos",
|
"-vf", f"scale={self.to_width}:{self.to_height}:flags=lanczos",
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,7 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
||||||
"photoshop"
|
"photoshop"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
settings_category = "core"
|
||||||
# Supported extensions
|
# Supported extensions
|
||||||
image_exts = {"exr", "jpg", "jpeg", "png", "dpx", "tga", "tiff", "tif"}
|
image_exts = {"exr", "jpg", "jpeg", "png", "dpx", "tga", "tiff", "tif"}
|
||||||
video_exts = {"mov", "mp4"}
|
video_exts = {"mov", "mp4"}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ class ExtractThumbnail(pyblish.api.InstancePlugin):
|
||||||
"houdini",
|
"houdini",
|
||||||
"circuit",
|
"circuit",
|
||||||
]
|
]
|
||||||
|
settings_category = "core"
|
||||||
enabled = False
|
enabled = False
|
||||||
|
|
||||||
integrate_thumbnail = False
|
integrate_thumbnail = False
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,7 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
|
||||||
label = "Collect USD Layer Contributions (Asset/Shot)"
|
label = "Collect USD Layer Contributions (Asset/Shot)"
|
||||||
families = ["usd"]
|
families = ["usd"]
|
||||||
enabled = True
|
enabled = True
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
# A contribution defines a contribution into a (department) layer which
|
# A contribution defines a contribution into a (department) layer which
|
||||||
# will get layered into the target product, usually the asset or shot.
|
# will get layered into the target product, usually the asset or shot.
|
||||||
|
|
@ -633,6 +634,8 @@ class ExtractUSDLayerContribution(publish.Extractor):
|
||||||
label = "Extract USD Layer Contributions (Asset/Shot)"
|
label = "Extract USD Layer Contributions (Asset/Shot)"
|
||||||
order = pyblish.api.ExtractorOrder + 0.45
|
order = pyblish.api.ExtractorOrder + 0.45
|
||||||
|
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
use_ayon_entity_uri = False
|
use_ayon_entity_uri = False
|
||||||
|
|
||||||
def process(self, instance):
|
def process(self, instance):
|
||||||
|
|
@ -795,6 +798,8 @@ class ExtractUSDAssetContribution(publish.Extractor):
|
||||||
label = "Extract USD Asset/Shot Contributions"
|
label = "Extract USD Asset/Shot Contributions"
|
||||||
order = ExtractUSDLayerContribution.order + 0.01
|
order = ExtractUSDLayerContribution.order + 0.01
|
||||||
|
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
use_ayon_entity_uri = False
|
use_ayon_entity_uri = False
|
||||||
|
|
||||||
def process(self, instance):
|
def process(self, instance):
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,8 @@ class IntegrateHeroVersion(
|
||||||
# Must happen after IntegrateNew
|
# Must happen after IntegrateNew
|
||||||
order = pyblish.api.IntegratorOrder + 0.1
|
order = pyblish.api.IntegratorOrder + 0.1
|
||||||
|
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
optional = True
|
optional = True
|
||||||
active = True
|
active = True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ class IntegrateProductGroup(pyblish.api.InstancePlugin):
|
||||||
order = pyblish.api.IntegratorOrder - 0.1
|
order = pyblish.api.IntegratorOrder - 0.1
|
||||||
label = "Product Group"
|
label = "Product Group"
|
||||||
|
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
# Attributes set by settings
|
# Attributes set by settings
|
||||||
product_grouping_profiles = None
|
product_grouping_profiles = None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ class PreIntegrateThumbnails(pyblish.api.InstancePlugin):
|
||||||
label = "Override Integrate Thumbnail Representations"
|
label = "Override Integrate Thumbnail Representations"
|
||||||
order = pyblish.api.IntegratorOrder - 0.1
|
order = pyblish.api.IntegratorOrder - 0.1
|
||||||
|
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
integrate_profiles = []
|
integrate_profiles = []
|
||||||
|
|
||||||
def process(self, instance):
|
def process(self, instance):
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ class ValidateOutdatedContainers(
|
||||||
|
|
||||||
label = "Validate Outdated Containers"
|
label = "Validate Outdated Containers"
|
||||||
order = pyblish.api.ValidatorOrder
|
order = pyblish.api.ValidatorOrder
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
optional = True
|
optional = True
|
||||||
actions = [ShowInventory]
|
actions = [ShowInventory]
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ class ValidateCurrentSaveFile(pyblish.api.ContextPlugin):
|
||||||
label = "Validate File Saved"
|
label = "Validate File Saved"
|
||||||
order = pyblish.api.ValidatorOrder - 0.1
|
order = pyblish.api.ValidatorOrder - 0.1
|
||||||
hosts = ["fusion", "houdini", "max", "maya", "nuke", "substancepainter",
|
hosts = ["fusion", "houdini", "max", "maya", "nuke", "substancepainter",
|
||||||
"cinema4d", "silhouette", "gaffer", "blender"]
|
"cinema4d", "silhouette", "gaffer", "blender", "loki"]
|
||||||
actions = [SaveByVersionUpAction, ShowWorkfilesAction]
|
actions = [SaveByVersionUpAction, ShowWorkfilesAction]
|
||||||
|
|
||||||
def process(self, context):
|
def process(self, context):
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ class ValidateIntent(pyblish.api.ContextPlugin):
|
||||||
order = pyblish.api.ValidatorOrder
|
order = pyblish.api.ValidatorOrder
|
||||||
|
|
||||||
label = "Validate Intent"
|
label = "Validate Intent"
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
enabled = False
|
enabled = False
|
||||||
|
|
||||||
# Can be modified by settings
|
# Can be modified by settings
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ class ValidateVersion(pyblish.api.InstancePlugin, OptionalPyblishPluginMixin):
|
||||||
order = pyblish.api.ValidatorOrder
|
order = pyblish.api.ValidatorOrder
|
||||||
|
|
||||||
label = "Validate Version"
|
label = "Validate Version"
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
optional = False
|
optional = False
|
||||||
active = True
|
active = True
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue