License New BSD license
Lines 162
Keywords
Blender (3) DEM (1) GIS (7)
Permissions
Owner: Stou S.
Viewable by Everyone
Editable by All Siafoo Users
Hide
Easily highlight source code for your blog with our Syntax Highlighter. Join Siafoo Now or Learn More

Load DEM Terrain in Blender Atom Feed 1

In Brief A somewhat unfinished DEM loader script.... more
# 's
  1#!BPY
2"""
3Name: 'DEM import'
4Blender: 243
5Group: 'Import'
6Tooltip: 'Imports anything that GDAL can read including DEMs'
7License: New BSD
8"""
9
10import Blender
11import BPyMessages
12import bpy
13import datetime
14from osgeo import gdal, gdalconst
15import numpy
16import time
17
18from Blender import BGL, Draw, Mesh, Scene, Window, sys
19from Blender.Window import DrawProgressBar
20
21from numpy import array, hstack
22
23#terrain_file = '/home/stou/3D/terrain/77230965/77230965.tif'
24#terrain_file = '/home/stou/3D/terrain/93988521/93988521.tif'
25terrain_file = '/home/stou/3D/terrain/19306769/19306769.tif'
26
27
28grid_sizes_labels = [['1/3 Arcsecond', 1.0/3.0],
29 ['1/9 Arcsecond', 1.0/9.0],
30 ['1 Arcsecond', 1.0]
31 ]
32
33grid_sizes = [['1/3 Arcsecond', 10.0], ['1/9 Arcsecond', 10.0]]
34
35# 1 BU = Xm
36bu_in_meters = 25.0
37
38def load_dem(sce):
39
40 dataset = gdal.Open(terrain_file, gdalconst.GA_ReadOnly)
41 terrain_data = array(dataset.ReadAsArray())#xsize=100,ysize=100))
42
43 grid_size = grid_sizes[0][1]
44
45# x_size = dataset.RasterXSize
46# y_size = dataset.RasterYSize
47
48 x_size = terrain_data.shape[0]
49 y_size = terrain_data.shape[1]
50
51 x_scale = y_scale = grid_size/bu_in_meters
52
53 print terrain_data.shape, terrain_data.reshape(-1, 1).shape
54 print x_scale, y_scale
55
56# x_scale = float(x_size)
57# y_scale = float(y_size)
58
59 z_scale = 1/bu_in_meters
60
61 scale = 1
62
63 window = Mesh.New('Terrain')
64
65 verts = []
66
67 time_start = time.time()
68
69 DrawProgressBar (0.0, "Preparing verteces...")
70
71 x, y = numpy.meshgrid(range(x_size), range(y_size))
72
73# print x,y
74# return
75
76# data_verts = hstack((x.reshape(-1, 1), y.reshape(-1, 1)[::-1], terrain_data.reshape(-1, 1)))
77 data_verts = hstack((y.reshape(-1, 1), x.reshape(-1, 1), terrain_data.T.reshape(-1, 1)))
78
79 data_verts = array([0, y_size, 0]) + array([1, -1, 1])*data_verts
80
81 DrawProgressBar (0.3, "Scaling data...")
82 verts_ar = data_verts * array([x_scale, y_scale, z_scale], dtype=float)
83
84 DrawProgressBar (0.4, "Adding verteces...")
85 window.verts.extend(verts_ar.tolist())
86
87 vert_count = x_size*y_size
88
89 DrawProgressBar (0.5, "Generating faces...")
90
91 idx_ar = numpy.arange((y_size-1)*(x_size))
92 idx_truth = (idx_ar + 1) % x_size != 0
93 v_idx = idx_ar[idx_truth].reshape(-1, 1)
94
95 faces = hstack((v_idx + x_size,
96 v_idx + x_size + 1,
97 v_idx + 1,
98 v_idx)).tolist()
99
100 DrawProgressBar (0.8, "Generating faces...")
101 window.faces.extend(faces)
102 DrawProgressBar (1.0, "Adding faces...")
103
104# for face in window.faces:
105# face.smooth = 1
106
107 print "Total Elapsed time: " + str(datetime.timedelta(seconds = (time.time() - time_start)))
108
109 window.update()
110 # Save the object to the scene
111 sce.objects.new(window, 'myTerrain')
112 Blender.Redraw()
113
114def main():
115 # Gets the current scene, there can be many scenes in 1 blend file.
116 sce = bpy.data.scenes.active
117
118 # Get the active object, there can only ever be 1
119 # and the active object is always the editmode object.
120# ob_act = sce.objects.active
121
122 Window.WaitCursor(1)
123# me = ob_act.getData(mesh=1) # old NMesh api is default
124 t = sys.time()
125
126 # Run the mesh editing function
127 load_dem(sce)
128
129# main_gui = GeoToolsUI()
130
131 # Timing the script is a good way to be aware on any speed hits when scripting
132 print 'My Script finished in %.2f seconds' % (sys.time()-t)
133 Window.WaitCursor(0)
134
135#mystring = ""
136#mymsg = ""
137#toggle = 0
138
139
140class GeoToolsUI(object):
141
142 def __init__(self):
143 self.mystring = ''
144 self.mymsg = ''
145 self.toggle = 0
146
147 Draw.Register(self.gui, self.event, self.button_event)
148
149 def button_event(self, evt): # the function to handle Draw Button events
150
151 if evt == 1:
152 self.mymsg = "You pressed the toggle button."
153 self.toggle = 1 - self.toggle
154 Draw.Redraw(1)
155
156 def event(self, evt, val): # the function to handle input events
157 if not val: # val = 0: it's a key/mbutton release
158 if evt in [Draw.LEFTMOUSE, Draw.MIDDLEMOUSE, Draw.RIGHTMOUSE]:
159 self.mymsg = "You released a mouse button."
160 Draw.Redraw(1)
161 return
162
163 if evt == Draw.ESCKEY:
164 Draw.Exit() # exit when user presses ESC
165 return
166
167 elif Draw.AKEY <= evt <= Draw.ZKEY: self.mystring += chr(evt)
168 elif evt == Draw.SPACEKEY: self.mystring += ' '
169 elif evt == Draw.BACKSPACEKEY and len(self.mystring):
170 self.mystring = mystring[:-1]
171 else: return # no need to redraw if nothing changed
172
173 Draw.Redraw(1)
174
175
176 def gui(self): # the function to draw the screen
177 if len(self.mystring) > 90: self.mystring = ""
178 BGL.glClearColor(0, 0, 1, 1)
179 BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
180 BGL.glColor3f(1, 1, 1)
181 Draw.Toggle("Toggle", 1, 10, 10, 55, 20, self.toggle, "A toggle button")
182 BGL.glRasterPos2i(72, 16)
183 if self.toggle: toggle_state = "down"
184 else: toggle_state = "up"
185 Draw.Text("The toggle button is %s." % toggle_state, "small")
186 BGL.glRasterPos2i(10, 230)
187 Draw.Text("Type letters from a to z, ESC to leave.")
188 BGL.glRasterPos2i(20, 200)
189 Draw.Text(self.mystring)
190 BGL.glColor3f(1, 0.4, 0.3)
191 BGL.glRasterPos2i(340, 70)
192 Draw.Text(self.mymsg, "tiny")
193
194
195# This lets you can import the script without running it
196if __name__ == '__main__':
197 main()

A somewhat unfinished DEM loader script.

Note

You need GDAL (with Python bindings) and Numpy in order to get this to work.

To use modify the source, edit the terrain_file variable and put the name of the DEM file you'd like to import. Open the file with the Blender text editor and select run from the menu or press Alt+P.

Warning

This script isn't finished and it seems to only work with some DEMs... good luck.

Comments

over 7 years ago (12 Feb 2009 at 12:49 PM) by alexandra_diehl
Thank you Stou!!! your script is very useful. I imported USGS dems, SRTM dems, etc!
Then I exported these to direct x using http://directpython.sourceforge.net/exportx.html

I hope this could be useful too!

Best regards!

Alexandra.
over 7 years ago (14 Feb 2009 at 01:26 PM) by Stou S.
Excellent!