disp3D 0.2.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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