Notifications
Clear all

[Closed] execute() fails when accessing "$My-Box"

Anyone know why the following use of execute() gives an error?

MyBox = Box name:"MyBox"
$Box:MyBox @ [0.000000,0.000000,0.000000]
execute "$MyBox"
$Box:MyBox @ [0.000000,0.000000,0.000000]
MyBox.name = "My-Box"
"My-Box"
execute "$My-Box"
-- Error occurred during fileIn in StringStream:"$My-Box"
-- No ""-"" function for undefined

It also chokes on the characters #, @ and probably some others. There is nothing mentioned in the docs about restrictions on the strings that execute() can accept.

I’ve used execute() extensively in LightRigger for accessing custom TrackViewNodes, and I’ve never stumbled upon any problems at all.

(BTW, I confirmed this behavior in prior versions of 3ds Max, so this isn’t new.)

7 Replies

You may need to put a slash before the “-” character to escape it:

execute “$My-box”
$Box:My-Box @ [35.599663,-38.134167,0.000000]

 JHN

Why wouldn’t you just use

getNodeByName "My-Box"

But if you don’t want that then you should use this

execute " '$My-Box' "

Notice the single quotations.

Be aware execute is very slow when in a big loop… if you can use getNodeByName.

Also lookup “Spaces and Other Special Characters in Pathnames” in the mxs help file.

*edit: Kopars solution works too, but if your looping over objects you don’t want to check if you need to escape each special character that’s in there.

Hope this helps,
-Johan

That double-single quote trick is pretty sweet! I’ll try and remember that one. Got any tricks for file paths? trying to constantly escape out all the back slashes is a chore!

myPath = “\\server\folder
ew folder\file.max”

So many slashies!

1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

Since Max 2008, you can say

myPath = @”\server\folder
ew folder\file.max”

Since Max 2, you can use forward slashes / instead of double-backslashes \ to specify folders.

I’ve used pathname literals very rarely, so I suspected I was missing something fundamental. I always get the most revealing answers when I ask the dumbest questions.

Ok, so the errors had nothing to do with execute() at all. Instead, they had to do with pathname literals requiring escape sequences for characters that do not otherwise need them. For example, the string “-” is not needed to create the string “-”, but the pathname $My-Box (or $‘My-Box’) is needed to access an object named “My-Box”. That’s what was throwing me off.

I’d glanced over the Spaces and Other Special Characters in Pathnames page in the docs many times, but I always thought I knew the list of special characters that needed escape sequences. Until now, I thought that escape sequences were purely related to building string values.

I could definitely use an alternative to pathnames, but I wanted to understand exactly why it was failing. I thought the problem was with execute(), which I’ve had to rely on heavily in LightRigger.

The only reason I’ve needed to use execute() in LightRigger was to restore references to dozens of custom-named TrackView nodes/controllers when the script starts up. These are only accessible via the trackViewNodes interface (i.e. “trackViewNodes.MyTVnodeName.MyTVconName”). Because of their custom names, I had to use a loop with execute() being fed custom built string values.

(The name trackViewNodes is very misleading, as they aren’t 3ds Max “nodes” in any other sense. They are not scene objects and they only appear in TrackView. Neither custom attributes nor appData can be applied to them, and persistent globals will not restore references to them. They can only be accessed by name via the trackViewNodes interface.)

Kopar and Johan, thanks for the help.

Execute() is the same as FileIn(), just for StringStreams instead of FileStreams. In other words, calling Execute() evaluates the string as if it were a MAXScript .MS file.

So what happens with (execute “$My-Box”) is that the parser sees

(($My) - (Box))

and tries to perform a subtraction between two values that are, as far as MAXScript is concerned at that point, either UNDEFINED or a function. $My would be a non-existent scene node and Box would be the constructor of a box.

What is really funky is that calling this in a scene where $My IS a valid object (say, a box) would cause a different error.

(execute "$My-Box")
   -- Error occurred during fileIn in StringStream:"$My-Box"
   -- Error occurred in anonymous codeblock; filename: none; position: 0
   --  Frame:
   -- Unable to convert: Box to type: <node>

This is because – IS a valid operation between two nodes. Once $My is resolved as a valid scene node, the second part of the expression is expected to also be a node to perform a Boolean subtraction between the two meshes! But since Box is not a node, it does not work.

But if you create a Sphere, store it in a global variable Test and try to call

Test = sphere()
   $Sphere:Sphere01 @ [37.067688,-12.059479,0.000000]
   execute "$My-Test"
   $Editable_Mesh:My @ [-3.202702,-5.373291,0.000000]

the result will be an actual boolean subtraction stored in the node ‘My’ which is implicitly converted to Editable_Mesh to store the result.

Fun eh?

that is just pure quality:thumbsup: