disp3D 0.2.1 → 1.0.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 (56) hide show
  1. data/Gemfile +1 -1
  2. data/README.md +56 -0
  3. data/VERSION +1 -1
  4. data/disp3D.gemspec +24 -20
  5. data/example/stl_viewer/document_ctrl.rb +2 -2
  6. data/example/stl_viewer/qt_widget_controller.rb +3 -7
  7. data/example/tutorial/03_CameraScene.rb +5 -5
  8. data/example/tutorial/04_Qt.rb +4 -4
  9. data/example/tutorial/05_Pick.rb +13 -13
  10. data/example/tutorial/06_FileParser.rb +3 -3
  11. data/example/tutorial/07_SceneGraph.rb +16 -4
  12. data/example/tutorial/08_SceneGraph2.rb +16 -15
  13. data/example/tutorial/09_Texture.rb +28 -0
  14. data/example/tutorial/10_Animation.rb +27 -0
  15. data/example/tutorial/10_AnimationQt.rb +53 -0
  16. data/example/tutorial/11_MultiView.rb +41 -0
  17. data/example/tutorial/12_Light.rb +65 -0
  18. data/example/tutorial/13_RectPick.rb +38 -0
  19. data/example/tutorial/14_LineRubberband.rb +43 -0
  20. data/example/{test → tutorial}/data/test.png +0 -0
  21. data/example/{test → tutorial}/data/test2.jpg +0 -0
  22. data/lib/camera.rb +8 -0
  23. data/lib/compass.rb +21 -14
  24. data/lib/disp3D.rb +3 -0
  25. data/lib/gl_view.rb +70 -40
  26. data/lib/glut_window.rb +24 -18
  27. data/lib/light.rb +35 -21
  28. data/lib/manipulator.rb +0 -7
  29. data/lib/node/node.rb +100 -105
  30. data/lib/node/node_arrows.rb +1 -1
  31. data/lib/node/node_collection.rb +63 -17
  32. data/lib/node/node_cone.rb +49 -0
  33. data/lib/node/node_coord.rb +26 -11
  34. data/lib/node/node_leaf.rb +17 -11
  35. data/lib/node/node_lines.rb +1 -1
  36. data/lib/node/node_points.rb +2 -1
  37. data/lib/node/node_polylines.rb +1 -1
  38. data/lib/node/node_rectangle.rb +9 -4
  39. data/lib/node/node_sphere.rb +28 -0
  40. data/lib/node/node_tea_pod.rb +4 -4
  41. data/lib/node/node_text.rb +2 -2
  42. data/lib/node/node_tris.rb +1 -1
  43. data/lib/node/node_workplane.rb +33 -1
  44. data/lib/picker.rb +157 -3
  45. data/lib/qt_widget_gl.rb +24 -11
  46. data/lib/scene_graph.rb +3 -3
  47. data/test/node/test_node.rb +230 -0
  48. data/test/node/test_node_collection.rb +99 -79
  49. data/test/test_picker.rb +6 -6
  50. metadata +28 -24
  51. data/README.rdoc +0 -63
  52. data/example/test/capture_test.rb +0 -16
  53. data/example/test/dsl_test.rb +0 -46
  54. data/example/test/texture_test.rb +0 -39
  55. data/test/data/binary_test.stl +0 -0
  56. data/test/data/bunny-flatfoot.stl +0 -0
