OO AddPointToNull in Python


Someone posted Olivier Ozoux’s 11-year-old AddNulltoPoints script to xisbase the other day. You can see from the install instructions that this script is old-school.

'################################################################################
'NAME: Add Null To Point v2.0
'AUTHOR: Olivier Ozoux <oliviero@softimage.com>
'LAST MODIFIED: 2001-05-22
'
'v2.0 is a complete rewrite using the Object Model where possible
'
'INSTALL
'
'1. Copy the SPDL file:
'	{5CD342AD-2FB1-4646-9D14-3E82C805177D}.spdl
'	to the spdl directory of XSI (for example):
'	C:\Softimage\XSI_1.5\Application\spdl
'
'2. Copy the Preset file:
'	AddNullToPointDialog.Preset
'	to the Preset Property directory of XSI (for example):
'	D:\Softimage\XSI_1.5\DSPresets\Properties
'
'3. Restart XSI
'
'4. Run the Script or Create a Command/Button on a toolbar
'	
'
'This tool will create a single Null for each point of the selected object(s).
'(you can also select a point cluster, or tag points). Then based on the dialog
'choice, it will either Constrain the Null to the Point using Object to Cluster
'constraint, or Deform the point to the Null with a Cluster Center operator.
'
'-Olivier Ozoux
'###############################################################################

To get rid of the SPDL and preset, I took a few minutes and updated it to Python.

#
# Softimage 2013 and later
#
from sipyutils import si			# win32com.client.Dispatch('XSI.Application')
from sipyutils import log		# LogMessage
from sipyutils import C			# win32com.client.constants
si = si()


#
# Softimage 2012
#
#from siutils import si		# Application
#from siutils import log		# LogMessage
#from siutils import disp	# win32com.client.Dispatch
#from siutils import C		# win32com.client.constants

#
# For Softimage 2011
# 
#from win32com.client import Dispatch as disp
#from win32com.client import constants as C
#si = disp('XSI.Application')
#log = si.LogMessage

def CreateUIDialog():

	oDialog = si.ActiveSceneRoot.Properties( 'AddNullToPoint' )
	
	if oDialog is None:
		oDialog = si.ActiveSceneRoot.AddProperty( 'CustomProperty', False, 'AddNullToPoint' )
		oDialog.AddParameter2("CnsType",C.siInt4,0,0,100,0,100,C.siClassifUnknown,C.siPersistable + C.siKeyable)
		oDialog.AddParameter2("NullName",C.siString,"",None,None,None,None,C.siClassifUnknown,C.siPersistable + C.siKeyable)
		oDialog.AddParameter2("ParentObj",C.siBool,True,None,None,None,None,C.siClassifUnknown,C.siPersistable + C.siKeyable)

		oLayout = oDialog.PPGLayout
		oLayout.Clear()
		oLayout.AddEnumControl( 'CnsType', [ 'Null to Point (Object to Cluster)', 0, 'Point to Null (Cluster Center)', 1 ], 'Constraint Type', C.siControlRadio )
		oLayout.AddGroup( 'Options' )
		oLayout.AddItem( 'NullName' )
		oLayout.AddItem( 'ParentObj' )
		oLayout.EndGroup()
		
		oDialog.Parameters( 'NullName' ).Value = '<obj>_pnt'
	
	return oDialog
	

def addNullToPoint( oSel, Mode, Name, Parent ):
	oRoot = si.ActiveSceneRoot
	if oSel.Type in [ 'polymsh', 'crvlist', 'surfmsh' ]:
		aIndex = [x for x in range( oSel.ActivePrimitive.Geometry.Points.Count ) ]
		oGeom = oSel.ActivePrimitive.Geometry
		oPoints = oGeom.Points
	elif oSel.Type == 'pntSubComponent':
		aIndex = oSel.SubElements
		oSel = oSel.SubComponent.Parent3DObject
		if oSel.Type in [ 'polymsh', 'crvlist', 'surfmsh' ]:
			oGeom = oSel.ActivePrimitive.Geometry
			oPoints = oGeom.Points
		else:
			log( 'Not a geometric object' )
			return
	elif oSel.Type == 'pnt':
		aIndex = oSel.Elements.Array
		oGeom = oSel.Parent
		oPoints = oGeom.Points
		oSel = oSel.Parent3DObject
	else:
		log( 'Not a geometric object' )
		return

	pntName = Name.replace( '<obj>', oSel.Name )

	for i in aIndex:
		oCls = oGeom.AddCluster( 'pnt', 'pnt' + str( i ), [i] )
		oNull = oSel.AddNull( 'pntName' + str( i ) )
		#TODO

		if Mode == 0:
			# Constrain the Null to the Cluster
			oNull.Kinematics.AddConstraint( "ObjectToCluster", oCls, False )
		elif Mode == 1:
			#Move the Null in position
			oNull.Kinematics.Local.Parameters("posx").Value = oPoints(i).Position.X
			oNull.Kinematics.Local.Parameters("posy").Value = oPoints(i).Position.Y
			oNull.Kinematics.Local.Parameters("posz").Value = oPoints(i).Position.Z

			# Create ClusterCenter
			si.ApplyOperator( "ClusterCenter", str(oCls) + ";" + str(oNull), 0 )

		#Cut The Null if needed
		if Parent == False:
			si.CutObj( oNull )

def AddNullToPointProc():
	oDialog = CreateUIDialog()
	retval = si.InspectObj( oDialog, "", "", C.siModal )

	mode = oDialog.Parameters("CnsType").Value
	name = oDialog.Parameters("NullName").Value
	parent = oDialog.Parameters("ParentObj").Value
	
	for oSel in si.Selection:
			addNullToPoint( oSel, mode, name, parent )


AddNullToPointProc()

8 thoughts on “OO AddPointToNull in Python

  1. this script, it’s does’nt work.
    here is error:
    ERROR : Traceback (most recent call last):
    # File “”, line 99, in
    # AddNullToPointProc()
    # File “”, line 88, in AddNullToPointProc
    # oDialog = CreateUIDialog()
    # File “”, line 19, in CreateUIDialog
    # oDialog = si.ActiveSceneRoot.Properties( ‘AddNullToPoint’ )
    # AttributeError: ‘function’ object has no attribute ‘ActiveSceneRoot’
    # – [line 19]
    maybe i was do some wrong?

  2. Hi, I tried to use your script, added the line to the top of the script, but get error:
    # ERROR : invalid syntax – [line 5]
    …referring to
    from siutils import si      # Application

    I know nothing about scripting! Can you help at all please? Softimage 2013

    Olly : )

    • Hi Olly

      Sorry for the late reply.
      For 2013 and later, put this at the top of the script:

      from sipyutils import si			# win32com.client.Dispatch('XSI.Application')
      from sipyutils import log		# LogMessage
      from sipyutils import C			# win32com.client.constants
      si = si()
      

      thanks

      Stephen

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s