[Closed] Global tracks and custom attributes
I have a problem with global tracks and custom attributes. I would like to store frames which i have stored in an array, in string, which is a custom attribute of global track i have created.
First, here is the code i use to add global track:
newTrackViewNode globalTracks “GUN”
theCont = bezier_float ()
addTrackViewController globalTracks.GUN theCont “myVariable”
myCAs = attributes GUN_Atts
(
parameters GUN_Params
(
GUN_shotTimeArr type:#stringTab tabSize:0 tabSizeVariable:true
)
)
custattributes.add globalTracks.GUN myCAs
after this, in the code i try to add my array into GUN_shotTimeArr as string:
append globalTracks.GUN.GUN_Atts.GUN_shotTimeArr (theShotTime as string)
What happens, it seems like it works when the array is relatively small, but when i have more than say, 25 frames stored, it seems like the string gets stored like the listener output:
#(“#(0f, 7f, 14f, 21f, 28f, 35f, 42f, 49f, 56f, 63f, 70f, 77f, 84f, 112f, 119f, 126f, 133f, 140f, 147f, 154f, …)”)
It gets cropped from the end.
So. Am i doing this in completely wrong way ? I’m not familiar with any other method to store arrays to scene file, except this method…
I’m storing array-driven strings using the setAppData and getAppData methods without any problems. It doesn’t seem to have any drawbacks, and is much simpler than custom attributes or persistent global variables. (Persistent Global Variables are another option for what you want, but they involve a great deal of bulletproofing/safeguarding since the data is not attached to any nodes and can be unpredictably affected during File Open/New/Reset/Merge events. I bulletproofed a previous large project successfully, but it’s quite involved.)
I originally looked into using Custom Attributes for my current project, but they seemed unsuited to the task, severely limited, overly complicated and they were definitely incompatible with 3ds max 3. I went with the AppData functions and they work great. I did some brief testing, and it looks like you can get/set AppData directly on the TrackViewNode itself. Below is some psuedo-code showing the overall approach:
fn StoreFrameArrayStringToTVnode =
(
local AppDataString = ""
for i=1 to FrameArray.count do (AppDataString+=((((FrameArray[i]) as integer) as string)+","))
setAppData MyTVnode 101 AppDataString
)
fn RebuildFrameArrayFromTVnodeString =
(
local AppDataString = (getAppData MyTVnode 101)
local FrameStringArray = (filterString AppDataString ",")
local FrameCount = FrameStringArray.count
FrameArray = (for i=1 to FrameCount collect ((FrameStringArray[i] as integer) as time))
)
-
Thanks John! i’ll take a look into your solution!
-
Anyway, only thing i’m going to do, is to store 2-3 arrays, which will be deleted / overwritten everytime the script will be run… So my current method might be just enough for this task.
-
I already solved the problem with “with printAllElements on” – Otherwise max only prints first 20 elements and not all elements of array…