dxf-in-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'sketch-in-ruby'
6
+ gem 'units', github: 'bfoz/units-ruby'
7
+
8
+ group :test do
9
+ gem 'rake'
10
+ end
data/README.markdown ADDED
@@ -0,0 +1,33 @@
1
+ # DXF
2
+
3
+ [![Build Status](https://travis-ci.org/bfoz/dxf-ruby.png)](https://travis-ci.org/bfoz/dxf-ruby)
4
+
5
+ Tools for working with the popular DXF file format
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'DXF'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install dxf
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ require 'dxf'
25
+
26
+ # To export the my_sketch object in inches
27
+ DXF.write('filename.dxf', my_sketch, :inches)
28
+ ```
29
+
30
+ License
31
+ -------
32
+
33
+ Copyright 2012-2013 Brandon Fosdick <bfoz@bfoz.net> and released under the BSD license.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ task :default => :test
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs.push "lib"
8
+ t.test_files = FileList['test/**/*.rb']
9
+ t.verbose = true
10
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "dxf-in-ruby"
7
+ gem.version = '0.0.1'
8
+ gem.authors = ["Brandon Fosdick", "Meseker Yohannes"]
9
+ gem.email = ["meseker.yohannes@gmail.com"]
10
+ gem.description = %q{Read and write DXF files using Ruby}
11
+ gem.summary = %q{Tools for working with the popular DXF file format}
12
+ gem.homepage = "http://github.com/meseker/dxf-ruby"
13
+
14
+ gem.files = `git ls-files`.split($/)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = ["lib"]
18
+
19
+ gem.add_dependency 'geometry-in-ruby'
20
+ gem.add_dependency 'sketch-in-ruby'
21
+ gem.add_dependency 'units', '~> 2.2'
22
+ end
data/lib/dxf.rb ADDED
@@ -0,0 +1,25 @@
1
+ require_relative 'dxf/parser'
2
+ require_relative 'dxf/unparser'
3
+
4
+ module DXF
5
+ =begin
6
+ Reading and writing of files using AutoCAD's {http://en.wikipedia.org/wiki/AutoCAD_DXF Drawing Interchange File} format.
7
+
8
+ {http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=12272454&linkID=10809853 DXF Specifications}
9
+ =end
10
+
11
+ # Export a {Sketch} to a DXF file
12
+ # @param [String] filename The path to write to
13
+ # @param [Sketch] sketch The {Sketch} to export
14
+ # @param [Symbol] units Convert all values to the specified units (:inches or :mm)
15
+ def self.write(filename, sketch, units=:mm)
16
+ File.open(filename, 'w') {|f| Unparser.new(units).unparse(f, sketch)}
17
+ end
18
+
19
+ # Read a DXF file
20
+ # @param [String] filename The path to the file to read
21
+ # @return [DXF] the resulting {DXF} object
22
+ def self.read(filename)
23
+ File.open(filename, 'r') {|f| DXF::Parser.new.parse(f) }
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ # Include this module in the base class of a class cluster to handle swizzling
2
+ # of ::new
3
+ module ClusterFactory
4
+ def self.included(parent)
5
+ class << parent
6
+ alias :original_new :new
7
+
8
+ def inherited(subclass)
9
+ class << subclass
10
+ alias :new :original_new
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/dxf/entity.rb ADDED
@@ -0,0 +1,97 @@
1
+ require 'geometry'
2
+
3
+ require_relative 'cluster_factory'
4
+
5
+ module DXF
6
+ # {Entity} is the base class for everything that can live in the ENTITIES block
7
+ class Entity
8
+ TypeError = Class.new(StandardError)
9
+
10
+ include ClusterFactory
11
+
12
+ attr_accessor :handle
13
+ attr_accessor :layer
14
+
15
+ def self.new(type)
16
+ case type
17
+ when 'CIRCLE' then Circle.new
18
+ when 'LINE' then Line.new
19
+ else
20
+ raise TypeError, "Unrecognized entity type '#{type}'"
21
+ end
22
+ end
23
+
24
+ def parse_pair(code, value)
25
+ # Handle group codes that are common to all entities
26
+ # These are from the table that starts on page 70 of specification
27
+ case code
28
+ when '5'
29
+ handle = value
30
+ when '8'
31
+ layer = value
32
+ else
33
+ p "Unrecognized entity group code: #{code} #{value}"
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def point_from_values(*args)
40
+ Geometry::Point[args.flatten.reverse.drop_while {|a| not a }.reverse]
41
+ end
42
+ end
43
+
44
+ class Circle < Entity
45
+ attr_accessor :x, :y, :z
46
+ attr_accessor :radius
47
+
48
+ def parse_pair(code, value)
49
+ case code
50
+ when '10' then self.x = value.to_f
51
+ when '20' then self.y = value.to_f
52
+ when '30' then self.z = value.to_f
53
+ when '40' then self.radius = value.to_f
54
+ else
55
+ super # Handle common and unrecognized codes
56
+ end
57
+ end
58
+
59
+ # @!attribute [r] center
60
+ # @return [Point] the composed center of the {Circle}
61
+ def center
62
+ a = [x, y, z]
63
+ a.pop until a.last
64
+ Geometry::Point[*a]
65
+ end
66
+ end
67
+
68
+ class Line < Entity
69
+ attr_accessor :x1, :y1, :z1
70
+ attr_accessor :x2, :y2, :z2
71
+
72
+ def parse_pair(code, value)
73
+ case code
74
+ when '10' then self.x1 = value.to_f
75
+ when '20' then self.y1 = value.to_f
76
+ when '30' then self.z1 = value.to_f
77
+ when '11' then self.x2 = value.to_f
78
+ when '21' then self.y2 = value.to_f
79
+ when '31' then self.z2 = value.to_f
80
+ else
81
+ super # Handle common and unrecognized codes
82
+ end
83
+ end
84
+
85
+ # @!attribute [r] first
86
+ # @return [Point] the starting point of the {Line}
87
+ def first
88
+ point_from_values x1, y1, z1
89
+ end
90
+
91
+ # @!attribute [r] last
92
+ # @return [Point] the end point of the {Line}
93
+ def last
94
+ point_from_values x2, y2, z2
95
+ end
96
+ end
97
+ end
data/lib/dxf/parser.rb ADDED
@@ -0,0 +1,98 @@
1
+ require_relative 'entity'
2
+
3
+ module DXF
4
+ class Parser
5
+ ParseError = Class.new(StandardError)
6
+
7
+ # @!attribute entities
8
+ # @return [Array] the entities that comprise the drawing
9
+ attr_accessor :entities
10
+
11
+ # @!attribute header
12
+ # @return [Hash] the header variables
13
+ attr_accessor :header
14
+
15
+ def initialize(units=:mm)
16
+ @entities = []
17
+ @header = {}
18
+ end
19
+
20
+ def parse(io)
21
+ parse_pairs io do |code, value|
22
+ raise ParseError, "DXF files must begin with group code 0, not #{code}" unless '0' == code
23
+ raise ParseError, "Expecting a SECTION, not #{value}" unless 'SECTION' == value
24
+ parse_section(io)
25
+ end
26
+ self
27
+ end
28
+
29
+ private
30
+
31
+ def read_pair(io)
32
+ [io.gets.chomp, io.gets.chomp]
33
+ end
34
+
35
+ def parse_pairs(io, &block)
36
+ while not io.eof?
37
+ code, value = read_pair(io)
38
+ case [code, value]
39
+ when ['0', 'ENDSEC'] then return
40
+ when ['0', 'EOF'] then return
41
+ else
42
+ yield code, value
43
+ end
44
+ end
45
+ end
46
+
47
+ def parse_section(io)
48
+ code, value = read_pair(io)
49
+ raise ParseError, 'SECTION must be followed by a section type' unless '2' == code
50
+
51
+ case value
52
+ # when 'BLOCKS'
53
+ # when 'CLASSES'
54
+ when 'ENTITIES'
55
+ parse_entities(io)
56
+ when 'HEADER'
57
+ parse_header(io)
58
+ # when 'OBJECTS'
59
+ # when 'TABLES'
60
+ # when 'THUMBNAILIMAGE'
61
+ else
62
+ raise ParseError, "Unrecognized section type '#{value}'"
63
+ end
64
+ end
65
+
66
+ # Parse the ENTITIES section
67
+ def parse_entities(io)
68
+ parse_pairs io do |code, value|
69
+ if '0' == code
70
+ entities.push Entity.new(value)
71
+ else
72
+ entities.last.parse_pair(code, value)
73
+ end
74
+ end
75
+ end
76
+
77
+ # Parse the HEADER section
78
+ def parse_header(io)
79
+ variable_name = nil
80
+ parse_pairs io do |code, value|
81
+ case code
82
+ when '9'
83
+ variable_name = value
84
+ else
85
+ header[variable_name] = parse_header_value(code, value)
86
+ end
87
+ end
88
+ end
89
+
90
+ def parse_header_value(code, value)
91
+ case code
92
+ when '2' then value # String
93
+ else
94
+ raise ParseError, "Unrecognized header value: #{code} '#{value}'"
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,118 @@
1
+ require 'geometry'
2
+ require 'sketch'
3
+ require 'units'
4
+ require 'stringio'
5
+
6
+ module DXF
7
+ class Unparser
8
+ attr_accessor :container
9
+
10
+ # Initialize with a Sketch
11
+ # @param [String,Symbol] units The units to convert length values to (:inches or :millimeters)
12
+ def initialize(units=:mm)
13
+ @units = units
14
+ end
15
+
16
+ def to_s
17
+ io = StringIO.new
18
+ unparse(io, container)
19
+ io.string
20
+ end
21
+
22
+ # @group Element Formatters
23
+ # Convert a {Geometry::Line} into group codes
24
+ def line(first, last, layer=0, transformation=nil)
25
+ first, last = Geometry::Point[first], Geometry::Point[last]
26
+ first, last = [first, last].map {|point| transformation.transform(point) } if transformation
27
+
28
+ [ 0, 'LINE',
29
+ 8, layer,
30
+ 10, format_value(first.x),
31
+ 20, format_value(first.y),
32
+ 11, format_value(last.x),
33
+ 21, format_value(last.y)]
34
+ end
35
+ # @endgroup
36
+
37
+ def text(position, content, layer=0, transformation=nil)
38
+ position = transformation.transform(position) if transformation
39
+
40
+ [0, 'TEXT',
41
+ 8, layer,
42
+ 10, format_value(position.x),
43
+ 20, format_value(position.y),
44
+ 1, content,
45
+ 7, 'NewTextStyle_4']
46
+ end
47
+
48
+ # @group Property Converters
49
+ # Convert the given value to the correct units and return it as a formatted string
50
+ # @return [String]
51
+ def format_value(value)
52
+ if value.is_a? Units::Numeric
53
+ "%g" % value.send("to_#{@units}".to_sym)
54
+ else
55
+ "%g" % value
56
+ end
57
+ end
58
+
59
+ # Emit the group codes for the center property of an element
60
+ # @param [Point] point The center point to format
61
+ def center(point, transformation)
62
+ point = transformation.transform(point) if transformation
63
+ [10, format_value(point.x), 20, format_value(point.y)]
64
+ end
65
+
66
+ # Emit the group codes for the radius property of an element
67
+ def radius(element, transformation=nil)
68
+ [40, format_value(transformation ? transformation.transform(element.radius) : element.radius)]
69
+ end
70
+
71
+ def section_end
72
+ [0, 'ENDSEC']
73
+ end
74
+
75
+ def section_start(name)
76
+ [0, 'SECTION', 2, name]
77
+ end
78
+ # @endgroup
79
+
80
+ # Convert an element to an Array
81
+ # @param [Transformation] transformation The transformation to apply to each geometry element
82
+ # @return [Array]
83
+ def to_array(element, transformation=nil)
84
+ layer = 0;
85
+ case element
86
+ when Geometry::Arc
87
+ [ 0, 'ARC', center(element.center, transformation), radius(element),
88
+ 50, format_value(element.start_angle),
89
+ 51, format_value(element.end_angle)]
90
+ when Geometry::Circle
91
+ [0, 'CIRCLE', 8, layer, center(element.center, transformation), radius(element)]
92
+ when Geometry::Text
93
+ text(element.position, element.content, layer)
94
+ when Geometry::Edge, Geometry::Line
95
+ line(element.first, element.last, layer, transformation)
96
+ when Geometry::Polyline
97
+ element.edges.map {|edge| line(edge.first, edge.last, layer, transformation) }
98
+ when Geometry::Rectangle
99
+ element.edges.map {|edge| line(edge.first, edge.last, layer, transformation) }
100
+ when Geometry::Square
101
+ points = element.points
102
+ points.each_cons(2).map {|p1,p2| line(p1,p2, layer, transformation) } + line(points.last, points.first, layer, transformation)
103
+ when Sketch
104
+ transformation = transformation ? (transformation + element.transformation) : element.transformation
105
+ element.geometry.map {|e| to_array(e, transformation)}
106
+ end
107
+ end
108
+
109
+ # Convert a {Sketch} to a DXF file and write it to the given output
110
+ # @param [IO] output A writable IO-like object
111
+ # @param [Sketch] sketch The {Sketch} to unparse
112
+ def unparse(output, sketch)
113
+ output << (section_start('HEADER') + section_end +
114
+ section_start('ENTITIES') + to_array(sketch) + section_end +
115
+ [0, 'EOF']).join("\n")
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,35 @@
1
+ require 'minitest/autorun'
2
+ require 'dxf/parser'
3
+
4
+ describe DXF::Parser do
5
+ it 'must read from an IO stream' do
6
+ File.open('test/fixtures/circle.dxf', 'r') {|f| DXF::Parser.new.parse(f) }
7
+ end
8
+
9
+ it 'must parse a file with a circle' do
10
+ parser = File.open('test/fixtures/circle.dxf', 'r') {|f| DXF::Parser.new.parse(f) }
11
+ parser.entities.length.must_equal 1
12
+ circle = parser.entities.last
13
+ circle.must_be_instance_of(DXF::Circle)
14
+ circle.center.must_equal Geometry::Point[0,0]
15
+ circle.radius.must_equal 1
16
+ end
17
+
18
+ it 'must parse a file with a translated circle' do
19
+ parser = File.open('test/fixtures/circle_translate.dxf', 'r') {|f| DXF::Parser.new.parse(f) }
20
+ parser.entities.length.must_equal 1
21
+ circle = parser.entities.last
22
+ circle.must_be_instance_of(DXF::Circle)
23
+ circle.center.must_equal Geometry::Point[1,1]
24
+ circle.radius.must_equal 1
25
+ end
26
+
27
+ it 'must parse a file with a square' do
28
+ parser = File.open('test/fixtures/square_inches.dxf', 'r') {|f| DXF::Parser.new.parse(f) }
29
+ parser.entities.length.must_equal 4
30
+ line = parser.entities.last
31
+ line.must_be_instance_of(DXF::Line)
32
+ line.first.must_equal Geometry::Point[0, 1]
33
+ line.last.must_equal Geometry::Point[0, 0]
34
+ end
35
+ end
@@ -0,0 +1,213 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../../lib/dxf'
3
+
4
+ describe DXF::Unparser do
5
+ subject { DXF::Unparser.new }
6
+ let(:builder) { DXF::Unparser.new }
7
+ let(:eof) { ['0', 'EOF'] }
8
+ let(:empty_header) {['0', 'SECTION',
9
+ '2', 'HEADER',
10
+ '0', 'ENDSEC']}
11
+ let(:end_section) { ['0', 'ENDSEC'] }
12
+ let(:entities_header) { ['0', 'SECTION',
13
+ '2', 'ENTITIES'] }
14
+
15
+ describe "when give an empty Sketch object" do
16
+ it "must export a minimal file" do
17
+ builder.container = Sketch.new
18
+ builder.to_s.must_equal (empty_header + entities_header + end_section + eof).join("\n")
19
+ end
20
+ end
21
+
22
+ describe "when exporting a Sketch" do
23
+ let(:sketch) { Sketch.new }
24
+ let(:square_lines) {
25
+ ['0', 'LINE',
26
+ '8', '0',
27
+ '10', '0',
28
+ '20', '0',
29
+ '11', '1',
30
+ '21', '0',
31
+ '0', 'LINE',
32
+ '8', '0',
33
+ '10', '1',
34
+ '20', '0',
35
+ '11', '1',
36
+ '21', '1',
37
+ '0', 'LINE',
38
+ '8', '0',
39
+ '10', '1',
40
+ '20', '1',
41
+ '11', '0',
42
+ '21', '1',
43
+ '0', 'LINE',
44
+ '8', '0',
45
+ '10', '0',
46
+ '20', '1',
47
+ '11', '0',
48
+ '21', '0']
49
+ }
50
+
51
+ before do
52
+ subject.container = sketch
53
+ builder.container = sketch
54
+ end
55
+
56
+ it "with a single Arc" do
57
+ sketch.push Geometry::Arc.new center:[0,0], radius:1, start:0, end:45
58
+ builder.to_s.must_equal (empty_header + entities_header + ['0', 'ARC',
59
+ '10', '0',
60
+ '20', '0',
61
+ '40', '1',
62
+ '50', '0',
63
+ '51', '45'] + end_section + eof).join("\n")
64
+ end
65
+
66
+ it "with a single Circle" do
67
+ sketch.push Geometry::Circle.new [0,0], 1
68
+ builder.to_s.must_equal File.read('test/fixtures/circle.dxf')
69
+ end
70
+
71
+ it "with a single Line" do
72
+ sketch.push Geometry::Line[[0,0], [1,1]]
73
+ builder.to_s.must_equal (empty_header + entities_header +
74
+ ['0', 'LINE',
75
+ '8', '0',
76
+ '10', '0',
77
+ '20', '0',
78
+ '11', '1',
79
+ '21', '1'] +
80
+ end_section + eof).join("\n")
81
+ end
82
+
83
+ it "with a single Polygon" do
84
+ sketch.push Geometry::Polygon.new [0,0], [1,0], [1,1], [0,1]
85
+ builder.to_s.must_equal (empty_header + entities_header +
86
+ square_lines +
87
+ end_section + eof).join("\n")
88
+ end
89
+
90
+ it "with a single Polyline" do
91
+ sketch.push Geometry::Polyline.new [0,0], [1,0], [1,1], [0,1]
92
+ builder.to_s.must_equal (empty_header + entities_header +
93
+ square_lines[0, 36] +
94
+ end_section + eof).join("\n")
95
+ end
96
+
97
+ it "with a single Rectangle" do
98
+ sketch.push Geometry::Rectangle.new [0,0], [1,1]
99
+ builder.to_s.must_equal (empty_header + entities_header + square_lines +
100
+ end_section + eof).join "\n"
101
+ end
102
+
103
+ it "with a single Square" do
104
+ sketch.push Geometry::Rectangle.new [0,0], [1,1]
105
+ builder.to_s.must_equal (empty_header + entities_header + square_lines +
106
+ end_section + eof).join "\n"
107
+ end
108
+
109
+ it "with a group" do
110
+ Sketch::Builder.new(sketch).evaluate do
111
+ group origin:[1,1] do
112
+ circle center:[0,0], radius:1
113
+ end
114
+ end
115
+ subject.to_s.must_equal File.read('test/fixtures/circle_translate.dxf')
116
+ end
117
+
118
+ describe "when the sketch has a transformation" do
119
+ before do
120
+ sketch.transformation = Geometry::Transformation.new(origin:[2,2])
121
+ end
122
+
123
+ it "and a group" do
124
+ Sketch::Builder.new(sketch).evaluate do
125
+ group origin:[-1,-1] do
126
+ circle center:[0,0], radius:1
127
+ end
128
+ end
129
+ subject.to_s.must_equal File.read('test/fixtures/circle_translate.dxf')
130
+ end
131
+ end
132
+
133
+ describe "with a Sketch" do
134
+ let(:circle_sketch) { Sketch.new { push Geometry::Circle.new(center:[0,0], radius:1) } }
135
+
136
+ describe "without a transformation" do
137
+ it "must unparse correctly" do
138
+ sketch.push circle_sketch
139
+ builder.to_s.must_equal File.read('test/fixtures/circle.dxf')
140
+ end
141
+ end
142
+
143
+ describe "with a transformation" do
144
+ it "must unparse correctly" do
145
+ sketch.push circle_sketch, origin:[1,1]
146
+ builder.to_s.must_equal File.read('test/fixtures/circle_translate.dxf')
147
+ end
148
+ end
149
+ end
150
+
151
+ describe "when the sketch has units" do
152
+ let(:sketch) { Sketch.new }
153
+
154
+ describe "when exporting to inches" do
155
+ subject { DXF::Unparser.new :inches }
156
+ let(:square_inches) { File.read('test/fixtures/square_inches.dxf') }
157
+
158
+ before do
159
+ subject.container = sketch
160
+ end
161
+
162
+ describe "when the units are all inches" do
163
+ before do
164
+ sketch.push Geometry::Polygon.new [0.inches, 0.inches], [1.inches, 0.inches], [1.inches, 1.inches], [0.inches, 1.inches]
165
+ end
166
+
167
+ it "must not convert the values" do
168
+ subject.to_s.must_equal square_inches
169
+ end
170
+ end
171
+
172
+ describe "when the units are all metric" do
173
+ before do
174
+ sketch.push Geometry::Polygon.new [0.mm, 0.mm], [25.4.mm, 0.mm], [25.4.mm, 25.4.mm], [0.mm, 25.4.mm]
175
+ end
176
+
177
+ it "must convert the values" do
178
+ subject.to_s.must_equal square_inches
179
+ end
180
+ end
181
+ end
182
+
183
+ describe "when exporting to millimeters" do
184
+ subject { DXF::Unparser.new :mm }
185
+ let(:square_millimeters) { File.read('test/fixtures/square_millimeters.dxf') }
186
+
187
+ before do
188
+ subject.container = sketch
189
+ end
190
+
191
+ describe "when the units are all inches" do
192
+ before do
193
+ sketch.push Geometry::Polygon.new [0.inches, 0.inches], [1.inches, 0.inches], [1.inches, 1.inches], [0.inches, 1.inches]
194
+ end
195
+
196
+ it "must convert the values" do
197
+ subject.to_s.must_equal square_millimeters
198
+ end
199
+ end
200
+
201
+ describe "when the units are all metric" do
202
+ before do
203
+ sketch.push Geometry::Polygon.new [0.mm, 0.mm], [25.4.mm, 0.mm], [25.4.mm, 25.4.mm], [0.mm, 25.4.mm]
204
+ end
205
+
206
+ it "must not convert the values" do
207
+ subject.to_s.must_equal square_millimeters
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,24 @@
1
+ 0
2
+ SECTION
3
+ 2
4
+ HEADER
5
+ 0
6
+ ENDSEC
7
+ 0
8
+ SECTION
9
+ 2
10
+ ENTITIES
11
+ 0
12
+ CIRCLE
13
+ 8
14
+ 0
15
+ 10
16
+ 0
17
+ 20
18
+ 0
19
+ 40
20
+ 1
21
+ 0
22
+ ENDSEC
23
+ 0
24
+ EOF
@@ -0,0 +1,24 @@
1
+ 0
2
+ SECTION
3
+ 2
4
+ HEADER
5
+ 0
6
+ ENDSEC
7
+ 0
8
+ SECTION
9
+ 2
10
+ ENTITIES
11
+ 0
12
+ CIRCLE
13
+ 8
14
+ 0
15
+ 10
16
+ 1
17
+ 20
18
+ 1
19
+ 40
20
+ 1
21
+ 0
22
+ ENDSEC
23
+ 0
24
+ EOF
@@ -0,0 +1,62 @@
1
+ 0
2
+ SECTION
3
+ 2
4
+ HEADER
5
+ 0
6
+ ENDSEC
7
+ 0
8
+ SECTION
9
+ 2
10
+ ENTITIES
11
+ 0
12
+ LINE
13
+ 8
14
+ 0
15
+ 10
16
+ 0
17
+ 20
18
+ 0
19
+ 11
20
+ 1
21
+ 21
22
+ 0
23
+ 0
24
+ LINE
25
+ 8
26
+ 0
27
+ 10
28
+ 1
29
+ 20
30
+ 0
31
+ 11
32
+ 1
33
+ 21
34
+ 1
35
+ 0
36
+ LINE
37
+ 8
38
+ 0
39
+ 10
40
+ 1
41
+ 20
42
+ 1
43
+ 11
44
+ 0
45
+ 21
46
+ 1
47
+ 0
48
+ LINE
49
+ 8
50
+ 0
51
+ 10
52
+ 0
53
+ 20
54
+ 1
55
+ 11
56
+ 0
57
+ 21
58
+ 0
59
+ 0
60
+ ENDSEC
61
+ 0
62
+ EOF
@@ -0,0 +1,62 @@
1
+ 0
2
+ SECTION
3
+ 2
4
+ HEADER
5
+ 0
6
+ ENDSEC
7
+ 0
8
+ SECTION
9
+ 2
10
+ ENTITIES
11
+ 0
12
+ LINE
13
+ 8
14
+ 0
15
+ 10
16
+ 0
17
+ 20
18
+ 0
19
+ 11
20
+ 25.4
21
+ 21
22
+ 0
23
+ 0
24
+ LINE
25
+ 8
26
+ 0
27
+ 10
28
+ 25.4
29
+ 20
30
+ 0
31
+ 11
32
+ 25.4
33
+ 21
34
+ 25.4
35
+ 0
36
+ LINE
37
+ 8
38
+ 0
39
+ 10
40
+ 25.4
41
+ 20
42
+ 25.4
43
+ 11
44
+ 0
45
+ 21
46
+ 25.4
47
+ 0
48
+ LINE
49
+ 8
50
+ 0
51
+ 10
52
+ 0
53
+ 20
54
+ 25.4
55
+ 11
56
+ 0
57
+ 21
58
+ 0
59
+ 0
60
+ ENDSEC
61
+ 0
62
+ EOF
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dxf-in-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brandon Fosdick
9
+ - Meseker Yohannes
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2014-03-13 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: geometry-in-ruby
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: sketch-in-ruby
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: units
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.2'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: '2.2'
63
+ description: Read and write DXF files using Ruby
64
+ email:
65
+ - meseker.yohannes@gmail.com
66
+ executables: []
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - Gemfile
72
+ - README.markdown
73
+ - Rakefile
74
+ - dxf-in-ruby.gemspec
75
+ - lib/dxf.rb
76
+ - lib/dxf/cluster_factory.rb
77
+ - lib/dxf/entity.rb
78
+ - lib/dxf/parser.rb
79
+ - lib/dxf/unparser.rb
80
+ - test/dxf/parser.rb
81
+ - test/dxf/unparser.rb
82
+ - test/fixtures/circle.dxf
83
+ - test/fixtures/circle_translate.dxf
84
+ - test/fixtures/square_inches.dxf
85
+ - test/fixtures/square_millimeters.dxf
86
+ homepage: http://github.com/meseker/dxf-ruby
87
+ licenses: []
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 1.8.23
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: Tools for working with the popular DXF file format
110
+ test_files:
111
+ - test/dxf/parser.rb
112
+ - test/dxf/unparser.rb
113
+ - test/fixtures/circle.dxf
114
+ - test/fixtures/circle_translate.dxf
115
+ - test/fixtures/square_inches.dxf
116
+ - test/fixtures/square_millimeters.dxf