Exemplo n.º 1
0
    def checkUnits(self):

        CustomSysUnits = cfgl.configLoader()[9]

        CurrentWorkUnits = str(rt.units.Systemtype)

        if CustomSysUnits != CurrentWorkUnits:

            rt.execute("units.Systemtype = #" + CustomSysUnits)

            if CustomSysUnits == 'meters':
                self.cboxSysUnits.setCurrentIndex(0)

            if CustomSysUnits == 'centimeters':
                self.cboxSysUnits.setCurrentIndex(1)

            if CustomSysUnits == 'millimeters':
                self.cboxSysUnits.setCurrentIndex(2)

            print("PolygonTools: Units changed to", CustomSysUnits)
            self.lblInfo_01.setText("Units changed to " + CustomSysUnits)
        else:

            if CustomSysUnits == 'meters':
                self.cboxSysUnits.setCurrentIndex(0)

            if CustomSysUnits == 'centimeters':
                self.cboxSysUnits.setCurrentIndex(1)

            if CustomSysUnits == 'millimeters':
                self.cboxSysUnits.setCurrentIndex(2)

            print("PolygonTools: Units is", CustomSysUnits)
            self.lblInfo_01.setText("Units is " + CustomSysUnits)
Exemplo n.º 2
0
def main():
	original = rt.selection[0]
	rt.execute("maxOps.cloneNodes $ cloneType:#copy newNodes:&nnl select nnl")# have to use Maxscript
	temp = rt.selection[0]
	temp.name = "High_" + original.name
	rt.addmodifier(temp,rt.Turbosmooth(iterations = 2,sepBySmGroups = True))
	rt.addmodifier(temp,rt.Turbosmooth(iterations = 1))
Exemplo n.º 3
0
def new_scene(force=True, do_save=True):
    """
    Creates a new Max scene
    :param force: bool, True if we want to save the scene without any prompt dialog
    :param do_save: bool, True if you want to save the current scene before creating new scene
    """

    if do_save and not force:
        save()
        ACTION_TABLE_ID = 0
        NEW_ACTION_ID = "16"
        rt.EvalMAXScript('actionMan.executeAction ' + str(ACTION_TABLE_ID) + ' "' + str(NEW_ACTION_ID) + '"')
        return

    mxs_function = """fn mf = (
        local windowHandle = DialogMonitorOPS.GetWindowHandle()
        if (windowHandle != 0) then (
            UIAccessor.PressButtonByName windowHandle "Do&n't Save"
        )
        return true
    )
    """
    rt.execute('mf={}'.format(mxs_function))

    rt.DialogMonitorOPS.unRegisterNotification(id=rt.Name('forceNewFile'))
    rt.DialogMonitorOPS.registerNotification(rt.mf, id=rt.Name('forceNewFile'))
    rt.DialogMonitorOPS.enabled = True
    rt.actionMan.executeAction(0, '16')     # new file macro action
    rt.DialogMonitorOPS.unRegisterNotification(id=rt.Name('forceNewFile'))
    rt.DialogMonitorOPS.enabled = False

    return True
Exemplo n.º 4
0
def convert_python_list_to_maxscript_bit_array(python_list):
    """
    Converts given Python list to a MaxScript Byte array
    :param python_list: list
    :return: rt.ByteArray
    """

    rt.execute('fn b2a b = (return b as BitArray)')
    return rt.b2a(python_list)
Exemplo n.º 5
0
def initializeBabylonExport():
    rt.execute('Assembly = dotNetClass "System.Reflection.Assembly"')
    dllPath = os.path.join(rt.symbolicPaths.getPathValue(1),
                           "bin\\assemblies\\Max2Babylon.dll")
    rt.execute('Assembly.loadfrom "{0}"'.format(dllPath))
    rt.execute(
        'maxScriptManager = dotNetObject "Max2Babylon.MaxScriptManager"')
    rt.execute('param = maxScriptManager.InitParameters "c:\\default.gltf"')
    rt.execute('param.logLevel = (dotNetClass "Max2Babylon.LogLevel").WARNING')
    rt.maxScriptManager.InitializeGuidTable()
Exemplo n.º 6
0
def castIntToDotNetEnum(dotnetenum, index):
    '''
    Cast python int to dotnetobject enum
    \nin : 
    dotnetenum= str("dotnetenum") 
    index= int 
    \nout : 
    rt.dotNetObject 
    '''
    animExpType = rt.getPropNames(
        rt.execute('(dotnetclass "{0}")'.format(dotnetenum)))
    prop = rt.name(animExpType[index])
    command = '(dotnetclass "{0}").{1}'.format(dotnetenum, prop)
    return rt.execute(command)
