예제 #1
0
 def SelectNameSet(self):
     name = self.select_set_list_qcombobox.currentText()
     #print(name)
     rt.clearSelection()
     if not self.IsSelectSetNewName(name):
         set_tiem = rt.selectionSets[name]
         rt.select(set_tiem)
     rt.redrawViews()
예제 #2
0
def select_nodes_by_name(names, add=False):
    """
    Selects nodes by name
    :param names: list<str>, names of nodes to select
    :param add: bool, Whether to add given node names to an existing selection or not
    """

    names = python.force_list(names)

    nodes = list() if not add else list(rt.selection)
    for n in names:
        node = get_node_by_name(n)
        if node:
            nodes.append(node)

    # Clear selection if need it
    if not add:
        rt.clearSelection()

    rt.select(nodes)
예제 #3
0
    def startTransfer(self):
        mxs.execute("max create mode")

        with pymxs.undo(True):

            for i in self.skinMeshes:
                skinSource = mxs.skinUtils.ExtractSkinData(i[0])
                skinSource = mxs.getNodeByName("SkinData_{}".format(i[0].name))

                count = mxs.skinOps.GetNumberBones(i[1])
                newBones = []

                for item in range(count):
                    # print(item +1, i[0].name, mxs.skinOps.GetBoneNode(i[1], item + 1))
                    try:
                        newBones.append(self.dict[mxs.skinOps.GetBoneNode(
                            i[1], item + 1)])
                    except:
                        pass

                oldSkin = i[1]
                oldSkin.enabled = False

                skinMod = mxs.Skin()
                skinMod.name = "Transfered Skin"

                mxs.addModifier(i[0], skinMod, before=i[2] - 1)

                for bone in newBones:
                    mxs.skinOps.addbone(skinMod, bone, 0)

                mxs.select(i[0])
                mxs.selectmore(skinSource)
                mxs.skinUtils.ImportSkinDataNoDialog(True, False, False, False,
                                                     False, 1.0, 0)

                mxs.delete(skinSource)
                mxs.clearSelection()

        mxs.execute("max modify mode")
