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
data/lib/glut_window.rb CHANGED
@@ -15,7 +15,7 @@ module Disp3D
15
15
 
16
16
  GLUT.MouseFunc(method(:mouse).to_proc())
17
17
  GLUT.MotionFunc(method(:motion).to_proc())
18
- GLUT.PassiveMotionFunc(method(:passive_motion).to_proc())
18
+ GLUT.PassiveMotionFunc(method(:motion).to_proc())
19
19
  super(width, height)
20
20
  end
21
21
 
@@ -28,34 +28,40 @@ module Disp3D
28
28
  GLUT.SwapBuffers
29
29
  end
30
30
 
31
- def reshape(w,h)
32
- @camera.reshape(w,h)
31
+ def idle_process(wait_msec = nil, &block)
32
+ if(!wait_msec.nil?)
33
+ new_block = lambda do
34
+ @lasttime = Time.now if(@lasttime.nil?)
35
+ interval = Time.now - @lasttime
36
+ next if( interval < wait_msec/1000.0)
37
+ yield
38
+ @lasttime = Time.now
39
+ end
40
+ GLUT.IdleFunc(new_block)
41
+ else
42
+ GLUT.IdleFunc(block)
43
+ end
33
44
  end
34
45
 
46
+ def start
47
+ fit
48
+ GLUT.MainLoop()
49
+ end
50
+
51
+ private
35
52
  def mouse(button,state,x,y)
36
53
  if(state == GLUT::GLUT_UP)
37
- @mouse_release_proc.call(self, button, x, y) if( @mouse_release_proc != nil)
54
+ mouse_release_process(button, x, y)
38
55
  elsif(state == GLUT::GLUT_DOWN)
39
- @mouse_press_proc.call(self, button, x, y) if( @mouse_press_proc != nil)
56
+ mouse_press_process(button, x, y)
40
57
  end
41
- @manipulator.mouse(button,state,x,y)
42
58
  end
43
59
 
44
60
  def motion(x,y)
45
- @mouse_move_proc.call(self, x,y) if( @mouse_move_proc != nil)
46
- update = @manipulator.motion(x,y)
47
- if(update)
61
+ need_update = mouse_move_process(x, y)
62
+ if(need_update)
48
63
  GLUT.PostRedisplay()
49
64
  end
50
65
  end
51
-
52
- def passive_motion(x,y)
53
- @mouse_move_proc.call(self, x,y) if( @mouse_move_proc != nil)
54
- end
55
-
56
- def start
57
- fit
58
- GLUT.MainLoop()
59
- end
60
66
  end
61
67
  end
data/lib/light.rb CHANGED
@@ -2,38 +2,21 @@ require 'disp3D'
2
2
 
3
3
  module Disp3D
4
4
  class Light
5
- def gl_display()
6
- idx = 0
7
- GL.Enable(GL::GL_LIGHTING)
8
- all_disable = true
9
- @enable.each do | enable |
10
- if(enable)
11
- GL.Enable( @light_id[idx])
12
- GL.Lightfv( @light_id[idx], GL::GL_POSITION, @position[idx] )
13
- GL.Lightfv( @light_id[idx], GL::GL_DIFFUSE, @deffuse[idx] )
14
- GL.Lightfv( @light_id[idx], GL::GL_AMBIENT, @ambient[idx] )
15
- GL.Lightfv( @light_id[idx], GL::GL_SPECULAR, @specular[idx] )
16
- all_disable = false
17
- end
18
- end
19
- if(all_disable)
20
- GL.Enable(@light_id[0])
21
- end
22
- end
23
-
24
5
  def initialize()
25
6
  @diffuse_default = [0.7, 0.7, 0.7, 1]
26
7
  @ambient_default = [0.2, 0.2, 0.2, 1]
27
8
  @specular_default = [1, 1, 1, 1]
28
- @position_default = [0.0, 0.0, 1.0, 0.0]
9
+ @position_default = Vector3.new(0.0, 0.0, 1.0)
10
+ @spot_direction_default = Vector3.new(0.0, 0.0, -1.0)
29
11
 
30
12
  light_count = 8 # openGL spec
31
13
 
32
14
  @enable = [false, false, false, false, false, false, false, false]
33
- @deffuse = Array.new(light_count, @diffuse_default)
15
+ @diffuse = Array.new(light_count, @diffuse_default)
34
16
  @ambient = Array.new(light_count, @ambient_default)
