コード例 #1
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
    def exportCurves(descName, fxmName):
        # setup
        value = xg.getAttr("exportDir", palette, descName, fxmName)
        xg.setAttr("exportDir", str(value), palette, descName, fxmName)
        xg.setAttr("exportCurves", "true", palette, descName, fxmName)

        # Need to fill in the export faces to correct value
        xg.setAttr("exportFaces", "", palette, descName, fxmName)

        # export clumpCurves.mel
        pmc.mel.xgmNullRender(descName, percent=0)

        # get clumpCurves.mel file path
        curvesMelPath = xg.getAttr("_fullExportDir", palette, descName,
                                   fxmName)

        # Remove clumpCurves.mel's last cmd : "xgmMakeCurvesDynamic;"
        print("Reading curves mel. -> %s" % curvesMelPath)
        with open(curvesMelPath, "r") as mel_script:
            curvesMel = mel_script.readlines()
        cmdIndex = curvesMel.index("xgmMakeCurvesDynamic;\n")
        curvesMel[cmdIndex] = ""

        # execute it, and we will run our MakeCurvesDynamic later
        pmc.mel.eval("".join(curvesMel))
        # restore
        xg.setAttr("exportCurves", "false", palette, descName, fxmName)
        xg.setAttr("exportFaces", "", palette, descName, fxmName)
コード例 #2
0
    def importDescription(self, palName, descName, version, binding=False):
        """
		XGen description will imported without validator.
		When importing baked description, @binding set to False should be fine.
		"""
        xdscFileName = descName + '.xdsc'
        xdscFile = '/'.join(
            [self.paletteVerDir(palName, version), descName, xdscFileName])
        if not os.path.isfile(xdscFile):
            pm.error('[XGen Hub] : .xdsc file is not exists. -> ' + xdscFile)
            return None

        self.clearPreview()

        # check if descriptions exists in current scene
        if descName in xg.descriptions(palName):
            # delete current description folder
            descDir = xg.expandFilepath('${DESC}', descName)
            if os.path.isdir(descDir):
                try:
                    dir_util.remove_tree(descDir)
                except:
                    pm.warning('[XGen Hub] : Dir may not remove. -> ' +
                               descDir)
            # delete current description
            xg.deleteDescription(palName, descName)
        # IMPORT DESCRIPTION
        desc = base.importDescription(palName, xdscFile)
        # create imported descriptions folder
        dataPath = xg.getAttr('xgDataPath', palName)
        paletteRoot = xg.expandFilepath(dataPath, '')
        msxgApi.setupDescriptionFolder(paletteRoot, palName, desc)
        # wrap into maya nodes
        pm.mel.xgmWrapXGen(pal=palName, d=desc, gi=binding)
        # bind to selected geometry
        if binding:
            igdesc = xg.getAttr('groom', palName, desc)
            xg.modifyFaceBinding(palName, desc, 'Append', '', False,
                                 len(igdesc))
            if igdesc:
                # set groom density and sampling method
                pm.setAttr(igdesc + '.density', 1)
                pm.setAttr(igdesc + '.interpStyle', 1)

            # import grooming as well
            self.importGrooming(palName, descName, version)
        # import guides as well
        self.importGuides(palName, descName, version)

        self.notifyMsg('Description Import Complete !', 0)

        return desc
コード例 #3
0
    def importAnimResult(self, palName, version, shotName):
        """
		"""
        self.clearPreview()

        # get delta .xgd file
        deltaPath = self.paletteDeltaDir(palName, version, shotName)
        deltaFile = '/'.join([deltaPath, palName + '.xgd'])

        # import
        if os.path.isfile(deltaFile):
            if not self.importPalette(palName, version, False, False, True,
                                      [deltaFile]):
                return None
        else:
            pm.error('[XGen Hub] : .xgd file not exists. Import stopped. -> ' +
                     deltaFile)
            return None

        # get wires.abc
        wiresAbc = {}
        for abc in os.listdir(deltaPath):
            abcPath = '/'.join([deltaPath, abc])
            if os.path.isfile(abcPath):
                descName = abc.split('.')[0]
                wiresAbc[descName] = str(abcPath)
        # animWire turn off live mode to read .abc
        for desc in [
                desc for desc in wiresAbc if desc in xg.descriptions(palName)
        ]:
            for fxm in [
                    fxm
                    for fxm in xg.fxModules(palName, desc) if xg.fxModuleType(
                        palName, desc, fxm) == 'AnimWiresFXModule'
            ]:
                if xg.getAttr('active', palName, desc, fxm) == 'true':
                    xg.setAttr('liveMode', 'false', palName, desc, fxm)
                    xg.setAttr('wiresFile', wiresAbc[desc], palName, desc, fxm)

        # set ref frame
        self.setRefWiresFrame(xg.getAttr(self.xgRefFrame, palName))

        # assign shaders

        # render settings
        self.xgOutputSettings(palName)

        self.refresh('Full')

        self.notifyMsg('Anim Result Import Complete !', 0)

        return True
