[maxscript教程] 函数库
MaxScriptMAX脚本 3839 24
实名

通过了实名认证的内容创造者

发布于 2018-6-17 16:10:05

您需要 登录 才可以下载或查看,没有账号?注册

x
Snipaste_2018-07-07_17-55-57.jpg

把一些常用的自定义函数放在一个统一的脚本中,之后在编写脚本时就不需要重复编写,这时就需要用到库函数。库函数除了可以简化脚本的操作外,还可以在Maxscript Listener(后面简称 侦听器)中当做宏来使用。

新建一个.ms文件放到maxscript的安装目录的startup文件夹下,如果不知道安装目录可以在侦听器中输入 getdir #Scripts,我返回的是:
D:\Program Files\Autodesk\2013\3ds Max 2013\scripts  好吧,我现在写教程是用的2013的环境,因为max9实在太老了,而且内置编辑器很难用。

比如我取名叫 EZ_Global.ms ,之所以以EZ开头是因为学maxscript ,瘦 easy;然后我就可以将以前常用的自定义函数放入其中了。比如上一节讲到的 isUsualObj
--常用公用函数定义
fn isUsualObj obj = (  --是否为常规物体
        isValidObj obj and canConvertTo obj Editable_Poly and classof obj.baseobject !=boneGeometry and classof obj.baseobject!=Biped_Object
)


每次编写完成后需要按ctrl+E 来确定脚本可以运行,并读到内存,之后其它脚本才能识别新功能。在后续的教程中,如果运行报错,会弹出提示框
下面是我的库函数,将一一讲解各函数的功能;函数有点多,也可以下载脚本查看链接:https://pan.baidu.com/s/1Q8x-aiBkS-AQyTUhTlp8Ag 密码:0yp0

fn isEndWith str endstr = ( --str是否以endstr结尾
        if str.count < endstr.count then false
        else (
                firstInd = (str.count - endstr.count + 1)
                if firstInd > 0 and substring str firstInd -1 == endstr then true
                else false
        )
)

fn getDirPath thePath = ( --获得不带斜线的路径,或者说去除路径结尾的斜线
        result = ""
        if isEndWith thePath "/" or isEndWith thePath "\\" then result = substring thePath 1 (thepath.count-1)
        else (
                thePath = getfilenamePath thePath
                result = substring thePath 1 (thepath.count-1)
        )
        result
)

fn getDirName thePath = ( --获得上一层目录的名字
        dirPath = getDirPath thePath
        fileNameFromPath dirPath
)

--常用公用函数定义
fn isUsualObj obj = (  --是否为常规物体
        isValidObj obj and canConvertTo obj Editable_Poly and classof obj.baseobject !=boneGeometry and classof obj.baseobject!=Biped_Object
)
        
fn getMinBound obj cen:[0,0,0]=(        --获得模型的最小外框,以世界坐标为准;cen为任意坐标
        t = [0,0,0]
        if (isUsualObj obj) then(  --单个标准物体
                t=[(obj.max.x-obj.min.x),(obj.max.y-obj.min.y),(obj.max.z-obj.min.z)]
                cen = obj.center
        )
        else if classof obj == Array then (  --多个物体集合
                if obj.count==1 then (
                        t= getMinBound (obj[1]) cen:(obj[1].center)
                )
                else if obj.count>1 then (
                        xmax=xmin=obj[1].x
                        ymax=ymin=obj[1].y
                        zmax=zmin=obj[1].z
                        cen = obj[1].center
                        for i=2 to obj.count do(
                                if obj.x>xmax then xmax=obj.x
                                if obj.x<xmin then xmin=obj.x
                                if obj.y>ymax then ymax=obj.y
                                if obj.y<ymin then ymin=obj.y
                                if obj.z>zmax then zmax=obj.z
                                if obj.z<zmin then zmin=obj.z
                                cen+=obj.center
                        )
                        t=[xmax-xmin,ymax-ymin,zmax-zmin]
                        cen/=obj.count
                )
        )
        t
)
-- dotnet 获取选择的多个文件
Fn GetMutiOpenFileName Title:"Select Files" FileFilter:"All Files (*.*)|*.*"  =
(
    local OpenFileDialog,OpenFileResult
    OpenFileDialog = DotNetObject "System.Windows.Forms.OpenFileDialog"
    OpenFileDialog.title = Title
    OpenFileDialog.Multiselect = true
    OpenFileDialog.Filter = FileFilter
    OpenFileDialog.FilterIndex = 1
    OpenFileResult = OpenFileDialog.ShowDialog()
    if OpenFileResult.Equals OpenFileResult.OK then
    (
        OpenFileDialog.FileNames
    )
    else Undefined
)

