4Point Surface Constraint in ICE

When rigging swimming or flowting things it’s not the best idea to put the hole object under one null and to rotate that. A better idea is to make a linear surface grid with four points, cluster constrain the four points to nulls and create a fifth null which is surface constrained to the middle of the surface.

Read More

Add Closest Surface Constraint

This one is quite Interesting I think. During the Anomalia rigging workshop in Litomyšl (Czech Republic) the instructor Josh Carey from ReelFX has constantly used follicle constraints for all kinds of rigging topics. In Softimage language a follicle constraint is just a simple surface constraint. But that was not what I found interesting. I liked the way Josh was creating the constraints. He had a small script that searched the closest location from locator, read the u and v coordinates of the location and appled a surface constraint with exact this coordinates. With this technique it is quite easy, to get the controllers exact to the point where I want them. In the case of surface constraints, it is not always as easy as you think.

Read More

Create controls in bounding box

Frequently I’m using the “Create Cluster with Center” command to create control objects. After a while I found myself tagging components and running this command, just to get a null in the bounding box center. What’s annoying about that is, it creates also the “cluster center” operator and an cluster on the mesh. Unfortunately this is not my original intention. I just want centered nulls for rigging.

So I made small python function that reads the bounding box information of the tagged components (points, edges or polygons) creates a reset-null plus a control-null and set them to the coordinates of the bounding box.

Read More

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()

Select every Nth Component

When modeling things, it’s often needed to select every Nth Component. To make this selections more easy, I have made a temporary PPG that helps you to deselect components.

The PPG has two parameters (start and pattern) and two options (restore selection and apply new selection).

Parameter – Start: Defines the start component
Parameter – Pattern: Defines the the numbers of unselected components – 1. An example: if pattern is set to 4 every fourth component will be selected.

Option – Restore Selection: Restores the start-selection
Option – Apply New Selection: Applies the new selection with the chosen parameters

Usage:
1. Save the script somewhere.
2. Change this line to the file location:”oPPGLayout.SetAttribute(c.siUILogicFile, “\\\\Server\\Scripts\\select_components.py”)”
3. Select one object, tag some components:”Points, Edges, Polygons” and run the script

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

def selectEveryNth_createPSet(oInObjName, oInComponents, oTypecheck):
	oPSet = XSIFactory.CreateObject("CustomProperty")
	oPSet.Name = "AB_SelectEveryNthComponent"
	oPSet.AddParameter3( "Start", c.siInt4, 0)
	oPSet.AddParameter3( "Pattern", c.siInt4, 2)
	oPSet.AddParameter3( "oObjName", c.siString, str(oInObjName))	
	oPSet.AddParameter3( "oInSelection", c.siString, str(oInComponents))	
	oPSet.AddParameter3( "oTypeCheck", c.siString, str(oTypecheck))	
	return oPSet	

def selectEveryNth_createLayout(oPSet):
	oPPGLayout = oPSet.PPGLayout
	oPPGLayout.AddGroup( "Start/Pattern" ) 
	oPPGLayout.AddItem( "Start", "", "" )
	oPPGLayout.AddItem( "Pattern", "", "" )
	oPPGLayout.EndGroup() 
	
	oPPGLayout.AddGroup( "Selection" )
	oPPGLayout.AddRow() 
	oPPGLayout.AddButton( "ButtonRestore", "Restore Selection" )
	oPPGLayout.AddButton( "ButtonSelectNew", "Apply New Selection" )
	oPPGLayout.EndRow() 
	oPPGLayout.EndGroup()
	oPPGLayout.Language="Python"
	oPPGLayout.SetAttribute(c.siUILogicFile, "\\\\Server\\Scripts\\select_components.py")
	return True
	