コード例 #4
0
ファイル: Xgen.py プロジェクト: jonntd/mira
    def set_abs_path(self, xgen_dir):
        if not xgg.Maya:
            return
        # palette is collection, use palettes to get collections first.
        palettes = xgen.palettes()
        for palette in palettes:
            # Use descriptions to get description of each collection
            descriptions = xgen.descriptions(palette)
            for description in descriptions:
                commaon_objs = xgen.objects(palette, description, True)
                fx_objs = xgen.fxModules(palette, description)
                objs = commaon_objs + fx_objs
                # Get active objs,e.g. SplinePrimtives
                for obj in objs:
                    attrs = xgen.allAttrs(palette, description, obj)
                    for attr in attrs:
                        value = xgen.getAttr(attr, palette, description, obj)
                        if "${DESC}" in value:
                            print palette, description, obj, attr
                            description_dir = os.path.join(xgen_dir, "collections", palette, description).replace("\\", "/")
                            new_value = value.replace("${DESC}", description_dir)
                            xgen.setAttr(attr, new_value, palette, description, obj)

        de = xgg.DescriptionEditor
        de.refresh("Full")
コード例 #5
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
def parse_map_path(map_attr):
    """Parse attribute returned from `filePathEditor` into file path

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

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

    Returns:
        str: File path
        tuple: Name of the attribute and it's parent objects

    """
    palette, description, obj, attr, index = parse_objects(map_attr)

    expr_maps = parse_expr_maps(attr, palette, description, obj)

    if not expr_maps:
        # Not expression type
        path = xg.getAttr(attr, palette, description, obj)
    else:
        path = expr_maps[index].file

    parents = (palette, description, obj, attr, index)

    return path, parents
コード例 #6
0
def get_xgen(task_id):
    _xgen_ = []
    _file_name = cmds.file(q=True, sceneName=True)
    _file_path = os.path.dirname(_file_name)
    if not xgg.Maya:
        return _xgen_
    _all_palettes = xg.palettes()
    _task = zfused_api.task.Task(task_id)
    _task_project_entity = _task.project_entity()
    _task_production_path = _task.production_path()
    # for _palette in _all_palettes:
    #     _palette_dict ={}
    #     _palette_xgen_filename =cmds.getAttr('{}.xgFileName'.format(_palette))
    #     _palette_path =os.path.join(_file_path,_palette_xgen_filename)
    #     _palette_date =xg.getAttr('xgDataPath',_palette)
    #     _palette_dict['_palette_name'] = _palette
    #     _palette_dict['_palette_path'] = _palette_path
    #     _palette_dict['_palette_date'] = _palette_date
    for _palette in _all_palettes:
        _palette_dict = {}
        _palette_xgen_filename = cmds.getAttr('{}.xgFileName'.format(_palette))
        _palette_path = os.path.join(_task_production_path,
                                     _palette_xgen_filename).replace(
                                         '\\', '/')
        _palette_date = xg.getAttr('xgDataPath', _palette)
        _palette_dict['_palette_name'] = _palette
        _palette_dict['_palette_path'] = _palette_path
        _palette_dict['_palette_date'] = _palette_date
        _xgen_.append(_palette_dict)
    return _xgen_
コード例 #7
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'
コード例 #8
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
def current_data_paths(palette, expand=False):
    paths = list()
    for path in xg.getAttr("xgDataPath", palette).split(";"):
        if expand:
            path = xg.expandFilepath(str(path), "")
        path = os.path.normpath(path).replace("\\", "/")
        paths.append(path)
    return paths
コード例 #9
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
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"
コード例 #10
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
def get_groom(description):
    """Return description's grooming node

    Args:
        description (str): XGen Legacy description name

    Returns:
        (str)

    """
    palette = get_palette_by_description(description)
    return xg.getAttr("groom", palette, description)
コード例 #11
0
    def get_invalid(cls, instance):
        import xgenm as xg

        invalid = list()

        for description in instance.data["xgenDescriptions"]:
            palette = xg.palette(description)
            percent = float(
                xg.getAttr("percent", palette, description, "GLRenderer"))
            if not percent == 100:
                invalid.append(description)

        return invalid
コード例 #12
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
    def attachSlot(palette, desc, fxmName, descHairSysName):
        if not (str(xg.fxModuleType(palette, desc, fxmName))
                == "AnimWiresFXModule"):
            return

        refwFrame = xg.getAttr("refWiresFrame", palette, desc, fxmName)
        if str(xg.getAttr("liveMode", palette, desc, fxmName)) == "false":
            wiresfile = xg.getAttr("wiresFile", palette, desc, fxmName)
            pmc.mel.xgmFindAttachment(d=desc,
                                      f=wiresfile,
                                      fm=int(refwFrame),
                                      m=fxmName)
        else:
            curves = getHairCurves(descHairSysName)
            if curves:
                # attach wires to curves
                cmds.select(curves, replace=True)
                pmc.mel.xgmFindAttachment(d=desc, fm=int(refwFrame), m=fxmName)
                # print('The following curves were attached: ',
                #       [c.name() for c in curves])
            else:
                cmds.warning("No curves selected. Nothing to attach.")
