3dmax一键展uv_MaxScript打图集&uv处理
本文最后更新于654 天前,其中的信息可能已经过时,如有错误请发送邮件到84581927@qq.com

为了减少材质球的数量,减少SetPassCall,美术通常会把贴图打成图集,uv移动的正确的位置。数量少还好,数量多的话会很耗时间。今天来分享一个可以一键解决美术需要做3,4天工作的工具。

功能:
1.在3dmax里面选中的objs,提取他们的diffuseMap,打成图集。

2.把objs的uv,用unwrap uvw把uv也打成图集形式。

效果:
本来的贴图

本来的uv:

工具处理后的贴图:

工具处理后的uv

原理:
1.使用了bitmap的getPixels,setPixels接口打图集

2.使用了unwrap uvw的scaleSelectedXY接口处理了uv

unwrapMod.scaleSelectedXY 1 0.5 [1,1,0] 代表以[1,1]点为中心向Y轴缩放0.5

3.使用了bin packing的思想把本来就是2的N次方的图片打成图集

4.特别注意不能启动进度条,会报错 具体原因不清楚

报错

源码在这里

global realseBitMapArray = #()
global isSetUV = true
global isProgress = false
struct BitMapData
(
public
p_bitmap,
p_packingSize,
p_volume,
p_objArray = #(),

on create do 
(
--format "Struct Created: %n" this
)
)

struct BitMapDicData
(
public 
p_packingSize,
p_Array = #() -- BitMapData数组
)

