Start a new topic

combine (switch) nodes script

I have several switches that I would like to combine, each with ~80 children.  I'd like one of the selected switches to be a 'root' or parent, and each child of the other switches get re-located to become a child of the corresponding node on the root or parent.


Combine node search came back with nothing useful (I did not look past the first few seemingly off topic returns).


Was hoping someone already had a script to do this, or something similar.


Thx


Do you have complicated masks set up in the switches?

nope.  if masks there are, they are simply one per node.

If masks are not important, you can simply reparent the switch nodes you want to remove under the switch node you want to be the only remaining switch and use the delete level command found in the hierarchy toolbox. This will delete all the selected switch nodes and reparent their children to the switch node parent. Wow, that sounds more complicated than it is. Let me know if you were able to decipher that!

I understand the logic, thx

As Chris suggests, the Delete Level will reparent the Switch children to the parent switch. The previous masks of the parent switch will be right but the masks of the deleted level switch will have to be rebuilt on the parent switch.

I was thinking there had to be a better/faster way, but it seems not without some effort on the script front.

I can do re-parenting manually (carefully) and have 99% confidence that things are right, but If I put a switch under the parent and delete level, things get messy.  Too many children.


Thanks for checking in though!

About masks... Are your masks set up very simply like this, for example?
Mask 1 turns on child 1 only, all others off
Mask 2 turns on child 2 only, all others off
...
Mask N turns on child N only, all others off

If this is how you set up your masks, you can use the following script to set your masks after you fiddle with the children of your switches. Select the switch you want to setup and then run the script. It will:

Delete all the masks of the switch
Create a new mask (one for each child of the switch)
For each mask (one for each child) turn ON that child and turn OFF all the other children.


def DeleteAllMasks(switch):
	numMasks = mgGetSwitchMaskCount(switch)
	for i in range(0,numMasks):
		b = mgDeleteSwitchMask(switch, 0)

def SetSimpleSwitchMasks(switch):
	numChildren = mgCountChild(switch)
	# there will always be one mask
	for i in range(0,numChildren-1):	
		mgAddSwitchMask(switch)
	numMasks = mgGetSwitchMaskCount(switch)
	print numMasks,numChildren
	for i in range(0,numMasks):
		mgInitSwitchMask(switch, i, MG_FALSE)
		mgSetSwitchBit(switch, i, i, MG_TRUE)
	
db = mgGetCurrentDb ()
selectList = mgGetSelectList (db)
rec,m = mgGetNextRecInList (selectList)
if (rec is None):
	mgSendMessage (MMSG_ERROR, "Nothing selected")
elif (mgGetCode(rec) != fltSwitch):
	mgSendMessage (MMSG_ERROR, "No Switch node selected")
else:
	name = mgGetName (rec)
	DeleteAllMasks(rec)
	SetSimpleSwitchMasks(rec)

  


Steve,


Thanks.


I'm going to butcher your script and see what I come up with.  If there's no radioactive cloud I may post it.

 OK, some radiation.  Had the loop working briefly, now it's too short by 1.

Also have the break coded in b/c, well, once the script editor goes off the rails, bye-bye creator.

db = mgGetCurrentDb()
selectList = mgGetSelectList (db)

rec,m = mgGetNextRecInList (selectList)
num_recs = mgGetRecListCount (selectList)

if (rec is None):
    mgSendMessage (MMSG_ERROR, "Nothing selected")
elif (mgGetCode(rec) != fltSwitch):
    mgSendMessage (MMSG_ERROR, "No Switch node selected")
elif num_recs < 2:
    mgSendMessage (MMSG_ERROR, "Only one Switch selected!")
else:
    count = 0
    for i in range (0, num_recs):
        count = count + 1
        rec,m = mgGetNextRecInList (selectList)
        mgSelectOne(rec)
        name = mgGetName (rec)
        print name, i
        if count > num_recs:
            break

 


OK.  This loop does not work:

 