Exemplo n.º 7
0
def setSelectedObjVertexColor():
    rt.execute('max modify mode')
    s = list(rt.selection)
    if s != None and len(s) > 0:
        for nod in s:
            if HasEditPolyn(nod):
                rt.Select(nod)
                rt.subobjectLevel = 1
                rt.actionMan.executeAction( 0 ,"40021")
                nod.SetVertexColor(rt.color( 255, 255, 255), rt.name('VertexColor'))
                nod.SetVertexColor(rt.color( 255, 255, 255), rt.name('Illumination'))
                nod.SetVertexColor(rt.color(255,0,0), rt.name('Alpha'))
                rt.subobjectLevel = 0
                print("Obj {0} Finished".format(nod))
            else:
                print("OBJ {0} is not an Editable Poly, tool cannot perform vertex modifications".format(nod))
Exemplo n.º 8
0
    def _uvSnaps(self, assetName):
        originalSelection = rt.execute("selection as array")
        validShapes = rt.execute(
            "for o in selection where superClassOf o == geometryClass collect o"
        )

        if len(validShapes) > 10:
            msg = "There are %s objects for UV snapshots.\nAre you sure you want to include snapshots to the Asset?" % (
                len(validShapes))
            state = rt.queryBox(msg, title='Too many objects for UV Snapshot')
            if state:
                pass
            else:
                return

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

        if not os.path.isdir(os.path.normpath(UVdir)):
            os.makedirs(os.path.normpath(UVdir))

        rt.execute("max modify mode")

        for i in validShapes:
            objName = i.name
            UVpath = os.path.join(UVdir, '%s_uv.jpg' % objName)
            rt.select(i)
            defUnwrapMod = rt.Unwrap_UVW()
            rt.addModifier(i, defUnwrapMod)
            defUnwrapMod.setMapChannel = 1
            defUnwrapMod.renderuv_fillmode = 0
            defUnwrapMod.renderuv_seamColor = rt.Name("green")
            defUnwrapMod.renderuv_showframebuffer = False
            defUnwrapMod.renderuv_force2sided = False
            defUnwrapMod.renderuv_fillColor = rt.Name("black")
            defUnwrapMod.renderuv_showoverlap = False
            defUnwrapMod.renderuv_overlapColor = rt.Name("red")
            defUnwrapMod.renderuv_edgeColor = rt.Name("white")
            defUnwrapMod.renderuv_visibleedges = True
            defUnwrapMod.renderuv_invisibleedges = False
            defUnwrapMod.renderuv_seamedges = False
            defUnwrapMod.renderUV(UVpath)
            rt.deleteModifier(i, defUnwrapMod)

        rt.select(originalSelection)
Exemplo n.º 9
0
def castStrToDotNetEnum(dotnetenum, string):
    '''
    Find enum value of key string and returns it
    \nin : 
    dotnetenum= str("dotnetenum") 
    string= str  
    \nout : 
    rt.dotNetObject 
    '''
    arg = string.replace(" ", "")
    command = '(dotnetclass "{0}").{1}'.format(dotnetenum, arg)
    return rt.execute(command)
Exemplo n.º 10
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")
Exemplo n.º 11
0
    def setWorkUnits(self):

        #load path and config
        PathConfig = cfgl.configLoader()[99:101]

        if self.cboxSysUnits.currentIndex() == 0:
            rt.execute("units.Systemtype = #meters")
            self.lblInfo_01.setText("Units changed to meters")
            print(self.lblInfo_01.text())
            cfgl.ConfigWriter('Units', 'Custom_System_type_units', 'meters',
                              PathConfig[0], PathConfig[1])

        if self.cboxSysUnits.currentIndex() == 1:
            rt.execute("units.Systemtype = #centimeters")
            self.lblInfo_01.setText("Units changed to centimeters")
            print(self.lblInfo_01.text())
            cfgl.ConfigWriter('Units', 'Custom_System_type_units',
                              'centimeters', PathConfig[0], PathConfig[1])

        if self.cboxSysUnits.currentIndex() == 2:
            rt.execute("units.Systemtype = #millimeters")
            self.lblInfo_01.setText("Units changed to millimeters")
            print(self.lblInfo_01.text())
            cfgl.ConfigWriter('Units', 'Custom_System_type_units',
                              'millimeters', PathConfig[0], PathConfig[1])
