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.
- 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
|