How many times I find a bone affecting the weight in a selection of vertices

Hello everyone,

I’m back here again with perhaps a silly question on some simple coding I can’t get to fix at the moment.
Perhaps I will look at the code tonight and will realise how silly I was with this question eheheh

What I am trying to do is to store for a selection of vertices the bones’ weight affecting the selection and how many time each bone with a weight value greater than one is found along that selection. So then I can use this counter to divide and calculate the average of specific values. Among 5 vertices I might have left arm affecting just 4 of the vertices and chest just affecting 2.

So then for the average I can use the counter in this way :

averageWeights = (weight[0] + weight [n]) / number times found a specific bone with influence greater than 0.

Apart from getting this up and running would also love to modify it so then it’d also work with either a big selection or an additive one.

I’m not entirely sure but it looks like in maya 2010 I have different behaviour than in maya 2012…

This is my code attempt:

      
                skinValue = []
		skinBones = []
		skinpercen = []
		selection = []
		repeatingBones = []
		timesRepeating = []
		tolerance = 0.001
					
				
		selection = cmds.ls(sl=True)
					
								
		for vert in selection:
			listinf = cmds.skinCluster(vert,query=True,inf=True)
			for inf in listinf:
				skinpercen = cmds.skinPercent("skinCluster1",vert,transform = inf,query=True)
				if skinpercen > tolerance:
                                        repeatingBones.append(inf)                          # big list of all bones encountered through the loop to calculate later how many times each was found ??
					if not inf in skinBones:
						skinBones.append(inf)                       # the skin bone names to display
						skinValue.append(round(skinpercen,3))       # the values to display
			
							
		for repeatingB in repeatingBones:
			timesRepeating.append(repeatingBones.count(repeatingB))             # trying to check how many times for each bone ??
			
		
		for i in range (len(skinBones)):
			print skinBones[i] ,skinValue[i] , timesRepeating[i]                # printing all the info together for debugging 

please help lol :slight_smile:

Thanks a lot in advance as usual and hope this post will help other people too

Ok sorry I have a little correction regarding the selection. My bad, I didn’t add “fl = True” to the selection command therefore I was having a wrong size array as a start. Now after printing I just found out.
Still not sure if my logic will work but looks like it’s doing almost entirely what I need.
The last line as a print is just a test to see things nice and concatenated together but withing that piece of code just need to obtain the times each bone is found along my selection. That is what I am interested in… Nothing else…

Just going to correct the selection syntax in here in case it helps…

      
                skinValue = []
		skinBones = []
		skinpercen = []
		selection = []
		repeatingBones = []
		timesRepeating = []
		tolerance = 0.001
					
				
		selection = cmds.ls(sl=True,fl=True)
					
								
		for vert in selection:
			listinf = cmds.skinCluster(vert,query=True,inf=True)
			for inf in listinf:
				skinpercen = cmds.skinPercent("skinCluster1",vert,transform = inf,query=True)
				if skinpercen > tolerance:
                                        repeatingBones.append(inf)                          # big list of all bones encountered through the loop to calculate later how many times each was found ??
					if not inf in skinBones:
						skinBones.append(inf)                       # the skin bone names to display
						skinValue.append(round(skinpercen,3))       # the values to display
			
							
		for repeatingB in repeatingBones:
			timesRepeating.append(repeatingBones.count(repeatingB))             # trying to check how many times for each bone ??
			
		
		for i in range (len(skinBones)):
			print skinBones[i] , timesRepeating[i]                              # printing all the info together for debugging 

This time it feels like I’m speaking to myself LOL

Disclaimer: I’m a newb at this stuff, but here’s what I see:

You’re not actually tracking how many times the repeated bones are found in your code, just adding the bone to list w/out any additional info.

Try building 2 dictionaries using the actual bone names for keys: on dictionary for the number of times the bone is found, and another for the weight value.
(pseudo code):


boneCountDict={'bone1name':0,'bone2name':0,...'boneNname':0}
boneWeightDict={'bone1name':0,'bone2name':0,...'boneNname':0}

select verts
	for each vert
		list influences
			for each inf
				if infPercentValue >tolerance
					boneCountDict[inf]+=1
					#each time the bone is found the count increases
					boneWeightDict[inf]+=infPercentValue
					#each weight found will add to this value 
					

after all selected verts in this group verts are processed, iterate through one of the dictionaries and grab the values


	for inf in boneCountDict:
		count=boneCountDict[inf]#number of times found with weight >tolerance
		weight=boneWeightDict[inf]#sum of all weight values found
		print('average weight for'+inf+' is: '+weight/count)

of course you’ll have to reset all the dictionary values to 0 for each selection.

there is probably a way to dynamically build the dictionaries as you loop, but that’s beyond my infant skills.

just a guess, untested, no guarantees,etc…