fn GetUVW obj = 
(
-- select obj
-- if (obj.modifiers[#unwrap_uvw] == undefined)do --添加uv组件
-- (
-- addModifier obj (unwrap_UVW())
-- )

-- unwrapMod = obj.modifiers[#unwrap_uvw]
-- max modify mode
-- --break()
-- subobjectlevel = 3
-- max select all

select obj
max modify mode
unwrapMod = obj.modifiers[#unwrap_uvw]
if (unwrapMod == undefined)then --添加uv组件
(
modPanel.addModToSelection (Unwrap_UVW ()) ui:on
unwrapMod = obj.modifiers[#unwrap_uvw]
)
else
(
modPanel.setCurrentObject unwrapMod 
)

subobjectlevel = 3
max select all

return unwrapMod
)

fn packing dicData packingSize =
(
tempDicData = BitMapDicData()
tempDicData.p_packingSize = packingSize

for i = 1 to (dicData.p_Array.count) do
(
obj = dicData.p_Array[i]

if (obj.p_bitmap.width > obj.p_bitmap.height)then --横向矩形
(
--图片换向
tempBitMap = bitmap obj.p_bitmap.height obj.p_bitmap.width color:white
realseBitMapArray = append realseBitMapArray tempBitMap
for i = 0 to (obj.p_bitmap.width-1) do
(
for j = 0 to (obj.p_bitmap.height-1) do
(
pixel = getPixels obj.p_bitmap [i,j] 1 linear:true
--setPixels tempBitMap [i,j] pixel
--根据旋转矩阵得出
setPixels tempBitMap [obj.p_bitmap.height - j, i] pixel
)
)

--需要换向的都是原图,不考虑拼的图
--uv换向
if (isSetUV) then
(
for p_obj in obj.p_objArray do
(
unwrapMod = GetUVW p_obj
unwrapMod.unwrap2.RotateSelected (DegToRad(-90)) [0.5,0.5,0]
subobjectlevel = 0

collapseStack p_obj
)
)

obj.p_bitmap = tempBitMap
)

if ( (mod i 2) == 1)then
(
picWidth = obj.p_bitmap.width
picHeight = obj.p_bitmap.height

if(obj.p_bitmap.width == obj.p_bitmap.height)then --正方形
(
picHeight = picHeight * 2

tempBitMapData = BitMapData()

tempBitMap = bitmap picWidth picHeight color:white
realseBitMapArray = append realseBitMapArray tempBitMap

for i = 0 to (obj.p_bitmap.width-1) do ---第一张
(
for j = 0 to (obj.p_bitmap.height-1) do
(
pixel = getPixels obj.p_bitmap [i,j] 1 linear:true
setPixels tempBitMap [i,j] pixel
)
)

--------------------------第一张的UV,上移-----------------------------------
if (isSetUV) then
(
for innObj in obj.p_objArray do 
(
unwrapMod = GetUVW innObj
-- unwrapMod.unwrap2.scaleSelectedXY 1 0.5 [1,1,0]--上移
unwrapMod.scaleSelectedXY 1 0.5 [1,1,0]--上移

subobjectlevel = 0
collapseStack innObj

tempBitMapData.p_objArray = append tempBitMapData.p_objArray innObj
)
)
------------------------------------------------------------------------------

if(i != dicData.p_Array.count)then
(
obj2 = dicData.p_Array[i+1]
for i = 0 to (obj2.p_bitmap.width-1) do ---第二张
(
for j = 0 to (obj2.p_bitmap.height-1) do
(
pixel = getPixels obj2.p_bitmap [i,j] 1 linear:true
setPixels tempBitMap [i,j + obj2.p_bitmap.height] pixel
)
)

if (isSetUV) then
(
--------------------------第二张的UV,下移-----------------------------------
for innObj in obj2.p_objArray do 
(
unwrapMod = GetUVW innObj
-- unwrapMod.unwrap2.scaleSelectedXY 1 0.5 [0,0,0]--下移
unwrapMod.scaleSelectedXY 1 0.5 [0,0,0]--下移

subobjectlevel = 0
collapseStack innObj
tempBitMapData.p_objArray = append tempBitMapData.p_objArray innObj
)
-------------------------- -------------------------- --------------------------
)

)

tempBitMapData.p_packingSize = packingSize
tempBitMapData.p_volume = picWidth * picHeight
tempBitMapData.p_bitmap = tempBitMap
tempDicData.p_Array = append tempDicData.p_Array tempBitMapData
)
else --纵向矩形
(
picWidth = picWidth * 2

tempBitMapData = BitMapData()

tempBitMap = bitmap picWidth picHeight color:white
realseBitMapArray = append realseBitMapArray tempBitMap

for i = 0 to (obj.p_bitmap.width-1) do ---第一张
(
for j = 0 to (obj.p_bitmap.height-1) do
(
pixel = getPixels obj.p_bitmap [i,j] 1 linear:true
setPixels tempBitMap [i,j] pixel
)
)

if (isSetUV) then
(
--------------------------第一张的UV,左移-----------------------------------
for innObj in obj.p_objArray do 
(
unwrapMod = GetUVW innObj
-- unwrapMod.unwrap2.scaleSelectedXY 0.5 1 [0,0,0]--左移
unwrapMod.scaleSelectedXY 0.5 1 [0,0,0]--左移

subobjectlevel = 0

collapseStack innObj
tempBitMapData.p_objArray = append tempBitMapData.p_objArray innObj
)
-------------------------- -------------------------- --------------------------
)


if(i != dicData.p_Array.count)then
(
obj2 = dicData.p_Array[i+1]
for i = 0 to (obj2.p_bitmap.width-1) do ---第二张
(
for j = 0 to (obj2.p_bitmap.height-1) do
(
pixel = getPixels obj2.p_bitmap [i,j] 1 linear:true
setPixels tempBitMap [i + obj2.p_bitmap.width,j] pixel
)
)

if (isSetUV) then
(
--------------------------第二张的UV,右移-----------------------------------
for innObj in obj2.p_objArray do 
(
unwrapMod = GetUVW innObj
-- unwrapMod.unwrap2.scaleSelectedXY 0.5 1 [1,1,0]--右移
unwrapMod.scaleSelectedXY 0.5 1 [1,1,0]--右移

subobjectlevel = 0

collapseStack innObj
tempBitMapData.p_objArray = append tempBitMapData.p_objArray innObj
)
-------------------------- -------------------------- --------------------------
)

)

tempBitMapData.p_packingSize = packingSize
tempBitMapData.p_volume = picWidth * picHeight
tempBitMapData.p_bitmap = tempBitMap
tempDicData.p_Array = append tempDicData.p_Array tempBitMapData
)
)
)

return tempDicData
)



rollout TidyRollout "整理地形图集&UV工具"
(
button tidyBtn "整理" width:100 height:50
on tidyBtn pressed do
(
if( $ != undefined) then
(
bitMapArray = #()
bitMapDic = #()
outBitMapArray = #()

if(isProgress)then
progressStart "正在整理图片(打图集)" 

for obj in $ do 
(
if (not (isGroupHead obj))then
(
-- print obj
if (obj.material != undefined or obj.material.diffuseMap != undefined )do -- 把图片,图片体积,记录
(
-- break()
tempData = undefined
for b in bitMapArray do -----分辨是否同一个贴图
(
if (b.p_bitmap.fileName == obj.material.diffuseMap.bitmap.fileName)then
(
tempData = b
exit
)
)

--处理MultiMaterial
if (classof (obj.material) == MultiMaterial)then
(
obj.material = obj.material.materialList[1]
)

if (tempData == undefined) then
(
tempData = BitMapData()
tempData.p_bitmap = obj.material.diffuseMap.bitmap
tempData.p_volume = tempData.p_bitmap.width * tempData.p_bitmap.height
bitMapArray = append bitMapArray tempData
)
outBitMapArray = append outBitMapArray obj.material
tempData.p_objArray = append tempData.p_objArray obj

)
)
)

if(isProgress)then
progressUpdate 10

if (bitMapArray.count > 1)then
(
--------------------------------------------------sort--------------------------------------------------------------
fn compareFN v1 v2 =
(
case of
(
(v1.p_volume < v2.p_volume) : -1
(v1.p_volume > v2.p_volume) : 1
default: 0
)
)

qsort bitMapArray compareFN --按体积排序
--------------------------------------------------sort--------------------------------------------------------------
-------------------------------------------------存字典-------------------------------------------------------------
for obj in bitMapArray do 
(
--算出打包的size
obj.p_packingSize = obj.p_volume / bitMapArray[1].p_volume

--把准备打包的数据存在 字典bitMapDic里
if (bitMapDic.count == 0)then
(
tempDicData = BitMapDicData()
tempDicData.p_packingSize = obj.p_packingSize
tempDicData.p_Array = append tempDicData.p_Array obj
bitMapDic = append bitMapDic tempDicData
)
else
(
inIf = false 
for dic in bitMapDic do 
(
if (obj.p_packingSize == dic.p_packingSize)then
(
dic.p_Array = append dic.p_Array obj
inIf = true
)
)

if (not inIf)then
(
tempDicData = BitMapDicData()
tempDicData.p_packingSize = obj.p_packingSize
tempDicData.p_Array = append tempDicData.p_Array obj
bitMapDic = append bitMapDic tempDicData
)
)
)
-------------------------------------------------存字典-------------------------------------------------------------
----------------------------------------------2的N次方循环----------------------------------------------------------
for i = 0 to 10 do
(
tempDicData = undefined

if(isProgress)then
progressUpdate ( ( (2+i) / 10.0) * 100)

for obj in bitMapDic do 
(
if (obj.p_packingSize == 2^i)then
(
tempDicData = packing obj (2^(i+1)) --打图集,tempDicData打出来的图集信息
exit
)
)
-- print (1111111)
-- print tempDicData
if (tempDicData != undefined and tempDicData.p_Array.count != 0)then
(
inIf = false

for obj in bitMapDic do
(
if(obj.p_packingSize == tempDicData.p_packingSize)then --找到p_packingSize一样的
(
for bit in (tempDicData.p_Array) do --逐个插入
(
obj.p_Array = append obj.p_Array bit
) 
inIf = true
exit
)
)

if (not inIf)do --找不到 p_packingSize一样的
(
index = -1
for iter=1 to (bitMapDic.count) do
(
if(bitMapDic[iter].p_packingSize > tempDicData.p_packingSize)then --找一个比他大的p_packingSize
(
index = iter
exit
)
)

if (index == -1)then --找不到判断是否可以继续打图集
(
bitMapDic = append bitMapDic tempDicData
if (tempDicData.p_Array.count == 1)then
exit--结束循环
)
else --找得到插在他前面
(
insertItem tempDicData bitMapDic (index-1)
)
) 
)
else
(
messageBox "tempDicData为空!!!!!!!!!!"
exit
)
)
----------------------------------------------2的N次方循环----------------------------------------------------------
----------------------------------------------存最终图集------------------------------------------------------------

outBitMapDic = bitMapDic[bitMapDic.count]
outBitMap = outBitMapDic.p_Array[1].p_bitmap

outBitMap.filename = SelectSaveBitmap caption:"Select a file" gamma:&gma metadata:&data
if (outBitMap.filename != "undefine") do save outBitMap gamma:gma metadata:data

-- outBitMap.filename = "C:Users/Administrator/Desktop/testImage.png"
-- save outBitMap

if (isSetUV)then
(
for obj in outBitMapArray do
(
obj.diffuseMap.bitmap = outBitMap
)
)
----------------------------------------------存最终图集------------------------------------------------------------
------------------------------------------------释放内存------------------------------------------------------------
for obj in realseBitMapArray do
(
close obj
free obj
)

close outBitMap 
free outBitMap
if(isProgress)then
(
progressUpdate 100
progressEnd() 
)

free realseBitMapArray
free bitMapArray
free bitMapDic
free outBitMapArray

gc()
------------------------------------------------释放内存------------------------------------------------------------
)
else
(
if(isProgress)then
(
progressUpdate 100
progressEnd() 
)
)
)
else
(
if(isProgress)then
(
progressUpdate 100
progressEnd() 
)
messageBox "You should Pick a Obj !!!!!!!!!!"
)
)
)
createDialog TidyRollout 200 100

————————————————
版权声明:本文为CSDN博主「a11董常伟」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_35411438/article/details/112369236

 

 

 

 

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