Notifications
Clear all

[Closed] $…* = everything in scene????

I thought $…* = selection and its children and its childrens children, ect

Am I doing something wrong to get the current selected objects entire hierarchy?

or is this a bug with some versions of max?

18 Replies
1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

example

select $Box001/.../* 
--or
select $Box001...*

ok so I can’t use the current selection and get the children of it without specifying the node, so cant use $…* then right, also cant use something like
x = selection
select x…*
or
x = $
select x…*
or
x = selection as array
for i in x do i…*

or anything like that, we must put in the specific node, seems kind of silly for a maxscript but what do i know…

any other way? like

allthehierarchy = #()
for x in selection do
(
if x.children != undefined do
(
selectmore x.children
append allthehierarchy x.children
)
)

just trying to find a way to get all the children of the selected node.

You want to avoid selecting stuff in the viewport as that is slow.

You will need to use a recursive function to recurse down the hierarchy of children.

Something like this: (iv not got max on this machine so cant check if this is working)


(

	local childArr = #()

	fn getAllTheChildren obj = (

		for a in obj.children do (
			append childArr a
			getAllTheChildren a
		)
		
	)

	--this function will only work with one object selected, but can easily be changed to allow more
	getAllTheChildren $
	
	--array of all children
	print childArr

)

try this example

(
 clearlistener()
 -- this array in this cast , before function
 NodesHandles = #()
 NodesHyerarchy = #()
 function AppendRecursiveChildren parent level=
 (
 	append NodesHandles parent.handle
 	append NodesHyerarchy level
 	-- store handles integer is more memory friendly , if no children the recursive function exit
 	for child in parent.children do AppendRecursiveChildren child (level+1)
 )
 mainNodes = selection as array
 for main in mainNodes do AppendRecursiveChildren main 0
 -- for other methods you can utilize all numbers's array tools esample : makeuniquearray NodesHandles
-- but in this case you can't find duplicate
 
 for i=1 to NodesHandles.count do
 (
 	h = NodesHandles[i]
 	l = NodesHyerarchy[i]
 	format "[%]" (formattedprint h format:"04i") 
 	for j=1 to l do format "  "
 	format "%
" (maxops.getnodebyhandle h).name
 )
 
 clearSelection()
 for i=1 to NodesHandles.count do NodesHandles[i] = maxops.getnodebyhandle NodesHandles[i]
 select NodesHandles
 
 )

ahaha, post in simultaneous the same solution.

actually collect node handles is much more expensive than collect nodes:


  (
  	delete objects
  	for k=1 to 1000 do box()
  
  	t1 = timestamp()
  	m1 = heapfree
  	for k=1 to 1000 collect objects[k]
  	format "Collect Nodes	>> time:% memory:%
" (timestamp() - t1) (m1 - heapfree)	
  
  	t1 = timestamp()
  	m1 = heapfree
  	for k=1 to 1000 collect objects[k].inode.handle
  	format "Collect Handles	>> time:% memory:%
" (timestamp() - t1) (m1 - heapfree)
  )
  
1 Reply
(@johnwhile)
Joined: 11 months ago

Posts: 0

i made a script that manage a lot of nodes (1000-2000) and i see a difference passing elements of array as node, the first evaluation “thenode.handle” is slow but “maxops.getnodebyhandle handle” is more fast than using directly the node reference.
And using:

	  t1 = timestamp()
	  m1 = heapfree
	arr = dotnetobject "System.int32[]" 1000
	  for k=1 to 1000 do arr.setValue (objects[k].inode.handle) (k-1)
	  format "Build dotnet array	>> time:% memory:%
" (timestamp() - t1) (m1 - heapfree)

made this result :
Collect Nodes >> time:28 memory:192L
Collect Handles >> time:72 memory:272192L
Build dotnet array >> time:174 memory:80256L

so nodes are the best

You could use that approach, but would need to build a string and execute it. For example:

if selection.count == 1 do (
	nm = selection[1].name
	execute ("select $"+nm+"...*")
)

-Eric

Ok thanks very much all, I ended up using:


getselectionshierarchyarray = #()
if selection.count >= 1 do
(
	for x = 1 to selection.count do
	(
		nm = selection[x].name
		execute ("append getselectionshierarchyarray $"+nm+"...*")
	)
	for i in getselectionshierarchyarray do
	(
		print i
	)
)

based from pixelmonkeys code.

just wondering why does it work if its

execute ("append getselectionshierarchyarray $"+nm+"...*")

and not when its

append getselectionshierarchyarray $"+nm+"...*

srry just trying to understand execute a bit better, if someone could try to explain it to me i’d appreciate it.

2 Replies
(@pixel_monkey)
Joined: 11 months ago

Posts: 0

Execute takes a compiled string and runs it as direct maxscript code. So if you assume for simplicity sake selection[1] is $Sphere001 then the following is true:
nm = “Sphere001”
execute (“append getselectionshierarchyarray $”+nm+”…“) would become:
execute (“append getselectionshierarchyarray $”+“Sphere001”+”…
“) or:
[color=RoyalBlue]execute (“append getselectionshierarchyarray $Sphere001…“)[/color]
when run it would execute:
append getselectionshierarchyarray $Sphere001…

while:
append getselectionshierarchyarray $”+nm+”…* would become:
append getselectionshierarchyarray $”+“Sphere001”+”…* and error because of how it is laid out
append getselectionshierarchyarray $””+“Sphere001”+”…” would execute:
append getselectionshierarchyarray $”Sphere001…
“, which isn’t a valid object.

Hope that helps,
-Eric

(@opifex)
Joined: 11 months ago

Posts: 0

ok thanks that helps me understand a bit better, but I’m wondering why this dont work now


getselectionshierarchyarray = #()
if selection.count >= 1 do
(
	for x = 1 to selection.count do
	(
		nm = selection[x].name
		execute ("append getselectionshierarchyarray $"+nm+"...*")
	)
	for i in getselectionshierarchyarray do
	(
		print i.parent
	)
)

returns unknown property.

or even if i try to print the i.name instead of i.parent it returns the same error like they no longer have properties?

the access to INode interface takes a time and a memory use. It might be cheaper to collect and store Integers than Pointers to a node (but i’m not absolutely sure, probably in both cases it’s 4bytes in 32 system and 8bytes in 64). The difference might be if mxs integer is still stored as 4bytes value in 64 system. Well.

about the using of “dotnetobject “System.Int32[]”. It’s not more friendly than msx array if you only use it as a storage. It will be slower and will use more memory.

about inode.handle… the better way is to use Anim Handle. It works fast for both get and find by. see the mxs help AnimHandle system.

that’s what i told about…

Page 1 / 2