mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-27 06:12:19 +01:00
Merge pull request #3 from aardschok/fusion_integration
Fusion integration
This commit is contained in:
commit
ad9ce2fb0d
25 changed files with 765 additions and 34 deletions
|
|
@ -36,15 +36,6 @@ class CollectInstances(pyblish.api.ContextPlugin):
|
|||
|
||||
from avalon.fusion.lib import get_frame_path
|
||||
|
||||
# Change family when submitting to Deadline
|
||||
targets = pyblish.api.registered_targets()
|
||||
if "deadline" in targets:
|
||||
# Submit to Deadline
|
||||
family = "fusion.deadline"
|
||||
else:
|
||||
# Render local
|
||||
family = "fusion.local"
|
||||
|
||||
comp = context.data["currentComp"]
|
||||
|
||||
# Get all savers in the comp
|
||||
|
|
@ -85,8 +76,8 @@ class CollectInstances(pyblish.api.ContextPlugin):
|
|||
"outputDir": os.path.dirname(path),
|
||||
"ext": ext, # todo: should be redundant
|
||||
"label": label,
|
||||
"families": [family],
|
||||
"family": family,
|
||||
"families": ["colorbleed.saver"],
|
||||
"family": "colorbleed.saver",
|
||||
"active": active,
|
||||
"publish": active # backwards compatibility
|
||||
})
|
||||
|
|
|
|||
44
colorbleed/plugins/fusion/publish/collect_render_target.py
Normal file
44
colorbleed/plugins/fusion/publish/collect_render_target.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import pyblish.api
|
||||
|
||||
|
||||
class CollectFusionRenderMode(pyblish.api.InstancePlugin):
|
||||
"""Collect current comp's render Mode
|
||||
|
||||
Options:
|
||||
renderlocal
|
||||
deadline
|
||||
|
||||
Note that this value is set for each comp separately. When you save the
|
||||
comp this information will be stored in that file. If for some reason the
|
||||
available tool does not visualize which render mode is set for the
|
||||
current comp, please run the following line in the console (Py2)
|
||||
|
||||
comp.GetData("colorbleed.rendermode")
|
||||
|
||||
This will return the name of the current render mode as seen above under
|
||||
Options.
|
||||
|
||||
"""
|
||||
|
||||
order = pyblish.api.CollectorOrder + 0.4
|
||||
label = "Collect Render Mode"
|
||||
hosts = ["fusion"]
|
||||
families = ["colorbleed.saver"]
|
||||
|
||||
def process(self, instance):
|
||||
"""Collect all image sequence tools"""
|
||||
options = ["renderlocal", "deadline"]
|
||||
|
||||
comp = instance.context.data.get("currentComp")
|
||||
if not comp:
|
||||
raise RuntimeError("No comp previously collected, unable to "
|
||||
"retrieve Fusion version.")
|
||||
|
||||
rendermode = comp.GetData("colorbleed.rendermode") or "renderlocal"
|
||||
assert rendermode in options, "Must be supported render mode"
|
||||
|
||||
self.log.info("Render mode: {0}".format(rendermode))
|
||||
|
||||
# Append family
|
||||
family = "colorbleed.saver.{0}".format(rendermode)
|
||||
instance.data["families"].append(family)
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
import pyblish.api
|
||||
|
||||
import avalon.fusion as fusion
|
||||
|
||||
class ExtractImageSequence(pyblish.api.Extractor):
|
||||
|
||||
class ExtractImageSequence(pyblish.api.InstancePlugin):
|
||||
"""Extract result of saver by starting a comp render
|
||||
|
||||
This will run the local render of Fusion.
|
||||
|
|
@ -11,9 +13,18 @@ class ExtractImageSequence(pyblish.api.Extractor):
|
|||
order = pyblish.api.ExtractorOrder
|
||||
label = "Render Local"
|
||||
hosts = ["fusion"]
|
||||
targets = ["renderlocal"]
|
||||
families = ["colorbleed.saver.renderlocal"]
|
||||
|
||||
def process(self, context):
|
||||
def process(self, instance):
|
||||
|
||||
# This should be a ContextPlugin, but this is a workaround
|
||||
# for a bug in pyblish to run once for a family: issue #250
|
||||
context = instance.context
|
||||
key = "__hasRun{}".format(self.__class__.__name__)
|
||||
if context.data.get(key, False):
|
||||
return
|
||||
else:
|
||||
context.data[key] = True
|
||||
|
||||
current_comp = context.data["currentComp"]
|
||||
start_frame = current_comp.GetAttrs("COMPN_RenderStart")
|
||||
|
|
@ -23,6 +34,8 @@ class ExtractImageSequence(pyblish.api.Extractor):
|
|||
self.log.info("Start frame: {}".format(start_frame))
|
||||
self.log.info("End frame: {}".format(end_frame))
|
||||
|
||||
result = current_comp.Render()
|
||||
with fusion.comp_lock_and_undo_chunk(current_comp):
|
||||
result = current_comp.Render()
|
||||
|
||||
if not result:
|
||||
raise RuntimeError("Comp render failed")
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class FusionIncrementCurrentFile(pyblish.api.ContextPlugin):
|
|||
label = "Increment current file"
|
||||
order = pyblish.api.IntegratorOrder + 9.0
|
||||
hosts = ["fusion"]
|
||||
families = ["colorbleed.saver"]
|
||||
families = ["colorbleed.saver.deadline"]
|
||||
optional = True
|
||||
|
||||
def process(self, context):
|
||||
|
|
|
|||
|
|
@ -24,14 +24,13 @@ def _get_script():
|
|||
return module_path
|
||||
|
||||
|
||||
class PublishImageSequence(pyblish.api.Extractor):
|
||||
class PublishImageSequence(pyblish.api.Integrator):
|
||||
"""Publish the generated local image sequences."""
|
||||
|
||||
order = pyblish.api.ExtractorOrder + 0.1
|
||||
order = pyblish.api.IntegratorOrder
|
||||
label = "Publish Rendered Image Sequence(s)"
|
||||
hosts = ["fusion"]
|
||||
targets = ["renderlocal"]
|
||||
families = ["fusion.local"]
|
||||
families = ["colorbleed.saver.renderlocal"]
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ class FusionSaveComp(pyblish.api.ContextPlugin):
|
|||
"""Save current comp"""
|
||||
|
||||
label = "Save current file"
|
||||
order = pyblish.api.IntegratorOrder - 0.49
|
||||
order = pyblish.api.ExtractorOrder - 0.49
|
||||
hosts = ["fusion"]
|
||||
families = ["colorbleed.saver"]
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from avalon.vendor import requests
|
|||
import pyblish.api
|
||||
|
||||
|
||||
class FusionSubmitDeadline(pyblish.api.ContextPlugin):
|
||||
class FusionSubmitDeadline(pyblish.api.InstancePlugin):
|
||||
"""Submit current Comp to Deadline
|
||||
|
||||
Renders are submitted to a Deadline Web Service as
|
||||
|
|
@ -19,10 +19,17 @@ class FusionSubmitDeadline(pyblish.api.ContextPlugin):
|
|||
label = "Submit to Deadline"
|
||||
order = pyblish.api.IntegratorOrder
|
||||
hosts = ["fusion"]
|
||||
families = ["fusion.deadline"]
|
||||
targets = ["deadline"]
|
||||
families = ["colorbleed.saver.deadline"]
|
||||
|
||||
def process(self, context):
|
||||
def process(self, instance):
|
||||
|
||||
context = instance.context
|
||||
|
||||
key = "__hasRun{}".format(self.__class__.__name__)
|
||||
if context.data.get(key, False):
|
||||
return
|
||||
else:
|
||||
context.data[key] = True
|
||||
|
||||
from avalon.fusion.lib import get_frame_path
|
||||
|
||||
|
|
@ -33,16 +40,19 @@ class FusionSubmitDeadline(pyblish.api.ContextPlugin):
|
|||
# Collect all saver instances in context that are to be rendered
|
||||
saver_instances = []
|
||||
for instance in context[:]:
|
||||
if instance.data.get("families")[0] != "fusion.deadline":
|
||||
if not self.families[0] in instance.data.get("families"):
|
||||
# Allow only saver family instances
|
||||
continue
|
||||
|
||||
if not instance.data.get("publish", True):
|
||||
# Skip inactive instances
|
||||
continue
|
||||
|
||||
self.log.debug(instance.data["name"])
|
||||
saver_instances.append(instance)
|
||||
|
||||
if not saver_instances:
|
||||
raise RuntimeError("No instances found for Deadline submittion")
|
||||
|
||||
fusion_version = int(context.data["fusionVersion"])
|
||||
filepath = context.data["currentFile"]
|
||||
filename = os.path.basename(filepath)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class ValidateBackgroundDepth(pyblish.api.InstancePlugin):
|
|||
label = "Validate Background Depth 32 bit"
|
||||
actions = [action.RepairAction]
|
||||
hosts = ["fusion"]
|
||||
families = ["fusion.deadline", "fusion.local"]
|
||||
families = ["colorbleed.saver"]
|
||||
optional = True
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ class ValidateFusionCompSaved(pyblish.api.ContextPlugin):
|
|||
|
||||
order = pyblish.api.ValidatorOrder
|
||||
label = "Validate Comp Saved"
|
||||
families = ["fusion.deadline", "fusion.local"]
|
||||
families = ["colorbleed.saver"]
|
||||
hosts = ["fusion"]
|
||||
|
||||
def process(self, context):
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class ValidateCreateFolderChecked(pyblish.api.InstancePlugin):
|
|||
order = pyblish.api.ValidatorOrder
|
||||
actions = [action.RepairAction]
|
||||
label = "Validate Create Folder Checked"
|
||||
families = ["fusion.deadline", "fusion.local"]
|
||||
families = ["colorbleed.saver"]
|
||||
hosts = ["fusion"]
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class ValidateFilenameHasExtension(pyblish.api.InstancePlugin):
|
|||
|
||||
order = pyblish.api.ValidatorOrder
|
||||
label = "Validate Filename Has Extension"
|
||||
families = ["fusion.deadline", "fusion.local"]
|
||||
families = ["colorbleed.saver"]
|
||||
hosts = ["fusion"]
|
||||
|
||||
def process(self, instance):
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ class ValidateSaverPassthrough(pyblish.api.InstancePlugin):
|
|||
|
||||
order = pyblish.api.ValidatorOrder
|
||||
label = "Validate Saver Active"
|
||||
families = ["fusion.deadline", "fusion.local"]
|
||||
families = ["colorbleed.saver"]
|
||||
hosts = ["fusion"]
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ class ValidateUniqueSubsets(pyblish.api.InstancePlugin):
|
|||
|
||||
order = pyblish.api.ValidatorOrder
|
||||
label = "Validate Unique Subsets"
|
||||
families = ["fusion.deadline", "fusion.local"]
|
||||
families = ["colorbleed.saver"]
|
||||
hosts = ["fusion"]
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class SubmitDependentImageSequenceJobDeadline(pyblish.api.InstancePlugin):
|
|||
label = "Submit image sequence jobs to Deadline"
|
||||
order = pyblish.api.IntegratorOrder + 0.1
|
||||
hosts = ["fusion", "maya"]
|
||||
families = ["fusion.deadline", "colorbleed.renderlayer"]
|
||||
families = ["colorbleed.saver.deadline", "colorbleed.renderlayer"]
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
class FusionLockComp(object):
|
||||
def __init__(self, undoQueueName="Script CMD"):
|
||||
# Lock flow
|
||||
comp.Lock()
|
||||
# Start undo event
|
||||
comp.StartUndo(undoQueueName)
|
||||
|
||||
def __enter__(self):
|
||||
return None
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
comp.EndUndo(True)
|
||||
comp.Unlock()
|
||||
|
||||
|
||||
|
||||
def f1():
|
||||
with FusionLockComp('Selected Backgrounds to 32bit'):
|
||||
toolsDict = comp.GetToolList(True)
|
||||
if toolsDict:
|
||||
for i, tool in toolsDict.items():
|
||||
if tool.ID == "Background":
|
||||
tool.Depth = 5
|
||||
|
||||
f1()
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
class FusionLockComp(object):
|
||||
def __init__(self, undoQueueName="Script CMD"):
|
||||
# Lock flow
|
||||
comp.Lock()
|
||||
# Start undo event
|
||||
comp.StartUndo(undoQueueName)
|
||||
|
||||
def __enter__(self):
|
||||
return None
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
comp.EndUndo(True)
|
||||
comp.Unlock()
|
||||
|
||||
|
||||
|
||||
def f1():
|
||||
with FusionLockComp('Backgrounds to 32bit'):
|
||||
toolsDict = comp.GetToolList(False)
|
||||
if toolsDict:
|
||||
for i, tool in toolsDict.items():
|
||||
if tool.ID == "Background":
|
||||
tool.Depth = 5
|
||||
|
||||
f1()
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
class FusionLockComp(object):
|
||||
def __init__(self, undoQueueName="Script CMD"):
|
||||
# Lock flow
|
||||
comp.Lock()
|
||||
# Start undo event
|
||||
comp.StartUndo(undoQueueName)
|
||||
|
||||
def __enter__(self):
|
||||
return None
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
comp.EndUndo(True)
|
||||
comp.Unlock()
|
||||
|
||||
|
||||
|
||||
def f1():
|
||||
with FusionLockComp('Selected Loaders to 32bit'):
|
||||
toolsDict = comp.GetToolList(True)
|
||||
if toolsDict:
|
||||
for i, tool in toolsDict.items():
|
||||
if tool.ID == "Loader":
|
||||
tool.Depth = 5
|
||||
|
||||
f1()
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
class FusionLockComp(object):
|
||||
def __init__(self, undoQueueName="Script CMD"):
|
||||
# Lock flow
|
||||
comp.Lock()
|
||||
# Start undo event
|
||||
comp.StartUndo(undoQueueName)
|
||||
|
||||
def __enter__(self):
|
||||
return None
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
comp.EndUndo(True)
|
||||
comp.Unlock()
|
||||
|
||||
|
||||
|
||||
def f1():
|
||||
with FusionLockComp('Loaders to 32bit'):
|
||||
toolsDict = comp.GetToolList(False)
|
||||
if toolsDict:
|
||||
for i, tool in toolsDict.items():
|
||||
if tool.ID == "Loader":
|
||||
tool.Depth = 5
|
||||
|
||||
f1()
|
||||
|
||||
|
||||
107
setup/fusion/scripts/Comp/colorbleed/SE_LoaderTweaker.lua
Normal file
107
setup/fusion/scripts/Comp/colorbleed/SE_LoaderTweaker.lua
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
------------------------------------------------------------
|
||||
-- Change various options in Loadertools, Revision: 2.1
|
||||
--
|
||||
--
|
||||
-- place in Fusion:\Scripts\Comp
|
||||
--
|
||||
-- written by Isaac Guenard (izyk@eyeonline.com) / Sean Konrad
|
||||
-- created : January 24rd, 2005
|
||||
-- modified by Eric Westphal (Eric@SirEdric.de), February 2007
|
||||
------------------------------------------------------------
|
||||
|
||||
|
||||
MissingFramesOpt = {"Do Not Change", "Fail", "Hold Previous", "Output Black", "Wait"}
|
||||
DepthOpt={"Do Not Change", "Format", "Default", "int8", "int16", "float16", "float32"}
|
||||
GeneralOpt={"Do Not Change", "Off", "On"}
|
||||
HoldOpt={"Do Not Change", "Set to..."}
|
||||
PixelOpt={"Do Not Change", "From File", "Default", "Custom (set below)"}
|
||||
|
||||
ret = comp.AskUser("SirEdric's Tweak-All-Loaders", {
|
||||
{"AlphaSolid", "Dropdown", Options = GeneralOpt},
|
||||
{"PostMultiply", "Dropdown", Options = GeneralOpt},
|
||||
{"InvertAlpha", "Dropdown", Options = GeneralOpt},
|
||||
{"MissingFrames", "Dropdown", Options = MissingFramesOpt},
|
||||
{"Depth", "Dropdown", Options = DepthOpt},
|
||||
{"PixelAspect", "Dropdown", Options = PixelOpt},
|
||||
{"CustomPixelAspect", "Position", Default={1,1} },
|
||||
{"HoldFirstOpt", Name="Hold First Frame", "Dropdown", Options = HoldOpt},
|
||||
{"HoldFirst", Name = "Hold first Frame for", "Screw", Default = 0, Min = 0, Max=500, Integer = true},
|
||||
{"HoldLastOpt", Name="Hold Last Frame", "Dropdown", Options = HoldOpt},
|
||||
{"HoldLast", Name = "Hold first Frame for", "Screw", Default = 0, Min = 0, Max=500, Integer = true},
|
||||
{"Selected", Name = "Affect Selected Tools Only", "Checkbox", Default = 0}
|
||||
})
|
||||
|
||||
if ret then
|
||||
composition:StartUndo("SE_LoaderTweaker")
|
||||
MyPixX=ret.CustomPixelAspect[1]
|
||||
MyPixY=ret.CustomPixelAspect[2]
|
||||
print(MyPixX.."bb".. MyPixY)
|
||||
print()
|
||||
print("SE_LoaderTweaker is about to change...")
|
||||
print("...AlphaSolid to ["..GeneralOpt[ret.AlphaSolid+1].."]")
|
||||
print("...PostMultiply to ["..GeneralOpt[ret.PostMultiply+1].."]")
|
||||
print("...InvertAlpha to ["..GeneralOpt[ret.InvertAlpha+1].."]")
|
||||
print("...Missing Frames to [".. MissingFramesOpt[ret.MissingFrames + 1].."]")
|
||||
print("...Depth to ["..DepthOpt[ret.Depth+1].."]")
|
||||
print("...PixelAspect to ["..PixelOpt[ret.PixelAspect+1].."]")
|
||||
print("...CustomPixelAspect(if selected): X="..MyPixX.." Y="..MyPixY)
|
||||
print("...Hold First Frame to ["..HoldOpt[ret.HoldFirstOpt+1]..": " .. ret.HoldFirst.."]")
|
||||
print("...Hold Last Frame to ["..HoldOpt[ret.HoldLastOpt+1]..": " .. ret.HoldLast.."]")
|
||||
if ret.Selected then
|
||||
print("...... *** on selected tools only! ***")
|
||||
end
|
||||
print("---------------------------------------------------")
|
||||
print()
|
||||
|
||||
-- ((ret.Selected ==1)) will return true if the
|
||||
-- selected checkbox is enabled.....
|
||||
|
||||
for i, v in composition:GetToolList((ret.Selected == 1)) do
|
||||
id = v:GetAttrs().TOOLS_RegID
|
||||
MyName = v:GetAttrs().TOOLS_Name
|
||||
if id == "Loader" then
|
||||
print("Changing "..MyName.." Options:")
|
||||
if ret.AlphaSolid > 0 then -- check for 'DoNothing'
|
||||
print("MakeAlphaSolid set to: "..(ret.AlphaSolid-1))
|
||||
v.MakeAlphaSolid = (ret.AlphaSolid-1)
|
||||
end
|
||||
if ret.PostMultiply > 0 then -- check for 'DoNothing'
|
||||
print("PostMultiplyByAlpha set to: "..(ret.PostMultiply-1))
|
||||
v.PostMultiplyByAlpha = (ret.PostMultiply-1)
|
||||
end
|
||||
if ret.InvertAlpha > 0 then -- check for 'DoNothing'
|
||||
print("InvertAlpha set to: "..(ret.InvertAlpha-1))
|
||||
v.InvertAlpha = (ret.InvertAlpha-1)
|
||||
end
|
||||
if ret.MissingFrames >0 then -- check for 'DoNothing'
|
||||
print("MissingFrames set to: "..(ret.MissingFrames-1))
|
||||
v.MissingFrames = (ret.MissingFrames-1)
|
||||
end
|
||||
if ret.Depth >0 then -- check for 'DoNothing'
|
||||
print("Depth set to: "..(ret.Depth-1))
|
||||
v.Depth = (ret.Depth-1)
|
||||
end
|
||||
if ret.PixelAspect >0 then -- check for 'DoNothing'
|
||||
print("PixelAspect set to: "..(ret.PixelAspect-1))
|
||||
v.PixelAspect = (ret.PixelAspect-1)
|
||||
if ret.PixelAspect == 3 then
|
||||
v.CustomPixelAspect={MyPixX, MyPixY}
|
||||
end
|
||||
end
|
||||
if ret.HoldFirstOpt >0 then -- check for 'DoNothing'
|
||||
print("HoldFirstFrame set to: "..(ret.HoldFirst))
|
||||
v.HoldFirstFrame = (ret.HoldFirst)
|
||||
end
|
||||
|
||||
if ret.HoldLastOpt >0 then -- check for 'DoNothing'
|
||||
print("HoldLastFrame set to: "..(ret.HoldLast))
|
||||
v.HoldLastFrame = (ret.HoldLast)
|
||||
end
|
||||
|
||||
print(v:GetAttrs().TOOLS_Name)
|
||||
end
|
||||
end
|
||||
composition:EndUndo(true)
|
||||
end
|
||||
|
||||
print()
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
class FusionLockComp(object):
|
||||
def __init__(self, undoQueueName="Script CMD"):
|
||||
# Lock flow
|
||||
comp.Lock()
|
||||
# Start undo event
|
||||
comp.StartUndo(undoQueueName)
|
||||
|
||||
def __enter__(self):
|
||||
return None
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
comp.EndUndo(True)
|
||||
comp.Unlock()
|
||||
|
||||
|
||||
def pairs(n):
|
||||
it = iter(n)
|
||||
return zip(it, it)
|
||||
|
||||
|
||||
def duplicateWithInputConnections():
|
||||
|
||||
with FusionLockComp("Duplicate With Input Connections"):
|
||||
originalTools = comp.GetToolList(True)
|
||||
if not originalTools:
|
||||
return # nothing selected
|
||||
|
||||
comp.Copy()
|
||||
comp.SetActiveTool()
|
||||
comp.Paste()
|
||||
|
||||
duplicateTools = comp.GetToolList(True)
|
||||
|
||||
for i, tool in originalTools.iteritems():
|
||||
dupToolInputs = duplicateTools[i].GetInputList()
|
||||
|
||||
for j, input in tool.GetInputList().iteritems():
|
||||
if input.GetAttrs()['INPB_Connected']:
|
||||
if j in dupToolInputs:
|
||||
if dupToolInputs[j].GetAttrs()['INPB_Connected']:
|
||||
print (" Both connected. ")
|
||||
else:
|
||||
dupToolInputs[j].ConnectTo(input.GetConnectedOutput())
|
||||
if dupToolInputs[j].GetAttrs()['INPB_Connected']:
|
||||
print (" Connection Successful ")
|
||||
|
||||
|
||||
|
||||
duplicateWithInputConnections()
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
class FusionLockComp(object):
|
||||
def __init__(self, undoQueueName="Script CMD"):
|
||||
# Lock flow
|
||||
comp.Lock()
|
||||
# Start undo event
|
||||
comp.StartUndo(undoQueueName)
|
||||
|
||||
def __enter__(self):
|
||||
return None
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
comp.EndUndo(True)
|
||||
comp.Unlock()
|
||||
|
||||
idList = set(["BrightnessContrast", "ColorCorrector"])
|
||||
attrName = "PreDividePostMultiply"
|
||||
|
||||
with FusionLockComp("BC & CC set PreMultiplyPostDivide to 1"):
|
||||
toolsDict = comp.GetToolList(False)
|
||||
if toolsDict:
|
||||
for i, tool in toolsDict.items():
|
||||
if tool.ID in idList:
|
||||
for input in tool.GetInputList().values():
|
||||
setattr(tool, attrName, 1.0)
|
||||
107
setup/fusion/scripts/Comp/colorbleed/search_replace_paths.py
Normal file
107
setup/fusion/scripts/Comp/colorbleed/search_replace_paths.py
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import os
|
||||
import re
|
||||
|
||||
|
||||
class FusionLockComp(object):
|
||||
def __init__(self, undoQueueName="Script CMD"):
|
||||
# Lock flow
|
||||
comp.Lock()
|
||||
# Start undo event
|
||||
comp.StartUndo(undoQueueName)
|
||||
|
||||
def __enter__(self):
|
||||
return None
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
comp.EndUndo(True)
|
||||
comp.Unlock()
|
||||
|
||||
|
||||
def replaceStr(inputString, srchFor, srchTo, caseSensitive=True):
|
||||
if caseSensitive:
|
||||
return inputString.replace(srchFor, srchTo)
|
||||
else:
|
||||
regex = re.compile(re.escape(srchFor), re.IGNORECASE)
|
||||
return regex.sub(srchTo, inputString)
|
||||
|
||||
|
||||
def searchReplaceLoaderSavers():
|
||||
userResponse = comp.AskUser("Repath All Loaders",
|
||||
{1:{1:"Loaders", 2:"Checkbox", "Name":"Loaders", "NumAcross":3, "Default":1},
|
||||
2:{1:"Savers", 2:"Checkbox", "Name":"Savers", "NumAcross":3, "Default":1},
|
||||
3:{1:"Proxy", 2:"Checkbox", "Name":"Proxy", "NumAcross":3, "Default":1},
|
||||
4:{1:"Source", 2:"Text", "Name":"Enter pattern to search for"},
|
||||
5:{1:"Replacement", 2:"Text", "Name":"Enter the replacement path"},
|
||||
6:{1:"Valid", 2:"Checkbox", "Name":"Check If New Path is Valid", "Default":1},
|
||||
7:{1:"CaseSensitive", 2:"Checkbox", "Name":"Case Sensitive", "Default":1},
|
||||
8:{1:"SelectedOnly", 2:"Checkbox", "Name":"Selected Only", "Default":0},
|
||||
9:{1:"PreserveGlobalIn", 2:"Checkbox", "Name":"Preserve Global In Point", "Default":1}
|
||||
}
|
||||
)
|
||||
|
||||
if userResponse:
|
||||
srchFor = userResponse['Source']
|
||||
if not srchFor:
|
||||
raise RuntimeError("No source string specified.")
|
||||
|
||||
srchTo = userResponse['Replacement']
|
||||
if not srchTo:
|
||||
raise RuntimeError("No replacement string specified.")
|
||||
|
||||
doLoaders = userResponse['Loaders']
|
||||
doSavers = userResponse['Savers']
|
||||
doProxy = userResponse['Proxy']
|
||||
doValidate = userResponse['Valid']
|
||||
doCaseSensitive = userResponse['CaseSensitive']
|
||||
doSelectedOnly = bool(userResponse['SelectedOnly'])
|
||||
doPreserveGlobalIn = bool(userResponse['PreserveGlobalIn'])
|
||||
|
||||
|
||||
with FusionLockComp('Path Remap - "{0}" to "{1}"'.format(srchFor, srchTo)):
|
||||
toolsDict = comp.GetToolList(doSelectedOnly)
|
||||
for i, tool in toolsDict.items():
|
||||
toolId = tool.ID
|
||||
if toolId == "Loader" or toolId == "Saver":
|
||||
tool_a = tool.GetAttrs()
|
||||
if (doLoaders or doProxy) and toolId == "Loader":
|
||||
clipTable = tool_a['TOOLST_Clip_Name']
|
||||
altclipTable = tool_a['TOOLST_AltClip_Name']
|
||||
startTime = tool_a['TOOLNT_Clip_Start']
|
||||
|
||||
if doPreserveGlobalIn:
|
||||
oldGlobalIn = tool.GlobalIn[comp.CurrentTime]
|
||||
|
||||
if doLoaders:
|
||||
for n, name in clipTable.items():
|
||||
#for i in table.getn(clipTable):
|
||||
if name:
|
||||
newPath = replaceStr(name, srchFor, srchTo, doCaseSensitive)
|
||||
print (name, newPath)
|
||||
if not doValidate or os.path.exists(comp.MapPath(newPath)):
|
||||
tool.Clip[startTime[n]] = newPath
|
||||
else:
|
||||
print( "FAILED : New clip does not exist; skipping sequence.\n {0} .. {1}".format(name, newPath))
|
||||
|
||||
if doProxy:
|
||||
for n, name in altclipTable.items():
|
||||
if name:
|
||||
newPath = replaceStr(name, srchFor, srchTo, doCaseSensitive)
|
||||
if not doValidate or os.path.exists(comp.MapPath(newPath)):
|
||||
tool.ProxyFilename[startTime[n]] = newPath
|
||||
else:
|
||||
print( "FAILED : New proxy clip does not exist; skipping sequence.\n {0} .. {1}".format(name, newPath))
|
||||
|
||||
if doPreserveGlobalIn:
|
||||
tool.GlobalIn[comp.CurrentTime] = oldGlobalIn
|
||||
|
||||
if doSavers and toolId == "Saver":
|
||||
for i, name in tool_a['TOOLST_Clip_Name'].items():
|
||||
newPath = replaceStr(name, srchFor, srchTo, doCaseSensitive)
|
||||
if not doValidate or os.path.exists(os.path.dirname(comp.MapPath(newPath))):
|
||||
tool.Clip[comp. ] = newPath
|
||||
else:
|
||||
print( "FAILED : Output directory does not exist; skipping saver.\n {0} .. {1}".format(name, newPath))
|
||||
|
||||
searchReplaceLoaderSavers()
|
||||
|
||||
|
||||
96
setup/fusion/scripts/Comp/colorbleed/set_relative_paths.py
Normal file
96
setup/fusion/scripts/Comp/colorbleed/set_relative_paths.py
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import os
|
||||
import re
|
||||
|
||||
|
||||
class FusionLockComp(object):
|
||||
def __init__(self, undoQueueName="Script CMD"):
|
||||
# Lock flow
|
||||
comp.Lock()
|
||||
# Start undo event
|
||||
comp.StartUndo(undoQueueName)
|
||||
|
||||
def __enter__(self):
|
||||
return None
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
comp.EndUndo(True)
|
||||
comp.Unlock()
|
||||
|
||||
|
||||
def makeRelativePath(root, path):
|
||||
try:
|
||||
return "Comp:\{0}".format(os.path.relpath(os.path.abspath(fusion.MapPath(path)), root))
|
||||
except ValueError:
|
||||
print("Warning -- Can't define relative path for: {0}".format(path))
|
||||
return path
|
||||
|
||||
def pathToCurrentComp():
|
||||
return comp.GetAttrs()["COMPS_FileName"]
|
||||
|
||||
|
||||
def cbRelativePaths():
|
||||
userResponse = comp.AskUser("Make paths relative",
|
||||
{
|
||||
1:{1:"Loaders", 2:"Checkbox", "Name":"Loaders", "NumAcross":3, "Default":1},
|
||||
2:{1:"Savers", 2:"Checkbox", "Name":"Savers", "NumAcross":3, "Default":1},
|
||||
3:{1:"Proxy", 2:"Checkbox", "Name":"Proxy", "NumAcross":3, "Default":1},
|
||||
4:{1:"SelectedOnly", 2:"Checkbox", "Name":"Selected Only", "Default":0}
|
||||
}
|
||||
)
|
||||
|
||||
if userResponse:
|
||||
|
||||
root = pathToCurrentComp()
|
||||
if not root:
|
||||
raise RuntimeError("Fusion file has not been saved. Can't make paths relative")
|
||||
if root:
|
||||
root = os.path.dirname(root)
|
||||
|
||||
# set root
|
||||
os.chdir(root)
|
||||
|
||||
doLoaders = userResponse['Loaders']
|
||||
doSavers = userResponse['Savers']
|
||||
doProxy = userResponse['Proxy']
|
||||
doSelectedOnly = bool(userResponse['SelectedOnly'])
|
||||
|
||||
|
||||
|
||||
with FusionLockComp('Make paths relative'):
|
||||
toolsDict = comp.GetToolList(doSelectedOnly)
|
||||
for i, tool in toolsDict.items():
|
||||
toolId = tool.ID
|
||||
if toolId == "Loader" or toolId == "Saver":
|
||||
tool_a = tool.GetAttrs()
|
||||
if (doLoaders or doProxy) and toolId == "Loader":
|
||||
clipTable = tool_a['TOOLST_Clip_Name']
|
||||
altclipTable = tool_a['TOOLST_AltClip_Name']
|
||||
startTime = tool_a['TOOLNT_Clip_Start']
|
||||
|
||||
# Preserve global in
|
||||
oldGlobalIn = tool.GlobalIn[comp.CurrentTime]
|
||||
|
||||
if doLoaders:
|
||||
for n, name in clipTable.items():
|
||||
if name:
|
||||
newPath = makeRelativePath(root, name)
|
||||
tool.Clip[startTime[n]] = newPath
|
||||
|
||||
if doProxy:
|
||||
for n, name in altclipTable.items():
|
||||
if name:
|
||||
newPath = makeRelativePath(root, name)
|
||||
tool.ProxyFilename[startTime[n]] = newPath
|
||||
|
||||
# Set global in (to what we preserved)
|
||||
tool.GlobalIn[comp.CurrentTime] = oldGlobalIn
|
||||
|
||||
if doSavers and toolId == "Saver":
|
||||
for i, name in tool_a['TOOLST_Clip_Name'].items():
|
||||
if name:
|
||||
newPath = makeRelativePath(root, name)
|
||||
tool.Clip[comp.TIME_UNDEFINED] = newPath
|
||||
|
||||
cbRelativePaths()
|
||||
|
||||
|
||||
138
setup/fusion/scripts/Comp/colorbleed/set_rendermode.py
Normal file
138
setup/fusion/scripts/Comp/colorbleed/set_rendermode.py
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
import os
|
||||
|
||||
from avalon.vendor.Qt import QtCore, QtWidgets
|
||||
from avalon.vendor import qtawesome
|
||||
import avalon.fusion as avalon
|
||||
|
||||
|
||||
_help = {"renderlocal": "Render the comp on your own machine and publish "
|
||||
"it from that the destination folder",
|
||||
"deadline": "Submit a Fusion render job to Deadline to use all other "
|
||||
"computers and add a publish job"}
|
||||
|
||||
|
||||
class SetRenderMode(QtWidgets.QWidget):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QtWidgets.QWidget.__init__(self, parent)
|
||||
|
||||
self._comp = avalon.get_current_comp()
|
||||
self._comp_name = self._get_comp_name()
|
||||
|
||||
self.setWindowTitle("Set Render Mode - {}".format(self._comp_name))
|
||||
self.resize(300, 150)
|
||||
self.setFixedSize(300, 150)
|
||||
|
||||
layout = QtWidgets.QVBoxLayout()
|
||||
|
||||
# region comp info
|
||||
comp_info_layout = QtWidgets.QHBoxLayout()
|
||||
|
||||
update_btn = QtWidgets.QPushButton(qtawesome.icon("fa.refresh"), "")
|
||||
update_btn.setFixedWidth(25)
|
||||
update_btn.setFixedHeight(25)
|
||||
|
||||
comp_information = QtWidgets.QLineEdit()
|
||||
comp_information.setEnabled(False)
|
||||
|
||||
comp_info_layout.addWidget(comp_information)
|
||||
comp_info_layout.addWidget(update_btn)
|
||||
# endregion comp info
|
||||
|
||||
# region modes
|
||||
mode_options = QtWidgets.QComboBox()
|
||||
mode_options.addItems(_help.keys())
|
||||
|
||||
mode_information = QtWidgets.QTextEdit()
|
||||
mode_information.setEnabled(False)
|
||||
# endregion modes
|
||||
|
||||
accept_layout = QtWidgets.QHBoxLayout()
|
||||
accept_btn = QtWidgets.QPushButton("Accept")
|
||||
validation_state = QtWidgets.QPushButton()
|
||||
validation_state.setFixedHeight(15)
|
||||
validation_state.setFixedWidth(15)
|
||||
validation_state.setEnabled(False)
|
||||
validation_state.setStyleSheet("background-color: green")
|
||||
|
||||
accept_layout.addWidget(accept_btn)
|
||||
accept_layout.addWidget(validation_state)
|
||||
|
||||
layout.addLayout(comp_info_layout)
|
||||
layout.addWidget(mode_options)
|
||||
layout.addWidget(mode_information)
|
||||
layout.addLayout(accept_layout)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
self.comp_information = comp_information
|
||||
self.update_btn = update_btn
|
||||
|
||||
self.mode_options = mode_options
|
||||
self.mode_information = mode_information
|
||||
|
||||
self.accept_btn = accept_btn
|
||||
self.validation = validation_state
|
||||
|
||||
self.connections()
|
||||
self.update()
|
||||
|
||||
def connections(self):
|
||||
"""Build connections between code and buttons"""
|
||||
|
||||
self.update_btn.clicked.connect(self.update)
|
||||
self.accept_btn.clicked.connect(self._set_comp_rendermode)
|
||||
self.mode_options.currentIndexChanged.connect(
|
||||
self._update_rendermode_info)
|
||||
|
||||
def update(self):
|
||||
"""Update all information in the UI"""
|
||||
|
||||
self._comp = avalon.get_current_comp()
|
||||
self._comp_name = self._get_comp_name()
|
||||
|
||||
self.setWindowTitle("Set Render Mode")
|
||||
self.comp_information.setText(self._comp_name)
|
||||
|
||||
self._update_rendermode_info()
|
||||
|
||||
def _update_rendermode_info(self):
|
||||
|
||||
rendermode = self._get_comp_rendermode()
|
||||
if rendermode is None:
|
||||
rendermode = "renderlocal"
|
||||
|
||||
self.mode_information.setText(_help[rendermode])
|
||||
|
||||
def _get_comp_name(self):
|
||||
return os.path.basename(self._comp.GetAttrs("COMPS_FileName"))
|
||||
|
||||
def _get_comp_rendermode(self):
|
||||
return self._comp.GetData("colorbleed.rendermode")
|
||||
|
||||
def _set_comp_rendermode(self):
|
||||
rendermode = self.mode_options.currentText()
|
||||
self._comp.SetData("colorbleed.rendermode", rendermode)
|
||||
|
||||
# Validate the rendermode has been updated correctly
|
||||
if not self._validation():
|
||||
self.validation.setStyleSheet("background-color: red")
|
||||
raise AssertionError("Rendermode in UI is not render mode in comp: "
|
||||
"%s" % self._comp_name)
|
||||
|
||||
print("Updated render mode for %s to %s" % (self._comp_name, rendermode))
|
||||
|
||||
def _validation(self):
|
||||
ui_mode = self.mode_options.currentText()
|
||||
comp_mode = self._get_comp_rendermode()
|
||||
|
||||
return comp_mode == ui_mode
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
import sys
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
w = SetRenderMode()
|
||||
w.show()
|
||||
sys.exit(app.exec_())
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
|
||||
class FusionLockComp(object):
|
||||
def __init__(self, undoQueueName="Script CMD"):
|
||||
# Lock flow
|
||||
comp.Lock()
|
||||
# Start undo event
|
||||
comp.StartUndo(undoQueueName)
|
||||
|
||||
def __enter__(self):
|
||||
return None
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
comp.EndUndo(True)
|
||||
comp.Unlock()
|
||||
|
||||
|
||||
with FusionLockComp("Reload clip time ranges"):
|
||||
toolsDict = comp.GetToolList(True)
|
||||
if toolsDict:
|
||||
for i, tool in toolsDict.items():
|
||||
if tool.ID != "Loader":
|
||||
continue
|
||||
|
||||
tool_a = tool.GetAttrs()
|
||||
clipTable = tool_a['TOOLST_Clip_Name']
|
||||
altclipTable = tool_a['TOOLST_AltClip_Name']
|
||||
startTime = tool_a['TOOLNT_Clip_Start']
|
||||
oldGlobalIn = tool.GlobalIn[comp.CurrentTime]
|
||||
|
||||
for n, c in clipTable.items():
|
||||
tool.Clip[startTime[n]] = tool.Clip[startTime[n]]
|
||||
|
||||
for n, c in altclipTable.items():
|
||||
tool.ProxyFilename[startTime[n]] = tool.ProxyFilename[startTime[n]]
|
||||
|
||||
tool.GlobalIn[comp.CurrentTime] = oldGlobalIn
|
||||
Loading…
Add table
Add a link
Reference in a new issue