Exemplo n.º 12
0
def _add_to_menu(menu, title, callback):
    """
    Add a new action item to the menu and invokes the given callback when selected.

    :param menu: MaxScript menu object to add to.
    :param str title: Name of the action item
    :param callable callback: Method to call when the menu item is selected.
    """
    from tank_vendor.shotgun_api3.lib import six

    # Hash the macro name just like we do in the engine for consistency.
    macro_name = "sg_" + hashlib.md5(six.ensure_binary(
        callback.__name__)).hexdigest()
    category = "Shotgun Bootstrap Menu Actions"
    # The createActionItem expects a macro and not some MaxScript, so create a
    # macro first...
    rt.execute("""
        macroScript {macro_name}
        category: "{category}"
        tooltip: "{title}"
        (
            on execute do
            (
                python.execute "from tk_3dsmax_basic import plugin_bootstrap; plugin_bootstrap.{method_name}()"
            )
        )
    """.format(
        macro_name=macro_name,
        category=category,
        title=title,
        method_name=callback.__name__,
    ))
    # ... and then pass its name down to the createActionItem menu.
    menu_action = rt.menuMan.createActionItem(macro_name, category)
    menu_action.setUseCustomTitle(True)
    menu_action.setTitle(title)
    menu.addItem(menu_action, -1)
Exemplo n.º 13
0
def runPreExportProcess():
    babylonLogger.info("New Pre-Export started at " +
                       str(datetime.datetime.now()))
    rt.execute('logger = dotNetObject "Max2Babylon.MaxScriptLogger" false')
    rt.execute(
        'logger.logLevel = (dotNetClass "Max2Babylon.LogLevel").WARNING')
    rt.execute(
        'preExportProcess = dotNetObject "Max2Babylon.PreExport.PreExportProcess" param logger'
    )
    action = lambda: rt.preExportProcess.ApplyPreExport()
    successMsg = "Pre Export completed"
    return _runBabylonAction(action, successMsg)
Exemplo n.º 14
0
    def pickPoints(self):
        self.geo = self.geometry()
        self.hide()

        try:
            mxs.unregisterRedrawViewsCallback(self.debugView)
        except:
            pass

        try:
            self.pos1 = mxs.pickPoint(
                snap=mxs.readvalue(mxs.StringStream('#3D')))
            self.pos2 = mxs.pickPoint(
                snap=mxs.readvalue(mxs.StringStream('#3D')))

            self.moveVector = self.pos2 - self.pos1

            vector = self.moveVector

            X = mxs.normalize(vector)
            Z = mxs.point3(0, 0, 1)
            Y = mxs.normalize(mxs.cross(Z, X))
            Z = mxs.normalize(mxs.cross(X, Y))

            self.transform = mxs.matrix3(Z, Y, X, mxs.point3(0, 0, 0))

            mxs.WorkingPivot.SetTM(self.transform)
            mxs.execute("max tti")

            mxs.registerRedrawViewsCallback(self.debugView)
            mxs.execute("max move")
            mxs.execute("toolMode.coordsys #working_pivot")
            self.show()
            self.setGeometry(self.geo)

        except:
            print("Point Picking Cancelled")
