3Dmax如何批量修改贴图名及模型名
关关 2018-06-26 来源 : 阅读 1958 评论 0

摘要:本文讲解了3Dmax如何通过MAXScript批量修改贴图名及模型名,希望阅读本篇文章以后大家有所收获,帮助大家对3Dmax的掌握更加熟练。

批量修改模型名

  步骤: 

  1. 建立两个txt文件,一个是用于存放原模型名的列表,一个用于存放新模型名的列表
  2. 逐行读取两个txt文件的内容; 
  3. 读取一行,就搜索场景中名称匹配的模型,然后替换成新名称。 
  具体实现: 
  1. 只能手动解决,这个没有什么快捷方式。 
  2. 可以通过FileStream(文件数据流)的OpenFile方法对文本文件进行I/O操作。切记: maxscript的函数并不是以一对“()”括号来标识的,传参数的方法也不像其他常用语言那样在“()”里填入参数,而是在函数名后“ ”加“空格”然后在后面带上函数参数,如要读取D盘下的maxscript.txt文件内容,应如此写:

source = OpenFile "d:\maxscript.txt"    --后面不带封号,不一样的注释符号"--";

而不是:

source = OpenFile("d:\maxscript.txt");

  3. 这个步骤主要是获取指定名称的对象。可以通过for循环遍历selection中所有的模型对象,但是此法效率过于低下,因为找一个物体就要遍历一遍selection,没找到更好的方法,将就用吧,下面附上源码:

source = OpenFile "C:\Users\Administrator\Desktop\批量改名\原名.txt"   --获取"原名.txt文件"的io流
des = OpenFile "C:\Users\Administrator\Desktop\批量改名\新名.txt"    --获取"新名.txt文件"的io流
for j = 1 to 3 do   --列表几条记录就写几条,maxscript习惯从1开始计数
(
    str = readLine source   --逐行读取文本内容
    strD = readLine des
 
    for obj in selection do    --遍历场景中所有模型,注:selection需要选中场景中的模型哦
    (
        if obj.name==str then  --判断模型名称是否与原名一致,如果一致,就替换成新名
        (
            obj.name = strD
            exit    --退出循环
        )
    )
)

  代码是不是有点简单?千万千万不要说我絮絮叨叨的侃了一堆,只写出了这么几行代码,要知道,这几行代码可都是精华呀,好啦,下面才是重头戏。

批量修改贴图名

  示例代码:

rm = renderMap $foo.Material.diffuseMap size:[640,480] \fileName: "foodif.bmp"
save rm
close rm
  通过上述代码的启发,是不是可以通过 (模型对象).Material.diffuseMap.fileName = “贴图路径”,其实在3DMAX中,贴图名可看成是贴图在硬盘上的路径。测试一下,首先在场景中随便建个Box用于测试,先给其关联上一张贴图,然后再随便选择一个路径放一张其他的贴图,然后将其路径复制下来作为要修改的贴图名,然后打开maxscript侦听器,执行脚本,成功修改贴图名,并关联上硬盘的贴图文件。应该说,核心的问题已经解决了。写代码之前,照例整理一下思路,归纳一下步骤: 

  1. 保留原贴图路径及位置,将硬盘上的原贴图复制到另一个文件夹下,并修改贴图名,作为新贴图; 
  2. 将原贴图完整路径与新贴图完整路径分别写进两个txt列表中; 
  3. 读取两个txt文件,通过遍历模型,找到材质,找到贴图,再将贴图与txt的原贴图进行匹配,匹配成功后,替换成新贴图。 
  具体实现: 
  1. 如果对新贴图名的命名并没有什么要求,其实这一个步骤有一个快捷的方法,随便使用什么编程语言,写一个小程序,让程序帮你做复制贴图,并将贴图路径写入各自的txt文件中,几秒就可以搞定第一个步骤;如果对贴图名称有要求,那就比较麻烦了,要一个个改贴图名称,还要一一对应写入列表; 
  2. 参见1; 
  3. 使用openfile读取列表,selection遍历模型,并遍历每个模型的材质和贴图,然后替换贴图。上代码:

遍历模型法