コード例 #13
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
def list_fx_modules(description, activated=None):
    palette = get_palette_by_description(description)
    modules = xg.fxModules(palette, description)

    if activated is not None:
        state = "true" if activated else "false"
        matched = list()
        for fxm in modules:
            if xg.getAttr("active", palette, description, fxm) == state:
                matched.append(fxm)
        return matched

    else:
        return modules
コード例 #14
0
	def setPreviewInCam(self, palName, valueDict= None):
		"""doc"""
		if valueDict:
			# restore value
			for desc in xg.descriptions(palName):
				xg.setAttr('inCameraOnly', valueDict[desc], palName, desc, 'GLRenderer')
			return None
		else:
			# set to false if no value in
			valueDict = {}
			for desc in xg.descriptions(palName):
				valueDict[desc] = xg.getAttr('inCameraOnly', palName, desc, 'GLRenderer')
				xg.setAttr('inCameraOnly', 'false', palName, desc, 'GLRenderer')
			return valueDict
コード例 #15
0
def attachSlot(palName, descName, fxmName, descHairSysName):
    """doc"""
    if not xg.fxModuleType(palName, descName, fxmName) == 'AnimWiresFXModule':
        return

    refwFrame = xg.getAttr('refWiresFrame', palName, descName, fxmName)
    if xg.getAttr('liveMode', palName, descName, fxmName) == 'false':
        wiresfile = xg.getAttr('wiresFile', palName, descName, fxmName)
        pm.mel.xgmFindAttachment(d=descName,
                                 f=wiresfile,
                                 fm=int(refwFrame),
                                 m=fxmName)
    else:
        curves = getHairCurves(descHairSysName)
        if curves:
            # attach wires to curves
            pm.select(curves, r=1)
            pm.mel.xgmFindAttachment(d=descName, fm=int(refwFrame), m=fxmName)
            print 'The following curves were attached: ', [
                c.name() for c in curves
            ]
        else:
            print 'No curves selected. Nothing to attach.'
コード例 #16
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
def switch_data_path(palette, data_path):
    """Switch xgDataPath context

    Args:
        palette (str): XGen Legacy palette name
        data_path (str): xgDataPath

    """
    origin = xg.getAttr("xgDataPath", palette)
    data_path = data_path.replace("\\", "/")
    try:
        xg.setAttr("xgDataPath", data_path, palette)
        yield
    finally:
        xg.setAttr("xgDataPath", origin, palette)
コード例 #17
0
def exportCurvesMel(palName, descName, fxmName):
    """doc"""
    # setup
    value = xg.getAttr('exportDir', palName, descName, fxmName)
    xg.setAttr('exportDir', str(value), palName, descName, fxmName)
    xg.setAttr('exportCurves', 'true', palName, descName, fxmName)
    #
    # Need to fill in the export faces to correct value
    #
    xg.setAttr('exportFaces', '', palName, descName, fxmName)
    # export clumpCurves.mel
    pm.mel.xgmNullRender(descName, percent=0)
    # get clumpCurves.mel file path
    curvesMelPath = xg.getAttr('_fullExportDir', palName, descName, fxmName)
    # remove clumpCurves.mel's last cmd : "xgmMakeCurvesDynamic;"
    print 'Reading curves mel. -> ' + curvesMelPath
    curvesMel = open(curvesMelPath, 'r').readlines()
    cmdIndex = curvesMel.index('xgmMakeCurvesDynamic;\n')
    curvesMel[cmdIndex] = ''
    # execute it, and we will run our MakeCurvesDynamic later
    pm.mel.eval(''.join(curvesMel))
    # restore
    xg.setAttr('exportCurves', 'false', palName, descName, fxmName)
    xg.setAttr('exportFaces', '', palName, descName, fxmName)
コード例 #18
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
def bake_modules(palette, description):
    """Bake description's modifiers which data needs to be baked

    This bakes NoiseFXModule and MeshCutFXModule, also set ClumpingFXModule
    attribute 'cvAttr' to True for AnimModifiers.

    Args:
        palette (str): XGen Legacy palette name
        description (str): XGen Legacy description name

    """
    fxmod_typ = (lambda fxm: xg.fxModuleType(palette, description, fxm))

    fx_modules = xg.fxModules(palette, description)

    previous_clump = None

    # (NOTE) fxModules iterate from bottom to top
    for fxm in fx_modules:

        if fxmod_typ(fxm) == "ClumpingFXModule":
            # set the top clumpingMod cvAttr to True, for AnimModifiers
            # which needs clump
            if previous_clump:
                xg.setAttr("cvAttr", "false", palette, description,
                           previous_clump)

            xg.setAttr("cvAttr", "true", palette, description, fxm)
            previous_clump = fxm

        if fxmod_typ(fxm) in ("NoiseFXModule", "MeshCutFXModule"):
            # temporarily turn off lod so we dont bake it in
            lod = xg.getAttr("lodFlag", palette, description)
            xg.setAttr("lodFlag", "false", palette, description)
            # change mode for bake
            xg.setAttr("mode", "2", palette, description, fxm)
            # bake the noise
            cmds.xgmNullRender(description, progress=True)
            # restore
            xg.setAttr("lodFlag", lod, palette, description)
            # change mode to baked
            xg.setAttr("mode", "1", palette, description, fxm)