fn createEmptyPoly pos: =( --创建空物体,主要用于合并主物体的位置初始化
        b = box pos:pos
        convertTo b Editable_Poly
        b.EditablePoly.SetSelection #Vertex #{1..8}
        b.EditablePoly.delete #Vertex
        b
)

fn sum valArr = ( --求数组的和,会过滤undefined值,使用前请确认
        num = 0
        for i=1 to valArr.count where valArr!=undefined do num+=valArr
        num
)

fn average what =( --求数组的平均值
        if classof what == array then(
                if what.count>1 then (
                        num = sum what
                        num/=(what.count)
                        return num
                )
                else if what.count==1 then return (what[1])
                else return 0
        ) else return undefined
)
        
fn num2seq num length = ( --数字转序列,例如 (num2seq 789 4)将789转换为"0789"
        numstr = num as string
        zeros = length - numstr.count
        if zeros<=0 do return numstr
        result = ""
        for i=1 to zeros do append result "0"
        result+=numstr
)

-- 根据路径创建文件夹
fn creatDirBy Path = (
        if isEndWith Path "\\" or isEndWith Path "/" do (
                dirNames = filterstring path "\\,/"
                if not doesFileExist dirNames[1] then (messagebox (dirNames[1] + "盘不存在,创建失败!") ; return 0 )
                else (
                        currPath = dirNames[1]
                        for i=2 to dirNames.count do (
                                currPath += "\\" + dirNames
                                if not doesFileExist currPath do makedir currPath
                        )
                )
        )
)

fn delListItem listBox index =( --删除ListBox控件中的第index行的数据
        arrTemp = listBox.items
        deleteItem arrTemp index
        listBox.items = arrTemp
)

fn equals arr1 arr2=(       --判断两个数组是否完全相等
        if arr1.count!=arr2.count then false
        else (
                for i=1 to arr1.count do(
                        if arr1!=arr2 do false
                )
                true
        )
)

fn arrToStr arr =( --将数组转成字符串形式,直接format超长array到文件可能出现省略的情况
        if not (iskindof arr array) then undefined
        else if arr.count == 0 then "#()"
        else (
                result ="#("
                for i in arr do result+=(i as string)+","
                result = substring result 1 (result.count-1)
                result +=")"
                result
        )
)

-- 字符串转为大写字母
fn uppercase instring = (
        local upper, lower, outstring
        upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        lower="abcdefghijklmnopqrstuvwxyz"
        outstring=copy instring
        for i=1 to outstring.count do (
                j=findString lower outstring
                if (j != undefined) do outstring=upper[j]
        )
        outstring
)

-- 二进制字符串转十六进制字符串
fn bin2hex bin_str =
(
        local result = 0
        local num = bin_str as Integer
        local maxn = floor(log10 num) + 1
        for i=1 to maxn do
        (
                local n = floor(mod num (pow 10 i)/floor(pow 10 (i-1)))
                result = result + n*(pow 2 (i-1))
        )
        toUpper (bit.intAsHex result)
)

-- 十六进制字符串转二进制字符串
fn hex2bin hex_str =
(
        local num = ("0x"+(toLower hex_str)) as integer
        
        temp = #()
    result = ""
    while num!=0 do
        (
                local n = mod num 2
        num = floor (num/2)
        append temp (n as integer)
        )

    for i=temp.count to 1 by -1 do
                result = result + temp as string

    return result
)

fn findLastString str substr =(  --可以使用findLastString "ABxx3xxxx4xxx567x8" "xx"测试;找到最后一个字符串的索引
        lastInd = ind = 0
        while ((ind = findstring str substr) !=undefined) do(
                str = substring str (ind+1) -1
                lastInd+=ind
        )
        lastInd
)

