Skip to content

Commit 907c63e

Browse files
author
aza
committed
adding volume calculation
1 parent 226089d commit 907c63e

4 files changed

Lines changed: 122 additions & 1 deletion

File tree

lib/stl.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,13 @@ def translate(offset)
132132
def write(filename, format=:binary)
133133
self.class.write(filename, faces, format)
134134
end
135-
end
135+
136+
# @return [Float] the volume in cube stl units (usually milimeters)
137+
def volume
138+
vol = 0
139+
faces.each do |face|
140+
vol = vol + face.signed_volume
141+
end
142+
vol.abs
143+
end
144+
end

lib/stl/face.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,18 @@ def initialize(normal, *vertices)
1515
@normal = normal
1616
@points = vertices
1717
end
18+
19+
# @return [Float] The signed volume
20+
def signed_volume
21+
# math voodoo acording to:
22+
# http://stackoverflow.com/questions/1406029/how-to-calculate-the-volume-of-a-3d-mesh-object-the-surface-of-which-is-made-up
23+
v321 = @points[2][0] * @points[1][1] * @points[0][2]
24+
v231 = @points[1][0] * @points[2][1] * @points[0][2]
25+
v312 = @points[2][0] * @points[0][1] * @points[1][2]
26+
v132 = @points[0][0] * @points[2][1] * @points[1][2]
27+
v213 = @points[1][0] * @points[0][1] * @points[2][2]
28+
v123 = @points[0][0] * @points[1][1] * @points[2][2]
29+
(1.0/6.0)*(-v321 + v231 + v312 - v132 - v213 + v123)
30+
end
1831
end
1932
end

test/fixtures/box.stl

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
solid OpenSCAD_Model
2+
facet normal -1 0 0
3+
outer loop
4+
vertex -15 -10 10
5+
vertex -15 10 10
6+
vertex -15 -10 -10
7+
endloop
8+
endfacet
9+
facet normal -1 0 0
10+
outer loop
11+
vertex -15 -10 -10
12+
vertex -15 10 10
13+
vertex -15 10 -10
14+
endloop
15+
endfacet
16+
facet normal 0 0 1
17+
outer loop
18+
vertex -15 -10 10
19+
vertex 15 -10 10
20+
vertex 15 10 10
21+
endloop
22+
endfacet
23+
facet normal 0 0 1
24+
outer loop
25+
vertex -15 10 10
26+
vertex -15 -10 10
27+
vertex 15 10 10
28+
endloop
29+
endfacet
30+
facet normal 0 -1 0
31+
outer loop
32+
vertex -15 -10 -10
33+
vertex 15 -10 -10
34+
vertex 15 -10 10
35+
endloop
36+
endfacet
37+
facet normal 0 -1 0
38+
outer loop
39+
vertex -15 -10 10
40+
vertex -15 -10 -10
41+
vertex 15 -10 10
42+
endloop
43+
endfacet
44+
facet normal 0 0 -1
45+
outer loop
46+
vertex -15 10 -10
47+
vertex 15 10 -10
48+
vertex -15 -10 -10
49+
endloop
50+
endfacet
51+
facet normal 0 0 -1
52+
outer loop
53+
vertex -15 -10 -10
54+
vertex 15 10 -10
55+
vertex 15 -10 -10
56+
endloop
57+
endfacet
58+
facet normal 0 1 0
59+
outer loop
60+
vertex -15 10 10
61+
vertex 15 10 10
62+
vertex -15 10 -10
63+
endloop
64+
endfacet
65+
facet normal 0 1 0
66+
outer loop
67+
vertex -15 10 -10
68+
vertex 15 10 10
69+
vertex 15 10 -10
70+
endloop
71+
endfacet
72+
facet normal 1 0 0
73+
outer loop
74+
vertex 15 -10 -10
75+
vertex 15 10 -10
76+
vertex 15 10 10
77+
endloop
78+
endfacet
79+
facet normal 1 0 0
80+
outer loop
81+
vertex 15 -10 10
82+
vertex 15 -10 -10
83+
vertex 15 10 10
84+
endloop
85+
endfacet
86+
endsolid OpenSCAD_Model

test/stl.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,19 @@
6666
end
6767
end
6868

69+
describe 'when reading a box' do
70+
subject { STL.read('test/fixtures/box.stl') }
71+
72+
it 'face must have a signed volume' do
73+
subject.faces.first.signed_volume.must_equal 1000.0
74+
end
75+
76+
it 'must have a volume' do
77+
subject.volume.must_equal 12000.0
78+
subject.scale(2).volume.must_equal 96000.0
79+
end
80+
end
81+
6982
describe 'when reading from a binary file' do
7083
subject { STL.read('test/fixtures/binary_triangle.stl') }
7184

0 commit comments

Comments
 (0)