Houdini Python Temp

From bernie's
Jump to navigation Jump to search

Alembic Camera Timewarper

This will extract any camera found in a given alembic archive node and copy it with a CHOP timewarp set to the start and endframe of the playbar TODO: cleanup code and make it as a def, do some error checking, make sur to warn the user if timeranges differ)

import hou
from _alembic_hom_extensions import alembicTimeRange as abctr


abc = hou.selectedNodes()[0] #expects an ABC archive
startF,endF = abctr(abc.parm('fileName').eval())
startF = startF * hou.fps()
endF = endF * hou.fps()


cameras = abc.recursiveGlob('*',filter=hou.nodeTypeFilter.ObjCamera)
if len(cameras)>1:
    selectedCams = hou.ui.selectFromList([camera.name() for camera in cameras], message='Select Cameras')
else:
    selectedCams = [0]
if selectedCams:
    chop = abc.parent().createNode('chopnet',abc.name()+'_warpcams')
    chop.setPosition(abc.position()+hou.Vector2(2.5, 0))
    
for index in selectedCams:
    
    cam = cameras[index]
    
    object = chop.createNode('object', cam.name())
    parms = {'targetpath':cam.path() , 'compute':'fullxform' , 'start':startF , 'end':endF , 'units':'frames'}
    for parm, value in parms.items():
        object.parm(parm).set(value)

    fetch = chop.createNode('fetch', 'camera_channels_extra')
    parms = {'nodepath':cam.path() , 'path':'aperture focal' , 'start':startF , 'end':endF , 'units':'frames' , 'range':'user'}
    for parm, value in parms.items():
        fetch.parm(parm).set(value)

    merge = chop.createNode('merge')
    merge.setInput(0,object)
    merge.setInput(1,fetch)
        
    warpcurve = chop.createNode('channel', 'time_warp_curve')
    rfstart, rfend = hou.playbar.frameRange()
    
    kf = hou.Keyframe()
    kf.setTime((rfstart-1)/hou.fps())
    kf.setValue(rfstart)
    warpcurve.parmTuple('value0')[0].setKeyframe(kf)
    kf = hou.Keyframe()
    kf.setTime((rfend-1)/hou.fps())
    kf.setValue(rfend)
    warpcurve.parmTuple('value0')[0].setKeyframe(kf)
    
    warp = chop.createNode('warp')
    warp.parm('method').set('index')
    warp.parm('scaleindex').set(1)
    warp.setInput(0,merge)
    warp.setInput(1,warpcurve)
    
    export = chop.createNode('export')
    export.parm('channels').set('t[xyz] r[xyz] aperture focal')
    export.parm('path').set('t[xyz] r[xyz] aperture focal')
    export.setExportFlag(True)
    export.setAudioFlag(True)
    export.setDisplayFlag(True)
    export.setInput(0,warp)
    
    newCam = abc.parent().createNode('cam',cam.name()+'_warp')
    export.parm('nodepath').set(newCam.path())
    newCam.setPosition(chop.position()+hou.Vector2(0, - (index+1)))
    newCam.setComment('Old: {}-{} ({}f)\nNew: {}-{} ({}f)'.format(str(int(startF)),str(int(endF)),str(int(endF-startF)), str(int(rfstart)),str(int(rfend)),str(int(rfend-rfstart))))
    newCam.setGenericFlag(hou.nodeFlag.DisplayComment,True)
    

if selectedCams:    
    chop.layoutChildren() 

hdr generator

import hou, pprint, glob, os, subprocess
node = hou.pwd()
def human_readable_size(size, decimal_places=2):
    for unit in ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']:
        if size < 1024.0 or unit == 'PiB':
            break
        size /= 1024.0
    return f"{size:.{decimal_places}f} {unit}"

def list_files(dir):
    return glob.glob(dir+'/**/*.exr',recursive=True) + glob.glob(dir+'/**/*.hdr',recursive=True)

