Skip to content

Commit

Permalink
Merge pull request #2 from ynput/core/enhancement/AY-5186_3dsmax-proj…
Browse files Browse the repository at this point in the history
…ect-creation

Max: Create/Set Project Folder when starting Max or task changed
  • Loading branch information
moonyuet committed Jul 18, 2024
2 parents 4b9506e + f55e144 commit a7c2313
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 1 deletion.
34 changes: 33 additions & 1 deletion client/ayon_max/api/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@
import json

from ayon_core.host import HostBase, IWorkfileHost, ILoadHost, IPublishHost

from ayon_core.lib import register_event_callback
import pyblish.api
from ayon_core.pipeline import (
register_creator_plugin_path,
register_loader_plugin_path,
AVALON_CONTAINER_ID,
AYON_CONTAINER_ID,
get_current_project_name
)
from ayon_max.api.menu import AYONMenu
from ayon_core.settings import get_project_settings
from ayon_max.api import lib
from ayon_max.api.plugin import MS_CUSTOM_ATTRIB
from ayon_max import MAX_HOST_DIR
Expand Down Expand Up @@ -47,9 +51,11 @@ def install(self):
register_loader_plugin_path(LOAD_PATH)
register_creator_plugin_path(CREATE_PATH)

# self._register_callbacks()
_set_project()

self.menu = AYONMenu()

register_event_callback("workfile.open.before", on_before_open)
self._has_been_setup = True

rt.callbacks.addScript(rt.Name('systemPostNew'), on_new)
Expand Down Expand Up @@ -205,6 +211,32 @@ def containerise(name: str, nodes: list, context,
return container


def _set_project():
project_name = get_current_project_name()
project_settings = get_project_settings(project_name)
enable_project_creation = project_settings["max"].get("enabled_project_creation")
if not enable_project_creation:
log.debug("Project creation disabled. Skipping project creation.")
workdir = os.getenv("AYON_WORKDIR")

os.makedirs(workdir, exist_ok=True)
mxp_filepath = os.path.join(workdir, "workspace.mxp")
if os.path.exists(mxp_filepath):
rt.pathConfig.load(mxp_filepath)
directory_count = rt.pathConfig.getProjectSubDirectoryCount()
for count in range(directory_count):
proj_dir = rt.pathConfig.getProjectSubDirectory(count)
if proj_dir:
os.makedirs(proj_dir, exist_ok=True)
rt.pathConfig.setCurrentProjectFolder(workdir)


def on_before_open():
"""Check and set up project before opening workfile
"""
_set_project()


def load_custom_attribute_data():
"""Re-loading the AYON custom parameter built by the creator
Expand Down
32 changes: 32 additions & 0 deletions client/ayon_max/hooks/pre_copy_mxp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from ayon_applications import PreLaunchHook, LaunchTypes
from ayon_max.mxp import create_workspace_mxp


class PreCopyMxp(PreLaunchHook):
"""Copy workspace.mxp to workdir.
Hook `GlobalHostDataHook` must be executed before this hook.
"""
app_groups = {"3dsmax", "adsk_3dsmax"}
launch_types = {LaunchTypes.local}

def execute(self):
max_setting = self.data["project_settings"]["max"]
mxp_workspace = max_setting.get("mxp_workspace")
# Ensure the hook would not cause possible error
# when using the old addon.
if mxp_workspace is None:
self.log.warning("No mxp workspace setting found in the "
"latest Max Addon.")
return
enabled_project_creation = mxp_workspace.get("enabled_project_creation")
if not enabled_project_creation:
self.log.debug("3dsmax project creation is not enabled. "
"Skipping creating workspace.mxp to workdir.")
return
workdir = self.launch_context.env.get("AYON_WORKDIR")
if not workdir:
self.log.warning("BUG: Workdir is not filled.")
return

create_workspace_mxp(workdir, mxp_workspace=mxp_workspace)
52 changes: 52 additions & 0 deletions client/ayon_max/mxp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import os
from ayon_core.lib import Logger


def create_workspace_mxp(workdir, mxp_workspace=None):
dst_filepath = os.path.join(workdir, "workspace.mxp")
if os.path.exists(dst_filepath):
return

log = Logger.get_logger("create_workspace_mxp")
max_script = default_mxp_template()
if mxp_workspace:
if not mxp_workspace.get("enabled_project_creation"):
log.debug("3dsmax project creation is disabled.")
return

max_script = mxp_workspace.get("mxp_workspace_script")
# Skip if mxp script in settings is empty
if not max_script:
log.debug("File 'workspace.mxp' not created. Settings value is empty.")
return

os.makedirs(workdir, exist_ok=True)
with open(dst_filepath, "w") as mxp_file:
mxp_file.write(max_script)

return dst_filepath


def default_mxp_template():
"""Return text script for the path configuration if
users do not enable project creation in AYON project
setting
"""
mxp_template = "\n".join((
'[Directories]',
'Animations= ./',
'Archives=./',
'AutoBackup=./',
'BitmapProxies=./',
'Fluid Simulations=./',
'Images=./',
'MaxStart=./',
'Previews=./',
'RenderAssets=./',
'RenderOutput= ./renders/3dsmax',
'Scenes=./',
'Sounds=./',
'[XReferenceDirs]',
'Dir1=./'
))
return mxp_template
35 changes: 35 additions & 0 deletions server/settings/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ def unit_scale_enum():
]


class MxpWorkspaceSettings(BaseSettingsModel):
enabled_project_creation: bool = SettingsField(
False, title="Enable Project Creation")
mxp_workspace_script: str = SettingsField(
title="Max mxp Workspace", widget="textarea"
)


class UnitScaleSettings(BaseSettingsModel):
enabled: bool = SettingsField(True, title="Enabled")
scene_unit_scale: str = SettingsField(
Expand All @@ -46,6 +54,10 @@ class MaxSettings(BaseSettingsModel):
default_factory=UnitScaleSettings,
title="Set Unit Scale"
)
mxp_workspace: MxpWorkspaceSettings = SettingsField(
default_factory=MxpWorkspaceSettings,
title="Max Workspace"
)
imageio: ImageIOSettings = SettingsField(
default_factory=ImageIOSettings,
title="Color Management (ImageIO)"
Expand All @@ -67,11 +79,34 @@ class MaxSettings(BaseSettingsModel):
title="Publish Plugins")


DEFAULT_MXP_WORKSPACE_SETTINGS = "\n".join((
'[Directories]',
'Animations= ./sceneassets/animations',
'Archives=./archives',
'AutoBackup=./autoback',
'BitmapProxies=./proxies',
'Fluid Simulations=./SimCache',
'Images=./sceneassets/images',
'MaxStart=./',
'Previews=./previews',
'RenderAssets=./sceneassets/renderassets',
'RenderOutput= ./renders/3dsmax',
'Scenes=./',
'Sounds=./sceneassets/sounds',
'[XReferenceDirs]',
'Dir1=./'
))


DEFAULT_VALUES = {
"unit_scale_settings": {
"enabled": True,
"scene_unit_scale": "Centimeters"
},
"mxp_workspace": {
"enabled_project_creation": False,
"mxp_workspace_script": DEFAULT_MXP_WORKSPACE_SETTINGS
},
"RenderSettings": DEFAULT_RENDER_SETTINGS,
"CreateReview": DEFAULT_CREATE_REVIEW_SETTINGS,
"PointCloud": {
Expand Down

0 comments on commit a7c2313

Please sign in to comment.