コード例 #19
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
def parse_expr_maps(attr, palette, description, object):
    """Return a list of map file data from expression in an object attribute

    Args:
        attr (str): Modifier attribute name
        palette (str): XGen Legacy palette name
        description (str): XGen Legacy description name
        object (str): Name of an XGen object

    Returns:
        (list): A list of `ExpressionUI.MapItem` object.
            Object attribute:
                name: Expression var name
                file: Map file path
                mode: Map file mode
                pos: Expression var in line position

    """
    expr = xg.getAttr(attr, palette, description, object)
    return _parseMapString(expr)
コード例 #20
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
def xgen_preview_all(palette):
    """Preview all XGen Legacy primitives instead of in view only

    Args:
        palette (str): XGen Legacy palette name

    """
    origin_value = {}

    for desc in xg.descriptions(palette):
        origin_value[desc] = xg.getAttr("inCameraOnly", palette, desc,
                                        "GLRenderer")
        xg.setAttr("inCameraOnly", "false", palette, desc, "GLRenderer")

    try:
        yield

    finally:
        # restore value
        for desc in xg.descriptions(palette):
            xg.setAttr("inCameraOnly", origin_value[desc], palette, desc,
                       "GLRenderer")
コード例 #21
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
def is_modifier_under_bake_manager(palette, description, modifier):
    """Is this modifier stack under an active bake groom manager ?

    Args:
        palette (str): XGen Legacy palette name
        description (str): XGen Legacy description name
        modifier (str): Name of an XGen modifier object

    Returns:
        (bool)

    """
    fxmod_typ = (lambda fxm: xg.fxModuleType(palette, description, fxm))

    fx_modules = xg.fxModules(palette, description)
    bake_found = False
    for fxm in reversed(fx_modules):
        if fxm == modifier:
            return bake_found

        if fxmod_typ(fxm) == "BakedGroomManagerFXModule":
            if xg.getAttr("active", palette, description, fxm) == "true":
                bake_found = True
コード例 #22
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
コード例 #23
0
 def _get_root_folder(self):
     """
     Gets the xgen root folder
     :return: String with the xgen folder path
     """
     return xg.getAttr('xgDataPath', str(self.collection_name))
コード例 #24
0
    def buildUI(self):
        layout = QVBoxLayout()
        self.setLayout(layout)

        descriptionGrpBox = QGroupBox(self.description)
        layout.addWidget(descriptionGrpBox)

        descriptionGrpBoxLayout = QVBoxLayout()
        descriptionGrpBox.setLayout(descriptionGrpBoxLayout)

        # Description Toolbar
        descriptionToolBar = QToolBar()
        descriptionToolBar.setIconSize(QSize(32, 32))
        descriptionGrpBoxLayout.addWidget(descriptionToolBar)

        guideDisplayToggleAction = QAction(
            QIcon(os.path.join(XGEN_ICON_PATH, 'xgToggleGuide.png')),
            'Guide Display Toggle', self)
        descriptionToolBar.addAction(guideDisplayToggleAction)

        xgPreviewRefreshAction = QAction(
            QIcon(os.path.join(XGEN_ICON_PATH, 'xgPreviewRefresh.png')),
            'Refresh Primitive', self)
        descriptionToolBar.addAction(xgPreviewRefreshAction)

        xgPreviewClearAction = QAction(
            QIcon(os.path.join(XGEN_ICON_PATH, 'xgPreviewClear.png')),
            'Clear Primitive', self)
        descriptionToolBar.addAction(xgPreviewClearAction)

        # Renderable Button
        self.renderableButton = QPushButton()

        renderablePixmap = QPixmap(os.path.join(ICON_PATH, 'renderable.png'))
        self.renderableIcon = QIcon(renderablePixmap)
        disRenderablePixmap = QPixmap(
            os.path.join(ICON_PATH, 'disRenderable.png'))
        self.disRenderableIcon = QIcon(disRenderablePixmap)

        self.renderableButton.setIcon(self.renderableIcon)
        self.renderableButton.setIconSize(renderablePixmap.rect().size())
        self.renderableButton.setCheckable(True)
        self.renderableButton.setStyleSheet("background-color: white")
        descriptionGrpBoxLayout.addWidget(self.renderableButton)

        # Density Widget
        densityLayout = QHBoxLayout()
        descriptionGrpBoxLayout.addLayout(densityLayout)

        densityLabel = QLabel('Density')
        densityLayout.addWidget(densityLabel)

        densityValue = xg.getAttr("density", self.collection, self.description,
                                  "RandomGenerator")

        densityLineEdit = QLineEdit()
        densityLineEdit.setText(densityValue)
        densityLineEditValidator = QDoubleValidator(0.000, 3000.000, 6,
                                                    densityLineEdit)
        densityLineEdit.setValidator(densityLineEditValidator)
        densityLayout.addWidget(densityLineEdit)

        # Connect Widgets
        guideDisplayToggleAction.triggered.connect(
            lambda: xg.toggleGuideDisplay(self.description))
        xgPreviewRefreshAction.triggered.connect(lambda: pm.mel.eval(
            'xgmPreview -progress {"%s"};' % self.description))
        xgPreviewClearAction.triggered.connect(lambda: pm.mel.eval(
            'xgmPreview -clean {"%s"};' % self.description))
        densityLineEdit.returnPressed.connect(
            lambda: self.setDensity(densityLineEdit.text()))
        self.renderableButton.toggled.connect(
            lambda checked: self.renderableButtonToggledSlot(checked))
