Fusion - Loader plugins updates (#4920)

* Added get_bmd_library to acces BMD's internal python library

* Added the option to import image and online families. + black formatted

* Added workfile loader

To import the content of another workfile into your current comp

* Fixed wrong family and extension in workfile loader

* black formatting

* Added missing formats to fbx importer

Fusions fbx importer can import a bunch of different formats other then fbx (confusing I know but it's how it is)

* Update openpype/hosts/fusion/plugins/load/load_workfile.py

Co-authored-by: Roy Nieterau <roy_nieterau@hotmail.com>

---------

Co-authored-by: Roy Nieterau <roy_nieterau@hotmail.com>
This commit is contained in:
Ember Light 2023-05-22 10:43:11 +02:00 committed by GitHub
parent 0b8400bc8e
commit e178244d46
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 118 additions and 47 deletions

View file

@ -13,6 +13,7 @@ from .lib import (
update_frame_range,
set_asset_framerange,
get_current_comp,
get_bmd_library,
comp_lock_and_undo_chunk
)

View file

@ -309,6 +309,12 @@ def get_fusion_module():
return fusion
def get_bmd_library():
"""Get bmd library"""
bmd = getattr(sys.modules["__main__"], "bmd", None)
return bmd
def get_current_comp():
"""Get current comp in this session"""
fusion = get_fusion_module()

View file

@ -1,4 +1,3 @@
from openpype.pipeline import (
load,
get_representation_path,
@ -6,7 +5,7 @@ from openpype.pipeline import (
from openpype.hosts.fusion.api import (
imprint_container,
get_current_comp,
comp_lock_and_undo_chunk
comp_lock_and_undo_chunk,
)
@ -15,7 +14,21 @@ class FusionLoadFBXMesh(load.LoaderPlugin):
families = ["*"]
representations = ["*"]
extensions = {"fbx"}
extensions = {
"3ds",
"amc",
"aoa",
"asf",
"bvh",
"c3d",
"dae",
"dxf",
"fbx",
"htr",
"mcd",
"obj",
"trc",
}
label = "Load FBX mesh"
order = -10
@ -27,23 +40,24 @@ class FusionLoadFBXMesh(load.LoaderPlugin):
def load(self, context, name, namespace, data):
# Fallback to asset name when namespace is None
if namespace is None:
namespace = context['asset']['name']
namespace = context["asset"]["name"]
# Create the Loader with the filename path set
comp = get_current_comp()
with comp_lock_and_undo_chunk(comp, "Create tool"):
path = self.fname
args = (-32768, -32768)
tool = comp.AddTool(self.tool_type, *args)
tool["ImportFile"] = path
imprint_container(tool,
name=name,
namespace=namespace,
context=context,
loader=self.__class__.__name__)
imprint_container(
tool,
name=name,
namespace=namespace,
context=context,
loader=self.__class__.__name__,
)
def switch(self, container, representation):
self.update(container, representation)

View file

@ -3,17 +3,14 @@ import contextlib
import openpype.pipeline.load as load
from openpype.pipeline.load import (
get_representation_context,
get_representation_path_from_context
get_representation_path_from_context,
)
from openpype.hosts.fusion.api import (
imprint_container,
get_current_comp,
comp_lock_and_undo_chunk
)
from openpype.lib.transcoding import (
IMAGE_EXTENSIONS,
VIDEO_EXTENSIONS
comp_lock_and_undo_chunk,
)
from openpype.lib.transcoding import IMAGE_EXTENSIONS, VIDEO_EXTENSIONS
comp = get_current_comp()
@ -57,20 +54,23 @@ def preserve_trim(loader, log=None):
try:
yield
finally:
length = loader.GetAttrs()["TOOLIT_Clip_Length"][1] - 1
if trim_from_start > length:
trim_from_start = length
if log:
log.warning("Reducing trim in to %d "
"(because of less frames)" % trim_from_start)
log.warning(
"Reducing trim in to %d "
"(because of less frames)" % trim_from_start
)
remainder = length - trim_from_start
if trim_from_end > remainder:
trim_from_end = remainder
if log:
log.warning("Reducing trim in to %d "
"(because of less frames)" % trim_from_end)
log.warning(
"Reducing trim in to %d "
"(because of less frames)" % trim_from_end
)
loader["ClipTimeStart"][time] = trim_from_start
loader["ClipTimeEnd"][time] = length - trim_from_end
@ -109,11 +109,15 @@ def loader_shift(loader, frame, relative=True):
# Shifting global in will try to automatically compensate for the change
# in the "ClipTimeStart" and "HoldFirstFrame" inputs, so we preserve those
# input values to "just shift" the clip
with preserve_inputs(loader, inputs=["ClipTimeStart",
"ClipTimeEnd",
"HoldFirstFrame",
"HoldLastFrame"]):
with preserve_inputs(
loader,
inputs=[
"ClipTimeStart",
"ClipTimeEnd",
"HoldFirstFrame",
"HoldLastFrame",
],
):
# GlobalIn cannot be set past GlobalOut or vice versa
# so we must apply them in the order of the shift.
if shift > 0:
@ -129,7 +133,14 @@ def loader_shift(loader, frame, relative=True):
class FusionLoadSequence(load.LoaderPlugin):
"""Load image sequence into Fusion"""
families = ["imagesequence", "review", "render", "plate"]
families = [
"imagesequence",
"review",
"render",
"plate",
"image",
"onilne",
]
representations = ["*"]
extensions = set(
ext.lstrip(".") for ext in IMAGE_EXTENSIONS.union(VIDEO_EXTENSIONS)
@ -143,7 +154,7 @@ class FusionLoadSequence(load.LoaderPlugin):
def load(self, context, name, namespace, data):
# Fallback to asset name when namespace is None
if namespace is None:
namespace = context['asset']['name']
namespace = context["asset"]["name"]
# Use the first file for now
path = get_representation_path_from_context(context)
@ -151,7 +162,6 @@ class FusionLoadSequence(load.LoaderPlugin):
# Create the Loader with the filename path set
comp = get_current_comp()
with comp_lock_and_undo_chunk(comp, "Create Loader"):
args = (-32768, -32768)
tool = comp.AddTool("Loader", *args)
tool["Clip"] = path
@ -160,11 +170,13 @@ class FusionLoadSequence(load.LoaderPlugin):
start = self._get_start(context["version"], tool)
loader_shift(tool, start, relative=False)
imprint_container(tool,
name=name,
namespace=namespace,
context=context,
loader=self.__class__.__name__)
imprint_container(
tool,
name=name,
namespace=namespace,
context=context,
loader=self.__class__.__name__,
)
def switch(self, container, representation):
self.update(container, representation)
@ -222,24 +234,28 @@ class FusionLoadSequence(load.LoaderPlugin):
start = self._get_start(context["version"], tool)
with comp_lock_and_undo_chunk(comp, "Update Loader"):
# Update the loader's path whilst preserving some values
with preserve_trim(tool, log=self.log):
with preserve_inputs(tool,
inputs=("HoldFirstFrame",
"HoldLastFrame",
"Reverse",
"Depth",
"KeyCode",
"TimeCodeOffset")):
with preserve_inputs(
tool,
inputs=(
"HoldFirstFrame",
"HoldLastFrame",
"Reverse",
"Depth",
"KeyCode",
"TimeCodeOffset",
),
):
tool["Clip"] = path
# Set the global in to the start frame of the sequence
global_in_changed = loader_shift(tool, start, relative=False)
if global_in_changed:
# Log this change to the user
self.log.debug("Changed '%s' global in: %d" % (tool.Name,
start))
self.log.debug(
"Changed '%s' global in: %d" % (tool.Name, start)
)
# Update the imprinted representation
tool.SetData("avalon.representation", str(representation["_id"]))
@ -264,9 +280,11 @@ class FusionLoadSequence(load.LoaderPlugin):
# Get frame start without handles
start = data.get("frameStart")
if start is None:
self.log.warning("Missing start frame for version "
"assuming starts at frame 0 for: "
"{}".format(tool.Name))
self.log.warning(
"Missing start frame for version "
"assuming starts at frame 0 for: "
"{}".format(tool.Name)
)
return 0
# Use `handleStart` if the data is available

View file

@ -0,0 +1,32 @@
"""Import workfiles into your current comp.
As all imported nodes are free floating and will probably be changed there
is no update or reload function added for this plugin
"""
from openpype.pipeline import load
from openpype.hosts.fusion.api import (
get_current_comp,
get_bmd_library,
)
class FusionLoadWorkfile(load.LoaderPlugin):
"""Load the content of a workfile into Fusion"""
families = ["workfile"]
representations = ["*"]
extensions = {"comp"}
label = "Load Workfile"
order = -10
icon = "code-fork"
color = "orange"
def load(self, context, name, namespace, data):
# Get needed elements
bmd = get_bmd_library()
comp = get_current_comp()
# Paste the content of the file into the current comp
comp.Paste(bmd.readfile(self.fname))