For your productions, bundles are still an important scene-structure-tool. Since the Houdini 18 and solaris, this is a legacy workflow which will be less important over the next years. Anyway, we found it a little bit to early to jump to solaris – we’ll stay on the known workflows for a while.
When working with a huge amount of objects we organize our scenes with bundles. There are bundles for ogl capturings, rendering bundles, simulation bundles or light bundles. The downside of bundles is, that they are not copy- and pasteable. So I decided to create two scripts – One for copying and one for pasting bundles.
Feel free to download the scripts and to try them.
Copy Bundles
import hou import xml.etree.cElementTree as ET import xml.dom.minidom as minidom #set a counter bNR = 0 #create an empty bundle list crrBNodes = [] #setup elementtree root and sublement root = ET.Element("scene") doc = ET.SubElement(root, "bundles") #check if an bundle is selected if len(hou.selectedNodeBundles()) != 0: #loop over the selected bundles for currB in hou.selectedNodeBundles(): #loop over the bundle elements for currNode in currB.nodes(): #appand the current node to the bundle list crrBNodes.append(currNode.path()) #appand the new bundle subelement to the elment tree ET.SubElement(doc, "bundle", name=str(currB.name())).text = str(crrBNodes) #reset the bundle list crrBNodes = [] #format the elementtree rough_string = ET.tostring(root, 'utf-8') reparsed = minidom.parseString(rough_string) formatedTree = reparsed.toprettyxml(indent="\t") #setup the output path for the xml file outputDIR = hou.hscriptExpression("$TEMP") + "\\BUNDLE_Copy.xml" #write the xml file to the users temp direction with open(outputDIR, "w") as f: f.write(formatedTree)
Paste Bundles
#import modules import hou import os.path import xml.etree.cElementTree as ET #setup the output path for the xml file imputDIR = hou.hscriptExpression("$TEMP") + "/BUNDLE_Copy.xml" #check if the xml file exists if(os.path.exists(imputDIR)): #import the element tree from file tree = ET.parse(imputDIR) #get the root root = tree.getroot() #loop over the root for child in root: #loop over the bundles for elm in child: #create an checker variable oCheckBundleExists = 0 #loop over the scene bundles for currB in hou.nodeBundles(): #check if there is already a bundle with t if(elm.get('name') == currB.name()): #if ther is an existing bundle, set the checker to 1 oCheckBundleExists = 1 #convert sting to array oBundleMembers = elm.text oBundleMembers = oBundleMembers.replace("[","") oBundleMembers = oBundleMembers.replace("]","") oBundleMembers = oBundleMembers.replace("'","") oBundleMembers = oBundleMembers.replace(" ","") oBundleMembers = oBundleMembers.split(",") #check if the bundle exists if oCheckBundleExists == 1: #if it exists, create a bundle with _1 oCurrentBundle = hou.addNodeBundle(str(elm.get('name') + "_1")) else: #if it not exists create a the bundle wit the proper name oCurrentBundle = hou.addNodeBundle(str(elm.get('name'))) #Loop over the created array oBundleMembers for oNode in oBundleMembers: #assign the Node to add the the oNodeToAdd Variable oNodeToAdd = hou.node(oNode) #check if the node to add is valid if oNodeToAdd: #if yes add the node to the current bundle oCurrentBundle.addNode(oNodeToAdd) else: #if no put an error to the console print "Node not found " + oNode + ". Skip adding to Bundele: " + str(elm.get('name'))