Combine selection lists from different functions into one

I’m trying to combine a list of objects into one and I’m having a rough time understanding how to accomplish this since I’m new to this.

I have three functions in a Chain_select class; each create a list containing objects I’ve selected in the viewport. List 1 (Fks) contains three items corresponding to my shoulder, elbow and wrist fk controls. List 2 (ikw) and list 3 (ikpv)contain only one object each, for my ik wrist and pole vector control

For now what I want to happen is when I press a button in my ui, I want a list to be created containing all the previous items in a flattened list. verified by having the list printed in the output.

As stated before, I believe I have the first part figured out. The functions below make my three lists. but please correct me if I’m wrong:

class Chain_Selection():
    def selectJointLAFK():
        Fks = []
        Fks.clear()
        if cmds.ls(selection = True,type=("transform",'nurbsCurve')):
            sel = cmds.ls(sl=True)
            fkCtrls = cmds.listRelatives(sel, allDescendents=True, type=("transform",'nurbsCurve'))
            Fks = [nurbsCurve for nurbsCurve in fkCtrls if nurbsCurve.startswith('FK') & nurbsCurve.endswith('Ctrl')]
            cmds.textFieldButtonGrp(gtF0, edit = True, tx ='' .join(sel),buttonLabel='IK OK',backgroundColor = (.5,.8,.2))
            del Fks[1]
            del Fks[2]
            Fks.extend(sel)
            
            print Fks[0]
            print Fks[1]
            print Fks[2]

        else:
            text = cmds.confirmDialog( title='Error', message='Must select joint', button=['OK'], defaultButton='Ok', dismissString='No' )


    def selectJointLwristIK():
        ikw = []
        ikw.clear()
        if cmds.ls(selection = True,type=("transform",'nurbsCurve')):
            ikwrist=cmds.ls(selection = True)
            ikw = [nurbsCurve for nurbsCurve in ikwrist if nurbsCurve.startswith('IK') & nurbsCurve.endswith('Ctrl')]
            cmds.textFieldButtonGrp(gtF1, edit = True, tx ='' .join(ikwrist),buttonLabel='IK OK',backgroundColor = (.5,.8,.2))

        else:
            text = cmds.confirmDialog( title='Error', message='Must select joint', button=['OK'], defaultButton='Ok', dismissString='No' )

    def selectJointLelbowIK():
        ikpv = []
        ikpc.clear()
        if cmds.ls(selection = True,type=("transform",'nurbsCurve')):
            ikPvsel = cmds.ls(selection = True)
            ikpv = [locator for locator in ikPvsel if locator.startswith('IK') & locator.endswith('Ctrl')]
            cmds.textFieldButtonGrp(gtF2, edit = True, tx ='' .join(ikPvsel),buttonLabel='IK OK',backgroundColor = (.5,.8,.2))        
            print ikpv
        else:
            text = cmds.confirmDialog( title='Error', message='Must select joint', button=['OK'], defaultButton='Ok', dismissString='No' )


The part I don’t understand is getting these lists into my other function in a different class. I’ve tried different things but I’m not getting it obviously. I know this is wrong but here is what I last had

class Combined_Selection():
    
    @staticmethod
    def __init__(self,*arg):
        combined_selection=[]
    @staticmethod    
    def combine_lists():
        self.Fks = Chain_Selection.selectJointLAFK(Fks)
        self.ikw = Chain_Selection.selectJointLwristIK(ikw)
        self.ikpv = Chain_Selection.selectJointLelbowIK(ikpv)
        self.combined_selection.append(Fks,ikw,ikpv)
        
        print combined_Selection

This is for my button to call the function:

cmds.button(label='Test 1', command = '', width=100)
cmds.button(label='Combine',  command = Combined_Selection, width=100)
cmds.setParent('..')
cmds.separator(h=5, style = 'none')
cmds.separator(h=5)

any help would be greatly appreciated

Currently your Combined_Selection class doesn’t look like it needs to be a class at all.
(Unless it has to do anything other than what’s shown in the example)

So if all you want to do is get a combined list from Chain_Selection, you can get away with a simple function.

def combine_lists():

    sel = Chain_Selection()
    
    Fks = sel.selectJointLAFK()
    ikw = sel.selectJointLwristIK()
    ikpv = sel.selectJointLelbowIK()

    return [Fks, ikw, ikpv]

Even shorter would be doing that as a method in Chain_selection.

def combine_lists(self):    

    Fks = self.selectJointLAFK()
    ikw = self.selectJointLwristIK()
    ikpv = self.selectJointLelbowIK()

    return [Fks, ikw, ikpv]
1 Like

Thank you soo much!

My reasoning for wanting to use this as a method in a different class was that eventually I wanted the list to be used by a function that moves my controls by first taking the combined Fks, ikw, & ikpv lists. I was think that by using a class, I wouldn’t have to create additional code for the right AND left arms…or however many arms I have since it would create a new instance on selection every time I called it?

I’m hoping I had the right idea, if it doesn’t make sense let me know

sort of like

combined_list_selections(from combine_lists ) = work_with_this_list

#assign selection
fkWrist = work_with_this_list[0]
fkShldr = work_with_this_list[1]
fkuElbow = work_with_this_list[2]
ikwrist = work_with_this_list[3]
ikpv = work_with_this_list[4]


# move controls around
...

So I thought it would be best to have that in a different class. well I would rename the class to snap or something more appropriate

Hi @hanaharu,

I’m going to link some sites on classes for you - theres a general rule that you only really need classes if your manipulating state. And most of the time module functions should suffice.

You’re treating the class method that initializes the bound instance of the class as a staticMethod, a method that neither needs a pointer to the class or the instance. (Essentially a module function that can be called by the instance/class) This means your making self an argument you have to pass.

The __init__ method is crucially used to instantiate the class, binding it to a variable - it can do anything but should not return anything. It’s there to create variables that live with the instance of the class and not the class itself.

Inversely you’re combine_list method, defined as a staticMethod, is referring to the class’s instance self, but because it’s defined as a staticMethod, self is out of scope and not being passed as an argument. Which in this case would be an instance of the class.

Im cleaning up this code a little - I’m not sure your using PEP8 compatibility tools, but this should suffice:

class CombinedSelection(object):  #CamelCase for class names - new style classes inherit from object -ignore if python3.

   def __init__(self, *args): # Made 'arg' args instead.

       self.combined_selection = list() # Made your list a literal.
   
   def combine(self): # Pointer to the class instance as it refers to instance variables.

      fk_joints = self.select_joints_left_afk() # Clear variable names - lowercase methods with _.
      # ...


1 Like

O wow I see! Thank you very much for your explanation! Looks as though I was completely misunderstanding quite a bit. I’m going to read and work through the links you provided.