Exemplo n.º 15
0
def getAssetRefs(filename):
    """
    Gets all references in the scene, based on the BitmapClasses list
    from the settings .json file. This returns a dictionary with the
    materials, geometry, and modifiers associated with the filename.
    @param {str} filename: The full filename to get all references from
    @return {dictionary}
    """
    # Get the .json settings first. This'll list all of the classes to
    # iterate through, and what their respective 'filename' parameter
    # is called.
    data = getSettings()

    materials = []
    geometry  = []
    modifiers = []

    # Iterates through the different MAXScript classes to check through
    for classKey in data["BitmapClasses"]:

        # Get the respective class' denoted 'filename' parameter
        # These vary a bit per class
        paramNames = data["BitmapClasses"][classKey]

        # Get the MAXScript Value of the class
        classValue = rt.execute(classKey)

        # Create an empty list of the nodes we'll look through
        nodes = []

        # If it DOES exist, meaning the standard or 3rd party plugins
        # are found (Max, Arnold, V-Ray, etc.)
        if classValue != None:

            # Get all the instances of that node
            instances = rt.GetClassInstances(classValue)

            for inst in instances:
                # If that node matches the same filename we're currently
                # checking against, then it's a match!
                try:
                    for param in paramNames:
                        if (rt.getProperty(inst, param)) == filename:
                            nodes.append(inst)
                except:
                    pass

        # If we've found 1 or more matching nodes, we'll iterate through them
        if len(nodes) > 0:
            for node in nodes:

                # Get the node's dependents. This'll be a giant array of every
                # dependent found in the scene, which'll include a bunch of
                # nonsense nodes.
                deps = rt.refs.dependents(node)

                # Filter through each dependent and add to each respective list
                # whether it's a subclass of materials, geometry, or modifiers.
                for dep in deps:
                    if rt.superClassOf(dep) == MXS_MATERIAL_CLASS:
                        materials.append(dep)
                    if rt.superClassOf(dep) == MXS_GEOMETRY_CLASS:
                        geometry.append(dep)
                    if rt.superClassOf(dep) == MXS_MODIFIER_CLASS:
                        modifiers.append(dep)

            # Return the mapped dictionary of nodes we found
            return  {
                        "Materials" : materials,
                        "Geometry" : geometry,
                        "Modifiers": modifiers
                    }

    # If we didn't find anything, return an empty dictionary
    return {}
Exemplo n.º 16
0
def run():
    rt.execute('Assembly = dotNetClass "System.Reflection.Assembly"')
    dllPath = os.path.join(rt.symbolicPaths.getPathValue(1),"bin\\assemblies\\Max2Babylon.dll")
    rt.execute('Assembly.loadfrom "{0}"'.format(dllPath))
    rt.execute('maxScriptManager = dotNetObject "Max2Babylon.MaxScriptManager"')
    rt.maxScriptManager.AutoAssignLodInAnimationGroup()
Exemplo n.º 17
0
def setRTParameters(babylonParameters):
    if isinstance(babylonParameters, BabylonParameters):
        rt.execute(
            'param = maxScriptManager.InitParameters "c:\\default.gltf"')
        rt.execute(
            'param.logLevel = (dotNetClass "Max2Babylon.LogLevel").WARNING')
        rt.execute('logger = dotNetObject "Max2Babylon.MaxScriptLogger" false')
        rt.execute(
            'logger.logLevel = (dotNetClass "Max2Babylon.LogLevel").WARNING')
        if (babylonParameters.exportNode):
            rt.param.exportNode = rt.param.GetNodeByHandle(
                babylonParameters.exportNode.inode.handle)
        if (babylonParameters.exportLayers):
            rt.param.exportLayers = rt.param.NameToIILayer(
                babylonParameters.exportLayers)
        rt.param.outputPath = __overwriteIfSet(rt.param.outputPath,
                                               babylonParameters.outputPath)
        rt.param.outputFormat = __overwriteIfSet(
            rt.param.outputFormat, babylonParameters.outputFormat)
        rt.param.textureFolder = __overwriteIfSet(
            rt.param.textureFolder, babylonParameters.textureFolder)
        rt.param.scaleFactor = __overwriteIfSet(rt.param.scaleFactor,
                                                babylonParameters.scaleFactor)
        rt.param.writeTextures = __overwriteIfSet(
            rt.param.writeTextures, babylonParameters.writeTextures)
        rt.param.animationExportType = __overwriteIfSet(
            rt.param.animationExportType,
            babylonParameters.animationExportType)
        rt.param.enableASBAnimationRetargeting = __overwriteIfSet(
            rt.param.enableASBAnimationRetargeting,
            babylonParameters.enableASBAnimationRetargeting)
        rt.param.enableASBUniqueID = __overwriteIfSet(
            rt.param.enableASBUniqueID, babylonParameters.enableASBUniqueID)
        rt.param.overwriteTextures = __overwriteIfSet(
            rt.param.overwriteTextures, babylonParameters.overwriteTextures)
        rt.param.exportHiddenObjects = __overwriteIfSet(
            rt.param.exportHiddenObjects,
            babylonParameters.exportHiddenObjects)
        rt.param.exportMaterials = __overwriteIfSet(
            rt.param.exportMaterials, babylonParameters.exportMaterials)
        rt.param.exportOnlySelected = __overwriteIfSet(
            rt.param.exportOnlySelected, babylonParameters.exportOnlySelected)
        rt.param.usePreExportProcess = __overwriteIfSet(
            rt.param.usePreExportProcess,
            babylonParameters.usePreExportProcess)
        rt.param.applyPreprocessToScene = __overwriteIfSet(
            rt.param.applyPreprocessToScene,
            babylonParameters.applyPreprocessToScene)
        rt.param.flattenGroups = __overwriteIfSet(
            rt.param.flattenGroups, babylonParameters.flattenGroups)
        rt.param.mergeContainersAndXRef = __overwriteIfSet(
            rt.param.mergeContainersAndXRef,
            babylonParameters.mergeContainersAndXRef)
        #rt.param.flattenScene = __overwriteIfSet(rt.param.flattenScene,babylonParameters.flattenScene)
        rt.param.bakeAnimationType = __overwriteIfSet(
            rt.param.bakeAnimationType, babylonParameters.bakeAnimationType)
        rt.param.removeNamespaces = __overwriteIfSet(
            rt.param.removeNamespaces, babylonParameters.removeNamespaces)
        rt.param.removeLodPrefix = __overwriteIfSet(
            rt.param.removeLodPrefix, babylonParameters.removeLodPrefix)
        rt.param.keepInstances = __overwriteIfSet(
            rt.param.keepInstances, babylonParameters.keepInstances)
        rt.param.tangentSpaceConvention = __overwriteIfSet(
            rt.param.tangentSpaceConvention,
            babylonParameters.tangentSpaceConvention)
        rt.param.mergeAOWithMR = __overwriteIfSet(
            rt.param.mergeAOWithMR, babylonParameters.mergeAOWithMR)
