Note: A few people have reported that this script does not work with 3ds max 2016. I haven’t had a chance to investigate yet, so it might need a few modifications to work on the latest version of max.
It’s fairly common knowledge that when creating a model that will have a baked normal map, you want to have a split in your UV wherever you have a hard edge. Usually you’d have to make sure you keep in mind your UV layout when setting up your smoothing groups, or vice-versa. I’ve been meaning to get into learning Maxscript for awhile, so I figured I’d have a go at writing a script to make the process a bit easier and less prone to error.
What the script does, is put hard edges wherever there’s a seam on the UV. You could also think of it as assigning a single smoothing group to each UV island. I’m definitely not the first person to come up with this, but the scripts I’ve come across that do this tend to have some cases in which they don’t work, or produce incorrect results.
You can download it below, and be sure to check the header of the script for usage instructions!
Download – UVIslandsToSmoothingGroups.ms
------------------------------------- UV Islands To Smoothing Groups ------------------------------------- -- By Martin Palko -- www.martinpalko.com -- -- -- Tested: - Max 2014 -- -- Install: - Drag script into max, then assign it to a hotkey or menu bar in "Customize -> User Interface" -- - Can be found by setting the category to "MP_Tools" while in the "Main UI" group -- -- Usage: - Select any mesh object, and activate the script. Choose a UV channel and hit run. -- -- Notes: - This script will not affect your modifier stack, it will simply put an edit poly with the -- smoothing groups at the top. -- - Undo is not currently supported, so save before, just in case. You can however, just delete -- the edit poly modifier to get your old smoothing groups back. -- - Selecting any channel other than UV channel 1 will show a dialogue box asking if you want to -- reset UVs. You must hit yes for it to work based on the channel you've specified. This -- will NOT affect the model's existing UV set. macroscript UVIslandsToSmoothing category:"MP_Tools" buttontext:"UV 2 Smooth" tooltip:"Convert UV islands to smoothing groups" autoUndoEnabled:false ( -- Helper function to get the index of the first true element in a bit array function getFirstActiveInBitarray aBitArray = ( for i = 1 to aBitArray.count do ( if aBitArray[i] == true do return i ) -- return 0 if none are found active return 0 ) -- Actually performs the operation on the currently selected object function ConvertUVIslandsToSmoothingGroups aUVChannel = ( if $ != undefined then ( modPanel.addModToSelection(Edit_Poly()) ui:on local editPoly = $.modifiers[#edit_poly] local facesDone = #{} -- empty bit array since no faces are done local allFaces = #{1.. polyop.getNumFaces $} local facesNotDone = allFaces -- Stick on a UVW modifier modPanel.addModToSelection (Unwrap_UVW ()) ui:on local uv_modifier = $.modifiers[#unwrap_uvw] uv_modifier.unwrap2.setTVSubObjectMode 3 -- Use face selection if (aUVChannel != 1) then -- Only need to mess with this if it's not default ( uv_modifier.unwrap.setMapChannel aUVChannel uv_modifier.unwrap.reset() forcecompleteredraw dodisabled:true -- Hacky fix for a bug, see http://www.polycount.com/forum/showthread.php?t=97059 ) local uv_islands = #() -- Empty array that will store bitarrays of all our UV islands local abort = false -- Abort boolean for breaking out of the loop and avoid the performance penalty of using break -- Build array of UV islands while (facesNotDone.isEmpty == false and abort == false) do ( nextFace = getFirstActiveInBitarray facesNotDone -- Get next face that hasn't been processed yet uv_modifier.unwrap2.selectFaces #{nextFace} -- Select that face uv_modifier.unwrap2.selectElement() -- Grow selection to element uv_island = uv_modifier.unwrap2.getSelectedFaces() -- Get a bitaray of all those faces (representing a UV island) -- Update faces done/not done bit masks facesDone += uv_island facesNotDone -= uv_island insertItem uv_island uv_islands (uv_islands.count + 1) -- Add that bitarray to our array of UV islands if uv_islands.count > allFaces.count then -- this should never happen, if it does means we are in an infinite loop and will crash max, so bail ( abort = true print ("Error, calculated too many islands, something went wrong") ) ) deletemodifier $ uv_modifier -- Don't need the UV modifier anymore editPoly.autoSmoothThreshold = 180.0 -- If we auto smooth, it should always be in the same smoothing group for island = 1 to uv_islands.count do -- Select and auto smooth each UV island ( editPoly.SetSelection #Face uv_islands[island] editPoly.ButtonOp #Autosmooth ) ) ) local isOpen = false -- Store if the rollout is open or closed rollout UV2SmoothRollout "UV_2_Smooth" ( spinner UVChannelSpinner "UV Channel" range:[1,99,1] type:#integer button GoBtn " Run " on GoBtn pressed do ( ConvertUVIslandsToSmoothingGroups (UVChannelSpinner.value) destroyDialog UV2SmoothRollout -- Close rollout after running ) on UV2SmoothRollout close do ( isOpen = false updateToolbarButtons() -- Update the toolbar icon when closing ) ) on execute do ( if isOpen then --if open, close it ( destroyDialog UV2SmoothRollout ) else --if closed, open it ( createDialog UV2SmoothRollout isOpen = true ) ) on isChecked return isOpen --return the flag on isEnabled do ( -- Need an editable poly selected to work if $ == undefined then ( -- Close the window if it's open and it shouldn't be if (isOpen) then destroyDialog UV2SmoothRollout return false ) else return true ) )
Comments 14
It works on 3ds max 2022. Thank you very much!
Cool tool, is there a way to have it so it could do it to multiple objects at a time instead of one at time?
Fantastic piece of software! I am getting one very nasty error while trying to apply the script on multiple meshes though — Unknown property: “modifiers” in $selection. It doesn’t crash Max, but I’d very much like to use the script on multiple objects, can you help me out?
Awesome script! Works in 3ds Max 2021 ๐
Fantastic script and very useful, ever since 3D Max introduced the amazing feature using the ‘champfer’ utility in a ‘editable poly’ upon geometry removes all your smooth groups by default, unless you remember to uncheck the stupid option!
This has just saved my bacon and works in v2019
Thank you Very much
3Ds Max 2019 OK!
์คํฌ๋ฆฝํธ๋ฅผ ๋งฅ์ค๋ก ๋๋๊ทธ ํ์ฌ ์ค์นํ ํ
๋จ์ถํค ๋๋ ๋ฉ๋ด๋ฐ๋ก ์ง์ ํ ํ ์ฌ์ฉํด์ผ ํ๋ค.
๊ฐ๋จํ ์คํฌ๋ฆฝํธ์ ๊ฒฝ์ฐ ๋๋ถ๋ถ ์ด๋ฐ ์์ผ๋ก ์ฌ์ฉํ๋ค.
Brill, thanks. It does work with 2016 btw.
cheers
Thank you so much. This is a very useful script. He saves time very much.
does this by chance work on 2017?
Thank you
thank you so much! this is exactly what I needed and it works perfectly.
Doesn’t do anything :/ Probably it doesn’t work with 3ds 2016
This is great! Thanks for sharing. Does it handle a case where there are more than 32 UV islands (more than the number of individual smoothing groups)?
Author
It does! Since the script just applies auto-smooth, it picks the next available smoothing group that isn’t being used by a neighboring island. Even on complex models, it shouldn’t use more than a handful of smoothing groups.