Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separating Collectors + Extractor/Integrator separation for model #11

Merged
merged 8 commits into from
Jun 29, 2015
67 changes: 67 additions & 0 deletions pyblish_magenta/plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import os
import shutil
import tempfile
import contextlib

import pyblish.api
import pyblish_magenta.schema


class Extractor(pyblish.api.Extractor):
def temp_dir(self, instance):
"""Provide a (temporary) directory in which to store files"""
extract_dir = instance.data('extractDir')

if not extract_dir:
extract_dir = tempfile.mkdtemp()
instance.set_data('extractDir', value=extract_dir)

return extract_dir


class Integrator(pyblish.api.Integrator):

def compute_integrate_dir(self, instance):
# Get instance data
data = {'root': instance.data('root'),
'container': instance.data('container'),
'asset': instance.data('asset')}
family_id = instance.data('familyId')

if not family_id:
raise pyblish.api.ConformError("No family id found on instance. Can't resolve asset path.")

# Get asset directory
schema = pyblish_magenta.schema.load()
output_template = "{0}.asset".format(family_id)
dir_path = schema.get(output_template).format(data)

return dir_path

def integrate(self, instance):

extract_dir = instance.data('extractDir')
if not extract_dir:
raise pyblish.api.ConformError("Cannot integrate if no `commitDir`"
" temporary directory found.")

integrate_dir = self.compute_integrate_dir(instance)

self.log.info("Integrating extracted files for '{0}'..".format(instance))

if os.path.isdir(integrate_dir):
self.log.info("Existing directory found, merging..")
for fname in os.listdir(extract_dir):
abspath = os.path.join(extract_dir, fname)
commit_path = os.path.join(integrate_dir, fname)
shutil.copy(abspath, commit_path)
else:
self.log.info("No existing directory found, creating..")
shutil.copytree(extract_dir, integrate_dir)

# Persist path of commit within instance
instance.set_data('integrateDir', value=integrate_dir)

self.log.info("Integrated to directory '{0}'".format(integrate_dir))

return integrate_dir
40 changes: 40 additions & 0 deletions pyblish_magenta/plugins/collect_asset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import pyblish.api
import pyblish_magenta.schema


@pyblish.api.log
class CollectAsset(pyblish.api.Collector):
order = pyblish.api.Collector.order + 0.1

def process(self, context):
self.log.info("Collecting Asset..")

work_file = context.data('workFile')
if not work_file:
return

# Ensure we use a path with forward slashes
work_file = work_file.replace('\\', '/')

# Parse with schema
schema = pyblish_magenta.schema.load()
data, template = schema.parse(work_file)

# Note that this the family id retrieved from the template.
# This is not a one-to-one copy of the 'family' used in the plug-ins.
# That's why we store this information as 'familyId' to avoid confusion
family_id = template.name.split('.')[0]
context.set_data('familyId', family_id)

# Store the project root's path
root = data['root']
context.set_data('root', root)

# Store the asset name
asset = data['asset']
context.set_data('asset', asset)

# Store the container's name
container = data['container']
context.set_data('container', container)

26 changes: 26 additions & 0 deletions pyblish_magenta/plugins/collect_conceptart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import os
import pyblish.api


@pyblish.api.log
class CollectConceptArt(pyblish.api.Collector):
"""
Collect Concept Art files from the current work directory.

Any `.png` files in the `cwd` are considered to be artwork.
"""
def process(self, context):
self.log.info("Selecting concept art..")

cwd = context.data("cwd")
for fname in os.listdir(cwd):
if fname.lower().endswith(".png"):
name = os.path.basename(fname.rsplit(".", 1)[0])

self.log.info("Creating instance: %s" % name)
instance = context.create_instance(name)

# Capture certain characteristics for validation
instance.set_data("family", "conceptArt")
instance.set_data("path", os.path.join(context.data("cwd"), fname))
instance.set_data("bytes", os.stat(fname).st_size)
27 changes: 27 additions & 0 deletions pyblish_magenta/plugins/collect_maya_current_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import os

import pyblish.api

from maya import cmds


@pyblish.api.log
class CollectMayaCurrentFile(pyblish.api.Collector):
hosts = ["maya"]

def process(self, context):
self.log.info("Collecting Maya Work File..")

# File Path
# ---------
current_file = cmds.file(q=1, sceneName=True)
if not current_file:
# file not saved
self.log.error("Scene has not been saved.")
return

# Maya returns forward-slashes by default
current_file = os.path.normpath(current_file)

context.set_data('workFile', value=current_file)

Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import pyblish.api

from maya import cmds
from maya import mel
import pyblish.api


@pyblish.api.log
class SelectMayaUnits(pyblish.api.Selector):
""" Select Maya's scene units. """
order = pyblish.api.Selector.order + 0.1
class CollectMayaUnits(pyblish.api.Selector):
""" Collect Maya's scene units. """
order = pyblish.api.Selector.order
hosts = ["maya"]
families = ['model', 'rig', 'anim', 'layout']

