I am still in the process of learning Pyblish, now I am turning my head to our lookdev department.
I want to validate:
ShadingEngines
Meshes
Textures
So how should I collect them?
According to CVEI documentation, only Collectors should read data from the scene. So I should create instances for them and store the data in it.
So something like
instance = create_instance("spiderman_meshes", family="lookdev.meshes")
instance[:] = meshes
# ... same for textures and SEs
and match the family for each validator.
But as I understand, instances are basically the data that I want to export, so it should be one instance per asset.
You’re right, that’s ambiguous. The four stages of CVEI have a natural relationship that you are encouraged to exploit; in this case, it’s the relationship that collection collects information for you to use in subsequent stages. What these 2 points are awarded for is when plug-ins that go beyond this natural relationship become dependent on each other.
For example.
from pyblish import api
class CollectTransforms(api.ContextPlugin):
order = api.CollectorOrder
def process(self, context):
from maya import cmds
for assembly in cmds.ls(assemblies=True):
context.create_instance(assembly)
class CollectAttributes(api.ContextPlugin):
order = api.CollectorOrder
def process(self, context):
from maya import cmds
for instance in context:
instance.data["visibility"] = cmds.getAttr(
instance.data["name"] + ".visible")
In here you’ve made CollectAttributes dependent on CollectTransforms in that CollectTransforms is assumed to run first. The way you can guarantee this, is by tweaking the order variable.
class CollectAttributes(api.ContextPlugin):
order = api.CollectorOrder + 0.1
And viola, a dependency. Sometimes these are unavoidable (and sometimes even OK), but they are generally discouraged.
Thanks, @marcus!
This clarifies the plug-in dependency (maybe the documentation should be updated too).
So are you suggesting that my second solution is more appropriate?
BTW, I have a third one, which I like more:
In the collector I can collect all nodes that are used and taking part in the lookdev process, shaders, meshes, textures, etc.
instance = create_instance("spiderman", family="lookdev")
instance.data["nodes"] = nodes # all nodes used by the shaders
And then in the validators I can get the ones it is looking for:
for shading_engine in pm.ls(instance.data['nodes'], type='shadingEngine'):
# validate it
For nodes, I’d recommend adding them to the instance itself, like in your first example.
instance[:] = meshes
Then you can do…
for shading_engine in pm.ls(instance, type='shadingEngine'):
As the Instance object is subclassed from a typical Python list type. There isn’t nothing in Pyblish that assumes that you do, so either approach that makes the most sense to you is fine.
Conceptually, the instance is considered “the inverse of a file” as in, it should contain what you would get if you were to import the resulting published file. But also here it’s just a guideline and is mainly intended to simplify the vocabulary during conversations about publishing, such as this one.