-- 逐字符过滤字符串,与官方的filterstring不同
fn filterstr str findstr &strs= (
        ind = findstring str findstr
        if ind !=undefined then (
                if ind > 1 do (
                        cutstr = substring str 1 (ind-1)
                        append strs cutstr
                )
                levstr = substring str (ind + findstr.count) -1
                filterstr levstr findstr &strs
        )
        else if str!="" then append strs str
)

fn replaceString str findStr replaceStr filterStand:on =( --默认开启标准filter,需要使用逐字符过滤就关闭
        strArr = #()
        if filterStand then (
                strArr = filterstring str findstr
        ) --filterstring "xxx-xxx-xxx" "x-x"结果为#()空,不是#("xx","x","xx")
        else(
                filterstr str findstr &strArr
        )
        firstInd = findstring str findstr
        lastkey  = findLaststring str findstr
        result = ""
        for i=1 to strArr.count do append result (strArr+replaceStr)
        if lastkey+findstr.count != str.count+1 do result = substring result 1 (result.count-replaceStr.count) --替换字符串不为尾项就掐掉
        if firstInd == 1 do result = replaceStr + result  --替换字符串为首项就添加替换字符到最前
        result
)

fn getLastWord str flagStr =( --获取最后一个flagStr后面的字符串,结合getfilenamePath可用于获取文件所在的目录名称
        lastInd = findLastString str flagStr
        lastWord = substring str (flagStr.count+lastInd) (str.count-flagStr.count-lastInd+1)
        lastWord
)

-- 判断path是否为目录路径
fn isDirectory path = (
        try (
                getFileAttribute path #directory
        )
        catch ( false )
)

-- 规格化目录路径为以"/"结尾
fn formatDir path = (
        if isDirectory path then (
                path = replaceString path "\\" "/"
                if isEndWith path "/" then (
                        path
                )
                else (
                        path + "/"
                )
        )
        else (
                path
        )
)

-- 获得目录的父目录
fn GetParentDir path = (
        if isDirectory path then (
                if isEndWith path "/" or isEndWith path "\\" then (
                        path = substring path 1 (path.Count-1)
                        GetFilenamePath path
                )
                else
                        GetFilenamePath path
        )
        else (
                GetFilenamePath path
        )
)

-- 所有cmpstr 用 stricmp 代替, 在不认识 stricmp 之前我一直用这个自定义函数在处理字符串排序,其实功能一样的
fn cmpstr str1 str2 = ( --主要用于qsort函数的比较参数,其参数的比较函数多数都是字符串比较的再封装
        if str1 < str2 then -1
        else if str1 > str2 then 1
        else 0
)

-- 比较4长度的seq
fn cmp4seq str1 str2 = (
        str1 = num2seq (str1 as integer) 4
        str2 = num2seq (str2 as integer) 4
        stricmp str1 str2
)

fn cmpNodeByName obj1 obj2 = ( --用于qsort中按名称为结点选择集排序的比较函数
        stricmp obj1.name obj2.name
)

fn sortObjs objArr = ( --对对象集合按名字排序        
        qsort objArr cmpNodeByName
        objArr
)

fn getNodeById autoId objSel:objects = ( --类似于getNodeByName,依据autoId获取唯一结点
        for obj in objSel where (getAppData obj g_const_autoId) == autoId do return obj
        undefined
)

fn getObjGroupBy g_const_id objSel:objects = ( --通过key-value获得对象组#(#(obj1,obj2),#(obj3,obj4),#(obj5)) 每个组的value相同
        result = #()
        objInfos = for obj in objSel where getAppData obj g_const_id != undefined collect (pairData v1:obj v2:(getAppData obj g_const_id))
        for i=1 to objInfos.count where objInfos != undefined do (
                groupSel = #( objInfos.v1)
                for j=i+1 to objInfos.count  where objInfos[j] != undefined do (
                        if objInfos[j].v2 == objInfos.v2 do (
                                append groupSel (objInfos[j].v1)
                                objInfos[j] = undefined
                        )
                )
                append result groupSel
        )
        result
)

fn getIdGroupBy g_const_id objSel:objects = ( --通过key-value获得id组#(#(id1,obj2),#(id3,id4),#(id5)) 每个组的id对应obj的value相同
        --暂不写
)

