torqml 0.1.1

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.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +32 -0
  3. data/.yardopts +3 -0
  4. data/Gemfile +5 -0
  5. data/LICENSE +21 -0
  6. data/README.md +148 -0
  7. data/Rakefile +6 -0
  8. data/assets/images/capture.png +0 -0
  9. data/assets/images/configure.png +0 -0
  10. data/assets/images/edit.png +0 -0
  11. data/assets/images/play.png +0 -0
  12. data/assets/images/reload.png +0 -0
  13. data/assets/images/stop.png +0 -0
  14. data/assets/shapes/TQBox.obj +44 -0
  15. data/assets/shapes/TQCone.obj +169 -0
  16. data/assets/shapes/TQCylinder.obj +585 -0
  17. data/assets/shapes/TQSphere.obj +1497 -0
  18. data/assets/shapes/TQTorus.obj +3754 -0
  19. data/bin/torqml +12 -0
  20. data/examples/SerialLink/SerialLink.qml +35 -0
  21. data/examples/SerialLink/main.qml +29 -0
  22. data/examples/SerialLink/main_multi.qml +40 -0
  23. data/examples/Tutorial/MyModel.qml +34 -0
  24. data/examples/Tutorial/main_00_minimal.qml +10 -0
  25. data/examples/Tutorial/main_01_property.qml +15 -0
  26. data/examples/Tutorial/main_02_pose.qml +19 -0
  27. data/examples/Tutorial/main_03_link.qml +32 -0
  28. data/examples/Tutorial/main_04_importmodel.qml +7 -0
  29. data/examples/Tutorial/main_05_cameralight.qml +17 -0
  30. data/examples/Tutorial/main_06_animation.qml +18 -0
  31. data/examples/WheeledVehicle/WheeledVehicle.qml +62 -0
  32. data/examples/WheeledVehicle/data/maze2014student.dat +19 -0
  33. data/examples/WheeledVehicle/data/wheeledvehicle.csv +11712 -0
  34. data/examples/WheeledVehicle/main.qml +38 -0
  35. data/examples/WheeledVehicle/plugins/MazeWallGenerator/plugin.rb +68 -0
  36. data/examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/MazeHorizWall.qml +29 -0
  37. data/examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/MazeVertWall.qml +30 -0
  38. data/examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/MazeWallGenerator.qml +24 -0
  39. data/examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/qmldir +4 -0
  40. data/examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/wallAllocator.js +47 -0
  41. data/ext/TorQML/FrameGrabber/extconf.rb +45 -0
  42. data/ext/TorQML/FrameGrabber/framegrabber.cpp +36 -0
  43. data/ext/TorQML/FrameGrabber/framegrabber.pro +9 -0
  44. data/ext/TorQML/FrameGrabber/qmldir +2 -0
  45. data/lib/torqml.rb +47 -0
  46. data/lib/torqml/datasources.rb +12 -0
  47. data/lib/torqml/datasources/csvdatasource.rb +44 -0
  48. data/lib/torqml/datasources/datasource.rb +44 -0
  49. data/lib/torqml/datasources/lineardatasource.rb +47 -0
  50. data/lib/torqml/datasources/matrixdatasource.rb +37 -0
  51. data/lib/torqml/plugins.rb +44 -0
  52. data/lib/torqml/version.rb +6 -0
  53. data/plugins/DO_NOT_MODIFY_THIS_DIRECTORY +2 -0
  54. data/qml/TorQML/DataSources/TQCSVDataSource.qml +17 -0
  55. data/qml/TorQML/DataSources/TQLinearDataSource.qml +18 -0
  56. data/qml/TorQML/DataSources/qmldir +3 -0
  57. data/qml/TorQML/Shapes/TQAxis.qml +26 -0
  58. data/qml/TorQML/Shapes/TQBox.qml +11 -0
  59. data/qml/TorQML/Shapes/TQCone.qml +17 -0
  60. data/qml/TorQML/Shapes/TQCoordinate.qml +30 -0
  61. data/qml/TorQML/Shapes/TQCylinder.qml +17 -0
  62. data/qml/TorQML/Shapes/TQGrid.qml +36 -0
  63. data/qml/TorQML/Shapes/TQPrimitive.qml +33 -0
  64. data/qml/TorQML/Shapes/TQSphere.qml +18 -0
  65. data/qml/TorQML/Shapes/TQTorus.qml +18 -0
  66. data/qml/TorQML/Shapes/qmldir +10 -0
  67. data/qml/TorQML/TQModel.qml +9 -0
  68. data/qml/TorQML/Views/Dialogs/TQCaptureDialog.qml +197 -0
  69. data/qml/TorQML/Views/Dialogs/TQProgressDialog.qml +36 -0
  70. data/qml/TorQML/Views/Dialogs/qmldir +3 -0
  71. data/qml/TorQML/Views/TQBasicView.qml +148 -0
  72. data/qml/TorQML/Views/TQCamera.qml +11 -0
  73. data/qml/TorQML/Views/TQViewport.qml +41 -0
  74. data/qml/TorQML/Views/basicview.js +172 -0
  75. data/qml/TorQML/Views/mouseEventHandler.js +55 -0
  76. data/qml/TorQML/Views/qmldir +4 -0
  77. data/qml/TorQML/qmldir +2 -0
  78. data/torqml.gemspec +29 -0
  79. metadata +181 -0
