siren2 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +21 -0
  6. data/README.md +36 -0
  7. data/Rakefile +18 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/ext/siren2/extconf.rb +66 -0
  11. data/ext/siren2/inc/bndbox.h +51 -0
  12. data/ext/siren2/inc/bo.h +20 -0
  13. data/ext/siren2/inc/brep.h +17 -0
  14. data/ext/siren2/inc/common.h +98 -0
  15. data/ext/siren2/inc/curve.h +65 -0
  16. data/ext/siren2/inc/curve/bscurve.h +22 -0
  17. data/ext/siren2/inc/curve/bzcurve.h +17 -0
  18. data/ext/siren2/inc/curve/circle.h +29 -0
  19. data/ext/siren2/inc/curve/ellipse.h +15 -0
  20. data/ext/siren2/inc/curve/hyperbola.h +15 -0
  21. data/ext/siren2/inc/curve/line.h +17 -0
  22. data/ext/siren2/inc/curve/offsetcurve.h +15 -0
  23. data/ext/siren2/inc/curve/parabola.h +15 -0
  24. data/ext/siren2/inc/filler.h +26 -0
  25. data/ext/siren2/inc/heal.h +19 -0
  26. data/ext/siren2/inc/io/iges.h +19 -0
  27. data/ext/siren2/inc/io/step.h +18 -0
  28. data/ext/siren2/inc/io/stl.h +13 -0
  29. data/ext/siren2/inc/offset.h +35 -0
  30. data/ext/siren2/inc/shape.h +140 -0
  31. data/ext/siren2/inc/shape/chunk.h +26 -0
  32. data/ext/siren2/inc/shape/compound.h +22 -0
  33. data/ext/siren2/inc/shape/edge.h +50 -0
  34. data/ext/siren2/inc/shape/face.h +67 -0
  35. data/ext/siren2/inc/shape/shell.h +21 -0
  36. data/ext/siren2/inc/shape/solid.h +41 -0
  37. data/ext/siren2/inc/shape/vertex.h +23 -0
  38. data/ext/siren2/inc/shape/wire.h +31 -0
  39. data/ext/siren2/inc/siren.h +39 -0
  40. data/ext/siren2/inc/surface/dummy +0 -0
  41. data/ext/siren2/inc/topalgo.h +52 -0
  42. data/ext/siren2/inc/trans.h +48 -0
  43. data/ext/siren2/inc/vec.h +65 -0
  44. data/ext/siren2/src/bndbox.cpp +343 -0
  45. data/ext/siren2/src/bo.cpp +66 -0
  46. data/ext/siren2/src/brep.cpp +69 -0
  47. data/ext/siren2/src/common.cpp +18 -0
  48. data/ext/siren2/src/curve.cpp +75 -0
  49. data/ext/siren2/src/curve/bscurve.cpp +118 -0
  50. data/ext/siren2/src/curve/bzcurve.cpp +55 -0
  51. data/ext/siren2/src/curve/circle.cpp +146 -0
  52. data/ext/siren2/src/curve/ellipse.cpp +17 -0
  53. data/ext/siren2/src/curve/hyperbola.cpp +17 -0
  54. data/ext/siren2/src/curve/line.cpp +24 -0
  55. data/ext/siren2/src/curve/offsetcurve.cpp +17 -0
  56. data/ext/siren2/src/curve/parabola.cpp +17 -0
  57. data/ext/siren2/src/filler.cpp +191 -0
  58. data/ext/siren2/src/heal.cpp +92 -0
  59. data/ext/siren2/src/io/iges.cpp +85 -0
  60. data/ext/siren2/src/io/step.cpp +47 -0
  61. data/ext/siren2/src/io/stl.cpp +22 -0
  62. data/ext/siren2/src/offset.cpp +256 -0
  63. data/ext/siren2/src/shape.cpp +617 -0
  64. data/ext/siren2/src/shape/chunk.cpp +65 -0
  65. data/ext/siren2/src/shape/compound.cpp +96 -0
  66. data/ext/siren2/src/shape/edge.cpp +254 -0
  67. data/ext/siren2/src/shape/face.cpp +366 -0
  68. data/ext/siren2/src/shape/shell.cpp +41 -0
  69. data/ext/siren2/src/shape/solid.cpp +256 -0
  70. data/ext/siren2/src/shape/vertex.cpp +68 -0
  71. data/ext/siren2/src/shape/wire.cpp +100 -0
  72. data/ext/siren2/src/siren.cpp +80 -0
  73. data/ext/siren2/src/surface/dummy +0 -0
  74. data/ext/siren2/src/topalgo.cpp +246 -0
  75. data/ext/siren2/src/trans.cpp +330 -0
  76. data/ext/siren2/src/vec.cpp +454 -0
  77. data/lib/io/dxf.rb +68 -0
  78. data/lib/io/plot.rb +38 -0
  79. data/lib/io/ply.rb +57 -0
  80. data/lib/io/stl.rb +35 -0
  81. data/lib/io/svg.rb +44 -0
  82. data/lib/kernel/array.rb +133 -0
  83. data/lib/kernel/float.rb +15 -0
  84. data/lib/shape.rb +157 -0
  85. data/lib/shape/compound.rb +11 -0
  86. data/lib/shape/edge.rb +15 -0
  87. data/lib/shape/face.rb +7 -0
  88. data/lib/shape/shell.rb +21 -0
  89. data/lib/shape/solid.rb +10 -0
  90. data/lib/shape/vertex.rb +7 -0
  91. data/lib/shape/wire.rb +14 -0
  92. data/lib/shapes.rb +52 -0
  93. data/lib/siren.rb +166 -0
  94. data/lib/siren2/version.rb +3 -0
  95. data/lib/vec.rb +81 -0
  96. data/siren2.gemspec +28 -0
  97. metadata +195 -0
