Class: STL::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/stl/parser.rb

Overview

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.parse(io) ⇒ Array

Returns An array of [Normal, Triangle] pairs.

Parameters:

  • io (IO)

    the stream to parse

Returns:

  • (Array)

    An array of [Normal, Triangle] pairs



8
9
10
11
12
13
14
15
16
17
18
# File 'lib/stl/parser.rb', line 8

def self.parse(io)
    # A binary STL file has an 80 byte header that should never contain
    #  the word 'solid'. The first non-whitespace characters of an ASCII
    #  STL file should contain 'solid'.
    if io.gets(80).include?('solid')
	io.rewind
	self.new.parse_ascii(io)
    else
	self.new.parse_binary(io)
    end
end

Instance Method Details

#parse_ascii(io) ⇒ Array

Parse an ASCII STL file

Parameters:

  • io (IO)

    the stream to parse

Returns:

  • (Array)

    An array of [Normal, Triangle] pairs



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/stl/parser.rb', line 23

def parse_ascii(io)
    stack = []
    triangles = []
    io.each do |line|
	case line
	    when /solid (.*)/
		name = $1
	    when /facet normal\s+(\S+)\s+(\S+)\s+(\S+)/
		stack.push Vector[Float($1), Float($2), Float($3)]
	    when /vertex\s+(\S+)\s+(\S+)\s+(\S+)/
		stack.push Vector[Float($1), Float($2), Float($3)]
	    when /endloop/
		normal, *vertices = stack.pop(4)
		triangles.push [normal, Geometry::Triangle.new(*vertices)]
	end
    end
    triangles
end

#parse_binary(io) ⇒ Array

Parse a binary STL file, assuming that the header has already been read

Parameters:

  • io (IO)

    the stream to parse

Returns:

  • (Array)

    An array of [Normal, Triangle] pairs

Raises:

  • (StandardError)


45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/stl/parser.rb', line 45

def parse_binary(io)
    count = io.read(4).unpack('V').first

    faces = []
    while not io.eof?
	normal, *vertices = io.read(50).unpack('F3F3F3F3x2').each_slice(3).to_a
	faces.push [Vector[*normal], Geometry::Triangle.new(*vertices)]
    end
    raise StandardError, "Unexpected end of file after #{faces.length} triangles" if faces.length != count

    faces
end