Ejemplo n.º 1
0
def parm_create(node, type, name, label):

    if type == "integer":
        new_template = hou.IntParmTemplate(name, name, 1)

    if type == "toggle":
        new_template = hou.ToggleParmTemplate(name, name)

    if type == "float":
        new_template = hou.FloatParmTemplate(name, name, 1)

    if type == "vector":
        new_template = hou.FloatParmTemplate(name, name, 3)
        new_template.setLook(hou.parmLook.Regular)

    if type == "color":
        new_template = hou.FloatParmTemplate(name, name, 3)
        new_template.setNamingScheme(hou.parmNamingScheme.RGBA)
        new_template.setLook(hou.parmLook.ColorSquare)

    if type == "string":
        new_template = hou.StringParmTemplate(name, label, 1)
        new_template.setStringType(hou.stringParmType.Regular)

    if type == "file":
        new_template = hou.StringParmTemplate(name, name, 1)
        new_template.setStringType(hou.stringParmType.FileReference)

    if type == "node":
        new_template = hou.StringParmTemplate(name, name, 1)
        new_template.setStringType(hou.stringParmType.NodeReference)

    if type == "separator":
        new_template = hou.SeparatorParmTemplate(name)

    if type == "label":
        new_template = hou.LabelParmTemplate(name, label, [label], False, True)

    if type == "rampfloat":
        new_template = hou.RampParmTemplate(name, name, hou.rampParmType.Float)
        new_template.setShowsControls(False)

    if type == "rampcolor":
        new_template = hou.RampParmTemplate(name, name, hou.rampParmType.Color)
        new_template.setShowsControls(False)

    try:
        ptg = node.parmTemplateGroup()
        ptg.addParmTemplate(new_template)
        node.setParmTemplateGroup(ptg)
        existed = 0

    except:
        existed = 1
Ejemplo n.º 2
0
def PopulateFromXML(kwargs, folder, filename):
    '''
        Fill folder with labels that will get its data from XML file.
    '''
    data = ReadXMLData(kwargs, 'author.xml')

    for d in data:
        partial = '' if d.tag.lower() == 'separator' else '{0}:'.format(d.tag)
        formatted = '{0} {1}'.format(partial, d.text)

        label = hou.LabelParmTemplate(d.tag.lower(), '', (formatted, ))
        label.hideLabel(1)
        folder.addParmTemplate(label)
Ejemplo n.º 3
0
def PopulateFromJSON(kwargs, folder, filename):
    '''
        Fill folder with labels that will get its data from JSON file.    
    '''
    data = ReadJSONData(kwargs, 'author.json')

    for d in data:
        partial = '' if d.lower() == 'separator' else '{0}:'.format(d)
        formatted = '{0} {1}'.format(partial, data[d])

        label = hou.LabelParmTemplate(d.lower(), '', (formatted, ))
        label.hideLabel(1)
        folder.addParmTemplate(label)
Ejemplo n.º 4
0
def addOwner():
	import hou
	import datetime

	nodes +=hou.node('/obj/').recursiveGlob("*")
	nodes +=hou.node('/mat/').recursiveGlob("*")
	nodes +=hou.node('/out/').recursiveGlob("*")
	nodes +=hou.node('/shop/').recursiveGlob("*")

	for n in nodes:


		label = "created_igor_si"+datetime.datetime.now().strftime("%Y%m%d")
		template = hou.LabelParmTemplate('name',label,is_hidden=True)
		group = n.parmTemplateGroup()
		group.addParmTemplate(template)

		try:
			n.setParmTemplateGroup(group)
			print "adding owner to %s" % n
		except: print "cannot add owner to %s" %n		
