autocad 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop/minitest.yml +2 -0
  3. data/.rubocop/strict.yml +4 -0
  4. data/.rubocop.yml +33 -0
  5. data/.solargraph.yml +22 -0
  6. data/.vscode/launch.json +30 -0
  7. data/CHANGELOG.md +5 -0
  8. data/CODE_OF_CONDUCT.md +132 -0
  9. data/Guardfile +66 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +39 -0
  12. data/Rakefile +10 -0
  13. data/Steepfile +35 -0
  14. data/WASD-D-TDS-C001.dwg +0 -0
  15. data/WASD-D-TDS-C001.pdf +0 -0
  16. data/autocad.log +1 -0
  17. data/autocad_example.rb +26 -0
  18. data/event_handler.log +24 -0
  19. data/examples/example_save_pdf.rb +5 -0
  20. data/exe/autocad +3 -0
  21. data/exe/dgn2pdf +50 -0
  22. data/exe/pw_print +43 -0
  23. data/gemfiles/rubocop.gemfile +6 -0
  24. data/lib/autocad/app.rb +655 -0
  25. data/lib/autocad/arc.rb +29 -0
  26. data/lib/autocad/block.rb +141 -0
  27. data/lib/autocad/block_reference.rb +198 -0
  28. data/lib/autocad/drawing.rb +426 -0
  29. data/lib/autocad/element.rb +454 -0
  30. data/lib/autocad/enumerator.rb +24 -0
  31. data/lib/autocad/errors.rb +37 -0
  32. data/lib/autocad/event_handler.rb +30 -0
  33. data/lib/autocad/filter.rb +168 -0
  34. data/lib/autocad/layer.rb +41 -0
  35. data/lib/autocad/line.rb +55 -0
  36. data/lib/autocad/message_box.rb +95 -0
  37. data/lib/autocad/model.rb +89 -0
  38. data/lib/autocad/mtext.rb +110 -0
  39. data/lib/autocad/paths.rb +29 -0
  40. data/lib/autocad/point3d.rb +143 -0
  41. data/lib/autocad/pviewport.rb +21 -0
  42. data/lib/autocad/selection_filter.rb +180 -0
  43. data/lib/autocad/selection_set.rb +61 -0
  44. data/lib/autocad/selection_set_adapter.rb +146 -0
  45. data/lib/autocad/text.rb +74 -0
  46. data/lib/autocad/version.rb +5 -0
  47. data/lib/autocad.rb +161 -0
  48. data/olegen.rb +341 -0
  49. data/rbs_collection.lock.yaml +188 -0
  50. data/rbs_collection.yaml +19 -0
  51. data/scanner.obj +0 -0
  52. data/sig/generated/autocad/app.rbs +251 -0
  53. data/sig/generated/autocad/arc.rbs +17 -0
  54. data/sig/generated/autocad/block.rbs +63 -0
  55. data/sig/generated/autocad/block_reference.rbs +59 -0
  56. data/sig/generated/autocad/drawing.rbs +158 -0
  57. data/sig/generated/autocad/element.rbs +166 -0
  58. data/sig/generated/autocad/enumerator.rbs +15 -0
  59. data/sig/generated/autocad/errors.rbs +23 -0
  60. data/sig/generated/autocad/event_handler.rbs +14 -0
  61. data/sig/generated/autocad/filter.rbs +60 -0
  62. data/sig/generated/autocad/layer.rbs +19 -0
  63. data/sig/generated/autocad/line.rbs +25 -0
  64. data/sig/generated/autocad/message_box.rbs +81 -0
  65. data/sig/generated/autocad/model.rbs +41 -0
  66. data/sig/generated/autocad/paths.rbs +19 -0
  67. data/sig/generated/autocad/point3d.rbs +66 -0
  68. data/sig/generated/autocad/selection_filter.rbs +50 -0
  69. data/sig/generated/autocad/selection_set.rbs +37 -0
  70. data/sig/generated/autocad/selection_set_adapter.rbs +28 -0
  71. data/sig/generated/autocad/text.rbs +19 -0
  72. data/sig/generated/autocad/text_node.rbs +37 -0
  73. data/sig/generated/autocad/version.rbs +5 -0
  74. data/sig/generated/autocad/viewport.rbs +11 -0
  75. data/sig/generated/autocad.rbs +68 -0
  76. data/sig/prototype/lib/autocad/app.rbs +34 -0
  77. data/sig/prototype/lib/autocad/block.rbs +5 -0
  78. data/sig/prototype/lib/autocad/block_reference.rbs +5 -0
  79. data/sig/prototype/lib/autocad/drawing.rbs +13 -0
  80. data/sig/prototype/lib/autocad/element.rbs +9 -0
  81. data/sig/prototype/lib/autocad/enumerator.rbs +5 -0
  82. data/sig/prototype/lib/autocad/event_handler.rbs +7 -0
  83. data/sig/prototype/lib/autocad/model.rbs +5 -0
  84. data/sig/prototype/lib/autocad/paths.rbs +5 -0
  85. data/sig/prototype/lib/autocad.rbs +3 -0
  86. data/temp/autocad.dwg +0 -0
  87. data/temp/autocad.log +1 -0
  88. data/temp/event_handler.log +0 -0
  89. metadata +147 -0
