forked from Colorbleed/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial draft integration for Cinema4D
- Loading branch information
Showing
4 changed files
with
318 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
"""Public API | ||
Anything that isn't defined here is INTERNAL and unreliable for external use. | ||
""" | ||
|
||
from .pipeline import ( | ||
install, | ||
uninstall, | ||
|
||
ls, | ||
|
||
) | ||
|
||
from .workio import ( | ||
open_file, | ||
save_file, | ||
current_file, | ||
has_unsaved_changes, | ||
file_extensions, | ||
work_root | ||
) | ||
|
||
|
||
__all__ = [ | ||
"install", | ||
"uninstall", | ||
|
||
"ls", | ||
|
||
# Workfiles API | ||
"open_file", | ||
"save_file", | ||
"current_file", | ||
"has_unsaved_changes", | ||
"file_extensions", | ||
"work_root", | ||
|
||
|
||
] | ||
|
||
# Backwards API compatibility | ||
open = open_file | ||
save = save_file |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import sys | ||
import importlib | ||
|
||
from pyblish import api as pyblish | ||
|
||
|
||
self = sys.modules[__name__] | ||
|
||
|
||
def install(config): | ||
"""Install Maya-specific functionality of avalon-core. | ||
This function is called automatically on calling `api.install(maya)`. | ||
""" | ||
|
||
_register_callbacks() | ||
_install_menu() | ||
|
||
pyblish.register_host("cinema4d") | ||
|
||
config = find_host_config(config) | ||
if config and hasattr(config, "install"): | ||
config.install() | ||
|
||
|
||
def find_host_config(config): | ||
module = config.__name__ + ".cinema4d" | ||
try: | ||
config = importlib.import_module(module) | ||
except ImportError as exc: | ||
if str(exc) != "No module name {}".format(module): | ||
print(exc) | ||
config = None | ||
|
||
return config | ||
|
||
|
||
def uninstall(config): | ||
"""Uninstall Maya-specific functionality of avalon-core. | ||
This function is called automatically on calling `api.uninstall()`. | ||
""" | ||
config = find_host_config(config) | ||
if config and hasattr(config, "uninstall"): | ||
config.uninstall() | ||
|
||
_uninstall_menu() | ||
|
||
pyblish.deregister_host("cinema4d") | ||
|
||
|
||
def _install_menu(): | ||
pass | ||
|
||
|
||
def _uninstall_menu(): | ||
pass | ||
|
||
|
||
def ls(): | ||
"""Yields containers from active Maya scene | ||
This is the host-equivalent of api.ls(), but instead of listing | ||
assets on disk, it lists assets already loaded in Maya; once loaded | ||
they are called 'containers' | ||
Yields: | ||
dict: container | ||
""" | ||
pass | ||
|
||
|
||
def _register_callbacks(): | ||
pass | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
"""Host API required Work Files tool""" | ||
import os | ||
|
||
import c4d | ||
|
||
|
||
def file_extensions(): | ||
return [".c4d"] | ||
|
||
|
||
def _document(): | ||
return c4d.documents.GetActiveDocument() | ||
|
||
|
||
def has_unsaved_changes(): | ||
doc = _document() | ||
if doc: | ||
return doc.GetChanged() | ||
|
||
|
||
def save_file(filepath): | ||
doc = _document() | ||
if doc: | ||
return c4d.documents.SaveDocument(doc, | ||
filepath, | ||
c4d.SAVEDOCUMENTFLAGS_NONE, | ||
c4d.FORMAT_C4DEXPORT) | ||
|
||
|
||
def open_file(filepath): | ||
filepath = str(filepath) # C4D LoadFile fails on unicode | ||
return c4d.documents.LoadFile(str(filepath)) | ||
|
||
|
||
def current_file(): | ||
doc = _document() | ||
if doc: | ||
root = doc.GetDocumentPath() | ||
fname = doc.GetDocumentName() | ||
if root and fname: | ||
return os.path.join(root, fname) | ||
|
||
|
||
def work_root(): | ||
from avalon import Session | ||
|
||
work_dir = Session["AVALON_WORKDIR"] | ||
scene_dir = Session.get("AVALON_SCENEDIR") | ||
if scene_dir: | ||
return os.path.join(work_dir, scene_dir) | ||
else: | ||
return work_dir |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import c4d | ||
from c4d import gui | ||
|
||
|
||
class ShowCreator(c4d.plugins.CommandData): | ||
id = 999121031 | ||
label = "Create.." | ||
help = "Show Avalon Creator" | ||
icon = None | ||
|
||
def Execute(self, doc): | ||
from avalon.tools import creator as tool | ||
tool.show() | ||
return True | ||
|
||
|
||
class ShowLoader(c4d.plugins.CommandData): | ||
id = 999121032 | ||
label = "Loader.." | ||
help = "Show Avalon Loader" | ||
icon = None | ||
|
||
def Execute(self, doc): | ||
from avalon.tools import loader as tool | ||
tool.show() | ||
return True | ||
|
||
|
||
class ShowSceneInventory(c4d.plugins.CommandData): | ||
id = 999121033 | ||
label = "Manage.." | ||
help = "Show Avalon Loader" | ||
icon = None | ||
|
||
def Execute(self, doc): | ||
from avalon.tools import sceneinventory as tool | ||
tool.show() | ||
return True | ||
|
||
|
||
class ShowPublish(c4d.plugins.CommandData): | ||
id = 999121034 | ||
label = "Publish.." | ||
help = "Show Avalon Publish" | ||
icon = None | ||
|
||
def Execute(self, doc): | ||
from avalon.tools import publish | ||
publish.show() | ||
return True | ||
|
||
|
||
class ShowWorkFiles(c4d.plugins.CommandData): | ||
id = 999121035 | ||
label = "Work Files.." | ||
help = "Show Avalon Work Files" | ||
icon = None | ||
|
||
def Execute(self, doc): | ||
from avalon.tools import workfiles as tool | ||
tool.show() | ||
return True | ||
|
||
|
||
def _install_menu(): | ||
|
||
main_menu = gui.GetMenuResource('M_EDITOR') | ||
|
||
# Create Avalon menu | ||
menu = c4d.BaseContainer() | ||
menu.InsData(c4d.MENURESOURCE_SUBTITLE, "Avalon") | ||
|
||
# Add commands | ||
menu.InsData(c4d.MENURESOURCE_COMMAND, | ||
"PLUGIN_CMD_%s" % ShowCreator.id) | ||
menu.InsData(c4d.MENURESOURCE_COMMAND, | ||
"PLUGIN_CMD_%s" % ShowLoader.id) | ||
menu.InsData(c4d.MENURESOURCE_COMMAND, | ||
"PLUGIN_CMD_%s" % ShowPublish.id) | ||
menu.InsData(c4d.MENURESOURCE_COMMAND, | ||
"PLUGIN_CMD_%s" % ShowSceneInventory.id) | ||
menu.InsData(c4d.MENURESOURCE_SEPERATOR, True) | ||
menu.InsData(c4d.MENURESOURCE_COMMAND, | ||
"PLUGIN_CMD_%s" % ShowWorkFiles.id) | ||
|
||
# Add Avalon menu to main menu | ||
main_menu.InsData(c4d.MENURESOURCE_STRING, menu) | ||
|
||
# Refresh menu bar | ||
gui.UpdateMenus() | ||
|
||
|
||
def _register_commands(): | ||
"""Register C4D commands. | ||
This is required to make Menu Item entries | ||
""" | ||
|
||
for command in [ShowCreator, | ||
ShowLoader, | ||
ShowSceneInventory, | ||
ShowPublish, | ||
ShowWorkFiles]: | ||
c4d.plugins.RegisterCommandPlugin(id=command.id, | ||
str=command.label, | ||
info=0, | ||
icon=command.icon, | ||
help=command.help, | ||
dat=command()) | ||
|
||
|
||
def main(): | ||
|
||
from avalon.vendor.Qt import QtWidgets | ||
|
||
# Initialize a QApplication instance so that whenever we run | ||
# an Avalon tool it assumes the QApplication is already running. | ||
# This way QApplication.exec_() will never be triggered which | ||
# is somehow magically how Qt works in Cinema4D | ||
app = QtWidgets.QApplication.instance() | ||
if not app: | ||
app = QtWidgets.QApplication([]) | ||
app.aboutToQuit.connect(app.deleteLater) # ensure cleanup with C4D | ||
|
||
# Install avalon itself | ||
import avalon.api | ||
import avalon.cinema4d | ||
avalon.api.install(avalon.cinema4d) | ||
|
||
_register_commands() | ||
|
||
|
||
def PluginMessage(id, data): | ||
|
||
if id == c4d.C4DPL_BUILDMENU: | ||
_install_menu() | ||
|
||
return True | ||
|
||
|
||
# Execute main() | ||
if __name__ == '__main__': | ||
main() |