Skip to content

Commit

Permalink
Initial draft integration for Cinema4D
Browse files Browse the repository at this point in the history
  • Loading branch information
BigRoy committed Jan 4, 2020
1 parent d380d88 commit 99bd8bb
Show file tree
Hide file tree
Showing 4 changed files with 318 additions and 0 deletions.
44 changes: 44 additions & 0 deletions avalon/cinema4d/__init__.py
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
78 changes: 78 additions & 0 deletions avalon/cinema4d/pipeline.py
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

52 changes: 52 additions & 0 deletions avalon/cinema4d/workio.py
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
144 changes: 144 additions & 0 deletions setup/cinema4d/avalon_c4d.pyp
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()

0 comments on commit 99bd8bb

Please sign in to comment.