@@ -0,0 +1,180 @@
1
+ module Autocad
2
+ class SelectionFilter
3
+ attr_reader :types, :values
4
+
5
+ def initialize
6
+ @types = []
7
+ @values = []
8
+ end
9
+
10
+ def has_filters?
11
+ @types.any?
12
+ end
13
+
14
+ # Logical Operators
15
+ def and(*conditions)
16
+ return self if conditions.empty?
17
+
18
+ @types << -4
19
+ @values << "<AND"
20
+
21
+ conditions.each do |condition|
22
+ @types.concat(condition.types)
23
+ @values.concat(condition.values)
24
+ end
25
+
26
+ @types << -4
27
+ @values << "AND>"
28
+
29
+ self
30
+ end
31
+
32
+ def or(*conditions)
33
+ return self if conditions.empty?
34
+
35
+ @types << -4
36
+ @values << "<OR"
37
+
38
+ conditions.each do |condition|
39
+ @types.concat(condition.types)
40
+ @values.concat(condition.values)
41
+ end
42
+
43
+ @types << -4
44
+ @values << "OR>"
45
+
46
+ self
47
+ end
48
+
49
+ def xor(condition1, condition2)
50
+ @types << -4
51
+ @values << "<XOR"
52
+
53
+ @types.concat(condition1.types)
54
+ @values.concat(condition1.values)
55
+
56
+ @types.concat(condition2.types)
57
+ @values.concat(condition2.values)
58
+
59
+ @types << -4
60
+ @values << "XOR>"
61
+
62
+ self
63
+ end
64
+
65
+ def not(condition)
66
+ @types << -4
67
+ @values << "<NOT"
68
+
69
+ @types.concat(condition.types)
70
+ @values.concat(condition.values)
71
+
72
+ @types << -4
73
+ @values << "NOT>"
74
+
75
+ self
76
+ end
77
+
78
+ # Relational Operators
79
+ # f.type("Circle").greater_than(5)
80
+ def greater_than(value)
81
+ @types << -4
82
+ @values << ">="
83
+ @types << 40 # floating point
84
+ @values << value
85
+ self
86
+ end
87
+
88
+ def less_than(value)
89
+ @types << -4
90
+ @values << "<="
91
+ @types << 40 # floating point
92
+ @values << value
93
+ self
94
+ end
95
+
96
+ def equal_to(value)
97
+ @types << -4
98
+ @values << "="
99
+ @types << 40 # floating point
100
+ @values << value
101
+ self
102
+ end
103
+
104
+ def not_equal_to(value)
105
+ @types << -4
106
+ @values << "<>"
107
+ @types << 40 # floating point
108
+ @values << value
109
+ self
110
+ end
111
+
112
+ def block_reference(name = nil)
113
+ # return unless name
114
+
115
+ @types << 0
116
+ @values << "INSERT"
117
+ self
118
+ end
119
+
120
+ def name(value)
121
+ @types << [0, 2]
122
+ @values << value
123
+ self
124
+ end
125
+
126
+ def type(kind)
127
+ @types << 0
128
+ @values << kind
129
+ self
130
+ end
131
+
132
+ def layer(name)
133
+ @types << 8
134
+ @values << name
135
+ self
136
+ end
137
+
138
+ def visible(vis = true)
139
+ @types << 60
140
+ @values << (vis ? 0 : 1)
141
+ self
142
+ end
143
+
144
+ def color(num)
145
+ @types << 62 # Color number filter
146
+ @values << num
147
+ self
148
+ end
149
+
150
+ def paper_space
151
+ @types << 67 # Paper space filter
152
+ @values << 1
153
+ self
154
+ end
155
+
156
+ def model_space
157
+ @types << 67 # Model space filter
158
+ @values << 0
159
+ self
160
+ end
161
+
162
+ def contains(str)
163
+ @types << -4
164
+ @values << "<OR"
165
+
166
+ # Filter for TEXT
167
+ @types << 1 # Text string group code for TEXT
168
+ @values << "*#{str}*"
169
+
170
+ # Filter for MTEXT
171
+ @types << 1 # Text string group code for MTEXT
172
+ @values << "*#{str}*"
173
+
174
+ @types << -4
175
+ @values << "OR>"
176
+
177
+ self
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,61 @@
1
+ # require_relative "selection_filter"
2
+ require_relative 'filter'
3
+
4
+ module Autocad
5
+ class SelectionSet
6
+ attr_reader :filter_types, :filter_values, :name
7
+
8
+ def initialize(name)
9
+ @name = name
10
+ @filter_types = []
11
+ @filter_values = []
12
+ end
13
+
14
+ def has_filter?
15
+ filter_types && filter_types.any?
16
+ end
17
+
18
+ def filter_text(str = nil)
19
+ if str
20
+ filter_text_containing(str)
21
+ else
22
+ filter do |f|
23
+ f.or(f.type('TEXT'), f.type('MTEXT'))
24
+ end
25
+ end
26
+ end
27
+
28
+ # filter do |f|
29
+ # st = f.type('Circle').or(f.type('Arc'))
30
+ # st2 = f.layer('0').or(f.layer('1'))
31
+ # f.and(st, st2)
32
+ # end
33
+ def filter
34
+ if block_given?
35
+ filter = Filter.new
36
+ result = yield filter
37
+ @filter_types, @filter_values = result.convert_clauses
38
+ end
39
+ self
40
+ end
41
+
42
+ # Helper methods for common operations
43
+ def filter_by_type(*types)
44
+ filter { |f| f.or(*types.map { |t| f.type(t) }) }
45
+ end
46
+
47
+ def filter_by_layer(*layers)
48
+ filter { |f| f.or(*layers.map { |l| f.layer(l) }) }
49
+ end
50
+
51
+ def filter_text_containing(text)
52
+ filter do |f|
53
+ f.and(f.has_text(text), f.or(f.type('TEXT'), f.type('MTEXT')))
54
+ end
55
+ end
56
+
57
+ def filter_block_references(name = nil)
58
+ filter { |f| f.block_reference(name) }
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,146 @@
1
+ module Autocad
2
+ class SelectionSetAdapter
3
+ def self.from_ole_obj(drawing, ole)
4
+ ss = SelectionSet.new(ole.Name)
5
+ new(drawing, ss, ole)
6
+ end
7
+
8
+ attr_reader :ole_obj, :drawing, :selection_set
9
+
10
+ def initialize(drawing, selection_set, ole = nil)
11
+ @drawing = drawing
12
+ @selection_set = selection_set
13
+ @ole_obj = ole || create_selection_set
14
+ end
15
+
16
+ def delete
17
+ @ole_obj.Delete
18
+ @selection_set = nil
19
+ end
20
+
21
+ # checks if the selection set has any items
22
+ # @ rbs return bool
23
+ def has_items?
24
+ ole_obj.Count > 0
25
+ end
26
+
27
+ def count
28
+ ole_obj.Count
29
+ end
30
+
31
+ def clear
32
+ ole_obj.Clear
33
+ end
34
+
35
+ def filter_text(str)
36
+ @selection_set.filter_text(str)
37
+ end
38
+
39
+ def filter_text_containing(str)
40
+ @selection_set.filter_text_containing(str)
41
+ end
42
+
43
+ def app
44
+ @drawing.app
45
+ end
46
+
47
+ def each
48
+ return to_enum(__callee__) unless block_given?
49
+
50
+ ole_obj.each { |o| yield app.wrap(o) }
51
+ end
52
+
53
+ def name
54
+ @ole_obj.Name
55
+ end
56
+
57
+ def filter_types
58
+ @selection_set.filter_types
59
+ end
60
+
61
+ def filter_values
62
+ @selection_set.filter_values
63
+ end
64
+
65
+ def select_on_screen(ft = ole_filter_types, fv = ole_filter_values)
66
+ @ole_obj.SelectOnScreen(ft, fv)
67
+ end
68
+
69
+ def select(mode: :all, pt1: nil, pt2: nil, ft: ole_filter_types, fv: ole_filter_values)
70
+ acad_mode = case mode
71
+ when :all
72
+ ACAD::AcSelectionSetAll
73
+ when :window
74
+ ACAD::AcSelectionSetWindow
75
+ when :crossing
76
+ ACAD::AcSelectionSetCrossing
77
+ when :previous
78
+ ACAD::AcSelectionSetPrevious
79
+ when :last
80
+ ACAD::AcSelectionSetLast
81
+ else
82
+ Acad::AcSelectionSetAll
83
+ end
84
+ @ole_obj.Select(acad_mode, nil, nil, ft, fv)
85
+ end
86
+
87
+ # accepts Point3d | [x,y] | (x,y)
88
+ def select_at_point(x, y)
89
+ point = if x.respond_to?(:x) && x.respond_to?(:y)
90
+ # Handle Point3d object
91
+ [x.x, x.y]
92
+ elsif x.is_a?(Array)
93
+ # Handle array input
94
+ x
95
+ else
96
+ # Handle separate x,y coordinates
97
+ [x, y]
98
+ end
99
+
100
+ @ole_obj.SelectAtPoint(point, filter_types, filter_values)
101
+ end
102
+
103
+ # @param points [Array<Point3d>] Array of points defining the polygon
104
+ # @param mode [:fence, :window, :crossing] Selection mode
105
+ def select_by_polygon(points: [], mode: :fence)
106
+ # Convert points to arrays of coordinates
107
+ point_coords = points.map { |p| [p.x, p.y] }
108
+
109
+ mode_code = case mode
110
+ when :fence then 5
111
+ when :window then 3
112
+ when :crossing then 4
113
+ else
114
+ raise ArgumentError, "Invalid selection mode: #{mode}. Must be :fence, :window, or :crossing"
115
+ end
116
+
117
+ @ole_obj.SelectByPolygon(mode_code, point_coords, filter_types, filter_values)
118
+ end
119
+
120
+ def filter(&)
121
+ @selection_set.filter(&)
122
+ end
123
+
124
+ private
125
+
126
+ def create_selection_set
127
+ @drawing.ole_obj.SelectionSets.Add(@selection_set.name)
128
+ end
129
+
130
+ def ole_filter_types
131
+ WIN32OLE::Variant.new(filter_types, WIN32OLE::VARIANT::VT_ARRAY | WIN32OLE::VARIANT::VT_I2)
132
+ end
133
+
134
+ def ole_filter_values
135
+ WIN32OLE::Variant.new(filter_values, WIN32OLE::VARIANT::VT_ARRAY | WIN32OLE::VARIANT::VT_VARIANT)
136
+ end
137
+ end
138
+ end
139
+
140
+ # ss = Autocad::SelectionSet.new('test_ss')
141
+ # ss.filter_text_containing('test')
142
+ # ss = drawing.create_selection_set('test_ss') do
143
+ # filter do |f|
144
+ # f.or(f.type('Circle'), f.type('Arc'))
145
+ # end
146
+ # end
@@ -0,0 +1,74 @@
1
+ require_relative "element"
2
+
3
+ module Autocad
4
+ class Text < Element
5
+ def read_ole(_ole)
6
+ ole_obj.TextString
7
+ end
8
+
9
+ def write_ole(text)
10
+ ole_obj.TextString = text
11
+ end
12
+
13
+ def to_regexp
14
+ Regexp.new(read_ole.to_s)
15
+ end
16
+
17
+ def =~(reg)
18
+ @original =~ reg
19
+ end
20
+
21
+ # de_relativef tocad_id
22
+ # @ole_obj.Id || @ole_obj.ID64
23
+ # end
24
+ # def text?
25
+ # true
26
+ # end
27
+
28
+ # def text_node?
29
+ # false
30
+ # end
31
+
32
+ def to_s
33
+ original.to_s
34
+ end
35
+
36
+ def bounds
37
+ binding.break
38
+ rotation = ole_obj.Rotation
39
+ begin
40
+ app_ole_obj.Matrix3dInverse(rotation)
41
+ rescue
42
+ binding.irb
43
+ end
44
+ transform = app_ole_obj.Transform3dFromMatrix3dandFixedPoint3d(app_ole_obj.Matrix3dInverse(rotation),
45
+ ole_obj.origin)
46
+ ole_obj.transform transform
47
+
48
+ 0.upto(4) do |i|
49
+ points[i] = ole_obj.Boundary.Low
50
+ end
51
+ points[2] = self.Boundary.High
52
+ points[1].X = points[2].x
53
+ points[3].y = points[2].Y
54
+ end
55
+
56
+ def method_missing(meth, *, &)
57
+ if /^[A-Z]/.match?(meth)
58
+ ole_obj.send(meth, *)
59
+ else
60
+ dup = @original.dup
61
+ result = dup.send(meth, *, &)
62
+ update(result)
63
+ result
64
+ end
65
+ end
66
+
67
+ # def method_missing(meth,*args,&block)
68
+ # dup = @original_text.dup
69
+ # result = dup.send(meth,*args, &block)
70
+ # _update(dup) unless dup == @original_text
71
+ # result
72
+ # end
73
+ end
74
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Autocad
4
+ VERSION = '0.4.6'
5
+ end
data/lib/autocad.rb ADDED
@@ -0,0 +1,161 @@
1
+ # rbs_inline: enabled
2
+
3
+ module Autocad
4
+ module Common
5
+ def method_missing(method, ...)
6
+ if /^[A-Z]/.match?(method.to_s)
7
+ ole_obj.send(method, ...)
8
+ else
9
+ super
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ module ACAD
16
+ end
17
+
18
+ require "logger"
19
+ require "autocad/version"
20
+ require "win32ole"
21
+ require "pathname"
22
+ require "autocad/app"
23
+ require "autocad/errors"
24
+ require "autocad/point3d"
25
+ require "autocad/layer"
26
+ require "autocad/message_box"
27
+
28
+ def Point3d(...)
29
+ Autocad::Point3d.new(...)
30
+ end
31
+
32
+ module Autocad
33
+ ROOT = Pathname.new(__dir__).parent
34
+
35
+ class << self
36
+ # @yield [Autocad::App]
37
+ def run(...) #: void
38
+ App.run(...)
39
+ end
40
+
41
+ # @return [Pathname]
42
+ def root #:Pathname
43
+ ROOT
44
+ end
45
+
46
+ # @rbs dir: String -- the directory of drawing dgn|dwg -- to convert
47
+ # @rbs outdir: String -- the output dir for converted pdf files
48
+ def dgn2pdf(dir_or_file, outdir: dir_or_file, mode: :dir)
49
+ raise "Mode on of :dir or :file" unless [:dir, :file].include? mode
50
+ if mode == :dir
51
+ drawings = drawings_in_dir(dir_or_file)
52
+ with_drawings(drawings) do |drawing|
53
+ drawing.save_as_pdf(name: drawing.name, dir: outdir)
54
+ end
55
+ else
56
+ open_drawing(dir_or_file) do |drawing|
57
+ drawing.save_as_pdf(name: drawing.name, dir: outdir)
58
+ end
59
+ end
60
+ end
61
+
62
+ # save the current drawing
63
+ # @rbs dir: String|Pathname -- the dir to save drawing to
64
+ # @rbs exit: bool -- whether to exit afterwards or start irb
65
+ # @rbs model: bool -- prints model space instead of paperspace in pdf document
66
+ # @rbs return void
67
+ def save_open_drawings(dir: Pathname.getwd, exit: true, model: false)
68
+ if exit
69
+ run do |app|
70
+ return unless app.has_drawings?
71
+ drawings = app.drawings
72
+ drawings.each do |d|
73
+ d.copy(dir:)
74
+ d.save_as_pdf(dir:, model:)
75
+ d.close(false)
76
+ end
77
+ end
78
+ else
79
+ app = App.new
80
+ return unless app.has_drawings?
81
+ drawings = app.drawings
82
+ drawings.each do |d|
83
+ d.copy(dir:)
84
+ d.save_as_pdf(dir:, model:)
85
+ # d.close(false)
86
+ end
87
+ app
88
+ end
89
+ end
90
+
91
+ # save the current drawing
92
+ # @rbs dir: String|Dir -- the dir to save drawing to
93
+ # @rbs exit: bool -- whether to exit afterwards or start irb
94
+ # @rbs model: bool -- prints model space in pdf document
95
+ # @rbs return void
96
+ def save_current_drawing(dir, exit: true, model: false)
97
+ if exit
98
+ run do |app|
99
+ drawing = app.current_drawing
100
+ return unless drawing
101
+ drawing.copy(dir: dir)
102
+ drawing.save_as_pdf(dir:, model:)
103
+ drawing.close(false)
104
+ end
105
+ else
106
+ app = App.new
107
+ drawing = app.current_drawing
108
+ return unless drawing
109
+ drawing.copy(dir: dir)
110
+ drawing.save_as_pdf(dir: dir)
111
+ app
112
+ end
113
+ end
114
+
115
+ # save the current drawing as pdf
116
+ # @rbs dir: String|Dir -- the dir to save drawing to
117
+ # @rbs return void
118
+ def save_current_drawing_as_pdf(dir)
119
+ App.run do |app|
120
+ drawing = app.current_drawing
121
+ drawing.save_as_pdf(dir: dir)
122
+ drawing.close
123
+ end
124
+ end
125
+
126
+ # gets all dwg and dgn dfiles in a directory
127
+ # @rbs dir: String|Pathname
128
+ def drawings_in_dir(dir)
129
+ dirpath = Pathname.new(dir).expand_path
130
+ dirpath.glob("*.d{gn,wg,xf}").sort_by { _1.basename(".*").to_s.downcase }
131
+ end
132
+
133
+ def open_drawing(drawing, ...)
134
+ App.open_drawing(drawing, ...)
135
+ end
136
+
137
+ # Runs the app, opening the filenames
138
+ # and yielding each open drawing to the
139
+ # supplied block
140
+ # it automatically closes the drawing and
141
+ # the app when done
142
+ #
143
+ # @rbs *files: Array[String|Pathname]
144
+ # @rbs visible: bool -- show the app window
145
+ # @rbs error_proc: (Exception, Drawing) -> void
146
+ # @rbs wait_time: Integer -- the total amount of time to wait to open file (500)
147
+ # @rbs wait_interval: Float -- the amount of time to wait between attempts (0.5)
148
+ # @rbs read_only: bool
149
+ # @rbs &: (Drawing) -> void
150
+ def with_drawings(...)
151
+ App.with_drawings(...)
152
+ end
153
+
154
+ # Finds the drawing in dir and calls with_drawing forwarding all params
155
+ # @rbs dir: String|Pathname -- directory to search for drawings
156
+ def with_drawings_in_dir(dir, ...)
157
+ drawings = drawings_in_dir(dir)
158
+ with_drawings(drawings, ...)
159
+ end
160
+ end
161
+ end