예제 #4
0
    def createPreview(self, *args, **kwargs):
        """Creates a Playblast preview from currently open scene"""
        # rt = pymxs.runtime

        openSceneInfo = self.getOpenSceneInfo()
        if not openSceneInfo:
            msg = "This is not a base scene. Scene must be saved as a base scene before playblasting."
            # raise Exception([360, msg])
            self._exception(360, msg)
            return
            # logger.warning(msg)
            # return -1, msg

        # get view info
        viewportType = rt.viewport.getType()
        if str(viewportType) == "view_camera":
            currentCam = str(rt.getActiveCamera().name)
        else:
            currentCam = str(viewportType)

        validName = currentCam.replace("|", "__").replace(" ", "_")
        extension = "avi"

        # versionName = rt.getFilenameFile(rt.maxFileName) #
        versionName = rt.maxFilePath + rt.maxFileName  # abs path of the filename with extension
        relVersionName = os.path.relpath(
            versionName, start=openSceneInfo["projectPath"]
        )  # relative path of filename with ext

        if not os.path.isdir(os.path.normpath(openSceneInfo["previewPath"])):
            os.makedirs(os.path.normpath(openSceneInfo["previewPath"]))
        playBlastFile = os.path.join(
            openSceneInfo["previewPath"],
            "{0}_{1}_PB.{2}".format(self.niceName(versionName), validName,
                                    extension))
        relPlayBlastFile = os.path.relpath(playBlastFile,
                                           start=openSceneInfo["projectPath"])

        if os.path.isfile(playBlastFile):
            try:
                os.remove(playBlastFile)
            except WindowsError:
                msg = "The file is open somewhere else"
                logger.warning(msg)
                return -1, msg

        jsonInfo = self._loadJson(openSceneInfo["jsonFile"])
        if jsonInfo == -1:
            msg = "Database file is corrupted"
            return -1, msg
        # returns 0,"" if everything is ok, -1,msg if error

        pbSettings = self.loadPBSettings()
        originalValues = {"width": rt.renderWidth, "height": rt.renderHeight}

        originalSelection = rt.execute("selection as array")

        # change the render settings temporarily
        rt.renderWidth = pbSettings["Resolution"][0]
        rt.renderHeight = pbSettings["Resolution"][1]

        if pbSettings["PolygonOnly"]:
            dspGeometry = True
            dspShapes = False
            dspLights = False
            dspCameras = False
            dspHelpers = False
            dspParticles = False
            dspBones = False
        else:
            dspGeometry = True
            dspShapes = True
            dspLights = True
            dspCameras = True
            dspHelpers = True
            dspParticles = True
            dspBones = True

        dspGrid = pbSettings["ShowGrid"]
        dspFrameNums = pbSettings["ShowFrameNumber"]
        percentSize = pbSettings["Percent"]

        if pbSettings["WireOnShaded"]:
            rndLevel = rt.execute("#litwireframe")
        else:
            rndLevel = rt.execute("#smoothhighlights")

        if pbSettings["ClearSelection"]:
            rt.clearSelection()

        # find the path of where the avi file be created
        # if rt.maxFilePath:
        #     previewname = rt.getFilenameFile(rt.maxFileName)
        # else:
        #     previewname = "Untitled"

        # sourceClip = rt.GetDir(rt.execute("#preview")) + "\_scene.avi"

        # if os.path.isfile(sourceClip):
        #     try:
        #         os.remove(sourceClip)
        #     except WindowsError:
        #         msg = "Cannot continue creating preview.\n Close '%s' and try again" %sourceClip
        #         logger.error(msg)
        #         return -1, msg

        test = rt.createPreview(filename=playBlastFile,
                                percentSize=percentSize,
                                dspGeometry=dspGeometry,
                                dspShapes=dspShapes,
                                dspLights=dspLights,
                                dspCameras=dspCameras,
                                dspHelpers=dspHelpers,
                                dspParticles=dspParticles,
                                dspBones=dspBones,
                                dspGrid=dspGrid,
                                dspFrameNums=dspFrameNums,
                                rndLevel=rndLevel)

        # prior to version 2020, filename flag is not working
        if not os.path.isfile(playBlastFile):
            # find the path of where the avi file be created
            if rt.maxFilePath:
                previewname = rt.getFilenameFile(rt.maxFileName)
            else:
                previewname = "Untitled"

            sourceClip = rt.GetDir(rt.execute("#preview")) + "\_scene.avi"
            shutil.copy(sourceClip, playBlastFile)

            # if os.path.isfile(sourceClip):
            #     try:
            #         os.remove(sourceClip)
            #     except WindowsError:
            #         msg = "Cannot continue creating preview.\n Close '%s' and try again" %sourceClip
            #         logger.error(msg)
            #         return -1, msg

        # return
        # return the render width and height to original:
        rt.renderWidth = originalValues["width"]
        rt.renderHeight = originalValues["height"]

        rt.select(originalSelection)

        # shutil.copy(sourceClip, playBlastFile)

        if pbSettings["ConvertMP4"]:
            convertedFile = self._convertPreview(playBlastFile,
                                                 overwrite=True,
                                                 deleteAfter=False,
                                                 crf=pbSettings["CrfValue"])
            relPlayBlastFile = os.path.relpath(
                convertedFile, start=openSceneInfo["projectPath"])
            # os.startfile(convertedFile)
        else:
            relPlayBlastFile = os.path.relpath(
                playBlastFile, start=openSceneInfo["projectPath"])

        ## find this version in the json data

        for version in jsonInfo["Versions"]:
            if relVersionName == version["RelativePath"]:
                version["Preview"][currentCam] = relPlayBlastFile

        self._dumpJson(jsonInfo, openSceneInfo["jsonFile"])
        return 0, ""
