Ejemplo n.º 1
0
def disable_in_camera_only(palette):
    """
    Args:
        palette (str): XGen Legacy palette name
    """
    palette = str(palette)
    for description in list_descriptions(palette):
        prev = xg.getActive(palette, description, "Previewer")
        if xg.attrExists("inCameraOnly", palette, description, prev):
            xg.setAttr("inCameraOnly", "false", palette, description, prev)
Ejemplo n.º 2
0
def disable_tube_shade(palette):
    """
    Args:
        palette (str): XGen Legacy palette name
    """
    palette = str(palette)
    for description in list_descriptions(palette):
        prim = xg.getActive(palette, description, "Primitive")
        if xg.attrExists("tubeShade", palette, description, prim):
            xg.setAttr("tubeShade", "false", palette, description, prim)
Ejemplo n.º 3
0
	def descControlMethod(self, palName, descName):
		"""
		Find out what instance method used by description to control primitives,
		and return type name:
			'Guides'
			'Attribute'
			'Groom'
		"""
		# check instance method
		primitive = xg.getActive(palName, descName, 'Primitive')
		if xg.getAttr('iMethod', palName, descName, primitive):
			return 'Guides'
		else:
			if xg.getAttr('groom', palName, descName):
				return 'Groom'
			else:
				return 'Attribute'
Ejemplo n.º 4
0
def description_ctrl_method(description):
    """
    Find out what instance method used by description to control primitives,
    and return type name:
        'Guides'
        'Attribute'
        'Groom'
    """
    palette = get_palette_by_description(description)
    primitive = xg.getActive(palette, description, "Primitive")

    if xg.getAttr("iMethod", palette, description, primitive) == "1":
        return "Guides"
    else:
        # iMethod == "0"
        if xg.getAttr("groom", palette, description):
            return "Groom"
        else:
            return "Attribute"
Ejemplo n.º 5
0
def parse_objects(map_attr):
    """Parse attribute returned from `filePathEditor` into XGen object names

    (NOTE) Remember to refresh filePathEditor by calling
           `cmds.filePathEditor(refresh=True)`, or the
           fxmodule index might not return correctly.

    >>> cmds.filePathEditor(refresh=True)
    >>> maps = cmds.filePathEditor(q=1, listFiles="", withAttribute=1)
    ["descriptionShape.primitive.ClumpingFXModule(1).HeadPoint", ...]
    >>> parse_objects(maps[0])
    ('CY_Mon_Hair', 'description', 'Clumping2', 'pointDir', 0)

    Args:
        map_attr (str): An attribute path returned from `cmds.filePathEditor`

    Returns:
        tuple: Names of palette, description, object, attr, attr-index

    """
    address = map_attr.split(".")

    # The description shape name in `map_attr` string is a short name,
    # and since we only need the description transform short name, it
    # doesn't matter which shape node we get from `cmds.ls`.
    desc_shape = cmds.ls(address[0])[0]
    description = str(cmds.listRelatives(desc_shape,
                                         parent=True)[0])  # get short name
    palette = get_palette_by_description(description)

    if address[1] == "glRenderer":
        subtype = "GLRenderer"
    else:
        # primitive, generator
        subtype = xg.getActive(palette, description,
                               str(address[1].capitalize()))

    if len(address) < 4:
        # Example: descriptionShape.generator.mask

        attr = address[2]
        attr, attr_indx = _parse_attribute(attr, subtype)

        return palette, description, subtype, attr, attr_indx

    else:
        # Example: descriptionShape.primitive.ClumpingFXModule(1).HeadPoint

        modifier_cls, mod_indx = address[2][:-1].split("(")
        mod_indx = int(mod_indx)

        attr = address[3]
        attr, attr_indx = _parse_attribute(attr, subtype)

        try:
            module = xg.fxModules(palette, description)[mod_indx]
        except IndexError:
            raise IndexError("Object not found, possible `filePathEditor` "
                             "not refreshed: {}".format(map_attr))
        else:
            if xg.fxModuleType(palette, description, module) == modifier_cls:

                return palette, description, module, attr, attr_indx

        raise Exception("Object not found, this is a bug: {}".format(map_attr))