35
17
  @specular = Array.new(light_count, @specular_default)
36
18
  @position = Array.new(light_count, @position_default)
19
+ @spot_direction = Array.new(light_count, @spot_direction_default)
37
20
  @light_id = Array.new(light_count)
38
21
  @light_id[0] = GL::GL_LIGHT0
39
22
  @light_id[1] = GL::GL_LIGHT1
@@ -45,5 +28,36 @@ module Disp3D
45
28
  @light_id[7] = GL::GL_LIGHT7
46
29
  end
47
30
 
31
+ def gl_display()
32
+ GL.Enable(GL::GL_LIGHTING)
33
+ @enable.each_with_index do | enable, idx |
34
+ if(enable)
35
+ GL.Enable( @light_id[idx])
36
+ GL.Lightfv( @light_id[idx], GL::POSITION, [@position[idx].x,@position[idx].y,@position[idx].z] )
37
+ GL.Lightfv( @light_id[idx], GL::SPOT_DIRECTION, [@spot_direction[idx].x,@spot_direction[idx].y,@spot_direction[idx].z] )
38
+ GL.Lightfv( @light_id[idx], GL::DIFFUSE, @diffuse[idx] )
39
+ GL.Lightfv( @light_id[idx], GL::AMBIENT, @ambient[idx] )
40
+ GL.Lightfv( @light_id[idx], GL::SPECULAR, @specular[idx] )
41
+ end
42
+ end
43
+ if(!@enable.include?(true))
44
+ GL.Enable(@light_id[0])
45
+ end
46
+ end
47
+
48
+ def open(&block)
49
+ self.instance_eval(&block)
50
+ end
51
+
52
+ private
53
+ def set(hash)
54
+ Util3D.check_key_arg(hash, :id)
55
+ target_idx = hash[:id]
56
+ hash.each do | key, value |
57
+ next if( key == :id)
58
+ target_ary = eval "@#{key.to_s}"
59
+ target_ary[target_idx]=value
60
+ end
61
+ end
48
62
  end
49
63
  end
data/lib/manipulator.rb CHANGED
@@ -1,4 +1,3 @@
1
- # -*- coding: cp932 -*-
2
1
  require 'disp3D'
3
2
 
4
3
  include GMath3D
@@ -15,8 +14,6 @@ module Disp3D
15
14
  @scalling = false
16
15
  @translating = false
17
16
  @trackball_size = 0.8
18
-
19
- @compass = Compass.new(camera)
20
17
  end
21
18
 
22
19
  def centering(scene_graph)
@@ -97,10 +94,6 @@ module Disp3D
97
94
  return false
98
95
  end
99
96
 
100
- def gl_display_compass
101
- @compass.gl_display()
102
- end
103
-
104
97
  private
105
98
  def set_clicked_point_as_rotation_center(x,y)
106
99
  results = @picker.pick(x,y)
data/lib/node/node.rb CHANGED
@@ -1,90 +1,115 @@
1
1
  require 'disp3D'
2
2
 
3
+ class Class
4
+ # use this instead of attr_accessor.
5
+ # if attribute is changed call Node#update
6
+ def attr_for_disp(attribute)
7
+ define_method "#{attribute}=" do |value|
8
+ instance_variable_set("@#{attribute}", value)
9
+ update_for_display
10
+ end
11
+ define_method attribute do
12
+ instance_variable_get "@#{attribute}"
13
+ end
14
+ end
15
+ end
16
+
3
17
  module Disp3D
4
18
  class Node
5
- attr_accessor :pre_translate # GMath3D::Vector3
6
- attr_accessor :rotate # GMath3D::Quat
7
- attr_accessor :post_translate # GMath3D::Vector3
19
+ attr_for_disp :pre_translate # GMath3D::Vector3
20
+ attr_for_disp :rotate # GMath3D::Quat
21
+ attr_for_disp :post_translate # GMath3D::Vector3
8
22
 
9
23
  attr_reader :name
10
24
  attr_reader :instance_id
11
-
12
- attr_accessor :parents # Array of Node
25
+ attr_reader :parents # Array of Node
13
26
 
14
27
  def initialize(name = nil)
15
28
  Util3D.check_arg_type(Symbol, name, true)
16
-
17
- @name = name
18
- @translate = nil
19
- @rotate = nil
20
29
  @parents = []
