So you could use the gradientControlNoAttr to get what you want like this
class AttractionProfileWindow():
# If your working on a UI it can be annoying to pass lots of variables
# between different functions. So it's often better to use a python class
# that contains the data and the functions.
def __init__(self):
# This is called when we first create the class
# self.x means the variable belongs to the class
# not just the function.
self.source_curve = None
self.getTheNurbsCurve()
if not self.source_curve:
return
self.createWindow()
def getTheNurbsCurve(self):
# Any function that belongs to a class should have "self"
# as the first input. This tells the function
# "you have access to all the variables" held by the class.
# Get the nurbs curve we will be using.
self.source_curve = cmds.ls(sl=True, dag=True, typ="nurbsCurve")
if not self.source_curve:
cmds.warning('No curve was selected')
return
else:
self.source_curve = self.source_curve[0]
# Check if the curve has "attractionProfile"
if not cmds.objExists(self.source_curve + '.attractionProfile'):
cmds.warning('{} is missing "attractionProfile"'.format(self.source_curve))
self.source_curve = None
def createWindow(self):
# Create the window
cmds.window( title='Gradient Control For OptionVar')
cmds.columnLayout()
# Add the ramp widget
cmds.gradientControlNoAttr(
'attractionProfile',
h = 120,
ck=0,
changeCommand = self.rampModified,
)
cmds.setParent( '..' )
self.setUpRamp()
# Add the other widgets
cmds.rowLayout(nc=3)
cmds.floatFieldGrp('posFieldRadius', pre=3, l="Selected Position", nf=1, v1=0.000, s=1.0, cw=(1, 70), changeCommand = self.posModified)
cmds.floatFieldGrp('valFieldRadius', pre=3, l="Selected Value", nf=1, v1=1.000, s=1.0, cw=(1, 70), changeCommand = self.valModified)
# Update these float sliders to show the value from the selected key
cmds.gradientControlNoAttr(
'attractionProfile',
e = True,
currentKeyChanged = self.currentKeyChanged,
)
self.currentKeyChanged('')
cmds.optionMenuGrp('interpMenuRadius', cw=(1, 50), l="Interpolation")
cmds.menuItem(l=" None ")
cmds.menuItem(l=" Linear ")
cmds.menuItem(l=" Smooth ")
cmds.menuItem(l=" Spline ")
cmds.setParent( '..' )
cmds.showWindow()
def currentKeyChanged(self, currentData):
currentIndex = cmds.gradientControlNoAttr('attractionProfile', q = True, currentKey = True)
if currentIndex == -1:
return
# Get the values for that key
currentData = cmds.gradientControlNoAttr('attractionProfile', q = True, asString = True)
if not currentData:
return
a = currentData.split(',')
posVal = float(a[currentIndex*3])
valVal = float(a[currentIndex*3+1])
# Update the two floatFields
cmds.floatFieldGrp('posFieldRadius', e = True, v =[posVal]*4)
cmds.floatFieldGrp('valFieldRadius', e = True, v =[valVal]*4)
def posModified(self, val):
# Change the position of the selected key
currentIndex = cmds.gradientControlNoAttr('attractionProfile', q = True, currentKey = True)
if currentIndex == -1:
return
currentData = cmds.gradientControlNoAttr('attractionProfile', q = True, asString = True)
a = currentData.split(',')
a[currentIndex*3+1] = str(val)
newData = ','.join(a)
currentData = cmds.gradientControlNoAttr('attractionProfile', e = True, asString = newData)
def valModified(self, val):
# Change the position of the selected key
currentIndex = cmds.gradientControlNoAttr('attractionProfile', q = True, currentKey = True)
if currentIndex == -1:
return
currentData = cmds.gradientControlNoAttr('attractionProfile', q = True, asString = True)
a = currentData.split(',')
a[currentIndex*3] = str(val)
newData = ','.join(a)
currentData = cmds.gradientControlNoAttr('attractionProfile', e = True, asString = newData)
def setUpRamp(self):
# This function will make the ramp in the UI match the existing values of the ramp curve
attributeData = []
for i in cmds.getAttr(self.source_curve + ".attractionProfile", mi = True) or []:
attributeData.append(cmds.getAttr("{}.attractionProfile[{}].attractionProfile_Position".format(self.source_curve, i)))
attributeData.append(cmds.getAttr("{}.attractionProfile[{}].attractionProfile_FloatValue".format(self.source_curve, i)))
attributeData.append(cmds.getAttr("{}.attractionProfile[{}].attractionProfile_Interp".format(self.source_curve, i)))
# Set the data
currentData = cmds.gradientControlNoAttr('attractionProfile', e = True, asString = str(attributeData))
def rampModified(self, gradient_data):
# Convert the gradient_data from a unicode (string) to a list
gradient_data = gradient_data.split(',')# Split the string up
# We will convert each element from a string to a float or int
data_list = []
for i,s in enumerate(gradient_data):
# If the elements index is a multiple of 3
# we want it to be an int
# since every third element represents the interpolation
# we check for this by using modular arithmetic (the % sysmbol)
if (i+1)%3 == 0:
data_list.append(float(s))
else:
data_list.append(float(s))
# Then we will split up the data into chunks of 3
# so instead of having 1 list of data, we have a list of lists
# where each element contains all the data for a specific cv
attraction_profile = []
for i in range(len(data_list)/3):
attraction_profile.append(data_list[i*3:(i*3)+3])
# Do whatever it is you were doing with that data
# THIS WILL AFFECT ALL THE CURVES NOT JUST THE ONE YOU
# SELECTED WHEN YOU LAUNCHED THE WINDOW
for eachCurve in (cmds.ls(sl=True, dag=True, typ="nurbsCurve") or []) + [self.source_curve]:
for i in cmds.getAttr(eachCurve + ".attractionProfile", mi = True) or []:
cmds.removeMultiInstance("{}.attractionProfile[{}]".format(eachCurve, i), b=True)
for i, (pos, value, interp) in enumerate(attraction_profile):
cmds.setAttr("{}.attractionProfile[{}].attractionProfile_Position".format(eachCurve, i), pos)
cmds.setAttr("{}.attractionProfile[{}].attractionProfile_FloatValue".format(eachCurve, i), value)
cmds.setAttr("{}.attractionProfile[{}].attractionProfile_Interp".format(eachCurve, i), interp)
AttractionProfileWindow()
This code is mostly complete, except for setting the interpolation when you change the enum widget in the UI.
But what could be easier is using the gradientControl. The difference between the two is that the gradientControl gets linked to a specified attribute, and the gradientControlNoAttr does not (hence the NoAttr). Having them linked allows you to use undo and redo without messing up the UI but doesn't give you floatField for setting precise values. gradientControl only links to one attribute one one node you would need to use the "visbleChangeCommand" to update the attributes on the other selected curves but that's something that we already do in the code above.
That's a lot of info, so let me know if things don't make sense.
class AttractionProfileWindow():
# If your working on a UI it can be annoying to pass lots of variables
# between different functions. So it's often better to use a python class
# that contains the data and the functions.
def __init__(self):
# This is called when we first create the class
# self.x means the variable belongs to the class
# not just the function.
self.source_curve = None
self.getTheNurbsCurve()
if not self.source_curve:
return
self.createWindow()
def getTheNurbsCurve(self):
# Any function that belongs to a class should have "self"
# as the first input. This tells the function
# "you have access to all the variables" held by the class.
# Get the nurbs curve we will be using.
self.source_curve = cmds.ls(sl=True, dag=True, typ="nurbsCurve")
if not self.source_curve:
cmds.warning('No curve was selected')
else:
self.source_curve = self.source_curve[0]
# Check if the curve has "attractionProfile"
if not cmds.objExists(self.source_curve + '.attractionProfile'):
cmds.warning('{} is missing "attractionProfile"'.format(self.source_curve))
self.source_curve = None
def createWindow(self):
# Create the window
cmds.window( title='Gradient Control For OptionVar')
cmds.columnLayout()
# Add the ramp widget
cmds.gradientControl(
'attractionProfile',
h=120,
at='{}.attractionProfile'.format(self.source_curve)
)
cmds.setParent( '..' )
x = cmds.attrEnumOptionMenuGrp( l='Output Format',
at='defaultRenderGlobals.imageFormat',
ei=[(0, 'None'),(1, 'Linear'), (2, 'Smooth'),
(3, 'Spline')])
cmds.setParent( '..' )
cmds.gradientControl(
'attractionProfile',
e = True,
selectedInterpControl=x
)
cmds.showWindow()
def addAttributes(self):
cmds.addAttr(self.source_curve, ln = 'attractionProfile', nc = 3, at = 'compound', multi = True)
cmds.addAttr(self.source_curve, ln = 'attractionProfile_Position', at = 'float', parent = 'attractionProfile')
cmds.addAttr(self.source_curve, ln = 'attractionProfile_FloatValue', at = 'float', parent = 'attractionProfile')
cmds.addAttr(
self.source_curve,
ln = 'attractionProfile_Interp',
at = 'enum',
p = 'attractionProfile',
enumName = 'None:Linear:Smooth:Spline'
)
AttractionProfileWindow()