Notifications
Clear all

[Closed] All group members

no… it works just for a specific case. let’s change the combination:

delete objects
(
	c0 = box name:"c0" pos:[40,40,0] wirecolor:orange
	c1 = box name:"c1" pos:[40,80,40] wirecolor:orange
	c2 = box name:"c2" pos:[40,80,0] wirecolor:orange

	b0 = box name:"b0" pos:[40,0,0] wirecolor:orange
	b1 = box name:"b1" pos:[80,0,0] wirecolor:orange


	b2 = box name:"b2" pos:[40,40,0] wirecolor:green
	b3 = box name:"b3" pos:[80,40,0] wirecolor:green

	g4 = group #(c1,c2) name:"g4"
	g0 = group #(b0,b1)	name:"g0" 
	g4.parent = b0
	
	g1 = group #(b2,b3,g0) name:"g1" 
	g2 = group #(c0, g1) name:"g2" 
	
	in b0 (box name:"d0" pos:[0,0,80] wirecolor:blue)
	in g0 (box name:"d1" pos:[0,0,120] wirecolor:blue)
	
	a0 = box name:"a0" pos:[0,40,80]
	a1 = box name:"a1" pos:[0,80,80]
	g3 = group #(a0,a1) name:"g3"  
	g3.parent = g2
	
	for g in #(g0,g1,g2,g3,g4) do setGroupOpen g on
)

here are right members for “g2” and yours. yours is wrong.

also opening and closing groups shouldn’t be used in method. it’s always better to not change scene state if it’s not necessary.

delete objects
 (
 	fn getClRootGroupHead node = if node != undefined do
 	(
 		with undo on
 		(	
 			if isgroupmember node then
 			(
 				if isOpenGroupHead node.parent then 
 				(	
 					node.parent
 				)	
 				else	
 					getClRootGroupHead node.parent
 			)
 			else node
 		)
 	)
 	
 	fn getRootGroupHead node = if node != undefined do
 	(
 		if isgroupmember node then
 		(
 			getRootGroupHead node.parent
 		)
 		else node
 	)
 	
 	fn findRealGroupMembers allmembers node = 
 	(
 		real_group_members = #()
 		for s in allmembers do
 			if (getRootGroupHead s) == node and (not isgrouphead s) do
 		appendIfUnique real_group_members s
 		print real_group_members
 		select real_group_members
 	)		
 	
 	
 	c0 = box name:"c0" pos:[40,40,0] wirecolor:orange
 	c1 = box name:"c1" pos:[40,80,40] wirecolor:orange
 	c2 = box name:"c2" pos:[40,80,0] wirecolor:orange
 
 	b0 = box name:"b0" pos:[40,0,0] wirecolor:orange
 	b1 = box name:"b1" pos:[80,0,0] wirecolor:orange
 
 
 	b2 = box name:"b2" pos:[40,40,0] wirecolor:green
 	b3 = box name:"b3" pos:[80,40,0] wirecolor:green
 
 	g4 = group #(c1,c2) name:"g4"
 	g0 = group #(b0,b1)	name:"g0" 
 	g4.parent = b0
 	
 	g1 = group #(b2,b3,g0) name:"g1" 
 	g2 = group #(c0, g1) name:"g2" 
 	
 	in b0 (box name:"d0" pos:[0,0,80] wirecolor:blue)
 	in g0 (box name:"d1" pos:[0,0,120] wirecolor:blue)
 	
 	a0 = box name:"a0" pos:[0,40,80]
 	a1 = box name:"a1" pos:[0,80,80]
 	g3 = group #(a0,a1) name:"g3"  
 	g3.parent = g2
 	
 	for g in #(g0,g1,g2,g3,g4) do setGroupOpen g on
 	
 	clearlistener()
 	allmembers = join #() (getClRootGroupHead g2) 
 
 	
 	findRealGroupMembers allmembers (getClRootGroupHead g2) 
 )

it’s very close to the right… but g1 and g0 are members too.

and there is a way to do it without recursion which is faster

it’s not working for every case… for example a new setup, but the same task – “all real members of g2”:

