ruby-gr 0.0.24 → 0.61.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.so (NOT .dylib)
61
+ # MacOSX | lib/libGR.dylib ( <= v0.53.0 .so)
61
62
  # Ubuntu | lib/libGR.so
62
- self.ffi_lib = case RbConfig::CONFIG['host_os']
63
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
64
- search_shared_library('libgr.dll', 'gr')
65
- else
66
- search_shared_library('libGR.so', 'gr')
67
- end
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 [Array, NArray] A list containing the X coordinates
169
- # @param y [Array, NArray] A list containing the Y coordinates
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
- super(n, x, y)
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 [Array, NArray] A list containing the X coordinates
183
- # @param y [Array, NArray] A list containing the Y coordinates
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
- super(n, x, y)
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
- super(x, y, dimx, dimy, 1, 1, dimx, dimy, int(color))
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 xorg [Numeric] X coordinate of the disk center in world
337
+ # @param x_org [Numeric] X coordinate of the disk center in world
274
338
  # coordinates
275
- # @param yorg [Numeric] Y coordinate of the disk center in world
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 dimiphi [Integer] Phi (X) dimension of the color index array
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
- # @params indicator [Integer] An indicator specifying whether clipping is on
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 lavels [Array, NArray] A list of contour levels
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
- # @!method beginprint
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
- # @parm codes [Array, NArray] N-length array of path codes
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
- # @parm fill [Integer]
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
- def interp2(x, y, z, xq, yq, method, extrapval) # flatten
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 : GR_PROJECTION_DEFAULT - default
2031
- # * 1 : GR_PROJECTION_ORTHOGRAPHIC - orthographic
2032
- # * 2 : GR_PROJECTION_PERSPECTIVE - perspective
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::Extern
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.so (NOT .dylib)
71
+ # MacOSX | lib/libGR3.dylib ( <= v0.53.0 .so)
71
72
  # Ubuntu | lib/libGR3.so
72
- self.ffi_lib = case RbConfig::CONFIG['host_os']
73
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
74
- search_shared_library('libGR3.dll', 'gr3')
75
- else
76
- search_shared_library('libGR3.so', 'gr3')
77
- end
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
- GRCommons::GRCommonUtils.public_send(default_type, arg)
19
+ GRCommonUtils.public_send(default_type, arg)
20
20
  when ->(x) { defined?(Numo::NArray) && x.is_a?(Numo::NArray) }
21
- GRCommons::GRCommonUtils.public_send(default_type, arg)
21
+ GRCommonUtils.public_send(default_type, arg)
22
22
  else
23
23
  arg
24
24
  end
@@ -188,7 +188,7 @@ module GRCommons
188
188
  @size = @ptr.size
189
189
  else
190
190
  @size = type2size(type) * num
191
- @ptr = Fiddle::Pointer.malloc(@size)
191
+ @ptr = Fiddle::Pointer.malloc(@size, Fiddle::RUBY_FREE)
192
192
  end
193
193
  end
194
194
 
@@ -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) # TODO
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(:uint, data.to_a.flatten) # TODO
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 'search_shared_library'
11
- require_relative 'extern'
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