macroScript UVSetEditor category:"Custom" internalCategory:"Custom" tooltip:"UV Set Editor" ButtonText:"UVSetEditor" autoUndoEnabled:false Icon:#("UVWUnwrapSelection",28) ( --variables related to the file naming and paths for saving defaults local ScriptName = "UVSetEditor" local ScriptsFolder = pathconfig.getdir #userscripts local DefaultsFolder = pathconfig.appendPath ScriptsFolder "\\UnwrapTools" local DefaultsFilePath = pathconfig.appendPath DefaultsFolder ("\\" + ScriptName + "_Defaults.ini") local UnwrapDirectory = pathconfig.appendPath (pathconfig.getdir #maxData) "\\plugcfg_ln\\unwrapuvw.ini" global UVSetEditorRollout ---------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------ SAVE & LOAD DEFAULTS FUNTIONS ------------------------------------------ ---------------------------------------------------------------------------------------------------------------------------------- --A function which is used to save defaults to a file fn SaveToFile FilePath SectionString KeyString ValueString = ( local theFile = FilePath as string local theSection = SectionString as string local theKey = KeyString as string local theValue = ValueString as string if not doesFileExist theFile then ( --take directory path part of a full file name local Directory = getFilenamePath theFile --Create a directory makeDir Directory --OutPut to log format "Directory % has been created\n" Directory ) --if write sucessfull if (setINISetting theFile theSection theKey theValue) then format "File has been updated sucessfully in %\n" theFile else format "ERROR: File was not saved in %\n" theFile )--end of function --Function that return value by its name which was readed from ini file. fn LoadValueFromFile FilePath SectionString KeyString = ( local theFile = FilePath as string local theSection = SectionString as string local theKey = KeyString as string -- If file is not exists if not doesFileExist theFile then ( return undefined ) return getINISetting theFile theSection theKey )--end of function ---------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------- UTILITY FUNCTIONS ---------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- --Return how many UV Channel does object have fn getNumUVChannels obj = ( if (isKindOf obj GeometryClass) == false do return undefined local count = 0 local objMesh = obj.mesh /*for i in 1 to meshOp.getNumMaps objMesh do if meshOp.getMapSupport objMesh i then*/ count = meshOp.getNumMaps objMesh return (count-1) )-- end of function --Return a specific name of a UV Set from a provided ID fn GetSpecificUVSetFromObj id obj = ( local uvName = (getUserProp obj ("MapChannel:" + id as string)) return uvName )-- end of function --Return array of names of UV Channels from obj fn GetUVSetsFromObj obj = ( UVSetEditorRollout.UVSetsListBox.items = #() local arr = #() try ( local numUVs = getNumUVChannels obj if numUVs == 0 do return false for i = 1 to numUVs do ( local uvName = (getUserProp obj ("MapChannel:" + i as string)) if uvName == "" or uvName == undefined then ( append arr (i as string + ": " + "-No Name-") ) else ( append arr (i as string + ": " + uvName as string) ) ) ) catch() return arr )-- end of function ---------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- -------------------------------------- ROLLOUT RenameUVSetRollout DEFINITION-------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- --Rollout RenameUVSet Definition rollout RenameUVSetRollout "Rename UV Set" width:350 height:110 ( --local variables local str = if isKindOf str String then str else "Default" --Interface edittext NameEdTxt "Enter a new name:" pos:[25,15] fieldWidth:300 labelOnTop:true button OkBtn "OK" pos:[90,70] width:85 height:25 tooltip: "" button CancelBtn "Cancel" pos:[180,70] width:85 height:25 tooltip: "" ---------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------ DIALOG INITIALIZATION ----------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- on RenameUVSetRollout open do ( NameEdTxt.text = str ) ---------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------ DIALOG EVENTS ------------------------------------------------------ ---------------------------------------------------------------------------------------------------------------------------------- /*on NameEdTxt entered str do ( UVSetEditorRollout.RenameUVSet str try(destroyDialog RenameUVSetRollout)catch() )*/ --this shit doesnt work if you type something and press cancel so i got rid from it on OkBtn pressed do ( str = NameEdTxt.text UVSetEditorRollout.RenameUVSet str try(destroyDialog RenameUVSetRollout)catch() ) on CancelBtn pressed do ( try(destroyDialog RenameUVSetRollout)catch() ) ) ---------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------- DIALOG UVSetEditorRollout DEFINITION -------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- --Rollout UVSetEditorRollout Definition rollout UVSetEditorRollout "UV Set Editor" width:270 height:290 ( -- ROLLOUT FUNCTIONS --Updating UVSetsListBox with UV Channels which are present in a selected object fn UpdateUVSetList = ( local UVSets = GetUVSetsFromObj $ if UVSets != false then ( UVSetEditorRollout.UVSetsListBox.items = UVSets ) else ( UVSetEditorRollout.UVSetsListBox.items = #() ) )-- end of function --Return real index of specific UV channel for Unwrap UVW (0 - is 1st UV channel, 1 is reserved for vertex channel) fn GetUVChannelIndex = ( if UVSetEditorRollout.UVSetsListBox.selection == 1 then return 0 else return UVSetEditorRollout.UVSetsListBox.selection )-- end of function fn RenameUVSet newname = ( local id = UVSetEditorRollout.UVSetsListBox.selection channelInfo.NameChannel $ 3 id newname UVSetEditorRollout.UpdateUVSetList() ) fn UVChannelSilentReset UVWMod = --Press Reset UVW in Unwrap and close pop-up window ( --Press "Yes" in pop-up window fn confirmReset = ( local hwnd = dialogMonitorOps.getWindowHandle() if UIAccessor.GetWindowText hwnd == "Unwrap UVW" then ( --uiAccessor.pressDefaultButton() -- stopped working for max 2022 UIAccessor.SendMessageID hwnd #IDYES --fix for max 2022 true ) else false )-- end of function dialogMonitorOps.unRegisterNotification id:#unwrap_reset dialogMonitorOps.enabled = true dialogMonitorOps.interactive = false dialogMonitorOps.registerNotification confirmReset id:#unwrap_reset UVWMod.reset() dialogMonitorOps.enabled = false )-- end of function --Interface listbox UVSetsListBox "UV Sets:" pos: [10,15] width:160 height:15 toolTip:"" button NewBtn "New" pos:[175,30] width:85 height:25 tooltip: "Create new UV Set" button EditBtn "Edit" pos:[175,60] width:85 height:25 tooltip: "Edit selected UV Set using Unwrap UVW" button RenameBtn "Rename" pos:[175,90] width:85 height:25 tooltip: "Rename selected UV Set" button DeleteBtn "Clear" pos:[175,120] width:85 height:25 tooltip: "Clear selected UV Set\nIf it is a last UV set in the list - it will be deleted\n1st UV Set can't be deleted or cleared" button DuplicateBtn "Duplicate" pos:[175,150] width:85 height:25 tooltip: "Duplicate UV Set" button CopyBtn "Copy" pos:[175,180] width:85 height:25 tooltip: "Copy UVs from selected UV Set in clipboard" button PasteBtn "Paste" pos:[175,210] width:85 height:25 tooltip: "Paste UVs in selected UV Set from clipboard" groupBox grpline "" pos:[5,235] width:260 height:8 button UpdateBtn "Update" pos:[10,250] width:120 height:30 tooltip: "Update list of UV Sets" button CloseBtn "Close" pos:[140,250] width:120 height:30 tooltip: "Close this window" ---------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------ DIALOG INITIALIZATION ----------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- --Initialize variables on start on UVSetEditorRollout open do ( try ( --update UVSetList UpdateUVSetList() --setting callback to update list when selection is changing try (callbacks.removeScripts id:#UpdateUVSetList) catch() callbacks.addScript #selectionSetChanged "UVSetEditorRollout.UpdateUVSetList()" id:#UpdateUVSetList --if selection.count != 0 do ) catch () ) --End initialize ---------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------ DIALOG EVENTS ------------------------------------------------------ ---------------------------------------------------------------------------------------------------------------------------------- --User pressed New button on NewBtn pressed do ( channelInfo.addChannel $ local UVNum = getNumUVChannels $ local StrName = "map" + UVNum as string channelInfo.NameChannel $ 3 UVNum StrName UpdateUVSetList() UVSetsListBox.selection = UVSetsListBox.items.count ) --User pressed Update button on UpdateBtn pressed do ( UpdateUVSetList() ) --User pressed Delete button on DeleteBtn pressed do ( local UVSetSelection = UVSetsListBox.selection if UVSetSelection != 1 do ( if UVSetsListBox.selection == UVSetsListBox.items.count then ( channelInfo.ClearChannel $ UVSetSelection UVSetsListBox.selection = UVSetSelection-1 ) else ( channelInfo.ClearChannel $ UVSetSelection local StrName = "map" + UVSetSelection as string channelInfo.NameChannel $ 3 UVSetSelection StrName UpdateUVSetList() ) ) ) --User pressed Edit button on EditBtn pressed do ( local uvw_mod = modpanel.getcurrentobject() local UVChannel = GetUVChannelIndex() --if uvw_mod != undefined and classof (uvw_mod) == Unwrap_UVW then if classof (uvw_mod) == Unwrap_UVW and uvw_mod.getMapChannel() == UVChannel then ( uvw_mod.edit() ) else ( modPanel.addModToSelection (Unwrap_UVW ()) ui:on uvw_mod = modpanel.getcurrentobject() uvw_mod.unwrap.setMapChannel UVChannel UVChannelSilentReset uvw_mod uvw_mod.edit() ) ) --User pressed Close button on CloseBtn pressed do ( try(destroyDialog UVSetEditorRollout)catch() ) --User pressed Rename button on RenameBtn pressed do ( local theDialogPos = GetDialogPos UVSetEditorRollout theDialogPos.x -= 40 theDialogPos.y += UVSetEditorRollout.height/2-30 local UVSetName = GetSpecificUVSetFromObj UVSetsListBox.selection $ RenameUVSetRollout.Str = UVSetName createDialog RenameUVSetRollout pos:[theDialogPos.x,theDialogPos.y] parent:UVSetEditorRollout.hwnd style:#(#style_toolwindow, #style_sysmenu) modal:true ) --User pressed Duplicate button on DuplicateBtn pressed do ( ChannelInfo.CopyChannel $ 3 UVSetsListBox.selection channelInfo.addChannel $ local UVNum = getNumUVChannels $ local StrName = "map" + UVNum as string channelInfo.NameChannel $ 3 UVNum StrName ChannelInfo.PasteChannel $ 3 UVNum UpdateUVSetList() UVSetsListBox.selection = UVSetsListBox.items.count ) on CopyBtn pressed do ( ChannelInfo.CopyChannel $ 3 UVSetsListBox.selection ) on PasteBtn pressed do ( ChannelInfo.PasteChannel $ 3 UVSetsListBox.selection ) ---------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------- SAVE DEFAULTS TO FILE ------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------- --when user closing this window on UVSetEditorRollout close do ( --getting dialog position local theDialogPos = GetDialogPos UVSetEditorRollout --saving settings to a file SaveToFile DefaultsFilePath "Defaults" "DialogPositionX" theDialogPos.x SaveToFile DefaultsFilePath "Defaults" "DialogPositionY" theDialogPos.y --remove callback try(callbacks.removeScripts id:#UpdateUVSetList)catch() ) )--End of Rollout Definition --When script is launching on execute do ( --Try to destroy previous rollout try(destroyDialog UVSetEditorRollout)catch() try ( local DialogPositionX = LoadValueFromFile DefaultsFilePath "Defaults" "DialogPositionX" as integer local DialogPositionY = LoadValueFromFile DefaultsFilePath "Defaults" "DialogPositionY" as integer ) catch() --OpenDialog if (DialogPositionX != undefined) and (DialogPositionY != undefined) then ( --load postion from file createDialog UVSetEditorRollout Pos: [DialogPositionX,DialogPositionY] style:#(#style_toolwindow, #style_sysmenu) ) else ( --start from the default postion createDialog UVSetEditorRollout Pos: [1300,230] style:#(#style_toolwindow, #style_sysmenu) ) ) )