Exemple #1
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
Exemple #2
0
    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")
Exemple #3
0
	def getPaletteBoundGeo(self, palName):
		"""doc"""
		bGeoList = []
		for desc in xg.descriptions(palName):
			bGeoList.extend(xg.boundGeometry(palName, desc))
		bGeoList = list(set(bGeoList))
		return bGeoList
Exemple #4
0
    def update_descriptions(self):
        if not self.ui_description:
            return

        collection = self.get_collection()
        descriptions = xg.descriptions(collection)

        self.ui_description.set_items(descriptions)
Exemple #5
0
	def exportAnimPackage(self, palName, shotName):
		"""doc"""
		# get version info from [xgDogTag]
		version = self.getAnimBranch(palName)
		if not version:
			pm.error('[XGen Hub] : Couldn\'t get ANIM branch name. Export process stop.')
			return None

		self.clearPreview()

		# add shotName attribute to xgen and save in xgen delta later
		if not xg.attrExists(self.xgShotAttr, palName):
			xg.addCustomAttr(self.xgShotAttr, palName)
		xg.setAttr(self.xgShotAttr, shotName, palName)

		# add nucleus startFrame attribute to xgen and save in xgen delta later
		if not xg.attrExists(self.xgRefFrame, palName):
			xg.addCustomAttr(self.xgRefFrame, palName)
		xg.setAttr(self.xgRefFrame, str(int(pm.PyNode('nucleus1').startFrame.get())), palName)
		
		# get resolved repo shotName path
		deltaPath = self.paletteDeltaDir(palName, version, shotName)
		if not os.path.exists(deltaPath):
			os.mkdir(deltaPath)
		
		deltaFile = '/'.join([deltaPath, palName + '.xgd'])

		# export delta
		xg.createDelta(palName, deltaFile)

		# get curves and export
		for desc in xg.descriptions(palName):
			curvesGrp = pm.ls(desc + '_hairSystemOutputCurves', type= 'transform')
			if curvesGrp and curvesGrp[0].listRelatives():
				curves = curvesGrp[0].listRelatives()
				# cache curves, export as alembic
				if not pm.pluginInfo('AbcExport', q= 1, l= 1):
					pm.loadPlugin('AbcExport')
				start, end = self.getTimeSliderMinMax()
				abcCmds = '-frameRange %d %d -uvWrite -worldSpace -dataFormat ogawa ' % (start, end)
				abcRoot = '-root ' + ' -root '.join([cur.longName() for cur in pm.ls(curves)])
				abcPath = '/'.join([deltaPath, desc + '.abc'])
				pm.mel.AbcExport(j= abcCmds + abcRoot + ' -file ' + abcPath)

		# 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), shotName)
				if not os.path.exists(os.path.dirname(imgPath)):
					os.mkdir(os.path.dirname(imgPath))
				shutil.move(tmpPath, imgPath)

		self.refresh('Full')

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

		return True
Exemple #6
0
def get_description():
    palettes = xgen.palettes()
    if not palettes:
        return
    descriptions = list()
    for palette in palettes:
        cell_desc = xgen.descriptions(palette)
        if cell_desc:
            descriptions.extend(cell_desc)
    return descriptions
Exemple #7
0
	def xgOutputSettings(self, palName):
		"""doc"""
		for desc in xg.descriptions(palName):
			# set renderer
			xg.setAttr( 'renderer', 'VRay', palName, desc, 'RendermanRenderer')
			# auto set primitive Bound
			value = xgcmds.autoSetPrimitiveBound(palName, desc)
			#xg.setAttr('primitiveBound', value, palName, desc, 'RendermanRenderer')

		self.refresh('Full')