db = mgGetCurrentDb()
selectList = mgGetSelectList (db)
num_recs = mgGetRecListCount (selectList)
rec,m = mgGetNextRecInList (selectList)

if (rec is None):
    mgSendMessage (MMSG_ERROR, "Nothing selected")
elif (mgGetCode(rec) != fltSwitch):
    mgSendMessage (MMSG_ERROR, "No Switch node selected")
elif num_recs < 2:
    mgSendMessage (MMSG_ERROR, "Only one Switch selected!")
else:
    print str(num_recs)
    for i in range (0, num_recs):

        rec,m = mgGetNextRecInList (selectList)
        mgSelectOne(rec)
        name = mgGetName (rec)
        print name, i

 

but this one does:

 

db = mgGetCurrentDb()
selectList = mgGetSelectList (db)
num = mgGetRecListCount (selectList)

if (num == 0):
    mgSendMessage (MMSG_ERROR, "Nothing selected")
else:
    mgDeselectAll(db)
    for i in range (0, num):
        rec,m = mgGetNextRecInList (selectList)
        mgSelectOne(rec)
        comment = mgGetComment (rec)
        name = mgGetName (rec)
        tmp_id = name[1:len(name)]
        id = tmp_id.split(' ')
        print ('ID: ', id)

        if comment:
            print ('Name: ', name, '\n', 'Comment: ', comment)
            tmp_new = comment.split(' ')
            tmp_new[2] = tmp_id
            print ('New comment? ', tmp_new)
            new_comment = ' '.join(str(x) for x in tmp_new)
            print (type(new_comment))

	    ok = mgSetComment (rec, new_comment)  

 Have tried with, without the mgDeselectAll line.  num_recs == 2; shouldn't the loop execute 2x?


This silly thing works:

 

blip = ['0','1']
for m in blip:
    print m

 


is it just me, or does everyone post a dummy comment to the forum to get their last post to show up, then delete that dummy comment?

OK, the loop works again.  Moving forward.

 

db = mgGetCurrentDb()
selectList = mgGetSelectList (db)

num_recs = mgGetRecListCount(selectList)

if (num_recs == 0):
    mgSendMessage (MMSG_ERROR, "Nothing selected")
elif num_recs < 2:
    mgSendMessage (MMSG_ERROR, "Only one Switch selected!")
else:
#elif (mgGetCode(rec) != fltSwitch):
#    mgSendMessage (MMSG_ERROR, "No Switch node selected")
    
    print num_recs
    for i in range (0, num_recs):
        rec,m = mgGetNextRecInList (selectList)
        mgSelectOne(rec)
        name = mgGetName (rec)
        print name, i

 


Hi Shawn, lots here... lets focus on your first script here. I'll address each of your separate scripts in separate responses so we can avoid confusion.

So in your first script, here are some comments/suggestions:


1) Line 4, you call 

rec,m = mgGetNextRecInList (selectList)

then later you loop through all the items. Effectively you are calling mgGetNextRecInList one too many times. Put another way, the first call to mgGetNextRecInList in your loop on line 17 will actually return the 2nd selected item since the call on line 4 ate the first one. 


2) There are several ways to fix this. The easiest way is to call mgResetRecInList after line 4 and before your first call to mgGetNextRecInList in your loop. Doing this will ensure that your first call to mgGetNextRecInList in your loop will return the first item in the list.


3) Minor suggestion... on line 18 you call mgSelectOne.That is not necessary since the rec is already selected.


4) A logic suggestion: you are only validating the first item in the select list as being a switch node, when perhaps you may want to validate each item in the select list to be a switch).

Looks like you figured it out. In your first script, you were calling mgGetNextRecInList once too many times. You were calling it for the first rec (on line 4) then when you called it again in your loop, that call would return the 2nd selected node, not the first. In later scripts you removed the first call to mgGetNextRecInList. Another way to fix this would have been to call mgResetRecList after your first call to mgGetNextRecInList but before the first call in your loop.


Another comment/suggestion: You are calling mgSelectOne to select the switch but it's already selected. No need for that.

Login to post a comment