def selectEveryNth_Execute(inSelection):
	oMyComponentSel = []
	oTypeCheck = 0
	if inSelection.Count > 0:
		log('debug: Ok, you have selected something')
		if inSelection.Count == 1:
			log('debug: right, one object selected')
			if inSelection(0).Type == 'polySubComponent':
				oTypeCheck = 1
			elif inSelection(0).Type == 'pntSubComponent':
				log('debug: pntSubComponent')
				log(inSelection(0).SubElements2)
				oTypeCheck = 2
			elif inSelection(0).Type == 'edgeSubComponent':
				oTypeCheck = 3
			else:
				log('debug: please select some components')
			if oTypeCheck != 0:
				oParent = inSelection[0].SubComponent.Parent.Parent.Parent.FullName
				oParentSplit = oParent.split(".",1)
				if oParent[0] != "Scene_Root":
					log(oParent)
					oPSet = selectEveryNth_createPSet(str(oParent), inSelection(0).SubElements2,oTypeCheck )										
				else:
					log(oParent)
					oPSet = selectEveryNth_createPSet(str(inSelection[0].Name), inSelection(0).SubElements2,oTypeCheck )					
				selectEveryNth_createLayout(oPSet)
				xsi.InspectObj( oPSet, "", "", c.siLock, False )

		else:
			log('debug: please select just one object')
	else:
		log(' debug: please select something')
	return True
	
def selectEveryNth_selectNew():
	if 'PPG' in globals():
		oPattern = xsi.GetValue(str(PPG.InspectedObjects)+".Pattern")
		oStart = xsi.GetValue(str(PPG.InspectedObjects)+".Start")
		oObjName = xsi.GetValue(str(PPG.InspectedObjects)+".oObjName")
		oInSelection = xsi.GetValue(str(PPG.InspectedObjects)+".oInSelection")
		oTypeCheck = xsi.GetValue(str(PPG.InspectedObjects)+".oTypeCheck")
	xsi.DeselectAll()
	xsi.SelectObj(oObjName, "", True)
	oMyComponentSel = str(oInSelection).replace(')','')
	oMyComponentSel = oMyComponentSel.replace('(','')
	oMyComponentSel = oMyComponentSel.split(',')
	oNewComponentSel = oMyComponentSel[int(oStart)::int(oPattern)]
	oNewComponentSelStr = str(oNewComponentSel).replace(']','')
	oNewComponentSelStr = oNewComponentSelStr.replace('[','')	
	oNewComponentSelStr = oNewComponentSelStr.replace("'",'')	
	if int(oTypeCheck) == 1:
		xsi.SetSelFilter("Polygon")
		xsi.SelectGeometryComponents(str(oObjName) + '.poly[' + oNewComponentSelStr + ']')
	elif int(oTypeCheck) == 2:
		xsi.SetSelFilter("Vertex")
		xsi.SelectGeometryComponents(str(oObjName) + '.pnt[' + oNewComponentSelStr + ']')
	elif int(oTypeCheck) == 3:
		xsi.SetSelFilter("Edge")
		xsi.SelectGeometryComponents(str(oObjName) + '.edge[' + oNewComponentSelStr + ']')

def selectionRestore_selectNew():
	if 'PPG' in globals():
		oPattern = xsi.GetValue(str(PPG.InspectedObjects)+".Pattern")
		oStart = xsi.GetValue(str(PPG.InspectedObjects)+".Start")
		oObjName = xsi.GetValue(str(PPG.InspectedObjects)+".oObjName")
		oInSelection = xsi.GetValue(str(PPG.InspectedObjects)+".oInSelection")
		oTypeCheck = xsi.GetValue(str(PPG.InspectedObjects)+".oTypeCheck")
	xsi.DeselectAll()
	xsi.SelectObj(oObjName, "", True)
	oMyComponentSel = str(oInSelection).replace(')','')
	oMyComponentSel = oMyComponentSel.replace('(','')
	if int(oTypeCheck) == 1:
		xsi.SetSelFilter("Polygon")
		xsi.SelectGeometryComponents(str(oObjName) + '.poly[' + oMyComponentSel + ']')
	elif int(oTypeCheck) == 2:
		xsi.SetSelFilter("Vertex")
		xsi.SelectGeometryComponents(str(oObjName) + '.pnt[' + oMyComponentSel + ']')
	elif int(oTypeCheck) == 3:
		xsi.SetSelFilter("Edge")
		xsi.SelectGeometryComponents(str(oObjName) + '.edge[' + oMyComponentSel + ']')

def ButtonRestore_OnClicked():
	Application.LogMessage("Restore Selection")
	selectionRestore_selectNew()

def ButtonSelectNew_OnClicked():
	Application.LogMessage("Apply New Selection")
	selectEveryNth_selectNew()
	
selectEveryNth_Execute(collSel)