Maya Light Converter UI

This page shows the results of my personal explorations of creating a UI in Maya that will convert lights that are compatible with the Arnold rendering system to lights that are compatible with the RenderMan rendering system. The UI will also allow the user to select the specific lights that he or she wishes to convert.

 

ALGORITHM

  1. Create parameters for window.

  2. Define the functions for each conversion button.

    2.1 Create associated RenderMan light.

    2.2 Connect attributes (translate, rotate, scale, intensity, exposure, and color).

  3. Create layout for each tab.

    3.1 Insert Outliner for each tab.

    3.2 Insert conversion button and connect to function defined above for each tab.

    3.3 Set parent for each layout style for each tab.

 

INSTRUCTIONS

  1. Save the python script "lightConverterUI.py" into the "../maya/scripts" folder.

  2. Inside Maya, open the script editor.

  3. Import the python script by typing this into the script editor (image example below under "Executing the Script"):

    import lightConverterUI
    reload (lightConverterUI)

  4. Execute the command by selecting all (ctrl + a) and pressing the enter button on the number pad; or by selecting all (ctrl + a), clicking the right mouse button, and pressing execute.

 

THE CODE - "lightConverterUI.py"

import maya.cmds as cmds
import rfm2
import mtoa.utils
  
# 1. Create parameters for window.
cmds.window(title = "Arnold to RenderMan Light Converter", widthHeight=(423, 500), mnb = False, mxb = False)
form = cmds.formLayout()
tabs = cmds.tabLayout(innerMarginWidth=5, innerMarginHeight=5)
cmds.formLayout( form, edit=True, attachForm=((tabs, 'top', 0), (tabs, 'left', 0), (tabs, 'bottom', 0), (tabs, 'right', 0)) )
  
# 2. Define the functions for each conversion button.
def buttonPush(*args):
    # 2.1 Create associated RenderMan light.
    rfm2.api.nodes.create_and_select('PxrRectLight')
    # 2.2 Connect attributes (translate, rotate, scale, intensity, exposure, and color).
    cmds.connectAttr('areaLight*.translate', 'PxrRectLight.translate')
    cmds.connectAttr('areaLight*.rotate', 'PxrRectLight.rotate')
    cmds.connectAttr('areaLight*.scale', 'PxrRectLight.scale')
    cmds.connectAttr('areaLight*.intensity', 'PxrRectLight.intensity')
    cmds.connectAttr('areaLightShape*.aiExposure', 'PxrRectLightShape.exposure')
    cmds.connectAttr('areaLightShape*.color', 'PxrRectLightShape.lightColor')
  
def buttonPush2(*args):
    rfm2.api.nodes.create_and_select('PxrDistantLight')
    cmds.connectAttr('directionalLight*.translate', 'PxrDistantLight.translate')
    cmds.connectAttr('directionalLight*.rotate', 'PxrDistantLight.rotate')
    cmds.connectAttr('directionalLight*.scale', 'PxrDistantLight.scale')
    cmds.connectAttr('directionalLight*.intensity', 'PxrDistantLight.intensity')
    cmds.connectAttr('directionalLightShape*.aiExposure', 'PxrDistantLightShape.exposure')
    cmds.connectAttr('directionalLightShape*.color', 'PxrDistantLightShape.lightColor')
    
def buttonPush3(*args):
    rfm2.api.nodes.create_and_select('PxrDiskLight')
    cmds.connectAttr('spotLight*.translate', 'PxrDiskLight.translate')
    cmds.connectAttr('spotLight*.rotate', 'PxrDiskLight.rotate')
    cmds.connectAttr('spotLight*.scale', 'PxrDiskLight.scale')
    cmds.connectAttr('spotLight*.intensity', 'PxrDiskLight.intensity')
    cmds.connectAttr('spotLightShape*.aiExposure', 'PxrDiskLightShape.exposure')
    cmds.connectAttr('spotLightShape*.color', 'PxrDiskLightShape.lightColor')
  