@@ -0,0 +1,68 @@
1
+ #
2
+ # AutoCAD DXF file I/O method
3
+ #
4
+ module Siren
5
+
6
+ def self.save_dxf(shape, path, deflect = 1.0, angle = 5.0.to_rad)
7
+ File.open(path, "w") do |f|
8
+ @ff = f
9
+ def self.w(code, data)
10
+ @ff.write "% 3d\n#{data}\n" % [code]
11
+ end
12
+ def self.wp(pt, ofs = 0)
13
+ w 10 + ofs, pt.x
14
+ w 20 + ofs, pt.y
15
+ w 30 + ofs, pt.z
16
+ end
17
+ w 0, "SECTION"
18
+ w 2, "ENTITIES"
19
+ shape.vertices(Siren::Edge).each do |e|
20
+ w 0, "POINT"
21
+ w 8, "0"
22
+ wp e.xyz
23
+ end
24
+ shape.edges(Siren::Face).each do |e|
25
+ ps = e.to_pts(deflect)
26
+ if ps.size == 2
27
+ w 0, "LINE"
28
+ w 8, "0"
29
+ wp ps.first
30
+ wp ps.last, 1
31
+ else
32
+ w 0, "POLYLINE"
33
+ wp [0, 0, 0]
34
+ w 8, "0"
35
+ w 66, 1
36
+ w 70, 8 # 3D=8,2D=0
37
+ ps.each do |pt|
38
+ w 0, "VERTEX"
39
+ w 8, "0"
40
+ wp pt
41
+ end
42
+ w 0, "SEQEND"
43
+ end
44
+ end
45
+ shape.faces.each do |face|
46
+ face.triangle(deflect, angle).each do |m|
47
+ w 0, "3DFACE"
48
+ w 8, "0"
49
+ mm = m[0,3]
50
+ wp mm[0]
51
+ wp mm[1], 1
52
+ wp mm[2], 2
53
+ wp mm[0], 3
54
+ w 70, 8
55
+ end
56
+ end
57
+ w 0, "ENDSEC"
58
+ w 0, "EOF"
59
+ end
60
+ nil
61
+ end
62
+
63
+ def save_dxf(*args)
64
+ Siren.save_dxf(*args)
65
+ end
66
+
67
+ end
68
+
@@ -0,0 +1,38 @@
1
+ #
2
+ # Gnuplot data file I/O method
3
+ #
4
+ module Siren
5
+
6
+ def self.save_plot(shape, path, face_mode = false, deflect = 1.0, angle = 5.0.to_rad)
7
+ File.open(path, "w") do |f|
8
+ f.puts "# Created by siren - http://siren.xyz/"
9
+ if face_mode
10
+ shape.faces.map {|e|
11
+ e.triangle(deflect, angle).map {|m|
12
+ m[0,3]
13
+ }
14
+ }.flatten(1).each do |m|
15
+ f.puts "%.f %.f %.f" % m[0]
16
+ f.puts "%.f %.f %.f" % m[1]
17
+ f.puts "%.f %.f %.f" % m[2]
18
+ f.puts ""
19
+ end
20
+ else
21
+ # Curve mode
22
+ shape.edges.each do |e|
23
+ e.to_pts(deflect).each do |pos|
24
+ f.puts "%.f %.f %.f" % pos
25
+ end
26
+ f.puts ""
27
+ end
28
+ end
29
+ end
30
+ nil
31
+ end
32
+
33
+ def save_plot(*args)
34
+ Siren.save_plot(*args)
35
+ end
36
+
37
+ end
38
+
@@ -0,0 +1,57 @@
1
+ #
2
+ # Stanford PLY file I/O method
3
+ #
4
+ module Siren
5
+
6
+ def self.save_ply(shape, path, deflect = 1.0, angle = 5.0.to_rad)
7
+ File.open(path, "w") do |f|
8
+ fs = shape.faces.map {|e|
9
+ e.triangle(deflect, angle).map {|m|
10
+ m[0,3]
11
+ }
12
+ }.flatten(1)
13
+ es = shape.edges(Siren::Face).map{|e|
14
+ e.to_pts(deflect)
15
+ }
16
+ vs = [fs, es].flatten(2).sort.uniq
17
+ f.puts "ply"
18
+ f.puts "format ascii 1.0"
19
+ f.puts "comment Created by siren - http://siren.xyz/"
20
+ if vs.size > 0
21
+ f.puts "element vertex %d" % vs.size
22
+ f.puts "property float x"
23
+ f.puts "property float y"
24
+ f.puts "property float z"
25
+ end
26
+ if es.size > 0
27
+ f.puts "element edge %d" % es.size
28
+ f.puts "property uint vertex1"
29
+ f.puts "property uint vertex2"
30
+ end
31
+ if fs.size > 0
32
+ f.puts "element face %d" % fs.size
33
+ f.puts "property list uchar uint vertex_indices"
34
+ end
35
+ f.puts "end_header"
36
+ vs.each do |e|
37
+ f.puts "%.f %.f %.f" % e
38
+ end
39
+ es.each do |e|
40
+ sp = vs.index(e.first)
41
+ tp = vs.index(e.last)
42
+ f.puts "%d %d" % [sp, tp]
43
+ end
44
+ fs.each do |e|
45
+ pts = e.map{|m| vs.index(m)}
46
+ f.puts pts.size.to_s + " " + pts.join(" ")
47
+ end
48
+ nil
49
+ end
50
+ end
51
+
52
+ def save_ply(*args)
53
+ Siren.save_ply(*args)
54
+ end
55
+
56
+ end
57
+
@@ -0,0 +1,35 @@
1
+ #
2
+ # STL file I/O method
3
+ #
4
+
5
+ module Siren
6
+
7
+ def self.save_stl(shape, path, ascii = true, deflect = 1.0, angle = 5.0.to_rad)
8
+ File.open(path, "w") do |f|
9
+ if ascii
10
+ f.write "solid shape, STL ascii file built with siren. http://siren.xyz/\n"
11
+ shape.faces.each do |face|
12
+ face.triangle(deflect, angle).each do |mesh|
13
+ f.write "facet normal %8e %8e %8e\n" % mesh[5]
14
+ f.write " outer loop\n"
15
+ f.write " vertex %8e %8e %8e\n" % mesh[0]
16
+ f.write " vertex %8e %8e %8e\n" % mesh[1]
17
+ f.write " vertex %8e %8e %8e\n" % mesh[2]
18
+ f.write " endloop\n"
19
+ f.write "endfacet\n"
20
+ end
21
+ end
22
+ f.write "endsolid shape\n"
23
+ else
24
+ raise NotImplementedError
25
+ end
26
+ end
27
+ nil
28
+ end
29
+
30
+ def save_stl(*args)
31
+ Siren.save_stl(*args)
32
+ end
33
+
34
+ end
35
+
@@ -0,0 +1,44 @@
1
+ #
2
+ # SVG file I/O method
3
+ #
4
+
5
+ module Siren
6
+
7
+ def self.save_svg(shape, path, deflect = 1.0, angle = 5.0.to_rad)
8
+ File.open(path, "w") do |f|
9
+ df = 0.5 # Depth factor
10
+ header = <<-EOF
11
+ <?xml version='1.0' encoding='utf-8'?>
12
+ <!-- This SVG file built with siren. http://siren.xyz/ -->
13
+ <svg xmlns='http://www.w3.org/2000/svg'>
14
+ <defs>
15
+ <style type='text/css'><![CDATA[
16
+ path {
17
+ fill: none;
18
+ stroke: black;
19
+ stroke-width: 1;
20
+ }
21
+ ]]></style>
22
+ </defs>
23
+ <g transform="matrix(1,0,0,1,0,0)">
24
+ EOF
25
+ f.write header
26
+ shape.edges.each do |edge|
27
+ pts = edge.to_pts(deflect)
28
+ sp = pts.shift
29
+ d = "M#{sp.y + sp.x * df},#{sp.z + sp.x * df}"
30
+ pts.each {|pt| d << "L#{pt.y + pt.x * df},#{pt.z + pt.x * df}" }
31
+ f.write " <path d='#{d}' />\n"
32
+ end
33
+ f.write " </g>\n"
34
+ f.write "</svg>\n"
35
+ end
36
+ nil
37
+ end
38
+
39
+ def save_svg(*args)
40
+ Siren.save_svg(*args)
41
+ end
42
+
43
+ end
44
+
@@ -0,0 +1,133 @@
1
+ #
2
+ # Array クラス拡張メソッド
3
+ #
4
+ class Array
5
+
6
+ def to_v
7
+ Siren::Vec.new self
8
+ end
9
+
10
+ def to(other)
11
+ other.to_v - self.to_v
12
+ end
13
+
14
+ def from(other)
15
+ self.to_v - other.to_v
16
+ end
17
+
18
+ def xyz
19
+ self[0,3]
20
+ end
21
+
22
+ def xyz=(val)
23
+ self[0,3] = val
24
+ end
25
+
26
+ def dist(other)
27
+ (self.to_v - other.to_v).magnitude
28
+ end
29
+
30
+ def center(other)
31
+ ((self.to_v + other.to_v) / 2.0).xyz
32
+ end
33
+
34
+ def equal?(other, lintol)
35
+ dist(other) < lintol
36
+ end
37
+
38
+ def translate(t)
39
+ if t.is_a? Siren::Vec
40
+ v = t
41
+ else
42
+ v = t.to_v
43
+ end
44
+ (self.to_v + v).xyz
45
+ end
46
+
47
+ def translate!(t)
48
+ self.xyz = translate(t)
49
+ end
50
+
51
+ def rotate(op, dir, angle)
52
+ self.from(op).rotate(dir, angle).xyz.translate(op).xyz
53
+ end
54
+
55
+ def rotate!(op, dir, angle)
56
+ self.xyz = rotate(op, dir, angle)
57
+ end
58
+
59
+ def scale(op, f)
60
+ if (op.equal?(self, 1.0e-7))
61
+ self.xyz
62
+ else
63
+ (self.from(op).normal * f).xyz.translate(op).xyz
64
+ end
65
+ end
66
+
67
+ def scale!(op, f)
68
+ self.xyz = scale(op, f)
69
+ end
70
+
71
+ def mirror(op, dir = Siren::Vec.zero)
72
+ if dir == Siren::Vec.zero
73
+ op.translate(self.to(op)).xyz
74
+ else
75
+ self.from(op).mirror(dir).xyz.translate(op).xyz
76
+ end
77
+ end
78
+
79
+ def mirror!(op, dir = Siren::Vec.zero)
80
+ self.xyz = mirror(op, dir)
81
+ end
82
+
83
+ def trans(t)
84
+ t.move_point self
85
+ end
86
+
87
+ def trans!(t)
88
+ r = t.move_point self
89
+ self.xyz = r.xyz
90
+ end
91
+
92
+ def x
93
+ val = (self[0] ||= 0.0)
94
+ if val.is_a?(Float)
95
+ val
96
+ elsif val.is_a?(Numeric)
97
+ val.to_f
98
+ else
99
+ 0.0
100
+ end
101
+ end
102
+
103
+ def y
104
+ val = (self[1] ||= 0.0)
105
+ if val.is_a?(Float)
106
+ val
107
+ elsif val.is_a?(Numeric)
108
+ val.to_f
109
+ else
110
+ 0.0
111
+ end
112
+ end
113
+
114
+ def z
115
+ val = (self[2] ||= 0.0)
116
+ if val.is_a?(Float)
117
+ val
118
+ elsif val.is_a?(Numeric)
119
+ val.to_f
120
+ else
121
+ 0.0
122
+ end
123
+ end
124
+
125
+ def x=(val); self[0] = val end
126
+ def y=(val); self[1] = val end
127
+ def z=(val); self[2] = val end
128
+
129
+ def self.origin
130
+ [0, 0, 0]
131
+ end
132
+ end
133
+
@@ -0,0 +1,15 @@
1
+ #
2
+ # Float クラス拡張メソッド
3
+ #
4
+ class Float
5
+
6
+ def to_deg
7
+ self * 180.0 / Math::PI
8
+ end
9
+
10
+ def to_rad
11
+ self * Math::PI / 180.0
12
+ end
13
+
14
+ end
15
+
@@ -0,0 +1,157 @@
1
+ #
2
+ # Shape クラス拡張メソッド
3
+ #
4
+ class Siren::Shape
5
+
6
+ # Explorer wrapper methods
7
+
8
+ def compounds(filter = nil)
9
+ if filter.nil?
10
+ self.explore(Siren::Compound)
11
+ else
12
+ self.explore(Siren::Compound, filter)
13
+ end
14
+ end
15
+
16
+ def solids(filter = nil)
17
+ if filter.nil?
18
+ self.explore(Siren::Solid)
19
+ else
20
+ self.explore(Siren::Solid, filter)
21
+ end
22
+ end
23
+
24
+ def shells(filter = nil)
25
+ if filter.nil?
26
+ self.explore(Siren::Shell)
27
+ else
28
+ self.explore(Siren::Shell, filter)
29
+ end
30
+ end
31
+
32
+ def faces(filter = nil)
33
+ if filter.nil?
34
+ self.explore(Siren::Face)
35
+ else
36
+ self.explore(Siren::Face, filter)
37
+ end
38
+ end
39
+
40
+ def wires(filter = nil)
41
+ if filter.nil?
42
+ self.explore(Siren::Wire)
43
+ else
44
+ self.explore(Siren::Wire, filter)
45
+ end
46
+ end
47
+
48
+ def edges(filter = nil)
49
+ if filter.nil?
50
+ self.explore(Siren::Edge)
51
+ else
52
+ self.explore(Siren::Edge, filter)
53
+ end
54
+ end
55
+
56
+ def vertices(filter = nil)
57
+ if filter.nil?
58
+ self.explore(Siren::Vertex)
59
+ else
60
+ self.explore(Siren::Vertex, filter)
61
+ end
62
+ end
63
+
64
+ # Type check methods
65
+
66
+ def compound?
67
+ self.is_a? Siren::Compound
68
+ end
69
+
70
+ def solid?
71
+ self.is_a? Siren::Solid
72
+ end
73
+
74
+ def shell?
75
+ self.is_a? Siren::Shell
76
+ end
77
+
78
+ def face?
79
+ self.is_a? Siren::Face
80
+ end
81
+
82
+ def wire?
83
+ self.is_a? Siren::Wire
84
+ end
85
+
86
+ def edge?
87
+ self.is_a? Siren::Edge
88
+ end
89
+
90
+ def vertex?
91
+ self.is_a? Siren::Vertex
92
+ end
93
+
94
+ def dump_tree(current_depth = 0, &limit)
95
+ hc = sprintf("%06X", self.hashcode(0xFFFFFF))
96
+ type = self.class.to_s
97
+ puts " " * current_depth + "%s:0x%s" % [type, hc]
98
+ if limit && limit.call(current_depth, self)
99
+ # puts " " * current_depth + "..."
100
+ return
101
+ end
102
+ current_depth += 1
103
+ self.subshapes.each do |s|
104
+ s.dump_tree(current_depth, &limit)
105
+ end
106
+ nil
107
+ end
108
+
109
+ def dump_compound
110
+ self.dump_tree{|depth, child| child.compound?}
111
+ end
112
+
113
+ def dump_solid
114
+ self.dump_tree{|depth, child| child.solid?}
115
+ end
116
+
117
+ def dump_shell
118
+ self.dump_tree{|depth, child| child.sell?}
119
+ end
120
+
121
+ def dump_face
122
+ self.dump_tree{|depth, child| child.face?}
123
+ end
124
+
125
+ def dump_wire
126
+ self.dump_tree{|depth, child| child.wire?}
127
+ end
128
+
129
+ def dump_edge
130
+ self.dump_tree{|depth, child| child.edge?}
131
+ end
132
+
133
+ def dump_vertex
134
+ self.dump_tree{|depth, child| child.vertex?}
135
+ end
136
+
137
+ def clone(copy_geom = true)
138
+ Siren.copy(self, copy_geom)
139
+ end
140
+
141
+ def to_a
142
+ if self.compound?
143
+ ar = []
144
+ self.subshapes.each do |s|
145
+ if s.compound?
146
+ ar << s.to_a
147
+ else
148
+ ar.push s
149
+ end
150
+ end
151
+ return ar
152
+ else
153
+ return [self]
154
+ end
155
+ end
156
+
157
+ end