@@ -0,0 +1,28 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../', 'lib'))
2
+ require 'disp3D'
3
+
4
+ main_view = Disp3D::GLUTWindow.new(600,400)
5
+
6
+ # load images
7
+ file_path1 = File.dirname(__FILE__) + '/data/test.png'
8
+ file_path2 = File.dirname(__FILE__) + '/data/test2.jpg'
9
+
10
+ image1 = Magick::Image.read(file_path1).first
11
+ image2 = Magick::Image.read(file_path2).first
12
+
13
+ length = 100
14
+
15
+ main_view.world_scene_graph.open do
16
+ add_new :type => :Rectangle,
17
+ :geom => Rectangle.new(Vector3.new(-200,0,0), Vector3.new(length,0,0), Vector3.new(0,length,0)),
18
+ :image => image1
19
+
20
+ add_new :type => :Rectangle,
21
+ :geom => Rectangle.new(Vector3.new(0,0,0), Vector3.new(length,0,0), Vector3.new(0,length,0))
22
+
23
+ add_new :type => :Rectangle,
24
+ :geom => Rectangle.new(Vector3.new(200,0,0), Vector3.new(length,0,0), Vector3.new(0,length,0)),
25
+ :image => image2
26
+ end
27
+
28
+ main_view.start
@@ -0,0 +1,27 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../', 'lib'))
2
+ require 'disp3D'
3
+
4
+ main_view = Disp3D::GLUTWindow.new(400,400,"10_Animation")
5
+
6
+ main_view.world_scene_graph.open do
7
+ add_new :type => :TeaPod,
8
+ :material_color => [1,1,0,1],
9
+ :size => 10.0,
10
+ :name => :pod
11
+ end
12
+
13
+ main_view.idle_process 100 do
14
+ node = Disp3D::NodeDB.find_by_name(:pod)
15
+ if(!node.nil?)
16
+ rot_quat = Quat::from_axis(Vector3.new(0,1,0), 10.0/180.0*Math::PI)
17
+ if(node.rotate.nil?)
18
+ node.rotate = rot_quat
19
+ else
20
+ node.rotate += rot_quat
21
+ end
22
+ end
23
+ main_view.update
24
+ end
25
+ main_view.camera.projection = Disp3D::Camera::ORTHOGONAL
26
+ main_view.start
27
+
@@ -0,0 +1,53 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../', 'lib'))
2
+
3
+ require 'disp3D'
4
+ require 'qt_widget_gl'
5
+
6
+ class TestQTGLWindow < Qt::Widget
7
+ def initialize(parent = nil)
8
+ super
9
+ @gl_widget = QtWidgetGL.new(self, 600, 400)
10
+ self.layout = Qt::HBoxLayout.new do |m|
11
+ m.addWidget(@gl_widget)
12
+ end
13
+ self.windowTitle = tr("10_AnimationQt")
14
+ @is_first_show = true
15
+
16
+ define_idle_process
17
+ end
18
+
19
+ def define_idle_process
20
+ @gl_widget.idle_process 100 do
21
+ node = Disp3D::NodeDB.find_by_name(:pod)
22
+ if(!node.nil?)
23
+ rot_quat = Quat::from_axis(Vector3.new(0,1,0), 10.0/180.0*Math::PI)
24
+ if(node.rotate.nil?)
25
+ node.rotate = rot_quat
26
+ else
27
+ node.rotate += rot_quat
28
+ end
29
+ end
30
+ @gl_widget.update
31
+ end
32
+ end
33
+
34
+ def showEvent(eventArg)
35
+ if( @is_first_show )
36
+ @gl_widget.world_scene_graph.open do
37
+ add_new :type => :TeaPod,
38
+ :material_color => [1,1,0,1],
39
+ :size => 10.0,
40
+ :name => :pod
41
+ end
42
+ @gl_widget.camera.projection = Disp3D::Camera::ORTHOGONAL
43
+ @gl_widget.fit
44
+ @is_first_show = false
45
+ end
46
+ end
47
+ end
48
+
49
+ # start application
50
+ app = Qt::Application.new(ARGV)
51
+ window = TestQTGLWindow.new
52
+ window.show
53
+ app.exec
@@ -0,0 +1,41 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../', 'lib'))
2
+
3
+ require 'disp3D'
4
+ require 'qt_widget_gl'
5
+
6
+ class TestQTGLWindow < Qt::Widget
7
+ def initialize(parent = nil)
8
+ super
9
+ @gl_widget1 = QtWidgetGL.new(self, 300, 300)
10
+ @gl_widget2 = QtWidgetGL.new(self, 300, 300)
11
+ self.layout = Qt::HBoxLayout.new do |m|
12
+ m.addWidget(@gl_widget1)
13
+ m.addWidget(@gl_widget2)
14
+ end
15
+ self.windowTitle = tr("11_MultiView")
16
+ @is_first_show = true
17
+ end
18
+
19
+ def showEvent(eventArg)
20
+ if( @is_first_show )
21
+ @gl_widget1.world_scene_graph.open do
22
+ add_new :type => :TeaPod,
23
+ :material_color => [1,1,0,1],
24
+ :size => 10.0,
25
+ :name => :pod
26
+ end
27
+ @gl_widget2.sync_to @gl_widget1
28
+ @gl_widget1.camera.projection = Disp3D::Camera::ORTHOGONAL
29
+ @gl_widget1.fit
30
+ @gl_widget2.camera.projection = Disp3D::Camera::PERSPECTIVE
31
+ @gl_widget2.fit
32
+ @is_first_show = false
33
+ end
34
+ end
35
+ end
36
+
37
+ # start application
38
+ app = Qt::Application.new(ARGV)
39
+ window = TestQTGLWindow.new
40
+ window.show
41
+ app.exec
@@ -0,0 +1,65 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../', 'lib'))
2
+ require 'disp3D'
3
+
4
+ main_view = Disp3D::GLUTWindow.new(400,400,"12_Light")
5
+
6
+ light_pos_ary = [Vector3.new(30,0,0), Vector3.new(-30,0,0), Vector3.new(0,0,30), Vector3.new(0,5,0)]
7
+ light_spot_dir_ary = [Vector3.new(-1,0,0), Vector3.new(1,0,0), Vector3.new(0,0,-1), Vector3.new(0,-1,0)]
8
+
9
+ main_view.world_scene_graph.open do
10
+ add_new :type => :TeaPod,
11
+ :name => :pod,
12
+ :material_color => [1,1,1,1],
13
+ :size => 10.0
14
+
15
+ add_new :type => :Workplane,
16
+ :name => :workplane,
17
+ :geom => Plane.new(Vector3.new(0,-8,0), Vector3.new(0,1,0)),
18
+ :material_color => [0.8,0.8,0.2,0.5],
19
+ :grid => 10
20
+
21
+ light_pos_ary.each_with_index do |light_pos,idx|
22
+ add_new :type => :Sphere,
23
+ :name => :lightSource,
24
+ :radius => 1.0,
25
+ :center => light_pos
26
+ end
27
+ end
28
+
29
+ main_view.light.open do
30
+ set :id => 0,
31
+ :enable => true,
32
+ :diffuse => [0, 0.7, 0, 1],
33
+ :ambient => [0, 0.2, 0, 1],
34
+ :specular => [0, 1, 0, 1],
35
+ :position => light_pos_ary[0],
36
+ :spot_direction => light_spot_dir_ary[0]
37
+
38
+ set :id => 1,
39
+ :enable => true,
40
+ :diffuse => [0.7, 0, 0, 1],
41
+ :ambient => [0.2, 0, 0, 1],
42
+ :specular => [1, 0, 0, 1],
43
+ :position => light_pos_ary[1],
44
+ :spot_direction => light_spot_dir_ary[1]
45
+
46
+ set :id => 2,
47
+ :enable => true,
48
+ :diffuse => [0, 0, 0.7, 1],
49
+ :ambient => [0, 0, 0.2, 1],
50
+ :specular => [0, 0, 1, 1],
51
+ :position => light_pos_ary[2],
52
+ :spot_direction => light_spot_dir_ary[2]
53
+
54
+ set :id => 3,
55
+ :enable => true,
56
+ :diffuse => [0.7, 0.7, 0.7, 1],
57
+ :ambient => [0.2, 0.2, 0.2, 1],
58
+ :specular => [1, 1, 1, 1],
59
+ :position => light_pos_ary[3],
60
+ :spot_direction => light_spot_dir_ary[3]
61
+ end
62
+
63
+ main_view.camera.projection = Disp3D::Camera::ORTHOGONAL
64
+ main_view.start
65
+
@@ -0,0 +1,38 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../', 'lib'))
2
+ require 'disp3D'
3
+
4
+ main_view = Disp3D::GLUTWindow.new(400,400,"13_RectPick")
5
+
6
+ sphere_count = 20
7
+ main_view.world_scene_graph.open do
8
+ idx = 0
9
+ sphere_count.times.each do |idx_x|
10
+ sphere_count.times.each do |idx_y|
11
+ add_new :type => :Sphere,
12
+ :center => Vector3.new(idx_x*5, idx_y*5, 0),
13
+ :name => "node_#{idx}".to_sym
14
+ idx += 1
15
+ end
16
+ end
17
+ end
18
+
19
+ main_view.picker.max_select_count = 3000
20
+ main_view.picker.start_rect_pick do |results|
21
+ if(results != nil)
22
+ results.each do |result|
23
+ result.node_path_info.each do |path_info|
24
+ main_view.world_scene_graph.open do
25
+ update :name => path_info.node.name,
26
+ :material_color => [1,0,0,1]
27
+ end
28
+ end
29
+ end
30
+ main_view.update
31
+ end
32
+ end
33
+
34
+ main_view.camera.projection = Disp3D::Camera::ORTHOGONAL
35
+ main_view.fit
36
+ main_view.start
37
+
38
+
@@ -0,0 +1,43 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../', 'lib'))
2
+ require 'disp3D'
3
+
4
+ main_view = Disp3D::GLUTWindow.new(400,400,"14_LineRubberband")
5
+
6
+ sphere_count = 20
7
+ main_view.world_scene_graph.open do
8
+ idx = 0
9
+ sphere_count.times.each do |idx_x|
10
+ sphere_count.times.each do |idx_y|
11
+ add_new :type => :Sphere,
12
+ :center => Vector3.new(idx_x*5, idx_y*5, 0),
13
+ :name => "node_#{idx}".to_sym
14
+ idx += 1
15
+ end
16
+ end
17
+ end
18
+
19
+ main_view.picker.post_picked do |start_results, end_results|
20
+ if(!start_results.nil? && start_results.size > 0 && !end_results.nil? && end_results.size >0)
21
+ start_point = start_results[0].world_position
22
+ end_point = end_results[0].world_position
23
+ main_view.world_scene_graph.open do
24
+ add_new :type => :Lines,
25
+ :geom => FiniteLine.new(start_point, end_point),
26
+ :colors => [1,0,0,1]
27
+ end
28
+ main_view.update
29
+ end
30
+ main_view.picker.end_pick
31
+ end
32
+
33
+ main_view.mouse_press do |view, button, x, y|
34
+ next if( button != GLUT::LEFT_BUTTON )
35
+ results = main_view.picker.point_pick(x,y)
36
+ if(results != nil && results.size > 0)
37
+ main_view.picker.start_line_pick
38
+ end
39
+ end
40
+
41
+ main_view.camera.projection = Disp3D::Camera::ORTHOGONAL
42
+ main_view.fit
43
+ main_view.start
File without changes
File without changes
data/lib/camera.rb CHANGED
@@ -32,6 +32,14 @@ module Disp3D
32
32
  @orth_scale = 1.0