def hoiio_stats(file):
    hoiio = hou.getenv('hfs')+'/bin/hoiiotool.exe'
    try:
        info = subprocess.check_output([hoiio, file, '--printstats'], shell=True)
        a = info.decode("utf-8")
        size = a.split(',')[0]
        max = a.split('\n')[2].split('Max: ')[1].split(' ')[:3]
        avg = a.split('\n')[3].split('Avg: ')[1].split(' ')[:3]
        dev = a.split('\n')[4].split('Dev: ')[1].split(' ')[:3]
        max = [ round(float(elem), 1) for elem in max ]
        avg = [ round(float(elem), 1) for elem in avg ]
        dev = [ round(float(elem), 1) for elem in dev ]
        output = [size,max,avg,dev]
        return output
    except subprocess.CalledProcessError:
        hdrlistrejected.append(str(i)+'|'+f+'| cant get EXR stats')
        return False

    
basedir = hou.parm('/obj/generateHDRI_list/dir').eval()
startat = hou.parm('/obj/generateHDRI_list/startat').eval()
hdrprelist = list_files(basedir)
hdrprelist = [ x for x in hdrprelist if "0_hdr_previews" not in x]
hdrprelist.sort()
hdrlist = []
hdrlistrejected = []

mins = hou.parmTuple('/obj/generateHDRI_list/minsize').eval()
maxs = hou.parmTuple('/obj/generateHDRI_list/maxsize').eval()
maxfs = hou.parm('/obj/generateHDRI_list/maxfilesize').eval()


if startat != 0:
    hdrlist = hou.parm('/obj/hdr_list/list').eval().split('\n')
    hdrlistrejected = hou.parm('/obj/hdr_list_rejected/list').eval().split('\n')

i = startat
with hou.InterruptableOperation("Fetching EXR size and infos", "Generator.hip", open_interrupt_dialog=True) as operation:
    for f in hdrprelist[startat:]:
        try:
            filesize = os.path.getsize(f)
            if filesize < maxfs*1024.0*1000:
                stats = hoiio_stats(f)
                if stats:
                    size = [int(x) for x in stats[0].split('x')]
                    if size[0] < mins[0] or size[1] < mins[1] or size[0] > maxs[0] or size[1] > maxs[1]:
                        hdrlistrejected.append(str(i)+'|'+f+'| size too small or big: ' + stats[0])
                    else:
                        output = stats[0] + '|' + ','.join(str(x) for x in stats[1]) + '|'+','.join(str(x) for x in stats[2]) + '|'+','.join(str(x) for x in stats[3])
                        hdrlist.append(str(i)+'|'+f+'|'+human_readable_size(filesize)+'|'+output)
            else:
                hdrlistrejected.append(str(i)+'|'+f+'| filesize too big ' + str(int(filesize/1024.0/1000.0)) + 'mb')
        except:
            hdrlistrejected.append(str(i)+'|'+f+'| getting file size problem. Network issue?')
        percent = (float(i) - startat) / float(len(hdrprelist)-startat)
        operation.updateProgress(percent)
        folder = os.path.normpath(f).split(os.path.normpath(basedir))[1][:10]+'…'
        operation.updateLongProgress(percent, str(i-startat+1)+'/'+str(len(hdrprelist)-startat)+' ['+str(len(hdrlist))+'|'+str(len(hdrlistrejected))+'] ' + folder)
        if i%20==0 : #refresh every 20 items
            hou.parm('/obj/hdr_list/list').set('\n'.join(hdrlist))
            hou.parm('/obj/hdr_list_rejected/list').set('\n'.join(hdrlistrejected))
        i += 1


hou.parm('/obj/hdr_list/list').set('\n'.join(hdrlist))
hou.parm('/obj/hdr_list_rejected/list').set('\n'.join(hdrlistrejected))