コード例 #25
0
	def linkHairSystem(self, palName):
		"""doc"""
		self.clearPreview()

		nHairAttrs = {
			# This will cause Maya crash if the dyn-curves shape is weried
			# xgen NullRender might generate weired shaped curve if scene is too large
			#'noStretch': 1,
			'stretchResistance': 600,
			'compressionResistance': 100,
			'startCurveAttract': 0.3,
			'mass': 0.05
			}

		# get active AnimWire module list
		animWireDict = {}
		refWiresFrame = ''
		for desc in xg.descriptions(palName):
			for fxm in xg.fxModules(palName, desc):
				if xg.fxModuleType(palName, desc, fxm) == 'AnimWiresFXModule':
					if xg.getAttr('active', palName, desc, fxm) == 'true':
						refWiresFrame = xg.getAttr('refWiresFrame', palName, desc, fxm)
						hsysName = self.getHairSysName(desc)
						hsysTransforms = [str(hsys.getParent().name()) for hsys in pm.ls(type= 'hairSystem')]
						if hsysName in hsysTransforms:
							pm.warning('[XGen Hub] : description: %s has hairSystem [%s], skipped.' % (desc, hsysName))
						else:
							animWireDict[desc] = fxm
		# build hairSystem
		for desc in animWireDict:
			fxm = animWireDict[desc]
			pm.warning('[XGen Hub] : Building hairSystem for description: %s, FXModule: %s' % (desc, fxm))
			descHairSysName = self.getHairSysName(desc)
			msxgAwt.exportCurvesMel(palName, desc, fxm)
			meshPatch, hsys = msxgAwt.xgmMakeCurvesDynamic(descHairSysName, False)
			msxgAwt.nRigidRename(meshPatch, self.getRigidNameVar())
			msxgAwt.attachSlot(palName, desc, fxm, descHairSysName)
			pm.warning('[XGen Hub] : Link hairSystem done.')
			# set some attributes
			for attr in nHairAttrs:
				hsys.setAttr(attr, nHairAttrs[attr])
			# set follicles
			focGrp = pm.ls(desc + '_hairSystemFollicles', type= 'transform')
			if focGrp and focGrp[0].listRelatives(ad= 1, typ= 'follicle'):
				follicles = focGrp[0].listRelatives(ad= 1, typ= 'follicle')
			if palName == 'BossHair':
				for foc in follicles:
					foc.fixedSegmentLength.set(1)
					foc.segmentLength.set(20)
					# set rebuildCurve.rebuildType to update follicle changes
					cuv = pm.listConnections(foc, s= 1, d= 0, type= 'nurbsCurve', sh= 1)
					rebuildCuv = pm.listConnections(cuv, s= 1, d= 0, type= 'rebuildCurve')[0]
					rebuildCuv.rebuildType.set(0)

		if pm.objExists('nucleus1'):
			jobs = pm.scriptJob(lj= 1)
			for job in jobs:
				if 'nucleus1.startFrame' in job:
					pm.scriptJob(k= int(job.split(':')[0]))
			pm.scriptJob(ac= ['nucleus1.startFrame', self.setRefWiresFrame])
			pm.PyNode('nucleus1').startFrame.set(int(refWiresFrame))