21
30
  @instance_id = gen_instance_id()
22
- Node.add_to_node_name_db(self) if(!name.nil?)
31
+ @name = name
32
+ NodeDB.add(self)
23
33
  end
24
34
 
25
- # path id DB
26
- def self.init_path_db
27
- @path_db = Hash.new
35
+ def pre_draw
36
+ GL.PushMatrix()
37
+ GL.Translate(pre_translate.x, pre_translate.y, pre_translate.z) if(@pre_translate)
38
+ GL.MultMatrix(@rotate.to_array) if(@rotate)
39
+ GL.Translate(post_translate.x, post_translate.y, post_translate.z) if(@post_translate)
28
40
  end
29
41
 
30
- def self.add_to_path_db(path_id, node)
31
- return @path_db[path_id] = node
42
+ def post_draw
43
+ GL.PopMatrix()
32
44
  end
33
45
 
34
- def self.find_node_by_path_id(path_id)
35
- return @path_db[path_id]
46
+ def ancestors
47
+ rtn_ancestors_ary = []
48
+ return ancestors_inner(rtn_ancestors_ary)
36
49
  end
37
50
 
38
- # node name DB
39
- def self.add_to_node_name_db(node)
40
- Util3D.check_arg_type(Node, node)
41
- @node_db ||= Hash.new()
42
- key = node.name
43
- if(!@node_db.key?(key))
44
- @node_db[key] = node
45
- elsif(@node_db[key].kind_of?(Node))
46
- @node_db[key] = [@node_db[key], node]
47
- elsif(@node_db[key].kind_of?(Array))
48
- @node_db[key].push(node)
51
+ protected
52
+ def create(hash)
53
+ Util3D.check_key_arg(hash, :type)
54
+ geom_arg = hash[:geom]
55
+ name_arg = hash[:name]
56
+ clazz = eval "Node" + hash[:type].to_s
57
+ # node leaf constractor need 2 args
58
+ if( clazz < Disp3D::NodeLeaf )
59
+ new_node = clazz.new(geom_arg, name_arg)
60
+ elsif( clazz <= Disp3D::NodeCollection )
61
+ new_node = clazz.new(name_arg)
49
62
  else
50
63
  raise
51
64
  end
65
+ hash.delete(:geom)
66
+ hash.delete(:type)
67
+ hash.delete(:name)
68
+ new_node.update(hash)
69
+ return new_node
52
70
  end
53
71
 
54
- def self.find_node_by_name(node_name)
55
- Util3D.check_arg_type(Symbol, node_name)
56
- return @node_db[node_name]
57
- end
58
-
59
- def self.delete_from_node_name_db_by_node(node)
60
- node_name = node.name
61
- if(!node_name.nil?)
62
- entry = find_node_by_name(node_name)
63
- if(entry == node)
64
- @node_db[node_name] = nil
65
- elsif(entry.kind_of?(Array))
66
- entry.reject!{|item| item == node}
72
+ # cannnot contains key :type and :name. they cannot be set
73
+ def update(hash)
74
+ if(hash.include?(:name))
75
+ node = NodeDB.find_by_name(hash[:name])
76
+ hash.delete(:name)
77
+ if(node.kind_of?(Array))
78
+ node.each do |item|
79
+ item.update(hash)
80
+ end
81
+ elsif(!node.nil?)
82
+ node.update(hash)
83
+ end
84
+ elsif
85
+ hash.each do | key, value |
86
+ next if( key == :type or key ==:name) # cannot change name and type
87
+ self.send( key.to_s+"=", value)
67
88
  end
68
89
  end
69
90
  end
70
91
 
71
- def pre_draw
72
- GL.PushMatrix()
73
- GL.Translate(pre_translate.x, pre_translate.y, pre_translate.z) if(@pre_translate)
74
- GL.MultMatrix(@rotate.to_array) if(@rotate)
75
- GL.Translate(post_translate.x, post_translate.y, post_translate.z) if(@post_translate)
76
- end
92
+ def delete(node_name)
93
+ Util3D::check_arg_type(Symbol, node_name)
94
+ node = NodeDB.find_by_name(node_name)
77
95
 
78
- def post_draw
79
- GL.PopMatrix()
96
+ if(node.kind_of?(Array))
97
+ node.each do | node_ele |
98
+ remove_from_parents(node_ele)
99
+ end
100
+ elsif(!node.nil?)
101
+ remove_from_parents(node)
102
+ end
103
+ NodeDB.delete_by_name(node_name)
80
104
  end
81
105
 
82
- def ancestors
83
- rtn_ancestors_ary = []
84
- return ancestors_inner(rtn_ancestors_ary)
106
+ def remove_from_parents(node)
107
+ Util3D::check_arg_type(Node, node)
108
+ node.parents.each do |parent|
109
+ parent.remove_child_by_node(node)
110
+ end
85
111
  end
86
112
 
87
- protected
88
113
  def box_transform(box)
89
114
  box = box.translate(@pre_translate) if(@pre_translate)
90
115
  box = box.rotate(@rotate) if(@rotate)
@@ -92,24 +117,6 @@ protected
92
117
  return box
93
118
  end
94
119
 
95
- def create(hash)
96
- Util3D.check_key_arg(hash, :type)
97
- geom = hash[:geom]
98
- name = hash[:name]
99
- clazz = eval "Node" + hash[:type].to_s
100
- # node leaf constractor need 2 args
101
- if( clazz < NodeLeaf )
102
- new_node = clazz.new(geom, name)
103
- else
104
- new_node = clazz.new(name)
105
- end
106
- hash.each do | key, value |
107
- next if( key == :geom or key == :type or key ==:name)
108
- new_node.send( key.to_s+"=", value)
109
- end
110
- return new_node
111
- end
112
-
113
120
  def ancestors_inner(rtn_ancestors_ary)
114
121
  parents.each do |parent|
115
122
  if(!rtn_ancestors_ary.include?(parent.instance_id))
@@ -121,48 +128,36 @@ protected
121
128
  end
122
129
 
123
130
  private
124
- def remove(path_id)
125
- if(path_id.kind_of?(Integer))
126
- node = Node.find_node_by_path_id(path_id)
127
- else
128
- Util3D::raise_argurment_error(path_id)
129
- end
130
- node.parents.each do |parent|
131
- parent.remove_child_by_path_id(path_id)
132
- end
131
+ def gen_instance_id
132
+ return GL.GenLists(1)
133
133
  end
134
+ end
134
135
 
135
- def delete(node_name)
136
- if( node_name.kind_of?(Node) )
137
- node = node_name
138
- elsif(node_name.kind_of?(Symbol))
139
- node = Node.find_node_by_name(node_name)
136
+ class NodeDB
137
+ def self.add(node)
138
+ Util3D.check_arg_type(Node, node)
139
+ @node_db ||= Hash.new()
140
+ key = node.name
141
+ if(!@node_db.key?(key))
142
+ @node_db[key] = node
143
+ elsif(@node_db[key].kind_of?(Node))
144
+ @node_db[key] = [@node_db[key], node]
145
+ elsif(@node_db[key].kind_of?(Array))
146
+ @node_db[key].push(node)
140
147
  else
141
- Util3D::raise_argurment_error(node_name)
142
- end
143
- if(node.kind_of?(Array))
144
- node.each do | item |
145
- self.delete(item)
146
- end
147
- end
148
- if(!node.nil?)
149
- node.parents.each do |parent|
150
- parent.remove_child_by_node(node)
151
- end
152
- Node.delete_from_node_name_db_by_node(node)
148
+ raise
153
149
  end
154
150
  end
155
151
 
156
- def gen_instance_id
157
- id_adding = GL.GenLists(1)
158
- return id_adding
152
+ def self.find_by_name(node_name)
153
+ @node_db ||= Hash.new()
154
+ Util3D.check_arg_type(Symbol, node_name)
155
+ return @node_db[node_name]
159
156
  end
160
157
 
161
- @@path_id_list = Array.new()
162
- def gen_path_id
163
- id_adding = @@path_id_list.size
164
- @@path_id_list.push(id_adding)
165
- return id_adding
158
+ def self.delete_by_name(node_name)
159
+ return if @node_db.nil? || node_name.nil?
160
+ @node_db[node_name] = nil
166
161
  end
167
162
  end
168
163
  end
@@ -2,7 +2,7 @@ require 'disp3D'
2
2
 
3
3
  module Disp3D
4
4
  class NodeArrows < NodeLeaf
5
- attr_accessor :width
5
+ attr_for_disp :width
6
6
 
