aurora-dxf 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +10 -0
- data/README.markdown +33 -0
- data/Rakefile +10 -0
- data/aurora-dxf.gemspec +22 -0
- data/lib/dxf.rb +25 -0
- data/lib/dxf/cluster_factory.rb +15 -0
- data/lib/dxf/entity.rb +97 -0
- data/lib/dxf/parser.rb +98 -0
- data/lib/dxf/unparser.rb +105 -0
- data/test/dxf/parser.rb +35 -0
- data/test/dxf/unparser.rb +213 -0
- data/test/fixtures/circle.dxf +24 -0
- data/test/fixtures/circle_translate.dxf +24 -0
- data/test/fixtures/square_inches.dxf +62 -0
- data/test/fixtures/square_millimeters.dxf +62 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a03bc384bb55b21b7c1bd910b73985797191fa05
|
4
|
+
data.tar.gz: bcebe25e0f79bd3cafc2fd0eed0486d4dc77c113
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d08d53dc672d2e65f8e1e767cb60dc880255548065255b2e1de0ce2e8ffa1c3a2c8b8e58be855df7ab8a393ae5ab232920d4dd937ccec4cb72fcf0d81018816e
|
7
|
+
data.tar.gz: b3ff2a61715effb1505ca73ce49c39782a54139167e85752f585ca30e0b51d8772b868fc52e736973a1601885f0f772e23bac532f79052cf6cffdc7a2d9f18d3
|
data/.gitignore
ADDED
data/Gemfile
ADDED
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
data/aurora-dxf.gemspec
ADDED
@@ -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 = "aurora-dxf"
|
7
|
+
gem.version = '0.0.3'
|
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 'aurora-geometry'
|
20
|
+
gem.add_dependency 'aurora-sketch'
|
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
|
data/lib/dxf/unparser.rb
ADDED
@@ -0,0 +1,105 @@
|
|
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
|
+
# @group Property Converters
|
38
|
+
# Convert the given value to the correct units and return it as a formatted string
|
39
|
+
# @return [String]
|
40
|
+
def format_value(value)
|
41
|
+
if value.is_a? Units::Numeric
|
42
|
+
"%g" % value.send("to_#{@units}".to_sym)
|
43
|
+
else
|
44
|
+
"%g" % value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Emit the group codes for the center property of an element
|
49
|
+
# @param [Point] point The center point to format
|
50
|
+
def center(point, transformation)
|
51
|
+
point = transformation.transform(point) if transformation
|
52
|
+
[10, format_value(point.x), 20, format_value(point.y)]
|
53
|
+
end
|
54
|
+
|
55
|
+
# Emit the group codes for the radius property of an element
|
56
|
+
def radius(element, transformation=nil)
|
57
|
+
[40, format_value(transformation ? transformation.transform(element.radius) : element.radius)]
|
58
|
+
end
|
59
|
+
|
60
|
+
def section_end
|
61
|
+
[0, 'ENDSEC']
|
62
|
+
end
|
63
|
+
|
64
|
+
def section_start(name)
|
65
|
+
[0, 'SECTION', 2, name]
|
66
|
+
end
|
67
|
+
# @endgroup
|
68
|
+
|
69
|
+
# Convert an element to an Array
|
70
|
+
# @param [Transformation] transformation The transformation to apply to each geometry element
|
71
|
+
# @return [Array]
|
72
|
+
def to_array(element, transformation=nil)
|
73
|
+
layer = 0;
|
74
|
+
case element
|
75
|
+
when Geometry::Arc
|
76
|
+
[ 0, 'ARC', center(element.center, transformation), radius(element),
|
77
|
+
50, format_value(element.start_angle),
|
78
|
+
51, format_value(element.end_angle)]
|
79
|
+
when Geometry::Circle
|
80
|
+
[0, 'CIRCLE', 8, layer, center(element.center, transformation), radius(element)]
|
81
|
+
when Geometry::Edge, Geometry::Line
|
82
|
+
line(element.first, element.last, layer, transformation)
|
83
|
+
when Geometry::Polyline
|
84
|
+
element.edges.map {|edge| line(edge.first, edge.last, layer, transformation) }
|
85
|
+
when Geometry::Rectangle
|
86
|
+
element.edges.map {|edge| line(edge.first, edge.last, layer, transformation) }
|
87
|
+
when Geometry::Square
|
88
|
+
points = element.points
|
89
|
+
points.each_cons(2).map {|p1,p2| line(p1,p2, layer, transformation) } + line(points.last, points.first, layer, transformation)
|
90
|
+
when Sketch
|
91
|
+
transformation = transformation ? (transformation + element.transformation) : element.transformation
|
92
|
+
element.geometry.map {|e| to_array(e, transformation)}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Convert a {Sketch} to a DXF file and write it to the given output
|
97
|
+
# @param [IO] output A writable IO-like object
|
98
|
+
# @param [Sketch] sketch The {Sketch} to unparse
|
99
|
+
def unparse(output, sketch)
|
100
|
+
output << (section_start('HEADER') + section_end +
|
101
|
+
section_start('ENTITIES') + to_array(sketch) + section_end +
|
102
|
+
[0, 'EOF']).join("\n")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/test/dxf/parser.rb
ADDED
@@ -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 '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,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,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aurora-dxf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brandon Fosdick
|
8
|
+
- Meseker Yohannes
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-03-10 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: aurora-geometry
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - '>='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: aurora-sketch
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: units
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '2.2'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '2.2'
|
56
|
+
description: Read and write DXF files using Ruby
|
57
|
+
email:
|
58
|
+
- meseker.yohannes@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- Gemfile
|
65
|
+
- README.markdown
|
66
|
+
- Rakefile
|
67
|
+
- aurora-dxf.gemspec
|
68
|
+
- lib/dxf.rb
|
69
|
+
- lib/dxf/cluster_factory.rb
|
70
|
+
- lib/dxf/entity.rb
|
71
|
+
- lib/dxf/parser.rb
|
72
|
+
- lib/dxf/unparser.rb
|
73
|
+
- test/dxf/parser.rb
|
74
|
+
- test/dxf/unparser.rb
|
75
|
+
- test/fixtures/circle.dxf
|
76
|
+
- test/fixtures/circle_translate.dxf
|
77
|
+
- test/fixtures/square_inches.dxf
|
78
|
+
- test/fixtures/square_millimeters.dxf
|
79
|
+
homepage: http://github.com/meseker/dxf-ruby
|
80
|
+
licenses: []
|
81
|
+
metadata: {}
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 2.0.3
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
101
|
+
summary: Tools for working with the popular DXF file format
|
102
|
+
test_files:
|
103
|
+
- test/dxf/parser.rb
|
104
|
+
- test/dxf/unparser.rb
|
105
|
+
- test/fixtures/circle.dxf
|
106
|
+
- test/fixtures/circle_translate.dxf
|
107
|
+
- test/fixtures/square_inches.dxf
|
108
|
+
- test/fixtures/square_millimeters.dxf
|