コード例 #26
0
ファイル: legacy.py プロジェクト: VSPipe/reveries-config
def build_hair_system(palette):
    """Build hair system and link to the descriptions that has animWire modifier

    Args:
        palette (str): XGen Legacy palette name

    """
    def exportCurves(descName, fxmName):
        # setup
        value = xg.getAttr("exportDir", palette, descName, fxmName)
        xg.setAttr("exportDir", str(value), palette, descName, fxmName)
        xg.setAttr("exportCurves", "true", palette, descName, fxmName)

        # Need to fill in the export faces to correct value
        xg.setAttr("exportFaces", "", palette, descName, fxmName)

        # export clumpCurves.mel
        pmc.mel.xgmNullRender(descName, percent=0)

        # get clumpCurves.mel file path
        curvesMelPath = xg.getAttr("_fullExportDir", palette, descName,
                                   fxmName)

        # Remove clumpCurves.mel's last cmd : "xgmMakeCurvesDynamic;"
        print("Reading curves mel. -> %s" % curvesMelPath)
        with open(curvesMelPath, "r") as mel_script:
            curvesMel = mel_script.readlines()
        cmdIndex = curvesMel.index("xgmMakeCurvesDynamic;\n")
        curvesMel[cmdIndex] = ""

        # execute it, and we will run our MakeCurvesDynamic later
        pmc.mel.eval("".join(curvesMel))
        # restore
        xg.setAttr("exportCurves", "false", palette, descName, fxmName)
        xg.setAttr("exportFaces", "", palette, descName, fxmName)

    def xgmMakeCurvesDynamic(descHairSysName, collide):
        """
        Create nHairSystem with good name before MakeCurvesDynamic
        and without optionBox UI
        """
        selection = pmc.ls(sl=True, long=True)
        # find hair holding mesh for later rigid body rename
        meshPatch = []
        for dag in selection:
            if dag.getShape().type() == "mesh":
                meshPatch.append(dag.name())

        # create the first time we hit a valid curve
        hsys = pmc.createNode("hairSystem")
        hsys.getParent().rename(descHairSysName)

        # we want uniform stiffness because the curves
        # are initially point locked to both ends
        pmc.removeMultiInstance(hsys.stiffnessScale[1], b=True)

        hsys.clumpWidth.set(0.00001)
        hsys.hairsPerClump.set(1)
        pmc.connectAttr("time1.outTime", hsys.currentTime)

        nucleus = pmc.mel.getActiveNucleusNode(False, True)
        pmc.mel.addActiveToNSystem(hsys, nucleus)
        pmc.connectAttr(nucleus + ".startFrame", hsys.startFrame)

        # select the hairSystem we just created and well named,
        # and maya won't create one when making curves dynamic
        selection.append(hsys)
        # re-select curves, mesh and hairSystem
        pmc.select(selection, replace=True)
        # trun on 'Collide With Mesh'
        pmc.optionVar(
            intValue=["makeCurvesDynamicCollideWithMesh",
                      int(collide)])
        # MakeCurvesDynamic callback
        mel.eval('makeCurvesDynamic 2 { "1", "0", "1", "1", "0"}')

        return meshPatch, hsys.name()

    def nRigidRename(meshPatch):
        # `meshPatch` is a list of geo long name
        renameDict = {}
        for rigid in cmds.ls(type="nRigid"):
            shapes = cmds.listConnections(rigid + ".inputMesh", shapes=True)
            if shapes and cmds.nodeType(shapes[0]) == "mesh":
                meshName = cmds.listRelatives(shapes[0],
                                              parent=True,
                                              fullPath=True)[0]
                if meshName in meshPatch:
                    renameDict[rigid] = meshName
        # rename rigid body
        for rigidName in renameDict:
            rigid = cmds.ls(rigidName)
            if not rigid:
                continue
            cmds.rename(
                cmds.listRelatives(rigid[0], parent=True)[0],
                "%s_nRigid" % renameDict[rigidName])

    def getHairCurves(descHairSysName):
        """List out curves which output from descHairSysName"""
        # since we had our nHairSystem well named, we can search it by name
        hsysList = cmds.ls(descHairSysName)
        if not hsysList:
            return

        curves = []
        shapes = cmds.listRelatives(hsysList[0], shapes=True, fullPath=True)
        if cmds.nodeType(shapes[0]) == "hairSystem":
            # find curves
            hsys = shapes[0]
            follicles = cmds.listConnections(hsys + ".inputHair",
                                             shapes=True,
                                             type="follicle")
            for foll in follicles:
                curve = cmds.listConnections(foll + ".outCurve",
                                             shapes=True,
                                             type="nurbsCurve")
                curves.extend(curve)
        return curves

    def attachSlot(palette, desc, fxmName, descHairSysName):
        if not (str(xg.fxModuleType(palette, desc, fxmName))
                == "AnimWiresFXModule"):
            return

        refwFrame = xg.getAttr("refWiresFrame", palette, desc, fxmName)
        if str(xg.getAttr("liveMode", palette, desc, fxmName)) == "false":
            wiresfile = xg.getAttr("wiresFile", palette, desc, fxmName)
            pmc.mel.xgmFindAttachment(d=desc,
                                      f=wiresfile,
                                      fm=int(refwFrame),
                                      m=fxmName)
        else:
            curves = getHairCurves(descHairSysName)
            if curves:
                # attach wires to curves
                cmds.select(curves, replace=True)
                pmc.mel.xgmFindAttachment(d=desc, fm=int(refwFrame), m=fxmName)
                # print('The following curves were attached: ',
                #       [c.name() for c in curves])
            else:
                cmds.warning("No curves selected. Nothing to attach.")

    # Start process

    preview_clear()

    get_hsys_name = (lambda desc: desc + "_hairSystem")

    nHairAttrs = {
        "stretchResistance": 600,
        "compressionResistance": 100,
        "startCurveAttract": 0.3,
        "mass": 0.05
    }

    palette = str(palette)

    # get active AnimWire module list
    animWireDict = {}
    for desc in xg.descriptions(palette):
        for fxm in xg.fxModules(palette, desc):
            if xg.fxModuleType(palette, desc, fxm) != "AnimWiresFXModule":
                continue
            if xg.getAttr("active", palette, desc, fxm) == "true":

                hsysName = get_hsys_name(desc)
                hsysTransforms = [
                    cmds.listRelatives(hsys, parent=True)[0]
                    for hsys in cmds.ls(type="hairSystem")
                ]

                if hsysName in hsysTransforms:
                    cmds.warning("Description %s has hairSystem [%s], "
                                 "skipped." % (desc, hsysName))
                else:
                    animWireDict[desc] = fxm

    # build hairSystem
    for desc, fxm in animWireDict.items():

        print("Building hairSystem for description: %s, FXModule: %s"
              "" % (desc, fxm))

        fxm = animWireDict[desc]
        descHairSysName = get_hsys_name(desc)

        exportCurves(desc, fxm)
        # add patch to selection
        cmds.select(list_bound_geometry(desc), add=True)
        meshPatch, hsys = xgmMakeCurvesDynamic(descHairSysName, False)
        nRigidRename(meshPatch)
        attachSlot(palette, desc, fxm, descHairSysName)

        print("HairSystem linked.")

        # set some attributes
        for attr, val in nHairAttrs.items():
            cmds.setAttr(hsys + "." + attr, val)
