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,655 @@
1
+ # rbs_inline: enabled
2
+
3
+ require_relative "event_handler"
4
+ require_relative "drawing"
5
+ require_relative "paths"
6
+ require_relative "element"
7
+ require_relative "line"
8
+ require_relative "text"
9
+ require_relative "mtext"
10
+ require_relative "pviewport"
11
+ require_relative "block"
12
+ require_relative "block_reference"
13
+ require_relative "selection_set"
14
+
15
+ require "win32ole"
16
+ module Windows
17
+ class FileSystem
18
+ def self.windows_path(path)
19
+ obj = new
20
+ obj.windows_path(path)
21
+ end
22
+
23
+ # Convert path to windows path
24
+ # @rbs path: String, Pathname the path you want to convert
25
+ def windows_path(path)
26
+ path = path.to_path if path.respond_to? :to_path
27
+ fs_object.GetAbsolutePathName(path.to_str)
28
+ end
29
+
30
+ def fs_object
31
+ @fs_object ||= WIN32OLE.new("Scripting.FileSystemObject")
32
+ end
33
+ end
34
+ end
35
+
36
+ module Autocad
37
+ class App
38
+ include Common
39
+ @default_error_proc = ->(e, f) {
40
+ puts "Couldn't open drawing #{f}" if f
41
+ debug_error if $DEBUG
42
+ raise e
43
+ }
44
+
45
+ class << self
46
+ attr_accessor :default_error_proc
47
+
48
+ def default_app_options
49
+ {visible: false, error_proc: @default_error_proc, wait_time: 500, wait_interval: 0.5}
50
+ end
51
+
52
+ def debug_error
53
+ require "debug"
54
+ binding.break
55
+ end
56
+
57
+ # save the current drawing
58
+ # @rbs dir: String|Pathname -- the dir to save drawing to
59
+ # @rbs exit: bool -- whether to exit afterwards or start irb
60
+ # @rbs model: bool -- prints model space instead of paperspace in pdf document
61
+ # @rbs return void
62
+ def save_open_drawings(dir: Pathname.getwd, exit: true, model: false)
63
+ if exit
64
+ run do |app|
65
+ return unless app.has_drawings?
66
+ drawings = app.drawings
67
+ drawings.each do |d|
68
+ d.copy(dir:)
69
+ d.save_as_pdf(dir:, model:)
70
+ d.close(false)
71
+ end
72
+ end
73
+ else
74
+ app = App.new
75
+ return unless app.has_drawings?
76
+ drawings = app.drawings
77
+ drawings.each do |d|
78
+ d.copy(dir:)
79
+ d.save_as_pdf(dir:, model:)
80
+ # d.close(false)
81
+ end
82
+ app
83
+ end
84
+ end
85
+
86
+ # Runs the app, opening the filenames
87
+ # and yielding each open drawing to the
88
+ # supplied block
89
+ # it automatically closes the drawing and
90
+ # the app when done
91
+ #
92
+ # [source]
93
+ # dir = Pathname.new('C:/templates')
94
+ # drawings = Pathname.glob(dir + '/**/*.dgn')
95
+ # App.with_drawings(drawings) do |drawing|
96
+ # drawing.save_as_pdf(dir: 'c:/output/')
97
+ # end
98
+ #
99
+ # @rbs *files: Array[String|Pathname]
100
+ # @rbs visible: bool -- show the app window
101
+ # @rbs error_proc: (Exception, Drawing) -> void
102
+ # @rbs wait_time: Integer -- the total amount of time to wait to open file (500)
103
+ # @rbs wait_interval: Float -- the amount of time to wait between attempts (0.5)
104
+ # @rbs read_only: bool
105
+ # @rbs &: (Drawing) -> void
106
+ def with_drawings(*files, visible: false, error_proc: @default_error_proc,
107
+ wait_time: 500, wait_interval: 0.5, read_only: false, &block)
108
+ # drawing_options = default_drawing_options.merge(options)
109
+ # app_options = default_app_options
110
+ files = files[0] if files[0].is_a? Array
111
+ begin
112
+ the_app = new(visible:, error_proc:, wait_time:, wait_interval:)
113
+ files_enum = files.each
114
+ loop do
115
+ file = files_enum.next
116
+ puts "opening #{file}.."
117
+ begin
118
+ the_app.open_drawing(file, read_only:, wait_time:, wait_interval:, error_proc:, &block)
119
+ the_app.ole_obj.ole_methods # check if server still open
120
+ rescue => e
121
+ raise e unless error_proc
122
+
123
+ error_proc.call(e, file)
124
+ the_app = new(visible: opt_visible)
125
+ end
126
+ end
127
+ ensure
128
+ the_app&.quit
129
+ the_app = nil
130
+ end
131
+ end
132
+
133
+ # gets all dwg and dgn files in the directory given by
134
+ # dir_or_file or gets the file given by dir_or_file
135
+ # and saves them as pdf files in the outdir
136
+ # @rbs dir_or_file: String the directory of drawing [dgn,dwg] to convert
137
+ # @rbs outdir: String the output dir for converted pdf files
138
+ # @rbs return void
139
+ def dwg2pdf(dir_or_file, outdir: dir_or_file, mode: :dir)
140
+ raise "Mode on of :dir or :file" unless [:dir, :file].include? mode
141
+ if mode == :dir
142
+ drawings = drawings_in_dir(dir_or_file)
143
+ with_drawings(drawings, read_only: true) do |drawing|
144
+ drawing.save_as_pdf(name: drawing.name, dir: outdir)
145
+ end
146
+ else
147
+ open_drawing(dir_or_file) do |drawing|
148
+ drawing.save_as_pdf(name: drawing.name, dir: outdir)
149
+ end
150
+ end
151
+ end
152
+
153
+ # Initialize an instance of app with the options
154
+ # @rbs : Hash] options the options to create the app with
155
+ # @option options bool :visible Is the app visible
156
+ #
157
+ # [source]
158
+ # ----
159
+ # App.run do |app|
160
+ # drawing = app.open_drawing('test.dgn')
161
+ # drawing.scan_all_text do |model,text|
162
+ # puts "#{model} #{text}"
163
+ # end
164
+ # end
165
+ # @rbs options: Hash[Symbol,Object]
166
+ # @rbs &: (App) -> void -- the_app yields the instanciated app
167
+ def run(options = {}) #: void
168
+ opts = default_app_options.merge(options)
169
+ err_fn = opts.fetch(:error_proc, default_error_proc)
170
+ begin
171
+ the_app = new(**opts)
172
+ # binding.break if the_app.nil?
173
+ yield the_app
174
+ rescue => e
175
+ if e.respond_to? :drawing
176
+ err_fn.call(e, e.drawing)
177
+ else
178
+ err_fn.call(e, nil)
179
+ end
180
+ ensure
181
+ the_app&.quit
182
+ GC.start
183
+ end
184
+ end
185
+
186
+ # Calls #run to get an app instance then call open drawing with
187
+ # that app
188
+ # (see #open_drawing)
189
+ # @rbs &block: { (Drawing) -> void }
190
+ def open_drawing(drawing, **options, &block) #: void
191
+ run(**options) do |app|
192
+ app.open_drawing(drawing, **options, &block)
193
+ end
194
+ end
195
+ end
196
+
197
+ # @rbs return bool -- true if there is an active drawing
198
+ def active_drawing?
199
+ ole_obj.Documents.count > 0
200
+ end
201
+
202
+ # @rbs return Drawing | nil -- returns drawing if active_drawing
203
+ def active_drawing
204
+ return unless active_drawing?
205
+ ole = ole_obj.ActiveDocument
206
+ drawing_from_ole(ole)
207
+ end
208
+
209
+ def drawing_from_ole(ole) #: Drawing
210
+ Drawing.new(self, ole)
211
+ end
212
+
213
+ attr_reader :error_proc, :visible, :logger
214
+
215
+ # Constructor for app
216
+ # @rbs visible: bool -- do you want the app to be visible
217
+ # @rbs event_handler: EventHandler
218
+ def initialize(visible: true, error_proc: self.class.default_error_proc, event_handler: default_event_handler, wait_interval: nil, wait_time: nil)
219
+ @visible = visible
220
+ @logger = Logger.new("autocad.log")
221
+ @event_handler = event_handler
222
+ @error_proc = error_proc
223
+ @ole_obj, @app_event = init_ole_and_app_event(visible: @visible, event_handler: @event_handler, tries: 5,
224
+ sleep_duration: 0.5)
225
+ @run_loop = true
226
+ @windows = Windows::FileSystem.new
227
+ # make_visible(visible)
228
+ @scanners = {}
229
+ rescue => e
230
+ @error_proc.call(e, nil)
231
+ end
232
+
233
+ def windows_path(path)
234
+ @windows.windows_path(path)
235
+ end
236
+
237
+ def wrap(item, cell = nil)
238
+ Element.convert_item(item, self, cell)
239
+ end
240
+
241
+ # the default EventHandler
242
+ #
243
+ # @rbs return EventHandler -- returns the default EventHandler
244
+ def default_event_handler
245
+ event_handler = EventHandler.new
246
+ # event_handler.add_handler("BeginOpen") do |*args|
247
+ # puts "begining opening drawing #{args}"
248
+ # end
249
+ event_handler.add_handler("EndOpen") do |*args|
250
+ puts "drawing #{args} opened"
251
+ @drawing_opened = true
252
+ end
253
+ event_handler.add_handler("BeginDocClose") do |*args|
254
+ @drawing_opened = false
255
+ puts "drawing #{args} closed"
256
+ end
257
+
258
+ event_handler.add_handler("NewDrawing") do |*args|
259
+ @drawing_opened = true
260
+ puts "drawing #{args} created"
261
+ end
262
+ event_handler
263
+ end
264
+
265
+ def default_app_options
266
+ self.class.default_app_options
267
+ end
268
+
269
+ # register an handler
270
+ #
271
+ # @rbs event: String -- event to registor for
272
+ def register_handler(event, &)
273
+ @event_handler.add_handler(event, &) unless event == "OnQuit"
274
+ end
275
+
276
+ #
277
+ # return a Handler
278
+ #
279
+ # @rbs : String,Symbol] event the event key
280
+ #
281
+ # @rbs return Proc returns the Proc given by event name
282
+ #
283
+ def get_handler(event)
284
+ @event_handler.get_handler(event)
285
+ end
286
+
287
+ def load_constants(ole)
288
+ WIN32OLE.const_load(ole, ACAD) unless ACAD.constants.size > 0
289
+ end
290
+
291
+ def run_loop
292
+ WIN32OLE_EVENT.message_loop if @run_loop
293
+ end
294
+
295
+ def stop_loop
296
+ @run_loop = false
297
+ end
298
+
299
+ def exit_message_loop
300
+ puts "Autocad exiting..."
301
+ @run_loop = false
302
+ end
303
+
304
+ def visible?
305
+ @visible
306
+ end
307
+
308
+ def visible=(value)
309
+ make_visible !!value
310
+ end
311
+
312
+ def make_visible(visible)
313
+ @visible = visible
314
+ begin
315
+ @ole_obj.Visible = visible
316
+ true
317
+ rescue
318
+ false
319
+ end
320
+ end
321
+
322
+ # Zooms the current viewport to display the entire drawing
323
+ def zoom_all
324
+ ole_obj.ZoomAll
325
+ end
326
+
327
+ def zoom_center(center, magnify: 1.0)
328
+ pt = Point3d(center)
329
+ ole_obj.ZoomCenter(pt.to_ole, magnify.to_f)
330
+ end
331
+
332
+ def zoom_window(pt1, pt2)
333
+ pt1 = Point3d(pt1)
334
+ pt2 = Point3d(pt2)
335
+ ole_obj.ZoomWindow(pt1.to_ole, pt2.to_ole)
336
+ end
337
+
338
+ def zoom_pick_window
339
+ ole_obj.ZoomPickWindowo
340
+ end
341
+
342
+ def zoom_extents
343
+ ole_obj.ZoomExtents
344
+ end
345
+
346
+ def zoom_previous
347
+ ole_obj.ZoomPrevious
348
+ end
349
+
350
+ def zoom_scaled(magnify: 1.0, scale_type: :paper_space)
351
+ scale_type = case scale_type
352
+ when :paper_space
353
+ ACAD::AcZoomScaledRelativePSpace
354
+ when :absolute
355
+ ACAD::AcZoomScaledAbsolute
356
+ when :relative
357
+ ACAD::AcZoomScaledRelative
358
+ else
359
+ ACAD::AcZoomScaledRelative
360
+ end
361
+ ole_obj.ZoomScaled(magnify.to_f, scale_type)
362
+ end
363
+
364
+ # Zooms the current viewport to a specific center point and magnify factor
365
+ # @rbs center: Point3d | [Float, Float, Float| nil] -- center of zoom
366
+ # @rbs magnify: Float
367
+ def zoom_center(center, magnify: 1.0)
368
+ pt = Point3d(center)
369
+ ole_obj.ZoomCenter(pt.to_ole, magnify.to_f)
370
+ end
371
+
372
+ def ole_obj
373
+ is_ok = true
374
+ begin
375
+ @ole_obj.Visible
376
+ rescue
377
+ is_ok = false
378
+ end
379
+
380
+ @ole_obj, @app_event = init_ole_and_app_event(visible: @visible, event_handler: @event_handler, tries: 3) unless is_ok
381
+
382
+ @ole_obj
383
+ end
384
+
385
+ def quit
386
+ close_all_drawings
387
+ @ole_obj&.Quit
388
+ rescue
389
+ nil
390
+ end
391
+
392
+ def close_all_drawings(save: false)
393
+ return unless @ole_obj
394
+ until @ole_obj.Documents.Count == 0
395
+ begin
396
+ @ole_obj.ActiveDocument.Close(save)
397
+ rescue
398
+ break
399
+ end
400
+ end
401
+ end
402
+
403
+ def close_active_drawing
404
+ drawing = active_drawing
405
+ drawing&.close
406
+ end
407
+
408
+ # create a new drawing
409
+ #
410
+ # @rbs filename: String | Pathname -- The name of the drawing.
411
+ # @rbs seedfile: String -- The name of the seed file.
412
+ # should not include a path. The default ggextension is ".dgn".
413
+ # Typical values are "seed2d" or "seed3d".
414
+ # @rbs open: bool -- If the open argument is True,
415
+ # CreateDesignFile returns the newly-opened DesignFile object;
416
+ # this is the same value as ActiveDesignFile. If the Open argument is False,
417
+ # CreateDesignFile returns Nothing.
418
+ # @rbs return Drawing, void -- returns the new drawing
419
+ def new_drawing(filename, open: true, options: {}, &block)
420
+ opts = default_app_options.merge(options)
421
+ err_fn = opts.fetch(:error_proc, error_proc)
422
+ file_path = Pathname.new(filename).expand_path
423
+ raise ExistingFile, file_path if file_path.exist?
424
+
425
+ # drawing_name = normalize_name(filename)
426
+ # seedfile = determine_seed(seedfile)
427
+ # binding.break unless seedfile
428
+ windows_name = windows_path(filename)
429
+ ole = new_ole_drawing(windows_name, open: open, wait_time: opts[:wait_time], wait_interval: opts[:wait_interval])
430
+ drawing = drawing_from_ole(ole)
431
+ return drawing unless block
432
+
433
+ begin
434
+ yield drawing
435
+ rescue DrawingError => e
436
+ err_fn.call(e, e.drawing)
437
+ rescue => e
438
+ err_fn.call(e, file_path)
439
+ ensure
440
+ drawing.close
441
+ end
442
+ end
443
+
444
+ # open the drawing
445
+ # @rbs filename: String the name of the file to open
446
+ # @rbs : bool :read_only (false)
447
+ # @rbs wait_time: Integer -- the total amount of time to wait to open file (500)
448
+ # @rbs wait_interval: Float -- the amount of time in seconds to wait before retry (0.5)
449
+ # @rbs error_proc: Proc -- a proc to run
450
+ # @rbs &: (Drawing) -> (void)
451
+ # @rbs return Drawing | void
452
+ def open_drawing(filename, read_only: false, wait_time: nil,
453
+ wait_interval: nil, error_proc: nil, &block)
454
+ file_path = Pathname.new(filename).expand_path
455
+ raise FileNotFound.new(file_path) unless file_path.file?
456
+
457
+ begin
458
+ ole = ole_open_drawing(windows_path(filename), read_only:, wait_time:, wait_interval:)
459
+ rescue DrawingError => e
460
+ raise e unless err_fn
461
+
462
+ err_fn.call(e, e.drawing)
463
+ end
464
+ drawing = drawing_from_ole(ole)
465
+ return drawing unless block_given?
466
+
467
+ begin
468
+ yield drawing
469
+ rescue => e
470
+ raise e unless err_fn
471
+ err_fn.call(e, filename)
472
+ ensure
473
+ drawing.close
474
+ end
475
+ end
476
+
477
+ alias_method :doc, :active_drawing
478
+
479
+ alias_method :current_drawing, :active_drawing
480
+
481
+ def model_space
482
+ ModelSpace.new(doc_ole.ModelSpace)
483
+ end
484
+
485
+ def paper_space
486
+ PaperSpace.new(doc_ole.PaperSpace)
487
+ end
488
+
489
+ alias_method :model, :model_space
490
+
491
+ # @rbs message: String -- the String to put in Autocad prompt
492
+ def prompt(message)
493
+ doc.prompt(message)
494
+ end
495
+
496
+ # @rbs prompt: string -- the string to prompt the user for string
497
+ # @rbs has_spaces: bool -- whether the string returned can contain spaces
498
+ def get_input_string(...)
499
+ doc.get_input_string(...)
500
+ end
501
+
502
+ # @rbs prompt: string -- the string to prompt the user for integer
503
+ def get_input_integer(...)
504
+ doc.get_input_integer(...)
505
+ end
506
+
507
+ # In a running Autocad instance, prompts the user for a point.
508
+ # Uses the prompt argument as the prompt string.
509
+ # If base_point is provided, it is used as the base point and a
510
+ # stretched line is drawn from the base point to the returned point.
511
+ # @rbs prompt: String
512
+ # @rbs base_point: Array, Point3d, nil
513
+ # @rbs return [Point3d]
514
+ def get_point(...)
515
+ doc.get_point(...)
516
+ end
517
+
518
+ # In autocad prompts the user for a selection.
519
+ # @rbs prompt: String the prompt that displays in Autocad
520
+ # @rbs name: String the name of the selection
521
+ # @rbs return [SelectionSet]
522
+ def get_selection(prompt: "Select objects", name: "_SS1")
523
+ prompt(prompt)
524
+ begin
525
+ doc_ole.SelectionSets.Item(name).Delete
526
+ rescue
527
+ logger.debug("Delete selection failed")
528
+ end
529
+
530
+ selection = doc_ole.SelectionSets.Add(name)
531
+ selection.SelectOnScreen
532
+ selection
533
+ end
534
+
535
+ def has_documents?
536
+ ole_obj.Documents.Count > 0
537
+ end
538
+
539
+ alias_method :has_drawings?, :has_documents?
540
+
541
+ # @rbs return Enumerator[Drawing] | void
542
+ # @rbs &: (Drawing) -> void
543
+ def documents
544
+ return to_enum(__callee__) unless block_given?
545
+ ole_obj.Documents.each { |o| yield Drawing.new(self, o) }
546
+ end
547
+
548
+ alias_method :drawings, :documents
549
+
550
+ # @rbs return [bool] true
551
+ def drawing_opened?
552
+ @drawing_opened
553
+ end
554
+
555
+ # @rbs return [Pathname] Autocad Files.TemplateDwgPath
556
+ def templates_path
557
+ Pathname.new(ole_preferences_files.TemplateDwgPath)
558
+ end
559
+
560
+ def templates
561
+ return enum_for(:templates) unless block_given?
562
+
563
+ templates_path.children.each do |template|
564
+ yield template if template.file?
565
+ end
566
+ end
567
+
568
+ # Set Autocad Files.TemplateDwgPath
569
+ # @rbs path: Pathname, String the location on disk for Autocad templates
570
+ def template_path=(path)
571
+ ole_preferences_files.TemplateDwgPath = path.to_s
572
+ end
573
+
574
+ # @rbs return [Array<Pathname>] all paths in Files.SupportPath
575
+ def support_paths
576
+ ole_preferences_files.SupportPath.split(";").map { |f| Pathname.new(f) }
577
+ end
578
+
579
+ # @rbs return [Array<Pathname>] all paths in Files.PrinterConfigPath
580
+ def printer_config_paths
581
+ ole_preferences_files.PrinterConfigPath.split(";").map { |f| Pathname.new(f) }
582
+ end
583
+
584
+ # from the printer_config_paths, return all plotcfg files
585
+ # @rbs return [Enumerator[String]]
586
+ def plot_configs
587
+ return enum_for(:plot_configs) unless block_given?
588
+ printer_config_paths.each do |path|
589
+ path.children.each do |plot|
590
+ yield plot.to_s if plot.file?
591
+ end
592
+ end
593
+ end
594
+
595
+ private
596
+
597
+ def ole_preferences_files
598
+ @ole_preferences_files ||= ole_obj.Preferences.Files
599
+ end
600
+
601
+ def send_command(command)
602
+ ole_obj.SendCommand command
603
+ end
604
+
605
+ def init_ole_and_app_event(visible: @visible, event_handler: @event_handler, tries: 5, sleep_duration: 1)
606
+ ole = nil
607
+ begin
608
+ ole = WIN32OLE.connect("Autocad.Application")
609
+ rescue WIN32OLERuntimeError
610
+ ole = WIN32OLE.new("Autocad.Application")
611
+ end
612
+
613
+ sleep(sleep_duration)
614
+ # ole.Visible = visible
615
+ # ole.IsProcessLocked = true
616
+ load_constants(ole)
617
+ app_event = WIN32OLE_EVENT.new(ole)
618
+ app_event.handler = event_handler
619
+ [ole, app_event]
620
+ rescue => e
621
+ tries -= 1
622
+ sleep_duration += 1.5
623
+ puts "Error: #{e}. #{tries} tries left."
624
+ retry if tries.positive?
625
+ raise e, "unable to init ole app"
626
+ end
627
+
628
+ def doc_ole
629
+ ole_obj.ActiveDocument
630
+ end
631
+
632
+ def new_ole_drawing(filename, open: true, wait_time: 500, wait_interval: 0.5)
633
+ ole = ole_obj.Documents.add(filename)
634
+ wait_drawing_opened(wait_time, wait_interval)
635
+ return ole if drawing_opened?
636
+ raise DrawingError.new("New drawing not opened in #{wait_time} seconds", filename)
637
+ end
638
+
639
+ def ole_open_drawing(filename, read_only: false, wait_time: 500, wait_interval: 0.5)
640
+ ole = ole_obj.Documents.Open(filename, read_only)
641
+ wait_drawing_opened(wait_time: wait_time, wait_interval: wait_interval)
642
+ return ole if drawing_opened?
643
+ raise DrawingError.new("drewing not opened in #{wait_time}", path) unless drawing_opened?
644
+ end
645
+
646
+ def wait_drawing_opened(secs, interval = 1)
647
+ elapsed = 0
648
+ while !drawing_opened? && elapsed <= secs
649
+ elapsed += interval
650
+ sleep(interval)
651
+ run_loop
652
+ end
653
+ end
654
+ end
655
+ end
@@ -0,0 +1,29 @@
1
+ require_relative "element"
2
+
3
+ module Autocad
4
+ class Arc < Element
5
+ def length
6
+ @ole_obj.ArcLength
7
+ end
8
+
9
+ def start_point
10
+ Point3d(ole_obj.StartPoint)
11
+ end
12
+
13
+ def end_point
14
+ Point3d(ole_obj.EndPoint)
15
+ end
16
+
17
+ def start_angle
18
+ @ole_obj.StartAngle
19
+ end
20
+
21
+ def end_angle
22
+ @ole_obj.EndAngle
23
+ end
24
+
25
+ def total_angle
26
+ @ole_obj.TotalAngle
27
+ end
28
+ end
29
+ end