getavalon / core

The safe post-production pipeline - https://getavalon.github.io/2.0
MIT License
218 stars 48 forks source link

Allzparkalon #409

Open mottosso opened 5 years ago

mottosso commented 5 years ago

Goal

Implement final touches for compatibility with Allzpark.

Tasks

Overall it's quite compatible, with a few minor adjustments to the overall workflow.

See aforementioned website for details and background.

mottosso commented 5 years ago

Because Allzpark changes the fundamental nature of how a host is launched and assets specified with Avalon, we'll need to adjust how users interact with it.

Here's some ideas for how to accomplish that.

allzparkalon_mockup

Landing Screen

Upon entering a host, the Avalon Landing Screen appears.

It'll display three things.

  1. Your project, along with related graphics like icon, label and custom backdrop
  2. Your recent assets/tasks, as thumbnails
  3. Button for showing Context Manager, post-implementation of #412

Clicking on a recent item takes you immediately into the latest file for that task. The goal of this dialog is to get out of the way; it isn't the first time an artist launches this app, the only thing on their mind is to carry on with what they were doing the day before.

Context Manager+

Behind the Landing Screen is the new Context Manager.

This'll account for more complex choice, or first-choice. When a new task or project is started. It'll resemble Allzpark, but rather than changing project, it'll change asset, task and scene file.

It'll provide:

  1. Thumbnail per Project, Asset and Task, the latter two being editable by clicking
  2. Thumbnail from saved file
  3. Comment for saved file
  4. Metadata in sidepanel, such as:
    • Last modified
    • Who modified
    • Loaded representations, along with their state (imported/referenced)
    • Whether representations are of the latest versions (e.g. old rig)

Clicking on the asset or task brings up a floating tree-view of available assets, this is to fill in for what was provided by the Avalon Launcher, with visual hierarchy etc.

mottosso commented 5 years ago

Working Directories

Currently..

  1. You set your project
  2. You set the asset your working on
  3. You set the task

..from within the old Launcher before actually launching a host, like Maya.

The Launcher then does two things.

  1. Creates the working directory for said application, e.g. {project}/assets/{asset}/work/{task}/{app}
  2. Launches the application, preferably with this directory as the current directory

It can do that because it has all of the information, (1) project, (2) asset, (3) task and (4) application.

In the Colorbleed Config, users have the option to not only edit the task, but re-create this working directory post-launch, because the directory is (sometimes, depending on preference) relative the task.

Like Launcher, it has all the information and can perform this kind of action, but it means code is duplicated an so is responsibility. Now both the launcher and host requires access to the underlying application definition, both require relevant write-permissions and access to the same set of environment variables.

The way both of these determine what this path should look like, and what the missing pieces are, is..

  1. A configuration template, for the string with placeholders
  2. Environment variables for the values of those placeholders
  3. An application template for additional subdirectories of the final path, such as /scenes and /images in the case of Maya (default_dirs).


Adaptation

In order for Allzpark to accommodate for these, (1) and (2) can remain as-is, but as there is no more application template (replaced by Rez packages) default_dirs needs a new home.

Options

  1. Package environment variables
  2. Core Integration
  3. Config
  4. New class of plug-ins
Option 1 - Package environment variable
name = "maya"
version = "2019.3"

def commands():
  global env
  env["APPLICATION_DEFAULT_DIRS"] = "scenes;images;renders/comp;renders/lut"

Core could then query this variable for optional additional directories to create.

Option 2 - Core Integration

The Avalon core integration of a host like Maya determines what folders to generate per default, which can either remain fixed (do these default change often?) or customisable somehow. This would be the simplest option, but also least flexible (and implicit).

Option 3 - Config

The config provides an optional e.g. colorbleed.create_working_directory() function, that when isn't there is filled in with a core integration default. The function could query the current session for which application it's meant to create folders for.

Option 4 - Plug-in

Creating, Loading, Publishing and Managing content is currently governed by individual plug-ins, relative a particular "family" of data, such as model or pointcache. If this a good place for a plug-in relative an application?

class MayaPath(api.WorkingDirectory):
  apps = ["maya"]

  def process(self, config, context):
    import os

    template = config["template"]["work"]
    root = template.format(**context)
    os.makedirs(root)

    for dirname in ("scenes", "images", "renders"):
      abspath = os.path.join(root, dirname)
      os.makedirs(abspath)

    fname = os.path.join(root, "workspace.mel")
    with open(fname, "w") as f:
      f.write("""\
//Maya 2019 Project Definition

workspace -fr "mayaAscii" "scenes";
workspace -fr "shaders" "renderData/shaders";
""")

The advantage is uniformity with other plug-ins, at the cost of one more layer of plug-ins to manage. But then there's other paths, like where things go when you publish. There's currently no strict requirement for there to be exactly two paths; "work" and "publish" as the defaults are called. You could have any number of templates, or not use templates at all; handling paths in plug-ins in any way you want.

But applications do need a location to store its files, and output needs somewhere to go.

Maybe a more apt approach would be to have Template plug-ins?

Option 6 - Template Plug-ins

These would kick in whenever a template is used, for whatever purpose.

from avalon import api

class WorkTemplate(api.Template):
  templates = ["work"]

  def process(self, template, config, context):
    ...

class PublishTemplate(api.Template):
  templates = ["publish"]

  def process(self, template, config, context):
    ...

For example, from a loader plug-in.

def process(self, name, namespace, context):
  from avalon import api
  api.template(...)

No, that probaby doesn't make sense.. templates won't know about the app, other than by name.

Not 100% confident about the right approach here.