コード例 #27
0
	def getAnimBranch(self, palName):
		"""doc"""
		return str(xg.getAttr('xgDogTag', palName))
コード例 #28
0
	def importGrooming(self, palName, descName= None, version= None):
		"""
		"""
		self.clearPreview()

		if descName:
			descs = [descName]
		else:
			descs = xg.descriptions(palName)
		# copy groom dir from versionRepo if @version has given
		if version:
			# check exists
			groomDesc = {}
			hasMissing = False
			for desc in descs:
				if xg.getAttr('groom', palName, desc):
					groomSource = '/'.join([self.paletteVerDir(palName, version), desc, 'groom'])
					if os.path.exists(groomSource):
						groomDesc[desc] = groomSource
					else:
						hasMissing = True
						msg = '[XGen Hub] : palette [%s] description [%s] version [%s] NOT exists. -> %s'
						pm.warning(msg % (palName, desc, version, groomSource))
			# copy file if no missing
			if not hasMissing:
				for desc in groomDesc:
					src = groomDesc[desc]
					dst = '/'.join([self.paletteWipDir(palName), desc, 'groom'])
					if os.path.isdir(dst):
						try:
							dir_util.remove_tree(dst)
						except:
							pm.warning('[XGen Hub] : Dir may not remove. -> ' + dst)
					dir_util._path_created = {}
					dir_util.copy_tree(src, dst)
			else:
				pm.error('[XGen Hub] : Some data missing, Check ScriptEditor. grooming import stopped.')

				return None

		self.refresh()
		# IMPORT GROOMING
		# clear out autoExport path for preventing grooming auto export
		xg.setOptionVarString('igAutoExportFolder', '')
		for desc in descs:
			if xg.getAttr('groom', palName, desc):
				importPath = xg.expandFilepath('${DESC}/groom', desc)
				igDescr = xg.igDescription(desc)
				# import Attribute Map
				try:
					pm.waitCursor(state= True)
					pm.mel.iGroom(im= importPath, d= igDescr)
				finally:
					pm.waitCursor(state= False)
				# import Mask
				try:
					pm.waitCursor(state= True)
					pm.mel.iGroom(ik= importPath, d= igDescr)
				finally:
					pm.waitCursor(state= False)
				# import Region
				try:
					pm.waitCursor(state= True)
					pm.mel.iGroom(ir= importPath, d= igDescr)
				finally:
					pm.waitCursor(state= False)
		# restore default autoExport path
		xg.setOptionVarString('igAutoExportFolder', '${DESC}/groom')

		# IMPORT GROOM SETTINGS
		"""
		Currently only grab [density] setting,
		['length', 'width'] will messed up imported grooming's map attribute
		"""
		for desc in descs:
			igdesc = xg.getAttr('groom', palName, desc)
			jsonPath = xg.expandFilepath('${DESC}/groom', desc) + 'groomSettings.json'
			if igdesc and os.path.isfile(jsonPath):
				groomSettings = {}
				with open(jsonPath) as jsonFile:
					groomSettings = json.load(jsonFile)
				for key in groomSettings:
					# grab [density] setting only
					if key == 'density':
						pm.setAttr(igdesc + '.' + key, groomSettings[key])

		self.notifyMsg('Grooming Import Complete !', 0)

		return True
