Creating a NURBS curve generator (a python example)

Applies to: XSI 6.5

Here's an example that can be useful when you need a curve as input to something like a extrusion along axis and you want to control the curve's length and the number of control points.

Only the linear curve has been implemented, but there should be enough to get the idea.

Decoding what the NurbsCurveList.Set method expects can be tricky especially when trying to convert into python tuples; have a look at the LinearCurve_Init method for details.

# pyLinearCurveOpPlugin
# Initial code generated by XSI SDK Wizard
# Executed Wed May 28 12:51:38 EDT 2008 by sinwood
# 
# 
# Tip: To add a command to this plug-in, right-click in the 
# script editor and choose Tools > Add Command.
# 
# Tip: To get help on a callback, highlight the callback name
# (for example, "Init", "Define", or "Execute") and press F1.
import win32com.client
from win32com.client import constants

null = None
false = 0
true = 1
app = Application

def XSILoadPlugin( in_reg ):
	in_reg.Author = "sinwood"
	in_reg.Name = "pyLinearCurveOpPlugin"
	in_reg.Email = ""
	in_reg.URL = ""
	in_reg.Major = 1
	in_reg.Minor = 0

	in_reg.RegisterOperator("pyLinearCurveOp")
	in_reg.RegisterCommand("CreatePyLinearCurve","CreatePyLinearCurve")
	
	in_reg.RegisterCommand("DumpCurve","DumpCurve")
	#RegistrationInsertionPoint - do not remove this line

	return true

def XSIUnloadPlugin( in_reg ):
	strPluginName = in_reg.Name
	Application.LogMessage(str(strPluginName) + str(" has been unloaded."),constants.siVerbose)
	return true

def CreatePyLinearCurve_Init( in_ctxt ):
	oCmd = in_ctxt.Source
	oCmd.Description = "Create an instance of pyLinearCurveOp operator"
	oCmd.SetFlag(constants.siNoLogging,false)
	return true

def CreatePyLinearCurve_Execute(  ):

	Application.LogMessage("CreatePyLinearCurve_Execute called",constants.siVerbose)

	curve = LinearCurve_Create( "mycurve" )

	newOp = XSIFactory.CreateObject("pyLinearCurveOp")
	newOp.AddOutputPort( str(curve) + ".crvlist")
	newOp.AddInputPort( str(curve) + ".crvlist")
	newOp.Connect()
	return newOp

def pyLinearCurveOp_Define( in_ctxt ):
	oCustomOperator = in_ctxt.Source
	oPDef = XSIFactory.CreateParamDef("NbPoints",constants.siInt4,constants.siClassifUnknown,constants.siPersistable + constants.siAnimatable,"","",2,2,100,2,100)
	oCustomOperator.AddParameter(oPDef)
	oPDef = XSIFactory.CreateParamDef("Length",constants.siInt4,constants.siClassifUnknown,constants.siPersistable + constants.siAnimatable,"","",1,1,100,1,100)
	oCustomOperator.AddParameter(oPDef)

	oCustomOperator.AlwaysEvaluate = false
	oCustomOperator.Debug = 1
	return true

def pyLinearCurveOp_Init( in_ctxt ):
	Application.LogMessage("pyLinearCurveOp_Init called",constants.siVerboseMsg)
	return true

def pyLinearCurveOp_Term( in_ctxt ):
	Application.LogMessage("pyLinearCurveOp_Term called",constants.siVerboseMsg)
	return true

def pyLinearCurveOp_Update( in_ctxt ):
	InGeom = in_ctxt.GetInputValue(0)

	NbPoints = in_ctxt.GetParameterValue("NbPoints")
	Length = in_ctxt.GetParameterValue("Length")

	Application.LogMessage("pyLinearCurveOp_Update called",constants.siVerboseMsg)

	output = in_ctxt.OutputTarget
	
	LinearCurve_Init( output.Geometry, Length, NbPoints )
	
	return true

def pyLinearCurveOp_DefineLayout( in_ctxt ):
	oLayout = in_ctxt.Source
	oLayout.Clear()
	oLayout.AddItem("NbPoints")
	oLayout.AddItem("Length")
	return true

def pyLinearCurveOp_OnInit( ):
	Application.LogMessage("pyLinearCurveOp_OnInit called",constants.siVerbose)

