Hi, I'm using AC2K and Win2K. I've just finished a nice 3d map of a
hilly 5 acre building site --and a topo map from that. I'm posting
this for people who know AutoLISP and can't (or won't) afford a fancy
AutoCAD add-on.

I'd rather not post the source because it's far from universal but I thought the description would be useful.

My data are simple 3d points sampled in a cartisian grid pattern, IN MY CASE 1 GRID UNIT IS 20'. I've elevated all my data so that all of my Z's are above 0.

(How I obtained this data is another war story. Suffice it to say it involved a laser level and endlessly tromping thru brush much of this summer. No topo maps are available even close to this detail, and GPS can't be used for two reasons: 1) I think civillian resolution is still blunted temporarily by the military and 2) my lot is heavily wooded.)

All of the following was done in AutoLISP:

First I "squared" the data. By that I mean my lot is not rectangular so I calculated averages of ajacent points around the perimeter until I had a rectangular data set. I do this to make further processing easier and give a good margin for the ends of the splines yet to be drawn below. Most if not all of this synthesized data will be chopped off later. Your data set may have missing points in the middle of your property here and there. (Either you forgot to measure or couldn't because of steepness, brush etc.) Average out a guess from adjacent points.

Next, for every unit line in the grid, draw a SPLINE. Make sure the spline passes <through> the data points, else you won't be able to break them. (See system variable ?) I'm at default settings related to SPLINE.

Next, BREAK the splines up at each unit mark in the grid.

Next, for each cell in the drawing...

(Cell: a square 1 unit per side (20' in my case), defined by four data points or four (broken) splines.)

Find the splines making up the four sides of the cell. Feed the 4 splines to EDGESURF.

(Note: SURFTAB1 and SURFTAB2 will determine how many facets are in the resulting coons mesh. Pick your own value for SURFTAB1 and SURFTAB2 but make them equal. Do this once immediately preceeding this loop.)

EXPLODE the resulting coons mesh.

For each 3dface created from the explosion...

(We need create an extrusion that is then SLICEd in the plane of the 3dface, but this is impossible when the 4 points making up the 3dface are out of plane. So we...) Draw (PLINE) 2 triangles out of the points making up the 3dface. Make the Z's of all 3 points of each triangle 0.

(The rub here is that a diagonal must be chosen to divide the square 3dface into 2 triangles. Should we draw the diagnol from the SW to the NE or from the SE to the NW? One or the other can result in a quite different shape. But since I've chosen a relatively high SURFTAB1 and SURFTAB2 the facets are about 2' on a side which provides enough resolution for my purposes. I've just decided to always draw the diagnol SW to NE.)

For each triangle created... (2 of 'em)

EXTRUDE the triangle to some height well above your highest elevation. (I use 10000.)

SLICE the triangle extrusion using XY's from the points originally used to draw the triangle and the respective Z's from the 3dface. Keep only the side of the extrusion closest to Z=0.

End loop for each triangle Delete the 3dface.

End loop for each 3dface

End loop for each cell

The result will be quite a few solids. It may take days to UNION them all, but I use 2 ways with AutoLISP to accomplish this in short order. One function is called IncrementalUnion. This just selects solids within a given initial boundary square, moves the square over, does it again, etc. then when the drawing space is covered it increases the boundary square size by a factor of 2 and scans over the drawing again etc. until there is only 1 solid. Another routine is called RandomUnion. It picks X number of solids randomly from the existing set and UNIONs them, picks the next X of them, etc. I use both of these routines. Typically IncrementalUnion will produce AutoCAD 3d modeling errors about once every 1000 tries. Don't know why. You can't detect these errors via the (command) interface. The only way in pure AutoLISP I've found of detecting these errors involves turning on the log and inspecting the log every time a 3d command is done. Instead of bothering with all this, if after running IncrementalUnion the number of solids is greater than 1 I call RandomUnion. Somehow picking non-ajacent solids make the 3d modeling errors go away.

The result of the big UNION is 1 solid representing the land mass. Now we can get rid of the artificial portion of the solid resulting from "squaring the data" above. I have a region in my drawing representing the lot perimeter. I simply make sure DELOBJ=0, extrude that region to 10000 and INTERSECT the region with the land mass solid.

Now we're ready to make the topo map. Determine your contour line division. I've chosen 5 feet. Set the view to front. Start at the bottom. (You might want to save the landmass somewhere else first.)

set Z=5 Until you've reached the highest elevation SLICE the landmass thru the xy plane at Z EXPLODE the solid just created SELECT all of the resulting regions just above (Z-5) and just below Z and delete them (Use SELECT with the "box" method, although I wouldn't be surprised if there's a better way.) The remaining region represents the topo line for that elevation, move it down to Z=0. Increment Z by 5 feet end loop

Set your view to top.

Done.

I'd rather not post the source because it's far from universal but I thought the description would be useful.

My data are simple 3d points sampled in a cartisian grid pattern, IN MY CASE 1 GRID UNIT IS 20'. I've elevated all my data so that all of my Z's are above 0.

(How I obtained this data is another war story. Suffice it to say it involved a laser level and endlessly tromping thru brush much of this summer. No topo maps are available even close to this detail, and GPS can't be used for two reasons: 1) I think civillian resolution is still blunted temporarily by the military and 2) my lot is heavily wooded.)

All of the following was done in AutoLISP:

First I "squared" the data. By that I mean my lot is not rectangular so I calculated averages of ajacent points around the perimeter until I had a rectangular data set. I do this to make further processing easier and give a good margin for the ends of the splines yet to be drawn below. Most if not all of this synthesized data will be chopped off later. Your data set may have missing points in the middle of your property here and there. (Either you forgot to measure or couldn't because of steepness, brush etc.) Average out a guess from adjacent points.

Next, for every unit line in the grid, draw a SPLINE. Make sure the spline passes <through> the data points, else you won't be able to break them. (See system variable ?) I'm at default settings related to SPLINE.

Next, BREAK the splines up at each unit mark in the grid.

Next, for each cell in the drawing...

(Cell: a square 1 unit per side (20' in my case), defined by four data points or four (broken) splines.)

Find the splines making up the four sides of the cell. Feed the 4 splines to EDGESURF.

(Note: SURFTAB1 and SURFTAB2 will determine how many facets are in the resulting coons mesh. Pick your own value for SURFTAB1 and SURFTAB2 but make them equal. Do this once immediately preceeding this loop.)

EXPLODE the resulting coons mesh.

For each 3dface created from the explosion...

(We need create an extrusion that is then SLICEd in the plane of the 3dface, but this is impossible when the 4 points making up the 3dface are out of plane. So we...) Draw (PLINE) 2 triangles out of the points making up the 3dface. Make the Z's of all 3 points of each triangle 0.

(The rub here is that a diagonal must be chosen to divide the square 3dface into 2 triangles. Should we draw the diagnol from the SW to the NE or from the SE to the NW? One or the other can result in a quite different shape. But since I've chosen a relatively high SURFTAB1 and SURFTAB2 the facets are about 2' on a side which provides enough resolution for my purposes. I've just decided to always draw the diagnol SW to NE.)

For each triangle created... (2 of 'em)

EXTRUDE the triangle to some height well above your highest elevation. (I use 10000.)

SLICE the triangle extrusion using XY's from the points originally used to draw the triangle and the respective Z's from the 3dface. Keep only the side of the extrusion closest to Z=0.

End loop for each triangle Delete the 3dface.

End loop for each 3dface

End loop for each cell

The result will be quite a few solids. It may take days to UNION them all, but I use 2 ways with AutoLISP to accomplish this in short order. One function is called IncrementalUnion. This just selects solids within a given initial boundary square, moves the square over, does it again, etc. then when the drawing space is covered it increases the boundary square size by a factor of 2 and scans over the drawing again etc. until there is only 1 solid. Another routine is called RandomUnion. It picks X number of solids randomly from the existing set and UNIONs them, picks the next X of them, etc. I use both of these routines. Typically IncrementalUnion will produce AutoCAD 3d modeling errors about once every 1000 tries. Don't know why. You can't detect these errors via the (command) interface. The only way in pure AutoLISP I've found of detecting these errors involves turning on the log and inspecting the log every time a 3d command is done. Instead of bothering with all this, if after running IncrementalUnion the number of solids is greater than 1 I call RandomUnion. Somehow picking non-ajacent solids make the 3d modeling errors go away.

The result of the big UNION is 1 solid representing the land mass. Now we can get rid of the artificial portion of the solid resulting from "squaring the data" above. I have a region in my drawing representing the lot perimeter. I simply make sure DELOBJ=0, extrude that region to 10000 and INTERSECT the region with the land mass solid.

Now we're ready to make the topo map. Determine your contour line division. I've chosen 5 feet. Set the view to front. Start at the bottom. (You might want to save the landmass somewhere else first.)

set Z=5 Until you've reached the highest elevation SLICE the landmass thru the xy plane at Z EXPLODE the solid just created SELECT all of the resulting regions just above (Z-5) and just below Z and delete them (Use SELECT with the "box" method, although I wouldn't be surprised if there's a better way.) The remaining region represents the topo line for that elevation, move it down to Z=0. Increment Z by 5 feet end loop

Set your view to top.

Done.