numItems = len(hdrlist)
hou.parm('/obj/hdr_list/maxitems').set(len(hdrlist))
hou.playbar.setFrameRange(1,numItems)

Replace Node With Another

Replace not X with Y

  • Keep Position and other settings
  • Keep Inputs
  • Transfer Values
#code from an asset need to change it
def swap(*kwargs):
    self = kwargs[0]['node']
    path = self.parm('file').evalAtFrame(-6666)
    #trick to find $F#
    pathsplit = path.split('-6666')
    n = len(path)-len(pathsplit[0])-len(pathsplit[1])
    path = pathsplit[0]+'$F'+str(n-1)+pathsplit[1]
    file = self.parent().createNode('file',node_name=self.name())
    file.parm('file').set(path)
    file.setPosition(self.position())
    file.setInput(0,self.inputs()[0])
    if self.outputConnections():
        for node in self.outputConnections():
            #print(node.outputNode())
            #if node.networkItemType() == 'networkItemType.NetworkDot':
            node.outputItem().setInput(0,file) 
    print(path)

After Effect Camera To Houdini (WIP)

(unfinished, will try to make it more generic AE -> H)

import hou, re

def clipboardToCamera():
    '''takes a clipboard containing AE keyframe data and creates and returns camera'''

    matchFps = False    # match found fps from comp
    matchRez = True     # match camera rez from comp
    
    AEclipboard = hou.ui.getTextFromClipboard()
    
    #check if we have AE data
    if 'Keyframe Data' not in AEclipboard:
        hou.ui.displayMessage('No keyframe data from AE found')
        return
    
    #match FPS
    if matchFps:
        try:
            AEfps = float(AEclipboard.split('Units Per Second')[1].splitlines()[0])
            hou.setFps(AEfps)
            hou.ui.displayMessage('Changing FPS to '+string(AEfps))
        except:
            print('Units Per Second not found in keyframe data')

    #check for transform keyword, if so, create camera and add keys
    if 'Transform' in AEclipboard:
        camera = hou.node('/obj').createNode('cam')
    
        #match Resolution
        if matchRez:
            try:
                w = float(AEclipboard.split('Source Width')[1].splitlines()[0])
                h = float(AEclipboard.split('Source Height')[1].splitlines()[0])
                camera.parm('resx').set(w)
                camera.parm('resy').set(h)
                
            except:
                print('Source Width and/or Source Height not found in keyframe data')            
        
        #aeNames = ['Camera Options Aperture','Transform Position','Transform Orientation']
        aeNames = ['Transform Position','Transform Orientation']
        houdiniParms = ['t','r']
        
        for index, item in enumerate( aeNames ):
            aeName = item.replace(' ', '\\t*\\s*')
            # print('split @ '+aeName)
            # nasty but should give us tuples [[frame#1,x,y,z][frame#2,x,y,z]]
            clipboardSplit = re.split(aeName, AEclipboard)
            clipboarSplitKeyframes = clipboardSplit[1].split('\n\n')[0].splitlines()
            kf = [x.split('\t')[1:-1] for x in clipboarSplitKeyframes[3:]]
            
            # make a keyframe for each line
            for line in kf:
                for index2, subparm in enumerate(['x','y','z']):
                    curParm = camera.path()+'/'+houdiniParms[index]+subparm
                    
                    if houdiniParms[index] == 't':
                        scale = -0.01
                    else:
                        scale = 1
                        
                    frameOffset = 0
                    #print(curParm+' '+str(int(line[0])+frameOffset)+' '+str(float(line[index2+1])*scale))
                    setKeyFrame(curParm,int(line[0])+frameOffset,float(line[index2+1])*scale)

def setKeyFrame(parm,time,value):
    hou_keyframe = hou.Keyframe()
    hou_keyframe.setFrame(time)
    hou_keyframe.setValue(value)
    hou_keyframe.setSlope(0)
    hou_keyframe.setInSlope(0)
    hou_keyframe.useSlope(False)
    hou_keyframe.setAccel(0)
    hou_keyframe.useAccel(False)
    hou_keyframe.interpretAccelAsRatio(False)
    hou_keyframe.setExpression("constant()", hou.exprLanguage.Hscript)
    hou.parm(parm).setKeyframe(hou_keyframe)
            