fn setAutoId objSel:objects begin:1 = ( --对选择集自动设置id
        for i=1 to objSel.count do (
                seq = num2seq ( begin + i - 1 ) 4
                setAppData objSel g_const_autoId seq
        )
        return begin
)

fn getRefBones obj = ( --获取绑定骨骼列表,这些骨骼并非全部影响obj,有些是影响该obj的骨骼的父骨骼,而这些父骨骼并没有影响obj,或许他们也不在skin的骨骼列表内
        if obj.Skin==undefined do return undefined
        iBones = for o in objects where (refs.dependencyLoopTest (obj.skin) o) collect o
        iBones
)

fn getBonesNameFrom ASCIIenv = (  --从ASCII格式的蒙皮信息保存文件.env中获取骨骼信息,不能使用windows.getChildHWND #max "Parameters"的方法,因为max9不支持
        local boneNames = #()
        if doesFileExist ASCIIenv  do(
                inFile = openFile ASCIIenv
                if inFile != undefined do (
                        while not (eof inFile) do(
                                str = readLine inFile
                                if substring str 1 10 == "[boneName]" then (
                                        append boneNames (substring str 12 -1)
                                )
                        )
                )
        )
        boneNames
)

-- 获得对象的顶点数目
fn getVCount obj = (
        if classof obj == Editable_Poly then polyOp.getNumVerts obj
        else getNumVerts (obj.mesh)
)

fn getBonesNameOf selArr bonesNames:#() = ( --获取影响选定部件的骨骼名称列表,而那些不影响selArr却在skin的骨骼列表中的骨骼名称则获得不到
        for o in selArr do(
                boneArr=#()
                sk = o.modifiers[#Skin]
                select o
                modPanel.setCurrentObject sk --skin必须被选中
                obj = o.baseobject
                select o --一个skin同时套在多个部件上时,容易导致选择错误
                for i=1 to (getVCount obj) do(
                        boneCount = skinOps.GetVertexWeightCount sk i
                        for c=1 to boneCount where (skinOps.GetVertexWeight sk i c!=0.0) do(
                                boneID = skinOps.GetVertexWeightBoneID sk i c
                                append boneArr boneID
                        )
                )
                boneIDArr = (boneArr as bitarray) as array
                -- sort boneIDArr

                for sboneId in boneIDArr do(
                        boneName = skinOps.GetBoneName sk sboneId 0  --or 1?
                        if findItem bonesNames boneName == 0 do append bonesNames boneName
                )
        )
        bonesNames
)

Fn GetSkinBones inputSkin =( --之所以用 IsProperty 来判断是因为max可以用任意具有transform的物体来做骨骼,对美术来说就是“只要可以移动旋转缩放的东西就可以作为骨骼使用”。
    result = #()
    if ClassOf inputSkin == Skin do (
        result = for tempObject in Refs.DependsOn inputSkin where IsProperty tempObject #transform collect tempObject
    )
    result
)

fn saveSkinInfo obj envFile = (  --保存蒙皮信息 obj为要保存蒙皮信息的部件,envFile为蒙皮信息文件地址
        skinBones = #()
        setCommandPanelTaskMode mode:#modify
        if $bip01!=undefined do $bip01.controller.figureMode=true --进入体积模式
        select obj
        skinOps.SaveEnvelopeAsASCII obj.skin envFile
        skinBones = getBonesNameFrom envFile
        deleteModifier obj 1
        skinBones
)

fn setEnvLoadAutoPressOK flag:true = ( --设置加载env文件时自动按OK键 默认为true自动监听并按下,为false时停止自动
        if flag then (
                DialogMonitorOPS.unRegisterNotification id:#skinBoneListInfo
                fn autoPressOK = (
                        WindowHandle = DialogMonitorOPS.GetWindowHandle()
                        if UIAccessor.GetWindowText WindowHandle == "Load Envelopes" do (
                                skinBoneCtrls = UIAccessor.GetChildWindows WindowHandle
                                for hand in skinBoneCtrls where UIAccessor.GetWindowText hand == "OK" do UIAccessor.PressButton hand
                        )
                        true
                )
                DialogMonitorOPS.RegisterNotification autoPressOK id:#skinBoneListInfo
                DialogMonitorOPS.Enabled = true
                --DialogMonitorOPS.ShowNotification()
        )
        else(
                DialogMonitorOPS.unRegisterNotification id:#skinBoneListInfo --不应该将其简单的注销,否则所有窗口都将显示不正常
                DialogMonitorOPS.Enabled = false                             --一定要关闭窗口自动操作
        )
)

