def uvmp_align_cardinal(*args, **kwargs): ''' automaticaly rotate uv shell to align selected edge vertically or horizontally ''' edges = pm.filterExpand(sm=32, ex=True) if edges: uvs = pm.polyListComponentConversion(edges[0], toUV=True) uvs = pm.filterExpand(uvs, sm=35, ex=True) uvA = pm.polyEditUV(uvs[0], q=True) uvB = pm.polyEditUV(uvs[1], q=True) pm.select(uvs, replace=True) xDiff = uvA[0] - uvB[0] yDiff = uvA[1] - uvB[1] angle = math.degrees(math.atan2(yDiff, xDiff)) # find the quadrant of the vector and flip the rotation if needed sign = 1 if angle <= 45 and angle > -180: sign = -1 # find the minimum angle while abs(angle) > 45: if angle > 0: angle = 90 - angle else: angle = 90 + angle angle = sign * angle # invert or not try: texDim = lcTexture.TextureEditor().getTextureDimensions() uvCenter = lcGeometry.UV().getBoundingBoxCenter() lcGeometry.UV().grabShell() lcGeometry.UV().rotate(angle, uvCenter, texDim) except: lcUtility.Utility.lc_print_exception('something went wrong') finally: pm.select(edges, replace=True) else: lcUtility.Utility.lc_print('Please select an edge to straighten along', mode='warning')
def uvmp_rotate(angle=0, *args, **kwargs): ''' rotate uv's based on an angle with aspect ratio correction ''' shell = pm.checkBox(prefix + '_checkBox_shell', q=True, v=True) sel = pm.ls(sl=True) if sel: uvs = pm.polyListComponentConversion(sel, toUV=True) pm.select(uvs, replace=True) try: texDim = lcTexture.TextureEditor().getTextureDimensions() if shell: uvCenter = lcGeometry.UV().getBoundingBoxCenter(shell=True) lcGeometry.UV().rotateShell(angle, uvCenter, texDim) else: uvCenter = lcGeometry.UV().getBoundingBoxCenter() lcGeometry.UV().rotate(angle, uvCenter, texDim) except: lcUtility.Utility.lc_print_exception('something went wrong') finally: pm.select(sel, replace=True)
def uvmp_move(uvw=[0, 0], *args, **kwargs): ''' commands for moving uvs or uv shells ''' shell = pm.checkBox(prefix + '_checkBox_shell', q=True, v=True) sel = pm.ls(sl=True) if sel: uvs = pm.polyListComponentConversion(sel, toUV=True) pm.select(uvs, replace=True) try: if pm.checkBox(prefix + '_checkBox_shell', q=True, v=True): lcGeometry.UV().moveShell(uvw) lcGeometry.UV().grabShell( ) # not necessary to grab the shell, but makes for better visual feedback else: lcGeometry.UV().move(uvw) except: lcUtility.Utility.lc_print_exception('something went wrong') finally: pm.select(sel, replace=True)
def lcUVToolsUI(dockable=False, asChildLayout=False, *args, **kwargs): ''' ''' global lct_cfg global prefix global height windowName = 'lcUVTools' shelfCommand = 'import lct.src.{0}.{0} as {1}\nreload({1})\n{1}.{0}UI()'.format( windowName, prefix) commandString = 'import lct.src.{0}.{0} as {1}\nreload({1})\n{1}.{0}UI(asChildLayout=True)'.format( windowName, prefix) icon = os.path.join(basePath, 'lcUVTools.png') if pm.window(windowName, ex=True): pm.deleteUI(windowName) if not asChildLayout: lcUI.UI.lcToolbox_child_popout(prefix + '_columnLayout_main', windowName, height, commandString, iconPath, lct_cfg) mainWindow = lcUI.lcWindow(prefix=prefix, windowName=windowName, width=width, height=height, icon=icon, shelfCommand=shelfCommand, annotation=annotation, dockable=dockable, menuBar=True) mainWindow.create() # column for the uv tool bar pm.columnLayout(prefix + '_columnLayout_main') # build ui in parts # Row 1 - basic pm.rowColumnLayout(nc=4, cw=[(1, 95), (2, 35), (3, 35), (4, 35)]) pm.columnLayout() pm.checkBox( prefix + '_checkBox_shell', l=' Shell Mode', v=False, changeCommand=lambda *args: lct_cfg.set( 'lcUVToolsShell', pm.checkBox(prefix + '_checkBox_shell', query=True, v=True))) pm.button(l='Grab Shell', bgc=colorWheel.getNext(), h=20, w=93, command=lambda *args: lcGeometry.UV().grabShell()) pm.setParent('..') pm.symbolButton(image=os.path.join(srcPath, 'icons', 'temp.png'), enable=False, visible=False) button_snapshot = pm.symbolButton(image='polyUVSnapshot.png', annotation='Take UV Snapshot', command=lambda *args: uvmp_uv_snapshot()) popup_snapshot = pm.popupMenu(parent=button_snapshot) pm.menuItem( prefix + '_checkBox_antiAlias', l='Antialias', checkBox=False, parent=popup_snapshot, command=lambda *args: lct_cfg.set( 'lcUVToolsAntialias', pm.menuItem( prefix + '_checkBox_antiAlias', query=True, checkBox=True))) pm.menuItem( prefix + '_checkBox_openPS', l='Auto Open PS', checkBox=True, parent=popup_snapshot, command=lambda *args: lct_cfg.set( 'lcUVToolsOpenPS', pm.menuItem(prefix + '_checkBox_openPS', query=True, checkBox=True) )) pm.symbolButton(image='textureEditor.png', annotation='Open the UV Editor', command=lambda *args: pm.mel.eval('TextureViewWindow')) # pm.text(l='') pm.setParent(prefix + '_columnLayout_main') # Row 2 pm.separator(style='in', h=10, w=200) row2 = pm.rowColumnLayout(nc=3, cw=[(1, 66), (2, 66), (3, 66)]) ##MOVE pm.columnLayout() pm.text(l='Move', w=66, align='center') pm.separator(style='none', h=9) bgc = colorWheel.getNext() pm.rowColumnLayout(nc=3, cw=[(1, 15), (2, 34), (3, 15)]) pm.text(l='') pm.button( l='^', h=15, bgc=bgc, command=lambda *args: uvmp_move( [0, 1 * pm.floatField(prefix + '_move_value', q=True, v=True)])) pm.text(l='') pm.button( l='<', bgc=bgc, command=lambda *args: uvmp_move( [-1 * pm.floatField(prefix + '_move_value', q=True, v=True), 0])) pm.floatField(prefix + '_move_value', h=34, v=1.00, pre=2) pm.button( l='>', bgc=bgc, command=lambda *args: uvmp_move( [1 * pm.floatField(prefix + '_move_value', q=True, v=True), 0])) pm.text(l='') pm.button( l='v', h=15, bgc=bgc, command=lambda *args: uvmp_move( [0, -1 * pm.floatField(prefix + '_move_value', q=True, v=True)])) pm.text(l='') pm.setParent(row2) ##SCALE pm.columnLayout() pm.text(l='Scale', w=66, align='center') pm.separator(style='none', h=4) bgc = colorWheel.getNext() pm.rowColumnLayout(nc=3, cw=[(1, 25), (2, 14), (3, 25)]) pm.button('U+', bgc=bgc, c=lambda *args: uvmp_scale( [pm.floatField(prefix + '_scale_value', q=True, v=True), 1])) pm.button('+', bgc=bgc, c=lambda *args: uvmp_scale([ pm.floatField(prefix + '_scale_value', q=True, v=True), pm.floatField(prefix + '_scale_value', q=True, v=True) ])) pm.button( 'V+', bgc=bgc, c=lambda *args: uvmp_scale( [1, pm.floatField(prefix + '_scale_value', q=True, v=True)])) pm.setParent('..') pm.rowColumnLayout(nc=3, cw=[(1, 13), (2, 38), (3, 13)]) pm.text(l='') pm.floatField(prefix + '_scale_value', v=2.00, min=1.0, pre=2, h=25) pm.text(l='') pm.setParent('..') pm.rowColumnLayout(nc=3, cw=[(1, 25), (2, 14), (3, 25)]) pm.button( 'U-', bgc=bgc, c=lambda *args: uvmp_scale([ pm.floatField(prefix + '_scale_value', q=True, v=True) / pow( pm.floatField(prefix + '_scale_value', q=True, v=True), 2), 1 ])) # x/(x^2) pm.button( '-', bgc=bgc, c=lambda *args: uvmp_scale([ pm.floatField(prefix + '_scale_value', q=True, v=True) / pow( pm.floatField(prefix + '_scale_value', q=True, v=True), 2), pm.floatField(prefix + '_scale_value', q=True, v=True) / pow( pm.floatField(prefix + '_scale_value', q=True, v=True), 2) ])) # x/(x^2) pm.button( 'V-', bgc=bgc, c=lambda *args: uvmp_scale([ 1, pm.floatField(prefix + '_scale_value', q=True, v=True) / pow( pm.floatField(prefix + '_scale_value', q=True, v=True), 2) ])) # x/(x^2) pm.setParent(row2) ##ROTATE pm.columnLayout() pm.text(l='Rotate', w=66, align='center') pm.separator(h=2) bgc = colorWheel.getNext() pm.rowColumnLayout(nc=2, cw=[(1, 16), (2, 48)]) pm.columnLayout() pm.button(prefix + '_clockwise', l='>', bgc=bgc, w=15, h=20, c=lambda *args: uvmp_rotate(-pm.floatField( prefix + '_rotate_value', q=True, v=True))) pm.button(prefix + '_counter_clockwise', l='<', bgc=bgc, w=15, h=20, c=lambda *args: uvmp_rotate( pm.floatField(prefix + '_rotate_value', q=True, v=True))) pm.setParent('..') pm.floatField(prefix + '_rotate_value', v=45.00, pre=2, h=40) pm.setParent('..') pm.floatSlider(prefix + '_rotate_free', min=-1, max=1, v=0, w=64, dc=uvmp_rotate_interactive, cc=uvmp_reset_slider) pm.button(l='align', bgc=bgc, w=65, h=20, command=lambda *args: uvmp_align_cardinal()) pm.setParent(prefix + '_columnLayout_main') # Row 3 pm.separator(style='in', h=10, w=200) row3 = pm.rowColumnLayout(nc=2, cw=[(1, 100), (2, 100)]) uvmp_texture_range_UI() pm.setParent(row3) ##TOOLS pm.gridLayout(nrc=[2, 2], cwh=[48, 48]) pm.symbolButton(image='expandContainer.png', bgc=(0.25, 0.5, 0.25), command=lambda *args: uvmp_split_edges_at_UVs(), annotation='Enter UV Unfold') pm.symbolButton(image='collapseContainer.png', bgc=(0.5, 0.25, 0.25), command=lambda *args: uvmp_merge_special(), annotation='Exit UV Unfold') pm.symbolButton(image='polyMapCut.png', command=lambda *args: uvmp_cut_edge(), annotation='Cut UV Edge') pm.symbolButton(image='textureEditorUnfoldUVsLarge.png', command=lambda *args: uvmp_auto_layout(), annotation='Auto UV Layout') pm.setParent(prefix + '_columnLayout_main') # #Row 4 # pm.separator(style='in', h=10, w=200) # pm.rowColumnLayout(nc=2, cw=[(1,100), (2,100)]) # pm.setParent(prefix+'_columnLayout_main') # if not asChildLayout: mainWindow.show() pm.window(mainWindow.mainWindow, edit=True, h=height, w=width) else: pm.setParent('..') pm.setParent('..') # edit menus optionsMenu, helpMenu = lcUI.UI.lcToolbox_child_menu_edit( asChildLayout, windowName) # restore interface selections pm.checkBox(prefix + '_checkBox_shell', edit=True, value=lct_cfg.get('lcUVToolsShell')) # extra stuff pm.setFocus( prefix + '_move_value' ) # set cursor focus on move value, otherwise it sets to first available ui element lcPlugin.Plugin.reload_plugin(plugin='Unfold3D', autoload=True)