Code Monkey home page Code Monkey logo

pyblish-magenta's Introduction

image

Magenta

A Maya-oriented validation kit for Pyblish.

Test-case: The Deal

On the official Pyblish forums we started developing a project as a test-case for Pyblish Magenta, more information here.

The Deal is a very short animated film developed in a community-driven way where anyone is allowed to jump right in and start working on assets, shots and the whole shebang.

Want to play? Get access to the dropbox folder for The Deal and start contributing!

pyblish-magenta's People

Contributors

bigroy avatar mottosso avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyblish-magenta's Issues

Validate rig performance

Goal

Depending on how many rigs are expected to perform simultaneously, the sum of rigs moving together must never exceed the real-time threshold.

For example, in a scene with two characters, 30 frames per second, rigs must perform at ~60 fps each.

Validate locked normals

Goal

A modeling validator looking for whether a mesh has locked normals, something that can cause trouble during rendering but primarily an annoyance for rigging/animation where the mesh appears dark in places that would logically be bright, and vice versa.

Maya Instance Browser

We'll need a way to update instances in Maya without fuzz.

It should handle:

  • Listing instances in the current scene
  • Visualising the current version from which an instance was made
  • Listing available versions of an asset per instance
  • Switching between versions

Visually it needn't be much more complicated than..

Source asset | Instance | Version
 _________________________________
|_________________________________|
|/ben////////| ben01    | v001    |
| chair      |/ben02////| v002    |
| table      |          | v003    |
| sofa       |          | v004    |
| gunA       |          | v005    |
| hand       |          | v006    |
|            |          | v007    |
|            |          | v008    |
|            |          | v009    |
|            |          | v010    |
|            |          |/v011////|
|            |          | v012    |
|____________|__________|_________|
|                         Update  |
|_________________________________|

Scene saved validator

Because UUIDs are written on scene-save, we'll need to be sure the scene actually has been saved before publishing.

Alembic Extractor specifying attributes in job string twice with list or tuple values

The Alembic Extractor parses the options in the wrong manner where any list values are also appended again as a string value since the if..else statement are wrong:

Problem:

        job_args = list()
        for key, value in options.iteritems():
            if isinstance(value, (list, tuple)):
                for entry in value:
                    job_args.append("-{0} {1}".format(key, entry))
            if isinstance(value, bool):
                job_args.append("-{0}".format(key))
            else:
                job_args.append("-{0} {1}".format(key, value))

The second if should be elif so that else doesn't get triggered if the first if is entered.

Validate non-zero vertices

Vertices can have positions that messes with subsequent deformers and are difficult to track down.

Make sure vertices are zeroed out.

Maya Asset Browser

We'll need a way to get assets into Maya without fuzz.

Responsibilities