def process(self, context):

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import os.path

from maya import cmds
import pyblish.api

import pyblish_magenta.schema
from maya import cmds


def get_all_parents(long_name):
Expand All @@ -12,30 +9,30 @@ def get_all_parents(long_name):


@pyblish.api.log
class SelectModelInstance(pyblish.api.Selector):
class CollectModel(pyblish.api.Collector):
""" Inject all models from the scene into the context (if in modeling workspace)

.. note:: This skips intermediate objects.
"""
order = pyblish.api.Collector.order + 0.2
hosts = ["maya"]

def process(self, context):
self.log.info("Selecting model..")

# File Path
# ---------
scene_name = cmds.file(q=1, sceneName=True)
if not scene_name:
# file not saved
self.log.error("Scene has not been saved.")
# Check whether to select a model
# -------------------------------
# Ensure we're in the modeling context
family_id = context.data('familyId')
if not family_id or family_id != 'model':
return

# Parse with schema
schema = pyblish_magenta.schema.load()
data = schema.get("model.dev").parse(scene_name)
root = data['root']
asset = data['asset']
container = data['container']
# Get the root, asset and container information and ensure data is there.
root = context.data('root')
asset = context.data('asset')
container = context.data('container')
if not all([root, asset, container]):
return

# Scene Geometry
# --------------
Expand All @@ -60,13 +57,14 @@ def process(self, context):
# Create Asset
# ------------
instance = context.create_instance(name=asset,
familyId=family_id,
family='model')
for node in nodes:
instance.add(node)

# Set Pipeline data
# Set instance pipeline data
instance.set_data("root", root)
instance.set_data("source_file", scene_name)
instance.set_data("workFile", context.data('workFile'))
instance.set_data("asset", asset)
instance.set_data("container", container)

62 changes: 62 additions & 0 deletions pyblish_magenta/plugins/extract_gif.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import os
import shutil
import tempfile
import subprocess
import pyblish.api


class ExtractGif(pyblish.api.Extractor):
families = ["review"]
optional = True
order = pyblish.api.Extractor.order + 0.1

def process(self, context, instance):
output_path = instance.data("outputPath")
if not output_path:
return self.log.info("No capture available for conversion.")

self.log.info("Generating gif from %s" % output_path)

fps = context.data("fps") or 24
width = context.data("width") or 512

generate_palette = ("ffmpeg -y -i {input} -vf "
"\"fps={fps},scale={width}:-1:flags=lanczos,palettegen\" "
"{palette}")

generate_gif = ("ffmpeg -y -i {input} -i {palette} -filter_complex "
"\"fps={fps},scale={width}:-1:flags=lanczos[x];[x][1:v]paletteuse\" "
"{output}")
try:
tempdir = tempfile.mkdtemp()
palette = os.path.join(tempdir, "palette.png")
output = output_path.rsplit(".", 1)[0] + ".gif"
self.log.info("Outputting to %s" % output)

try:
output_ = subprocess.check_output(
generate_palette.format(
input=output_path,
fps=fps,
width=width,
palette=palette))
except subprocess.CalledProcessError:
self.log.warning(output_)
return self.log.warning("Could not generate palette")

try:
output_ = subprocess.call(
generate_gif.format(
input=output_path,
fps=fps,
width=width,
palette=palette,
output=output))
except subprocess.CalledProcessError:
self.log.warning(output_)
return self.log.warning("Could not generate gif")

finally:
shutil.rmtree(tempdir)

self.log.info("Finished successfully")
20 changes: 6 additions & 14 deletions pyblish_magenta/plugins/extract_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,29 @@

# local lib
from pyblish_magenta.utils.maya.exporter import MayaExporter
import pyblish_magenta.schema
import pyblish_magenta.plugin


@pyblish.api.log
class ExtractModel(pyblish.api.Extractor):
class ExtractModel(pyblish_magenta.plugin.Extractor):
""" Exports all nodes """
hosts = ["maya"]
families = ["model"]
optional = True

def process(self, instance):

# Get instance data
data = {'root': instance.data('root'),
'container': instance.data('container'),
'asset': instance.data('asset')}

# Get output directory
schema = pyblish_magenta.schema.load()
dir_path = schema.get("model.asset").format(data)

# Get output filename
# Define extract output file path
dir_path = self.temp_dir(instance)
filename = "{0}.ma".format(instance.name)

path = os.path.join(dir_path, filename)

# Define extract nodes
export_nodes = mc.ls(instance, long=True)

if not export_nodes:
raise RuntimeError("Nothing to export")

# Perform extraction
MayaExporter.export(path, export_nodes,
preserveReferences=False, constructionHistory=False,
expressions=False, channels=False,
Expand Down