(
 	 f0 = box name:"f0" pos:[80,40,0] wirecolor:orange
 	 in f0 (f1 = box name:"f1" pos:[80,80,40] wirecolor:orange)
 	 in f1 (f2 = box name:"f2" pos:[80,80,0] wirecolor:orange)
 	 
 	 c0 = box name:"c0" pos:[40,40,0] wirecolor:orange
 	 c1 = box name:"c1" pos:[40,80,40] wirecolor:orange
 	 c2 = box name:"c2" pos:[40,80,0] wirecolor:orange
  
 	 b0 = box name:"b0" pos:[40,0,0] wirecolor:orange
 	 b1 = box name:"b1" pos:[80,0,0] wirecolor:orange
  
  
 	 b2 = box name:"b2" pos:[40,40,0] wirecolor:green
 	 b3 = box name:"b3" pos:[80,40,0] wirecolor:green
  
 	 g4 = group #(c1,c2) name:"g4"
 	 g0 = group #(b0,b1)	name:"g0" 
 	 g4.parent = b0
 	 
 	 g1 = group #(b2,b3,g0) name:"g1" 
 	 g2 = group #(c0, g1) name:"g2" 
 	 
 	 in b0 (box name:"d0" pos:[0,0,80] wirecolor:blue)
 	 in g0 (box name:"d1" pos:[0,0,120] wirecolor:blue)
 	 
 	 a0 = box name:"a0" pos:[0,40,80]
 	 a1 = box name:"a1" pos:[0,80,80]
 	 g3 = group #(a0,a1) name:"g3"  
 	 g3.parent = g2
 	 
 	g5 = group #(f0,f1,f2,g2) name:"g5"
 	
 	 for g in #(g0,g1,g2,g3,g4,g5) do setGroupOpen g on
 )

this is right members:

delete objects
(
	fn getClRootGroupHead node = if node != undefined do
	(
		with undo on
		(	
			if isgroupmember node then
			(
				if isOpenGroupHead node.parent then 
				(	
					node.parent
				)	
				else	
					getClRootGroupHead node.parent
			)
			else node
		)
	)
	
	fn getRootGroupHead node = if node != undefined do
	(
		if isgroupmember node then
		(
			getRootGroupHead node.parent
		)
		else node
	)
	
	fn findRealGroupMembers node = 
	(
		allmembers = join #() node
		real_group_members = for s in allmembers where (getRootGroupHead s) == node and (not isgrouphead s) collect s
		return real_group_members
	)		
	
	
	c0 = box name:"c0" pos:[40,40,0] wirecolor:orange
	c1 = box name:"c1" pos:[40,80,40] wirecolor:orange
	c2 = box name:"c2" pos:[40,80,0] wirecolor:orange

	b0 = box name:"b0" pos:[40,0,0] wirecolor:orange
	b1 = box name:"b1" pos:[80,0,0] wirecolor:orange


	b2 = box name:"b2" pos:[40,40,0] wirecolor:green
	b3 = box name:"b3" pos:[80,40,0] wirecolor:green

	g4 = group #(c1,c2) name:"g4"
	g0 = group #(b0,b1)	name:"g0" 
	g4.parent = b0
	
	g1 = group #(b2,b3,g0) name:"g1" 
	g2 = group #(c0, g1) name:"g2" 
	
	in b0 (box name:"d0" pos:[0,0,80] wirecolor:blue)
	in g0 (box name:"d1" pos:[0,0,120] wirecolor:blue)
	
	a0 = box name:"a0" pos:[0,40,80]
	a1 = box name:"a1" pos:[0,80,80]
	g3 = group #(a0,a1) name:"g3"  
	g3.parent = g2
	
	for g in #(g0,g1,g2,g3,g4) do setGroupOpen g on
	
	
	
	clearlistener()
	select (findRealGroupMembers (getClRootGroupHead g2))
	print (findRealGroupMembers (getClRootGroupHead g2))
)

in my case, I need only objects, not grouphead, but if it’s needed then just exclude

and (not isgrouphead s)

Denis, for my situation, I need all members from inside last closed top group, that’s why

print (getClRootGroupHead g2)
is giving $Dummy:g5 and it’s selecting members of g5 as well.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

the situation might change some day it’s always good to have a universal solution.

fn isGroupHeadMember head node act:off = 
(
	while isvalidnode node and isgroupmember node and not (act = (node.parent == head)) do node = node.parent
	act
)
fn getAllGroupMembers head = if isgrouphead head do
(
	for node in (join #() head) where isGroupHeadMember head node collect node
)
select (getAllGroupMembers $g2)

So short, and so NICE!
Thank you, Denis! This is really useful!

Page 2 / 2