Exemplo n.º 18
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, ""
Exemplo n.º 19
0
    def projectVertexColor(self, nodeToBake, nodeToProject, outputPath,
                           padding):
        """
        Project the vertex color of a given node to a given surface and bake the result in the given path 

        Parameters
        ----------
            nodeToBake : INode
                the node used to bake the texture
            nodeToProject : INode
                the node used to project the vertex color
            outputPath : str
                the path of the baked texture
        """
        rt.disableSceneRedraw()
        rt.select(nodeToBake)
        snap = rt.snapshot(nodeToBake, name=nodeToBake.name + "_new")
        snap.material = rt.standard(showInViewport=False, name="GlassMat")
        nodeToProject.material = rt.standard(diffuseMap=rt.Vertex_Color(),
                                             showInViewport=False,
                                             name="WiperMat")
        # --Clear all render elements
        snap.iNodeBakeProperties.removeAllBakeElements()
        # --Preparing the Bake Elements:
        be1 = rt.diffusemap()  # --instance of the bake element class
        be1.outputSzX = be1.outputSzY = 1024  # --set the size of the baked map --specifythe full file path, name and type:
        be1.fileType = outputPath
        be1.fileName = rt.filenameFromPath(be1.fileType)
        be1.filterOn = True  # --enable filtering
        be1.shadowsOn = False  # --disable shadows
        be1.lightingOn = False  # --disable lighting
        be1.enabled = True  # --enable baking
        snap.iNodeBakeProperties.nDilations = padding  # --expand the texturea bit
        snap.iNodeBakeProperties.addBakeElement(be1)  # --add first element
        snap.iNodeBakeProperties.bakeEnabled = True  # --enabling baking
        snap.iNodeBakeProperties.bakeChannel = 2  # --channel to bake
        snap.INodeBakeProjProperties.bakeEnabled = True  # --enabling baking
        snap.INodeBakeProjProperties.bakeChannel = 2  # --channel to bake
        snap.INodeBakeProjProperties.subObjBakeChannel = 2
        snap.INodeBakeProjProperties.enabled = True  #enable projection baking

        # add a projection modifier and set it as the projection source
        projection = rt.Projection()
        rt.addModifier(snap, projection)
        projection.addObjectNode(nodeToProject)
        projection.resetCage()
        snap.INodeBakeProjProperties.projectionMod = projection
        snap.INodeBakeProjProperties.rayMissColor = rt.Point3(0, 0, 0)

        #select the object enter modify mode, offset the cage and bake the texture at the given path

        rt.select(
            snap
        )  # --we are baking the selection, so we select the object --Call the rendererto bake both elements:
        rt.execute("max modify mode")
        projection.pushCage(0.1)
        rt.render(rendertype=rt.Name("bakeSelected"),
                  vfb=False,
                  progressBar=True,
                  outputSize=rt.Point2(1024, 1024))
        print("baked image in {0}".format(be1.fileType))
        rt.delete(snap)
        rt.enableSceneRedraw()
        rt.CompleteRedraw()
