dxf_io 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: acd6e7e421e794fc455849a0bef5891546f156f0
4
+ data.tar.gz: 05ed5c94483547c11977cb46fe5aef576500326f
5
+ SHA512:
6
+ metadata.gz: d4ab61f9f327ca682d0f5960b9e17150f9444176bd5e09182877f75acbf0fcc1f14d667f986dfd12a9885654b3dd93bcc72465d6cb673f43d0b7304c05b103cb
7
+ data.tar.gz: af51a521f4325f2901fda5916c405801cf655ceb02f56e4f88bec4d4ae0de6aeb79fc3f6b5df04d6d847a7563a49b28be6505b73dd50cfe9b300c14308b94052
@@ -0,0 +1,11 @@
1
+ *.gem
2
+ /.bundle/
3
+ /.yardoc
4
+ /.idea/*
5
+ /Gemfile.lock
6
+ /_yardoc/
7
+ /coverage/
8
+ /doc/
9
+ /pkg/
10
+ /spec/reports/
11
+ /tmp/
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in dxf_io.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Ivan Zabrovskiy
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,224 @@
1
+ # DxfIO
2
+
3
+ This is a gem for read and write DXF files and for processing of simple actions over dxf entities.
4
+ Reader part of the gem based on [ruby-dxf-reader](https://github.com/jimfoltz/ruby-dxf-reader).
5
+ Gem supported DXF files generated by AutoCAD 2008 ([dxf-specification](http://images.autodesk.com/adsk/files/acad_dxf0.pdf)).
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'dxf_io'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install dxf_io
22
+
23
+ ## Usage
24
+
25
+ Gem consists from __Reader__, __Writer__, __Wrapper__ and support classes.
26
+
27
+ ### Reader
28
+
29
+ Reader require a path to DXF file and return a hash with dxf-objects.
30
+
31
+ Reader can be initialized as follows:
32
+
33
+ ```ruby
34
+ reader_instance = DxfIO::Reader.new(path: '/path/to/your/file.dxf')
35
+ ```
36
+
37
+ Additionally you can use `open` method:
38
+
39
+ ```ruby
40
+ DxfIO::Reader.open('/path/to/your/file.dxf') do |dxf_reader_instance|
41
+ # ...
42
+ end
43
+ ```
44
+
45
+ `open` receive same options as `new`.
46
+
47
+ Available options of __Reader__:
48
+
49
+ * path - path to DXF-file (required)
50
+ * encoding - encoding of input file (`'Windows-1251'` by default)
51
+
52
+ As alternative you may pass single string as input parameter:
53
+
54
+ ```ruby
55
+ reader_instance = DxfIO::Reader.new('/path/to/your/file.dxf')
56
+ ```
57
+
58
+ To obtain full hash with DXF content eval
59
+
60
+ ```ruby
61
+ dxf_content = reader_instance.run
62
+ ```
63
+
64
+ or
65
+
66
+ ```ruby
67
+ dxf_content = reader_instance.to_h
68
+ ```
69
+
70
+ Format of resulted hash:
71
+
72
+ {
73
+ "HEADER" => {...},
74
+ "CLASSES" => [...],
75
+ "TABLES" => [...],
76
+ "BLOCKS" => [...],
77
+ "ENTITIES" => [...],
78
+ "OBJECTS" => [...],
79
+ "THUMBNAILIMAGES" => [...]
80
+ }
81
+
82
+ If you need certain part of DXF you may execute one of the following functions
83
+
84
+ * header
85
+ * classes
86
+ * tables
87
+ * blocks
88
+ * entities
89
+ * objects
90
+ * thumbnailimages
91
+
92
+ Format of __header__ section is
93
+
94
+ {
95
+ $PLIMCHECK" => {
96
+ 70 => 0
97
+ },
98
+ "$PEXTMIN" => {
99
+ 10 => 1.0e+20,
100
+ 20 => 1.0e+20,
101
+ 30 => 1.0e+20
102
+ },
103
+ ...
104
+ }
105
+
106
+ Other section has different format:
107
+
108
+ [
109
+ [
110
+ { 0 => "CLASS" },
111
+ { 1 => "VISUALSTYLE" },
112
+ { 2 => "AcDbVisualStyle" },
113
+ { 3 => "ObjectDBX Classes" },
114
+ { 90 => 4095 },
115
+ { 280 => 0 },
116
+ { 281 => 0 }
117
+ ],
118
+ [...]
119
+ ]
120
+
121
+ Sequence of groups and values is same as in DXF file.
122
+
123
+ #### Notes
124
+
125
+ * Reader caches result of parse DXF file. If you want to update a cache call `reader_instance.rerun`.
126
+ * Reader automatically cast integer and float values to proper Ruby classes.
127
+
128
+ ### Writer
129
+
130
+ __Writer__ receive a dxf-hash in format from __Reader__ and construct a DXF-file.
131
+
132
+ __Writer__ can be initialized as follow
133
+
134
+ ```ruby
135
+ writer_instance = DxfIO::Writer.new(dxf_hash: dxf_content, path: '/path/to/new/file.dxf')
136
+ ```
137
+
138
+ To process write execute `writer_instance.run`.
139
+
140
+ Alternative way to use __Writer__:
141
+
142
+ ```ruby
143
+ writer_instance = DxfIO::Writer.open('/path/to/new/file.dxf') do |dxf_writer_instance|
144
+ # ...
145
+ dxf_writer_instance.write_hash dxf_hash
146
+ end
147
+ ```
148
+
149
+ `open` receive same options as `new`.
150
+
151
+ Available options of __Writer__:
152
+
153
+ * dxf_hash - hash with DXF-file in format of __Reader__ (required in `new` or in `run`/`write_hash` methods)
154
+ * path - path to new DXF-file (required)
155
+ * encoding - encoding of output file (`'Windows-1251'` by default)
156
+ * delimiter - delimiter in DXF-file (`"\r\n"` by default)
157
+ * strategy - strategy of _Writer_ (`:memory` by default)
158
+
159
+ #### Write strategy
160
+
161
+ __Writter__ support two strategy:
162
+
163
+ 1. `:disk` - a lot of small write operation for each group, section etc
164
+ 2. `:memory` - prepare full file content in memory and write by a single operation (default behaviour)
165
+
166
+ ### Wrapper
167
+
168
+ __Wrapper__ provide several tools for work with dxf-entities.
169
+
170
+ __Wrapper__ can be initialized as follow
171
+
172
+ ```ruby
173
+ wrapper_instance = DxfIO::Wrapper.new(dxf_hash: dxf_content)
174
+ ```
175
+
176
+ It has functions for fetch any groups except header:
177
+
178
+ * classes
179
+ * tables
180
+ * blocks
181
+ * entities
182
+ * objects
183
+ * thumbnailimages
184
+
185
+ Any of these functions return array with __Entity__ which is `DxfIO::Entity::Other`.
186
+
187
+ Each __Entity__ has follows methods
188
+
189
+ * to_a - same as in __Reader__ format
190
+ * to_h - hash with group code on keys and array with group values on values
191
+ * type - value of zero group (for example "LINE")
192
+ * points - array of __Points__ which is `DxfIO::Entity::Support::Point`
193
+ * xs - array of X-coordinates
194
+ * ys - array of Y-coordinates
195
+ * move_to! - receive __Point__ and move all points of current __Entity__
196
+
197
+ ### Support
198
+
199
+ #### Point
200
+
201
+ This is a simple class for storage 2D points. It provide follows methods:
202
+
203
+ * x - access to X-coordinate
204
+ * y - access to Y-coordinate
205
+ * start? - is this start-point of primitive (codes 10 and 20 from [dxf-specification](http://images.autodesk.com/adsk/files/acad_dxf0.pdf))
206
+ * end? - is this end-point of primitive (codes 11 and 21 from [dxf-specification](http://images.autodesk.com/adsk/files/acad_dxf0.pdf))
207
+ * `==`
208
+ * binary `+`, `-`, `*`, `/`
209
+ * unary `-`
210
+ * `rotate_90`, `rotate_180` (supposed what point is a vector from zero)
211
+
212
+ ## Development
213
+
214
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
215
+
216
+ To install this gem onto your local machine, run `bundle exec rake install`.
217
+
218
+ ## Contributing
219
+
220
+ 1. Fork it ( https://github.com/Loriowar/dxf_io/fork )
221
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
222
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
223
+ 4. Push to the branch (`git push origin my-new-feature`)
224
+ 5. Create a new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "dxf_io"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dxf_io/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'dxf_io'
8
+ spec.version = DxfIO::VERSION
9
+ spec.authors = ['Ivan Zabrovskiy']
10
+ spec.email = ['loriowar@gmail.com']
11
+
12
+ spec.summary = %q{Gem for read and write DXF files}
13
+ spec.description = <<-STRING
14
+ Gem for read and write DXF files.
15
+ Gem based on "ruby-dxf-reader" from https://github.com/jimfoltz/ruby-dxf-reader.
16
+ It support DXF files comes from AutoCAD 2008 (http://images.autodesk.com/adsk/files/acad_dxf0.pdf).
17
+ STRING
18
+ spec.homepage = 'https://github.com/Loriowar/dxf_io'
19
+ spec.license = 'MIT'
20
+
21
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
25
+
26
+ if spec.respond_to?(:metadata)
27
+ #spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com' to prevent pushes to rubygems.org, or delete to allow pushes to any server."
28
+ end
29
+
30
+ spec.add_dependency 'activesupport', '>= 3.2'
31
+
32
+ spec.add_development_dependency 'bundler', '~> 1.9'
33
+ spec.add_development_dependency 'rake', '~> 10.0'
34
+ end
@@ -0,0 +1,13 @@
1
+ require 'dxf_io/version'
2
+
3
+ module DxfIO
4
+ extend ActiveSupport::Autoload
5
+
6
+ autoload :Constants
7
+
8
+ autoload :Reader
9
+ autoload :Writer
10
+
11
+ autoload :Wrapper
12
+ autoload :Entity
13
+ end
@@ -0,0 +1,24 @@
1
+ module DxfIO
2
+ module Constants
3
+ SECTIONS_LIST = %w(CLASSES TABLES BLOCKS ENTITIES OBJECTS THUMBNAILIMAGES).freeze
4
+ HEADER_NAME = 'HEADER'.freeze
5
+
6
+ WRITER_STRATEGY = %i(memory disk).freeze
7
+
8
+ START_POINT_GROUP_NUMS = [10, 20].freeze
9
+ END_POINT_GROUP_NUMS = [11, 21].freeze
10
+
11
+ ENTITIES_TYPE_NAME_VALUE_MAPPING = {ellipse: 'ELLIPSE',
12
+ polyline: 'LWPOLYLINE',
13
+ arc: 'ARC',
14
+ circle: 'CIRCLE',
15
+ dimension: 'DIMENSION',
16
+ hatch: 'HATCH',
17
+ leader: 'LEADER',
18
+ line: 'LINE',
19
+ mline: 'MLINE',
20
+ text: 'TEXT',
21
+ mtext: 'MTEXT',
22
+ spline: 'SPLINE'}.freeze
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ module DxfIO
2
+ module Entity
3
+ extend ActiveSupport::Autoload
4
+
5
+ autoload :Ellipse
6
+ autoload :Polyline
7
+ autoload :Arc
8
+ autoload :Circle
9
+ autoload :Dimension
10
+ autoload :Hatch
11
+ autoload :Leader
12
+ autoload :Line
13
+ autoload :Mline
14
+ autoload :Text
15
+ autoload :Mtext
16
+ autoload :Spline
17
+
18
+ autoload :Other
19
+ autoload :Support
20
+ end
21
+ end
@@ -0,0 +1,44 @@
1
+ module DxfIO
2
+ module Entity
3
+ class Arc < Other
4
+ ADDITIONAL_GROUP_CODES = {radius: 40,
5
+ start_angle: 50,
6
+ end_angle: 51}.freeze
7
+
8
+ ADDITIONAL_GROUP_CODES.each_pair do |method_name, group_code|
9
+ class_eval <<-EOT, __FILE__, __LINE__ + 1
10
+ def #{method_name} # def radius
11
+ to_h[#{group_code}] # to_h[40]
12
+ end # end
13
+ EOT
14
+ end
15
+
16
+ def center
17
+ points.first
18
+ end
19
+
20
+ def bordering_points
21
+ [point_by_angle(start_angle,
22
+ point_type: :start),
23
+ point_by_angle(end_angle,
24
+ point_type: :end)]
25
+ end
26
+
27
+ protected
28
+
29
+ def initialize(groups, representation_hash)
30
+ @representation_hash = representation_hash
31
+ super(groups)
32
+ end
33
+
34
+ private
35
+
36
+ def point_by_angle(angle, point_type: :start)
37
+ DxfIO::Entity::Support::Point.new(center.x + radius * Math::cos(angle),
38
+ center.y + radius * Math::sin(angle),
39
+ type: point_type)
40
+ end
41
+
42
+ end
43
+ end
44
+ end