forked from getavalon/core
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e1f4012
commit 9d3d3e7
Showing
33 changed files
with
2,039 additions
and
75 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
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,50 @@ | ||
"""Public API | ||
Anything that isn't defined here is INTERNAL and unreliable for external use. | ||
""" | ||
|
||
from .lib import ( | ||
maintained_selection, | ||
) | ||
|
||
from .workio import ( | ||
file_extensions, | ||
has_unsaved_changes, | ||
save_file, | ||
open_file, | ||
current_file, | ||
work_root, | ||
) | ||
|
||
from .pipeline import ( | ||
register_commands, | ||
install, | ||
uninstall, | ||
ls, | ||
) | ||
|
||
__all__ = [ | ||
# Lib API. | ||
"maintained_selection", | ||
|
||
# Workfiles API | ||
"file_extensions", | ||
"has_unsaved_changes", | ||
"save_file", | ||
"open_file", | ||
"current_file", | ||
"work_root", | ||
|
||
# Pipeline API. | ||
"register_commands", | ||
"install", | ||
"uninstall", | ||
"ls", | ||
] | ||
|
||
# Backwards API compatibility | ||
open = open_file | ||
save = save_file | ||
|
||
host_name = 'cinema4d' |
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,26 @@ | ||
import os | ||
import contextlib | ||
import c4d | ||
|
||
AVALON_TAB = "avalon" | ||
|
||
|
||
@contextlib.contextmanager | ||
def maintained_selection(): | ||
"""Maintain selection during context | ||
Example: | ||
>>> doc = c4d.documents.GetActiveDocument() | ||
>>> with maintained_selection(): | ||
... doc.SetSelection([node]) | ||
>>> print(node in doc.GetSelection()) | ||
False | ||
""" | ||
|
||
doc = c4d.documents.GetActiveDocument() | ||
previous_selection = doc.GetSelection() | ||
try: | ||
yield | ||
finally: | ||
doc.SetSelection(previous_selection) |
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,212 @@ | ||
import os | ||
import sys | ||
import importlib | ||
|
||
import c4d | ||
from c4d import gui | ||
from pyblish import api as pyblish | ||
|
||
from ..lib import logger, find_submodule | ||
from .. import api | ||
|
||
self = sys.modules[__name__] | ||
self._menu = None | ||
|
||
|
||
class AvalonContextLabel(c4d.plugins.CommandData): | ||
PLUGIN_ID = 999000001 | ||
|
||
def GetSubContainer(self, doc, submenu): | ||
context_label = "{}, {}".format( | ||
api.Session["AVALON_ASSET"], | ||
api.Session["AVALON_TASK"] | ||
) | ||
submenu.InsData(1, context_label) | ||
return True | ||
|
||
def GetState(self, doc): | ||
# return False to disable the command action | ||
return False | ||
|
||
|
||
class AvalonSwitchTask(c4d.plugins.CommandData): | ||
PLUGIN_ID = 999000002 | ||
|
||
def Execute(self, doc): | ||
from ..tools import workfiles | ||
workfiles.show_switch_task() | ||
return True | ||
|
||
|
||
class AvalonCreate(c4d.plugins.CommandData): | ||
PLUGIN_ID = 999000003 | ||
|
||
def Execute(self, doc): | ||
from ..tools import creator | ||
creator.show() | ||
return True | ||
|
||
|
||
class AvalonLoad(c4d.plugins.CommandData): | ||
PLUGIN_ID = 999000004 | ||
|
||
def Execute(self, doc): | ||
from ..tools import loader | ||
loader.show() | ||
return True | ||
|
||
|
||
class AvalonPublish(c4d.plugins.CommandData): | ||
PLUGIN_ID = 999000005 | ||
|
||
def Execute(self, doc): | ||
from ..tools import publish | ||
publish.show() | ||
return True | ||
|
||
|
||
class AvalonManage(c4d.plugins.CommandData): | ||
PLUGIN_ID = 999000006 | ||
|
||
def Execute(self, doc): | ||
from ..tools import sceneinventory | ||
sceneinventory.show() | ||
return True | ||
|
||
|
||
class AvalonWorkfiles(c4d.plugins.CommandData): | ||
PLUGIN_ID = 999000007 | ||
|
||
def Execute(self, doc): | ||
from ..tools import workfiles | ||
workfiles.show() | ||
return True | ||
|
||
|
||
def reload_pipeline(): | ||
"""Attempt to reload pipeline at run-time. | ||
CAUTION: This is primarily for development and debugging purposes. | ||
""" | ||
|
||
api.uninstall() | ||
_uninstall_menu() | ||
|
||
for module in ("avalon.api", | ||
"avalon.io", | ||
"avalon.lib", | ||
"avalon.pipeline", | ||
"avalon.tools", | ||
"avalon.cinema4d", | ||
"avalon.cinema4d.pipeline", | ||
"avalon.cinema4d.lib", | ||
"avalon.cinema4d.workio" | ||
): | ||
|
||
logger.info("Reloading module: {}...".format(module)) | ||
|
||
module = importlib.import_module(module) | ||
reload(module) | ||
|
||
import avalon.cinema4d | ||
api.install(avalon.cinema4d) | ||
|
||
|
||
def register_commands(): | ||
c4d.plugins.RegisterCommandPlugin(AvalonContextLabel.PLUGIN_ID, "", 0, None, "", AvalonContextLabel()) | ||
c4d.plugins.RegisterCommandPlugin(AvalonSwitchTask.PLUGIN_ID, "Switch Task", 0, None, "", AvalonSwitchTask()) | ||
c4d.plugins.RegisterCommandPlugin(AvalonCreate.PLUGIN_ID, "Create...", 0, None, "", AvalonCreate()) | ||
c4d.plugins.RegisterCommandPlugin(AvalonLoad.PLUGIN_ID, "Load...", 0, None, "", AvalonLoad()) | ||
c4d.plugins.RegisterCommandPlugin(AvalonPublish.PLUGIN_ID, "Publish...", 0, None, "", AvalonPublish()) | ||
c4d.plugins.RegisterCommandPlugin(AvalonManage.PLUGIN_ID, "Manage...", 0, None, "", AvalonManage()) | ||
c4d.plugins.RegisterCommandPlugin(AvalonWorkfiles.PLUGIN_ID, "Work Files", 0, None, "", AvalonWorkfiles()) | ||
|
||
|
||
def install(): | ||
"""Install Cinema 4D-specific functionality of avalon-core. | ||
This is where you install menus and register families, data | ||
and loaders into Cinema 4D. | ||
It is called automatically when installing via `api.install(cinema4d)`. | ||
See the Maya equivalent for inspiration on how to implement this. | ||
""" | ||
|
||
_install_menu() | ||
_register_events() | ||
|
||
pyblish.register_host("cinema4d") | ||
|
||
logger.info("config.cinema4d installed") | ||
|
||
|
||
def uninstall(): | ||
"""Uninstall all that was previously installed | ||
This is where you undo everything that was done in `install()`. | ||
That means, removing menus, deregistering families and data | ||
and everything. It should be as though `install()` was never run, | ||
because odds are calling this function means the user is interested | ||
in re-installing shortly afterwards. If, for example, he has been | ||
modifying the menu or registered families. | ||
""" | ||
|
||
_uninstall_menu() | ||
|
||
pyblish.deregister_host("cinema4d") | ||
|
||
|
||
def _install_menu(): | ||
"""Installing Avalon menu to Cinema 4D | ||
""" | ||
|
||
mainMenu = gui.GetMenuResource("M_EDITOR") | ||
|
||
self._menu = c4d.BaseContainer() | ||
self._menu.InsData(c4d.MENURESOURCE_SUBTITLE, api.Session["AVALON_LABEL"]) | ||
|
||
# Create context menu | ||
self._menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_%s" % AvalonContextLabel.PLUGIN_ID) | ||
self._menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_%s" % AvalonSwitchTask.PLUGIN_ID) | ||
|
||
self._menu.InsData(c4d.MENURESOURCE_SEPERATOR, True) | ||
self._menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_%s" % AvalonCreate.PLUGIN_ID) | ||
self._menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_%s" % AvalonLoad.PLUGIN_ID) | ||
self._menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_%s" % AvalonPublish.PLUGIN_ID) | ||
self._menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_%s" % AvalonManage.PLUGIN_ID) | ||
|
||
self._menu.InsData(c4d.MENURESOURCE_SEPERATOR, True) | ||
|
||
self._menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_%s" % AvalonWorkfiles.PLUGIN_ID) | ||
|
||
pluginsMenu = gui.SearchPluginMenuResource() | ||
if pluginsMenu: | ||
# Insert menu after 'Plugins' menu | ||
mainMenu.InsDataAfter(c4d.MENURESOURCE_STRING, self._menu, pluginsMenu) | ||
else: | ||
# Insert menu after the last existing menu ('Plugins' menu was not found) | ||
mainMenu.InsData(c4d.MENURESOURCE_STRING, self._menu) | ||
|
||
|
||
def _uninstall_menu(): | ||
"""Uninstalling Avalon menu to Cinema 4D | ||
""" | ||
|
||
|
||
def ls(): | ||
"""Yields containers from active Cinema 4D scene | ||
""" | ||
|
||
|
||
def _register_events(): | ||
|
||
api.on("taskChanged", _on_task_changed) | ||
logger.info("Installed event callback for 'taskChanged'..") | ||
|
||
|
||
def _on_task_changed(*args): | ||
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,54 @@ | ||
import os | ||
import c4d | ||
|
||
|
||
def file_extensions(): | ||
return [".c4d"] | ||
|
||
|
||
def has_unsaved_changes(): | ||
doc = c4d.documents.GetActiveDocument() | ||
return doc.GetChanged() | ||
|
||
|
||
def save_file(filepath): | ||
dirname, basename = os.path.split(filepath) | ||
|
||
doc = c4d.documents.GetActiveDocument() | ||
doc.SetDocumentPath(dirname) | ||
doc.SetDocumentName(basename) | ||
|
||
flags = c4d.SAVEDOCUMENTFLAGS_NONE | ||
file_format = c4d.FORMAT_C4DEXPORT | ||
|
||
c4d.documents.SaveDocument(doc, filepath, flags, file_format) | ||
|
||
|
||
def open_file(filepath): | ||
filepath = filepath.replace("\\", "/") | ||
|
||
c4d.documents.LoadFile(filepath) | ||
|
||
|
||
def current_file(): | ||
doc = c4d.documents.GetActiveDocument() | ||
|
||
dirname = doc.GetDocumentPath() | ||
basename = doc.GetDocumentName() | ||
if not dirname: | ||
return None | ||
|
||
current_filepath = os.path.join(dirname, basename) | ||
|
||
return os.path.normpath(current_filepath).replace("\\", "/") | ||
|
||
def work_root(session): | ||
|
||
work_dir = session["AVALON_WORKDIR"] | ||
scene_dir = session.get("AVALON_SCENEDIR") | ||
if scene_dir: | ||
path = os.path.join(work_dir, scene_dir) | ||
else: | ||
path = work_dir | ||
|
||
return os.path.normpath(path).replace("\\", "/") |
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
Oops, something went wrong.