Exemplo n.º 20
0
    def buildWiperMesh(self, p1, p2):
        """
        Build the wiper mesh 

        Parameters
        ----------
            p1 : Point3
                the world position of the first dummy placed on the exterior part of the wiper
            p2 : Point3
                the world position of the second dummy placed on the exterior part of the wiper
        """

        animationLength = self.animInEndFrame - self.animInStartFrame + 1
        projectMeshVertices = []
        projectMeshFaces = []

        vColors = [rt.Point3(0, 0, 0) for i in range(animationLength * 2)]

        vert_count = 0

        if rt.DEBUG_MODE:
            print(
                "------------------------------------------------------------------"
            )

        #fill projectMeshVertices with the exterior points of the wiper for each frame
        f = self.animInStartFrame
        while f <= self.animInEndFrame:
            with at(f):
                projectMeshVertices.append(p1.transform.position)
                projectMeshVertices.append(p2.transform.position)
                f += 1

        # fill the vertexColors array during animation IN
        vIndex = 0
        f = self.animInStartFrame
        while f <= self.animInEndFrame:
            with at(f):
                self.setColorByFrame(f, vColors[vIndex])
                self.setColorByFrame(f, vColors[vIndex + 1])
                f += 1
                vIndex += 2

        # fill the vertexColors array during animation OUT
        vIndex = 0
        f = self.animOutEndFrame
        while f >= self.animOutStartFrame:
            with at(f):
                self.setColorByFrame(f, vColors[vIndex])
                self.setColorByFrame(f, vColors[vIndex + 1])
                f -= 1
                vIndex += 2

        axis = rt.Point3(1, 0, 0)
        result = rt.dot(p2.transform.position, axis)

        for i in range(1, len(projectMeshVertices) - 1):
            #build the triangle with the righ orientation
            if i % 2 != 0:
                projectMeshFaces.append(
                    rt.Point3(vert_count + 3, vert_count + 2, vert_count + 1))
            else:
                projectMeshFaces.append(
                    rt.Point3(vert_count + 2, vert_count + 3, vert_count + 1))

            vert_count += 1

        #build the mesh with an array of vertex and triangles
        projectionMesh = rt.mesh(vertices=rt.Array(*(projectMeshVertices)),
                                 faces=rt.Array(*(projectMeshFaces)))
        rt.defaultVCFaces(projectionMesh)

        #set the vertex color for each vertex
        for i in range(len(projectMeshVertices)):
            rt.setVertColor(projectionMesh, i + 1, vColors[i])

        if result > 0:
            rt.select(projectionMesh)
            rt.execute("max modify mode")
            normalModifier = rt.NormalModifier()
            rt.addModifier(projectionMesh, rt.NormalModifier())
            normal = rt.Name("Normal")
            projectionMesh.modifiers[normal].flip = True

        rt.maxOps.CollapseNode(projectionMesh, False)

        #quadrify
        rt.select(projectionMesh)
        rt.convertToPoly(projectionMesh)
        rt.execute("max modify mode")
        rt.PolyToolsModeling.Quadrify(True, False)
        edge = rt.Name("EDGE")
        edgeNumber = projectionMesh.EditablePoly.getNumEdges()
        edgeList = [1] if result < 0 else [2]
        edgeSelection = rt.BitArray(*(edgeList))
        rt.subObjectLevel = 2
        projectionMesh.EditablePoly.SetSelection(edge, edgeSelection)
        projectionMesh.EditablePoly.SelectEdgeRing()
        projectionMesh.connectEdgeSegments = 3
        rt.execute('macros.run "Ribbon - Modeling" "ConnectEdges"')

        return projectionMesh
