Instance Objects By Bundle Members

Hey!

I made a simple setup that reads the members of a bundle and copies the oppath as an instance attribute to points. When dealing with a huge amount of instances, it’s super easy to manage those instance masters. Click here to download the scene. InstanceByBundleMembers

Quick Edit: Please add the line oInstances.sort() to the Python SOP. With this line, the instaces will stay the same. Otherwhise it could be, that python reads the bundle members in another way from time to time.

Houdini: find all unused materials

Hey here is a python function that returns all unused materials of a scene. After a while Houdini scenes tend to have more and more materials that are not needed. This function helps to find all stuff that has no dependency in the scene. I’ve added a searchContext List that defines all the types of materials we were working with. So if you are working with other renderes (like vray or renderman), it is needed to add this type of materials to the list. If you don’t know your type of material, you can use the function in the third line. Simply put this into the python source editor, select your material and hit apply. The console should give you informations over the type.

 

 

  
import hou

#debug Line if you want to add new searchContexts
#print hou.selectedItems()[0].type()

#findUnUsedMaterails function
#returns a tupple of materialpathes
def findUnUsedMaterials():
    #define an empty list that will returned in the end
    outList = []
    #set the search Contexts
    searchContext = [["mat", "principledshader::2.0"],\
                    ["mat", "redshift_vopnet"],\
                    ["mat", "redshift::Material"], \
                    ["mat", "materialbuilder"],\
                    ["mat", "arnold_materialbuilder"],\
                    ["shop", "RS_Material"],\
                    ["shop", "vopsurface"],\
                    ["shop", "redshift_vopnet"],\
                    ["shop", "arnold_vopnet"]]
    #loop over the searchContext variable
    for inContext in searchContext:
        #define the node Context Type, mat or shop
        if inContext[0] == "mat":
            node_type = hou.nodeType(hou.vopNodeTypeCategory(), inContext[1])
        if inContext[0] == "shop":
            node_type = hou.nodeType(hou.shopNodeTypeCategory(), inContext[1])
        #get all Instances of the Mat type
        Mats = node_type.instances()
        for Mat in Mats:            
            #set a checker variable for adding materials to the outList
            checker = 0
            #get all dependencies of the current material instance
            allDepents = Mat.dependents() 
            #check if there are dependencies
            if allDepents:
                #loop over all dependencies of the material instance
                for currDepents in allDepents:
                    #if there is an dependency set the checker to 1
                    if (currDepents.type().name() != inContext[1]):
                        checker = 1 
                #if the checker is still == 0, meaning that there is no dependency append the material path to the outList
                if(checker == 0):
                    outList.append(str(Mat.path()))
            else:
                #if there is no dependency append the material paht the outList
                outList.append(str(Mat.path()))
    #return the list of unused materaials
    return outList

print findUnUsedMaterials()


        
        

PS: If you are a tough guy, loop over the returned list and delete the nodes 😀

  
unusedMats = findUnUsedMaterials()
for unusedMat in unusedMats:
    hou.node(unusedMat).destroy()

Deinstance PointClouds

When distributing object-instances across the scene, it’s most oft the time, the fastest way to do this within the ice framework of Softimage. The problem comes across if the director want’s to move objects manually. There are may solutions for that. In our last project, the most effective and time efficient way was to deinstance the pointcloud and to move the objects by hand.

I have programmed a small function in Python, that makes instances of models, clones of objects and new primitives plus clones from ice primitives.

Usage:
* Just select a pointcloud and run the script.

Known Issues:
* It’s getting slow with >250 particle Instances.
* When there is no per-point rotation data is set, the script will crash. Workaround: Set a particle orientation during the emission. For example with the “randomize rotation by cone” node.

Deinstance Pointcloud 2

from win32com.client import constants as c
xsi = Application
log = Application.LogMessage
collSel = xsi.Selection