Ejemplo n.º 5
0
def resizeFluidSops(kwargs):
    """ Select fluid and set it up to be resizeable.
    """
    sceneviewer = toolutils.activePane(kwargs)
    if not isinstance(sceneviewer, hou.SceneViewer):
        raise hou.Error("Invalid pane type for this operation.")

    # Select the target fluid box.
    fluidobjects = sceneviewer.selectDynamics(
        prompt="Select fluid box to resize.  Press Enter to complete.",
        allow_multisel=False)
    if len(fluidobjects) < 1:
        raise hou.Error(
            "No fluid container selected to set initial conditions.")
    fluidobject = fluidobjects[0]

    fluidnode = doptoolutils.getDopObjectCreator(fluidobject)
    if fluidnode is None:
        raise hou.Error("No fluid object node found.")
    """ Create and configure the reference container for resizing.
    """

    dopnet = doptoolutils.getCurrentDopNetwork()
    refobject = fluidnode.parent().parent().createNode(
        "geo", "fluid_resize_container", run_init_scripts=False)
    fluidfields = refobject.createNode("dopio", "fluidfields")
    fluidfields.parm("doppath").set(dopnet.path())
    fluidfields.setParmExpressions(
        {"defobj": "chs(\"" + fluidnode.path() + "/object_name\")"})
    fluidfields.parm("fields").set(2)
    fluidfields.parm("fieldname1").set("density")
    fluidfields.parm("fieldname2").set("vel")
    parms = refobject.parmTemplateGroup()
    parms.hideFolder("Transform", True)
    parms.hideFolder("Material", True)
    parms.hideFolder("Render", True)
    parms.hideFolder("Misc", True)
    ref_folder = hou.FolderParmTemplate("ref_folder", "Resize Container")
    ref_folder.addParmTemplate(
        hou.IntParmTemplate(
            "nptsperarea",
            "Scatter per Area",
            1,
            default_value=([5000]),
            min=1000,
            max=20000,
            help="Scatter points on simulated density to calculate bounds"))
    ref_folder.addParmTemplate(
        hou.FloatParmTemplate(
            "treshold",
            "Density Treshold",
            1,
            default_value=([0]),
            min=0,
            max=1,
            help="Delete density below this value prior to scattering points"))
    ref_folder.addParmTemplate(hou.SeparatorParmTemplate("sep1"))
    ref_folder.addParmTemplate(
        hou.LabelParmTemplate("merge_source", "Merge Sources"))
    ref_folder.addParmTemplate(
        hou.ButtonParmTemplate(
            "update",
            "Update sources",
            help="Push this to update ObjectMerge node inside",
            tags={
                "script_callback":
                "import adddoputils; adddoputils.updateSourcesButton()",
                "script_callback_language": "python"
            }))
    ref_folder.addParmTemplate(
        hou.IntParmTemplate(
            "source_activation",
            "All Sources Activation",
            1,
            default_value=([1]),
            min=0,
            max=1,
            min_is_strict=True,
            max_is_strict=True,
            help=
            "Activation of merging all of the listed sources and additional objects"
        ))
    ref_folder.addParmTemplate(
        hou.MenuParmTemplate(
            "xformtype", "Transform", "012",
            ("None", "Into This Object", "Into Specified Object"), 1))
    ref_folder.addParmTemplate(
        hou.StringParmTemplate("xformpath",
                               "Transform object",
                               1,
                               "",
                               hou.parmNamingScheme.Base1,
                               hou.stringParmType.NodeReference,
                               disable_when=("{ xformtype != 2 }")))

    sources_folder = hou.FolderParmTemplate(
        "source_folder",
        "Sources to Merge",
        folder_type=hou.folderType.MultiparmBlock)
    sources_folder.addParmTemplate(
        hou.ToggleParmTemplate("source_activation#",
                               "Source # Activation",
                               default_value=True))
    sources_folder.addParmTemplate(
        hou.StringParmTemplate("objpath#", "Object #", 1, "",
                               hou.parmNamingScheme.Base1,
                               hou.stringParmType.NodeReference))
    sources_folder.addParmTemplate(
        hou.StringParmTemplate("group#", "Group #", 1, "",
                               hou.parmNamingScheme.Base1,
                               hou.stringParmType.Regular))

    ref_folder.addParmTemplate(sources_folder)
    parms.append(ref_folder)
    refobject.setParmTemplateGroup(parms)

    keep_density = refobject.createNode("blast", "keep_density")
    keep_density.setFirstInput(fluidfields)
    keep_density.parm("group").set("@name==vel*")

    keep_vel = refobject.createNode("blast", "keep_vel")
    keep_vel.setFirstInput(fluidfields)
    keep_vel.parm("group").set("@name==density")

    # VOLUME VOP clamping density field below given treshold
    density_treshold = keep_density.createOutputNode("volumevop",
                                                     "density_treshold")

    vopglobals = density_treshold.node("volumevopglobal1")

    treshold = density_treshold.createNode("parameter", "treshold")
    treshold.parm("parmname").set("treshold")
    treshold.parm("parmlabel").set("Treshold")

    compare_density = density_treshold.createNode("compare", "compare_density")
    compare_density.parm("cmp").set("gte")
    compare_density.setInput(0, vopglobals, 1)
    compare_density.setInput(1, treshold, 0)

    twoway = compare_density.createOutputNode("twoway", "switch_density")
    twoway.setInput(1, vopglobals, 1)

    vop_output = density_treshold.node("volumevopoutput1")
    vop_output.setFirstInput(twoway, 0)
    density_treshold.setParmExpressions({"treshold": "ch(\"../treshold\")"})
    # End of VOLUME VOP

    scatter = refobject.createNode("scatter", "scatter")
    scatter.setFirstInput(density_treshold)
    scatter.parm("ptsperarea").set(1)
    scatter.setParmExpressions({"nptsperarea": "ch(\"../nptsperarea\")"})

    add_particles = scatter.createOutputNode("add", "add_particles")
    add_particles.parm("addparticlesystem").set(1)

    # VOP SOP adding velocity field to density-based pointcloud
    add_vel = refobject.createNode("vopsop", "add_vel")
    add_vel.parm("vex_numthreads").set(1)
    add_vel.setFirstInput(add_particles)
    add_vel.setInput(1, keep_vel, 0)

    globals = add_vel.node("global1")
    volumesamplex = add_vel.createNode("volumesample", "volumesample_x")
    volumesamplex.setInput(2, globals, 0)
    volumesamplex.parm("input_index").set(1)
    volumesamplex.parm("primnum").set(0)

    volumesampley = add_vel.createNode("volumesample", "volumesample_y")
    volumesampley.setInput(2, globals, 0)
    volumesampley.parm("input_index").set(1)
    volumesampley.parm("primnum").set(1)

    volumesamplez = add_vel.createNode("volumesample", "volumesample_z")
    volumesamplez.setInput(2, globals, 0)
    volumesamplez.parm("input_index").set(1)
    volumesamplez.parm("primnum").set(2)

    vel = volumesamplex.createOutputNode("floattovec", "vel")
    vel.setInput(1, volumesampley, 0)
    vel.setInput(2, volumesamplez, 0)

    vel_by_fps = vel.createOutputNode("divconst", "vel_by_fps")
    vel_by_fps.setParmExpressions({"divconst": "$FPS"})

    add_vector = globals.createOutputNode("add", "add_vector")
    add_vector.setNextInput(vel_by_fps, 0)

    vex_output = add_vel.node("output1")
    vex_output.setFirstInput(add_vector, 0)
    # End of VOP SOP

    merge1 = refobject.createNode("merge", "merge1")
    merge1.setFirstInput(add_particles)
    merge1.setInput(1, add_vel, 0)

    bound = merge1.createOutputNode("bound", "bound")

    # Box to switch from after first simulation frame
    initial_box = refobject.createNode("box", "initial_box")
    initial_box.setParmExpressions({
        "sizex":
        "ch(\"" + initial_box.relativePathTo(fluidnode) + "/sizex\")",
        "sizey":
        "ch(\"" + initial_box.relativePathTo(fluidnode) + "/sizey\")",
        "sizez":
        "ch(\"" + initial_box.relativePathTo(fluidnode) + "/sizez\")"
    })
    initial_box.setParmExpressions({
        "tx":
        "ch(\"" + initial_box.relativePathTo(fluidnode) + "/tx\")",
        "ty":
        "ch(\"" + initial_box.relativePathTo(fluidnode) + "/ty\")",
        "tz":
        "ch(\"" + initial_box.relativePathTo(fluidnode) + "/tz\")"
    })

    initial_switch = initial_box.createOutputNode("switch", "initial_switch")
    initial_switch.setParmExpressions({
        "input":
        "$F>ch(\"" + initial_switch.relativePathTo(fluidnode) +
        "/createframe\")",
    })
    initial_switch.setInput(1, bound, 0)

    # Null to switch to if merging of simulation sources is disabled
    no_active_source = refobject.createNode("null", "no_active_source")

    merge_source = refobject.createNode("object_merge", "merge_source")
    merge_source.setParmExpressions({
        "numobj": "ch(\"../source_folder\")",
        "xformtype": "ch(\"../xformtype\")"
    })
    merge_source.parm("xformpath").set("`chsop(\"../xformpath\")`")
    numobj = merge_source.parm("numobj").eval()

    source_switch = no_active_source.createOutputNode("switch",
                                                      "source_switch")
    source_switch.setParmExpressions({"input": "ch(\"../source_activation\")"})
    source_switch.setInput(1, merge_source, 0)

    merge2 = initial_switch.createOutputNode("merge", "merge2")
    merge2.setInput(1, source_switch, 0)

    bound = merge2.createOutputNode("bound", "bound")

    unroll_edges = bound.createOutputNode("ends", "unroll_edges")
    unroll_edges.parm("closeu").set(4)

    out = unroll_edges.createOutputNode("null", "OUT")

    density_treshold.layoutChildren()
    add_vel.layoutChildren()
    refobject.layoutChildren()

    out.setDisplayFlag(True)
    out.setRenderFlag(True)

    resize = resizeFluidToMatchSops(fluidnode, refobject)
    resize.setCurrent(True, True)
    sceneviewer.enterCurrentNodeState()