Exemplo n.º 21
0
def execute():

    # Define the target object
    my_target = mxs.selection[0]

    # Reset the pivot
    my_target.pivot = my_target.center

    # Define the grid object
    my_grid = mxs.grid()

    # Define the vector
    vector = my_target.transform.position - mxs.inverse(
        mxs.viewport.getTM()).position

    # Define the length of the target
    distance = (mxs.length(my_target.min - my_target.max) / 2)

    # Normalize + UP vector (Z)
    X = mxs.normalize(vector)
    Z = mxs.point3(0, 0, 1)
    Y = mxs.normalize(mxs.cross(Z, X))
    Z = mxs.normalize(mxs.cross(X, Y))

    # Define a new transform based on vector
    my_transform = mxs.matrix3(Z, Y, X, my_target.transform.position)

    # Edit the position of the transform
    new_position = my_transform.position - (X * distance)
    my_transform = mxs.matrix3(Z, Y, X, new_position)

    # Assign the transform to the grid
    my_grid.transform = my_transform

    # Activate the grid
    mxs.activegrid = my_grid

    # Define spline method
    def setMode(name):
        name.curveType = 1

    try:
        # Set iso view
        mxs.execute("max vpt iso user")

        # Define user draw curves
        curves = mxs.startObjectCreation(mxs.FreehandSpline,
                                         returnNewNodes=True,
                                         newNodeCallback=setMode)

        # Define modifiers
        noise_mod = mxs.Noisemodifier()
        quad_mod = mxs.Quadify_Mesh()
        extrude_mod = mxs.Extrude()

        # Change the parameters
        extrude_mod.amount = distance * 2
        quad_mod.quadsize = 2
        noise_mod.scale = 10
        noise_mod.fractal = True
        noise_mod.strength = mxs.point3(2, 10, 2)

        # Add the modifiers
        mxs.addmodifier(curves, extrude_mod)
        mxs.addmodifier(curves, quad_mod)
        mxs.addmodifier(curves, noise_mod)

        # Define cutter splines
        mxs.ProCutter.CreateCutter(curves, 1, True, True, False, True, True)

        # Define stock object
        mxs.ProCutter.AddStocks(curves[0], my_target, 1, 1)

        # Set perspective view
        mxs.execute("max vpt persp user")

        # Deactivate and delete the grid
        mxs.activegrid = None
        mxs.delete(my_grid)

    except:

        # Set perspective view
        mxs.execute("max vpt persp user")

        # Deactivate and delete the grid
        mxs.activegrid = None
        mxs.delete(my_grid)

        print("cancled")
Exemplo n.º 22
0
from pymxs import runtime as rt
import sys, os

# Paths
ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
sys.path.append(ROOT_DIR)

# Indexes
ITEM_NAME = 1
ITEM_EXT = 2
ITEM_PATH = 3
ITEM_TYPE = 4
ITEM_STATUS = 5
ITEM_SIZE = 6

# MAXScript Types
MXS_MATERIAL_CLASS = rt.execute("material")
MXS_GEOMETRY_CLASS = rt.execute("geometryclass")
MXS_MODIFIER_CLASS = rt.execute("modifier")
Exemplo n.º 23
0
from pymxs import runtime as rt
import os
import sys
import importlib

sys.path.append(os.path.dirname(__file__))
from maxsdk.globals import *

# start installing FlightSim material and legacy maxscript script
c = os.path.dirname(__file__)
cmd = 'filein @"{0}\\..\\msfs_max_ms\\FlightSim_EntryPoint.ms"'.format(c)
rt.execute(cmd)

IS_PUBLIC_SDK = rt.globalVars.get("IS_PUBLIC_SDK")

if not IS_PUBLIC_SDK:
    if MAXVERSION() >= MAX2021:
        from configparser import ConfigParser
        configur = ConfigParser()
        configur.read(os.path.join(c, 'internal_tools.ini'))
        internal_modules = []
        for k in configur["INTERNAL"]:
            internal_modules.append(configur["INTERNAL"].get(k))
    else:
        from ConfigParser import RawConfigParser
        configur = RawConfigParser()
        configur.read(os.path.join(c, 'internal_tools.ini'))
        internal_modules = []
        for (a, b) in configur.items("INTERNAL"):
            internal_modules.append((a, b)[1].replace('"', ''))