clipboardToCamera()

Reference Copy

import hou
fromNode = hou.node('/obj/geo2/box1')
toNode = hou.node('/obj/geo2/box4')
descriptions = [el.description() for el in fromNode.parmTuples()]
pt = fromNode.parmTuples()
#pt = [pt.name() for pt in a.parmTuples()]
for tuple in pt:
    #pt
    b.parmTuple(tuple.name()).set(tuple,language=None)
    
c = hou.ui.selectFromList(descriptions)
#print('ok')


#selectFromList(choices, default_choices=(), exclusive=False, message=None, title=None, column_header="Choices", num_visible_rows=10, clear_on_cancel=False, width=0, height=0) → tuple of int

Built maya scene with volume (py2)

import hou
import os 
import subprocess

volumecode = '''\
createNode transform -n "{0}Volume";
        //rename -uid "3D200489-4F9E-3F03-D09B-4FB5C1578C09";
createNode octaneVolume -n "{0}VolumeShape" -p "{0}Volume";
        //rename -uid "7AF43411-40AF-3AAE-8414-3DBE352D9B2A";
        setAttr -k off ".v";
        setAttr -l on ".f" -type "string" "{1}";
        setAttr ".ufe" yes;
        setAttr ".fe" 101;
createNode expression -n "{2}";
        //rename -uid "A7912C02-467B-AEBD-2FBB-92BD7C31F858";
        setAttr -k on ".nds";
        setAttr ".ixp" -type "string" ".O[0]=frame";
connectAttr "{2}.out[0]" "{0}VolumeShape.fe";
connectAttr ":time1.o" "{2}.tim";
'''

sel = hou.selectedNodes()

vdblist = []

for node in sel:
    for parm in node.parms():
        parmval = str(parm.eval())
        if parmval.find('.vdb') != -1:
            #print(parmval)
            vdblist.append([node.name(),parmval])

#for vdb in vdblist:
mayafile = hou.getenv("hip")+'/'+hou.getenv("hipname")+'.ma'

with open(mayafile, 'w') as file_handler:
    file_handler.write("//Maya ASCII 2018ff09 scene\n")
    count = 0
    for item in vdblist:
        count = count + 1
        mayaAscii = volumecode.format(item[0],item[1],'expression'+str(count))
        print count
        print mayaAscii
        file_handler.write(mayaAscii)
        #file_handler.write("{}\n".format(item))
    file_handler.write("// End of generate.ma\n")
    
        
subprocess.Popen(r'explorer /select,'+mayafile.replace('/','\\'))



Auto rig Alembic (.abc) with controls

import hou
abc = hou.node('/obj/crane_abc/crane_abc')
prims = abc.geometry().prims()
for prim in prims:
    tr = prim.fullTransform()
    path = prim.attributeValue('path')
    print(tr)
    print(path)
    #print(prim.inrinsicNames())
    #print(prim.intrinsicValue('packefulltransform'))    

Auto create nulls

import hou
for node in hou.selectedNodes():
    node.setSelected(0)
    null = node.parent().createNode("null", node.name()+"_null")
    null.setPosition(node.position())
    null.move(hou.Vector2(0, -1.5))
    null.setInput(0,node)
    null.setDisplayFlag(1)
    null.setSelected(1)

FaubourgFirm Montres

