The issue I appear to be having is that when I run a code that uses the plusMinusAverage class more than once (in my case a for loop), the new instance of the class keeps references to the previous list of pmaDicts created by the previous plustMinusAverage creation and adds to the end of it.
Meaning (Code that results this is further down below)
things = []
for i in range(2):
thing[i] = plusMinusAverage(count3D=2)
print thing[i]
print thing[i].values3D
>>> (plusMinusAverage at 0x00NSTUFF1)
>>> [{"x":(attr.connection at 0x1234),"y":(attr.connection at 0x2345), etc..},
{"x":(attr.connection at 0x3456),"y":(attr.connection at 0x4567), etc..}]
>>> (plusMinusAverage at 0x00NSTUFF2)
>>> [{"x":(attr.connection at 0x1234),"y":(attr.connection at 0x2345), etc..},
{"x":(attr.connection at 0x3456),"y":(attr.connection at 0x4567), etc..},
{"x":(attr.connection at 0x5678),"y":(attr.connection at 0x6789), etc..},
{"x":(attr.connection at 0x7890),"y":(attr.connection at 0x8901), etc..}]
What gets me about this is that it appears to print out the object, but then the list appears to point to the original but with more entries. I don't get why the list would not be a unique one.
Sorry for the massive posting of code below, but I figured this issue has enough nuances that trying to make a simpler version would likely invite solutions that wouldn't work for my circumstance, and since I'm not certain where the issue lies exactly, I'm going to include all the pertinent parts where it might be going wrong. ..plus maybe someone who works in maya can use this to build their own shaderNode tools.
class Tracker2(object):
dag = ""
obj = ""
getTime = "current"
def setPathing(self):
if self.nodeName == None:
self.nodeName = cmds.createNode('transform')
cmds.addAttr(self.nodeName, sn="type", ln="type", dt="string")
cmds.setAttr(self.nodeName + ".type", type="string", keyable=0)
sel = om.MSelectionList()
sel.add(self.nodeName)
self.obj = om.MObject()
self.dag = om.MDagPath()
sel.getDependNode(0, self.obj)
try:
sel.getDagPath(0, self.dag)
except:
pass
def __init__(self):
if not self.dag and not self.obj:
self.setPathing()
def fullpath(self):
if self.dag and self.dag.fullPathName():
return self.dag.fullPathName()
return om.MFnDependencyNode(self.obj).name()
class shaderNode(Tracker2):
def __init__(self):
self.nodeName = cmds.shadingNode(self.type,au=1)
Tracker2.__init__(self)
class connection(object):
def __init__(self, attr, *args):
self.attr = attr
def __set__(self, instance, value):
if isinstance(value,basestring):
try:
cmds.connectAttr(value,instance.fullpath()+"."+self.attr,f=1)
except Exception as inst:
cmds.warning(inst)
elif not value:
temp = cmds.listConnections(instance.fullpath()+"."+self.attr,s=1,d=0)
if temp:
cmds.disconnectAttr(instance.fullpath()+"."+self.attr, temp[0])
else:
cmds.warning("Set Connection: Source attribute is non-string value | "+value)
def __get__(self, instance, owner):
tempIn = cmds.listConnections(instance.fullpath()+"."+self.attr,s=1,d=0)
tempIn = tempIn if tempIn else []
tempOut = cmds.listConnections(instance.fullpath()+"."+self.attr,s=0,d=1)
tempOut = tempOut if tempOut else []
#returns list of [[incoming] , [outgoing]]
return [tempIn,tempOut]
In separate py file where class containing connection is loaded as attr
class pmaDict(dict):
def __init__(self,instance,*args,**kwargs):
self.instance = instance
dict.__init__(self,*args,**kwargs)
def __getitem__(self, key):
thing = dict.__getitem__(self,key)
if key in self and isinstance(dict.__getitem__(self, key),attr.Attribute):
return thing.__get__(self.instance,None)
if key in self and isinstance(dict.__getitem__(self,key),attr.connection):
return thing.__get__(self.instance,None)
else:
return dict.__getitem__(self,key)
def __setitem__(self, key, value):
thing = dict.__getitem__(self,key)
if key in self and isinstance(dict.__getitem__(self,key),attr.Attribute):
thing.__set__(self.instance,value)
elif key in self and isinstance(dict.__getitem__(self,key),attr.connection):
thing.__set__(self.instance, value)
else:
dict.__setitem__(self,key,value)
class plusMinusAvg(attr.shaderNode):
type = "plusMinusAverage"
values1D = []
values2D = []
values3D = []
def addInput1D(self):
i = len(self.values1D)
print self
cmds.setAttr(self.fullpath() + ".input1D[" + str(i) + "]", 0)
newInput = pmaDict(self,
{"x": attr.Attribute("input1D[" + str(i) + "]", "float"),
"x_con": attr.connection("input1D[" + str(i) + "]")})
self.values1D.append(newInput)
def addInput2D(self):
i = len(self.values2D)
print self
cmds.setAttr(self.fullpath() + ".input2D[" + str(i) + "]", 0, 0, type="double2")
newInput = pmaDict(self,
{"xy": attr.Attribute("input2D[" + str(i) + "]", "float"),
"x": attr.Attribute("input2D[" + str(i) + "].input2Dx", "float"),
"y": attr.Attribute("input2D[" + str(i) + "].input2Dy", "float"),
"xy_con": attr.connection("input2D[" + str(i) + "]"),
"x_con": attr.connection("input2D[" + str(i) + "].input2Dx"),
"y_con": attr.connection("input2D[" + str(i) + "].input2Dy")})
self.values2D.append(newInput)
def addInput3D(self):
i = len(self.values3D)
print self
cmds.setAttr(self.fullpath()+".input3D["+str(i)+"]",0,0,0, type="double3")
newInput = pmaDict(self,
{"xyz": attr.Attribute("input3D["+str(i)+"]","double3"),
"x": attr.Attribute("input3D["+str(i)+"].input3Dx","float"),
"y": attr.Attribute("input3D["+str(i)+"].input3Dy","float"),
"z": attr.Attribute("input3D["+str(i)+"].input3Dz","float"),
"xyz_con": attr.connection("input3D["+str(i)+"]"),
"x_con": attr.connection("input3D["+str(i)+"].input3Dx"),
"y_con": attr.connection("input3D["+str(i)+"].input3Dy"),
"z_con": attr.connection("input3D["+str(i)+"].input3Dz")})
self.values3D.append(newInput)
def __init__(self, count1D=0, count2D=0, count3D=0):
attr.shaderNode.__init__(self)
for i in range(count1D):
self.addInput1D()
for i in range(count2D):
self.addInput2D()
for i in range(count3D):
self.addInput3D()