martedì 13 aprile 2010

Creating a 3D terrain from height measurements

Sometimes we architects have to create a digital representation of a ground surface topography (DEM) for 3D visualizations. I usually start with a .dwg file and a bunch of  height measurements. The image on the left is a typical case.
I invented an "original" way to crank out a digital elevation model.
I usually use AutoCAD Map and a couple of extra tools.
I export all measurements in a text file and then import it into AutoCAD Map. Exporting all measurements is quite simple: I use CAD2FILE, a free Lisp program that allows me to export all needed parameters into a text file.

We can select the file type to create (on the left) and the properties to send to the file. In my case I select Insertion Point and click  Okay.

The result is a text file with this structure:

Start X,Start Y,Start Z,Text Value,

Start X, Start Y,Start Z are the coordinates of the insertion point of the measurement. Value is the measurement.

Cool! What I wanna do now is fix this file because AutoCAD Map can import a series of x, y and z coordinates only, without other parameters.
To do this I wrote a simple Java program named Virgola:

// Author: Stefano Bolli
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Virgola {

public static void main(String[] args) {
Virgola virgola = new Virgola();

public Virgola() {

// Text directory
File textDir = new File(".");
// Filter for text files
TextFilter tfilter = new TextFilter();
// Text files
String[] textList = textDir.list(tfilter);

if (textList.length == 1 ) {
System.out.println("I found the file:" + "\n");
System.out.println(textList[0] + "\n");
System.out.println("I'm fixing the file...");
else if (textList.length > 0) {
System.out.println("\nFound multiple files. Indicate the file you wanna fix:");

for (int i = 0; i < textList.length; i++)
System.out.println(i + ") " + textList[i]);
try {
BufferedReader in = new BufferedReader(new InputStreamReader(;
String fileChoosen = in.readLine();
int x = Integer.parseInt(fileChoosen);
} catch (IOException e) { }
System.out.println("No text file found");

public void readFile(String fileToRead) {
try {
BufferedReader br = new BufferedReader(new FileReader(new File(fileToRead)));
String line;
Vector vector = new Vector();
while ((line = br.readLine()) != null) {
// Store the row in the vector.
SaveFile(vector, changeNameToFile(fileToRead));
catch (IOException e) { } }
public String changeNameToFile(String name) {
String newName = name.substring(0, name.lastIndexOf(".")) + "_fixed_by_Virgola.txt";
return newName;
public void SaveFile(Vector v, String fileToSave) {
try {
BufferedWriter out = new BufferedWriter(new FileWriter(fileToSave));
for (int i = 0; i < v.size(); i++) {
String s = (String)v.elementAt(i);
if (!s.startsWith("Start")) {
out.write(cleanLine(s) + "\n");
} catch (IOException e) {
public String cleanLine(String line) {
String oldLine = line.substring(0, line.lastIndexOf(","));
String newLine = oldLine.substring(0, oldLine.indexOf(",0,")) + oldLine.substring(oldLine.lastIndexOf(","));
return newLine;
/** * Filter for text files. */
class TextFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
boolean acceptFile = false;
if (name.endsWith(".txt"))
acceptFile = true;
return acceptFile;

If someone needs this program, I can compile it and send as .exe file.

Ok, now we can import the text file into AutoCAD Map and create the terrain.
The final mesh is a triangular irregular network and can be imported into 3d softwares like Maya o 3DS Max: as you can see, I was working on a level land with a river. There are a few errors I can fix quickly before smoothing the mesh.

Best regards.