@@ -0,0 +1,172 @@
1
+ function updateFrame() {
2
+ if(!_viewport) return; // viewport has not initialized yet
3
+
4
+ for(var i = 0; i < _viewport.children.length; i++){
5
+ if("dataSource" in _viewport.children[i])
6
+ _viewport.children[i].dataSource.currentFrame = _slider.value // update current frame
7
+ }
8
+ _slider.from = _slider.value;
9
+ _frameText.text = Math.floor(_slider.value)
10
+ }
11
+
12
+ function restartTransition(value) {
13
+ // suspend & resume transition to apply the change of time/frame value
14
+ if(_sliderTransition.running){
15
+ _sliderTransition.stop();
16
+ _sliderTransition.start();
17
+ }
18
+ }
19
+
20
+ function reloadData() {
21
+ var min = -1;
22
+ for(var i = 0; i < _viewport.children.length; i++){
23
+ if("dataSource" in _viewport.children[i]){
24
+ _viewport.children[i].dataSource.prepare_data();
25
+ var n = _viewport.children[i].dataSource.rows();
26
+ // use minimum number as the maximum frame number
27
+ if(min <= 0) min = n;
28
+ else min = Math.min(min, n);
29
+ }
30
+ }
31
+ // FIXME: what if `min` is still negative here?
32
+ numberOfFrames = min;
33
+ _slider.value = 1;
34
+ }
35
+
36
+ function showCaptureDialog() {
37
+ // stop before proceeding
38
+ _sliderTransition.stop();
39
+
40
+ _captureDialog.frameWidth = _viewport.width;
41
+ _captureDialog.frameHeight = _viewport.height;
42
+ _captureDialog.maxFrame = numberOfFrames;
43
+ _captureDialog.show();
44
+ }
45
+
46
+ function onCaptureDialogClosed() {
47
+ var target = _captureConnection.target;
48
+ if(target.visible) return;
49
+
50
+ // closed with OK button
51
+ if(target.returnValue){
52
+ var config = JSON.parse(target.returnValue);
53
+ _window.width = config.dimension.width + _window.width - _viewport.width;
54
+ _window.height = config.dimension.height + _window.height - _viewport.height;
55
+
56
+ // preset frame range
57
+ if(config.range.mode == "current"){
58
+ config.range.from = config.range.to = _slider.value;
59
+ } else if(config.range.mode == "all"){
60
+ config.range.from = 1;
61
+ config.range.to = numberOfFrames;
62
+ }
63
+
64
+ // show a dialog to display the progress of exporting
65
+ _progressDialog.minimumValue = config.range.from;
66
+ _progressDialog.maximumValue = config.range.to;
67
+ _progressDialog.show();
68
+
69
+ // set configs and initial value, then delegate bootstrap to `_frameGrabberStarter`
70
+ _frameGrabberTimer.config = config;
71
+ _frameGrabberTimer.currentFrame = config.range.from;
72
+ _frameGrabberStarter.start();
73
+ }
74
+ }
75
+
76
+ function shouldFinish() {
77
+ var config = _frameGrabberTimer.config;
78
+
79
+ if(_frameGrabberTimer.currentFrame > config.range.to){
80
+ // finish exporting
81
+ _progressDialog.close();
82
+ _frameGrabberTimer.stop();
83
+ return true;
84
+ }
85
+
86
+ // abort exporting
87
+ if(!_progressDialog.visible) return true;
88
+
89
+ return false;
90
+ }
91
+
92
+ function captureFrame() {
93
+ if(shouldFinish()) return;
94
+
95
+ var config = _frameGrabberTimer.config;
96
+
97
+ // update values and capture a frame
98
+ _slider.value = _frameGrabberTimer.currentFrame;
99
+ _progressDialog.value = _frameGrabberTimer.currentFrame;
100
+
101
+ var filePath = config.path.directory + "/" + config.path.prefix + _frameGrabberTimer.currentFrame + ".png";
102
+ _frameGrabber.capture(
103
+ filePath,
104
+ 0, _window.height - _viewport.height - _statusBar.height,
105
+ _viewport.width, _viewport.height
106
+ );
107
+ _frameGrabberTimer.currentFrame += config.range.frameSkip + 1;
108
+ }
109
+
110
+ function onKeyPressed(event) {
111
+ // offers vim-like motion + arrow keys
112
+ event.accepted = true;
113
+ switch(event.key){
114
+ case Qt.Key_Left:
115
+ case Qt.Key_H:
116
+ if(_sliderTransition.running) _sliderTransition.stop();
117
+ _slider.value--;
118
+ break;
119
+ case Qt.Key_Right:
120
+ case Qt.Key_L:
121
+ if(_sliderTransition.running) _sliderTransition.stop();
122
+ _slider.value++;
123
+ break;
124
+ case Qt.Key_W:
125
+ if(_sliderTransition.running) _sliderTransition.stop();
126
+ if(event.modifiers & Qt.ShiftModifier){
127
+ _slider.value += 40;
128
+ } else {
129
+ _slider.value += 10;
130
+ }
131
+ break;
132
+ case Qt.Key_B:
133
+ if(_sliderTransition.running) _sliderTransition.stop();
134
+ if(event.modifiers & Qt.ShiftModifier){
135
+ _slider.value -= 40;
136
+ } else {
137
+ _slider.value -= 10;
138
+ }
139
+ break;
140
+ case Qt.Key_G:
141
+ if(_sliderTransition.running) _sliderTransition.stop();
142
+ if(event.modifiers & Qt.ShiftModifier){
143
+ _slider.value = numberOfFrames;
144
+ } else {
145
+ _slider.value = 1;
146
+ }
147
+ break;
148
+ default:
149
+ event.accepted = false;
150
+ break;
151
+ }
152
+ }
153
+
154
+ function initialize() {
155
+ // adjust window size to fix the size of viewport
156
+ _window.width -= _viewport.width;
157
+ _window.height -= _viewport.height;
158
+
159
+ // to avoid pointing out of bound, use the least value of frame numbers as the number of frames
160
+ var min = -1;
161
+ for(var i = 0; i < _viewport.children.length; i++){
162
+ if("dataSource" in _viewport.children[i]){
163
+ _viewport.children[i].dataSource.prepare_data();
164
+ var n = _viewport.children[i].dataSource.rows();
165
+ if(min < 0) min = n;
166
+ else min = Math.min(min, n);
167
+ }
168
+ }
169
+ numberOfFrames = min;
170
+ }
171
+
172
+ // vim:set ts=4 sw=4 et:
@@ -0,0 +1,55 @@
1
+ function onPressed(mouse) {
2
+ _viewport.focus = true;
3
+ if (mouse.button == Qt.LeftButton) {
4
+ _mouseArea.startX = mouse.x;
5
+ _mouseArea.startY = mouse.y;
6
+ _mouseArea.startEye = _viewport.camera.eye;
7
+ _mouseArea.startCenter = _viewport.camera.center;
8
+ _mouseArea.startUpVector = _viewport.camera.upVector;
9
+ if (mouse.modifiers & Qt.ShiftModifier) {
10
+ _mouseArea.translating = true;
11
+ } else {
12
+ _mouseArea.rotating = true;
13
+ }
14
+ }
15
+ }
16
+
17
+ function onReleased(mouse) {
18
+ if (mouse.button == Qt.LeftButton) {
19
+ _mouseArea.rotating = false;
20
+ _mouseArea.translating = false;
21
+ }
22
+ }
23
+
24
+ function onPositionChanged(mouse) {
25
+ var deltaX = mouse.x - _mouseArea.startX;
26
+ var deltaY = mouse.y - _mouseArea.startY;
27
+ if (_mouseArea.rotating) {
28
+ var angleAroundY = deltaX * 90 / _mouseArea.width;
29
+ var angleAroundX = deltaY * 90 / _mouseArea.height;
30
+ _viewport.camera.eye = _mouseArea.startEye;
31
+ _viewport.camera.center = _mouseArea.startCenter;
32
+ _viewport.camera.upVector = _mouseArea.startUpVector;
33
+ _viewport.camera.tiltPanRollCenter(-angleAroundX, -angleAroundY, 0);
34
+ } else if (_mouseArea.translating) {
35
+ var e = _mouseArea.startEye.minus(_mouseArea.startCenter);
36
+ var e3 = e.normalized();
37
+ var e2 = _mouseArea.startUpVector.normalized();
38
+ var e1 = e2.crossProduct(e3);
39
+ var deltaE1 = deltaX * e.length() * 0.5 / _mouseArea.width;
40
+ var deltaE2 = deltaY * e.length() * 0.5 / _mouseArea.height;
41
+ var afterEye = _mouseArea.startEye.minus(e1.times(deltaE1)).plus(e2.times(deltaE2));
42
+ var afterCenter = _mouseArea.startCenter.minus(e1.times(deltaE1)).plus(e2.times(deltaE2));
43
+ _viewport.camera.eye = afterEye;
44
+ _viewport.camera.center = afterCenter;
45
+ }
46
+ }
47
+
48
+ function onWheel(wheel) {
49
+ var delta = wheel.angleDelta.y / 2000;
50
+ var e = _viewport.camera.eye;
51
+ var afterEye = e.minus(e.times(delta));
52
+ _viewport.camera.eye = afterEye;
53
+ }
54
+
55
+ // vim:set ts=4 sw=4 et:
@@ -0,0 +1,4 @@
1
+ module TorQML.Views
2
+ TQBasicView 0.1 TQBasicView.qml
3
+ TQViewport 0.1 TQViewport.qml
4
+ TQCamera 0.1 TQCamera.qml
@@ -0,0 +1,2 @@
1
+ module TorQML
2
+ TQModel 0.1 TQModel.qml
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'torqml/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "torqml"
8
+ s.version = TorQML::VERSION
9
+ s.authors = ["Yuichi Tadokoro"]
10
+ s.email = ["tokoro10g@tokor.org"]
11
+ s.homepage = "http://torqml.tokor.org/"
12
+ s.license = "MIT"
13
+ s.summary = %q{A 3D visualization toolkit for simulations}
14
+ s.description = %q{TorQML provides an architecture for describing 3D structures in Qt Quick QML and enables you to animate the models with numerical data series.}
15
+
16
+ s.files = `git ls-files -z`.split("\x0")
17
+ s.executables = s.files.grep(%r{^bin/}){ |f| File.basename(f) }
18
+ s.test_files = s.files.grep(%r{^(test,spec,features)/})
19
+ s.require_paths = ["lib"]
20
+ s.extensions = ["ext/TorQML/FrameGrabber/extconf.rb"]
21
+
22
+ s.required_ruby_version = '>=2.0.0'
23
+
24
+ s.add_runtime_dependency "qml", "~> 1.0"
25
+
26
+ s.add_development_dependency "bundler", "~> 1.5"
27
+ s.add_development_dependency "rake", "~> 10.3"
28
+ s.add_development_dependency "rspec", "~> 3.0"
29
+ end
metadata ADDED
@@ -0,0 +1,181 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: torqml
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Yuichi Tadokoro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: qml
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description: TorQML provides an architecture for describing 3D structures in Qt Quick
70
+ QML and enables you to animate the models with numerical data series.
71
+ email:
72
+ - tokoro10g@tokor.org
73
+ executables:
74
+ - torqml
75
+ extensions:
76
+ - ext/TorQML/FrameGrabber/extconf.rb
77
+ extra_rdoc_files: []
78
+ files:
79
+ - ".gitignore"
80
+ - ".yardopts"
81
+ - Gemfile
82
+ - LICENSE
83
+ - README.md
84
+ - Rakefile
85
+ - assets/images/capture.png
86
+ - assets/images/configure.png
87
+ - assets/images/edit.png
88
+ - assets/images/play.png
89
+ - assets/images/reload.png
90
+ - assets/images/stop.png
91
+ - assets/shapes/TQBox.obj
92
+ - assets/shapes/TQCone.obj
93
+ - assets/shapes/TQCylinder.obj
94
+ - assets/shapes/TQSphere.obj
95
+ - assets/shapes/TQTorus.obj
96
+ - bin/torqml
97
+ - examples/SerialLink/SerialLink.qml
98
+ - examples/SerialLink/main.qml
99
+ - examples/SerialLink/main_multi.qml
100
+ - examples/Tutorial/MyModel.qml
101
+ - examples/Tutorial/main_00_minimal.qml
102
+ - examples/Tutorial/main_01_property.qml
103
+ - examples/Tutorial/main_02_pose.qml
104
+ - examples/Tutorial/main_03_link.qml
105
+ - examples/Tutorial/main_04_importmodel.qml
106
+ - examples/Tutorial/main_05_cameralight.qml
107
+ - examples/Tutorial/main_06_animation.qml
108
+ - examples/WheeledVehicle/WheeledVehicle.qml
109
+ - examples/WheeledVehicle/data/maze2014student.dat
110
+ - examples/WheeledVehicle/data/wheeledvehicle.csv
111
+ - examples/WheeledVehicle/main.qml
112
+ - examples/WheeledVehicle/plugins/MazeWallGenerator/plugin.rb
113
+ - examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/MazeHorizWall.qml
114
+ - examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/MazeVertWall.qml
115
+ - examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/MazeWallGenerator.qml
116
+ - examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/qmldir
117
+ - examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/wallAllocator.js
118
+ - ext/TorQML/FrameGrabber/extconf.rb
119
+ - ext/TorQML/FrameGrabber/framegrabber.cpp
120
+ - ext/TorQML/FrameGrabber/framegrabber.pro
121
+ - ext/TorQML/FrameGrabber/qmldir
122
+ - lib/torqml.rb
123
+ - lib/torqml/datasources.rb
124
+ - lib/torqml/datasources/csvdatasource.rb
125
+ - lib/torqml/datasources/datasource.rb
126
+ - lib/torqml/datasources/lineardatasource.rb
127
+ - lib/torqml/datasources/matrixdatasource.rb
128
+ - lib/torqml/plugins.rb
129
+ - lib/torqml/version.rb
130
+ - plugins/DO_NOT_MODIFY_THIS_DIRECTORY
131
+ - qml/TorQML/DataSources/TQCSVDataSource.qml
132
+ - qml/TorQML/DataSources/TQLinearDataSource.qml
133
+ - qml/TorQML/DataSources/qmldir
134
+ - qml/TorQML/Shapes/TQAxis.qml
135
+ - qml/TorQML/Shapes/TQBox.qml
136
+ - qml/TorQML/Shapes/TQCone.qml
137
+ - qml/TorQML/Shapes/TQCoordinate.qml
138
+ - qml/TorQML/Shapes/TQCylinder.qml
139
+ - qml/TorQML/Shapes/TQGrid.qml
140
+ - qml/TorQML/Shapes/TQPrimitive.qml
141
+ - qml/TorQML/Shapes/TQSphere.qml
142
+ - qml/TorQML/Shapes/TQTorus.qml
143
+ - qml/TorQML/Shapes/qmldir
144
+ - qml/TorQML/TQModel.qml
145
+ - qml/TorQML/Views/Dialogs/TQCaptureDialog.qml
146
+ - qml/TorQML/Views/Dialogs/TQProgressDialog.qml
147
+ - qml/TorQML/Views/Dialogs/qmldir
148
+ - qml/TorQML/Views/TQBasicView.qml
149
+ - qml/TorQML/Views/TQCamera.qml
150
+ - qml/TorQML/Views/TQViewport.qml
151
+ - qml/TorQML/Views/basicview.js
152
+ - qml/TorQML/Views/mouseEventHandler.js
153
+ - qml/TorQML/Views/qmldir
154
+ - qml/TorQML/qmldir
155
+ - torqml.gemspec
156
+ homepage: http://torqml.tokor.org/
157
+ licenses:
158
+ - MIT
159
+ metadata: {}
160
+ post_install_message:
161
+ rdoc_options: []
162
+ require_paths:
163
+ - lib
164
+ required_ruby_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: 2.0.0
169
+ required_rubygems_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ requirements: []
175
+ rubyforge_project:
176
+ rubygems_version: 2.2.2
177
+ signing_key:
178
+ specification_version: 4
179
+ summary: A 3D visualization toolkit for simulations
180
+ test_files: []
181
+ has_rdoc: