i created two plugins and i see an interesting thing, two family with one name in the list of instances: collect_rig.py
import pyblish.api
from maya import cmds
class CollectRig(pyblish.api.Collector):
"""Discover and collect available rigs into the context"""
hosts = ["maya"] # Only compatible with Maya
def process(self, context):
for node in cmds.ls(sets=True):
if not node.endswith("_RIG"):
continue
name = node.rsplit("_", 1)[0]
instance = context.create_instance(name, family="rig")
# Collect associated nodes
members = cmds.sets(node, query=True)
cmds.select([node] + members, noExpand=True)
instance[:] = cmds.file(
constructionHistory=True,
exportSelected=True,
preview=True,
force=True)
collect_rig_instance.py
import pyblish.api
from maya import cmds
class SelectRigInstance(pyblish.api.Selector):
hosts = ["maya"] # Only compatible with Maya
def process(self, context):
instance = context.create_instance(name="RigInstance")
# instance.set_data("family", "rig")
instance.data["family"] = "rig"
for node in cmds.ls():
instance.add(node)
To more easily find this thread while searching, I’ll throw in some additional keywords; duplicate families in gui, multiple section labels, sorting the context.
Actually you don’t want to put this in every plug-in. Just make a new SortCollector plug-in that runs last like order +0.1.
You’re using the python syntax for in-place list assignment with the context to override the data in the object itself.
context = [1, 2, 3]
This would make a new object and assign it to the context variable in the local space. The “new” assignment is important here, because that’s what the other one does different.
context[:] = [1, 2, 3]
Here the context object is still the same object in memory as opposed to instantiating a new object and using that. As such the contents of context are altered as opposed to assigning a new object purely to the name.
It’s more of a Python thing than a Pyblish thing. Just imagine you’re updating the context’ data so that it is sorted.
Pyblish tries to do it for you, but prioritizes being clear on the order of processing the plug-ins.
They are actually combined (visually under a header) only when “processed one after the other”. Since Pyblish’ order of processing for plug-ins is dependent of the order they are added in the context.
In your scenario you have two collectors collecting instances of family rig that run with the same order as other plug-ins. The same order means it’s somewhat undefined which must run first or last and as such no specific order is assumed. This means your two rigging collectors might not run right after each other, another collector could be running in-between. That’s exactly what’s happening.
You’re collecting:
set1 (rig)
MyInstance (default)
Maya_Instance (animate)
RigInstance (rig)
And this is stored in the context (as a list).
So you would have (somewhat simplified example here):
In this order even though set1 and RigInstance are both of family rig they cannot be grouped together because they don’t run one after the other. So @marcus solution is to “sort” the instances by family so they can always be grouped together.
Basically it is you taking control and telling it the order you prefer.
Theoretically you can sort it in any way you like and take full control over the order of the plug-ins if you need to. Again it’s something that Pyblish doesn’t try to make too much assumptions about.
Thanks you @tokejepsen
so if we use order = pyblish.api.Collector.order + 0.2 we don’t need to use context[:] = sorted(context, key=lambda i: i.data["family"])
yes?