<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Recursive Function Problem in 3ds Max Programming Forum</title>
    <link>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226412#M19242</link>
    <description>@Steve - mine is failing.&lt;BR /&gt;&lt;BR /&gt;I'll ponder over you guy's input and see if I can adapt it. I'm probably making the script harder than it needs to be.&lt;BR /&gt;&lt;BR /&gt;thx</description>
    <pubDate>Fri, 04 Nov 2011 16:55:35 GMT</pubDate>
    <dc:creator>lee_j_keith</dc:creator>
    <dc:date>2011-11-04T16:55:35Z</dc:date>
    <item>
      <title>Recursive Function Problem</title>
      <link>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226407#M19237</link>
      <description>Hi,&lt;BR /&gt;&lt;BR /&gt;I have a function that calls itself in a for loop. That all works fine, except for the last loop. I'm looping through a hierarchy of dummy &amp;amp; mesh objects. I'm collapsing the mesh objects into a new mesh and then deleting the dummy nodes at the end of the collapsing operation. So on the first run of the function it calls itself, to handle the first node it finds in the for loop that has children. It appears that Maxscript does not finish executing the remainder of the function past this point, until every recursive iteration in the for loop has finished. That's Ok I guess. At the end of the function after this for loop, there is code that deletes the dummy objects that have been stored in an array. This block of code only needs to run after all of the recursive iterations are finished. The code block has an if statement that compares the number of iterations against the number of children the top level node has, and if they are equal, it executes the code. The problem is that this evaluates to true on the last iteration of the for loop, and so it executes, and then again once the original call to the function finishes executing. That is a problem, and I do not know how to resolve it. It's probably simple, and I don't see it because I've been staring at it all day, but if anyone has an idea let me know.&lt;BR /&gt;&lt;BR /&gt;Below is a skeleton of what I am attempting.&lt;BR /&gt;thx&lt;BR /&gt;&lt;BR /&gt;&lt;PRE&gt;function collapseSelectedDummy theNode =&lt;BR /&gt;(&lt;BR /&gt;for c in nodeChildren do&lt;BR /&gt;(&lt;BR /&gt;--here I'm processing the nodes.&lt;BR /&gt;--if it is a mesh it gets collapsed&lt;BR /&gt;--if it is a dummy node then it calls this function again&lt;BR /&gt;--I'm also keeping a tally of the nodes processed with the variable dummyChildrenProcessed&lt;BR /&gt;)&lt;BR /&gt;&lt;BR /&gt;--this code only needs to execute once, but it is getting called twice&lt;BR /&gt;--here I am deleting out the dummy nodes&lt;BR /&gt;--it compares the number of processed nodes against the number of children&lt;BR /&gt;--the selected scene node has&lt;BR /&gt;if dummyChildrenProcessed == selectedNodeNumChildren then&lt;BR /&gt;(&lt;BR /&gt;for i in dummiesToDelete do&lt;BR /&gt;(&lt;BR /&gt;delete i&lt;BR /&gt;)&lt;BR /&gt;)&lt;/PRE&gt;</description>
      <pubDate>Thu, 03 Nov 2011 21:31:10 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226407#M19237</guid>
      <dc:creator>lee_j_keith</dc:creator>
      <dc:date>2011-11-03T21:31:10Z</dc:date>
    </item>
    <item>
      <title>Re: Recursive Function Problem</title>
      <link>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226408#M19238</link>
      <description>Is there any particular reason why you're creating a list of dummies to delete rather than simply deleting them once they're processed? I feel that the code is being complicated by doing so, and because we only have a rough outline of the code it will be difficult to determine just why it seems to be running twice - we don't know if the list is intended to be per-iteration or only supposed to happen when the initial invocation of the recursive function is about to end.&lt;BR /&gt;&lt;BR /&gt;The following is very "bare bones" but does work as intended, recursing through (then deleting) any dummies it finds and converting everything else to a Mesh object. Assumes one or more dummies (in different hierarchies) are pre-selected.&lt;BR /&gt;&lt;PRE&gt;&lt;BR /&gt;(&lt;BR /&gt;fn recurse thisObj = &lt;BR /&gt;   (&lt;BR /&gt;   if thisObj.children.count &amp;gt; 0 then&lt;BR /&gt;      (&lt;BR /&gt;      for o = thisObj.children.count to 1 by -1 do&lt;BR /&gt;         (&lt;BR /&gt;         obj = thisObj.children&lt;O&gt;&lt;BR /&gt;         if classof obj == Dummy then&lt;BR /&gt;            (&lt;BR /&gt;            recurse obj&lt;BR /&gt;            delete obj&lt;BR /&gt;            )&lt;BR /&gt;         else&lt;BR /&gt;            (&lt;BR /&gt;            convertToMesh obj&lt;BR /&gt;            )&lt;BR /&gt;         )&lt;BR /&gt;      )&lt;BR /&gt;   )&lt;BR /&gt;   &lt;BR /&gt;for obj in selection where classof obj == Dummy do&lt;BR /&gt;   (&lt;BR /&gt;   Recurse obj&lt;BR /&gt;   delete obj&lt;BR /&gt;   )&lt;BR /&gt;)&lt;BR /&gt;&lt;/O&gt;&lt;/PRE&gt;&lt;BR /&gt;&lt;BR /&gt;ps. You don't need a "sig sep" in your signature - the forum puts one there for you, and you missed the most important detail, namely your max version.</description>
      <pubDate>Fri, 04 Nov 2011 11:53:29 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226408#M19238</guid>
      <dc:creator>Steve_Curley</dc:creator>
      <dc:date>2011-11-04T11:53:29Z</dc:date>
    </item>
    <item>
      <title>Re: Recursive Function Problem</title>
      <link>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226409#M19239</link>
      <description>Hi Steve,&lt;BR /&gt;&lt;BR /&gt;I tried deleting them as they were processed, but kept getting errors saying that I was trying to access scene nodes that were deleted. The intent of this script is to optimize imported CAD hierarchies. They are often very nested and deep. First you select a dummy node then run the script. It creates a mesh and adapts all of the selected dummy's properties. Then it loops thru all of the nested children of the dummy. For every mesh it finds, it attaches it to the new mesh; for every dummy it deletes it. The result is one mesh object from the entire hierarchy.&lt;BR /&gt;&lt;BR /&gt;In it's current state it will throw this error: -- Runtime error: Attempt to access deleted scene object &amp;lt;&amp;lt;&lt;BR /&gt;&lt;BR /&gt;That error is caused when ran on this type of hierarchy:&lt;BR /&gt;&lt;BR /&gt;dummy1&lt;BR /&gt;--mesh1&lt;BR /&gt;--mesh2&lt;BR /&gt;--dummy2&lt;BR /&gt;----mesh3&lt;BR /&gt;----mesh4 (Deletion code block is executing after this, which is fine is the function never calls itself)&lt;BR /&gt;&lt;BR /&gt;But when working with a hierarchy like this, it works.&lt;BR /&gt;&lt;BR /&gt;dummy&lt;BR /&gt;--mesh&lt;BR /&gt;&lt;BR /&gt;So what is happening is that on the first iteration of the function, it processes mesh1, mesh2, and when it gets to dummy2, it calls itself. Then the function processes mesh3 &amp;amp; mesh4. Upon processing mesh4, it exits the for loop started by the second call to the function and executes the deletion code block that follows. At that point all of the dummy objects I have stored in the array are deleted and the code returns back to the first iteration of the script, and since dummy2 has been delete, the runtime can't finish the loop because the node is gone. I need the deletion block to only run on the last iteration. I'll try and dumb down the script and post it, but does this give a clearer picture?&lt;BR /&gt;&lt;BR /&gt;thx</description>
      <pubDate>Fri, 04 Nov 2011 15:13:22 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226409#M19239</guid>
      <dc:creator>lee_j_keith</dc:creator>
      <dc:date>2011-11-04T15:13:22Z</dc:date>
    </item>
    <item>
      <title>Re: Recursive Function Problem</title>
      <link>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226410#M19240</link>
      <description>As you delete all dummies and end with one mesh, you can done this without recurse function, something like...&lt;BR /&gt;&lt;PRE&gt;--select entire hierarchy&lt;BR /&gt;for n in selection do selectMore n.children&lt;BR /&gt;&lt;BR /&gt;--delete all dummies in selection&lt;BR /&gt;delete(for n in selection where isKindOf n Dummy collect n)&lt;BR /&gt;&lt;BR /&gt;--and then attach&lt;BR /&gt;objs = selection as array&lt;BR /&gt;for i = 2 to objs.count do meshop.attach objs objs&lt;I&gt;&lt;BR /&gt;&lt;/I&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 04 Nov 2011 16:02:31 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226410#M19240</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2011-11-04T16:02:31Z</dc:date>
    </item>
    <item>
      <title>Re: Recursive Function Problem</title>
      <link>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226411#M19241</link>
      <description>@Keith - your script fails or mine? Below is the hierarchy I tested it on and although I'm simply converting the Spheres to Mesh rather than attaching them, the script does work. The important thing to note is that I'm working DOWN the list of children, not UP the list for the very reason you describe.&lt;BR /&gt;&lt;BR /&gt;Anubis's method may be a lot easier, if it does what you need.&lt;P&gt;&lt;IMG class="migr-att-link" src="http://area.autodesk.com/userdata/forum/r/recursion_test.png" /&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 04 Nov 2011 16:30:36 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226411#M19241</guid>
      <dc:creator>Steve_Curley</dc:creator>
      <dc:date>2011-11-04T16:30:36Z</dc:date>
    </item>
    <item>
      <title>Re: Recursive Function Problem</title>
      <link>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226412#M19242</link>
      <description>@Steve - mine is failing.&lt;BR /&gt;&lt;BR /&gt;I'll ponder over you guy's input and see if I can adapt it. I'm probably making the script harder than it needs to be.&lt;BR /&gt;&lt;BR /&gt;thx</description>
      <pubDate>Fri, 04 Nov 2011 16:55:35 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226412#M19242</guid>
      <dc:creator>lee_j_keith</dc:creator>
      <dc:date>2011-11-04T16:55:35Z</dc:date>
    </item>
    <item>
      <title>Re: Recursive Function Problem</title>
      <link>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226413#M19243</link>
      <description>Ok, here is what I have so far. Steve, I integrated your script and it did fail because I needed to check for an editable mesh after the dummy check. That was causing the runtime error. I used the IsValidNode method to compensate and that works. It did eliminate the need to store the dummies in a list though &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;BR /&gt;&lt;BR /&gt;The code block that deletes the tmp mesh still gets executed twice unless I incorporate 2 checks. I understand why this happens, but see no clean way to prevent it. My fix is very clumsy to me, so if you see a better way let me know.&lt;BR /&gt;&lt;BR /&gt;The only thing not working is if you select multiple dummy objects with children and run the script it will not process all of the selected nodes. Apparently the delete node call is messing with the selection array. Not sure yet how to fix that.&lt;BR /&gt;&lt;BR /&gt;&lt;PRE&gt;&lt;BR /&gt;macroScript CollapseChildren category:"KL Tools" tooltip:"Collapse child nodes of selected parent" Icon:#("uvwunwraptools",18)&lt;BR /&gt;(&lt;BR /&gt; local tmpMesh&lt;BR /&gt; local tmpMeshCreated&lt;BR /&gt; local dummyChildrenProcessed&lt;BR /&gt; local selectedNodeNumChildren&lt;BR /&gt; local tmpMeshDeleted&lt;BR /&gt; &lt;BR /&gt; function recurse theNode =&lt;BR /&gt; (&lt;BR /&gt; if tmpMeshCreated == false then&lt;BR /&gt; (&lt;BR /&gt; --Create empty mesh&lt;BR /&gt; tmpMesh = mesh length:25 width:25 lengthsegs:1 widthsegs:1&lt;BR /&gt; setFaceSelection tmpMesh #{1..2} name:#temp&lt;BR /&gt; tmpMesh.name = theNode.name&lt;BR /&gt; metadata = getUserPropBuffer theNode&lt;BR /&gt; setUserPropBuffer tmpMesh metadata&lt;BR /&gt; &lt;BR /&gt; -- if not root object&lt;BR /&gt; if theNode.parent != undefined then&lt;BR /&gt; (&lt;BR /&gt; attachObjects theNode.parent tmpMesh&lt;BR /&gt; )&lt;BR /&gt; tmpMesh.pos = theNode.pos&lt;BR /&gt; tmpMesh.rotation.x_rotation = theNode.rotation.x_rotation&lt;BR /&gt; tmpMesh.rotation.y_rotation = theNode.rotation.y_rotation&lt;BR /&gt; tmpMesh.rotation.z_rotation = theNode.rotation.z_rotation&lt;BR /&gt; tmpMeshCreated = true&lt;BR /&gt; )&lt;BR /&gt; &lt;BR /&gt; if theNode.children.count &amp;gt; 0 then&lt;BR /&gt; (&lt;BR /&gt; for o = theNode.children.count to 1 by -1 do&lt;BR /&gt; (&lt;BR /&gt; c = theNode.children&lt;O&gt;&lt;BR /&gt; if classof c == Dummy then&lt;BR /&gt; (&lt;BR /&gt; dummyChildrenProcessed += 1&lt;BR /&gt; recurse c&lt;BR /&gt; delete c&lt;BR /&gt; )&lt;BR /&gt; if IsValidNode c then&lt;BR /&gt; (&lt;BR /&gt; if classOf c == Editable_mesh then&lt;BR /&gt; (&lt;BR /&gt; collapseStack c&lt;BR /&gt; clearSmoothing c&lt;BR /&gt; clearEdgeVisibility c&lt;BR /&gt; attach tmpMesh c&lt;BR /&gt; dummyChildrenProcessed += 1&lt;BR /&gt; )&lt;BR /&gt; )&lt;BR /&gt; )&lt;BR /&gt; &lt;BR /&gt; )&lt;BR /&gt; --this check is needed is needed to ensure that this only executes after all&lt;BR /&gt; --nodes have been processed.&lt;BR /&gt; if dummyChildrenProcessed == selectedNodeNumChildren then&lt;BR /&gt; (&lt;BR /&gt; --because the above evaluates to true in the last 2 iterations&lt;BR /&gt; --we must have another check&lt;BR /&gt; if tmpMeshDeleted == false then&lt;BR /&gt; (&lt;BR /&gt; tmpMesh.selectedFaces = tmpMesh.Faces&lt;BR /&gt; meshOp.deleteFaces tmpMesh tmpMesh.selectedFaces&lt;BR /&gt; )&lt;BR /&gt; tmpMeshDeleted = true&lt;BR /&gt; )&lt;BR /&gt; )&lt;BR /&gt; &lt;BR /&gt; function getChildCount theNode =&lt;BR /&gt; (&lt;BR /&gt; for c in theNode.children do&lt;BR /&gt; (&lt;BR /&gt; if classOf c == Dummy then&lt;BR /&gt; (&lt;BR /&gt; getChildCount c&lt;BR /&gt; selectedNodeNumChildren += 1&lt;BR /&gt; )&lt;BR /&gt; &lt;BR /&gt; if classOf c == Editable_mesh then&lt;BR /&gt; (&lt;BR /&gt; selectedNodeNumChildren += 1&lt;BR /&gt; )&lt;BR /&gt; )&lt;BR /&gt; )&lt;BR /&gt; &lt;BR /&gt; function doCollapse =&lt;BR /&gt; (&lt;BR /&gt; if selection.count == 0 then&lt;BR /&gt; (&lt;BR /&gt; print "nothing selected"&lt;BR /&gt; )&lt;BR /&gt; else&lt;BR /&gt; (&lt;BR /&gt; for obj in selection where classof obj == Dummy do&lt;BR /&gt; (&lt;BR /&gt; tmpMeshCreated = false&lt;BR /&gt; tmpMeshDeleted = false&lt;BR /&gt; dummyChildrenProcessed = 0&lt;BR /&gt; selectedNodeNumChildren = 0&lt;BR /&gt; getChildCount obj&lt;BR /&gt; print obj.name&lt;BR /&gt; recurse obj&lt;BR /&gt; --this is causing multiple selections not to work&lt;BR /&gt; delete obj&lt;BR /&gt; )&lt;BR /&gt; )&lt;BR /&gt; )&lt;BR /&gt; &lt;BR /&gt; on execute do&lt;BR /&gt; (&lt;BR /&gt;        doCollapse()&lt;BR /&gt;    )&lt;BR /&gt;)&lt;BR /&gt;&lt;/O&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 04 Nov 2011 18:38:22 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/3ds-max-programming-forum/recursive-function-problem/m-p/4226413#M19243</guid>
      <dc:creator>lee_j_keith</dc:creator>
      <dc:date>2011-11-04T18:38:22Z</dc:date>
    </item>
  </channel>
</rss>