def assemble_set(project, environment, assembly, asset, checkout_file):
    set_hda = create_hda(asset, assembly, project, environment, checkout_file)

    print 'This is a set'
    print('----------')
    model = asset.get_element(Department.MODEL)

    # Get all of the static geo
    model_cache = model.get_cache_dir()
    model_cache = model_cache.replace(project.get_project_dir(), '$JOB')
    geo_files = [x for x in os.listdir(model.get_cache_dir()) if not os.path.isdir(x)]

    geo_files = clean_file_list(geo_files, '.abc')

    # Set up the set parameters
    # Create a folder for the set parameters
    set_folder = hou.FolderParmTemplate('set_options', 'Set Options', folder_type=hou.folderType.Tabs, default_value=0, ends_tab_group=False)
    auto_archive = hou.properties.parmTemplate(get_latest_prman(),"ri_auto_archive")
    auto_archive.setDefaultValue(("exist",))
    set_folder.addParmTemplate(auto_archive)
    set_folder.addParmTemplate(create_set_menu(hidden=True, value=asset.get_name()))
    set_folder.addParmTemplate(create_shot_menu())

    used_hdas = set()
    for geo_file in geo_files:
        geo_file_path = os.path.join(model_cache, geo_file)
        name = ''.join(geo_file.split('.')[:-1])
        #print 'The name of the alembic file is ', name
        # find the alembic version
        elementName = '_main'
        index = name.find(elementName)
        versionNum = name[index + len(elementName):]
        #print 'This is the versionNum ', versionNum
        # TODO : what if it is a rig? I am begninng to wonder if maybe it will always be the model becuase in the rig file it is referencing the model.
        index = name.find('_model')
        if(index < 0):
            index = name.find('_rig')
        if(index < 0):
            print 'We couldn\'t find either a rig or a model for this asset. That means something went wrong or I need to rethink this tool.'
        asset_name = name[:index]

        #check if HDA is set to prevent nested set HDAS
        project=Project()
        body = project.get_body(asset_name)
        print asset_name
        if body is not None:
            if body.get_type() == AssetType.SET:
                continue

        else:
            print ('No body exists for: ' + asset_name)
            continue

        #print asset_name
        asset_version = str(asset_name) + str(versionNum)
        if(asset_version in used_hdas):
            print used_hdas
            print 'But I think is okay if it is in used_hdas because we have decided that it\'s cool to have multibples'
            #TODO get rid of used_hdas if we don't need it anymore now that we are allowing duplication of assets
            continue
        try:
            hda = set_hda.createNode(asset_name + '_main')
        except:
            message_gui.error('There is no asset named ' + str(asset_name) + '. You may need to assemble it first.')
            hda.destroy()
            return
        used_hdas.add(asset_version)

        # set the alembic version number
        if versionNum != '':
            try:
                #print 'This is versionNum before the change ', versionNum
                versionNum = int(versionNum)
                #print 'This is versionNum after the change ', versionNum
                hda.parm('abcversion').set(int(versionNum))
            except Exception as err:
                errorMessage = 'There was an error assigning the version number. It may be because the asset needs to be reassembled. Check that the ' + str(asset_name) + ' node has the version slider. If not reassemble it and try again.\n'
                message_gui.error(errorMessage, details=str(err))

        #finish the rest of the setup
        label_text = asset_version.replace('_', ' ').title()
        # Using the column label instead of the regular label lets us put longer names without them getting truncated. The problem is that its not left justified like I would want but its going to have to do for now. It is really quite a bit less than ideal but it will still comunicate the needed info so here we go.
        columnLabel = (label_text,)
        #print columnLabel
        geo_label = hou.LabelParmTemplate(asset_version, '', column_labels=columnLabel)
        hide_toggle_name = 'hide_' + asset_version
        hide_toggle = hou.ToggleParmTemplate(hide_toggle_name, 'Hide')
        animate_toggle_name = 'animate_' + asset_version
        animate_toggle = hou.ToggleParmTemplate(animate_toggle_name, 'Animate')
        animate_toggle_to_int_name = 'animate_toggle_to_int_' + asset_version
        animate_toggle_to_int = hou.IntParmTemplate(animate_toggle_to_int_name, 'Toggle To Int', 1, is_hidden=True, default_expression=('ch("' + animate_toggle_name + '")',))
        set_folder.addParmTemplate(geo_label)
        set_folder.addParmTemplate(hide_toggle)
        set_folder.addParmTemplate(animate_toggle)
        set_folder.addParmTemplate(animate_toggle_to_int)
        try:
            hda.parm('hide').setExpression('ch("../' + hide_toggle_name + '")')
            hda.parm('shot').setExpression('chs("../shot")')
            hda.parm('set').setExpression('chs("../set")')
            hda.parm('source').setExpression('chs("../' + animate_toggle_to_int_name + '")')
        except AttributeError, e:
            message_gui.error("There was an error adding " + str(asset_name) + " to the set. Please make sure that the node exists and has all of the necessary parameters (hide, shot, set, source) and try again. Contact the pipeline team if you need help. We will continue assembling so you can see the output, but you will need to assemble this set again.", details=str(e))
        except Exception, e:
            message_gui.error('There was a problem with this node: ' + str(asset_name), details=str(e))