33
33
  end
34
34
 
35
+ def switch_projection
36
+ if(@projection == PERSPECTIVE)
37
+ @projection = ORTHOGONAL
38
+ else
39
+ @projection = PERSPECTIVE
40
+ end
41
+ end
42
+
35
43
  def reshape(w,h)
36
44
  GL.Viewport(0.0,0.0,w,h)
37
45
  set_projection_for_world_scene
data/lib/compass.rb CHANGED
@@ -4,26 +4,33 @@ module Disp3D
4
4
  class Compass
5
5
  def initialize(camera)
6
6
  @camera = camera
7
+ @coord_node = NodeCoord.new(nil, Vector3.new(), coord_size)
7
8
  end
8
9
 
9
- def node_coord
10
- dmy, dmy, screen_width, screen_height = @camera.viewport
11
- coord_size = [screen_width, screen_height].min
12
- scalling_factor = 0.1
13
- coord_size *= scalling_factor
14
- @coord_pos = Vector3.new(-screen_width*0.5 + coord_size*1.5, -screen_height*0.5 + coord_size*1.5, 0.0)
15
- node = NodeCoord.new(Vector3.new(), coord_size)
16
- return node
17
- end
18
-
19
- def gl_display
10
+ def gl_display current_view
20
11
  GL.PushMatrix()