def pyLinearCurveOp_OnClosed( ):
	Application.LogMessage("pyLinearCurveOp_OnClosed called",constants.siVerbose)

def pyLinearCurveOp_NbPoints_OnChanged( ):
	Application.LogMessage("pyLinearCurveOp_NbPoints_OnChanged called",constants.siVerbose)
	oParam = PPG.NbPoints
	paramVal = oParam.Value
	Application.LogMessage(str("New value: ") + str(paramVal),constants.siVerbose)

def pyLinearCurveOp_Length_OnChanged( ):
	Application.LogMessage("pyLinearCurveOp_Length_OnChanged called",constants.siVerbose)
	oParam = PPG.Length
	paramVal = oParam.Value
	Application.LogMessage(str("New value: ") + str(paramVal),constants.siVerbose)

def LinearCurve_Init(geomOut,length, nbpoints ):
	global app
	try:
		lCount = 1
		
		aX = []
		aY = []
		aZ = []
		aW = []
		aKnots = []
		
		for i in range(0, nbpoints):
			if nbpoints-1 : 
				x = i * (float(length) / (nbpoints-1))
			else :
				x = 0.0	
			aX.append( x )
			aY.append( 0.0 )
			aZ.append( 0.0 )
			aW.append( 1.0 )
			aKnots.append( [ float(i) ] )
			
		app.Logmessage( str(aX), constants.siVerbose )
		app.Logmessage( str(aKnots), constants.siVerbose )
	
		aControlVertex = [ aX, aY , aZ, aW ] 
		aNbControlVertex  = [ len(aX) ] 
		aNbKnots = [ len(aKnots) ]
		bClosed = [False]
		lDegree = [1] 
		eParameterization = [constants.siNonUniformParameterization] 
		
		# add data to  nurbs curve list.
		geomOut.Set( 
			lCount, 
			aControlVertex, 
			aNbControlVertex, 
			aKnots, 
			aNbKnots, 
			bClosed, 
			lDegree, 
			eParameterization, 
			constants.siSINurbs )

	except Exception, detail:
		app.Logmessage( "LinearCurve_Init: error " + str(detail), constants.siVerbose )

def LinearCurve_Create(strName):
	global app
	
	lDegree=1
	lCurveType=1
	obj = app.SICreateCurve(strName, lDegree, lCurveType)
	app.FreezeModeling( obj )
	return obj

def Curve_Dump( geomIn ) :
	global app
	aCurveData = geomIn.Get2(constants.siSINurbs)

	lCount = aCurveData[0]
	aControlVertex = aCurveData[1]
	aNbControlVertex = aCurveData[2]
	aKnots = aCurveData[3]
	aNbKnots = aCurveData[4]
	bClosed = aCurveData[5]
	lDegree = aCurveData[6]
	eParameterization = aCurveData[7]
 
	app.Logmessage( "curve " + str(geomIn), constants.siVerbose )
	app.Logmessage( "\tcount " + str(lCount), constants.siVerbose )
	app.Logmessage( "\taControlVertex " + str(aControlVertex), constants.siVerbose )
	app.Logmessage( "\taNbControlVertex " + str(aNbControlVertex), constants.siVerbose )
	app.Logmessage( "\taKnots " + str(aKnots), constants.siVerbose )
	app.Logmessage( "\tNbKnots " + str(aNbKnots), constants.siVerbose )
	app.Logmessage( "\tbClosed " + str(bClosed), constants.siVerbose )
	app.Logmessage( "\tlDegree " + str(lDegree), constants.siVerbose )
	app.Logmessage( "\teParameterization " + str(eParameterization), constants.siVerbose )

def DumpCurve_Init( in_ctxt ):
	oCmd = in_ctxt.Source
	oCmd.Description = ""
	oCmd.ReturnValue = true

	oArgs = oCmd.Arguments
	oArgs.AddWithHandler("objs","Collection")
	return true

def DumpCurve_Execute( objs ):
	global app
	
	# avoid error when focus in pluginmanager.
	try:
		for obj in objs:
			Curve_Dump( obj.ActivePrimitive.Geometry )

	except:
		return false
	
	return true


This page was last modified 12:32, 28 May 2008.
This page has been accessed 7727 times.

© Copyright 2009 Autodesk Inc. All Rights Reserved. Privacy Policy | Legal Notices and Trademarks | Report Piracy