Searching For Multiple Nodes

Is it possible to search the scenegraph for multiple node names and return a NodePathCollection? I understand I can loop through the target node names and search for them individually, but I am trying to avoid looping.

I stand to be corrected, but looking at the manual, I don’t think that there is such a feature, no.

Unless, of course, all of the desired node-names can be reduced to a common pattern unique to them. In which case, the fact that the “findAllMatches” method will accept pattern-elements such as wildcards might work for you.

For example, let’s say that you have a scene-hierarchy that includes the nodes “ob”, “obj1”, “obj2”.

Then the following search:
rootNode.findAllMatches("**/obj*")
Should return a NodePathCollection containing “obj1” and “obj2”–but not “ob”.

While the following search:
rootNode.findAllMatches("**/ob*")
Should return all of “ob”, “obj1”, and “obj2”.

See the manual for a more-detailed discussion of the sorts of pattern that the “find” functions will accept.

Naturally, if your various desired node-names don’t reduce to such a pattern, then this may not be viable.

I’m curious, if I may: Why are you trying to avoid looping?

Thank you @Thaumaturge.

Unfortunately, the node names cannot be reduced to a common pattern. Each node name is unique and arbitrary, as provided by the user.

I am trying to avoid looping because it becomes very slow. I’m not sure of the time complexity of the find() method, but assuming it’s O(n), if I want to search for k items, the total time complexity will be O(kn). I was hoping to find a similar method that can accept a list instead. Such a method would have a time complexity of O(k + n), which would be much better.

How many names do you expect to have, that you anticipate the complexity becoming a problem…?

As to a version of “find” that takes a list… honestly, if such a thing were available, I wouldn’t be surprised if it were internally implemented by iterative looping. (I’m honestly not sure of how else it would work–but I may well be missing an approach.) There might be some advantage from the looping occurring on the C++ side, I suppose.

There are a lot of nodes, in the thousands. They are not part of what is rendered, so there is no issue with the GPU.

If such a function were implemented, it would build a hashmap of the supplied list. For k items, this would be an O(k) process. As it traverses the nodepath, it would check if any of the node names are in the hashmap. Since hashmaps have a lookup cost of O(1), this would be very fast. The total cost would then be O(n+k). That plus the advantage of performing the operation on the C++ side would make the whole process efficient.

Hmm, fair.

I’d still suggest just doing it the naive way at first anyway–if you haven’t already–as it may turn out that the naive way is “fast enough”.

Okay, that’s a good point.

Well, in that case, I’d suggest posting an issue on the GitHub issues page requesting this be added as a new feature. :slight_smile:

(Don’t mistake me: the suggestion stands of trying the naive way for your current application.)

I have already tried it and observed how it behaves as the number of nodes increases, it becomes noticeably slow on my relatively good hardware. I will try getting all the children and filtering them myself. If that doesn’t work, I will consider requesting a feature.

Thanks a lot!

Fair enough! Good luck!

(And for what it’s worth, I’d still suggest requesting a feature whether your new approach works or not: even if it’s not required for your application, it might serve someone else in the future.)

Thanks and well noted!

1 Like