21
12
  GL.LoadIdentity()
22
- node = node_coord
23
- GL.Translate(@coord_pos.x, @coord_pos.y, @coord_pos.z)
13
+ GL.Translate(coord_pos.x, coord_pos.y, coord_pos.z)
24
14
  @camera.apply_rotate
25
- node.draw if( !node.nil? )
15
+ @coord_node.draw current_view
26
16
  GL.PopMatrix()
27
17
  end
18
+
19
+ def update
20
+ @coord_node.length = coord_size
21
+ end
22
+
23
+ private
24
+ def coord_pos
25
+ dmy, dmy, screen_width, screen_height = @camera.viewport
26
+ Vector3.new(-screen_width*0.5 + coord_size*1.5, -screen_height*0.5 + coord_size*1.5, 0.0)
27
+ end
28
+
29
+ def coord_size
30
+ dmy, dmy, screen_width, screen_height = @camera.viewport
31
+ coord_size = [screen_width, screen_height].min
32
+ scalling_factor = 0.1
33
+ coord_size *= scalling_factor
34
+ end
28
35
  end
29
36
  end
data/lib/disp3D.rb CHANGED
@@ -26,6 +26,9 @@ require 'node/node_collection'
26
26
  require 'node/node_leaf'
27
27
 
28
28
  require 'node/node_tea_pod'