source = OpenFile "F:\新名.txt"
des = OpenFile "F:\原名.txt"
for j = 1 to 39 do
(
    str = readLine source
    strD = readLine des
 
    print(str)
    print(strD)
    for i in selection do   --遍历场景中所有选中的物体
    (
        s = i.Material as string    --将材质属性转成字符串格式
 
        if s!="undefined" then(   --模型没有材质时,材质为  "undefined"    
            if s.count>18 then
            (
                ss = substring s  1 18   --获得材质属性子字符串,用于判断是否是“多维材质”
            )
            --多维材质
            if ss == "#Multi/Sub-Object:" then  --子字符串中若含有多维材质的信息,则为多维材质,按多维材质处理
            (
                for k=1 to  i.Material.MaterialList.count do    --将多维材质中的子材质放入数组中,并遍历每个子材质中的贴图
                (
                    multi = i.Material.MaterialList[k] as string   --将多维材质中的子材质属性转成字符串格式
                    if multi !="undefined" then      --若多维材质无子材质,则为  "undefined"
                    (
                        dif = i.Material.MaterialList[k].diffuseMap as string   --将贴图属性转成字符串格式
                        if dif !="undefined" then    --若材质无贴图,则贴图为  "undefined"
                        (
                            if i.Material.MaterialList[k].diffuseMap.filename==str then 
                            (   i.Material.MaterialList[k].diffuseMap.filename = strD
                                exit    --退出循环
                            )
                        )
                    )
                )
            )
            else   --标准材质
            (
 
                difS = i.material.diffuseMap as string    
                if difS !="undefined" then    
 
                (
                    if i.material.diffuseMap.filename==str then 
                    (
 
                        i.material.diffuseMap.filename = strD
                        exit
                    )
                )
            )
        )
    )
)

  和修改模型名一样的问题,此方法效率低下,耗时太长,当时一个场景5000多个模型,替换一张贴图要50s左右,因为替换一张贴图就要遍历5000多个模型,所以后来也一直在想有没有不通过遍历模型的方式。比如遍历材质,相对而言,材质要少得多,但是也是很久没有发现比较好的方式。那天下班回家又想起了这个问题,终于功夫不负有心人啊,无意中发现手册中3.5.13节一个叫MaterialLibrary(材质库)的类,类中有一个系统变量:SceneMaterials(场景里的材质的集合),于是又优化了一下程序,这次可快得多了,替换一张贴图只需要0.x秒,这么激动人心的时刻,快上代码:

遍历材质法

source = OpenFile "F:\贴图改名程序\原名.txt"
des = OpenFile "F:\贴图改名程序\新名.txt"
--b = false
for j = 1 to 176 do
(
    str = readLine source
    strD = readLine des
 
    print(str)
    print(strD)
 
    start =timeStamp()
 
    for i = 0 to SceneMaterials.count do    --SceneMaterials:为系统变量,是一个包含场景中的所有材质的数组。
    (
        s = SceneMaterials[i] as string    --将材质属性转成字符串格式
        if s!="undefined" then(      --模型没有材质时,材质为  "undefined"(此判断在通过遍历模型中的材质时用到)  
            if s.count>18 then
            (
                ss = substring s  1 18    --获得材质属性子字符串,用于判断是否是“多维材质”
            )
 
            --多维材质
            if ss == "#Multi/Sub-Object:" then  --子字符串中若含有多维材质的信息,则为多维材质,按多维材质处理
            (
                for k=1 to  SceneMaterials[i].MaterialList.count do --将多维材质中的子材质放入数组中,并遍历每个子材质中的贴图
                (
                    mat = SceneMaterials[i].MaterialList[k]     --将材质赋值给  mat  变量。
 
                    multi = mat as string
 
                    if multi !="undefined" then
                    (
                        if multi.count>18 then
                        (
                            sss = substring multi  1 18
                        )
 
                        --多维材质子材质为多维材质
                        if sss == "#Multi/Sub-Object:" then
                        (
                            for subk=1 to  mat.MaterialList.count do    --将多维材质中的子材质放入数组中,并遍历每个子材质中的贴图
                            (
                                subMat = mat.MaterialList[subk]     --将材质赋值给  subMat  变量。
 
 
                                submulti = subMat as string
 
                                if submulti !="undefined" then
                                (
 
                                    if submulti.count>18 then
                                    (
 
                                        ssss = substring submulti  1 18
 
                                    )
 
                                    if ssss == "#Multi/Sub-Object:" then
                                    (
 
                                    )
                                    else
                                    (
                                        subdif = subMat.diffuseMap as string
 
                                        if subdif !="undefined" then
                                        (
                                            if subMat.diffuseMap.filename==str then 
                                            (
                                                subMat.diffuseMap.filename = strD
                                                --exit
                                            )
                                        )
                                    )
                                )
                            )
                        )
 
                        --多维材质子材质为标准材质
                        else
                        (
 
                            dif = mat.diffuseMap as string    
                            if dif !="undefined" then   --若材质无贴图,则贴图为  "undefined"
 
                            (
                                if mat.diffuseMap.filename==str then 
                                (
 
                                    --b = true
                                    mat.diffuseMap.filename = strD     
                                    --exit
                                )
 
                            )
 
                        )
                    )
 
                )
 
 
            )
 
            --标准材质
            else
            (
 
                difS = SceneMaterials[i].diffuseMap as string    
                if difS !="undefined" then    
 
                (
                    if SceneMaterials[i].diffuseMap.filename==str then 
                    (
 
                        SceneMaterials[i].diffuseMap.filename = replace SceneMaterials[i].diffuseMap.filename 1 SceneMaterials[i].diffuseMap.filename.count strD
                        --exit
                    )
                )
            )
        )
 
    )
    end =timeStamp()
 
    intervalTime = (end - start)/ 1000.0
    print(intervalTime)
 
)

  好了,怕大家看不懂,多写了一些注释,大家应该已经懂了,希望这个小程序可以给大家省去很多麻烦,需要注意的是,大家应该看到了,程序中只对diffuseMap(即漫反射贴图)进行了处理,听同事说还有通道贴图,烘焙贴图等等,这个如有需要,大家略微修改程序即可。


  本文由职坐标整理发布,学习更多的3Dmax相关知识,请关注职坐标常用软件3Dmax频道!

本文由 @关关 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程