7
7
  def initialize(geom, name = nil)
8
8
  Util3D.check_arg_type(Symbol, name, true)
@@ -1,4 +1,3 @@
1
-
2
1
  require 'disp3D'
3
2
 
4
3
  module Disp3D
@@ -21,14 +20,14 @@ module Disp3D
21
20
  end
22
21
  end
23
22
 
24
- def draw
23
+ def draw currnet_view
25
24
  pre_draw()
26
25
  @children.each do |key, node|
27
26
  if(node.kind_of?(NodeLeaf))
28
- Node.add_to_path_db(key, node)
27
+ NodePathDB.add(key, node)
29
28
  GL.LoadName(key)
30
29
  end
31
- node.draw
30
+ node.draw currnet_view
32
31
  end
33
32
  post_draw()
34
33
  end
@@ -55,6 +54,14 @@ module Disp3D
55
54
  return @children[path_id]
56
55
  end
57
56
 
57
+ def child_nodes
58
+ return @children.values
59
+ end
60
+
61
+ def child_path_id
62
+ return @children.keys
63
+ end
64
+
58
65
  protected
59
66
  def remove_child_by_path_id(path_id)
60
67
  @children.delete(path_id)
@@ -64,25 +71,37 @@ protected
64
71
  @children.reject!{|key, value| value == child_node}
65
72
  end
66
73
 
74
+ def update_for_display
75
+ @children.each do |key, node|
76
+ node.update_for_display
77
+ end
78
+ end
67
79
  private
68
80
  def add_new(node_info, &block)
69
81
  if(block_given?)
70
82
  create_and_add_node_by_block(node_info, &block)
71
83
  elsif(node_info.kind_of?(Hash))
72
84
  create_and_add_node(node_info)
85
+ else
86
+ Util3D.raise_argurment_error(node_info)
73
87
  end
74
88
  end
75
89
 
76
- def create_and_add_node(hash)
77
- new_node = create(hash)
78
- add_node(new_node)
90
+ def remove(path_id)
91
+ if(path_id.kind_of?(Integer))
92
+ node = NodePathDB.find_by_path_id(path_id)
93
+ else
94
+ Util3D::raise_argurment_error(path_id)
95
+ end
96
+ node.parents.each do |parent|
97
+ parent.remove_child_by_path_id(path_id)
98
+ end
79
99
  end
80
100
 
81
- def create_and_add_node_by_block(hash, &block)
82
- hash[:type] = :Collection
83
- new_node = create(hash)
84
- new_node.instance_eval(&block) if(block_given?)
85
- add_node(new_node)
101
+ def add_node_by_name(node_name)
102
+ Util3D.check_arg_type(Symbol, node_name)
103
+ nodes = NodeDB.find_by_name(node_name)
104
+ add_node(nodes)
86
105
  end
87
106
 
88
107
  def add_node(node)
@@ -102,15 +121,42 @@ private
102
121
  node.parents.push(self)
103
122
  return new_id
104
123
  else
105
- raise # invalid Argument
124
+ Util3D.raise_argurment_error(node)
106
125
  end
107
126
  end
108
127
 
109
- def add_node_by_name(node_name)
110
- Util3D.check_arg_type(Symbol, node_name)
111
- nodes = Node.find_node_by_name(node_name)
112
- add_node(nodes)
128
+ def create_and_add_node(hash)
129
+ new_node = create(hash)
130
+ add_node(new_node)
131
+ end
132
+
133
+ def create_and_add_node_by_block(hash, &block)
134
+ hash[:type] = :Collection
135
+ new_node = create(hash)
136
+ new_node.instance_eval(&block) if(block_given?)
137
+ add_node(new_node)
113
138
  end
114
139
 
140
+ @@path_id_list = Array.new()
141
+ def gen_path_id
142
+ id_adding = @@path_id_list.size
143
+ @@path_id_list.push(id_adding)
144
+ return id_adding
145
+ end
146
+ end
147
+
148
+ # hold path id and node connectivity
149
+ class NodePathDB
150
+ def self.init
151
+ @path_db = Hash.new
152
+ end
153
+
154
+ def self.add(path_id, node)
155
+ return @path_db[path_id] = node
156
+ end
157
+
158
+ def self.find_by_path_id(path_id)
159
+ return @path_db[path_id]
160
+ end
115
161
  end
116
162
  end