Ejemplo n.º 6
0
	def exportFullPackage(self, palName, version, bake= False, anim= False):
		"""
		Export Palettes, Descriptions, Grooming, Guides, all together,
		even bake modifiers befoer export if needed.
		"""
		self.clearPreview()
		
		# bake modifiers
		generator = {}
		if bake:
			for desc in xg.descriptions(palName):
				# bake Noise modifiers
				# fxModules evals from bottom to top
				clumpModLast = ''
				for fxm in xg.fxModules(palName, desc):
					if xg.fxModuleType(palName, desc, fxm) == 'ClumpingFXModule':
						# set the top clumpingMod cvAttr to True, for anim modifiers which needs clump
						if clumpModLast:
							xg.setAttr('cvAttr', 'false', palName, desc, clumpModLast)
						xg.setAttr('cvAttr', 'true', palName, desc, fxm)
						clumpModLast = fxm
					if xg.fxModuleType(palName, desc, fxm) == 'NoiseFXModule':
						# temporarily turn off lod so we dont bake it in
						lod = xg.getAttr('lodFlag', palName, desc)
						xg.setAttr('lodFlag', 'false', palName, desc)
						# change mode for bake
						xg.setAttr('mode', '2', palName, desc, fxm)
						# bake the noise
						pm.mel.xgmNullRender(pb= desc)
						# restore
						xg.setAttr('lodFlag', lod, palName, desc)
						# change mode to baked
						xg.setAttr('mode', '1', palName, desc, fxm)
				# bake groom modifiers
				fxm = xg.addFXModule(palName, desc, 'BakedGroomManagerFXModule')
				xg.setAttr('active', 'true', palName, desc, fxm)
				xg.bakedGroomManagerBake(palName, desc)
				# set Generator to XPD
				generator[desc] = xg.getActive(palName, desc, 'Generator')
				xg.setActive(palName, desc, 'FileGenerator')
		
		# change to export version path and keep current
		workPath = xg.getAttr('xgDataPath', palName)
		workProj = xg.getAttr('xgProjectPath', palName)
		xg.setAttr('xgDataPath', self.paletteVerDir(palName, version, raw= True), palName)
		xg.setAttr('xgProjectPath', self.projPath, palName)
		# get resolved repo path
		dataPath = self.paletteVerDir(palName, version)

		# set [xgDogTag] attr for ANIM record branchName
		if anim:
			xg.setAttr('xgDogTag', version, palName)

		# export descriptions
		for desc in xg.descriptions(palName):
			dstDescDir = xg.expandFilepath('${DESC}', desc, True, True)
			expPath = dstDescDir + desc + '.xdsc'
			xg.exportDescription(palName, desc, expPath)
			# copy map files
			srcDescVar = workPath.replace('${PROJECT}', workProj) + '/${DESC}'
			srcDescDir = xg.expandFilepath(srcDescVar, desc)
			for mapDir in os.listdir(srcDescDir):
				srcMap = os.path.join(srcDescDir, mapDir)
				dstMap = os.path.join(dstDescDir, mapDir)
				if os.path.isdir(srcMap):
					dir_util._path_created = {}
					dir_util.copy_tree(srcMap, dstMap)

		# export palettes
		expPath = dataPath + '/' + palName + '.xgen'
		xg.exportPalette(palName, expPath)

		# export grooming
		for desc in xg.descriptions(palName):
			igdesc = xg.getAttr('groom', palName, desc)
			if igdesc:
				expPath = xg.expandFilepath('${DESC}/groom', desc, True, True)
				tpu = 5
				sampling = 1
				igDescr = xg.igDescription(desc)
				# export Attribute Map
				try:
					pm.waitCursor(state= True)
					# may have .ptx file handle lock issue
					pm.mel.iGroom(exportMaps= expPath, texelsPerUnit= tpu,
						instanceMethod= sampling, description= igDescr)
				finally:
					pm.waitCursor(state= False)
				# export Mask
				try:
					pm.waitCursor(state= True)
					# may have .ptx file handle lock issue
					pm.mel.iGroom(exportMask= expPath, texelsPerUnit= tpu,
						description= igDescr)
				finally:
					pm.waitCursor(state= False)
				# export Region
				try:
					pm.waitCursor(state= True)
					# may have .ptx file handle lock issue
					pm.mel.iGroom(exportRegion= expPath, texelsPerUnit= tpu,
						description= igDescr)
				finally:
					pm.waitCursor(state= False)
				# export Settings
				jsonPath = expPath + 'groomSettings.json'
				groomSettings = {}.fromkeys(['density', 'length', 'width'])
				for key in groomSettings:
					groomSettings[key] = pm.getAttr(igdesc + '.' + key)
				with open(jsonPath, 'w') as jsonFile:
					json.dump(groomSettings, jsonFile, indent=4)

		# export guides
		with undoable('exportGuides'):
			for desc in xg.descriptions(palName):
				# listGuides
				guides = xg.descriptionGuides(desc)
				if not guides:
					continue
				expPath = xg.expandFilepath('${DESC}', desc)
				pm.select(guides, r= 1)
				# guides to curves
				curves = pm.mel.xgmCreateCurvesFromGuides(0, True)
				# export as alembic
				if not pm.pluginInfo('AbcExport', q= 1, l= 1):
					pm.loadPlugin('AbcExport')
				abcCmds = '-frameRange 1 1 -uvWrite -worldSpace -dataFormat ogawa '
				abcRoot = '-root ' + ' -root '.join([cur.longName() for cur in pm.ls(curves)])
				abcPath = expPath + 'curves.abc'
				pm.mel.AbcExport(j= abcCmds + abcRoot + ' -file ' + abcPath)

		if anim:
			# save out hairSystem preset
			presetMel = []
			for nodeType in ['nucleus', 'hairSystem', 'nRigid']:
				presetDict = self.ioAttrPreset(nodeType, True)
				presetMel.extend(presetDict.values())
			# move preset file to version repo
			presetRepo = self.nDynPresetPath(palName, version)
			if not os.path.exists(presetRepo):
				os.makedirs(presetRepo)
			for prs in presetMel:
				dstPath = '/'.join([presetRepo, os.path.basename(prs)])
				shutil.move(prs, dstPath)
			# create empty _shot_ folder
			shotDir = self.paletteDeltaDir(palName, version, '')
			if not os.path.exists(shotDir):
				os.makedirs(shotDir)

		# export snapshot
		for i in range(5):
			tmpPath = self.snapshotTmp % (i+1)
			if os.path.isfile(tmpPath):
				imgPath = self.snapshotImgPath(palName, version, str(i+1))
				if not os.path.exists(os.path.dirname(imgPath)):
					os.makedirs(os.path.dirname(imgPath))
				shutil.move(tmpPath, imgPath)

		# restore dataPath
		xg.setAttr('xgDataPath', workPath, palName)
		xg.setAttr('xgProjectPath', workProj, palName)

		# restore modifiers
		if bake:
			for desc in xg.descriptions(palName):
				# bake Noise modifiers
				for fxm in xg.fxModules(palName, desc):
					if xg.fxModuleType(palName, desc, fxm) == 'NoiseFXModule':
						# restore to live mode
						xg.setAttr('mode', '0', palName, desc, fxm)
				# remove bake groom modifiers
				for fxm in xg.fxModules(palName, desc):
					if xg.fxModuleType(palName, desc, fxm) == 'BakedGroomManagerFXModule':
						xg.removeFXModule(palName, desc, fxm)
				# restore Generator
				xg.setActive(palName, desc, generator[desc])

		self.refresh('Full')

		self.notifyMsg('Collection Export Complete !', 0)

		return True