Exemple #8
0
	def importGuides(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
			guidesDesc = {}
			hasMissing = False
			for desc in descs:
				if self.descControlMethod(palName, desc) == 'Guides':
					abcPath = '/'.join([self.paletteVerDir(palName, version), desc, 'curves.abc'])
					if os.path.isfile(abcPath):
						guidesDesc[desc] = abcPath
					else:
						hasMissing = True
						msg = '[XGen Hub] : palette [%s] description [%s] version [%s] NOT exists. -> %s'
						pm.warning(msg % (palName, desc, version, abcPath))
			# copy file if no missing
			if not hasMissing:
				for desc in guidesDesc:
					src = guidesDesc[desc]
					dst = '/'.join([self.paletteWipDir(palName), desc, 'curves.abc'])
					if os.path.isdir(dst):
						os.remove(dst)
					shutil.copyfile(src, dst)
			else:
				pm.error('[XGen Hub] : Some .abc missing, Check ScriptEditor. guides import stopped.')

				return None

		# IMPORT GUIDES
		for desc in descs:
			# import alembic
			if not pm.pluginInfo('AbcImport', q= 1, l= 1):
				pm.loadPlugin('AbcImport')
			abcPath = xg.expandFilepath('${DESC}', desc) + 'curves.abc'
			if os.path.isfile(abcPath):
				pool = pm.group(em= 1, n= 'curvesToGuide_processPoll')
				pm.mel.AbcImport(abcPath, mode= 'import', rpr= pool)
				# select curves
				curves = pm.listRelatives(pool, c= 1)
				pm.select(curves, r= 1)
				# curvesToGuides
				pm.mel.xgmCurveToGuide(d= desc, tsp= 1.0, tsa= 0.0, deleteCurve= True)

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

		return True
    def _get_scalps(self):
        """
        Gets a list with the used scalps in the descriptions
        :return: List with the scalps names
        """
        scalps = list()
        for description in xg.descriptions(str(self.collection_name)):
            scalpt = xg.boundGeometry(str(self.collection_name), str(description))[0]
            if scalpt not in scalps:
                scalps.append(scalpt)

        return scalps
Exemple #10
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
Exemple #11
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
Exemple #12
0
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")
 def _get_shaders(self):
     """
     Gets a dictionary with the used materials for each description
     :return: Dictionary with the shader --> description mapping
     """
     import pymel.core as pm
     material_dict = dict()
     for description in xg.descriptions(str(self.collection_name)):
         pm.select(description)
         pm.hyperShade(shaderNetworksSelectMaterialNodes=True)
         for shd in pm.selected(materials=True):
             if [c for c in shd.classification() if 'shader/surface' in c]:
                 material_dict[description] = shd.name()
     return material_dict
Exemple #14
0
def list_descriptions(palette=""):
    """Return all descriptions of the palette or in scene

    Get a list of descriptions for the given palette; or, if no palette name
    is given, return all descriptions in the scene.

    Args:
        palette (str, optional): XGen Legacy palette name

    Return:
        (list): A list of description names

    """
    return list(xg.descriptions(str(palette)))
Exemple #15
0
	def setRefWiresFrame(self, refWiresFrame= None):
		"""doc"""
		if not refWiresFrame:
			refWiresFrame = str(int(pm.PyNode('nucleus1').startFrame.get()))
		else:
			if pm.objExists('nucleus1'):
				pm.PyNode('nucleus1').startFrame.set(int(refWiresFrame))
		for palName in xg.palettes():
			for desc in xg.descriptions(palName):
				for fxm in xg.fxModules(palName, desc):
					if xg.fxModuleType(palName, desc, fxm) == 'AnimWiresFXModule':
						xg.setAttr('refWiresFrame', refWiresFrame, palName, desc, fxm)

		self.refresh('Full')
Exemple #16
0
def set_refWires_frame(refWiresFrame, palette):
    """Setup refWireFrame to the descriptions that has animWire modifier

    Args:
        refWiresFrame (int, float): refWireFrame value
        palette (str): XGen Legacy palette name

    """
    refWiresFrame = str(int(refWiresFrame))
    palette = str(palette)

    for desc in xg.descriptions(palette):
        for fxm in xg.fxModules(palette, desc):
            if xg.fxModuleType(palette, desc, fxm) != "AnimWiresFXModule":
                continue
            xg.setAttr("refWiresFrame", refWiresFrame, palette, desc, fxm)
Exemple #17
0
def import_xgen_cache():
    palettes = xgen.palettes()
    if not palettes:
        return
    for palette in palettes:
        asset_name = palette.split("_")[0]
        descriptions = xgen.descriptions(palette)
        if not descriptions:
            continue
        cache_dir = get_cache_dir()
        for description in descriptions:
            cache_file_name = "%s/%s/hair/%s.abc" % (cache_dir, asset_name,
                                                     description)
            if not os.path.isfile(cache_file_name):
                continue
            xgen.setAttr("useCache", "true", palette, description,
                         "SplinePrimitive")
            xgen.setAttr("liveMode", "false", palette, description,
                         "SplinePrimitive")
            xgen.setAttr("cacheFileName", cache_file_name, palette,
                         description, "SplinePrimitive")

    de = xgg.DescriptionEditor
    de.refresh("Full")
Exemple #18
0
    def buildUI(self):
        centralWidget = QWidget()
        self.setCentralWidget(centralWidget)

        mainLayout = QVBoxLayout()
        centralWidget.setLayout(mainLayout)

        # Guide tools section
        guideToolGrpBox = QGroupBox('Guide Tools')
        mainLayout.addWidget(guideToolGrpBox)

        guideMainLayout = QVBoxLayout()
        guideToolGrpBox.setLayout(guideMainLayout)

        guideToolBar = QToolBar()
        guideToolBar.setIconSize(QSize(32, 32))
        guideMainLayout.addWidget(guideToolBar, 0, 1)

        addGuideAction = QAction(
            QIcon(os.path.join(XGEN_ICON_PATH, 'xgGuideContext.png')),
            'Add or Move Guides', self)
        guideToolBar.addAction(addGuideAction)

        sculptGuideAction = QAction(
            QIcon(os.path.join(XGEN_ICON_PATH, 'fx_sculpt.png')),
            'Sculpt Guides', self)
        guideToolBar.addAction(sculptGuideAction)

        convertToPolyAction = QAction(
            QIcon(os.path.join(XGEN_ICON_PATH, 'xgConvertToPoly.png')),
            'Convert Primitives to Polygons', self)
        guideToolBar.addAction(convertToPolyAction)

        guideLayout = QGridLayout()
        guideMainLayout.addLayout(guideLayout)

        numOfCVsLabel = QLabel('Number of CP')
        guideLayout.addWidget(numOfCVsLabel, 0, 0)

        minusButton = QPushButton('-')
        guideLayout.addWidget(minusButton, 0, 1)

        plusButton = QPushButton('+')
        guideLayout.addWidget(plusButton, 0, 2)

        normalizeButton = QPushButton('Normalize')
        guideLayout.addWidget(normalizeButton, 1, 0)

        bakeButton = QPushButton('Bake')
        guideLayout.addWidget(bakeButton, 1, 1, 1, 2)

        # Description section
        scrollArea = QScrollArea()
        scrollArea.setWidgetResizable(True)
        mainLayout.addWidget(scrollArea)

        scrollWidget = QWidget()
        scrollWidget.setContentsMargins(0, 0, 0, 0)
        scrollArea.setWidget(scrollWidget)

        scrollLayout = QVBoxLayout()
        scrollWidget.setLayout(scrollLayout)

        collections = xg.palettes()
        for collection in collections:
            descriptions = xg.descriptions(collection)
            for description in descriptions:
                descriptionWidget = DescriptionWidget(collection, description)
                scrollLayout.addWidget(descriptionWidget)

        # Connections
        addGuideAction.triggered.connect(lambda: pm.mel.eval('XgGuideTool;'))
        sculptGuideAction.triggered.connect(
            lambda: xgui.createDescriptionEditor(False).guideSculptContext(
                False))
        convertToPolyAction.triggered.connect(XGenManager.showWarningDialog)
        minusButton.clicked.connect(
            lambda: XGenManager.editNumGuideCP('decrease'))
        plusButton.clicked.connect(
            lambda: XGenManager.editNumGuideCP('increase'))
        normalizeButton.clicked.connect(
            lambda: pm.mel.eval('xgmNormalizeGuides();'))
        bakeButton.clicked.connect(
            lambda: pm.mel.eval('xgmBakeGuideVertices;'))
Exemple #19
0
            xgen_item._expanded = False
            xgen_item._active = True

    def _collect_xgen_geometry(self, parent_item):
        try:
            import xgenm as xg
        except Exception, e:
            self.logger.debug(e)
            return
        icon_path = os.path.join(self.disk_location, os.pardir, "icons",
                                 "XGen.png")

        collection = xg.palettes()[0]
        xg_geometry = set()
        for descriptions in xg.descriptions(collection):
            geometry = xg.boundGeometry(collection, descriptions)
            for geo in geometry:
                xg_geometry.add(geo)
        _geometry = list(xg_geometry)
        self.logger.debug("XGen Geometry:%s" % _geometry)
        _geometry_grp = cmds.listRelatives(_geometry[0], parent=True)[0]

        xgen_item = parent_item.create_item("maya.session.xggeometry",
                                            "XGen Geometry", _geometry_grp)
        # set the icon for the item
        xgen_item.set_icon_from_path(icon_path)

        xgen_item.properties["geometry"] = _geometry_grp

        xgen_item._expanded = False
Exemple #20
0
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)
Exemple #21
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
Exemple #22
0
# import collections
for geo in geoCollection.keys():
    cmds.select(cmds.ls('*' + geo, r=1)[0], r=1)
    cmds.setAttr(cmds.ls(sl=1)[0] + '.v', 0)
    xg.importPalette(geoCollection[geo], [], '')