Ejemplo n.º 7
0
        item_generator_script_language=hou.scriptLanguage.Hscript,
        menu_type=hou.menuType.Normal)
    selNode.addSpareParmTuple(hou_parm_template,
                              in_folder=(['Character']),
                              create_missing_folders=True)

    hou_parm_template = hou.ToggleParmTemplate("mocapswitch",
                                               "Use Mocap?",
                                               default_value=False)
    selNode.addSpareParmTuple(hou_parm_template,
                              in_folder=(['Character']),
                              create_missing_folders=True)

    # Alembic params
    hou_parm_template = hou.LabelParmTemplate("labelparm",
                                              "Alembic",
                                              column_labels=([""]))
    selNode.addSpareParmTuple(hou_parm_template,
                              in_folder=(['Cache']),
                              create_missing_folders=True)

    hou_parm_template = hou.ToggleParmTemplate("use_cache",
                                               "Use Cache",
                                               default_value=False)
    selNode.addSpareParmTuple(hou_parm_template,
                              in_folder=(['Cache']),
                              create_missing_folders=True)

    hou_parm_template = hou.FloatParmTemplate(
        "cache_scale",
        "Cache Scale",
def charAssetsToHDA():
    this = hou.node('.')
    importNode = hou.hipFile.importFBX(this.parm('char_fbx_file').eval(), suppress_save_prompt=True, merge_into_scene=True, import_cameras=False, import_joints_and_skin=True, import_geometry=True, import_lights=False, import_animation=False, import_materials=False, resample_animation=False, resample_interval=1.0, override_framerate=False,framerate=-1, hide_joints_attached_to_skin=True, convert_joints_to_zyx_rotation_order=False, material_mode=hou.fbxMaterialMode.FBXShaderNodes, compatibility_mode=hou.fbxCompatibilityMode.Maya, single_precision_vertex_caches=False, triangulate_nurbs=False, triangulate_patches=False, import_global_ambient_light=False, import_blend_deformers_as_blend_sops=False, segment_scale_already_baked_in=True, convert_file_paths_to_relative=False, unlock_geometry=True, unlock_deformations=True, import_nulls_as_subnets=False, import_into_object_subnet=True, convert_into_y_up_coordinate_system=False)
    fbxNode = importNode[0]   
    
    if fbxNode:
        # set up the parameters
        
        # CHOP mocap params
        hou_parm_template = hou.StringParmTemplate("fbxfile", "FBX File", 1, default_value=([""]), naming_scheme=hou.parmNamingScheme.Base1, string_type=hou.stringParmType.FileReference, menu_items=([]), menu_labels=([]), icon_names=([]), item_generator_script="", item_generator_script_language=hou.scriptLanguage.Python, menu_type=hou.menuType.StringReplace)
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Character']), create_missing_folders=True)
        
        hou_parm_template = hou.StringParmTemplate("fbxclip", "Clip", 1, default_value=([""]), naming_scheme=hou.parmNamingScheme.Base1, string_type=hou.stringParmType.Regular, menu_items=([]), menu_labels=([]), icon_names=([]), item_generator_script="opmenu -l CHOP/fbxagent/fbximport currentclip", item_generator_script_language=hou.scriptLanguage.Hscript, menu_type=hou.menuType.Normal)
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Character']), create_missing_folders=True)
        
        hou_parm_template = hou.ToggleParmTemplate("mocapswitch", "Use Mocap?", default_value=False)
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Character']), create_missing_folders=True)
        
        # Alembic params
        hou_parm_template = hou.LabelParmTemplate("labelparm", "Alembic", column_labels=([""]))
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.ToggleParmTemplate("use_cache", "Use Cache", default_value=False)
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.FloatParmTemplate("cache_scale", "Cache Scale", 1, default_value=([1]), min=0, max=10, min_is_strict=False, max_is_strict=False, look=hou.parmLook.Regular, naming_scheme=hou.parmNamingScheme.Base1)
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.MenuParmTemplate("trange", "Valid Frame Range", menu_items=(["off","normal","on"]), menu_labels=(["Render Current Frame","Render Frame Range","Render Frame Range Only (Strict)"]), default_value=0, icon_names=([]), item_generator_script="", item_generator_script_language=hou.scriptLanguage.Python, menu_type=hou.menuType.Normal)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.FloatParmTemplate("f", "Start/End/Inc", 3, default_value=([0, 0, 1]), default_expression=(["$FSTART","$FEND",""]), default_expression_language=([hou.scriptLanguage.Hscript,hou.scriptLanguage.Hscript,hou.scriptLanguage.Hscript]), min=0, max=10, min_is_strict=False, max_is_strict=False, look=hou.parmLook.Regular, naming_scheme=hou.parmNamingScheme.Base1)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.StringParmTemplate("cachefile", "Cache File", 1, default_value=(["$HIP/output.abc"]), naming_scheme=hou.parmNamingScheme.Base1, string_type=hou.stringParmType.FileReference, menu_items=([]), menu_labels=([]), icon_names=([]), item_generator_script="opmenu -l exportnet/alembic filename", item_generator_script_language=hou.scriptLanguage.Hscript, menu_type=hou.menuType.StringReplace)
        hou_parm_template.setTags({"autoscope": "0000000000000000", "filechooser_pattern": "*.abc"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.ButtonParmTemplate("cache_btn", "Cache to Disk")
        hou_parm_template.setTags({"autoscope": "0000000000000000", "takecontrol": "always"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        #FBX params
        hou_parm_template = hou.SeparatorParmTemplate("sepparm")
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.LabelParmTemplate("labelparm2", "FBX", column_labels=([""]))
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.MenuParmTemplate("trange2", "Valid Frame Range", menu_items=(["off","normal","on"]), menu_labels=(["Render Current Frame","Render Frame Range","Render Frame Range Only (Strict)"]), default_value=0, icon_names=([]), item_generator_script="", item_generator_script_language=hou.scriptLanguage.Python, menu_type=hou.menuType.Normal)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.FloatParmTemplate("f4", "Start/End/Inc", 3, default_value=([0, 0, 1]), default_expression=(["$FSTART","$FEND",""]), default_expression_language=([hou.scriptLanguage.Hscript,hou.scriptLanguage.Hscript,hou.scriptLanguage.Hscript]), min=0, max=10, min_is_strict=False, max_is_strict=False, look=hou.parmLook.Regular, naming_scheme=hou.parmNamingScheme.Base1)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.StringParmTemplate("take", "Render With Take", 1, default_value=(["_current_"]), naming_scheme=hou.parmNamingScheme.Base1, string_type=hou.stringParmType.Regular, menu_items=([]), menu_labels=([]), icon_names=([]), item_generator_script="opmenu -l exportnet/filmboxfbx1 take", item_generator_script_language=hou.scriptLanguage.Hscript, menu_type=hou.menuType.Normal)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.StringParmTemplate("sopoutput", "Output File", 1, default_value=(["$HIP/out.fbx"]), naming_scheme=hou.parmNamingScheme.Base1, string_type=hou.stringParmType.FileReference, menu_items=([]), menu_labels=([]), icon_names=([]), item_generator_script="opmenu -l exportnet/filmboxfbx1 sopoutput", item_generator_script_language=hou.scriptLanguage.Hscript, menu_type=hou.menuType.StringReplace)
        hou_parm_template.setTags({"autoscope": "0000000000000000", "filechooser_mode": "write"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.ToggleParmTemplate("mkpath", "Create Intermediate Directories", default_value=True, default_expression='on', default_expression_language=hou.scriptLanguage.Hscript)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.ToggleParmTemplate("exportkind", "Export in ASCII Format", default_value=True, default_expression='on', default_expression_language=hou.scriptLanguage.Hscript)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.StringParmTemplate("sdkversion", "FBX SDK Version", 1, default_value=([""]), naming_scheme=hou.parmNamingScheme.Base1, string_type=hou.stringParmType.Regular, menu_items=([]), menu_labels=([]), icon_names=([]), item_generator_script="opmenu -l exportnet/filmboxfbx1 sdkversion", item_generator_script_language=hou.scriptLanguage.Hscript, menu_type=hou.menuType.Normal)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.MenuParmTemplate("vcformat", "Vertex Cache Format", menu_items=(["mayaformat","maxformat"]), menu_labels=(["Maya Compatible (MC)","3DS MAX Compatible (PC2)"]), default_value=0, icon_names=([]), item_generator_script="", item_generator_script_language=hou.scriptLanguage.Python, menu_type=hou.menuType.Normal)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.MenuParmTemplate("invisobj", "Export Invisible Objects", menu_items=(["nullnodes","fullnodes"]), menu_labels=(["As Hidden Null Nodes","As Hidden Full Nodes"]), default_value=0, icon_names=([]), item_generator_script="", item_generator_script_language=hou.scriptLanguage.Python, menu_type=hou.menuType.Normal)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.FloatParmTemplate("polylod", "Conversion Level of Detail", 1, default_value=([1]), min=0, max=5, min_is_strict=True, max_is_strict=False, look=hou.parmLook.Regular, naming_scheme=hou.parmNamingScheme.Base1)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.ToggleParmTemplate("detectconstpointobjs", "Detect Constant Point Count Dynamic Objects", default_value=True, default_expression='on', default_expression_language=hou.scriptLanguage.Hscript)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.ToggleParmTemplate("convertsurfaces", "Convert NURBS and Bezier Surfaces to Polygons", default_value=False, default_expression='off', default_expression_language=hou.scriptLanguage.Hscript)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.ToggleParmTemplate("conservemem", "Conserve Memory at the Expense of Export Time", default_value=False, default_expression='off', default_expression_language=hou.scriptLanguage.Hscript)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.ToggleParmTemplate("deformsasvcs", "Export Deforms as Vertex Caches", default_value=False, default_expression='off', default_expression_language=hou.scriptLanguage.Hscript)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.ToggleParmTemplate("forceblendshape", "Force Blend Shape Export", default_value=False, default_expression='off', default_expression_language=hou.scriptLanguage.Hscript)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.ToggleParmTemplate("forceskindeform", "Force Skin Deform Export", default_value=False, default_expression='off', default_expression_language=hou.scriptLanguage.Hscript)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.ToggleParmTemplate("exportendeffectors", "Export End Effectors", default_value=True, default_expression='on', default_expression_language=hou.scriptLanguage.Hscript)
        hou_parm_template.setTags({"autoscope": "0000000000000000"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        hou_parm_template = hou.ButtonParmTemplate("execute", "Save to Disk")
        hou_parm_template.setTags({"autoscope": "0000000000000000", "takecontrol": "always"})
        fbxNode.addSpareParmTuple(hou_parm_template, in_folder=(['Cache']), create_missing_folders=True)
        
        children = fbxNode.children()
        fbxNodeName = fbxNode.name().rsplit('_', 1)
        
        charGeo = fbxNode.createNode('geo', fbxNodeName[0] + '_geo')
        if len(charGeo.children()) > 0:
            charGeo.children()[0].destroy() # older version of houdini had a lone file node

        ccache = charGeo.createNode('alembic', 'char_abc_cache')
        ccache.parm('fileName').set('`chs("../../cachefile")`')
        cscale = charGeo.createNode('xform', 'cache_scale')
        cscale.setFirstInput(ccache)
        cscale.parm('scale').setExpression('ch("../../cache_scale")')
        cswitch = charGeo.createNode('switch', 'cache_switch')
        cswitch.parm('input').setExpression('ch("../../use_cache")')
        
        exportNet = fbxNode.createNode('ropnet', 'exportnet')
        alembicRop = exportNet.createNode('alembic', 'alembic')
        alembicRop.parm('execute').setExpression('ch("../../cache_btn")')
        alembicRop.parm('trange').setExpression('ch("../../trange")')
        alembicRop.parm('f1').setExpression('ch("../../f1")')
        alembicRop.parm('f2').setExpression('ch("../../f2")')
        alembicRop.parm('f3').setExpression('ch("../../f3")')
        alembicRop.parm('use_sop_path').set(1)
        alembicRop.parm('sop_path').set('../../' + charGeo.name())
        alembicRop.parm('build_from_path').set(1)
        alembicRop.parm('path_attrib').set('path')
        alembicRop.parm('root').set('')

        fbxRop = exportNet.createNode('filmboxfbx', 'fbx')
        fbxRop.parm('startnode').set('`opfullpath("../../")`')
        fbxRop.parm('createsubnetroot').set(0)
        
        fbxRop.parm('trange').setExpression('ch("../../trange2")')
        fbxRop.parm('f1').setExpression('ch("../../f41")')
        fbxRop.parm('f2').setExpression('ch("../../f42")')
        fbxRop.parm('f3').setExpression('ch("../../f43")')
        fbxRop.parm('take').setExpression('ch("../../take")')
        fbxRop.parm('sopoutput').setExpression('ch("../../sopoutput")')
        fbxRop.parm('mkpath').setExpression('ch("../../mkpath")')
        fbxRop.parm('exportkind').setExpression('ch("../../exportkind")')
        fbxRop.parm('sdkversion').setExpression('ch("../../sdkversion")')
        fbxRop.parm('vcformat').setExpression('ch("../../vcformat")')
        fbxRop.parm('invisobj').setExpression('ch("../../invisobj")')
        fbxRop.parm('polylod').setExpression('ch("../../polylod")')
        fbxRop.parm('detectconstpointobjs').setExpression('ch("../../detectconstpointobjs")')
        fbxRop.parm('convertsurfaces').setExpression('ch("../../convertsurfaces")')
        fbxRop.parm('conservemem').setExpression('ch("../../conservemem")')
        fbxRop.parm('deformsasvcs').setExpression('ch("../../deformsasvcs")')
        fbxRop.parm('forceblendshape').setExpression('ch("../../forceblendshape")')
        fbxRop.parm('forceskindeform').setExpression('ch("../../forceskindeform")')
        fbxRop.parm('exportendeffectors').setExpression('ch("../../exportendeffectors")')
        fbxRop.parm('execute').setExpression('ch("../../execute")')
        
        rigBox = fbxNode.createNetworkBox()
        rigBox.setComment('Rig')
                        
        for child in children:
            # for the fbxchop we need to rename it and set up a bclip/agent network to
            # drive animation on the joints
            if child.type().name() == 'chopnet':
                child.destroy()
            
            if child.type().name() == 'null':
                 # we want to set CHOP expressions for nulls so they move the bones with our mocap CHOPs
                 if child.name() is not fbxNodeName[0]: # check to make sure this is not the root null
                    child.parmTuple('t').deleteAllKeyframes()
                    child.parmTuple('r').deleteAllKeyframes()
                    child.parm('rx').setExpression('chop("../CHOP/OUT/$OS:$CH")')
                    child.parm('ry').setExpression('chop("../CHOP/OUT/$OS:$CH")')
                    child.parm('rz').setExpression('chop("../CHOP/OUT/$OS:$CH")')
                    child.parm('tx').setExpression('chop("../CHOP/OUT/$OS:$CH")')
                    child.parm('ty').setExpression('chop("../CHOP/OUT/$OS:$CH")')
                    child.parm('tz').setExpression('chop("../CHOP/OUT/$OS:$CH")')
                    rigBox.addNode(child)
            
            if child.type().name() == 'bone':
                # add the bones to the rig net box
                rigBox.addNode(child)
                    
            if child.type().name() == 'geo':
                if child.name() is not charGeo.name():
                    # we want to convert these to a single geo pointing to a alembic
                    hou.copyNodesTo(child.children(), charGeo)
                    child.destroy()
        
        rigBox.fitAroundContents()
        
        # build the CHOP network
        child = fbxNode.createNode('chopnet', 'CHOP')
        
        #let's fetch the original tpose and place in in a bclip
        fetch = child.createNode('fetch')
        fetch.parm('rate').set(24)
        fetch.parm('nodepath').set('../../* ')
        
        bclip = fetch.clipData(True)
        fileName = this.parm('char_bclip_file').eval()
        
        f = open(hou.expandString(fileName), 'wb')
        f.write(bclip)
        
        f.close()
        
        fetch.destroy()
        
        tposeChop = child.createNode('file', 'tpose_clip')
        tposeChop.parm('file').set(fileName)
        agentChop = child.createNode('agent', 'mocap')
        agentChop.parm('clipname').set('`chs("../../fbxclip")`')
        switch = child.createNode('switch', 'switch')
        switch.parm('index').setExpression('ch("../../mocapswitch")')
        
        outChop = child.createNode('null', 'OUT')
        sopNode = child.createNode('sopnet', 'fbxagent')
        
        switch.setFirstInput(tposeChop)
        switch.setNextInput(agentChop)
        outChop.setFirstInput(switch)
        
        fbxImport = sopNode.createNode('agent', 'fbximport')
        fbxImport.parm('fbxfile').set('`chs("../../../fbxfile")`')
        
        fbxImport.parm('input').set(2)
        
        agentChop.parm('soppath').set('../fbxagent/fbximport')
        
        outChop.setDisplayFlag(True)
        #outChop.setRenderFlag(True)
        
        child.layoutChildren()
        
        # work on the character geo point all the captures to an alembic file
        overMerge = charGeo.createNode('merge', 'merge')
        
        alembic = charGeo.createNode('alembic', 'char_abc_geo')
        fileName = this.parm('char_abc_file').eval()
        alembic.parm('fileName').set(fileName)
        
        unpack = charGeo.createNode('unpack', 'unpack')
        unpack.setFirstInput(alembic)
        unpack.parm('transfer_attributes').set('path shop_materialpath')
        
        children = charGeo.children()
        for child in children:
            if child.type().name() == 'file':
                nodeName = child.name()   
                deleteNode = charGeo.createNode('delete', 'isolate_' + nodeName)
                deleteNode.parm('negate').set(1)
                deleteNode.parm('group').set('@path="/' + nodeName + '/*"')
                deleteNode.setFirstInput(unpack)
                if len(child.outputs()) > 0:
                    delOutput = child.outputs()[0]
                    delOutput.setFirstInput(deleteNode)
                
                child.destroy()
            elif child.type().name() == 'deform':
                child.destroy()
            elif child.type().name() == 'channel':
                child.destroy()
            elif child.type().name() == 'capture':
                child.setGenericFlag(hou.nodeFlag.Lock, False) 
            elif child.type().name() == 'captureoverride':
                overMerge.setNextInput(child)
        
        deform = charGeo.createNode('deform', 'deform')
        deform.setFirstInput(overMerge)
        cswitch.setFirstInput(deform)
        cswitch.setNextInput(cscale)
        
        cswitch.setDisplayFlag(True)
        cswitch.setRenderFlag(True)
        
        charGeo.layoutChildren()

        hdaNode = fbxNode.createDigitalAsset(this.parm('asset_name').eval(), this.parm('hda_location').eval(), this.parm('desc').eval())
        hdaDef = hdaNode.type().definition()
        hdaOptions = hdaDef.options()
        hdaDef.save(hdaDef.libraryFilePath(), hdaNode, hdaOptions)