def buttonPush4(*args):
    rfm2.api.nodes.create_and_select('PxrSphereLight')
    cmds.connectAttr('pointLight*.translate', 'PxrSphereLight.translate')
    cmds.connectAttr('pointLight*.rotate', 'PxrSphereLight.rotate')
    cmds.connectAttr('pointLight*.scale', 'PxrSphereLight.scale')
    cmds.connectAttr('pointLight*.intensity', 'PxrSphereLight.intensity')
    cmds.connectAttr('pointLightShape*.aiExposure', 'PxrSphereLightShape.exposure')
    cmds.connectAttr('pointLightShape*.color', 'PxrSphereLightShape.lightColor')
  
def buttonPush5(*args):
    rfm2.api.nodes.create_and_select('PxrDomeLight')
    cmds.connectAttr('aiSkyDomeLight*.translate', 'PxrDomeLight.translate')
    cmds.connectAttr('aiSkyDomeLight*.rotate', 'PxrDomeLight.rotate')
    cmds.connectAttr('aiSkyDomeLight*.scale', 'PxrDomeLight.scale')
    cmds.connectAttr('aiSkyDomeLight*.intensity', 'PxrDomeLight.intensity')
    cmds.connectAttr('aiSkyDomeLight*.aiExposure', 'PxrDomeLightShape.exposure')
    cmds.connectAttr('aiSkyDomeLight*.color', 'PxrDomeLightShape.lightColor')
  
# 3. Create layout for each tab.
tab1 = cmds.rowColumnLayout(numberOfColumns=2)
# 3.1 Insert Outliner for each tab.
cmds.frameLayout(w = 415, h = 475, label='Select Area Light Below', labelVisible=True)
panel = cmds.outlinerPanel()
outliner = cmds.outlinerPanel(panel, query=True,outlinerEditor=True)
cmds.outlinerEditor( outliner, edit=True, mainListConnection='worldList', selectionConnection='modelList', showShapes=False, showAttributes=False, showConnected=False, showAnimCurvesOnly=False, autoExpand=False, showDagOnly=True, ignoreDagHierarchy=False, expandConnections=False, showCompounds=True, showNumericAttrsOnly=False, highlightActive=True, autoSelectNewObjects=False, doNotSelectNewObjects=False, transmitFilters=False, showSetMembers=True, setFilter='defaultSetFilter')
# 3.2 Insert conversion button and connect to function defined above.
cmds.button(label = 'Convert', command = buttonPush, w = 350)
# 3.3 Set parent for each layout style.
cmds.setParent( '..' )
cmds.setParent( '..' )
cmds.setParent( '..' )
  
tab2 = cmds.rowColumnLayout(numberOfColumns=2)
cmds.frameLayout(w = 415, h = 475, label='Select Directional Light Below', labelVisible=True)
panel = cmds.outlinerPanel()
outliner = cmds.outlinerPanel(panel, query=True,outlinerEditor=True)
cmds.outlinerEditor( outliner, edit=True, mainListConnection='worldList', selectionConnection='modelList', showShapes=False, showAttributes=False, showConnected=False, showAnimCurvesOnly=False, autoExpand=False, showDagOnly=True, ignoreDagHierarchy=False, expandConnections=False, showCompounds=True, showNumericAttrsOnly=False, highlightActive=True, autoSelectNewObjects=False, doNotSelectNewObjects=False, transmitFilters=False, showSetMembers=True, setFilter='defaultSetFilter')
cmds.button(label = 'Convert', command = buttonPush2, w = 350)
cmds.setParent( '..' )
cmds.setParent( '..' )
cmds.setParent( '..' )
  
tab3 = cmds.rowColumnLayout(numberOfColumns=2)
cmds.frameLayout(w = 415, h = 475, label='Select Spotlight Below', labelVisible=True)
panel = cmds.outlinerPanel()
outliner = cmds.outlinerPanel(panel, query=True,outlinerEditor=True)
cmds.outlinerEditor( outliner, edit=True, mainListConnection='worldList', selectionConnection='modelList', showShapes=False, showAttributes=False, showConnected=False, showAnimCurvesOnly=False, autoExpand=False, showDagOnly=True, ignoreDagHierarchy=False, expandConnections=False, showCompounds=True, showNumericAttrsOnly=False, highlightActive=True, autoSelectNewObjects=False, doNotSelectNewObjects=False, transmitFilters=False, showSetMembers=True, setFilter='defaultSetFilter')
cmds.button(label = 'Convert', command = buttonPush3, w = 350)
cmds.setParent( '..' )
cmds.setParent( '..' )
cmds.setParent( '..' )
  
