Shader Tree Navigation

From The Foundry MODO SDK wiki
Jump to: navigation, search

Some useful utility functions for navigating the Shader Tree & returning items of various types.

#!/usr/bin/env python
 
import traceback
import lx
import lxu
from lxu import select
 
scene_service = lx.service.Scene()
current_scene = lxu.select.SceneSelection().current()
 
 
def get_masks():
    ''' gets *all* the mask in the shader tree - some of these could be children
        of other masks.
 
    '''
    masks = []
    # look up the mask item type
    mask_type = scene_service.ItemTypeLookup(lx.symbol.sITYPE_MASK)
    nummasks = current_scene.ItemCount(mask_type)
    for x in range(nummasks):
        masks.append(current_scene.ItemByIndex(mask_type, x))
    return masks
 
 
def get_root_items(itype=None):
    ''' gets items in the root of the shader tree. If an Item type is supplied
        as an argument method returns only items of that type.
 
    '''
    rootitems = []
    # get the render item type
    render_item_type = scene_service.ItemTypeLookup(lx.symbol.sITYPE_POLYRENDER)
    # currently there's only ever one render item in the scene so we can ask for
    # any item of that type
    render_item = current_scene.AnyItemOfType(render_item_type)
    if render_item.test():
        children = get_children(render_item)
        for child in children:
            # if an item type was passed in as an argument just add items of
            # that type.
            if itype:
                item_type = scene_service.ItemTypeLookup(itype)
                if child.TestType(item_type):
                    rootitems.append(child)
                continue
            # otherwise just append the current item
            rootitems.append(child)
    return rootitems
 
 
def get_children(item, itype=None):
    ''' returns the children of an item. If an item type is supplied method returns
        only items of that specific type.
 
    '''
    children = []
    numchildren = item.SubCount()
    for x in range(numchildren):
        child = item.SubByIndex(x)
        if itype:
            item_type = scene_service.ItemTypeLookup(itype)
            if child.TestType(item_type):
                children.append(child)
            continue
        children.append(child)
    return children
 
 
def get_selected_by_type(itype):
    ''' returns selected items of type itype '''
    items = []
    # get all curently selcted items
    selected = lxu.select.ItemSelection().current()
    # lookup the type we're interested in
    item_type = scene_service.ItemTypeLookup(itype)
    for item in selected:
        if item.TestType(item_type):
            items.append(item)
    return items
 
 
def get_items_by_type(itype):
    ''' returns all items in the scene of type itype '''
    items = []
    # lookup the item type
    item_type = scene_service.ItemTypeLookup(itype)
    # get a count of itype items in the scenr
    numitems = current_scene.ItemCount(item_type)
    for x in range(numitems):
        items.append(current_scene.ItemByIndex(item_type, x))
    return items



The last function, get_items_by_type(itype), is more a more general function. With it you can get a list of any item type, for example:

# gradient shader layers
gradients = get_items_by_type(lx.symbol.sITYPE_GRADIENT)
 
# environment items
environments = get_items_by_type(lx.symbol.sITYPE_ENVIRONMENT)
 
# all light items
lights = get_items_by_type(lx.symbol.sITYPE_LIGHT)
 
#just spotlight items
spotlights = get_items_by_type(lx.symbol.sITYPE_SPOTLIGHT)