Maxscript: Convert String to Point2

From: My Blog
I encountered a problem while working today.
Working with INI files in max, the only way that I can see to pull data out is by collecting it as a string.
That’s great. But what if the data you are working with, isn’t a string? What if you want to work with say a colour value or a point2 like I happened to require.
Background: I am storing a dialog location via point2. Yes I could have stored them as individual values, but I didn’t think about that before this writing. Instead, I solved it with a bit of hackery.



Point2String = getINISetting myFile "Value" "Point2"
local newVal = [0,0]
b1 = findString ALB.UI.UI_Pos "["   --find the location of the first bracket
c1 = findString ALB.UI.UI_Pos ","   --find the location of the comma
b2 = findString ALB.UI.UI_Pos "]"   --find the location of the second bracket
--Collect values between bracket 1 and comma, append newVal
temp = ""
for i in (b1+1) to (c1-1) do
(
    temp = temp + Point2String[i]
)
newVal.x = temp as integer
--Collect values between command and b2, append newVal
temp = ""
for i in (c1+1) to (b2-1) do
(
    temp = temp + Point2String[i]
)
newVal.y = temp as integer
newVal --This now contains your point2 in point2 form!

So, while I admit, it is not very pretty, and it can be cleaned up and optimized, I thought it might be a useful tidbit for others trying to do various things.

Has anyone else done anything glamorous with this kind of conversion?

why not just use execute?


val=[1,2]
classof val
--point2
valstring=val as string
classof valstring
--String
valP2=execute (valstring)
classof valP2
--point2


Look up the readValue() method in MaxScript’s StringStream class. readValue() will take a stringStream and convert it to the appropriate MaxScript operand automatically.
I store dialog sizes in an INI file. My code to recover them looks like this:

local point_string = getINISetting ini_file ini_section "dialog_size"
split_idx = findString point_string "="

if split_idx != undefined then (
   point_string = subString point_string (split_idx + 1) point_string.count
)

point_string = point_string as stringStream
seek point_string 0
local saved_dialog_size = readValue point_string

As for “why not just use execute?” - execute() is slow. Even the MXS docs say that it should only be considered if no other alternative exists.

There’s nothing wrong with using execute for the right task, the warnings in the help file mainly refer to the scoping issues which don’t apply here. Speed might be an issue if you were reading several hundreds thousands of records but then again, you’d be better off optimizing other parts of the code first (for example switching from ini-file model to database model) as 100000 calls of both readValue and execute still take less than one second. Also, casting string to stringStream consumes more memory (creating another variable to hold it would count too), and when talking about several hundred thousands such operations, gc kicks in, making it actually a bit slower so the miliseconds-big speed difference gets lost anyway. Personally, I would go with execute, it’s straightforward, concise and works well. Now, it would be a different story if you were dealing with a stream instead of individual string bits, but obviously that’s not the case here. You know, premature optimization and all that stuff.

Ah, thanks for the input guys.

Based on the scope of my tasks last week, I completely neglected execute() and forgot entirely about string stream operators.
My approach to SS would have varied slightly from yours.
Execute is precisely the improvement I should be using in this instance.
As Swordslayer points out, execute would be no hindrance here. Just a few calls for string to point2 conversions.