ruby-gr 0.0.24 → 0.61.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +2 -2
- data/README.md +54 -22
- data/lib/gr/ffi.rb +15 -1
- data/lib/gr/plot.rb +116 -67
- data/lib/gr.rb +242 -32
- data/lib/gr3/ffi.rb +7 -1
- data/lib/gr3.rb +28 -8
- data/lib/gr_commons/define_methods.rb +2 -2
- data/lib/gr_commons/fiddley.rb +1 -1
- data/lib/gr_commons/gr_common_utils.rb +2 -2
- data/lib/gr_commons/gr_commons.rb +2 -2
- data/lib/gr_commons/gr_lib.rb +104 -0
- data/lib/gr_commons/gr_logger.rb +24 -12
- data/lib/gr_commons/jupyter_support.rb +2 -2
- data/lib/gr_commons/{extern.rb → try_extern.rb} +1 -1
- data/lib/gr_commons/version.rb +1 -1
- data/lib/grm/ffi.rb +8 -3
- data/lib/grm.rb +22 -8
- metadata +5 -89
- data/lib/gr_commons/search_shared_library.rb +0 -74
data/lib/gr.rb
CHANGED
@@ -48,23 +48,37 @@
|
|
48
48
|
module GR
|
49
49
|
class Error < StandardError; end
|
50
50
|
|
51
|
+
class NotFoundError < Error; end
|
52
|
+
|
51
53
|
class << self
|
52
54
|
attr_accessor :ffi_lib
|
53
55
|
end
|
54
56
|
|
55
57
|
require_relative 'gr_commons/gr_commons'
|
56
|
-
extend GRCommons::SearchSharedLibrary
|
57
58
|
|
58
59
|
# Platforms | path
|
59
60
|
# Windows | bin/libgr.dll
|
60
|
-
# MacOSX | lib/libGR.
|
61
|
+
# MacOSX | lib/libGR.dylib ( <= v0.53.0 .so)
|
61
62
|
# Ubuntu | lib/libGR.so
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
platform = RbConfig::CONFIG['host_os']
|
64
|
+
lib_names, pkg_name = \
|
65
|
+
case platform
|
66
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
67
|
+
[['libGR.dll'], 'gr']
|
68
|
+
when /darwin|mac os/
|
69
|
+
ENV['GKSwstype'] ||= 'gksqt'
|
70
|
+
[['libGR.dylib', 'libGR.so'], 'gr']
|
71
|
+
else
|
72
|
+
[['libGR.so'], 'gr']
|
73
|
+
end
|
74
|
+
|
75
|
+
# On Windows + RubyInstaller,
|
76
|
+
# the environment variable GKS_FONTPATH will be set.
|
77
|
+
lib_path = GRCommons::GRLib.search(lib_names, pkg_name)
|
78
|
+
|
79
|
+
raise NotFoundError, "#{lib_names} not found" if lib_path.nil?
|
80
|
+
|
81
|
+
self.ffi_lib = lib_path
|
68
82
|
|
69
83
|
require_relative 'gr/version'
|
70
84
|
require_relative 'gr/ffi'
|
@@ -165,30 +179,78 @@ module GR
|
|
165
179
|
# Draw a polyline using the current line attributes,
|
166
180
|
# starting from the first data point and ending at the last data point.
|
167
181
|
#
|
168
|
-
# @param x
|
169
|
-
# @param y
|
182
|
+
# @param x [Array, NArray] A list containing the X coordinates
|
183
|
+
# @param y [Array, NArray] A list containing the Y coordinates
|
184
|
+
# @param linewidth [Array, NArray, Numeric] A list containing the line widths
|
185
|
+
# @param line_z [Array, NArray, Numeric] A list to be converted to colors
|
170
186
|
#
|
171
187
|
# The values for x and y are in world coordinates.
|
172
188
|
# The attributes that control the appearance of a polyline are linetype,
|
173
189
|
# linewidth and color index.
|
174
190
|
#
|
175
|
-
def polyline(x, y)
|
191
|
+
def polyline(x, y, linewidth = nil, line_z = nil)
|
192
|
+
# GR.jl - Multiple dispatch
|
176
193
|
n = equal_length(x, y)
|
177
|
-
|
194
|
+
if linewidth.nil? && line_z.nil?
|
195
|
+
super(n, x, y)
|
196
|
+
else
|
197
|
+
linewidth ||= GR.inqlinewidth
|
198
|
+
linewidth = if linewidth.is_a?(Numeric)
|
199
|
+
Array.new(n, linewidth * 100)
|
200
|
+
else
|
201
|
+
raise ArgumentError if n != linewidth.length
|
202
|
+
|
203
|
+
linewidth.map { |i| (100 * i).round }
|
204
|
+
end
|
205
|
+
line_z ||= GR.inqcolor(989) # FIXME
|
206
|
+
color = if line_z.is_a?(Numeric)
|
207
|
+
Array.new(n, line_z)
|
208
|
+
else
|
209
|
+
raise ArgumentError if n != line_z.length
|
210
|
+
|
211
|
+
to_rgb_color(line_z)
|
212
|
+
end
|
213
|
+
z = linewidth.to_a.zip(color).flatten # to_a : NArray
|
214
|
+
gdp(x, y, GDP_DRAW_LINES, z)
|
215
|
+
end
|
178
216
|
end
|
179
217
|
|
180
218
|
# Draw marker symbols centered at the given data points.
|
181
219
|
#
|
182
|
-
# @param x
|
183
|
-
# @param y
|
220
|
+
# @param x [Array, NArray] A list containing the X coordinates
|
221
|
+
# @param y [Array, NArray] A list containing the Y coordinates
|
222
|
+
# @param markersize [Array, NArray, Numeric] A list containing the marker sizes
|
223
|
+
# @param marker_z [Array, NArray, Numeric] A list to be converted to colors
|
184
224
|
#
|
185
225
|
# The values for x and y are in world coordinates.
|
186
226
|
# The attributes that control the appearance of a polymarker are marker type,
|
187
227
|
# marker size scale factor and color index.
|
188
228
|
#
|
189
|
-
def polymarker(x, y)
|
229
|
+
def polymarker(x, y, markersize = nil, marker_z = nil)
|
230
|
+
# GR.jl - Multiple dispatch
|
190
231
|
n = equal_length(x, y)
|
191
|
-
|
232
|
+
if markersize.nil? && marker_z.nil?
|
233
|
+
super(n, x, y)
|
234
|
+
else
|
235
|
+
markersize ||= GR.inqmarkersize
|
236
|
+
markersize = if markersize.is_a?(Numeric)
|
237
|
+
Array.new(n, markersize * 100)
|
238
|
+
else
|
239
|
+
raise ArgumentError if n != markersize.length
|
240
|
+
|
241
|
+
markersize.map { |i| (100 * i).round }
|
242
|
+
end
|
243
|
+
marker_z ||= GR.inqcolor(989) # FIXME
|
244
|
+
color = if marker_z.is_a?(Numeric)
|
245
|
+
Array.new(n, marker_z)
|
246
|
+
else
|
247
|
+
raise ArgumentError if n != marker_z.length
|
248
|
+
|
249
|
+
to_rgb_color(marker_z)
|
250
|
+
end
|
251
|
+
z = markersize.to_a.zip(color).flatten # to_a : NArray
|
252
|
+
gdp(x, y, GDP_DRAW_MARKERS, z)
|
253
|
+
end
|
192
254
|
end
|
193
255
|
|
194
256
|
# Draw a text at position `x`, `y` using the current text attributes.
|
@@ -259,7 +321,9 @@ module GR
|
|
259
321
|
def nonuniformcellarray(x, y, dimx, dimy, color)
|
260
322
|
raise ArgumentError unless x.length == dimx + 1 && y.length == dimy + 1
|
261
323
|
|
262
|
-
|
324
|
+
nx = dimx == x.length ? -dimx : dimx
|
325
|
+
ny = dimy == y.length ? -dimy : dimy
|
326
|
+
super(x, y, nx, ny, 1, 1, dimx, dimy, int(color))
|
263
327
|
end
|
264
328
|
|
265
329
|
# Display a two dimensional color index array mapped to a disk using polar
|
@@ -270,9 +334,9 @@ module GR
|
|
270
334
|
# raidus. The center point of the resulting disk is located at `xorg`, `yorg`
|
271
335
|
# and the radius of the disk is `rmax`.
|
272
336
|
#
|
273
|
-
# @param
|
337
|
+
# @param x_org [Numeric] X coordinate of the disk center in world
|
274
338
|
# coordinates
|
275
|
-
# @param
|
339
|
+
# @param y_org [Numeric] Y coordinate of the disk center in world
|
276
340
|
# coordinates
|
277
341
|
# @param phimin [Numeric] start angle of the disk sector in degrees
|
278
342
|
# @param phimax [Numeric] end angle of the disk sector in degrees
|
@@ -280,7 +344,7 @@ module GR
|
|
280
344
|
# coordinates
|
281
345
|
# @param rmax [Numeric] outer radius of the punctured disk in world
|
282
346
|
# coordinates
|
283
|
-
# @param
|
347
|
+
# @param dimphi [Integer] Phi (X) dimension of the color index array
|
284
348
|
# @param dimr [Integer] iR (Y) dimension of the color index array
|
285
349
|
# @param color [Array, NArray] Color index array
|
286
350
|
#
|
@@ -308,6 +372,27 @@ module GR
|
|
308
372
|
super(x_org, y_org, phimin, phimax, rmin, rmax, dimphi, dimr, 1, 1, dimphi, dimr, int(color))
|
309
373
|
end
|
310
374
|
|
375
|
+
# Display a two dimensional color index array mapped to a disk using polar
|
376
|
+
# coordinates with nonuniform cell sizes.
|
377
|
+
#
|
378
|
+
# @param phi [Array, NArray] array with the angles of the disk sector in degrees
|
379
|
+
# @param r [Array, NArray] array with the radii of the disk in world coordinates
|
380
|
+
# @param ncol [Integer] total number of columns in the color index array and the angle array
|
381
|
+
# @param nrow [Integer] total number of rows in the color index array and the radii array
|
382
|
+
# @param color [Integer] color index array
|
383
|
+
#
|
384
|
+
# The mapping of the polar coordinates and the drawing is performed simialr
|
385
|
+
# to `gr_polarcellarray` with the difference that the individual cell sizes
|
386
|
+
# are specified allowing nonuniform sized cells.
|
387
|
+
#
|
388
|
+
def nonuniformpolarcellarray(phi, r, ncol, nrow, color)
|
389
|
+
raise ArgumentError unless (ncol..(ncol + 1)).include?(phi.length) && (nrow..(nrow + 1)).include?(r.length)
|
390
|
+
|
391
|
+
dimphi = ncol == phi.length ? -ncol : ncol
|
392
|
+
dimr = nrow == r.length ? -nrow : nrow
|
393
|
+
super(0, 0, phi, r, dimphi, dimr, 1, 1, ncol, nrow, int(color))
|
394
|
+
end
|
395
|
+
|
311
396
|
# Generates a generalized drawing primitive (GDP) of the type you specify,
|
312
397
|
# using specified points and any additional information contained in a data
|
313
398
|
# record.
|
@@ -320,7 +405,7 @@ module GR
|
|
320
405
|
def gdp(x, y, primid, datrec)
|
321
406
|
n = equal_length(x, y)
|
322
407
|
ldr = datrec.length
|
323
|
-
super(n, x, y, primid, ldr, datrec)
|
408
|
+
super(n, x, y, primid, ldr, int(datrec))
|
324
409
|
end
|
325
410
|
|
326
411
|
# Generate a cubic spline-fit,
|
@@ -777,7 +862,7 @@ module GR
|
|
777
862
|
|
778
863
|
# Set the clipping indicator.
|
779
864
|
#
|
780
|
-
# @
|
865
|
+
# @param indicator [Integer] An indicator specifying whether clipping is on
|
781
866
|
# or off.
|
782
867
|
# * 0 : Clipping is off. Data outside of the window will be drawn.
|
783
868
|
# * 1 : Clipping is on. Data outside of the window will not be drawn.
|
@@ -1296,7 +1381,7 @@ module GR
|
|
1296
1381
|
# @param x [Array, NArray] A list containing the X coordinates
|
1297
1382
|
# @param y [Array, NArray] A list containing the Y coordinates
|
1298
1383
|
# @param z [Array, NArray] A list containing the Z coordinates
|
1299
|
-
# @param
|
1384
|
+
# @param levels [Array, NArray] A list of contour levels
|
1300
1385
|
#
|
1301
1386
|
def tricontour(x, y, z, levels)
|
1302
1387
|
npoints = x.length # equal_length ?
|
@@ -1355,6 +1440,16 @@ module GR
|
|
1355
1440
|
super(n, r, g, b, positions)
|
1356
1441
|
end
|
1357
1442
|
|
1443
|
+
# Inquire the color index range of the current colormap.
|
1444
|
+
#
|
1445
|
+
# @return [Array] first_color_ind The color index of the first color,
|
1446
|
+
# last_color_ind The color index of the last color
|
1447
|
+
def inqcolormapinds
|
1448
|
+
inquiry %i[int int] do |first_color_ind, last_color_ind|
|
1449
|
+
super(first_color_ind, last_color_ind)
|
1450
|
+
end
|
1451
|
+
end
|
1452
|
+
|
1358
1453
|
# @!method colorbar
|
1359
1454
|
|
1360
1455
|
def inqcolor(color)
|
@@ -1413,7 +1508,15 @@ module GR
|
|
1413
1508
|
# * .webm : WebM video file
|
1414
1509
|
# * .ogg : Ogg video file
|
1415
1510
|
#
|
1416
|
-
#
|
1511
|
+
# @note Ruby feature - you can use block to call endprint automatically.
|
1512
|
+
|
1513
|
+
def beginprint(file_path)
|
1514
|
+
super(file_path)
|
1515
|
+
if block_given?
|
1516
|
+
yield
|
1517
|
+
endprint
|
1518
|
+
end
|
1519
|
+
end
|
1417
1520
|
|
1418
1521
|
# Open and activate a print device with the given layout attributes.
|
1419
1522
|
#
|
@@ -1534,14 +1637,14 @@ module GR
|
|
1534
1637
|
# curves.
|
1535
1638
|
#
|
1536
1639
|
# @param points [Array, NArray] (N, 2) array of (x, y) vertices
|
1537
|
-
# @
|
1640
|
+
# @param codes [Array, NArray] N-length array of path codes
|
1538
1641
|
# * STOP : end the entire path
|
1539
1642
|
# * MOVETO : move to the given vertex
|
1540
1643
|
# * LINETO : draw a line from the current position to the given vertex
|
1541
1644
|
# * CURVE3 : draw a quadratic Bézier curve
|
1542
1645
|
# * CURVE4 : draw a cubic Bézier curve
|
1543
1646
|
# * CLOSEPOLY : draw a line segment to the start point of the current path
|
1544
|
-
# @
|
1647
|
+
# @param fill [Integer]
|
1545
1648
|
# A flag indication whether resulting path is to be filled or not
|
1546
1649
|
#
|
1547
1650
|
def drawpath(points, codes, fill)
|
@@ -1601,7 +1704,7 @@ module GR
|
|
1601
1704
|
def readimage(path)
|
1602
1705
|
# Feel free to make a pull request if you catch a mistake
|
1603
1706
|
# or you have an idea to improve it.
|
1604
|
-
data = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INTPTR_T)
|
1707
|
+
data = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INTPTR_T, Fiddle::RUBY_FREE)
|
1605
1708
|
w, h = inquiry [:int, :int] do |width, height|
|
1606
1709
|
# data is a pointer of a pointer
|
1607
1710
|
super(path, width, height, data.ref)
|
@@ -1739,7 +1842,7 @@ module GR
|
|
1739
1842
|
# Feel free to make a pull request if you catch a mistake
|
1740
1843
|
# or you have an idea to improve it.
|
1741
1844
|
npoints = equal_length(x, y)
|
1742
|
-
triangles = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INTPTR_T)
|
1845
|
+
triangles = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INTPTR_T, Fiddle::RUBY_FREE)
|
1743
1846
|
dim = 3
|
1744
1847
|
n_tri = inquiry_int do |ntri|
|
1745
1848
|
super(npoints, x, y, ntri, triangles.ref)
|
@@ -1829,7 +1932,8 @@ module GR
|
|
1829
1932
|
# * 3 : INTERP2_CUBIC - Cubic interpolation
|
1830
1933
|
# @param extrapval [Numeric] The extrapolation value
|
1831
1934
|
#
|
1832
|
-
|
1935
|
+
# flatten
|
1936
|
+
def interp2(x, y, z, xq, yq, method, extrapval)
|
1833
1937
|
nx = x.length
|
1834
1938
|
ny = y.length
|
1835
1939
|
# nz = z.length
|
@@ -2003,6 +2107,18 @@ module GR
|
|
2003
2107
|
super(n, x, y, codes)
|
2004
2108
|
end
|
2005
2109
|
|
2110
|
+
# @param z [Array, NArray]
|
2111
|
+
# @return [Array, NArray]
|
2112
|
+
def to_rgb_color(z)
|
2113
|
+
zmin, zmax = z.minmax
|
2114
|
+
return Array.new(z.length, 0) if zmax == zmin
|
2115
|
+
|
2116
|
+
z.map do |i|
|
2117
|
+
zi = (i - zmin) / (zmax - zmin).to_f
|
2118
|
+
inqcolor(1000 + (zi * 255).round)
|
2119
|
+
end
|
2120
|
+
end
|
2121
|
+
|
2006
2122
|
# Define the border width of subsequent path output primitives.
|
2007
2123
|
#
|
2008
2124
|
# @param width [Numeric] The border width scale factor
|
@@ -2023,13 +2139,19 @@ module GR
|
|
2023
2139
|
inquiry_int { |pt| super(pt) }
|
2024
2140
|
end
|
2025
2141
|
|
2142
|
+
# @!method selectclipxform
|
2143
|
+
|
2144
|
+
def inqclipxform
|
2145
|
+
inquiry_int { |pt| super(pt) }
|
2146
|
+
end
|
2147
|
+
|
2026
2148
|
# Set the projection type with this flag.
|
2027
2149
|
#
|
2028
2150
|
# @param flag [Integer] projection type
|
2029
2151
|
# The available options are:
|
2030
|
-
# * 0 :
|
2031
|
-
# * 1 :
|
2032
|
-
# * 2 :
|
2152
|
+
# * 0 : PROJECTION_DEFAULT - default
|
2153
|
+
# * 1 : PROJECTION_ORTHOGRAPHIC - orthographic
|
2154
|
+
# * 2 : PROJECTION_PERSPECTIVE - perspective
|
2033
2155
|
#
|
2034
2156
|
# @!method setprojectiontype
|
2035
2157
|
|
@@ -2179,6 +2301,90 @@ module GR
|
|
2179
2301
|
super(encoding)
|
2180
2302
|
end
|
2181
2303
|
end
|
2304
|
+
|
2305
|
+
# Load a font file from a given filename.
|
2306
|
+
#
|
2307
|
+
# This function loads a font from a given absolute filename and assigns a
|
2308
|
+
# font index to it. To use the loaded font call `gr_settextfontprec` using
|
2309
|
+
# the resulting font index and precision 3.
|
2310
|
+
#
|
2311
|
+
# @param filename [String] The absolute filename of the font
|
2312
|
+
#
|
2313
|
+
def loadfont(str)
|
2314
|
+
inquiry_int do |font|
|
2315
|
+
super(str, font)
|
2316
|
+
end
|
2317
|
+
end
|
2318
|
+
|
2319
|
+
# Set the number of threads which can run parallel.
|
2320
|
+
# The default value is the number of threads the cpu has.
|
2321
|
+
#
|
2322
|
+
# @param num [Integer] num number of threads
|
2323
|
+
#
|
2324
|
+
# @!method setthreadnumber
|
2325
|
+
|
2326
|
+
# Set the width and height of the resulting picture.
|
2327
|
+
# These values are only used for gr_volume and gr_cpubasedvolume.
|
2328
|
+
# The default values are 1000 for both.
|
2329
|
+
#
|
2330
|
+
# @param width [Integer] width of the resulting image
|
2331
|
+
# @param height [Integer] height of the resulting image
|
2332
|
+
#
|
2333
|
+
# @!method setpicturesizeforvolume
|
2334
|
+
|
2335
|
+
# Set the gr_volume border type with this flag.
|
2336
|
+
# This inflicts how the volume is calculated. When the flag is set to
|
2337
|
+
# GR_VOLUME_WITH_BORDER the border will be calculated the same as the points
|
2338
|
+
# inside the volume.
|
2339
|
+
#
|
2340
|
+
# @param flag [Integer] calculation of the gr_volume border
|
2341
|
+
# The available options are:
|
2342
|
+
# * 0 : VOLUME_WITHOUT_BORDER - default value
|
2343
|
+
# * 1 : VOLUME_WITH_BORDER - gr_volume with border
|
2344
|
+
#
|
2345
|
+
# @!method setvolumebordercalculation # @!method setthreadnumber
|
2346
|
+
|
2347
|
+
# Set if gr_cpubasedvolume is calculated approximative or exact.
|
2348
|
+
# To use the exact calculation set approximative_calculation to 0.
|
2349
|
+
# The default value is the approximative version, which can be set with the
|
2350
|
+
# number 1.
|
2351
|
+
#
|
2352
|
+
# @param approximative_calculation [Integer] exact or approximative calculation
|
2353
|
+
# of the volume
|
2354
|
+
#
|
2355
|
+
# @!method setapproximativecalculation
|
2356
|
+
|
2357
|
+
# Inquire the parameters which can be set for cpubasedvolume.
|
2358
|
+
# The size of the resulting image, the way the volumeborder is calculated and
|
2359
|
+
# the amount of threads which are used.
|
2360
|
+
#
|
2361
|
+
# @return [Array]
|
2362
|
+
# * border - flag which tells how the border is calculated
|
2363
|
+
# * max_threads - number of threads
|
2364
|
+
# * picture_width - width of the resulting image
|
2365
|
+
# * picture_height - height of the resulting image
|
2366
|
+
# * approximative_calculation - exact or approximative calculation of gr_cpubasedvolume
|
2367
|
+
#
|
2368
|
+
def inqvolumeflags
|
2369
|
+
inquiry([:int] * 5) do |*pts|
|
2370
|
+
super(*pts)
|
2371
|
+
end
|
2372
|
+
end
|
2373
|
+
|
2374
|
+
# FIXME! (#61)
|
2375
|
+
# @!method cpubasedvolume
|
2376
|
+
|
2377
|
+
def inqvpsize
|
2378
|
+
inquiry %i[int int double] do |*pts|
|
2379
|
+
super(*pts)
|
2380
|
+
end
|
2381
|
+
end
|
2382
|
+
|
2383
|
+
def polygonmesh3d(px, py, pz, connections, colors)
|
2384
|
+
n_points = equal_length(px, py, pz)
|
2385
|
+
n_connections = colors.length
|
2386
|
+
super(n_points, px, py, pz, n_connections, int(connections), int(colors))
|
2387
|
+
end
|
2182
2388
|
end
|
2183
2389
|
|
2184
2390
|
ASF_BUNDLED = 0
|
@@ -2387,6 +2593,10 @@ module GR
|
|
2387
2593
|
PATH_CURVE4 = 0x04
|
2388
2594
|
PATH_CLOSEPOLY = 0x4f
|
2389
2595
|
|
2596
|
+
GDP_DRAW_PATH = 1
|
2597
|
+
GDP_DRAW_LINES = 2
|
2598
|
+
GDP_DRAW_MARKERS = 3
|
2599
|
+
|
2390
2600
|
MPL_SUPPRESS_CLEAR = 1
|
2391
2601
|
MPL_POSTPONE_UPDATE = 2
|
2392
2602
|
|
data/lib/gr3/ffi.rb
CHANGED
@@ -15,7 +15,7 @@ module GR3
|
|
15
15
|
raise LoadError, 'Could not find GR Framework'
|
16
16
|
end
|
17
17
|
|
18
|
-
extend GRCommons::
|
18
|
+
extend GRCommons::TryExtern
|
19
19
|
|
20
20
|
# https://github.com/sciapp/gr/blob/master/lib/gr3/gr3.h
|
21
21
|
# keep same order
|
@@ -91,6 +91,8 @@ module GR3
|
|
91
91
|
'double offset_x, double offset_y, double offset_z)'
|
92
92
|
try_extern 'int gr3_createsurfacemesh(int *mesh, int nx, int ny, ' \
|
93
93
|
'float *px, float *py, float *pz, int option)'
|
94
|
+
try_extern 'int gr3_createsurface3dmesh(int *mesh, int ncols, int nrows, ' \
|
95
|
+
'float *px, float *py, float *pz);'
|
94
96
|
try_extern 'void gr3_drawmesh_grlike(int mesh, int n, ' \
|
95
97
|
'const float *positions, const float *directions, const float *ups, ' \
|
96
98
|
'const float *colors, const float *scales)'
|
@@ -138,5 +140,9 @@ module GR3
|
|
138
140
|
# try_extern 'void gr3_drawtrianglesurface(int n, const float *triangles)'
|
139
141
|
try_extern 'void gr_volume(int nx, int ny, int nz, double *data, ' \
|
140
142
|
'int algorithm, double *dmin_ptr, double *dmax_ptr)'
|
143
|
+
try_extern 'void gr3_setorthographicprojection' \
|
144
|
+
'(float left, float right, float bottom, float top, float znear, float zfar)'
|
145
|
+
try_extern 'void gr3_setsurfaceoption(int option)'
|
146
|
+
try_extern 'int gr3_getsurfaceoption(void)'
|
141
147
|
end
|
142
148
|
end
|
data/lib/gr3.rb
CHANGED
@@ -58,23 +58,37 @@
|
|
58
58
|
module GR3
|
59
59
|
class Error < StandardError; end
|
60
60
|
|
61
|
+
class NotFoundError < Error; end
|
62
|
+
|
61
63
|
class << self
|
62
64
|
attr_accessor :ffi_lib
|
63
65
|
end
|
64
66
|
|
65
67
|
require_relative 'gr_commons/gr_commons'
|
66
|
-
extend GRCommons::SearchSharedLibrary
|
67
68
|
|
68
69
|
# Platforms | path
|
69
70
|
# Windows | bin/libGR3.dll
|
70
|
-
# MacOSX | lib/libGR3.
|
71
|
+
# MacOSX | lib/libGR3.dylib ( <= v0.53.0 .so)
|
71
72
|
# Ubuntu | lib/libGR3.so
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
73
|
+
platform = RbConfig::CONFIG['host_os']
|
74
|
+
lib_names, pkg_name = \
|
75
|
+
case platform
|
76
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
77
|
+
[['libGR3.dll'], 'gr3']
|
78
|
+
when /darwin|mac os/
|
79
|
+
ENV['GKSwstype'] ||= 'gksqt'
|
80
|
+
[['libGR3.dylib', 'libGR3.so'], 'gr3']
|
81
|
+
else
|
82
|
+
[['libGR3.so'], 'gr3']
|
83
|
+
end
|
84
|
+
|
85
|
+
# On Windows + RubyInstaller,
|
86
|
+
# the environment variable GKS_FONTPATH will be set.
|
87
|
+
lib_path = GRCommons::GRLib.search(lib_names, pkg_name)
|
88
|
+
|
89
|
+
raise NotFoundError, "#{lib_names} not found" if lib_path.nil?
|
90
|
+
|
91
|
+
self.ffi_lib = lib_path
|
78
92
|
|
79
93
|
require_relative 'gr3/version'
|
80
94
|
require_relative 'gr3/ffi'
|
@@ -813,6 +827,7 @@ module GR3
|
|
813
827
|
IA_END_OF_LIST = 0
|
814
828
|
IA_FRAMEBUFFER_WIDTH = 1
|
815
829
|
IA_FRAMEBUFFER_HEIGHT = 2
|
830
|
+
IA_NUM_THREADS = 3
|
816
831
|
|
817
832
|
# Error
|
818
833
|
ERROR_NONE = 0
|
@@ -843,6 +858,11 @@ module GR3
|
|
843
858
|
DRAWABLE_OPENGL = 1
|
844
859
|
DRAWABLE_GKS = 2
|
845
860
|
|
861
|
+
# Projection
|
862
|
+
PROJECTION_PERSPECTIVE = 0
|
863
|
+
PROJECTION_PARALLEL = 1
|
864
|
+
PROJECTION_ORTHOGRAPHIC = 2
|
865
|
+
|
846
866
|
# SurfaceOption
|
847
867
|
SURFACE_DEFAULT = 0
|
848
868
|
SURFACE_NORMALS = 1
|
@@ -16,9 +16,9 @@ module GRCommons
|
|
16
16
|
args.map! do |arg|
|
17
17
|
case arg
|
18
18
|
when Array
|
19
|
-
|
19
|
+
GRCommonUtils.public_send(default_type, arg)
|
20
20
|
when ->(x) { defined?(Numo::NArray) && x.is_a?(Numo::NArray) }
|
21
|
-
|
21
|
+
GRCommonUtils.public_send(default_type, arg)
|
22
22
|
else
|
23
23
|
arg
|
24
24
|
end
|
data/lib/gr_commons/fiddley.rb
CHANGED
@@ -43,7 +43,7 @@ module GRCommons
|
|
43
43
|
if narray?(data)
|
44
44
|
Numo::Int32.cast(data).to_binary
|
45
45
|
else
|
46
|
-
Fiddley::Utils.array2str(:int32, data.to_a.flatten)
|
46
|
+
Fiddley::Utils.array2str(:int32, data.to_a.flatten)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -52,7 +52,7 @@ module GRCommons
|
|
52
52
|
if narray?(data)
|
53
53
|
Numo::UInt32.cast(data).to_binary
|
54
54
|
else
|
55
|
-
Fiddley::Utils.array2str(:
|
55
|
+
Fiddley::Utils.array2str(:uint32, data.to_a.flatten)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -7,8 +7,8 @@ end
|
|
7
7
|
# Change the default encoding to UTF-8.
|
8
8
|
ENV['GKS_ENCODING'] ||= 'utf8'
|
9
9
|
|
10
|
-
require_relative '
|
11
|
-
require_relative '
|
10
|
+
require_relative 'gr_lib'
|
11
|
+
require_relative 'try_extern'
|
12
12
|
require_relative 'define_methods'
|
13
13
|
require_relative 'gr_common_utils'
|
14
14
|
require_relative 'jupyter_support'
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pkg-config'
|
4
|
+
|
5
|
+
module GRCommons
|
6
|
+
# This module helps GR, GR and GRM to search the shared library.
|
7
|
+
#
|
8
|
+
# The order of priority:
|
9
|
+
# 1. RubyInstaller ( for Windows only )
|
10
|
+
# 2. Environment variable GRDIR
|
11
|
+
# 3. pkg-config : https://github.com/ruby-gnome/pkg-config
|
12
|
+
# The following packages (should) support pkg-config.
|
13
|
+
# - Linux
|
14
|
+
# - Red Data Tools https://github.com/red-data-tools/packages.red-data-tools.org
|
15
|
+
# - libgr-dev
|
16
|
+
# - libgr3-dev
|
17
|
+
# - libgrm-dev
|
18
|
+
# - Mac
|
19
|
+
# - Homebrew https://github.com/Homebrew/homebrew-core
|
20
|
+
# - libgr
|
21
|
+
# - Windows
|
22
|
+
# - MinGW https://github.com/msys2/MINGW-packages
|
23
|
+
# - mingw-w64-gr
|
24
|
+
module GRLib
|
25
|
+
class << self
|
26
|
+
# Check if using RubyInstaller or not.
|
27
|
+
def ruby_installer?
|
28
|
+
Object.const_defined?(:RubyInstaller)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Return the directory path from the GRDIR environment variable.
|
32
|
+
def get_grdir_from_env(lib_names)
|
33
|
+
return nil unless ENV['GRDIR']
|
34
|
+
return ENV['GRDIR'] if Dir.exist?(ENV['GRDIR'])
|
35
|
+
|
36
|
+
warn "#{lib_names} : Dir GRDIR=#{ENV['GRDIR']} not found." # return nil
|
37
|
+
end
|
38
|
+
|
39
|
+
# Search the shared library.
|
40
|
+
# @note This method does not detect the Operating System.
|
41
|
+
#
|
42
|
+
# @param lib_names [Array] The actual file name of the shared library.
|
43
|
+
# @param pkg_name [String] The package name to be used when searching with pkg-configg
|
44
|
+
def search(lib_names, pkg_name)
|
45
|
+
# FIXME: There may be a better way to do it...
|
46
|
+
def lib_names.map_find(&block)
|
47
|
+
lazy.map(&block).find { |path| path }
|
48
|
+
end
|
49
|
+
|
50
|
+
# ENV['GRDIR']
|
51
|
+
# Verify that the directory exists.
|
52
|
+
grdir = get_grdir_from_env(lib_names)
|
53
|
+
|
54
|
+
# Windows + RubyInstaller
|
55
|
+
if ruby_installer?
|
56
|
+
grdir ||= File.join(RubyInstaller::Runtime.msys2_installation.msys_path,
|
57
|
+
RubyInstaller::Runtime.msys2_installation.mingwarch)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Search grdir
|
61
|
+
if grdir
|
62
|
+
lib_path = lib_names.map_find do |lib_name|
|
63
|
+
recursive_search(lib_name, grdir)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Search with pkg-config
|
68
|
+
lib_path ||= lib_names.map_find do |lib_name|
|
69
|
+
pkg_config_search(lib_name, pkg_name)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Windows + RubyInstaller
|
73
|
+
if ruby_installer?
|
74
|
+
RubyInstaller::Runtime.add_dll_directory(File.dirname(lib_path))
|
75
|
+
# FIXME: Where should I write this code?
|
76
|
+
ENV['GKS_FONTPATH'] ||= grdir
|
77
|
+
end
|
78
|
+
|
79
|
+
lib_path
|
80
|
+
end
|
81
|
+
|
82
|
+
# Recursive file search in directories
|
83
|
+
# @param name [String] File to search for
|
84
|
+
# @param base_dir [String] Directory to search
|
85
|
+
# @return path [String, NilClass] Returns the first path found.
|
86
|
+
# If not found, nil is returned.
|
87
|
+
def recursive_search(name, base_dir)
|
88
|
+
Dir.chdir(base_dir) do
|
89
|
+
paths = Dir["**/#{name}"].sort
|
90
|
+
warn "More than one file found: #{paths}" if paths.size > 1
|
91
|
+
path = paths.first
|
92
|
+
File.expand_path(path) if path
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Use pkg-config to search for shared libraries
|
97
|
+
def pkg_config_search(lib_name, pkg_name)
|
98
|
+
PKGConfig.variable(pkg_name, 'sopath')
|
99
|
+
rescue PackageConfig::NotFoundError => e
|
100
|
+
warn "#{e.message} Cannot find #{lib_name}. "
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|