readDelimitedString if loop?

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

Thread Tools Search this Thread Display Modes
Old 04 April 2013   #1
readDelimitedString if loop?

Hi all,

I'm a long-time but low complexity maxscripter, but I know what I want to do and generally I get there through recursive tinkering.
My main issue is usually knowing the appropriate terminology to search for.

Here is a snippet of the first few lines of a file (it's an OS DTM format)

ncols 200 nrows 200 xllcorner 430000 yllcorner 250000 cellsize 50 68.6 69.2 69.6 70.2 71.2 71.9 73 74 75.3 89.2 88.2 80.3 79.4 86.7 87.8 85.9 81.5

Please note there are 200 lines of data, each with 200 entries per line in my actual file.

The area I'm struggling with is the readDelimitedString.

vert_array = #() face_array = #() in_name = getOpenFileName() if in_name != undefined then ( in_file = openFile in_name if in_file != undefined then ( -- get ncols skipToString in_file "ncols" ncols = readLine in_file as integer -- get nrows skipToString in_file "nrows" nrows = readLine in_file as integer -- get cellsize skipToString in_file "cellsize" cellsize = readLine in_file as integer num_verts = ncols * nrows --num_faces = (ncols - 1) * (nrows - 1) * 2 vert_array.count = num_verts --face_array.count = num_faces for r = 1 to nrows do ( for v = 1 to ncols do ( vert_y = readDelimitedString in_file " " as float vert_x = (v-1) * cellsize vert_z = (r-1) * cellsize x = vert_x as string y = vert_y as string z = vert_z as string xyz_array = execute ("[" + x + "," + y + "," + z + "]") index = (v)+(r) vert_array[index] = xyz_array ) skipToNextLine in_file ) close in_file --new_mesh = mesh vertices:vert_array -- debug debug= newScript() --print ncols to:debug --print nrows to:debug --print cellsize to:debug print vert_array to:debug print x to:debug print y to:debug print z to:debug )--end if )--end if

Right now this works ok, except that the last entry on every line ends in a carriage return, but I can't seem to add a syntax that allows me to run an if or while statement referencing the ncols variable.

Basically I want to say something like this:

if v < ncols ( read delimited string until " ") else ( read delimited string until "/r")

I've tried an if else statement, two if statements, and everything else I can think of but it's breaking the code. Is there a certain way I should be doing this?

I've tried this which should work?
if v < ncols do ( function) if v = ncols do ( other function)

Which I'm sure is the right maxscript syntax but it fails.

My quick bodge is find/replace on the data lines to add a trailing space before the carriage return... but I don't like bodges.

Also note my horrible array filling using a string. I can't seem to find any examples in the help files saying how to do this more elegantly.
I can't seem to find anything saying how to use point3 arrays at all.

I'm also struggling recursing through the rows/columns and indexing the correct array entry to store the vert data, but I think that will be easier once I can just run through each point3 coord at a time, filling X then Y then Z.
I've not really got to that part yet though so if my code looks iffy please ignore haha!

Many thanks for any help

I'll carry on working at it, I'm sure I'll get there eventually...

Old 04 April 2013   #2
everything looks ok in your code. just use readValue instead of readDelimitedString...
about point3...
you already have x,y,z as floats. you don't need them converted to string. the constructors for point3 are:
[x,y,z] -- or point3 x y z

where x,y,z are floats (or integers, which will be automatically converted to floats)
Old 04 April 2013   #3
so in you case the code might look as:
if (file = getOpenFileName()) != undefined and (ss = openfile file) != undefined do ( vert_array = #() skipToString ss "ncols" ncols = readValue skipToString ss "nrows" nrows = readvalue ss skipToString ss "cellsize" cellsize = readValue ss num_verts = ncols * nrows vert_array.count = num_verts for r = 1 to nrows do ( for v = 1 to ncols do ( y = readValue ss x = (v-1) * cellsize z = (r-1) * cellsize vert_array[v+r] = [x,y,z] ) ) close ss )
Old 04 April 2013   #4
Hi DenisT,

Thanks for clarifying those things. Oh, I didn't see the readValue method all the way down here haha. Never mind.

That all seems to work ok though. I'm getting some errors copying your code across but the syntax works ok.

I'm having trouble understanding why the v loop doesn't complete first though.

This is my test file:
ncols 5 nrows 5 xllcorner 430000 yllcorner 250000 cellsize 50 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5

And my output goes like this:
[0,1.1,0] [0,1.6,50] [0,2.1,100] [0,2.6,150] [0,3.1,200] [50,3.2,200] [100,3.3,200] [150,3.4,200] [200,3.5,200] undefined undefined undefined etc etc

I also had to put (r-1) in the array address so the array filled up from 1 > rather than 2 >
vert_array[v+(r-1)] = [x,y,z]

But it appears not to loop within the V loop fully 5 times (across the colums), and then exit the V loop with the readValue ready on the next line for the r=2 v=1 condition ready to read in the next line of values.

If I use readValue and get a raw stream of values it loops across then down fine in the first 5, then the next 5, then the next 5 values etc.

But it appears to be running through the r loop first!?

I'm probably missing something obvious. I'll have to come back with a fresh brain tomorrow and see what happens.

Next task is then completing the face build, which should be a simple function once the vert array is working nicely!


Old 04 April 2013   #5
I think this is because of the way you're calculating the index in vert_array to store the point3.

Give this (untested) a try.

vert_array[v + nrows * (r-1)] = [x,y,z]


Old 04 April 2013   #6
Thanks Drea,

That appears to have done the trick.

I was looking at that but couldn't see it, but now it makes sense. This is my problem with maxscripting, and coding in general. I use it but not enough to maintain solid skills...

Though I've decided to go through the video tutorials by JohnW to try fill in my blanks (lots of them) and have already found a few ways to optimise and imrpove this script!

Now to create some triangles!

If someone is willing to help make this script a bit more elegant once I've finished it it'd be nice to put it up on ScriptSpot. There are loads of GIS type 3D formats out there but precious few (none that are free) for getting things into 3DS Max or other '3D' apps for more interesting visualisations.


Old 04 April 2013   #7
Well I started to get really confused with the function needed to draw triangles with the vertex indexes, but then also the function needed to put the triangles in the appropriate array index.

It got a little confused. I wasn't far off filling in all the triangles for one set of verts, so was just going to do another pass to build the other triangle (and thus make a complete quad) with the array offset by the number of triangles in the first pass.

I'm sure there is an elegant way to do it but I just decided to cheat.

This is slower by a fair margin but it's perfectly workable.

macroScript ImportMesh category: "OS OpenData Importers" ( vert_array = #() in_name = getOpenFileName() if in_name != undefined then ( in_file = openFile in_name if in_file != undefined then ( -- get ncols skipToString in_file "ncols" ncols = readValue in_file -- get nrows skipToString in_file "nrows" nrows = readValue in_file -- get cellsize skipToString in_file "cellsize" cellsize = readValue in_file num_verts = ncols * nrows vert_array.count = num_verts -- put all the height data values into an array for v = 1 to num_verts do ( z = readValue in_file vert_array[v] = z ) close in_file -- create a plane (it appears I need to mirror the finished object in the y axis since the height data is actually addressed from the top left, despite the file reference coords being the bottom left!) -- this is slow, but it works, and maybe needs some manual mirroring at the end pwidth= ncols * cellsize plength = nrows * cellsize widthsegs = ncols-1 lengthsegs = nrows-1 convertToPoly(Plane length:plength width:pwidth pos:[pwidth/2,plength/2,0] isSelected:on lengthsegs:lengthsegs widthsegs:widthsegs name:"new_terrain") local theMesh = selection[1] if selection.count == 1 then ( if classof theMesh == Editable_Poly then ( n=1 for vert in (theMesh.mesh.verts as bitarray) do ( polyop.setVert theMesh vert [((polyop.getVert theMesh vert).x),((polyop.getVert theMesh vert).y),(((polyop.getVert theMesh vert).z) + vert_array[n])] n=n+1 vert_array[1] ) ) ) ) ) )

I think this approach works pretty well, though it's not optimal by any means.

This takes around 2min to process a 40k polygon DTM file, while my previous method was building a partially correct mesh in about 10s...

I'm quite surprised it's so slow though. Is this because I'm looking up the existing xyz data per vert and then altering a specific z coord data with an offset?

I guess simply taking a vert z index only and setting it's z value absolutely is going to be faster as it's just pure writing, rather than reading values and then re-writing them all back (including x and y)


Old 04 April 2013   #8
Hmmm, maybe it's not so workable.

It seems to use up a LOT of ram, and then leaves it resident once the mesh is built.

2GB > 16GB in about 30s, eek!

I can't see what might be doing that... it's a lot of memory...

Does the poly operation method do some caching? Maybe it's caching the whole mesh each time it processes the next vert?!


Old 04 April 2013   #9
Thread automatically closed

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
Thread Closed share thread

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Society of Digital Artists

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump

All times are GMT. The time now is 09:02 PM.

Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.