Creating an ASCII Text file for ArcGIS from existing Terrain

What I need is a MAXScript that will sample an existing terrain on a grid

that is n columns by n rows with a specified interval for each. For

example: 10 columns by 10 rows with 10m between each column and 10m

between each row.

All the script needs to do is start with a point in the upper left hand

corner of the array, project a test ray in the negative Z direction, once

that ray intersects with the terrain below write that elevation along

with the point number to a .txt file and then move the point to the next

position to the right (based on the spacing interval), renumber the

point, and repeat the same output process.

Once the point gets to the end of the column it needs to go back to the

far left and begin again on the next row, keeping the numbering

consistent. The numbering for the array would begin with "Point01" in

the upper left hand corner and go from left to right until it reaches the

bottom right of the array. In this example of a 10 x 10 array the last

point number would be "Point100" which would be the last point on the far

right of the last row.

For a small array I could create points in 3dsMax and use the 'Move to

Surface' script, then export the positions myself to a text file but the

arrays I'm dealing with for this particular project are thousands of

columns x thousands of rows. This results in millions of points in the

array. Figured if I could get someone to help me out with a script that

would move, rename, and output one point that traveled around the terrain

in an array fasion, it would be an easier approach to obtaining the

elevation data in a text format.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
todd21st's picture

Thanks. As I'm fairly a

Thanks. As I'm fairly a novice to this would you mind modifying the code to include a loop? That way I can just select all objects that make up my terrain and run the script. Only reason I ask is because I'm dealing with upwards of 80,000 tiles to create the terrain. Also, would it be too much to ask to drop a line of code in there for a default elevation value to assign to a point in case the point happens to not intersect terrain below? Say a default no data value of -999?

miauu's picture

If the selection is more than

If the selection is more than one object, then $ holds all seleced objects. The intersectRay require one node and one ray.
From maxscript help file

intersectRay <node> <ray>
Computes the closest intersection of the ray and the surface of the given node

Save your scene, attach all tiles to one object and use the script. Then reload original scene. Or do loop so all tiles to be processed.

todd21st's picture

WOW! This is absolutely

WOW! This is absolutely amazing!! What a great script. This does just about everything I wanted it to do. Thank you very very much!

Question: In my Max scene my terrain is a series of tiles. So when executing the script I will need to select my terrain manually and tell the script that the local z node will be whatever is in the selection. When I modify the script to read...

local z_node = $

it highlights and complains about this line...

local inteersectionPoint = (intersectRay z_node testRay).pos

any ideas why?

miauu's picture

Hope this will help

You do not need a real point(helper or some other object) to get the point of the arra.
See the code below. The Plane and the Point helper are created just to show you the name and the position of the points in the array. Remove them from the code if you want to use it. The positions will be printed in the listener. You know what to uncomment to store the values to the file. Execute the code in top viewport, since I don't know where is the top left for you.

(
	local z_node = plane pos:[0,0,-100] width:100 length:100
 
	out_name = ((GetDir #export)+"/terrainInfo.txt")
	out_file = createfile out_name	
 
	columns = 5	--	the amount of the columns
	rows = 5		--	the amount of the rows
	stepX = 10		--	ajust this to get real 10 m or any other value
	stepY = 10
	pos = [0,0,0]	--	the pos for point01
	cnt = 0	--	this will count the points and will be used to get the proper names 
	with undo off	--	will increase the speed
	(
		with redraw off		--	will increase the speed
		(			
			for i = (columns-1) to 0 by -1 do
			(
				for j = 0 to (rows-1) do
				(
					cnt += 1
					local pos = [(j*stepX),(i*stepY),0]
 
					--	create point in proper plces
					local p = point pos:pos size:5
 
					--	find trhe intersection here
					local testRay = ray pos [0,0,-1]
					local nodeMaxZ = z_node.max.z
					testRay.pos.z = nodeMaxZ + 0.0001 * abs nodeMaxZ
					local inteersectionPoint = (intersectRay z_node testRay).pos
 
					--	move the point 
					p.pos = inteersectionPoint
 
					-- print in the listener(uncommeent the to:out_file to store to file)
					format "% %\n" ("Point"+(cnt as string))  inteersectionPoint --to:out_file
				)
			)
		)
	)
	close out_file
)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.