29
+ require 'node/node_cone'
30
+ require 'node/node_sphere'
31
+
29
32
  require 'node/node_text'
30
33
  require 'node/node_points'
31
34
  require 'node/node_lines'
data/lib/gl_view.rb CHANGED
@@ -5,7 +5,7 @@ module Disp3D
5
5
  # GLView class hold primary object for 3D displaying like camera, scene_graph.
6
6
  # User never use this class
7
7
  # Use QtWidgetGL class (in Qt Application)
8
- # Use GLWindow class (in GLUT Window)
8
+ # Use GLUTWindow class (in GLUT Window)
9
9
  class GLView
10
10
  attr_reader :world_scene_graph
11
11
  attr_reader :camera_scene_graph
@@ -14,10 +14,6 @@ module Disp3D
14
14
  attr_reader :light
15
15
  attr_reader :picker
16
16
 
17
- attr_reader :mouse_move_proc
18
- attr_reader :mouse_press_proc
19
- attr_reader :mouse_release_proc
20
-
21
17
  attr_accessor :bk_color
22
18
 
23
19
  def initialize(width, height)
@@ -42,47 +38,15 @@ module Disp3D
42
38
  @bk_color = [0.28,0.23,0.55,1]
43
39
 
44
40
  @manipulator = Manipulator.new(@camera, @picker)
41
+ @compass = Compass.new(@camera)
45
42
 
46
43
  @mouse_move_proc = nil
47
44
  @mouse_press_proc = nil
48
45
  @mouse_release_proc = nil
49
46
  end
50
47
 
51
- def gl_display()
52
- GL.ClearColor(@bk_color[0],@bk_color[1],@bk_color[2],@bk_color[3])
53
- GL.Clear(GL::GL_COLOR_BUFFER_BIT | GL::GL_DEPTH_BUFFER_BIT)
54
-
55
- return if(@camera.nil? or @light.nil?)
56
- @light.gl_display()
57
-
58
- GL.Enable(GL::GL_DEPTH_TEST)
59
- @camera.set_projection_for_world_scene
60
- gl_display_world_scene_graph()
61
- GL.Disable(GL::GL_DEPTH_TEST)
62
- @camera.set_projection_for_camera_scene
63
- gl_display_camera_scene_graph()
64
- @manipulator.gl_display_compass()
65
- end
66
-
67
- def gl_display_world_scene_graph()
68
- return if(@world_scene_graph.nil?)
69
- GL.MatrixMode(GL::GL_MODELVIEW)
70
- GL.PushMatrix()
71
- GL.LoadIdentity()
72
- @camera.apply_position()
73
- @camera.apply_attitude()
74
- @world_scene_graph.gl_display()
75
- GL.PopMatrix()
76
- end
77
-
78
- def gl_display_camera_scene_graph()
79
- return if(@camera_scene_graph.nil?)
80
- GL.MatrixMode(GL::GL_MODELVIEW)
81
- GL.PushMatrix()
82
- GL.LoadIdentity()
83
- GLU.LookAt(0, 0, 1, 0, 0, 0, 0, 1, 0)
84
- @camera_scene_graph.gl_display()
85
- GL.PopMatrix()
48
+ def sync_to target_view
49
+ @world_scene_graph = target_view.world_scene_graph
86
50
  end
