graphkit 0.1.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,43 @@
1
+ class GraphKit
2
+ # Convert graphkit into a string which can be used by Mathematica
3
+ def to_mathematica
4
+ str = ""
5
+ case data[0].ranks
6
+ when [1], [1, 1]
7
+ str = "ListPlot[{#{data.map{|dk| dk.to_mathematica}.join(',')}}"
8
+
9
+
10
+ end
11
+ pas = plot_area_size
12
+ if (xrange or yrange or zrange)
13
+ str << ", PlotRange -> "
14
+ str << "{#{((0...naxes).to_a.map do |nax|
15
+ ax = AXES[nax]
16
+ specified_range = (send(ax + :range) or [nil, nil])
17
+ "{#{specified_range.zip(pas[nax]).map{|spec, pasr| (spec or pasr).to_s}.join(',')}}"
18
+ end).join(',')}}"
19
+ end
20
+ str << ", PlotStyle -> {#{(data.size.times.map do |i|
21
+ ((data[i].mtm.plot_style) or "{}")
22
+ end).join(',')}}"
23
+
24
+ str << "]"
25
+
26
+ end
27
+
28
+ class DataKit
29
+ class MathematicaOptions < KitHash
30
+ end
31
+ def mtm
32
+ self[:mtm] ||= MathematicaOptions.new
33
+ end
34
+ def to_mathematica
35
+ case ranks
36
+ when [1], [1,1], [1, 1, 1]
37
+ "{#{(axes.values.map{|ax| ax.data.to_a}.transpose.map do |datapoint|
38
+ "{#{datapoint.map{|coord| coord.to_s}.join(',')}}"
39
+ end).join(',')}}"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,550 @@
1
+ require 'matrix'
2
+ require 'stringio'
3
+ # Methods for writing graphkits to csv (comma separated value) files
4
+
5
+
6
+
7
+ class GraphKit
8
+
9
+
10
+
11
+
12
+
13
+
14
+ def to_vtk_legacy_fast(options={})
15
+ File.open(options[:file_name], 'w'){|file| file.puts to_vtk_legacy}
16
+ end
17
+ def to_vtk_legacy(options={})
18
+ check_integrity
19
+ ep 'to_vtk_legacy'
20
+ stringio = options[:io] || StringIO.new
21
+ npoints = data.map{|dk| dk.vtk_legacy_size}.sum
22
+ stringio << <<EOF
23
+ # vtk DataFile Version 3.0
24
+ vtk output
25
+ ASCII
26
+ DATASET UNSTRUCTURED_GRID
27
+ POINTS #{npoints} float
28
+ EOF
29
+ data.each do |dk|
30
+ dk.vtk_legacy_points(io: stringio)
31
+ #stringio << "\n\n"
32
+ end
33
+ #ncells = data.map{|dk| dk.vtk_legacy_cells(action: :count)}.sum
34
+ #ncell_elements = data.map{|dk| dk.vtk_legacy_cells(action: :count_elements)}.sum
35
+ cellstring = ""
36
+ pc = 0
37
+ data.each do |dk|
38
+ cellstring += dk.vtk_legacy_cells pointcount: pc
39
+ pc += dk.vtk_legacy_size
40
+ #stringio << "\n\n"
41
+ end
42
+ ncells = cellstring.count("\n")
43
+ ncell_elements = cellstring.scan(/\s+/).size
44
+ stringio << <<EOF
45
+
46
+ CELLS #{ncells} #{ncell_elements}
47
+ EOF
48
+ stringio << cellstring
49
+ stringio << <<EOF
50
+
51
+ CELL_TYPES #{ncells}
52
+ EOF
53
+ data.each do |dk|
54
+ dk.vtk_legacy_cell_types(io: stringio)
55
+ #stringio << "\n\n"
56
+ end
57
+ stringio << <<EOF
58
+
59
+ POINT_DATA #{npoints}
60
+ SCALARS myvals float
61
+ LOOKUP_TABLE default
62
+ EOF
63
+ data.each do |dk|
64
+ dk.vtk_legacy_point_data(io: stringio)
65
+ #stringio << "\n\n"
66
+ end
67
+ return stringio.string unless options[:io]
68
+ end
69
+
70
+
71
+ class DataKit
72
+
73
+ class TensorArray
74
+ def initialize(arr)
75
+ @arr=arr
76
+ end
77
+ def [](*args)
78
+ args.reverse.inject(@arr) do |arr,idx|
79
+ arr[idx]
80
+ end
81
+ end
82
+ end
83
+ def vtk_legacy_size
84
+ axs = self.axes.values_at(*AXES).compact
85
+ return axs[-1].shape.product
86
+ end
87
+ def vtk_legacy_points(options={})
88
+ io = options[:io] || StringIO.new
89
+ axs = self.axes.values_at(*AXES).compact
90
+ #ep 'axs', axs
91
+ dl = data_length = axs[-1].shape.product
92
+ dat = axs.map{|ax| ax.data}
93
+ sh = shapes
94
+ cml_sh = sh.map do |sh|
95
+ cml = 1
96
+ sh.reverse.map{|dim| cml *= dim; cml}.reverse
97
+ end
98
+ dat = dat.map do |d|
99
+ d.kind_of?(Array) ? TensorArray.new(d) : d
100
+ end
101
+
102
+ if self.errors
103
+ raise "Errors can only be plotted for 1D or 2D data" unless ranks == [1] or ranks == [1,1]
104
+ edat = self.errors.values_at(:x, :xmin, :xmax, :y, :ymin, :ymax).compact
105
+ #ep 'edat', edat
106
+ end
107
+ case ranks
108
+ when [1]
109
+ dl.times do |n|
110
+ next unless dat[-1][n]
111
+ dat.times.each{|idx| io << "0 " << idx << " #{dat[0][n]}"}
112
+ io << "\n"
113
+ end
114
+ when [1,1]
115
+ dl.times do |n|
116
+ next unless dat[-1][n]
117
+ io << "0 " << dat[0][n] << ' ' << dat[1][n]
118
+ #io << " " << edat.map{|e| e[n].to_s}.join(" ") if self.errors
119
+ io << "\n"
120
+ end
121
+ when [1,1,1],[1,1,1,1]
122
+ dl.times do |n|
123
+ next unless dat[-1][n]
124
+ io << dat[0][n] << ' ' << dat[1][n] << ' ' << dat[2][n]
125
+ io << "\n"
126
+ end
127
+ when [1,1,2]
128
+ sh[-1][0].times do |i|
129
+ sh[-1][1].times do |j|
130
+ next unless dat[2][i,j]
131
+ d = [dat[0][i], dat[1][j], dat[2][i,j]]
132
+ io << d[0] << " " << d[1] << " " << d[2] << "\n"
133
+ end
134
+ #io << "\n" unless sh[-1][1] == 1
135
+ end
136
+ when [2,2,2], [2,2,2,2]
137
+ sh[-1][0].times do |i|
138
+ sh[-1][1].times do |j|
139
+ next unless dat[2][i,j]
140
+ d = [dat[0][i,j], dat[1][i,j], dat[2][i,j]]
141
+ io << d[0] << " " << d[1] << " " << d[2] << "\n"
142
+ end
143
+ #io << "\n" unless sh[-1][1] == 1
144
+ end
145
+ when [1,1,2,2]
146
+ sh[-1][0].times do |i|
147
+ sh[-1][1].times do |j|
148
+ next unless dat[3][i,j]
149
+ d = [dat[0][i], dat[1][j], dat[2][i,j], dat[3][i,j]]
150
+ io << d[0] << " " << d[1] << " " << d[2] << "\n"
151
+ end
152
+ #io << "\n" unless sh[-1][1] == 1
153
+ end
154
+ when [1,1,1,3]
155
+ sh[-1][0].times do |i|
156
+ sh[-1][1].times do |j|
157
+ sh[-1][2].times do |k|
158
+ next unless dat[3][i,j,k]
159
+
160
+ d = [dat[0][i], dat[1][j], dat[2][k], dat[3][i,j,k]]
161
+ io << d[0] << " " << d[1] << " " << d[2] << "\n"
162
+ end
163
+ end
164
+ end
165
+ #when [2,2,2,2]
166
+ #sh[-1][0].times do |i|
167
+ #sh[-1][1].times do |j|
168
+ #next unless dat[3][i,j]
169
+ ##d = [dat[0][i,j], dat[1][i,j], dat[2][i,j], dat[3][i,j]]
170
+ #io << "#{dat[0][i,j]} #{dat[1][i,j]} #{dat[2][i,j]}\n"
171
+ ##d.each{|dt| io << dt << " "}
172
+ ##io << "\n"
173
+ #end
174
+ #end
175
+ when [3,3,3,3]
176
+ #pp dat
177
+ #pp dat
178
+ #pp sh
179
+ sh[-1][0].times do |i|
180
+ sh[-1][1].times do |j|
181
+ sh[-1][2].times do |k|
182
+ next unless dat[3][i,j,k]
183
+ #p [i,j,k]
184
+
185
+ #d = [dat[0][i,j,k], dat[1][i,j,k], dat[2][i,j,k], dat[3][i,j,k]]
186
+ io << "#{dat[0][i,j,k]} #{dat[1][i,j,k]} #{dat[2][i,j,k]}\n"
187
+ #d.each{|dt| io << dt << " "}
188
+ #io << "\n"
189
+ end
190
+ end
191
+ end
192
+ end
193
+
194
+ return io.string unless options[:io]
195
+ end
196
+ def vtk_legacy_point_data(options={})
197
+ io = options[:io] || StringIO.new
198
+ axs = self.axes.values_at(*AXES).compact
199
+ #ep 'axs', axs
200
+ dl = data_length = axs[-1].shape.product
201
+ dat = axs.map{|ax| ax.data}
202
+ sh = shapes
203
+ cml_sh = sh.map do |sh|
204
+ cml = 1
205
+ sh.reverse.map{|dim| cml *= dim; cml}.reverse
206
+ end
207
+ dat = dat.map do |d|
208
+ d.kind_of?(Array) ? TensorArray.new(d) : d
209
+ end
210
+
211
+ if self.errors
212
+ raise "Errors can only be plotted for 1D or 2D data" unless ranks == [1] or ranks == [1,1]
213
+ edat = self.errors.values_at(:x, :xmin, :xmax, :y, :ymin, :ymax).compact
214
+ #ep 'edat', edat
215
+ end
216
+ case ranks
217
+ when [1], [1,1], [1,1,1], [1,1,1,1]
218
+ dl.times do |n|
219
+ next unless dat[-1][n]
220
+ #dat.each{|d| io << d[n] << " "}
221
+ #io << " " << edat.map{|e| e[n].to_s}.join(" ") if self.errors
222
+ io << "#{dat[3] ? dat[3][n] : 0}\n"
223
+ end
224
+ #when [1,1,2]
225
+ #sh[-1][0].times do |i|
226
+ #sh[-1][1].times do |j|
227
+ #next unless dat[2][i,j]
228
+ #d = [dat[0][i], dat[1][j], dat[2][i,j]]
229
+ #io << d[0] << ", " << d[1] << ", " << d[2] << "\n"
230
+ #end
231
+ ##io << "\n" unless sh[-1][1] == 1
232
+ #end
233
+ when [1,1,2], [2,2,2]
234
+ sh[-1][0].times do |i|
235
+ sh[-1][1].times do |j|
236
+ next unless dat[2][i,j]
237
+ #d = [dat[0][i,j], dat[1][i,j], dat[2][i,j]]
238
+ #io << d[0] << ", " << d[1] << ", " << d[2] << "\n"
239
+ io << "0\n"
240
+ end
241
+ #io << "\n" unless sh[-1][1] == 1
242
+ end
243
+ when [1,1,2,2]
244
+ sh[-1][0].times do |i|
245
+ sh[-1][1].times do |j|
246
+ next unless dat[3][i,j]
247
+ #d = [dat[0][i], dat[1][j], dat[2][i,j], dat[3][i,j]]
248
+ io << dat[3][i,j] << "\n"
249
+ end
250
+ #io << "\n" unless sh[-1][1] == 1
251
+ end
252
+ when [1,1,1,3]
253
+ sh[-1][0].times do |i|
254
+ sh[-1][1].times do |j|
255
+ sh[-1][2].times do |k|
256
+ next unless dat[3][i,j,k]
257
+
258
+ #d = [dat[0][i], dat[1][j], dat[2][k], dat[3][i,j,k]]
259
+ io << dat[3][i,j,k] << "\n"
260
+ end
261
+ #io << "\n" unless sh[-1][2] == 1
262
+ end
263
+ #io << "\n" unless sh[-1][1] == 1
264
+ end
265
+ when [2,2,2,2]
266
+ sh[-1][0].times do |i|
267
+ sh[-1][1].times do |j|
268
+ next unless dat[3][i,j]
269
+ io << "#{dat[3][i,j]}\n"
270
+ end
271
+ end
272
+ when [3,3,3,3]
273
+ #pp dat
274
+ #pp dat
275
+ #pp sh
276
+ sh[-1][0].times do |i|
277
+ sh[-1][1].times do |j|
278
+ sh[-1][2].times do |k|
279
+ next unless dat[3][i,j,k]
280
+ #p [i,j,k]
281
+
282
+ #d = [dat[0][i,j,k], dat[1][i,j,k], dat[2][i,j,k], dat[3][i,j,k]]
283
+ io << "#{dat[3][i,j,k]}\n"
284
+ #d.each{|dt| io << dt << " "}
285
+ #io << "\n"
286
+ end
287
+ #io << "\n" unless sh[-1][2] == 1
288
+ end
289
+ #io << "\n" unless sh[-1][1] == 1
290
+ end
291
+ end
292
+
293
+ return io.string unless options[:io]
294
+ end
295
+ def vtk_legacy_cells(options={})
296
+ pointcount = options[:pointcount]
297
+ io = options[:io] || StringIO.new
298
+ axs = self.axes.values_at(*AXES).compact
299
+ #ep 'axs', axs
300
+ dl = data_length = axs[-1].shape.product
301
+ dat = axs.map{|ax| ax.data}
302
+ sh = shapes
303
+ cml_sh = sh.map do |sh|
304
+ cml = 1
305
+ sh.reverse.map{|dim| cml *= dim; cml}.reverse
306
+ end
307
+ dat = dat.map do |d|
308
+ d.kind_of?(Array) ? TensorArray.new(d) : d
309
+ end
310
+
311
+ if self.errors
312
+ raise "Errors can only be plotted for 1D or 2D data" unless ranks == [1] or ranks == [1,1]
313
+ edat = self.errors.values_at(:x, :xmin, :xmax, :y, :ymin, :ymax).compact
314
+ #ep 'edat', edat
315
+ end
316
+ case ranks
317
+ when [1], [1,1], [1,1,1], [1,1,1,1]
318
+ (dl-1).times do |n|
319
+ #dat.each{|d| io << d[n] << " "}
320
+ #io << " " << edat.map{|e| e[n].to_s}.join(" ") if self.errors
321
+ next unless dat[-1][n]
322
+ io << "2 #{n + pointcount} #{n + pointcount + 1}"
323
+ io << "\n"
324
+ end
325
+ #when [1,1,2]
326
+ #sh[-1][0].times do |i|
327
+ #sh[-1][1].times do |j|
328
+ #next unless dat[2][i,j]
329
+ #d = [dat[0][i], dat[1][j], dat[2][i,j]]
330
+ #io << d[0] << ", " << d[1] << ", " << d[2] << "\n"
331
+ #end
332
+ #io << "\n" unless sh[-1][1] == 1
333
+ #end
334
+ #when [2,2,2]
335
+ #sh[-1][0].times do |i|
336
+ #sh[-1][1].times do |j|
337
+ #next unless dat[2][i,j]
338
+ #d = [dat[0][i,j], dat[1][i,j], dat[2][i,j]]
339
+ #io << d[0] << ", " << d[1] << ", " << d[2] << "\n"
340
+ #end
341
+ #io << "\n" unless sh[-1][1] == 1
342
+ #end
343
+ #when [1,1,2,2]
344
+ #sh[-1][0].times do |i|
345
+ #sh[-1][1].times do |j|
346
+ #next unless dat[3][i,j]
347
+ #d = [dat[0][i], dat[1][j], dat[2][i,j], dat[3][i,j]]
348
+ #io << d[0] << ", " << d[1] << ", " << d[2] << ", " << d[3] << "\n"
349
+ #end
350
+ #io << "\n" unless sh[-1][1] == 1
351
+ #end
352
+ #when [1,1,1,3]
353
+ #ni, nj, nk = sh[-1]
354
+ #sh[-1][0].times do |i|
355
+ #sh[-1][1].times do |j|
356
+ #sh[-1][2].times do |k|
357
+ #next unless dat[3][i,j,k]
358
+
359
+ #d = [dat[0][i], dat[1][j], dat[2][k], dat[3][i,j,k]]
360
+ #io << d[0] << ", " << d[1] << ", " << d[2] << ", " << d[3] << "\n"
361
+ #end
362
+ #io << "\n" unless sh[-1][2] == 1
363
+ #end
364
+ #io << "\n" unless sh[-1][1] == 1
365
+ #end
366
+ when [1,1,2], [2,2,2], [1,1,2,2], [2,2,2,2]
367
+ ni, nj = sh[-1]
368
+ sh[-1][0].times do |i|
369
+ sh[-1][1].times do |j|
370
+ next unless (ni==1 or (i+1) < ni) and (nj==1 or (j+1) < nj)
371
+ cell = [
372
+ i*(nj) + j ,
373
+ nj > 1 ? i*(nj) + (j+1) : nil,
374
+ ni > 1 ? (i+1)*(nj) + j : nil,
375
+ ni > 1 && nj > 1 ? (i+1)*(nj) + (j+1) : nil,
376
+ ].compact.map{|pnt| pnt+pointcount}
377
+ cell = [cell[0],cell[1],cell[3],cell[2]] if cell.size == 4
378
+ io << cell.size << " " << cell.join(" ") << "\n"
379
+ end
380
+ #io << "\n" unless sh[-1][1] == 1
381
+ end
382
+ when [1,1,1,3],[3,3,3,3]
383
+ #pp dat
384
+ #pp dat
385
+ #pp sh
386
+ ni, nj, nk = sh[-1]
387
+ #ep ni, nj, nk; gets
388
+ sh[-1][0].times do |i|
389
+ sh[-1][1].times do |j|
390
+ sh[-1][2].times do |k|
391
+ next unless dat[3][i,j,k]
392
+ #p [i,j,k]
393
+
394
+ #d = [dat[0][i,j,k], dat[1][i,j,k], dat[2][i,j,k], dat[3][i,j,k]]
395
+ #io << "#{dat[0][i,j,k]} #{dat[1][i,j,k]} #{dat[2][i,j,k]} #{dat[3][i,j,k]}\n"
396
+
397
+ next unless (ni==1 or (i+1) < ni) and (nj==1 or (j+1) < nj) and (nk==1 or (k+1) < nk)
398
+ cell = [
399
+ i*(nj*nk) + j*nk + k,
400
+ nk > 1 ? i*(nj*nk) + j*nk + (k+1) : nil,
401
+ nj > 1 ? i*(nj*nk) + (j+1)*nk + (k) : nil,
402
+ nj > 1 && nk > 1 ? i*(nj*nk) + (j+1)*nk + (k+1) : nil,
403
+ ni > 1 ? (i+1)*(nj*nk) + j*nk + k : nil,
404
+ ni > 1 && nk > 1 ? (i+1)*(nj*nk) + j*nk + (k+1) : nil,
405
+ ni > 1 && nj > 1 ? (i+1)*(nj*nk) + (j+1)*nk + (k) : nil,
406
+ ni > 1 && nj > 1 && nk > 1 ? (i+1)*(nj*nk) + (j+1)*nk + (k+1) : nil,
407
+ ].compact.map{|pnt| pnt+pointcount}
408
+ cell = [cell[0],cell[1],cell[3],cell[2]] if cell.size == 4
409
+ io << cell.size << " " << cell.join(" ") << "\n"
410
+
411
+ #d.each{|dt| io << dt << " "}
412
+ #io << "\n"
413
+ end
414
+ #io << "\n" unless sh[-1][2] == 1
415
+ end
416
+ #io << "\n" unless sh[-1][1] == 1
417
+ end
418
+ end
419
+
420
+ return io.string unless options[:io]
421
+ end
422
+ def vtk_legacy_cell_types(options={})
423
+ pointcount = options[:pointcount]
424
+ io = options[:io] || StringIO.new
425
+ axs = self.axes.values_at(*AXES).compact
426
+ #ep 'axs', axs
427
+ dl = data_length = axs[-1].shape.product
428
+ dat = axs.map{|ax| ax.data}
429
+ sh = shapes
430
+ cml_sh = sh.map do |sh|
431
+ cml = 1
432
+ sh.reverse.map{|dim| cml *= dim; cml}.reverse
433
+ end
434
+ dat = dat.map do |d|
435
+ d.kind_of?(Array) ? TensorArray.new(d) : d
436
+ end
437
+
438
+ if self.errors
439
+ raise "Errors can only be plotted for 1D or 2D data" unless ranks == [1] or ranks == [1,1]
440
+ edat = self.errors.values_at(:x, :xmin, :xmax, :y, :ymin, :ymax).compact
441
+ #ep 'edat', edat
442
+ end
443
+ case ranks
444
+ when [1], [1,1], [1,1,1], [1,1,1,1]
445
+ (dl-1).times do |n|
446
+ io << "3" # Lines
447
+ io << "\n"
448
+ end
449
+ #when [1,1,2]
450
+ #sh[-1][0].times do |i|
451
+ #sh[-1][1].times do |j|
452
+ #next unless dat[2][i,j]
453
+ #d = [dat[0][i], dat[1][j], dat[2][i,j]]
454
+ #io << d[0] << ", " << d[1] << ", " << d[2] << "\n"
455
+ #end
456
+ #io << "\n" unless sh[-1][1] == 1
457
+ #end
458
+ #when [2,2,2]
459
+ #sh[-1][0].times do |i|
460
+ #sh[-1][1].times do |j|
461
+ #next unless dat[2][i,j]
462
+ #d = [dat[0][i,j], dat[1][i,j], dat[2][i,j]]
463
+ #io << d[0] << ", " << d[1] << ", " << d[2] << "\n"
464
+ #end
465
+ #io << "\n" unless sh[-1][1] == 1
466
+ #end
467
+ #when [1,1,2,2]
468
+ #sh[-1][0].times do |i|
469
+ #sh[-1][1].times do |j|
470
+ #next unless dat[3][i,j]
471
+ #d = [dat[0][i], dat[1][j], dat[2][i,j], dat[3][i,j]]
472
+ #io << d[0] << ", " << d[1] << ", " << d[2] << ", " << d[3] << "\n"
473
+ #end
474
+ #io << "\n" unless sh[-1][1] == 1
475
+ #end
476
+ #when [1,1,1,3]
477
+ #sh[-1][0].times do |i|
478
+ #sh[-1][1].times do |j|
479
+ #sh[-1][2].times do |k|
480
+ #next unless dat[3][i,j,k]
481
+
482
+ #d = [dat[0][i], dat[1][j], dat[2][k], dat[3][i,j,k]]
483
+ #io << d[0] << ", " << d[1] << ", " << d[2] << ", " << d[3] << "\n"
484
+ #end
485
+ #io << "\n" unless sh[-1][2] == 1
486
+ #end
487
+ #io << "\n" unless sh[-1][1] == 1
488
+ #end
489
+ when [1,1,2], [2,2,2], [1,1,2,2], [2,2,2,2]
490
+ ni, nj = sh[-1]
491
+ type = case [ni > 1 ? 1 : nil, nj > 1 ? 1 : nil].compact.size
492
+ when 2
493
+ 7 # Polygons see www.vtk.org/VTK/img/file-formats.pdf
494
+ when 1
495
+ 3 # Lines
496
+ when 0
497
+ 1 # Verteces
498
+ end
499
+ sh[-1][0].times do |i|
500
+ sh[-1][1].times do |j|
501
+ next unless dat[3][i,j]
502
+ next unless (ni==1 or (i+1) < ni) and (nj==1 or (j+1) < nj)
503
+ io << type << "\n"
504
+ end
505
+ #io << "\n" unless sh[-1][1] == 1
506
+ end
507
+ when [1,1,1,3],[3,3,3,3]
508
+ #pp dat
509
+ #pp dat
510
+ #pp sh
511
+ ni, nj, nk = sh[-1]
512
+ type = case [ni > 1 ? 1 : nil, nj > 1 ? 1 : nil, nk > 1 ? 1 : nil].compact.size
513
+ when 3
514
+ 11 # 3D cells, see www.vtk.org/VTK/img/file-formats.pdf
515
+ when 2
516
+ 7 # Polygons
517
+ when 1
518
+ 3 # Lines
519
+ when 0
520
+ 1 # Verteces
521
+ end
522
+
523
+ #ep ni, nj, nk; gets
524
+ sh[-1][0].times do |i|
525
+ sh[-1][1].times do |j|
526
+ sh[-1][2].times do |k|
527
+ next unless dat[3][i,j,k]
528
+ #p [i,j,k]
529
+
530
+ #d = [dat[0][i,j,k], dat[1][i,j,k], dat[2][i,j,k], dat[3][i,j,k]]
531
+ #io << "#{dat[0][i,j,k]} #{dat[1][i,j,k]} #{dat[2][i,j,k]} #{dat[3][i,j,k]}\n"
532
+
533
+ next unless (ni==1 or (i+1) < ni) and (nj==1 or (j+1) < nj) and (nk==1 or (k+1) < nk)
534
+ io << type << "\n"
535
+
536
+ #d.each{|dt| io << dt << " "}
537
+ #io << "\n"
538
+ end
539
+ #io << "\n" unless sh[-1][2] == 1
540
+ end
541
+ #io << "\n" unless sh[-1][1] == 1
542
+ end
543
+ end
544
+
545
+ return io.string unless options[:io]
546
+ end
547
+ end
548
+
549
+ end
550
+