# get abc
for disc in hairCacheDisc:
    xg.setAttr('cacheFileName', str(hairSimRoot + cutId + '/' + disc + '.abc'),
               hairColl, disc, 'SplinePrimitive')
    xg.setAttr('useCache', 'true', hairColl, disc, 'SplinePrimitive')
    xg.setAttr('liveMode', 'false', hairColl, disc, 'SplinePrimitive')

# set renderer
for collection in xg.palettes():
    for disc in xg.descriptions(collection):
        xg.setAttr('renderer', 'VRay', collection, disc, 'RendermanRenderer')

# update ui
de = xgg.DescriptionEditor
de.refresh('Full')

# assign shader
hairGrp = [
    'hairA3', 'hairA4', 'hairA5', 'hairA6', 'hairA14', 'assassin1', 'assassin2'
]
browlashGrp = ['lash1', 'lash2', 'lash3', 'lashBottom1']

cmds.select(hairGrp, r=1)
cmds.hyperShade(a='VRayHair_HairRed')
Exemple #23
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
Exemple #24
0
 def get_descriptions():
     collections = xgen.palettes()
     needed_collection = collections[0]
     descriptions = xgen.descriptions(needed_collection)
     return descriptions
Exemple #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))
Exemple #26
0
# import collections
for geo in geoCollection.keys():
	cmds.select(cmds.ls('*' + geo, r= 1)[0], r= 1)
	cmds.setAttr(cmds.ls(sl= 1)[0] + '.v', 0)
	xg.importPalette( geoCollection[geo], [], '' )


# get abc
for disc in hairCacheDisc:
	xg.setAttr( 'cacheFileName', str(hairSimRoot + cutId + '/' + disc + '.abc'), hairColl, disc, 'SplinePrimitive')
	xg.setAttr( 'useCache', 'true', hairColl, disc, 'SplinePrimitive')
	xg.setAttr( 'liveMode', 'false', hairColl, disc, 'SplinePrimitive')

# set renderer
for collection in xg.palettes():
	for disc in xg.descriptions(collection):
		xg.setAttr( 'renderer', 'VRay', collection, disc, 'RendermanRenderer')

# update ui
de = xgg.DescriptionEditor 
de.refresh('Full')

# assign shader
hairGrp = ['hairA3', 'hairA4', 'hairA5', 'hairA6', 'hairA14', 'assassin1', 'assassin2']
browlashGrp = ['lash1', 'lash2', 'lash3', 'lashBottom1']

cmds.select(hairGrp, r= 1)
cmds.hyperShade(a= 'VRayHair_HairRed')

cmds.select(browlashGrp, r= 1)
cmds.hyperShade(a= 'VRayHair_browLid')
Exemple #27
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