pyblish / pyblish-magenta Goto Github PK
View Code? Open in Web Editor NEWMagenta kit for Pyblish
License: GNU Lesser General Public License v3.0
Magenta kit for Pyblish
License: GNU Lesser General Public License v3.0
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.
We'll need a way to get assets into Maya without fuzz.
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"
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.
They shouldn't be, right?
We'll need a way to update instances in Maya without fuzz.
It should handle:
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 |
|_________________________________|
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.
Because UUIDs are written on scene-save, we'll need to be sure the scene actually has been saved before publishing.
Based on the discussion on the Pyblish forum we'll work towards a public facing API for Pyblish Magenta and its plug-ins.
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.
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.
For some reason, moving meshes doesn't come along when wrapping it in a Maya scene.
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:
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?
Vertices can have positions that messes with subsequent deformers and are difficult to track down.
Make sure vertices are zeroed out.
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.
Our Integrator
depends on knowing data about the Extracted content. It needs to know:
extractDir
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:
root
, container
and asset
.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?
To capture everything during collection and to decouple validators from host.
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.
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.
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.
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.
Randomly sample 3-4 global point-positions on relevant meshes and compare to positions of vertices on the envelope source (intermediate) mesh.
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:
pyblish
installed with pyblish_magenta
be
running with your project.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!
The output of a rig is quite large, with a lot of empty parents.
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.
@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:
In the case of Maya, cmds.file
has an option to exclude e.g. constructionHistory
.
cmds.file(exportSelected=True, constructionHistory=False)
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.