inst = hou.pwd() # set this node mat_path = 'geo_mat/material1' # path to material node in network mat = inst.node(mat_path) # set material node delt_path = 'geo_mat/delete1' # path to delete node in network for optomization delt = inst.node(delt_path) # set delete node shader = '../../shopnet1/v_asadlight1' # path to instanced light shader # list of light shader groups w/ wing number stripped from name ### NOTE: order is important; lights_cell_long (second floor light group) needs to be last groups = ['lights_skylight', 'lights_hanging', 'lights_cell_fill', 'lights_cell_short', 'lights_cell_long'] log_path = '/home/seandooley/_work/vsfx408/houdini/python' #log_path = '/media/LITTLE_ONE/vsfx408/houdini/python' ### ------------------------------------------------------------------------------------------------------ ### ----------------------------- ### ------------------------------------------------------------------------------------------------------ def update_all(): pen_path = inst.parm('input_geo').eval() # path to penitentiary node w/ controls wings = hou.node(pen_path).parm('num_wings').eval() # number of wings len_grp = len(groups) # number of light groups per wing overides = 6 # number of overides per light group num = wings * len_grp # total number of materials inst.parm('folder9_1').set(len_grp) # set number of light types inst.parm('folder9_2').set(wings) # set number of wings delt.parm('entity').set('point') # set delete node to points instead of primitives # set object merge in node to reference the digital asset's value for the object inst.node('geo_mat/object_merge1').parm('objpath1').setExpression('chs("../../../%s/input_lights")' % inst) # checks to see how many wings have a second floor and modifies the number of materials accordingly secnd = [] secnd_total = 0 for c in xrange(wings): c += 1 secnd.append(hou.node(pen_path).parm('secnd_floor%s' % c).eval()) secnd_total += secnd[c-1] without = wings - secnd_total # set number of wings without a second floor num -= without # modify number of total materials mat.parm('num_materials').set(num) # set number of materials mat.parm('style').set('point') # set attribute type to point attributes instead of primitive # on instance node, set number of materials per wing for i in xrange(wings): i += 1 # error check to see if there is a second floor if secnd[i-1] == 1: inst.parm('folder9_2_%s' % i).set(len_grp) else: inst.parm('folder9_2_%s' % i).set(int(len_grp) - 1) # on instance node, set group name for master light groups for b in xrange(len_grp): b += 1 inst.parm('grp_name_%s' % b).set('%s' % groups[b-1]) # on instance node, set group name per light group per wing for j in xrange(wings): j += 1 # error check to see if there is a second floor if secnd[j-1] == 1: temp = len_grp else: temp = len_grp - 1 for k in xrange(temp): k += 1 inst.parm('grp_name_%s_%s' % (j, k)).set('%s_%s' % (groups[k-1], j) ) # on material node, set common varriables for a in xrange(num): a += 1 mat.parm('shop_materialpath%s' % a ).set(shader) mat.parm('localvar%s' % a ).set(1) mat.parm('num_local%s' % a ).set(overides) # on material node, set group name based on group list and wing number x = 1 for y in xrange(wings): y += 1 # error to check to see if there is a second floor if secnd[y-1] == 1: temp = len_grp else: temp = len_grp - 1 for z in xrange(temp): mat.parm('group%s' % x).set('%s_%s' % (groups[z], y)) x += 1 # on material node, set values based on instance node parameters ### sets a complex expression so that if the master synchronize switch is enabbled for the light group (wing number independant), ### all materials belonging to the same light group type are the same l, p = 1, 0 # l for wing number, p for light group number for n in xrange(num): n += 1 p += 1 # light group increases every material number for m in xrange(overides): m += 1 if m == 1: mat.parm('local%s_name%s' % (n, m) ).set('lightcolor') mat.parm('local%s_type%s' % (n, m) ).set('color') mat.parm('local%s_cval%sr' % (n, m)).setExpression('if(ch("../../master_%s") == 0, ch("../../color_%s_%sr"), ch("../../color_%sr"))' % (p, l, p, p)) mat.parm('local%s_cval%sg' % (n, m)).setExpression('if(ch("../../master_%s") == 0, ch("../../color_%s_%sg"), ch("../../color_%sg"))' % (p, l, p, p)) mat.parm('local%s_cval%sb' % (n, m)).setExpression('if(ch("../../master_%s") == 0, ch("../../color_%s_%sb"), ch("../../color_%sb"))' % (p, l, p, p)) elif m == 2: mat.parm('local%s_name%s' % (n, m) ).set('atten') mat.parm('local%s_type%s' % (n, m) ).set('float') mat.parm('local%s_fval%s' % (n, m)).setExpression('if(ch("../../master_%s") == 0, ch("../../atten_%s_%s"), ch("../../atten_%s"))' % (p, l, p, p)) elif m == 3: mat.parm('local%s_name%s' % (n, m) ).set('docone') mat.parm('local%s_type%s' % (n, m) ).set('int') mat.parm('local%s_ival%s' % (n, m)).set(1) elif m == 4: mat.parm('local%s_name%s' % (n, m) ).set('coneangle') mat.parm('local%s_type%s' % (n, m) ).set('float') mat.parm('local%s_fval%s' % (n, m)).setExpression('if(ch("../../master_%s") == 0, ch("../../cone_angle_%s_%s"), ch("../../cone_angle_%s"))' % (p, l, p, p)) elif m == 5: mat.parm('local%s_name%s' % (n, m) ).set('conedelta') mat.parm('local%s_type%s' % (n, m) ).set('float') mat.parm('local%s_fval%s' % (n, m)).setExpression('if(ch("../../master_%s") == 0, ch("../../cone_delta_%s_%s"), ch("../../cone_delta_%s"))' % (p, l, p, p)) elif m == 6: mat.parm('local%s_name%s' % (n, m) ).set('conerolloff') mat.parm('local%s_type%s' % (n, m) ).set('float') mat.parm('local%s_fval%s' % (n, m)).setExpression('if(ch("../../master_%s") == 0, ch("../../cone_rolloff_%s_%s"), ch("../../cone_rolloff_%s"))' % (p, l, p, p)) # error check to see if there is a second floor or not - will affect how manyloops there need to be if secnd[l-1] == 1: if p % len_grp == 0: # checks size of p against size of light group list p = 0 # set light group number to 0 l += 1 # incriment wing number # if no second floor, need one less loop else: if p % (len_grp - 1) == 0: # checks size of p agasint size of light group list minue one p = 0 # set light group number to 0 l += 1 # incriment wing number ### ------------------------------------------------------------------------------------------------------ ### ----------------------------- ### ------------------------------------------------------------------------------------------------------ def optomize(): num = mat.parm('num_materials').eval() # set based on number of materials used_groups = [] # create empty list for group names that have light values # loops through number of materials on material node, checks the value of the attenuation for each material for g in xrange(num): g += 1 # if atten value is greater than 0 (i.e. there is light being emitted), get group name and add to used_groups list if mat.parm('local%s_fval2' % g).eval() > 0: used_groups.append(mat.parm('group%s' % g).eval()) delt_str = '' # create empty string for used light groups # loop through used_group list, adds each group name to the delt_str with spacing for k in xrange(len(used_groups)): delt_str += ('%s ' % used_groups[k]) # set up the delete node with all necessary values delt.parm('negate').set('keep') delt.parm('group').set(delt_str) ### ------------------------------------------------------------------------------------------------------ ### ----------------------------- ### ------------------------------------------------------------------------------------------------------ def output(): out = '' # set empty string for output file master = inst.parm('folder9_1').eval() # get number of master parameters (i.e. lights) out += '#--number of light types: %s\n' % master # add to output string for k in xrange(master): # loop through master lights to get the parameters k += 1 # get values from parameters switch = inst.parm('master_%s' % k).eval() group = inst.parm('grp_name_%s' % k).eval() atten = inst.parm('atten_%s' % k).eval() colorr = inst.parm('color_%sr' % k).eval() colorg = inst.parm('color_%sg' % k).eval() colorb = inst.parm('color_%sb' % k).eval() angle = inst.parm('cone_angle_%s' % k).eval() delta = inst.parm('cone_delta_%s' % k).eval() rollo = inst.parm('cone_rolloff_%s' % k).eval() # add values to output string out += '{' out += '\t%s: %s,' % ('master_%s' % k, switch) out += '\t%s: %s,' % ('grp_name_%s' % k, group) out += '\t%s: %s,' % ('atten_%s' % k, atten) out += '\t%s: %s,' % ('color_%sr' % k, colorr) out += '\t%s: %s,' % ('color_%sg' % k, colorg) out += '\t%s: %s,' % ('color_%sb' % k, colorb) out += '\t%s: %s,' % ('cone_angle_%s' % k, angle) out += '\t%s: %s,' % ('cone_delta_%s' % k, delta) out += '\t%s: %s' % ('cone_rolloff_%s' % k, rollo) out += '\t}\n' wings = inst.parm('folder9_2').eval() # get number of wings out += '#--number of wings: %s\n' % wings # add to output string for h in xrange(wings): # loop through number of wings h += 1 lights = inst.parm('folder9_2_%s' % h).eval() # determine number of lights for the wing for i in xrange(lights): # loop through number of lights to get parameters i += 1 # get values from parameters group = inst.parm('grp_name_%s_%s' % (h, i)).eval() atten = inst.parm('atten_%s_%s' % (h, i)).eval() colorr = inst.parm('color_%s_%sr' % (h, i)).eval() colorg = inst.parm('color_%s_%sg' % (h, i)).eval() colorb = inst.parm('color_%s_%sb' % (h, i)).eval() angle = inst.parm('cone_angle_%s_%s' % (h, i)).eval() delta = inst.parm('cone_delta_%s_%s' % (h, i)).eval() rollo = inst.parm('cone_rolloff_%s_%s' % (h, i)).eval() # add values to output string out += '{' out += '\t%s: %s,' % ('grp_name_%s_%s' % (h, i), group) out += '\t%s: %s,' % ('atten_%s_%s' % (h, i), atten) out += '\t%s: %s,' % ('color_%s_%sr' % (h, i), colorr) out += '\t%s: %s,' % ('color_%s_%sg' % (h, i), colorg) out += '\t%s: %s,' % ('color_%s_%sb' % (h, i), colorb) out += '\t%s: %s,' % ('cone_angle_%s_%s' % (h, i), angle) out += '\t%s: %s,' % ('cone_delta_%s_%s' % (h, i), delta) out += '\t%s: %s' % ('cone_rolloff_%s_%s' % (h, i), rollo) out += '\t}\n' # create the output file based on output string f = open('%s/light_log.txt' % log_path, 'w') f.write(out) f.close() ### ------------------------------------------------------------------------------------------------------ ### ----------------------------- ### ------------------------------------------------------------------------------------------------------ def readin(): out = '' f = open('%s/light_log.txt' % log_path, 'r') # loop through every line in the file for line in f: if line[0] == '{': # check to see if the line contains stored values (based on {} ) # remove unnecessary storage characters line = line.lstrip('{') line = line.rstrip('}\n') atr = line.split(',') # split apart the parameters in brackets of name and value for single in atr: # loop through the groupings key, value = single.split(':') # seperate apart the parameter name and the value key = key.strip() # clean up value = value.strip() # clean up if key.startswith('grp_'): # if the key (parameter name) is a group, set as a string value inst.parm(key).set(value) else: # else the key (parameter name) refers to a float value inst.parm(key).set( round(float(value), 3) ) f.close()