siren2 0.1.2

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 (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