Before we move on, let me throw you into the deep end and show you a full example.
Don't worry too much if it doesn't make sense just now, the rest of the examples are dedicated to explaining each feature in great detail.
The examples will be written primarily for Autodesk Maya, but should be easily readable and it's concepts applicable to any 3d content creation software. There is a slight simplification involved, for more clarity, but overall this represents a real-world implementation of a fully featured publishing pipeline with Pyblish.
The Deep End
The example uses the 2 available superclasses in Pyblish - ContextPlugin and InstancePlugin. The order in which these plug-ins are run is controlled by an integer attribute called order, with 4 default values.
Collection
Validation
Extraction
Integration
1. collect_rig.py
Gather information to validate and export.
import pyblish.apifrom maya import cmdsclassCollectRig(pyblish.api.ContextPlugin):"""Discover and collect available rigs into the context""" order = pyblish.api.CollectorOrderdefprocess(self,context):for node in cmds.ls(sets=True):ifnot 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)
2. validate_rig.py
Ensure the correctness of collected information.
import pyblish.apiclassValidateRigContents(pyblish.api.InstancePlugin):"""Ensure rig has the appropriate object sets""" order = pyblish.api.ValidatorOrder families = ["rig"]defprocess(self,instance):assert"controls_SEL"in instance,"%s is missing a controls set"% instanceassert"pointcache_SEL"in instance,"%s is missing a pointcache set"% instance
3. extract_rig.py
Write to disk.
import osimport shutilfrom datetime import datetimeimport pyblish.apifrom maya import cmdsclassExtractRig(pyblish.api.InstancePlugin):"""Serialise valid rig""" order = pyblish.api.ExtractorOrder families = ["rig"] hosts = ["maya"]defprocess(self,instance): context = instance.context dirname = os.path.dirname(context.data["currentFile"]) name, family = instance.data["name"], instance.data["family"] date = datetime.now().strftime("%Y%m%dT%H%M%SZ")# Find a temporary directory with support for publishing multiple times. tempdir = os.path.join(dirname, "temp", date, family, name) tempfile = os.path.join(tempdir, name +".ma") self.log.info("Exporting %s to %s"% (instance, tempfile))ifnot os.path.exists(tempdir): os.makedirs(tempdir) cmds.select(instance, noExpand=True)# `instance` a list cmds.file(tempfile, type="mayaAscii", exportSelected=True, constructionHistory=False, force=True)# Store reference for integration instance.set_data("tempdir", tempdir)
4. integrate_rig.py
Integrate written information into the pipeline, as per convention.
import osimport shutilimport pyblish.apiclassIntegrateRig(pyblish.api.InstancePlugin):"""Copy files to an appropriate location where others may reach it""" order = pyblish.api.IntegratorOrder families = ["rig"]defprocess(self,instance):assert instance.data("tempdir"),"Can't find rig on disk, aborting.." self.log.info("Computing output directory..") context = instance.context dirname = os.path.dirname(context.data("currentFile")) root = os.path.join(dirname, "public")ifnot os.path.exists(root): os.makedirs(root) version ="v%03d"% (len(os.listdir(root))+1) src = instance.data("tempdir") dst = os.path.join(root, version) self.log.info("Copying %s to %s.."% (src, dst)) shutil.copytree(src, dst) self.log.info("Copied successfully!")
That's a lot
I'm sure you have lots of questions, but don't worry. This is the part where we dig into exactly how we get to this point, and what all of this really means.
Test it out
It isn't necessary to run this on your own, but if you want to give it a try, here's what you do.