-
-
-
-
-
-
-
-
#---------------------------------------------------+
-
# ntFormulaCurve |
-
# Cinema 4D inspired expression curve generator |
-
# Nikolay Tashev - ntjahero@gmail.com |
-
#---------------------------------------------------+
-
# Created for Maya 2011/2012 |
-
#---------------------------------------------------+
-
# The following code is provided as is. |
-
# Modify at your own risk. |
-
# Please do not redistribute without my permission, |
-
# or at least notify me. |
-
#---------------------------------------------------+
-
# Usage: |
-
# Create the node and connect the .outCurve attr |
-
# to a nurbsCurve.create attribute |
-
#---------------------------------------------------+
-
# Since MStatus is removed from the python api |
-
# Maya 2013 just return the proper integer: |
-
# MStatus::kSuccess = 0 |
-
# MStatus::kFailure = 1 |
-
# MStatus::kInsufficientMemory = 2 |
-
# MStatus::kInvalidParameter = 3 |
-
# MStatus::kLicenseFailure = 4 |
-
# MStatus::kUnknownParameter = 5 |
-
# MStatus::kNotImplemented = 6 |
-
# MStatus::kNotFound = 7 |
-
# MStatus::kEndOfFile = 8 |
-
#---------------------------------------------------+
-
-
-
import sys
-
import maya.OpenMaya as om
-
import maya.OpenMayaMPx as ompx
-
-
nodeName = 'ntFormulaCurve'
-
nodeID = om.MTypeId(0xCC001)
-
nodeAuthor = "Nikolay Tashev"
-
nodeVersion = "1.1"
-
nodeApi = "Any"
-
-
def makeinput(attr, key=1):
-
attr.setWritable(1)
-
attr.setStorable(1)
-
attr.setKeyable(key)
-
def makeoutput(attr):
-
attr.setReadable(1)
-
attr.setKeyable(0)
-
-
class Formula_Curve(ompx.MPxNode):
-
kLinear = 0
-
kCubic = 1
-
kOpen = 0
-
kClosed = 1
-
kPeriodic = 2
-
aTime = om.MObject()
-
aNumSpans = om.MObject()
-
aParamRangeMin = om.MObject()
-
aDegree = om.MObject()
-
aForm = om.MObject()
-
aExpression = om.MObject()
-
aHelpStr = om.MObject()
-
aOutCurve = om.MObject()
-
-
@staticmethod
-
def AETemplate(nodeName):
-
AEStr = "global proc AE%sTemplate(string $nodeName)\n" % nodeName
-
AEStr += "{\n"
-
AEStr += "editorTemplate -beginScrollLayout;\n"
-
AEStr += " editorTemplate -addControl \"time\";\n"
-
AEStr += " editorTemplate -addControl \"spans\";\n"
-
AEStr += " editorTemplate -addControl \"parameterRange\";\n"
-
AEStr += " editorTemplate -addControl \"degree\";\n"
-
AEStr += " editorTemplate -addControl \"form\";\n"
-
AEStr += " editorTemplate -addControl \"valueX\";\n"
-
AEStr += " editorTemplate -addControl \"valueY\";\n"
-
AEStr += " editorTemplate -addControl \"valueZ\";\n"
-
AEStr += " editorTemplate -callCustom \"AE%sFormulaNew\" \"AE%sFormulaRepl\" \"expression\";\n" % (nodeName,nodeName)
-
AEStr += " editorTemplate -beginLayout \"Quick Help\" -collapse 1;\n"
-
AEStr += " editorTemplate -callCustom \"AE%sHelpNew\" \"AE%sHelpRepl\" \"quickHelp\";\n" % (nodeName,nodeName)
-
AEStr += " editorTemplate -endLayout;\n"
-
AEStr += " editorTemplate -addExtraControls;\n"
-
AEStr += "editorTemplate -endScrollLayout;\n"
-
AEStr += "}\n"
-
AEStr += "global proc AE%sHelpNew( string $attrName )\n" % nodeName
-
AEStr += "{\n"
-
AEStr += " textField AE%s_HelpTxt;\n" % nodeName
-
AEStr += " connectControl AE%s_HelpTxt $attrName;\n" % nodeName
-
AEStr += " scrollField -tx `textField -q -tx AE%s_HelpTxt` -ed 0 helpScroll;\n" % nodeName
-
AEStr += " textField -e -vis 0 AE%s_HelpTxt;\n" % nodeName
-
AEStr += "}\n"
-
AEStr += "global proc AE%sHelpRepl( string $attrName )\n" % nodeName
-
AEStr += "{\n"
-
AEStr += "}\n"
-
AEStr += "global proc AE%sFormulaNew( string $attrName )\n" % nodeName
-
AEStr += "{\n"
-
AEStr += " text -l \"Point Coordinates Expression:\";\n"
-
AEStr += " scrollField -tx `getAttr $attrName` AE%s_expressionField;\n" % nodeName
-
AEStr += " $AE%sCmd = \"setAttr -type \\\"string\\\" \"+$attrName+\" `scrollField -q -tx AE%s_expressionField`\";\n" % (nodeName, nodeName)
-
AEStr += " scrollField -e -cc $AE%sCmd -ec $AE%sCmd AE%s_expressionField;\n" % (nodeName, nodeName, nodeName)
-
AEStr += "}\n"
-
AEStr += "global proc AE%sFormulaRepl( string $attrName )\n" % nodeName
-
AEStr += "{\n"
-
AEStr += " scrollField -e -tx `getAttr $attrName` AE%s_expressionField;\n" % nodeName
-
AEStr += " $AE%sCmd = \"setAttr -type \\\"string\\\" \"+$attrName+\" `scrollField -q -tx AE%s_expressionField`\";\n" % (nodeName, nodeName)
-
AEStr += " scrollField -e -cc $AE%sCmd -ec $AE%sCmd AE%s_expressionField;\n" % (nodeName, nodeName, nodeName)
-
AEStr += "}\n"
-
return AEStr
-
-
def __init__(self):
-
super(Formula_Curve, self).__init__()
-
-
def compute(self, plug, db):
-
# Gather
-
spans = db.inputValue(self.aNumSpans).asInt()
-
time = db.inputValue(self.aTime).asTime().value()
-
plugRange = om.MPlug( self.thisMObject(), self.aParamRange)
-
prange = [ plugRange.child(0).asFloat(), plugRange.child(1).asFloat() ]
-
expression = db.inputValue(self.aExpression).asString()
-
degreeEnum = db.inputValue(self.aDegree).asShort()
-
formEnum = db.inputValue(self.aForm).asShort()
-
-
# Degree And Form
-
degree = 1
-
if degreeEnum != self.kLinear: degree = 3
-
spans = max(spans, degree)
-
form = om.MFnNurbsCurve.kOpen
-
if formEnum == self.kClosed: form = om.MFnNurbsCurve.kClosed
-
elif formEnum == self.kPeriodic: form = om.MFnNurbsCurve.kPeriodic
-
-
# Process
-
knotPositions = om.MPointArray()
-
msu = om.MScriptUtil()
-
ptr = msu.asDoublePtr()
-
pmin = prange[0]
-
pstep = (prange[1] - prange[0])/(spans-1)
-
cmdResult = om.MCommandResult()
-
vectorResult = om.MVector()
-
try:
-
for k in range(spans):
-
p = pmin + k*pstep
-
cmd = "float $K = %f;\n" % k
-
cmd += "float $P = %f;\n" % p
-
cmd += "float $T = %f;\n" % time
-
cmd += "float $N = %f;\n" % spans
-
cmd += "float $X = 0;\n"
-
cmd += "float $Y = 0;\n"
-
cmd += "float $Z = 0;\n"
-
cmd += "%s;\n" % expression
-
cmd += "vector $fnCurvePt = <<$X, $Y, $Z>>;\n"
-
om.MGlobal.executeCommand(cmd, cmdResult, 0, 0)
-
cmdResult.getResult(vectorResult)
-
knotPositions.append( om.MPoint(vectorResult) )
-
except:
-
#om.MGlobal.displayError("Error evaluating expression")
-
return 5
-
cvDataFn = om.MFnNurbsCurveData()
-
cvDataObj = cvDataFn.create()
-
cvFn = om.MFnNurbsCurve()
-
cvFn.createWithEditPoints(knotPositions, degree, form, 0, 1, 1, cvDataObj)
-
dhOutCurve = db.outputValue(self.aOutCurve)
-
dhOutCurve.setMObject(cvDataObj)
-
dhOutCurve.setClean()
-
#return om.MStatus.kSuccess
-
return 0
-
-
@staticmethod
-
def createNode():
-
return ompx.asMPxPtr( Formula_Curve() )
-
-
@staticmethod
-
def initializeNode():
-
atime = om.MFnUnitAttribute()
-
atype = om.MFnTypedAttribute()
-
anum = om.MFnNumericAttribute()
-
aenum = om.MFnEnumAttribute()
-
defStrData = om.MFnStringData()
-
-
Formula_Curve.aTime = atime.create("time", "t", om.MFnUnitAttribute.kTime)
-
makeinput(atime)
-
Formula_Curve.aNumSpans = anum.create("spans", "sp", om.MFnNumericData.kInt, 32)
-
makeinput(anum)
-
-
Formula_Curve.aDegree = aenum.create("degree", "d")
-
aenum.addField("Linear", Formula_Curve.kLinear)
-
aenum.addField("Cubic", Formula_Curve.kCubic)
-
makeinput(aenum)
-
-
Formula_Curve.aForm = aenum.create("form", "f")
-
aenum.addField("Open", Formula_Curve.kOpen)
-
aenum.addField("Closed", Formula_Curve.kClosed)
-
aenum.addField("Periodic", Formula_Curve.kPeriodic)
-
makeinput(aenum)
-
-
aPMin = anum.create("parameterMin", "pn", om.MFnNumericData.kFloat, -1.0)
-
makeinput(anum)
-
aPMax = anum.create("parameterMax", "px", om.MFnNumericData.kFloat, 1.0)
-
makeinput(anum)
-
-
Formula_Curve.aParamRange = anum.create("parameterRange", "pr", aPMin, aPMax)
-
makeinput(anum)
-
-
expression = "$X = $P;\n"
-
expression += "$Y = sind($P*360);\n"
-
expression += "$Z = cosd($P*360);\n"
-
defStr = defStrData.create(expression)
-
Formula_Curve.aExpression = atype.create("expression", "ex", om.MFnData.kString, defStr)
-
makeinput(atype)
-
-
helpStr = "Local Variables:\n"
-
helpStr += "\tfloat $K: current knot id, [0:spans]\n"
-
helpStr += "\tfloat $P: parameter per knot, [parameterMin:parameterMax]\n"
-
helpStr += "\tfloat $T: time attribute value\n"
-
helpStr += "\tfloat $N: number of spans\n"
-
helpStr += "\tfloat $X\\$Y\\$Z: current point coordinates\n"
-
-
defStr = defStrData.create(helpStr)
-
Formula_Curve.aHelpStr = atype.create("quickHelp", "qh", om.MFnData.kString, defStr)
-
atype.setStorable(0)
-
atype.setWritable(0)
-
atype.setKeyable(0)
-
-
Formula_Curve.aOutCurve = atype.create("outCurve", "ocv", om.MFnData.kNurbsCurve)
-
makeoutput(atype)
-
-
Formula_Curve.addAttribute(Formula_Curve.aTime)
-
Formula_Curve.addAttribute(Formula_Curve.aNumSpans)
-
Formula_Curve.addAttribute(Formula_Curve.aDegree)
-
Formula_Curve.addAttribute(Formula_Curve.aForm)
-
Formula_Curve.addAttribute(Formula_Curve.aParamRange)
-
Formula_Curve.addAttribute(Formula_Curve.aExpression)
-
Formula_Curve.addAttribute(Formula_Curve.aHelpStr)
-
Formula_Curve.addAttribute(Formula_Curve.aOutCurve)
-
-
Formula_Curve.attributeAffects(Formula_Curve.aTime, Formula_Curve.aOutCurve)
-
Formula_Curve.attributeAffects(Formula_Curve.aNumSpans, Formula_Curve.aOutCurve)
-
Formula_Curve.attributeAffects(Formula_Curve.aDegree, Formula_Curve.aOutCurve)
-
Formula_Curve.attributeAffects(Formula_Curve.aForm, Formula_Curve.aOutCurve)
-
Formula_Curve.attributeAffects(Formula_Curve.aParamRange, Formula_Curve.aOutCurve)
-
Formula_Curve.attributeAffects(Formula_Curve.aExpression, Formula_Curve.aOutCurve)
-
-
#return om.MStatus.kSuccess
-
return 0
-
-
def initializePlugin(obj):
-
plugin = ompx.MFnPlugin(obj, nodeAuthor, nodeVersion, nodeApi)
-
try:
-
om.MGlobal.executeCommand(Formula_Curve.AETemplate(nodeName))
-
plugin.registerNode(nodeName, nodeID, Formula_Curve.createNode, Formula_Curve.initializeNode)
-
except Exception as msg:
-
sys.stdout.write("%s Failed\n" % nodeName)
-
print '\n%s' % msg
-
-
def uninitializePlugin(obj):
-
plugin = ompx.MFnPlugin(obj)
-
try:
-
plugin.deregisterNode(nodeID)
-
except:
-
sys.stdout.write("%s Failed on exit\n" % nodeName)