Exemplo n.º 24
0
    def DeletedFrame(self, startFrame, endFrame):
        # rt.animationRange = rt.interval(0, 1)
        #프레임삭제
        max_script = '''
            fn GetAnimationRange_Interval target_nodeArray:(objects as Array)=
            (
                local keyIdex_int = 0
                local startKeyArray = #()
                local endKeyArray = #()
                local startFrame = undefined
                local endFrame = undefined

                for obj in target_nodeArray do (
                    if classof(obj.controller) == prs do (
                        keyIdex_int = numKeys obj.pos.controller
                        if (keyIdex_int != undefined and keyIdex_int >= 1) do
                        (
                            append startKeyArray (obj.pos.controller.keys[1]).time
                            append endKeyArray (obj.pos.controller.keys[keyIdex_int]).time
                        )
                        keyIdex_int = numKeys obj.rotation.controller
                        if (keyIdex_int != undefined and keyIdex_int >= 1) do
                        (
                            append startKeyArray (obj.rotation.controller.keys[1]).time
                            append endKeyArray (obj.rotation.controller.keys[keyIdex_int]).time
                        )
                        keyIdex_int = numKeys obj.scale.controller
                        if (keyIdex_int != undefined and keyIdex_int >= 1) do
                        (
                            append startKeyArray (obj.scale.controller.keys[1]).time
                            append endKeyArray (obj.scale.controller.keys[keyIdex_int]).time
                        )
                    )
                    if ClassOf obj == Biped_Object do 
                    (
                        keyIdex_int = numKeys obj.controller
                        if (keyIdex_int != undefined and keyIdex_int >= 1) do
                        (
                            append startKeyArray (biped.getKey obj.controller 1).time
                            append endKeyArray (biped.getKey obj.controller keyIdex_int).time
                        )
                    )
                )
                makeUniqueArray startKeyArray
                makeUniqueArray endKeyArray
                sort startKeyArray
                sort endKeyArray

                if startKeyArray.count > 0 then
                (
                    startFrame
                    startKey_integer = 0
                    i_int = 1
                    --while (startFrame == undefined and i_int < startKeyArray.count  ) do (
                    --    startKey_integer = (startKeyArray[i_int] as integer)/TicksPerFrame
                    --    if startKey_integer > -9999 do 
                    --    (
                    --        startFrame = startKeyArray[i_int]
                    --    )
                    --    i_int = i_int + 1
                    --)
                    startFrame = startKeyArray[i_int]
                    endFrame = endKeyArray[endKeyArray.count]
                )
                else 
                (
                    startFrame = 0
                    endFrame = 1
                )
                if (startFrame == undefined ) do 
                (
                    startFrame = 0
                )
                if (endFrame == undefined) do 
                (
                    endFrame == 1
                )
                if (startFrame == endFrame) do 
                (
                    endFrame = endFrame+1
                )
                reInterval = Interval startFrame endFrame
            )
            fn OutOfFrameDelet_fn arg_objs_array =
            (
                local startFrame =  copy(animationRange.start.frame)
                local endFrame =  Copy(animationRange.end.frame)
                local goObjs_array = #()
                local fullAniRange_interval = GetAnimationRange_Interval()
                print fullAniRange_interval
                goObjs_array = arg_objs_array
                    for obj in goObjs_array do
                    (
                        keyIdex_int = 0
                        obj_ctrl = obj.controller
                        deselectKeys obj.controller
                        selectKeys obj.controller
                        deselectKeys obj.controller (interval startFrame endFrame)
                        if ClassOf(obj) == biped_Object do
                        (
                            if (getClassName obj_ctrl == "Body") then
                            (
                                deleteKeys obj.controller.vertical.controller.keys #selection
                                deleteKeys obj.controller.horizontal.controller.keys #selection
                                deleteKeys obj.controller.turning.controller.keys #selection
                            )
                            else if obj.controller.keys.count > 0 do
                            (
                                deleteKeys obj.controller.keys #selection
                            )
                        )
                        if endFrame < fullAniRange_interval.end do 
                        (
                            deleteTime obj (endFrame+1) (fullAniRange_interval.end + 1)
                        )
                        if fullAniRange_interval.start < (startFrame - 1) do 
                        (
                            deleteTime obj (fullAniRange_interval.start - 1) (startFrame-1) #noSlide
                        )
                    )
            )
            OutOfFrameDelet_fn (objects as Array)
        '''
        rt.execute(max_script)
Exemplo n.º 25
0
 def _import(self, filePath, prompt=True, *args, **kwargs):
     if prompt:
         fManager.Merge(filePath)
     else:
         command = 'mergeMAXFile "%s"' % filePath.replace(os.sep, "/")
         rt.execute(command)
Exemplo n.º 26
0
 def _getSelection(self, asMaxArray=False):
     sel = rt.execute("selection as array")
     if not asMaxArray:
         return [x.name for x in sel]
     else:
         return sel
Exemplo n.º 27
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)