import hou
a = hou.node('/obj/montrerender/IN')
self = a.parent()
out = self.inputs()[0].node('OUT_output0')
test = 0
for p in out.geometry().prims():
    test = test + 1
    #if test == 5:
    #    break
    path = p.attribValue("path")
    mat = p.attribValue("shop_materialpath")
    geoname = path.rsplit('/',1)[-1]
    if not self.node(geoname):
        geo = self.createNode('geo',geoname)
        geo.moveToGoodPosition()
        merge = geo.createNode('object_merge')
        merge.parm('objpath1').set("hou.parent().parent().inputs()[0].path()+'/OUT_output0'")

        merge.parm('group1').set('@path='+path)
        merge.parm('xformtype').set(1)
    else:
        print(geoname+' exists already')

Set screenshot as network background (linux)

spPeavu.png

todo: set&use a global var to choose where to store the screenshots

import hou
import os
import subprocess

hipname = str(hou.getenv('HIPNAME'))
timestamp = subprocess.check_output('date +"%y%m%d_%H%M%S"',shell=True).rstrip()
path = '/harcoded/path/'+hipname+str(timestamp)+'.png'
#print path
os.system('import '+path)

editor = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor)
bounds = editor.visibleBounds()

node = editor.currentNode().parent()

'''
#TODO: ATTACH TO NODE/NETWORKVIEW
nb = editor.currentNode().parent().createNetworkBox()
nbbounds = bounds
nbbounds.setTo(bounds[0],bounds[1]+5,bounds[2],bounds[3]-5)
nb.setBounds(nbbounds)
nb.resize([0,.5])
nb.setMinimized(1)
nb.setComment('ctrl i to delete')
'''

image = hou.NetworkImage()
image.setPath(path)
image.setRect(bounds)
editor.setBackgroundImages([image])

#we need this otherwise the bg image doesn't get saved. dunno why
dic = '[{"path": "'+path+'", "rect": ['+str(bounds.min()[0])+','+str(bounds.min()[1])+','+str(bounds.max()[0])+','+str(bounds.max()[1])+']}]'
node.setUserData("backgroundimages", dic)

Create points from parsed text file

node = hou.pwd()
geo = node.geometry()
frame = geo.addAttrib(hou.attribType.Point, "frame", 0)
isNan = geo.addAttrib(hou.attribType.Point, "isnan", 0)

# Add code to modify contents of geo.
# Use drop down menu to select examples.


import re

fpath = '/prod/prod1/Projets/RESSOURCES/_graphistes/Bernie/joss/nuagepts.txt'
fpathvals = '/prod/prod1/Projets/RESSOURCES/_graphistes/Bernie/joss/nuagevals.txt'
pts = open(fpath)
ptsvals = open(fpathvals)

line = 'empty'

while line:
    line = pts.readline()
    lineb = ptsvals.readline()
    if len(line) > 8:
        curline = re.split(r'\t+', line.rstrip())
        for e in range(len(curline)):
            curline[e] = float(curline[e].replace(',','.'))
        pt = geo.createPoint()
        pt.setPosition(hou.Vector3(curline))
        floatFrame = lineb.rstrip()
        if floatFrame == 'NaN':
            floatFrame = 0
            pt.setAttribValue(isNan, 1)
        pt.setAttribValue(frame, int(floatFrame))

mikros

import hou
import os

def getKey(item):
    return item.position()[1]

