[Closed] Pathname context
Hi,
I’ve got a problem with getting to some nodes in my scene through a hierarchy. Although I have the feeling it should be very basic I’m not getting there. I need to loop through a list of parent nodes and get a specific child (grand-grandchild actually) from that node. One condition is the children of each parent all have the same object names.
I’ve found this: http://help.autodesk.com/cloudhelp/2017/ENU/MAXScript-Help/files/GUID-715B1CA8-B27D-495B-964D-1826EAE7030C.htm which should be helpful. It lets me set a context before I start looking for the childnode. However, it doesn’t seem to work the way I expect it to.
(
--setup the test scene
delete helpers
for n = 0 to 9 do
(
local d = dummy name:("Parent" + n as string) pos:[n*15,0,0]
local p = point name:"ChildPoint" parent:d pos:d.pos size:5
)
local arr = $Parent* as array
for n = 1 to arr.count do
(
--try to get the child of the parent
in arr[n]
(
print $ChildPoint.parent.name
)
)
)
This example creates a number of parent and child objects. The children all have the same name. Then I loop over the parent objects and use the in-context to get the child by name. I expect it to give me the child from the object I’ve set the context to. but it just gives me the first child it finds in the entire scene.
Does anybody know how to use this context system properly or otherwise know an alternative?
Hello Klaas,
I may not understand the way you need to get the parents, but in your example you are actually looking in the parents array. What if you look into the children array? Does it work the way you need?
for j in $ChildPoint* do print j.parent.name
Hey Jorge,
yes, looping through the children is a possibility. But I’d like to get to the children through the parents. This means I loop over each parent and then try to get the child. But doing that with the in-context gets me the same child for all parents instead of the actual child of the parent I’ve set the context to.
I seems as is the in-context is completely ignored, or I’m using it wrongly of course.
This does not uses ‘context’ but gives you the first child for each parent. I guess it’s not what you are after?
for parent in $Parent* where (child = parent.children).count > 0 do
(
format "Parent:% Child:%
" parent.name child[1].name
)
for obj in node do ()
this is map context
in node ()
this is <in node> context where every created in object will be a child of the node.
this code doesn’t make sense. <in node> context you ask a $childnode which is any (usually the first) node in scene with this name
Ah,
I thought the <in node> context also applied to the pathname and acted like a kind of filter by only returning the nodes within that context.
From the 3dsMax help
The at level <node> and in <node> contexts set the specified node to be the effective root for any specified pathnames or scene objects created in the context.
Yes, but is also says “specified pathnames”.
And in that same help page, there’s an example at the end which hints at this functionality (in bold)
in $dummy
(
-- create automatically as children of $dummy:
sphere name:"ear1" pos:[10,10,10]
sphere name:"ear2" pos:[-10,10,10]
[B]scale $foo/* [1,1,2] --look for 'foo' as a child of $dummy[/B]
)
But, if there’s another possibility to get children of a specific parent I’d be happy to use it. Otherwise it’s back to looping through the parents again.
in example above two things are combined – in context and pathname
if you know parent’s name and this name unique you can use path to a child as $parentname/childname
Denis,
if it’s not too much to ask, could you make an example which loops over my example objects? I just don’t know how to create a pathname with a variable.
delete objects
dd = for k=1 to 10 collect (dummy name:(uniquename "parent") pos:(random -[100,100,100] [100,100,100]))
pp = for k=1 to 10 collect in dd[random 1 dd.count]
(
point name:"child" pos:(random -[100,100,100] [100,100,100])
)
gg = for k=1 to 10 collect in pp[random 1 pp.count]
(
point name:"grandchild" pos:(random -[100,100,100] [100,100,100])
)
-- nodeandallchildren = join #() <node>
for d in dd do format "parent:% children:%
" d.name (for obj in (join #() d) where obj != d collect obj.name)
for d in dd do
(
format "parent:% allchildren:%
" d.name ((execute ("$'" + d.name + "'/*")) as array)
)
for d in dd do
(
format "parent:% children:%
" d.name ((execute ("$'" + d.name + "'/child*")) as array)
)
for d in dd do
(
format "parent:% grandchildren:%
" d.name (execute (("$'" + d.name + "'/*/grandchild*")) as array)
)
for d in dd do
(
format "parent:% firstchild:%
" d.name (execute ("$'" + d.name + "'/child"))
)
the only way to make ‘pathname’ on-the-fly is make a string using object names and execute it.