[Closed] Need help optimizing speed in a treeView control
Hi all,
I am trying to mimick the Outliner from Maya.
So far, I have it working … (kind of…)
But i have an speed issue with a funtion that would return all the children of a given treeNode.
the idea beeing:
- click on a TreeView Node
- get all the Treeview children of that node
- match the Scene objects
- select them
How would you write such a function:
fn getTVChildren TV theNode = (…)
so far I have it working using 2 functions and a local array variable
local TVchildren --
fn getTVFirstChildren tv theNode = -- get the direct children of a TV node
(
local Children=#()
if theNode.children>0 do
(
Children=for n in tv.nodes where (n.parent != undefined and n.parent.index==theNode.index) collect n
)
return Children
)
-- recursive funtion to get all the children from an TV node array into the TVchildren array
-- Note: MUST clear the TVchildren array before the call !!!
fn walkChildren tv arrayChildren =
(
for i = 1 to arrayChildren.count do
(
append TVchildren arrayChildren[i]
walkChildren tv (getTVFirstChildren tv arrayChildren[i])
)
)
then I call the functions from a NodeClick handler:
-- Left click Handler
on tv nodeClick theNode do
(
sel=#() -- clear the selection
TVchildren = #()
TVCursel = theNode.index
if theNode.children>0 do
(
theChildren = getTVChildren tv theNode -- get direct children
walkChildren tv theChildren -- get all children from the direct children
-- Nodes = for o in objects collect o
-- .tag property stores the index of the object from the Nodes array
sel = for Node in TVchildren collect Nodes[Node.tag]
)
append sel Nodes[theNode.tag] -- add the clicked Node itself
select sel -- Select the items
)
This works But is Very slow (testing with 2 biped objects) since all nodes are looped for each children…
Isn’t there a predefined function to get all the children (and the children’s children) from a Node ?
Thanks in advance for any input.
You may have already seen that there is a “how to develop a scene browser using Treeview Active X control” in the Maxscript help.
It also uses a function to recursively get children.
Hi,
The How-to example has a function to recursively ADD Scene Nodes to a tree: AddChildren
What I am looking for is a better way to implement a ‘GetTreeviewChildren’ function
I know how to get the all children from a SCENE node, but more complex is to get
all the children from a TREEVIEW node.
also I don’t have a ROOT node:
+ROOT
+item1
item2
+item3
and what i have (want) is this:
+item1
item2
+item3
or else, is there a way to hide the Root Node in a treeview ?
Try something like this
fn GetChildren node =
(
if ( node != undefined ) do
(
if(node.children>0) then
(
--Now get children (if any)
local currentNode = node.Child
for i=1 to node.children do
(
--Recurse on the current child
GetChildren currentNode
--Move to the next child
currentNode = currentNode.next
)
)
else
(
return node
)
)
)
Have a look at this thread on the 3dbuzz forum where i have implemented something similar to what you are doing.
http://www.3dbuzz.com/vbforum/showthread.php?t=137957&page=2
Hope this helps
Mobeen
Hi,
Thanks for the tip mobeen, very usefull !
But, the ‘getchildren’ function does not return anything unless ‘node’ has no children
if ‘node” has 1 or more children it return ‘OK’
so I modified it slighly to add the current child to an external array:
fn GetTVchildren node =
(
if(node.children>0) do
(
--Now get children (if any)
local currentNode = node.Child
for i=1 to node.children do
(
append TVchildren currentNode -- add the child to the array
GetTVchildren currentNode --Recurse on the current child
currentNode = currentNode.next --Move to the next child
)
)
)
Works a treat, and WAY faster than the previous code !!!
Thx again
But, is there a way to avoid using an external array, and have the function return an array of the children ?
Maybe this could help. It’s not related to TV nodes but shows how to gather node’s children without using an external array:
fn getNodeChildren node = (
local children = #()
if node.children.count > 0 do (
for child in node.children do (
append children child
join children (getNodeChildren child)
)
)
return children
)
Yeah i already have this function to get SCENE nodes
but for Treeview, the .children property returns the number of children, not the children themselves…
but using an external works great !
I was just thinking of a way to avoid external array.
Also, while i’m at it, i am trying to hack the fact the treeview does not allow multiple selection by changing the backcolor property…
I have implemented drag and drop functionality, and it works well, but when trying to implement the ‘shift-click’ handler (like selecting files in Windows explorer) , i have a problem retreiving the index of the nodes.
- store the index of a clicked note in a ‘clickedNode’ variable
- when shift click another node, check for the ‘clickedNode’ variable and store the index in 2. ‘shiftClickedNode’ variable
- retreive all nodes from the ‘clickedNode’ to the ‘shiftClickedNode’
But the prob i am facing is that the indices of the nodes in the treeview are not linear:
node1 may not have index 1, node2 may not have index2 etc …
so for example:
click node4 – (index 15)
shift click node 10 ( index 3)
how can I get the indices of the nodes DISPLAYED beween those 2 ?
this seams very hard (for me)
Any ideas ??