87
51
 
88
52
  def capture
@@ -126,5 +90,71 @@ module Disp3D
126
90
  def mouse_release(&block)
127
91
  @mouse_release_proc = block
128
92
  end
93
+
94
+ def gl_display()
95
+ GL.DrawBuffer( GL::BACK )
96
+ GL.ClearColor(@bk_color[0],@bk_color[1],@bk_color[2],@bk_color[3])
97
+ GL.Clear(GL::GL_COLOR_BUFFER_BIT | GL::GL_DEPTH_BUFFER_BIT)
98
+
99
+ return if(@camera.nil? or @light.nil?)
100
+
101
+ GL.Enable(GL::GL_DEPTH_TEST)
102
+ @camera.set_projection_for_world_scene
103
+ gl_display_world_scene_graph()
104
+ GL.Disable(GL::GL_DEPTH_TEST)
105
+ @camera.set_projection_for_camera_scene
106
+ gl_display_camera_scene_graph()
107
+ @compass.gl_display(self)
108
+ end
109
+
110
+ # users do not need to user them
111
+ #=====================================
112
+ def gl_display_world_scene_graph()
113
+ return if(@world_scene_graph.nil?)
114
+ GL.MatrixMode(GL::GL_MODELVIEW)
115
+ GL.PushMatrix()
116
+ GL.LoadIdentity()
117
+ @camera.apply_position()
118
+ @camera.apply_attitude()
119
+ @light.gl_display()
120
+ @world_scene_graph.gl_display(self)
121
+ GL.PopMatrix()
122
+ end
123
+
124
+ def gl_display_camera_scene_graph()
125
+ return if(@camera_scene_graph.nil?)
126
+ GL.MatrixMode(GL::GL_MODELVIEW)
127
+ GL.PushMatrix()
128
+ GL.LoadIdentity()
129
+ GLU.LookAt(0, 0, 1, 0, 0, 0, 0, 1, 0)
130
+ @camera_scene_graph.gl_display(self)
131
+ GL.PopMatrix()
132
+ end
133
+
134
+ def reshape(w,h)
135
+ @camera.reshape(w,h)
136
+ @compass.update
137
+ end
138
+
139
+ def mouse_press_process(button, x, y)
140
+ @mouse_press_proc.call(self, button, x, y) if( @mouse_press_proc != nil)
141
+ @manipulator.mouse(button, GLUT::GLUT_DOWN, x, y)
142
+ @picker.mouse(button, GLUT::GLUT_DOWN, x, y)
143
+ end
144
+
145
+ def mouse_release_process(button, x, y)
146
+ @mouse_release_proc.call(self, button, x, y) if( @mouse_release_proc != nil)
147
+ @manipulator.mouse(button, GLUT::GLUT_UP, x, y)
148
+ @picker.mouse(button, GLUT::GLUT_UP, x, y)
149
+ end
150
+
151
+ def mouse_move_process(x,y)
152
+ @mouse_move_proc.call(self, x,y) if( @mouse_move_proc != nil)
153
+ picking_in_progress = @picker.motion(x, y)
154
+ if(picking_in_progress)
155
+ return false
156
+ end
157
+ return @manipulator.motion(x, y)
158
+ end
129
159
  end
130
160
  end