tab4 = cmds.rowColumnLayout(numberOfColumns=2)
cmds.frameLayout(w = 415, h = 475, label='Select Point Light Below', labelVisible=True)
panel = cmds.outlinerPanel()
outliner = cmds.outlinerPanel(panel, query=True,outlinerEditor=True)
cmds.outlinerEditor( outliner, edit=True, mainListConnection='worldList', selectionConnection='modelList', showShapes=False, showAttributes=False, showConnected=False, showAnimCurvesOnly=False, autoExpand=False, showDagOnly=True, ignoreDagHierarchy=False, expandConnections=False, showCompounds=True, showNumericAttrsOnly=False, highlightActive=True, autoSelectNewObjects=False, doNotSelectNewObjects=False, transmitFilters=False, showSetMembers=True, setFilter='defaultSetFilter')
cmds.button(label = 'Convert', command = buttonPush4, w = 350)
cmds.setParent( '..' )
cmds.setParent( '..' )
cmds.setParent( '..' )
  
tab5 = cmds.rowColumnLayout(numberOfColumns=2)
cmds.frameLayout(w = 415, h = 475, label='Select Sky Dome Light Below', labelVisible=True)
panel = cmds.outlinerPanel()
outliner = cmds.outlinerPanel(panel, query=True,outlinerEditor=True)
cmds.outlinerEditor( outliner, edit=True, mainListConnection='worldList', selectionConnection='modelList', showShapes=False, showAttributes=False, showConnected=False, showAnimCurvesOnly=False, autoExpand=False, showDagOnly=True, ignoreDagHierarchy=False, expandConnections=False, showCompounds=True, showNumericAttrsOnly=False, highlightActive=True, autoSelectNewObjects=False, doNotSelectNewObjects=False, transmitFilters=False, showSetMembers=True, setFilter='defaultSetFilter')
cmds.button(label = 'Convert', command = buttonPush5, w = 350)
cmds.setParent( '..' )
cmds.setParent( '..' )
cmds.setParent( '..' )
  
# 4. Create the tabs and label them according to layouts defined above.
cmds.tabLayout( tabs, edit=True, tabLabel=((tab1, 'Area Light'), (tab2, 'Directional Light'), (tab3, 'Spotlight'), (tab4, 'Point Light'), (tab5, 'SkyDome Light')) )
  
# 5. Show the window upon execution of the code.
cmds.showWindow()
 

EXECUTING THE SCRIPT

Image of the commands in Maya's Script Editor that will execute the python script.

 

ARNOLD TO RENDERMAN LIGHT CONVERTER UI

Image of the Arnold to RenderMan Light Converter UI when the script is imported and executed in Maya.

 

TAB CONTENTS IN THE ARNOLD TO RENDERMAN LIGHT CONVERTER UI

Example image of the tab contents in the Arnold to RenderMan Light Converter UI before executing the conversion button.

Example image of the tab contents in the Arnold to RenderMan Light Converter UI after executing the conversion button.

 

CONVERTED LIGHTS IN MAYA WORKSPACE

Example image of Maya workspace after all conversions (except for the SkyDome Light).

 

EXAMPLE RENDERS

Example image of an Arnold render using a Directional Light.

Example image of a RenderMan render using a converted Distant Light from the Arnold Directional Light.

 

RESTRICTIONS

This code allows the user to convert Arnold lights to RenderMan lights, but restricts the user to keeping the pre-set names of the lights. The UI allows the user to convert only one light at a time and does not automatically delete the Arnold-compatable light in case the user did not wish to do so. When a new light is created through the UI, the attributes (translate, rotate, scale, intensity, exposure, and color) of the selected lights connect to those of the light created. However, the user must delete the Arnold-compatable light or break the connections to unlock and control the attributes of the light that was created. Deleting the Arnold-compatable light will not remove the values created from the connection, only the connection itself to unlock the attribute and to give the user control. I would like to go return to this code in the future and increase its functionality by removing some of these limitations.