def buildUiLine(mianFileNode,pTG,c):
    
    node = mianFileNode
    versionN = int(node.evalParm('cacheVersion'))
    checked = False if node.isBypassed() else True
    sf = int(node.evalParm('fx'))
    ef = int(node.evalParm('fy'))

    name = mianFileNode.name()
    n = str(c)

    t = hou.FolderParmTemplate("folder"+n, name, folder_type=hou.folderType.Simple, default_value=0, ends_tab_group=False)
    t.setTags({"group_type": "simple"})
    
    t2 = hou.ToggleParmTemplate("checkbx_"+n, " ", default_value=checked)
    t2.setJoinWithNext(True)
    t.addParmTemplate(t2)
    
    t2 = hou.IntParmTemplate("versBox_"+n, "v#", 1, default_value=([versionN]), min=0, max=10, min_is_strict=False, max_is_strict=False, naming_scheme=hou.parmNamingScheme.Base1, menu_items=([]), menu_labels=([]), icon_names=([]), item_generator_script="", item_generator_script_language=hou.scriptLanguage.Python, menu_type=hou.menuType.Normal)
    t2.setJoinWithNext(True)
    t.addParmTemplate(t2)
    
    t2 = hou.IntParmTemplate("startEnd_"+n, "start/end", 2, default_value=([sf,ef]), min=-1, max=1, min_is_strict=False, max_is_strict=False, naming_scheme=hou.parmNamingScheme.XYZW, menu_items=([]), menu_labels=([]), icon_names=([]), item_generator_script="", item_generator_script_language=hou.scriptLanguage.Python, menu_type=hou.menuType.Normal)
    t2.setJoinWithNext(True)
    t2.setTags({"units": ""})
    t.addParmTemplate(t2)
    
    t2 = hou.ButtonParmTemplate("gotoBut_"+n, "goto")
    t2.setScriptCallback("hou.clearAllSelected();hou.node('"+node.path()+"').setSelected(1)")
    t2.setScriptCallbackLanguage(hou.scriptLanguage.Python)
    t2.setJoinWithNext(True)
    t.addParmTemplate(t2)
    
    t2 = hou.ButtonParmTemplate("exploreBut_"+n, "explore")
    path = os.path.dirname(os.path.dirname(node.evalParm('outputPath')))
    expression = "import os.path;os.system('xdg-open \"%s\"' % '"+path+"')"
    t2.setScriptCallback(expression)
    t2.setScriptCallbackLanguage(hou.scriptLanguage.Python)
    t2.setJoinWithNext(True)
    t.addParmTemplate(t2)
    
    t2 = hou.ButtonParmTemplate("renderBut_"+n, "render")
    t2.setScriptCallback("hou.node('"+node.path()+"').parm('render').pressButton()")
    t2.setScriptCallbackLanguage(hou.scriptLanguage.Python)
    t2.setJoinWithNext(True)
    t.addParmTemplate(t2)
    
    t2 = hou.ButtonParmTemplate("farmBut_"+n, "farm")
    
    t2.setScriptCallback("hou.node('"+node.path()+"').parm('sendToFarm').pressButton()")
    t2.setScriptCallbackLanguage(hou.scriptLanguage.Python)
    
    
    t.addParmTemplate(t2)
    pTG.append(t)
    return n

#variables and shit
sel = sorted(hou.selectedNodes(), key=getKey,reverse=True)

mianfiles = []
counter = -1

chkexpression = ''
unchkexpression = ''
renderselected = ''
farmselected = ''
setversion = ''

#build ctrl node
ctrl = sel[0].parent().createNode('null','mianRenderCtrl')
ctrl.setUserData('nodeshape', 'trapezoid_down')
ctrl.setColor(hou.Color((1,1,.1)))
ctrl.moveToGoodPosition(False)
ctrl.setSelected(True,True)

#spaghetti code 1
for node in sel:
    if node.parent().path() != '/obj':
        if node.type().name() == 'mianFile':
            counter += 1
            mianfiles.append([counter,node])
            
            c = str(counter)
            renderselected += "if hou.parm('checkbx_"+c+"').eval() == 1: hou.parm('renderBut_"+c+"').pressButton()\n"
            farmselected += "if hou.parm('checkbx_"+c+"').eval() == 1: hou.parm('farmBut_"+c+"').pressButton()\n"
            setversion += "if hou.parm('checkbx_"+c+"').eval() == 1: hou.parm('versBox_"+c+"').set(hou.parm('globversion').eval())\n"
            chkexpression += "hou.parm('checkbx_"+c+"').set(1);"
            unchkexpression += "hou.parm('checkbx_"+c+"').set(0);"
    
    else:
        for subnode in node.children():
            if subnode.type().name() == 'mianFile':
                counter += 1
                mianfiles.append([counter,subnode])
                
                c = str(counter)
                renderselected += "if hou.parm('checkbx_"+c+"').eval() == 1: hou.parm('renderBut_"+c+"').pressButton()\n"
                farmselected += "if hou.parm('checkbx_"+c+"').eval() == 1: hou.parm('farmBut_"+c+"').pressButton()\n"
                setversion += "if hou.parm('checkbx_"+c+"').eval() == 1: hou.parm('versBox_"+c+"').set(hou.parm('globversion').eval())\n"
                chkexpression += "hou.parm('checkbx_"+c+"').set(1);"
                unchkexpression += "hou.parm('checkbx_"+c+"').set(0);"
                

