[Closed] Node GUID
I posted this on accident in the main forum. Sorry about the cross post.
Does every node have a GUID? Or something unique by which it can be selected later?
I have an array of objects that I need to convert into an array (to dynamically create a rollout where each button selects an object) but beside leaving the array in global memory I don’t know of a way to pass an identifier to the buttons like
For o in selection do (Append selectionGUIDs o.GUID)
on pressed do
(
select (getnodebyid selectionGUID[1])
)
What I’m currently using is this:
--- Get a node by a string. Example: getnodebystring((selection as array)[1] as string) ---
function GetNodebyString nodestring=
(
searcharray = #()
parsednode = (filterstring nodestring ":@")[2]
if parsednode != undefined do
(
nodename = (substring parsednode 1 (parsednode.count - 1))
searcharray = getnodebyname nodename ignorecase:false exact:true all:true
for o in searcharray do
(
if (o as string) == nodestring do
(
return o
)
)
return undefined
)
)
Edit: Decided if I wanted a GUID there was no reason I couldn’t define it myself.
fn getNodebyNodeGUID guid =
(
for o in objects do
(
if (getuserprop o "GUID") == guid do
(
return o
)
)
return undefined
)
fn setNodeGUID obj =
(
GUID = (random -99999999 99999999)
if (getNodebyNodeGUID GUID) == undefined and (getuserprop obj "GUID") == undefined do
(
setuserprop obj "GUID" GUID
return GUID
)
)
fn getNodeGUID obj =
(
getuserprop obj "GUID"
)
Each node in Max has a .handle exposed by the .inode interface. But the handle, while unique, is assigned at creation time, so it does not stick to the object in cases like merging an object from one scene to another and so on.
If you ensure that all object names are unique (by forcing it or asking the user to name objects uniquely), all you have to do is store an array of object names.
theNamesArray = for o in objects collect o.name
You can always convert the array back to a node array using
theArray = for o in theNamesArray where isValidNode (obj = getNodeByName o) collect obj
If you store nodes in a persistent global array, they will be resolved next time you open the Max scene (even between sessions), so you don’t have to store any IDs, just collect the nodes, dump them into a persistent global array, save the Max file, restart Max, reload the scene and the array will still contain all the nodes (pointing at the correct scene objects).
Handle is exactly what I wanted.
I don’t care if the guid doesn’t get passed along from scene to scene. As long as it’s unique within the scene. This works perfectly.
Remember to read the WARNING in the Help – never use .handle alone, because the teapot has a property with the same name. Always use theNode.inode.handle
Because the teapot was added to Max in version 1.0 and its ParamBlock had the name “handle”.
Then MAXScript came along in R2 and exposed the “handle” as “handle”.
Then in Release 4, somebody decided to add the INode interface and exposed the node handle as .handle, instead of, say, “NodeID” or “NodeHandle”.
Much later somebody realised that the two collide (just like the .castshadows node vs. baseobject property) and the note was added to the help as the fix because changing an existing interface in Max 5 or higher would have broken 3rd scripts and plugins. When a fix requires changes to MAXScript that would make older scripts not work, a decision is made regarding the impact and whether a documentation note is the better solution. In this case, once you know of the limitation, it IS the better solution.
I don’t see a warning in the help doc. Is there another place handle is mentioned than the “INode Interface” page?
See “Node Handles” topic.
Good point, I should add that warning to the INode interface page.
of course, then a smartalex comes along and puts a custom attribute block on the object and names a parameter within ‘inode’. hilarity ensues :\
Oh hey look at that “MaxOps.getNodeByhandle” I guess I can get rid of that custom function now…
Completely off topic but:
Bobo on the Rollout Interface Items image map. If you click on the Radio buttons… it goes to the label page instead of the radiobuttons page.
Good catch!
Unfortunately, I cannot fix this for 2009, but will make sure it is fixed in the future.
Good thing we’ve got the links on the right side…