fn loadSkinInfo obj envFile skinBones = ( --自动加载蒙皮信息,obj为要加载蒙皮的部件,envFile为蒙皮信息文件,skinBones为蒙皮骨骼列表
        addModifier obj (Skin())
        modPanel.setCurrentObject obj.modifiers[#Skin] --不添加这一句会出现未知系统异常
        for aBone in skinBones do(
                skinOps.addbone obj.modifiers[#Skin] (getNodeByName aBone) 0
        )
        setEnvLoadAutoPressOK()
        skinOps.LoadEnvelopeAsASCII obj.modifiers[#Skin] envFile
        setEnvLoadAutoPressOK flag:false
        --skinOps.LoadEnvelope obj.modifiers[#Skin] (CacheDir+"skinTemp.env")
        if $bip01!=undefined do $bip01.controller.figureMode=false
)


fn getIconFromBitmap fName iconW iconH = (  --获得位图的缩略图
        if iskindof fName bitmap then img = fName
        else if iskindof fName string then img = openBitmap fName
        else return undefined
        newImage = bitmap iconW iconH color:black
        copy img newImage
        newImage
)

fn append_if_unique arr val = ( --该方法max9没有,max2008以上版本才有,所以这里要自己写
        if findItem arr val == 0 then ( append arr val; return true )
        else return false
)

fn getVertColors meshobj =( --与getvertcolor不同,不是获取指定cpv索引的顶点色,而是获取各顶点索引对应的颜色值
        vertBuffer = #()
        for f in meshobj.faces as bitarray do (
                gverts = getFace meshobj f
                mverts = getVCFace meshobj f
                for k=1 to 3 do (
                        if vertBuffer[gverts[k]] == undefined do vertBuffer[gverts[k]] = #()
                        append_if_unique vertBuffer[gverts[k]] mverts[k]
                )
        )
        vertBuffer
)

fn isEnglish char = (    --判断字符是否为英文字符
        if char == undefined or char == "" then return false
        _ascii = bit.charasint char --把字符转换成int类型(整形)
        
        -- ASCII为32以后的是一些键盘上的功能项,
        -- 33到127内包含有键盘上的特殊标点符号,和数字,大小写字母,常规数学符号
        if ( _ascii > 32 and _ascii < 128) then
        (
                        return true --如果是单字节,返回true
        )
        return false --是双字节,返回false
)

fn arrAsSetColl arr=(  --去除array中的重复元素  与max2009中的makeUniqueArray 方法类似
        return ((arr as bitarray) as array)
)
--描述\t数据        各数据之间也是用\t分离,使用时无需了解函数内部使用什么字符分离
fn splitArr arr desc content =( -----分离描述和数据
        for i=1 to arr.count do (
                arrTemp = filterstring arr "\t"
                append desc arrTemp[1]
                contentStr = ""
                for i=2 to arrTemp.count do(
                        contentStr+=";"+arrTemp
                )
                contentStr = substring contentStr 2 -1
                append content contentStr
        )
)

fn mergeArr desc content =(   --合并描述和数据
        local arr=#() --必须赋空值
        for i=1 to desc.count do(
                arrTemp = filterstring (content as string) ";"
                contentStr = ""
                for i=1 to arrTemp.count do(
                        contentStr+="\t"+arrTemp
                )
                append arr (desc+contentStr)
        )
        arr
)

fn loadFileByReadLine filename =( ----------------使用readLine方法读取文件
        local localArr = #()
        if doesfileExist filename  then (
                inFile = openFile filename
                if inFile != undefined do (
                        if eof inFile do format "File: \"%\" content incorrect!" filename
                        while not (eof inFile) do(
                                append localArr (readLine inFile)
                        )
                        close inFile
                )
        )
        else format "filename:% does not exist!\n" filename
        localArr
)

fn loadFileByExecuteLine filename =( ----------------使用readLine方法执行文件
        local localArr = #()
        if  doesfileExist filename then (
                inFile = openFile filename
                if inFile != undefined do (
                        if eof inFile do messagebox ("File: \" " + filename + "\" content incorrect,
                        please try to new one by yourself,
                        and copy content to the txt file you created!")
                        while not (eof inFile) do(
                                append localArr (execute (readLine inFile))
                        )
                        close inFile
                )
        )
        else format "filename:% does not exist!\n" filename
        localArr
)

fn GetImgTypeObj imgType ImgTypeObjs:#() = ( -- 获得带有某个类型的贴图的所有物体
        fn AddImgTypeObjs map obj imgType ImgTypeObjs = (
                ext = getFilenameType map ;
                if( uppercase ext == uppercase imgType ) do (
                        if( 0 == (findItem ImgTypeObjs obj) ) do append ImgTypeObjs obj;
                )
        )

        for obj in objects where( undefined != obj.Material ) do
        EnumerateFiles obj AddImgTypeObjs obj;

        ImgTypeObjs;
)

fn ConvertToBitmap oldName FreeImage:(DotNetClass "FreeImageAPI.FreeImage") = (
        FREE_IMAGE_FORMAT = DotNetClass "FreeImageAPI.FREE_IMAGE_FORMAT"
        FREE_IMAGE_LOAD_FLAGS = DotNetClass "FreeImageAPI.FREE_IMAGE_LOAD_FLAGS"
        dib = undefined
        result = undefined
        try (FreeImage.unload dib) catch()
        imgType = FreeImage.getfiletype oldName 0
        if imgType == FREE_IMAGE_FORMAT.FIF_BMP then
        (
           result = new Bitmap(oldName);
        )
        else (
                if imgType == FREE_IMAGE_FORMAT.FIF_TARGA then
                (
                        dib = FreeImage.load (FREE_IMAGE_FORMAT.FIF_TARGA) oldName (FREE_IMAGE_LOAD_FLAGS.TARGA_LOAD_RGB888)
                )
                else if imgType == FREE_IMAGE_FORMAT.FIF_TARGA then
                (
                        dib = FreeImage.Load (FREE_IMAGE_FORMAT.FIF_TARGA) oldName (FREE_IMAGE_LOAD_FLAGS.TARGA_LOAD_RGB888);
                )
                else if imgType == FREE_IMAGE_FORMAT.FIF_DDS then
                (
                        dib = FreeImage.Load (FREE_IMAGE_FORMAT.FIF_DDS) oldName (FREE_IMAGE_LOAD_FLAGS.JPEG_ACCURATE);
                )
                else if imgType == FREE_IMAGE_FORMAT.FIF_BMP then
                (
                        dib = FreeImage.Load (FREE_IMAGE_FORMAT.FIF_BMP) oldName (FREE_IMAGE_LOAD_FLAGS.TIFF_CMYK);
                )
                else if imgType == FREE_IMAGE_FORMAT.FIF_JPEG then
                (
                        dib = FreeImage.Load (FREE_IMAGE_FORMAT.FIF_JPEG) oldName (FREE_IMAGE_LOAD_FLAGS.JPEG_ACCURATE);
                )
                else if imgType == FREE_IMAGE_FORMAT.FIF_PNG then
                (
                        dib = FreeImage.Load (FREE_IMAGE_FORMAT.FIF_PNG) oldName (FREE_IMAGE_LOAD_FLAGS.JPEG_ACCURATE);
                )
                else if imgType == FREE_IMAGE_FORMAT.FIF_PSD then
                (
                        dib = FreeImage.Load (FREE_IMAGE_FORMAT.FIF_PSD) oldName (FREE_IMAGE_LOAD_FLAGS.JPEG_ACCURATE);
                )
                else if imgType == FREE_IMAGE_FORMAT.FIF_ICO then
                (
                        dib = FreeImage.Load (FREE_IMAGE_FORMAT.FIF_ICO) oldName (FREE_IMAGE_LOAD_FLAGS.ICO_MAKEALPHA);
                )
                if dib.isnull do return undefined
                try (
                        result = FreeImage.getbitmap dib
                ) catch ( dib.SetNull();return undefined )
                dib.SetNull()
        )
        result -- 返回的是 dotNetObject:System.Drawing.Bitmap
)

fn cvtImgFormat oldName newName = (
        if FreeImageIsWorking then (
                if not doesFileExist oldName do return undefined
                fi = DotNetClass "FreeImageAPI.FreeImage"
                result = ConvertToBitmap oldName FreeImage:fi
                if result != undefined then fi.SaveBitmap result newName
                else print (newName + "保存失败!因为" +oldName+"无法转换!")
                return result
        )
        else (
                print "FreeImage.dll/FreeImageNet.dll加载出错,无法正常转换"
                return undefined
        )
)

fn changeFileType tagFileType cvt:false = ( -- 改变贴图路径的文件名后缀
        bitmapInstances = getClassInstances Bitmaptexture
        for m in bitmapInstances do (
                if(isProperty m #filename)do (
                        fname = m.filename;
                        newName = ( getfilenamePath fname) + ( getfilenamefile fname) + tagfileType
                        if cvt do cvtImgFormat fname newName
                        m.filename = newName
                )
        )
)

fn findFile tagPath fileName=(       ------------从tagPath目录及其子目录中查找filName文件,返回该路径
        local realPath = undefined
        if tagPath==undefined or fileName==undefined do return realPath
        if doesFileExist (tagPath+filename) then (
                realPath = tagPath+fileName
                return realPath
        )
        else(
                dirs = getDirectories (tagPath+"*")               
                for i in 1 to dirs.count where getFileAttribute dirs #hidden == false do (
                        thePath = findFile dirs fileName
                        if thePath!=undefined do ( return thePath)
                )
        )
        realPath
)
-------------------------------------------------------------获得所有类型的文件
Fn GetAllFiles inputPath inputFilterList outArray:#() =
(
    directories = GetDirectories (inputPath + "*")
    if directories.count > 0 do
    for tempPath in directories where getFileAttribute tempPath #hidden == false do
    (
        GetAllFiles tempPath inputFilterList outArray:outArray
    )
    for tempFilter in inputFilterList do
    (
        tempFiles = GetFiles (inputPath + tempFilter)
        for tempFile in tempFiles do append outArray tempFile
    )
    outArray
)

-- 删除所有指定类型的Camera
fn delAllCam camType =(
        oldCamArr = $cameras as array
        for c in (newCamArr=for cam in oldCamArr where classof cam==camType collect cam) do delete c
)

-- 搜集材质到
fn collectMaterial showInEditer:true = (
        objArr = objects as array
        matArr = #()
        for i=1 to objArr.count where isproperty (objArr) "material" and objArr.material!=undefined and findItem matArr (objArr.material) == 0 do
                append matArr (objArr.material)
        if showInEditer do (
                macros.run "Medit Tools" "clear_medit_slots"
                for i=1 to (amin (matArr.count) 24) do (
                        meditmaterials = matArr
                )
        )
        matArr
)

fn validDos dosStr = ( --规格化一个dos命令,解决路径中空格的问题
        dosStrArr = filterstring dosStr "\\,/"
        result = dosStrArr[1]
        for i=2 to dosStrArr.count do append result ("\\\""+dosStrArr+"\"")
        return  result
)

-- 将数组生成为日志
fn Logit logArr logName logPath:(GetFileNamePath (GetSourceFileName()) ) = (
        filePath = logPath + logName
        logStr = ""
        for str in logArr do logStr += str + "\n"
        filestream = CreateFile filePath
        format logStr to:filestream
        close filestream
        shellLaunch filePath ""
)

fn autoStdMatPath mat =(
                for i in 1 to mat.maps.count where classof mat.maps == Bitmaptexture and mat.maps.fileName!=undefined  do(
                        srcFile = mat.maps.fileName
                        
                        if not (doesFileExist srcFile) do(
                                realPath = findFile maxFilePath (fileNameFromPath srcFile)
                                if(realPath!=undefined) then (
                                        mat.maps.fileName = realPath
                                )
                        )
                )
                --
                if isProperty mat "diffusemap" and mat.diffusemap != undefined and mat.diffusemap.filename != ""do (
                        mat.name = GetFilenameFile mat.diffusemap.filename
                        mat.diffuseColor = white
                )
        )
        
fn autoDXMatPath mat =(
        for i in 1 to mat.numberofbitmaps() do(
                tex =mat.geteffectbitmap i
                if tex!=undefined then(
                        srcFile = tex.filename
                        if (classof tex)==Bitmap and srcFile!=undefined and not (doesFileExist srcFile) do (
                                realPath = findFile maxFilePath (fileNameFromPath srcFile)
                                -- print realPath
                                if(realPath!=undefined) then (
                                        tex.filename=realPath
                                        mat.seteffectbitmap i tex
                                )
                        )
                )
        )
)

fn autoMtMatPath obj = (
        for i=1 to obj.material.count do(
                if iskindof obj.material standardmaterial then ( autoStdMatPath obj.material )
                else if iskindof obj.material DirectX_9_Shader then (autoDXMatPath obj.material )
        )
)

fn autoPath = (
        for obj in $objects where isusualObj obj and obj.material!=undefined do(
                --print (classof obj)
                if iskindof obj.material standardMaterial  then autoStdMatPath obj.material
                else if iskindof obj.material DirectX_9_Shader then autoDXMatPath obj.material
                else if iskindof obj.material multimaterial then (
                        autoMtMatPath obj
                )
               
        )
)
        
Fn FnCloseProcessByName ProcessName =  for tProcess in ((DotNetClass "System.Diagnostics.Process").GetProcessesByName ProcessName) do tProcess.Kill() --终止进程By名字
fn notnull anything = (if anything==undefined do anything="";anything) --未定义变量处理
fn undefine2str val = (if val == undefined do val="undefined";val as string) --未定义变量输出处理
fn untitled val = (if val == "" then return "untitled.max" else return val) --未保存未命名处理




我的帖子不喜欢无意义的自动回复,如有疑问可加好友私聊或留言
使用道具 <
44897lojji  发表于 2018-6-17 16:56:51  
2#
天下武功出少林,世界资源入元素!
回复 收起回复
使用道具
bryi  发表于 2018-10-21 09:43:22  
3#
感谢分享
回复 收起回复
使用道具
peet07  发表于 2018-10-21 22:06:18  
4#
感謝大大
回复 收起回复
使用道具
haha123  发表于 2018-10-21 23:00:04  
5#
给力!元素有你更精彩
回复 收起回复
使用道具
fatlong  发表于 2018-10-23 11:00:20  
6#
感谢分享。
回复 收起回复
使用道具
HXDD12  发表于 2018-10-26 11:11:07  
7#
回复 收起回复
使用道具
HXDD12  发表于 2018-10-26 11:12:26  
8#
回复 收起回复
使用道具
玩嘢啊  发表于 2018-10-27 08:53:23  
9#
感谢楼主分享
回复 收起回复
使用道具
清风丨伊人醉  发表于 2018-10-27 11:29:18  
10#
给力!元素有你更精彩
回复 收起回复
使用道具
豪客轩  发表于 2018-10-29 00:06:33  
11#

神贴降临,吓死本宝宝了!
回复 收起回复
使用道具
behindjj  发表于 2018-10-29 09:10:55  
12#
十分感谢楼主分享!!!!!!
回复 收起回复
使用道具
建模大人  发表于 2018-10-29 10:24:35  
13#
感谢楼主分享
回复 收起回复
使用道具
月下獨酌灬龍  发表于 2018-10-29 14:16:12  
14#
谢谢分享
回复 收起回复
使用道具
kjsldj  发表于 2018-10-29 14:36:59  
15#
感谢分享,点赞
回复 收起回复
使用道具
likejie01  发表于 2018-10-29 15:00:52  
16#

天下武功出少林,世界资源入元素!
回复 收起回复
使用道具
建模大人  发表于 2018-10-30 20:59:01  
17#
感谢楼主分享
回复 收起回复
使用道具
宸宇  发表于 2018-10-31 08:39:53  
18#


感谢大大分享
回复 收起回复
使用道具
pxh02412  发表于 2018-11-18 07:55:46  
19#
每天一早上元素,挖矿撩妹两不误!
回复 收起回复
使用道具
建模大人  发表于 2018-11-18 20:24:34  
20#
感谢楼主分享
回复 收起回复
使用道具
12下一页
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表