예제 #5
0
    def saveAsset(self,
                  assetName,
                  exportUV=True,
                  exportOBJ=True,
                  exportFBX=True,
                  exportABC=True,
                  selectionOnly=True,
                  sceneFormat="max",
                  notes="N/A",
                  **info):
        """
        Saves the selected object(s) as an asset into the predefined library
        """
        # self.ssResolution = 1000
        if assetName == "":
            msg = "Asset Name cannot be empty"
            state = rt.messageBox(msg, title='Info')
            return

        if assetName in self.assetsList:
            msg = "This Asset already exists.\nDo you want to overwrite?"
            state = rt.queryBox(msg, title='Manager Question')
            if state:
                pass
            else:
                return

        originalSelection = self._getSelection(asMaxArray=True)
        originalPath = self._getSceneFile()

        dump, origExt = os.path.splitext(originalPath)

        assetDirectory = os.path.join(self.directory, assetName)

        assetAbsPath = os.path.join(assetDirectory,
                                    "%s%s" % (assetName, u'.%s' % sceneFormat))

        if selectionOnly:
            selection = self._getSelection(asMaxArray=True)
            if len(selection) == 0:
                msg = "No object selected"
                rt.messageBox(msg, title='Info')
                return
        else:
            rt.select(rt.objects)
            selection = self._getSelection(asMaxArray=True)

        # originalSelection = self._getSelection(asMaxArray=True)

        if not os.path.exists(assetDirectory):
            os.mkdir(assetDirectory)

        # GET TEXTURES
        # ------------

        if selectionOnly:

            possibleFileHolders = rt.execute("selection as Array")
            filteredBitmaps = self._getFileNodes(possibleFileHolders)

        else:
            allTexture = rt.usedMaps()
            allBitmap = rt.getClassInstances(rt.bitmapTexture)
            # this makes sure only the USED bitmaps will stored
            filteredBitmaps = [
                x for x in allBitmap if x.filename in allTexture
            ]

        textureDatabase = [
            x for x in self._buildPathDatabase(filteredBitmaps, assetDirectory)
        ]

        self._copyTextures(textureDatabase)

        # CREATE PREVIEWS
        # ---------------
        thumbPath, ssPath, swPath = self._createThumbnail(
            assetName, selectionOnly=selectionOnly, viewFit=True)

        # CREATE UV SNAPSHOTS
        # ----------------
        rt.select(selection)

        if exportUV:
            self._uvSnaps(assetName)

        # SAVE SOURCE
        # -----------
        fManager.SaveSelected(assetAbsPath)

        # EXPORT OBJ
        # ----------

        if exportOBJ:
            objFilePath = os.path.join(assetDirectory, "%s.obj" % assetName)
            if self._exportObj(objFilePath,
                               exportSettings=self.exportSettings):
                objName = "{0}.obj".format(assetName)
            else:
                objName = "N/A"
        else:
            objName = "N/A"

        # EXPORT FBX
        # ----------
        if exportFBX:
            fbxFilePath = os.path.join(assetDirectory, "%s.fbx" % assetName)
            frame = self._getCurrentFrame()

            if self._exportFbx(fbxFilePath,
                               exportSettings=self.exportSettings,
                               timeRange=[frame, frame]):
                fbxName = "{0}.fbx".format(assetName)
            else:
                fbxName = "N/A"
        else:
            fbxName = "N/A"

        # EXPORT ALEMBIC
        # --------------

        if exportABC:

            abcFilePath = os.path.join(assetDirectory, "%s.abc" % assetName)
            frame = self._getCurrentFrame()

            if self._exportAlembic(abcFilePath,
                                   exportSettings=self.exportSettings,
                                   timeRange=[frame, frame]):
                abcName = "{0}.abc".format(assetName)
            else:
                abcName = "N/A"
        else:
            abcName = "N/A"

        # NUMERIC DATA
        # ------------

        polyCount = sum(rt.getPolygonCount(x)[0] for x in selection)
        # polyCount = sum(rt.getPolygonCount(x)[0] for x in countLoop)
        tiangleCount = sum(rt.getPolygonCount(x)[1] for x in selection)
        # tiangleCount = sum(rt.getPolygonCount(x)[1] for x in countLoop)

        versionInfo = rt.maxversion()
        vInfo = [versionInfo[0], versionInfo[1], versionInfo[2]]

        # DATABASE
        # --------

        dataDict = {}
        dataDict['sourceProject'] = "3dsMax"
        dataDict['version'] = vInfo
        dataDict['assetName'] = assetName
        dataDict['objPath'] = objName
        dataDict['fbxPath'] = fbxName
        dataDict['abcPath'] = abcName
        dataDict['sourcePath'] = os.path.basename(assetAbsPath)
        dataDict['thumbPath'] = os.path.basename(thumbPath)
        dataDict['ssPath'] = os.path.basename(ssPath)
        dataDict['swPath'] = os.path.basename(swPath)
        dataDict['textureFiles'] = [x["Texture"] for x in textureDatabase]
        dataDict['Faces/Triangles'] = ("%s/%s" %
                                       (str(polyCount), str(tiangleCount)))
        dataDict['origin'] = originalPath
        dataDict['notes'] = notes

        self._setData(assetName, dataDict)

        rt.clearSelection()
        self._returnOriginal(textureDatabase)
        # self.scanAssets() # scanning issued at populate function on ui class
        rt.select(originalSelection)
        rt.messageBox("Asset Created Successfully", title='Info', beep=False)