def deinstancePointCloud():
	if collSel(0).Type == "pointcloud":
		#Turn Off Logging
		xsi.SetValue("preferences.scripting.cmdlog", False, "")

		pointShape=collSel[0].ActivePrimitive.GetICEAttributeFromName("Shape")
		pointPosition=collSel[0].ActivePrimitive.GetICEAttributeFromName("PointPosition")
		pointOrientation=collSel[0].ActivePrimitive.GetICEAttributeFromName("Orientation")
		pointSize=collSel[0].ActivePrimitive.GetICEAttributeFromName("Size")
		pointScale=collSel[0].ActivePrimitive.GetICEAttributeFromName("Scale")


		#Get Shape Type (0-9 Ice Shapes, 129 RealObj)
		InstanceType = pointShape.DataArray[0].Type
		log(pointShape.DataArray[0].Type)
		
		#Progessbar
		oProgressBar = XSIUIToolkit.ProgressBar 
		oProgressBar.Maximum = pointShape.ElementCount 
		oProgressBar.Step = 1
		oProgressBar.Caption = "Creating Instances/Clones"
		oProgressBar.CancelEnabled = True 
		oProgressBar.Visible = True

		#Loop through all elements
		for oElements in range(0,pointShape.ElementCount):
			#Check if the shape is one of the defaults:  Point, Box, Sphere...
			if InstanceType > 9:
				if oProgressBar.CancelPressed != True:
					objectID=pointShape.DataArray[oElements].ReferenceID
					instance=xsi.GetObjectFromID(objectID)
					ppos = pointPosition.DataArray[oElements]
					prot = pointOrientation.DataArray[oElements]
					psize = pointSize.DataArray[oElements]
					pscl = pointScale.DataArray[oElements]					
					if str(instance.Type) == "polymsh":
						currInst = xsi.Clone(str(instance), "", 1, 0, 0, 0, 1, 0, 1, "", "", "", "", "", "", "", "", "", "")
					if "model" in str(instance.Type):
						currInst = xsi.Instantiate(str(instance), "", 1, 1, 0, 1, "", "", "", "", "", "", "", "", "", "")
					xsi.Translate(str(currInst), ppos.X, ppos.Y, ppos.Z, "siAbsolute", "siPivot", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
					xsi.Rotate(str(currInst), prot.RotX, prot.RotY, prot.RotZ, "siAbsolute", "siPivot", "siObj", "siXYZ", "", "", "", "", "", "", "", 0, "")
					xsi.Scale(str(currInst), (pscl.X * psize), (pscl.Y * psize), (pscl.Z * psize), "siAbsolute", "siPivot", "siObj", "siXYZ", "", "", "", "", "", "", "", 0, "")
					log(oProgressBar.Value)
					oProgressBar.Increment()
				else:
					#Turn On Logging
					xsi.SetValue("preferences.scripting.cmdlog", True, "")
					break
			else:
				if oProgressBar.CancelPressed != True:
					#Check if the Instances are Points, Segments or Blobs
					if int(InstanceType) == 0:
						pass
					elif int(InstanceType) == 1:
						pass
					elif int(InstanceType) == 9:
						pass
					else:
						#Create a Master Disc
						if int(InstanceType) == 2:
							if oElements == 0:
								instance = xsi.CreatePrim("Disc", "MeshSurface", str(collSel[0].Name) + "_Master", "")
								xsi.SetValue(instance.Name + ".disc.innerradius", 0.01, "")
								xsi.SetValue(instance.Name + ".disc.outerradius", 1, "")
								xsi.SetValue(instance.Name + ".polymsh.geom.subdivv", 3, "")
						#Create a Master Disc
						if int(InstanceType) == 3:
							if oElements == 0:
								instance = xsi.CreatePrim("Grid", "MeshSurface", str(collSel[0].Name) + "_Master", "")
								xsi.SetValue(instance.Name + ".grid.ulength", 2, "")
								xsi.SetValue(instance.Name + ".grid.vlength", 2, "")
								xsi.SetValue(instance.Name + ".polymsh.geom.subdivu", 1, "")	
								xsi.SetValue(instance.Name + ".polymsh.geom.subdivv", 1, "")						
						#Create a Master Sphere
						if int(InstanceType) == 4:
							if oElements == 0:
								instance = xsi.CreatePrim("Sphere", "MeshSurface", str(collSel[0].Name) + "_Master", "")
								xsi.SetValue(instance.Name + ".sphere.radius", 1, "")
						#Create a Master Cube
						if int(InstanceType) == 5:
							if oElements == 0:
								instance = xsi.CreatePrim("Cube", "MeshSurface", str(collSel[0].Name) + "_Master", "")
								xsi.SetValue(instance.Name + ".cube.length", 2, "")
						#Create a Master Cylinder
						if int(InstanceType) == 6:
							if oElements == 0:
								instance = xsi.CreatePrim("Cylinder", "MeshSurface", str(collSel[0].Name) + "_Master", "")
								xsi.SetValue(instance.Name + ".cylinder.height", 2, "")
								xsi.SetValue(instance.Name + ".cylinder.radius", 1, "")
						#Create a Master Sphere
						if int(InstanceType) == 7:
							if oElements == 0:
								instance = xsi.CreatePrim("Sphere", "MeshSurface", str(collSel[0].Name) + "_Master", "")
								xsi.SetValue(instance.Name + ".sphere.radius", 1, "")
						#Create a Master Cone
						if int(InstanceType) == 8:
							if oElements == 0:
								instance = xsi.CreatePrim("Cone", "MeshSurface", str(collSel[0].Name) + "_Master", "")
								xsi.SetValue(instance.Name + ".cone.height", 2, "")
								xsi.SetValue(instance.Name + ".cone.radius", 1, "")
								xsi.SelectObj(instance, "", "")
								xsi.ActivateVertexSelTool("")
								xsi.SelectAllUsingFilter("Vertex", "siCheckComponentVisibility", "", "")
								xsi.Translate("", 0, -0.2917, 0, "siRelative", "siView", "siObj", "siY", "", "", "", "", "", "", "", "", "", 0, "")
								xsi.ActivateObjectSelTool("")
								xsi.ActivateObjectSelTool("")
								xsi.DeselectAll()
						ppos = pointPosition.DataArray[oElements]
						prot = pointOrientation.DataArray[oElements]
						psize = pointSize.DataArray[oElements]
						pscl = pointScale.DataArray[oElements]						
						currInst = xsi.Clone(str(instance), "", 1, 0, 0, 0, 1, 0, 1, "", "", "", "", "", "", "", "", "", "")
						xsi.Translate(str(currInst), ppos.X, ppos.Y, ppos.Z, "siAbsolute", "siPivot", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
						xsi.Rotate(str(currInst), prot.RotX, prot.RotY, prot.RotZ, "siAbsolute", "siPivot", "siObj", "siXYZ", "", "", "", "", "", "", "", 0, "")
						xsi.Scale(str(currInst), (pscl.X * psize), (pscl.Y * psize), (pscl.Z * psize), "siAbsolute", "siPivot", "siObj", "siXYZ", "", "", "", "", "", "", "", 0, "")
						tempName = str(currInst)
						tempName = tempName.replace("Master", "Instance")				
						xsi.SetValue(str(currInst) + ".Name", str(tempName), "")
						log(oProgressBar.Value)
						oProgressBar.Increment()
				else:
					#Turn On Logging
					xsi.SetValue("preferences.scripting.cmdlog", True, "")
					break

		#Turn On Logging
		xsi.SetValue("preferences.scripting.cmdlog", True, "")

deinstancePointCloud()