It should handle:

  • Listing assets of the current project, e.g. thedeal/assets/*.*

  • Importing as referencing the selected asset

  • Append namespace to imported asset, e.g. ben_

  • Apply environment variables to absolute path, e.g. $PROJECTROOT/assets/...

  • Add data to reference node, for lazy referencing.

    project: "hulk"
    asset: "bruce"
    task: "animRig"
    family: "rig"
    instance: "bruce"
    version: "v032"

Graphics

Visually it needn't be much more complicated than..

 _____________________
|_____________________|
| ben                 |
| - model             |
| - rig               |
| jerry               |
| - model             |
| - rig               |
| chair               |
| - model             |
| - rig               |
| table               |
| - model             |
| - rig               |
|_____________________|
|               Load  |
|_____________________|

It's mostly about functionality at this point.

Concatenate pointcache hierarchies

The output of a rig is quite large, with a lot of empty parents.

image

One option is making the root of the hierarchy the same as what is coming in from modeling. In this case ben01_:ben_GRP.

That way, hierarchies are preserved and rigging can't accidentally add or remove anything. The downside is that sometimes rigging does need additional output, like collision meshes or guide locators for, say, tracking in After Effects.

An alternative is making output_GRP the root. This way, the original modeling hierarchy can be preserved, an artist has control over what is ultimately outputted without a giant parent hierarchy.

Validate bind-pose

Goal

To assert that a mesh with an envelope looks identical (within range) with or without the envelope when no animation has been applied to any of it's controllers.

Motivation

Sometimes, a controller may have gotten zeroed out when the envelope is still active, resulting in an offset when controls have been zeroed out. It's also a good indicator that one or more controllers are not in their default position/orientation.

Implementation

Randomly sample 3-4 global point-positions on relevant meshes and compare to positions of vertices on the envelope source (intermediate) mesh.

Additive and subtractive extraction

@BigRoy I mentioned during a previous chat something about "additive and subtractive extraction", and in light of this plug-in: validate_keys_none.py, I thought this might be a good time to elaborate on this concept.

Another way to put it is inclusive versus exclusive extraction, in which a plug-in either excludes unwanted data or includes only what is wanted.

For example, in validate_keys_none.py, animation keys are sought after and if any exists the Instance is invalid.

Instead, data can be excluded during extraction.

data

Let's assume this is our data.

data = {"vertices": list(), "userDefinedAttributes": list(), "keys": list()}

Inclusion

By not allowing certain data to be included, we would throw an error here.

if "keys" in data:
    raise Exception
else:
    export(data)

exclusion

By selectively include only wanted data, we would get the same output, without the need to throw an error.

export({
    "vertices": data["vertices"],
    "userDefinedAttributes": data["userDefinedAttributes"]
})

This technique might also be applicable to:

Implementation

In the case of Maya, cmds.file has an option to exclude e.g. constructionHistory.

cmds.file(exportSelected=True, constructionHistory=False)

Benefits

  • Simpler implementations
  • No risk of uncaught, yet invalid data during validation
  • Less user-facing errors

Disadvantages

  • The data in a user's scene differ from what is outputted

Encapsulating Collection

Goal

To capture everything during collection and to decouple validators from host.

Benefits

At the moment, Validators may validate things unrelated to an instance.

For example, in the case of a rig and a number of utility nodes, such as measurements, the utility nodes aren't included in the Instance and will not get extracted, yet they are still subject to validation as each Validator handles their own collection.

When centralised, measurements and other unrelated nodes can be explicitly discarded and thus never subject to validation. The concept can then extend into more advanced use, where the end result is an Instance that fully captures what the Instance represents.

Implementation

Currently, collectors gather a minimum amount of information in the scene, leaving most of the gathering to Validators.

For example, a validator could look like this.

for node in cmds.ls(type="mesh"):
  assert cmds.getAttr(node + ".color") == "green", "%s is not green" % node

Which manually gathers additional information beyond what is available form Collection. Instead, a validator could look like this.

for node in instance:
  assert node.color == "green", "%s is not green" % node

For which a Collector could look like this.

for node in cmds.ls():
  node = type("MayaNode", (object,), {})
  node.color = "green"
  instance.add(node)

color then represents static data to be validated at a later point.

Integrator file naming

The current Integrator is naming the integrated files based on the families of the extractor.

For example the output model, a mayaAscii file, gets saved to <asset>/publish/v001/model.ma.

By using this naming convention we introduce a couple of downsides:

  1. We can't have multiple extractors with a same family and extension to be integrated correctly at the same time. For example having two review cameras in the scene will extract both (with same extractor) but integrate only one (since it will overwrite the first with the last integrated since they have the same name). The same would also happen with two extractors extracting a single instance with a same extension.
  2. The files will be called model.ma, review.mov, review.gif, etc. Most applications will use solely the filename to display what file it is. For example when referencing the file in Maya the reference editor will solely display model. The same would be for video players solely showing review. It would be much clearer if they would also display the asset's name. Therefore it might make more sense to prepend filenames with the asset's name, like for character ben: ben_model.ma, ben_rig.ma and ben_review.mov.

The reference editor in an animation scene would then be able to show:

- ben_rig.ma
- window_model.mb
- gun_model.mb
- gun2_rig.mb

A custom UI could also solve this (and it should in the long run for managing references!), but since most applications show at least the file name I think it's great to have this information available to you even if you step into a custom viewer (eg. Quicktime, a browser, Maya or another tool not using a custom scripted interface for the pipeline).

I'm raising this issue to see if we can get to a better naming convention for our published files, or whether there are enough pros to stick with the current one.

What do you think?

Setting up "Getting Started" documentation

With the latest efforts into simplifying the core of the Collectors, Validators, Extractors and Integrators I think it's time to lay out a 5 minute how to get started page so anyone can hop in being productive directly.

It would be great to have people join the test-case The Deal and chopping away without missing vital information about the set-up.

Essential information would be:

  • How to get pyblish installed with pyblish_magenta
  • How to get be running with your project.
  • How the core of Magenta works
  • What folder structure we recommend (and use for The Deal)

Let's use this issue to pinpoint what information is critical for anyone (also those less technical) to get a 5-minute introduction and knowing exactly how to get started!

Public facing API

Based on the discussion on the Pyblish forum we'll work towards a public facing API for Pyblish Magenta and its plug-ins.

Goal

Define a public facing API that remains consistent throughout the development (as far as possible). For this I think it's best to introduce a 1-2 month evaluation period of our first effort into this change. This way it's clear what functions will remain consistent of the minimalistic pipeline we are setting up.

Implementation

The first change is to make the API accessible from pyblish_magenta.api to have a clear interface for the API functionality.


I'm opening this up as an issue to get this started and have clarity going forward.
Also this is a good place to raise the first requirements of functionality of the API.

The Collect, Extract and Integration chain

Goal

Decide upon the way forward for building new family types and how to implement its Collector, Extractor and possibly Integrator.

The main goal is to have a simple, consistent and strong solution that can be used throughout Magenta and also allows the plug-ins to be easily used in other packages.

Implementation

Our Integrator depends on knowing data about the Extracted content. It needs to know:

  • Where the files have been extracted to, the extractDir
  • Where the files need to be integrated to, the integrateDir

We also want to implement versioning. So that could be additional required data.

The extractDir data is defined in the Extractor (see plugin.py) and is a temporary directory. This sets up the dependency that any instance has only 1 extractDir. This would require to inherit from plugin.py.

The integrateDir is computed using the project's schema and data from the instance. That data is:

  • Any data that is required to format a path, like root, container and asset.
  • The family name is used to define what output template from the project's schema to use for formatting.

Currently I've separated how we inject data into the Instance by taking it from the Context. This way injecting this data into the instance does not need to be done from within each Collector. Have a look here: BigRoy/pyblish-magenta@b6e4d19

Though this will always override it for any instance that has been Collected, which might be more annoying than what we gain from removing this duplicity in code.


Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.