예제 #6
0
    def _createThumbnail(self, assetName, selectionOnly=True, viewFit=True):
        # ssResolution = 1000

        thumbPath = os.path.join(self.directory, assetName,
                                 "%s_thumb.jpg" % assetName)
        SSpath = os.path.join(self.directory, assetName,
                              "%s_s.jpg" % assetName)
        WFpath = os.path.join(self.directory, assetName,
                              "%s_w.jpg" % assetName)

        if selectionOnly:
            rt.IsolateSelection.EnterIsolateSelectionMode()
            rt.redrawViews()

        # selection = rt.execute("selection as array")
        selection = self._getSelection(asMaxArray=True)
        rt.clearSelection()

        originalState = rt.viewport.GetRenderLevel()
        oWidth = 1600
        oHeight = 1600

        rt.viewport.SetRenderLevel(rt.Name("smoothhighlights"))
        rt.redrawViews()
        grabShaded = rt.gw.getViewportDib()
        rt.viewport.SetRenderLevel(rt.Name("wireframe"))
        rt.redrawViews()
        grabWire = rt.gw.getViewportDib()
        # rt.redrawViews()

        ratio = float(grabShaded.width) / float(grabShaded.height)

        if ratio < 1.0:
            new_width = oHeight * ratio
            new_height = oHeight
        elif ratio > 1.0:
            new_width = oWidth
            new_height = oWidth / ratio
        else:
            new_width = oWidth
            new_height = oWidth

        resizeFrameShaded = rt.bitmap(new_width,
                                      new_height,
                                      color=rt.color(0, 0, 0))
        rt.copy(grabShaded, resizeFrameShaded)

        resizeFrameWire = rt.bitmap(new_width,
                                    new_height,
                                    color=rt.color(0, 0, 0))
        rt.copy(grabWire, resizeFrameWire)

        ssFrame = rt.bitmap(oWidth, oHeight, color=rt.color(0, 0, 0))
        wfFrame = rt.bitmap(oWidth, oHeight, color=rt.color(0, 0, 0))

        xOffset = (oWidth - resizeFrameShaded.width) / 2
        yOffset = (oHeight - resizeFrameShaded.height) / 2

        rt.pasteBitmap(resizeFrameShaded, ssFrame, rt.point2(0, 0),
                       rt.point2(xOffset, yOffset))
        rt.pasteBitmap(resizeFrameWire, wfFrame, rt.point2(0, 0),
                       rt.point2(xOffset, yOffset))

        # rt.display(ssFrame)
        # rt.display(wfFrame)

        thumbFrame = rt.bitmap(200, 200, color=rt.color(0, 0, 0))
        rt.copy(ssFrame, thumbFrame)

        rt.display(thumbFrame)

        thumbFrame.filename = thumbPath
        rt.save(thumbFrame)
        rt.close(thumbFrame)

        ssFrame.filename = SSpath
        rt.save(ssFrame)
        rt.close(ssFrame)

        wfFrame.filename = WFpath
        rt.save(wfFrame)
        rt.close(wfFrame)

        # switch to original view
        rt.viewport.SetRenderLevel(originalState)

        rt.IsolateSelection.ExitIsolateSelectionMode()
        rt.redrawViews()

        return thumbPath, SSpath, WFpath
예제 #7
0
def clear_selection():
    """
    Clears current scene selection
    """

    return rt.clearSelection()