3ds Max导出OBJ的mtl贴图路径不正确

之前流程是写了一个3DSMAX插件把游戏的场景直接导出为自己定义的格式的文件,包含了顶点数据,三角形数据,贴图数据等。现在把插件从3DMAX上分离出来,先通过3DMAX导出OBJ,然后再把OBJ导出为自定义的格式。

3DSMax导出的材质mtl文件漫反射贴图路径不正确

一开始以为是一个Standardmaterial对应漫反射的Map名字一样但是贴图路径不一样导致了OBJ导出出错。写了一个把同一个Map但是对应不同的贴图路径的Map自动重命名的MaxScript脚本,导出发现结果是一样的。
一个Multimaterial下的Standardmaterial和一个Standardmaterial名字一样,但是这二个Standardmaterial的diffusemap的文件路径不一样。从而导致了OBJ导出出错。

自动转换的代码如下:

--My Dictionary
struct dict
(
    public keys = #(),
    public values = #(),
    --methods:
    fn Count = 
    (
        if keys.count == values.count then
        (
            keys.count as integer
        )
        else
        (
            print "Error: keys.count != values.count"
            0
        )
    ),
    fn Add key1 value1 = 
    (
        if findItem keys key1 == 0 then
        (
            append keys key1
            append values value1
            true
        )
        else
        (
            print ("key has already been added! -->" + key1)
            false
        )
    ),
    fn Clear = 
    (
        keys = #()
        values = #()
        true
    ),
    fn Remove key = 
    (
        index = findItem keys key
        if index != 0 then
        (
            deleteItem keys index
            deleteItem values index
            true
        )
        else
        (
            print ("cann't find the key! -->" + key)
            false
        )
    ),
    fn GetItem key = 
    (
        index = findItem keys key
        if index != 0 then
        (
            if keys.count == values.count then
            (
                values[index]
            )
            else
            (
                print "Error: keys.count != values.count"
                undefined
            )
        )
        else
        (
            print ("cann't find the key! -->" + key)
            undefined
        )
    ),
    fn ContainsKey key = 
    (
        index = findItem keys key
        if index != 0 then
        (
            true
        )
        else
        (
            false
        )
    )
) 

struct mtlData
(
    public mapName = "",
    public relalMap
)
openLog "D:\Users\Administrator\Desktop\3DMAX_OBJ\my_log.txt" mode:"a" outputOnly:true
texturePathToMapNameDict = dict()
mapCount = 1000

fn processStandardMaterial mat = 
(
    if (mat.diffusemap != undefined) then
        (
            diffmap = mat.diffusemap
            mapname = diffmap.name

            if (diffmap.fileName != undefined) then
            (
                filepath = diffmap.fileName as string

                if (texturePathToMapNameDict.ContainsKey filepath) then
                (
                    dm = texturePathToMapNameDict.getItem filepath
                    --print ("change " + mat.diffusemap.name + " to " + (texturePathToMapNameDict.getItem filepath).name)
                    mat.diffusemap = copy dm
                    updateMTLInMedit mat.diffusemap
                )
                else
                (
                    newMapName = "Map_#" + (mapCount as string)
                    mapCount = mapCount + 1
                    newDiffuse = mat.diffusemap
                    newDiffuse.name = newMapName
                    --newDiffuse.reload()
                    mat.diffusemap = copy newDiffuse
                    texturePathToMapNameDict.add filepath newDiffuse            
                )

            )
        )
)

fn processMultimaterial mat = 
(
    materialList = mat.materialList
    for mm in materialList do
    (
        if classof mm == Standardmaterial then
        (
            processStandardMaterial mm
        )
        else if classof mm == Multimaterial then
        (
            processMultimaterial mm
        )
    )
)
--meditMaterials
--SceneMaterials
for mat in SceneMaterials do
(
    if classof mat == Standardmaterial then
    (
        processStandardMaterial mat
    )
    else if classof mat == Multimaterial then
    (
        processMultimaterial mat
    )
)

standardMaterialDic = dict()
matNameCount = 1

fn processRenameStandardMaterial mat =
(
    --print ("process std" + mat.name)
    if (standardMaterialDic.ContainsKey mat.name) then
    (
        diffusemap = standardMaterialDic.getItem mat.name
        if ((diffusemap == undefined and mat.diffusemap == undefined) or (diffusemap != undefined and mat.diffusemap != undefined and diffusemap.name == mat.diffusemap.name)) then
        (
            --print ("same" + diffusemap.name)
        )
        else
        (
            print ("change " + mat.name + " to " + (mat.name + "_" + matNameCount as string))
            mat.name = (mat.name + "_" + matNameCount as string)
            matNameCount = matNameCount + 1
            standardMaterialDic.add mat.name mat.diffusemap
        ) 
    )
    else
    (
        --print ("change " + mat.name)
        standardMaterialDic.add mat.name mat.diffusemap
    )
)

fn processRenameMultimaterial mat = 
(
    --print ("process mul" + mat.name)
    materialList = mat.materialList
    for mm in materialList do
    (
        if classof mm == Standardmaterial then
        (

            processRenameStandardMaterial mm
        )
        else if classof mm == Multimaterial then
        (
            processRenameMultimaterial mm
        )
    )
)

for mat in SceneMaterials do
(
    if classof mat == Standardmaterial then
    (
        processRenameStandardMaterial mat
    )
    else if classof mat == Multimaterial then
    (
        processRenameMultimaterial mat
    )
)

print ("转换完成!!!")
closeLog()

dict字典代码来自博客

代码很简单,就是先把map同名但是贴图路径不一致名字自动修改map名字,然后Standardmaterial名字一样但是map名字不一致自动修Standardmaterial名字,不考虑Multimaterial名字一样但是里面数据不一样的情况。代码边学边写-_-。主要参考:
1. API参考:http://docs.autodesk.com/3DSMAX/16/ENU/MAXScript-Help/
2. 语法参考:<<3ds MAXScript 脚本语言>>

猜你喜欢

转载自blog.csdn.net/a352614834/article/details/78764989
今日推荐