#spaghetti code 2 UI
hou_parm_template_group = hou.ParmTemplateGroup()

t = hou.FolderParmTemplate("standardfolder_1", "Mianfiles Render Tool", folder_type=hou.folderType.Simple, default_value=0, ends_tab_group=False)


t2 = hou.ButtonParmTemplate("chkAll", "Check All")
t2.setScriptCallback(chkexpression)
t2.setScriptCallbackLanguage(hou.scriptLanguage.Python)
t2.setJoinWithNext(True)
t.addParmTemplate(t2)

t2 = hou.ButtonParmTemplate("unchk", "Uncheck All")
t2.setScriptCallback(unchkexpression)
t2.setScriptCallbackLanguage(hou.scriptLanguage.Python)
t2.setJoinWithNext(True)
t.addParmTemplate(t2)

t2 = hou.ButtonParmTemplate("render", "Render Selected")
t2.setScriptCallback(renderselected)
t2.setScriptCallbackLanguage(hou.scriptLanguage.Python)
t2.setJoinWithNext(True)
t.addParmTemplate(t2)

t2 = hou.ButtonParmTemplate("farm", "Farm Selected")
t2.setScriptCallback(farmselected)
t2.setScriptCallbackLanguage(hou.scriptLanguage.Python)
t.addParmTemplate(t2)

t2 = hou.ButtonParmTemplate("setver", "Set version for checked:")
t2.setScriptCallback(setversion)
t2.setScriptCallbackLanguage(hou.scriptLanguage.Python)
t2.setJoinWithNext(True)
t.addParmTemplate(t2)

t2 = hou.IntParmTemplate("globversion", "Label", 1, default_value=([1]), min=0, max=10, min_is_strict=False, max_is_strict=False, naming_scheme=hou.parmNamingScheme.Base1, menu_items=([]), menu_labels=([]), icon_names=([]), item_generator_script="", item_generator_script_language=hou.scriptLanguage.Python, menu_type=hou.menuType.Normal)
t2.hideLabel(True)
t.addParmTemplate(t2)

hou_parm_template_group.append(t)

for subnodetuple in mianfiles:
    buildUiLine(subnodetuple[1],hou_parm_template_group,subnodetuple[0])
    
#build ui
deleteexpression = ''
if counter > -1:
    ctrl.setParmTemplateGroup(hou_parm_template_group)


    #lock stuff, setup connections
    for uiN in mianfiles:
        hou_parm_tuple = ctrl.parmTuple("startEnd_"+str(uiN[0]))
        hou_parm_tuple.lock((True, True))
        expression = "ch('"+ctrl.path()+"/versBox_"+str(uiN[0])+"')"
        uiN[1].parm('cacheVersion').setExpression(expression)
        #make sure to delete expressions when node is deleted
        deleteexpression += 'python -c \'hou.node("'+uiN[1].path()+'").parm("cacheVersion").deleteAllKeyframes()\'\n'
        
        
    ctrl.setDeleteScript(deleteexpression, hou.scriptLanguage.Hscript)
    
    group = ctrl.parmTemplateGroup()
    group.hideFolder('Standard', True)
    ctrl.setParmTemplateGroup(group)