1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 import string, sys,time
16 from opengltk.OpenGL import GL
17 import Numeric
18 from struct import unpack
19 from Volume.Renderers.UTVolumeLibrary import UTVolumeLibrary
20
21
22 from DejaVu.viewerFns import checkKeywords
23 from Volume.Grid3D import Grid3DUC
24
25 from DejaVu.VolumeGeom import VolumeGeom, CropBox
26
28
29 kDisable = 0
30 kSubVolume = 1
31 k3DCross = 2
32 k3DCrossInvert = 3
33 k3DCrossInvert = 4
34 k3DFence = 5
35 k3DFenceInvert = 6
36
38 self.volgeom = volgeom
39 self.data = None
40 self.flag = self.kSubVolume
41 self.xmin = 0
42 self.xmax = 0
43 self.ymin = 0
44 self.ymax = 0
45 self.zmin = 0
46 self.zmax = 0
47 self.size = (0,0,0)
48
50 self.data = Numeric.array(self.volgeom.dataArr)
51 nx,ny,nz = self.volgeom.volumeSize
52 self.xmin = 0
53 self.xmax = nx
54 self.ymin = 0
55 self.ymax = ny
56 self.zmin = 0
57 self.zmax = nz
58 self.size = (nx,ny,nz)
59
61
62 self.xmin = xmin
63 self.xmax = xmax+1
64 if self.flag == self.kDisable: return
65 self.data[self.zmin:self.zmax, self.ymin:self.ymax, xmin:xmax+1] = self.volgeom.dataArr[self.zmin:self.zmax, self.ymin:self.ymax, xmin:xmax+1]
66 self.data[:, :, :xmin]=0
67 self.data[:, :, xmax+1: ]=0
68 nx,ny,nz=self.size
69 self.volgeom.volume.uploadColorMappedData(self.data.flat, nx,ny,nz)
70
72
73 self.ymax = ymax+1
74 self.ymin = ymin
75 if self.flag == self.kDisable: return
76 self.data[self.zmin:self.zmax, ymin:ymax+1, self.xmin:self.xmax] = self.volgeom.dataArr[self.zmin:self.zmax, ymin:ymax+1, self.xmin:self.xmax]
77 self.data[:, :ymin, :]=0
78 self.data[:, ymax+1:, :]=0
79 nx,ny,nz=self.size
80 self.volgeom.volume.uploadColorMappedData(self.data.flat,
81 nx, ny, nz)
82
84
85 self.zmax = zmax+1
86 self.zmin = zmin
87 if self.flag == self.kDisable: return
88 self.data[zmin:zmax+1, self.ymin:self.ymax, self.xmin:self.xmax] = \
89 self.volgeom.dataArr[zmin:zmax+1, self.ymin:self.ymax,
90 self.xmin:self.xmax]
91 self.data[:zmin, :, :]=0
92 self.data[zmax+1:, :, :]=0
93 nx,ny,nz=self.size
94 self.volgeom.volume.uploadColorMappedData(self.data.flat,
95 nx, ny, nz)
96
97 - def SetSlabs(self, xmin, xmax, ymin, ymax, zmin, zmax):
98
99 self.data[zmin:zmax+1, ymin:ymax+1, xmin:xmax+1] = \
100 self.volgeom.dataArr[zmin:zmax+1, ymin:ymax+1, xmin:xmax+1]
101 nx,ny,nz=self.size
102 if ymin > 0:
103 self.data[: , : ymin, :] = 0
104 if ymax < ny:
105 self.data[:, ymax+1: , :] = 0
106 if xmin > 0:
107 self.data[:xmin, :, :] = 0
108 if xmax < nx:
109 self.data[xmax+1:, :, :] = 0
110 if zmin > 0:
111 self.data[:, :, :zmin] = 0
112 if zmax < nz:
113 self.data[:, :, zmax+1:] = 0
114 self.volgeom.volume.uploadColorMappedData(self.data.flat,
115 nx, ny, nz)
116 self.xmin = xmin
117 self.xmax = xmax
118 self.ymax = ymax
119 self.ymin = ymin
120 self.zmax = zmax
121 self.zmin = zmin
122
124 self.flag = flag
125 if flag == self.kDisable:
126 nx,ny,nz=self.size
127 self.xmin = 0
128 self.xmax = nx
129 self.ymin = 0
130 self.ymax = ny
131 self.zmin = 0
132 self.zmax = nz
133 self.data[self.zmin:self.zmax+1,
134 self.ymin:self.ymax+1,
135 self.xmin:self.xmax+1] = \
136 self.volgeom.dataArr[self.zmin:self.zmax+1,
137 self.ymin:self.ymax+1,
138 self.xmin:self.xmax+1]
139 self.volgeom.volume.uploadColorMappedData(self.data.flat,
140 nx, ny,nz)
141
142
144
146 """ Display the render volume"""
147 if not self.dataArr:
148 return
149 t1 = time.time()
150 UTVolumeLibrary.InitTexParameteri()
151 self.volume.renderVolume()
152 t2 = time.time()
153
154
156
157 apply( VolumeGeom.__init__, (self,name,0), kw)
158 self.inheritXform=1
159 self.Set(frontPolyMode='fill', backPolyMode='fill')
160
161
162 self.volume = UTVolumeLibrary.VolumeRenderer()
163 self.dataArr =None
164 self.byte_map=None
165
166
167
168
169 self.volumeSize = (0,0,0)
170 self.onaddVolume_list = []
171 self.volrenInitialized = 0
172 self.updateBoundBox = 1
173 self.volume.GetSize = self.GetSize
174 self.crop = VolumeCrop(self)
175 self.cropBox = CropBox(self)
176 self.cropBox.crop = self.crop
177 self.masterObject = None
178 self.cropOpts = ['off','SubVolume']
179 self.firstLoaded = 1
180
181
182 self.coarseRenderingQuality = 0.5
183
184
186 self.volume.setQuality(self.coarseRenderingQuality)
187
188
190 self.volume.setQuality(1.0)
191
192
194 """ Initialize the volume rendering"""
195 if not self.volume.initRenderer():
196 print "Warning, there was an error initializing the volume renderer\n"
197 else:
198 self.volrenInitialized = 1
199
200
202 """ Get the data from binary file,rawiv format"""
203
204
205 myfile = open(file, "rb" )
206
207 header=myfile.read(68)
208
209 h = unpack('>6f5I6f',header)
210 width=int(h[8])
211 height=int(h[9])
212 depth =int(h[10])
213
214
215 l = myfile.read(width*height*depth)
216 self.dataArr = Numeric.fromstring(l, Numeric.UnsignedInt8,
217 (width*height*depth))
218 self.volumeSize = (width,height,depth)
219
220 myfile.close()
221
222 if self.dataArr == None:
223 print " you need to load a volume data"
224 return
225 if self.firstLoaded:
226 if self.viewer:
227 rootObject = self.viewer.rootObject
228 self.minBB=(-0.5, -0.5, -0.5)
229 self.maxBB=(0.5, 0.5, 0.5)
230 self.viewer.NormalizeCurrentObject()
231 self.firstLoaded = 0
232 status = self.volume.uploadColorMappedData(self.dataArr,width,height,depth)
233 if status !=1:
234 raise RuntimeError("uploadColorMappedData() in LoadVoulume failed. Status %d"% status)
235
236 self.dataArr = Numeric.reshape(self.dataArr,
237 (depth,height,width))
238 if self.byte_map == None:
239 self.grayRamp()
240
241 self.crop.updateData()
242 nx,ny,nz = self.volumeSize
243 self.cropBox.setVolSize((nx,ny,nz))
244 self.cropBox.xmin = 0
245 self.cropBox.xmax = nx
246 self.cropBox.ymin = 0
247 self.cropBox.ymax = ny
248 self.cropBox.zmin = 0
249 self.cropBox.zmax = nz
250 self.cropBox.update()
251 for c in self.onaddVolume_list:
252 c.OnAddVolumeToViewer()
253
254
256 assert isinstance(grid, Grid3DUC)
257
258 if not self.volrenInitialized:
259 if not self.viewer:
260 print "self.viewer: ", self.viewer
261 return
262 self.InitVolumeRenderer()
263 for c in self.viewer.cameras:
264 c.addButtonDownCB(self.coarseRendering)
265 c.addButtonUpCB(self.fineRendering)
266
267 orig = grid.origin[:]
268 step = grid.stepSize
269
270 nx, ny, nz = grid.data.shape
271 gridSize = [nx*step[0], ny*step[1], nz*step[2]]
272 gridSize2 = [gridSize[0]*0.5, gridSize[1]*0.5, gridSize[2]*0.5]
273 maxgrid = [ orig[0]+gridSize[0],
274 orig[1]+gridSize[1],
275 orig[2]+gridSize[2]]
276 transl = [ orig[0]+gridSize2[0],
277 orig[1]+gridSize2[1],
278 orig[2]+gridSize2[2]]
279
280
281
282 if grid.crystal:
283
284 x, y, z = grid.getStepSizeReal()
285
286
287 from mglutil.math.crystal import Crystal
288 if hasattr(grid, 'dataDims'):
289
290 dx = grid.dimensions[0] - grid.dataDims[0] - 1
291 dy = grid.dimensions[1] - grid.dataDims[1] - 1
292 dz = grid.dimensions[2] - grid.dataDims[2] - 1
293 ry = float(dx)/dy
294 rz = float(dx)/dz
295 else:
296 ry = rz = 1.0
297
298 dims = (grid.dimensions[0]-1, (grid.dimensions[1]-1)*ry,
299 (grid.dimensions[2]-1)*rz )
300 cryst = Crystal( (dims[0]*x, dims[1]*y, dims[2]*z),
301 grid.crystal.angles)
302
303 matrix = Numeric.identity(4, 'f')
304 matrix[:3, :3] = cryst.ftoc.astype('f')
305 matrix.shape = (16,)
306
307
308
309 self.MatrixRot, MatrixTransl, self.MatrixScale = self.Decompose4x4(
310 matrix, cleanup=False)
311
312
313 self.MatrixScale = (self.MatrixScale[0], self.MatrixScale[1]/ry,
314 self.MatrixScale[2]/rz)
315
316 origin = grid.crystal.toCartesian(grid.origin)
317 self.MatrixTransl = (origin[0]+MatrixTransl[0]+dims[0]*0.5*x,
318 origin[1]+MatrixTransl[1]+dims[1]*0.5*y/ry,
319 origin[2]+MatrixTransl[2]+dims[2]*0.5*z/rz)
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334 RotInv = Numeric.transpose(Numeric.reshape(self.MatrixRot, (4,4)))
335 self.MatrixRotInv = Numeric.reshape(RotInv, (16,))
336
337 self.MatrixRot = self.MatrixRot.astype('f')
338 self.MatrixRotInv = self.MatrixRot.astype('f')
339
340 else:
341 self.setMatrixComponents(trans=transl)
342 self.setMatrixComponents(scale=gridSize, trans=transl)
343
344 if self.firstLoaded:
345 if self.viewer:
346 rootObject = self.viewer.rootObject
347 self.minBB = [-0.5, -0.5, -0.5]
348 self.maxBB = [ 0.5, 0.5, 0.5]
349
350 self.viewer.NormalizeCurrentObject()
351 self.firstLoaded = 0
352
353
354
355
356
357
358
359
360
361
362 arr = Numeric.array( Numeric.transpose(grid.data),
363 grid.data.typecode())
364 upload = self.volume.uploadColorMappedData
365 status = upload(arr.flat, nx, ny,nz)
366 if status !=1:
367 raise RuntimeError("uploadColorMappedData() in AddVolume failed. Status %d"% status)
368
369 self.dataArr = Numeric.reshape(arr,(nz,ny,nx))
370 self.volumeSize = (nx,ny,nz)
371 if self.byte_map == None:
372 self.grayRamp()
373
374 self.crop.updateData()
375 self.cropBox.setVolSize((nx,ny,nz))
376 self.cropBox.xmin = 0
377 self.cropBox.xmax = nx
378 self.cropBox.ymin = 0
379 self.cropBox.ymax = ny
380 self.cropBox.zmin = 0
381 self.cropBox.zmax = nz
382 self.cropBox.update()
383 for c in self.onaddVolume_list:
384 c.OnAddVolumeToViewer()
385
386 - def AddVolume(self, arr, nx, ny, nz, datatype='numarr'):
387 if datatype == 'numarr':
388 assert len(arr.shape) == 1
389
390 if not self.volrenInitialized:
391 if not self.viewer:
392 return
393
394 self.InitVolumeRenderer()
395
396 if self.firstLoaded:
397 if self.viewer:
398 rootObject = self.viewer.rootObject
399 self.minBB=(-0.5, -0.5, -0.5)
400 self.maxBB=(0.5, 0.5, 0.5)
401 self.viewer.NormalizeCurrentObject()
402 self.firstLoaded = 0
403 if datatype == 'numarr':
404 status = self.volume.uploadColorMappedData(arr,nx,ny,nz)
405 else:
406 status = self.volume.uploadZeroPaddedData(arr,nx,ny,nz)
407
408 if status !=1:
409 raise RuntimeError("uploadColorMappedData() in AddVolume failed. Status %d"% status)
410 self.dataArr = Numeric.reshape(arr,(nz,ny,nx))
411 self.volumeSize = (nx,ny,nz)
412 if self.byte_map == None:
413 self.grayRamp()
414
415 self.crop.updateData()
416 self.cropBox.setVolSize((nx,ny,nz))
417 self.cropBox.xmin = 0
418 self.cropBox.xmax = nx
419 self.cropBox.ymin = 0
420 self.cropBox.ymax = ny
421 self.cropBox.zmin = 0
422 self.cropBox.zmax = nz
423 self.cropBox.update()
424 for c in self.onaddVolume_list:
425 c.OnAddVolumeToViewer()
426
428 """ Get the colormap data from binaries files"""
429
430 myfile = open(file, "rb" )
431 l = myfile.read(256*4)
432 self.byte_map =Numeric.fromstring(l,(256*4),
433 Numeric.UnsignedInt8)
434 self.byte_map = Numeric.reshape(self.byte_map,(256,4))
435 myfile.close()
436 if self.byte_map == None:
437 print " you need to load a color map"
438 return
439 else:
440 self.volume.uploadColorMap(self.byte_map)
441
442
444 """ update the color from the color map data"""
445
446
447 val = values[1] *255
448 self.byte_map[values[0]:values[0]+len(val),:3] = val.astype(Numeric.UnsignedInt8)
449 self.volume.uploadColorMap(self.byte_map)
450 self.viewer.Redraw()
451
453 """ update the opacity of the colormap"""
454
455 val = values[1]
456 self.byte_map[values[0]:values[0]+len(val),3] = val.astype(Numeric.UnsignedInt8)
457 self.volume.uploadColorMap(self.byte_map)
458 self.viewer.Redraw()
459
461 self.byte_map = Numeric.transpose(Numeric.array([range(256),range(256),range(256),range(256)] )).astype(Numeric.UnsignedInt8)
462 self.volume.uploadColorMap(self.byte_map)
463
464 - def Set(self, check=1, redo=1, **kw):
465 if __debug__:
466 if check:
467 apply( checkKeywords, (self.name,self.keywords), kw)
468 apply( VolumeGeom.Set, (self,0,0), kw)
469 s = kw.get('volscale')
470 tr = kw.get('voltranslate')
471 if s:
472 self.SetScale(s)
473 if tr:
474 tr = Numeric.array(tr)
475 self.SetTranslation(tr)
476
478 return self.volumeSize
479
480
481 if __name__ == '__main__':
482
483
484 from DejaVu import Viewer
485 vi = Viewer()
486
487 g = UTVolRenGeom('volren')
488 g.viewer = vi
489
490 vi.cameras[0].Activate()
491 g.InitVolumeRenderer()
492
493 g.LoadVolume("vh4.rawiv")
494 g.grayRamp()
495
496
497
498
499 vi.AddObject(g)
500
501
502
503
504
505
506
507
508