コード例 #29
0
	def importPalette(self, palName, version, binding= False, anim= False, asDelta= False, delta= []):
		"""
		** NOT SUPPORT NAMESPACE **
		XGen palette will imported without validator.
		[!!!] When importing [BAKED] palette, @binding set to False should be fine.
		"""
		xgenFileName = palName + '.xgen'
		xgenFile = str('/'.join([self.paletteVerDir(palName, version), xgenFileName]))
		if not os.path.isfile(xgenFile):
			self.notifyMsg('.xgen file is not exists.', 2)
			pm.error('[XGen Hub] : .xgen file is not exists. -> ' + xgenFile)
			return None
		if asDelta and not pm.sceneName():
			self.notifyMsg('Please save the scene.', 2)
			return None
		
		self.clearPreview()
		
		# check if palette exists in current scene
		if palName in xg.palettes():
			# delete current palette folder
			palDir = xg.expandFilepath(xg.getAttr('xgDataPath', palName), '')
			if os.path.isdir(palDir):
				try:
					dir_util.remove_tree(palDir)
				except:
					pm.warning('[XGen Hub] : Dir may not remove. -> ' + palDir)
			# delete current palette
			# this action might cry about 'None type object has no attr "previewer"'
			# when there is no xgen ui panel
			xg.deletePalette(palName)
		
		# IMPORT PALETTE
		palName = base.importPalette(xgenFile, delta, '')
		# update the palette with the current project
		xg.setAttr('xgProjectPath', str(pm.workspace(q= 1, rd= 1)), palName)
		dataPath = xg.paletteRootVar() + '/' + palName
		xg.setAttr('xgDataPath', dataPath, palName)
		# create imported palette folder
		paletteRoot = xg.expandFilepath(dataPath, '', True, True)
		# create all imported descriptions folder
		msxgApi.setupDescriptionFolder(paletteRoot, palName)
		# wrap into maya nodes
		palName = str(pm.mel.xgmWrapXGen(pal= palName, wp= binding, wlg= binding, gi= binding))
		# copy maps from source
		descNames = xg.descriptions(palName)
		msxgApi.setupImportedMap(xgenFile, palName, descNames, self.projPath)
		# bind grooming descriptions to geometry
		if binding:
			for desc in descNames:
				igdesc = xg.getAttr('groom', palName, desc)
				if igdesc:
					# get groom dag node
					igdesc = xg.igActivateDescription(desc)
					# bind groom to geo
					pm.mel.igBindFromXGen(desc)
					# set groom density and sampling method
					pm.setAttr(igdesc + '.density', 1)
					pm.setAttr(igdesc + '.interpStyle', 1)
					# set all groom visible on
					xg.igSetDescriptionVisibility(True)
					# sync primitives tab attritube map path with auto export path
					xg.igSyncMaps(desc)

			# import grooming as well
			self.importGrooming(palName)

		# import as anim, build hairSystem
		if anim:
			# build hairSystem
			self.linkHairSystem(palName)
			# check preset dir exists
			presetLocalDir = str(pm.internalVar(userPresetsDir= 1))
			presetRepo = self.nDynPresetPath(palName, version)
			if os.path.exists(presetRepo):
				# copy preset
				for prs in os.listdir(presetRepo):
					dstPath = presetLocalDir + prs
					prs = '/'.join([presetRepo, prs])
					shutil.copyfile(prs, dstPath)
				# load preset
				# [note] nucleus preset will not be loaded during current devlope
				presetMel = []
				for nodeType in ['hairSystem', 'nRigid']:
					presetDict = self.ioAttrPreset(nodeType, False)
					presetMel.extend(presetDict.values())
				# dump preset
				for prs in presetMel:
					if os.path.isfile(prs):
						os.remove(prs)
			else:
				pm.warning('[XGen Hub] : nDynamic attribute presets folder not found.')

		if asDelta:
			dataPath = xg.getAttr('xgDataPath', palName)
			dataPath = dataPath + ';' + self.paletteVerDir(palName, version, raw= True)
			xg.setAttr('xgDataPath', dataPath, palName)
			# save scenes
			pm.saveFile(f= 1)
			# set export delta
			pm.setAttr(palName + '.xgExportAsDelta', 1)

		pm.warning('[XGen Hub] : Collection Import Complete !')
		self.notifyMsg('Collection Import Complete !', 0)

		return palName
コード例 #30
0
	def getAnimShotName(self, palName):
		"""doc"""
		return str(xg.getAttr(self.xgShotAttr, palName))