microstation 0.4.1 → 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +23 -23
  3. data/.rspec +2 -2
  4. data/Gemfile +29 -10
  5. data/History.txt +6 -6
  6. data/LICENSE.adoc +22 -0
  7. data/Manifest.txt +91 -60
  8. data/README.adoc +131 -0
  9. data/Rakefile +72 -30
  10. data/bin/dgn2pdf +36 -37
  11. data/bin/dgn_template +107 -0
  12. data/bin/pw_print +35 -0
  13. data/cad_files/drawing_faatitle_in_non_default_model.dgn +0 -0
  14. data/cad_files/drawing_no_block.dgn +0 -0
  15. data/cad_files/drawing_with_3_block.dgn +0 -0
  16. data/cad_files/drawing_with_block.dgn +0 -0
  17. data/cad_files/drawing_with_text.dgn +0 -0
  18. data/cad_files/seed2d.dgn +0 -0
  19. data/cad_files/seed3d.dgn +0 -0
  20. data/lib/microstation/app.rb +781 -286
  21. data/lib/microstation/cad_input_queue.rb +100 -25
  22. data/lib/microstation/cell.rb +191 -0
  23. data/lib/microstation/changer.rb +70 -0
  24. data/lib/microstation/configuration.rb +193 -57
  25. data/lib/microstation/criteria_creation_t.rb +23 -0
  26. data/lib/microstation/dir.rb +252 -252
  27. data/lib/microstation/directory.rb +46 -0
  28. data/lib/microstation/drawing.rb +686 -189
  29. data/lib/microstation/element.rb +311 -0
  30. data/lib/microstation/enumerator.rb +32 -29
  31. data/lib/microstation/errors.rb +17 -0
  32. data/lib/microstation/event_handler.rb +28 -0
  33. data/lib/microstation/ext/pathname.rb +23 -25
  34. data/lib/microstation/ext/win32ole.rb +7 -0
  35. data/lib/microstation/extensions/faa.rb +124 -0
  36. data/lib/microstation/file_tests.rb +68 -0
  37. data/lib/microstation/functions.rb +60 -0
  38. data/lib/microstation/graphics.rb +35 -0
  39. data/lib/microstation/line.rb +19 -0
  40. data/lib/microstation/model.rb +45 -0
  41. data/lib/microstation/model_trait.rb +189 -0
  42. data/lib/microstation/ole_cad_input_message.rb +101 -0
  43. data/lib/microstation/ole_helper.rb +152 -0
  44. data/lib/microstation/pdf_support.rb +40 -40
  45. data/lib/microstation/point3d.rb +71 -0
  46. data/lib/microstation/primitive_command_interface.rb +66 -0
  47. data/lib/microstation/properties.rb +61 -57
  48. data/lib/microstation/property_handler.rb +48 -0
  49. data/lib/microstation/scan/color.rb +38 -38
  50. data/lib/microstation/scan/criteria.rb +89 -85
  51. data/lib/microstation/scan/klass.rb +43 -43
  52. data/lib/microstation/scan/level.rb +38 -38
  53. data/lib/microstation/scan/line_style.rb +45 -45
  54. data/lib/microstation/scan/line_weight.rb +33 -33
  55. data/lib/microstation/scan/range.rb +19 -0
  56. data/lib/microstation/scan/scan_trait.rb +51 -0
  57. data/lib/microstation/scan/subtype.rb +40 -40
  58. data/lib/microstation/scan/type.rb +134 -109
  59. data/lib/microstation/scan_trait.rb +62 -0
  60. data/lib/microstation/scanner.rb +24 -24
  61. data/lib/microstation/tag.rb +87 -58
  62. data/lib/microstation/tag_set.rb +385 -280
  63. data/lib/microstation/tag_set_trait.rb +51 -0
  64. data/lib/microstation/tagged_element.rb +105 -0
  65. data/lib/microstation/template.rb +90 -84
  66. data/lib/microstation/template_info.rb +172 -0
  67. data/lib/microstation/template_runner.rb +65 -0
  68. data/lib/microstation/text.rb +79 -54
  69. data/lib/microstation/text_node.rb +124 -74
  70. data/lib/microstation/ts/attribute.rb +140 -139
  71. data/lib/microstation/ts/instance.rb +146 -112
  72. data/lib/microstation/ts/tagset_trait.rb +49 -0
  73. data/lib/microstation/types.rb +91 -91
  74. data/lib/microstation/version.rb +5 -0
  75. data/lib/microstation/wrap.rb +28 -214
  76. data/lib/microstation.rb +252 -88
  77. data/plot/pdf-bw.plt +164 -164
  78. data/plot/pdf.plt +163 -163
  79. data/plot/png.plt +383 -383
  80. data/plot/tiff.plt +384 -384
  81. data/plot/wmbw.tbl +324 -66
  82. data/plot/wmcolor.tbl +62 -62
  83. data/spec/microstation/app_spec.rb +184 -0
  84. data/spec/microstation/configuration_spec.rb +131 -0
  85. data/spec/microstation/drawing_spec.rb +245 -0
  86. data/spec/microstation/functions_spec.rb +36 -0
  87. data/spec/microstation/tag_set_spec.rb +159 -0
  88. data/spec/microstation/template_spec.rb +159 -0
  89. data/spec/microstation/text_node_spec.rb +67 -0
  90. data/spec/microstation/text_spec.rb +42 -0
  91. data/spec/microstation_spec.rb +47 -36
  92. data/spec/spec_helper.rb +97 -31
  93. metadata +308 -84
  94. data/.gemtest +0 -0
  95. data/README.txt +0 -75
  96. data/lib/microstation/attributes.rb +0 -35
  97. data/lib/microstation/extensions/hash.rb +0 -27
  98. data/spec/app_spec.rb +0 -267
  99. data/spec/configuration_spec.rb +0 -122
  100. data/spec/drawing_spec.rb +0 -247
  101. data/spec/drawings/new_drawing.dgn +0 -0
  102. data/spec/drawings/test.dgn +0 -0
  103. data/spec/drawings/test1.dgn +0 -0
  104. data/spec/drawings/testfile.pdf +0 -0
  105. data/spec/enumerator_spec.rb +0 -60
  106. data/spec/scanner_spec.rb +0 -155
  107. data/spec/spec_app.rb +0 -11
  108. data/spec/tag_set_spec.rb +0 -123
  109. data/spec/text_node_spec.rb +0 -92
  110. data/spec/text_spec.rb +0 -62
@@ -1,189 +1,686 @@
1
- require_relative 'properties'
2
- require 'pry'
3
- module Microstation
4
-
5
- class Drawing
6
-
7
- include Properties
8
-
9
- attr_reader :app
10
-
11
- def initialize(app, ole)
12
- @app = app
13
- @ole_obj = ole
14
- end
15
-
16
- def active?
17
- @ole_obj.IsActive
18
- end
19
-
20
- def cad_input_queue(&block)
21
- @app.cad_input_queue(&block)
22
- end
23
-
24
- def save_as_pdf(name = nil, dir = nil)
25
- out_name = pdf_name(name,dir)
26
- windows_name = app.windows_path(out_name)
27
- cad_input_queue do |q|
28
- q << "Print Driver #{pdf_driver}"
29
- q << "Print Papername ANSI D"
30
- q << "Print BOUNDARY FIT ALL"
31
- q << "Print ATTRIBUTES BORDER OUTLINE OFF"
32
- q << "Print Attributes Fenceboundary Off"
33
- q << "Print Execute #{windows_name}"
34
- end
35
- puts "saved #{windows_name}"
36
- end
37
-
38
- def pdf_name_from_options(options = {})
39
- name = options.fetch(:name){ basename.ext('.pdf')}
40
- dir = options.fetch(:dir){ dirname}
41
- (dir + name).expand_path
42
- end
43
-
44
- # alias_method :title, :title=
45
-
46
- def create_scanner(&block)
47
- app.create_scanner(&block)
48
- end
49
-
50
- def scan(scanner = nil,&block)
51
- app.scan(scanner,&block)
52
- end
53
-
54
- def scan_graphical(&block)
55
- sc = create_scanner
56
- sc.ExcludeNonGraphical
57
- app.scan(sc,&block)
58
- end
59
-
60
- def scan_text(&block)
61
- sc = create_scanner do
62
- include_textual
63
- end
64
- app.scan(sc,&block)
65
- end
66
-
67
- def scan_tags(&block)
68
- sc = create_scanner do
69
- include_tags
70
- end
71
- app.scan(sc,&block)
72
- end
73
-
74
- def modified_date
75
- @ole_obj.DateLastSaved
76
- end
77
- # alias_method :keywords , :keywords=x
78
-
79
- def dimensions
80
- eval_cexpression("tcb->ndices")
81
- end
82
-
83
- # def fullname
84
- # @ole_obj.FullName
85
- # end
86
-
87
- def two_d?
88
- dimensions == 2
89
- end
90
-
91
- def three_d?
92
- dimensions == 3
93
- end
94
-
95
- def name
96
- @ole_obj.Name
97
- end
98
-
99
- def basename
100
- Pathname(name)
101
- end
102
-
103
- def dirname
104
- Pathname(@ole_obj.Path).expand_path
105
- end
106
-
107
- def path
108
- dirname + basename
109
- end
110
-
111
- def revision_count
112
- @ole_obj.DesignRevisionCount
113
- end
114
-
115
- def eval_cexpression(string)
116
- app.eval_cexpression(string)
117
- end
118
-
119
- def close
120
- @ole_obj.Close
121
- end
122
-
123
- def ole_obj
124
- @ole_obj
125
- end
126
-
127
- def pdf_name(lname = nil,dir=nil)
128
- dname = lname ? Pathname(lname) : Pathname(self.basename)
129
- pdfname = dname.ext('.pdf')
130
- dirname = dir ? Pathname(dir) : Pathname(self.dirname)
131
- pdfname = (dirname + pdfname).expand_path
132
- end
133
-
134
- def pdf_driver
135
- app.windows_path( (Microstation.plot_driver_directory + "pdf-bw.plt").to_s)
136
- end
137
-
138
- def tagset_names
139
- tagsets.map{|ts| ts.name}
140
- end
141
-
142
- def tagsets
143
- @tagsets = TagSets.new(ole_obj_tagsets)
144
- end
145
-
146
- def create_tagset(name,&block)
147
- ts = tagsets.create(name)
148
- block.call ts if block
149
- ts
150
- end
151
-
152
- def create_tagset!(name,&block)
153
- remove_tagset(name)
154
- create_tagset(name,&block)
155
- end
156
-
157
- def remove_tagset(name)
158
- tagsets.remove(name)
159
- end
160
-
161
- def find_tagset(name)
162
- ts = tagsets[name]
163
- ts.create_instances(scan_tags)
164
- end
165
-
166
- protected
167
- def ole_obj_tagsets
168
- @ole_obj.TagSets
169
- end
170
-
171
- def ensure_tags(tags)
172
- tags.map{|t| t.class == WIN32OLE ? app.wrap(t) : t }
173
- end
174
-
175
- # def create_tagset_instances(name,groups)
176
- # ts = tagsets[name]
177
- # ts.add_instance(group) if ts
178
- # end
179
-
180
- def save
181
- @ole_obj.Save
182
- end
183
-
184
-
185
-
186
-
187
- end
188
-
189
- end
1
+ require_relative 'properties'
2
+ require_relative 'tag_set_trait'
3
+ require_relative 'model'
4
+ require_relative 'errors'
5
+ require_relative 'scan_trait'
6
+ require 'liquid'
7
+ # /
8
+ # // MessageId: DISP_E_PARAMNOTFOUND
9
+ # //
10
+ # // MessageText:
11
+ # //
12
+ # // Parameter not found.
13
+ # //
14
+ # ##define DISP_E_PARAMNOTFOUND _HRESULT_TYPEDEF_(0x80020004L)
15
+ module Microstation
16
+ class Drawing
17
+ include Properties
18
+ include TagSetTrait
19
+ include ScanTrait
20
+
21
+ attr_reader :app
22
+
23
+ #
24
+ # Initialize drawing
25
+ #
26
+ # @param app [<Application>] the app instance
27
+ # @param ole [<WIN32OLIE>] the ole object returned from app.ole_obj
28
+ #
29
+ def initialize(app, ole)
30
+ @app = app
31
+ @ole_obj = ole
32
+ @find_tagset_instances_called = false
33
+ @app.register_handler('ISaveAsEvents_AfterSaveAs') do |*args|
34
+ @drawing_saved = true
35
+ end
36
+ end
37
+
38
+ def find_tagset_instances_called?
39
+ @find_tagset_instances_called
40
+ end
41
+
42
+ def reset_tagset_instances
43
+ @find_tagset_instances_called = false
44
+ end
45
+
46
+ # @return [Boolean] is the drawing active?
47
+ def active?
48
+ ole_obj.IsActive
49
+ end
50
+
51
+ # @yield [Microstation::CadInputQueue] yields a cad_input_queue to
52
+ # the block
53
+ def cad_input_queue(&block)
54
+ @app.cad_input_queue(&block)
55
+ end
56
+
57
+ # copy the drawing
58
+ # @param [String] name of the file
59
+ # @param [String,Pathname] dir
60
+ def copy(name: nil, dir: nil)
61
+ if dir.nil?
62
+ lname = name || copy_name
63
+ dir_path = self.dirname
64
+ else
65
+ lname = name || self.name
66
+ dir_path = Pathname(dir)
67
+ end
68
+ copy_path = dir_path + lname
69
+ FileUtils.copy self.path.to_s, copy_path.to_s, verbose: true
70
+ end
71
+
72
+ # save the drawing as a pdf file
73
+ # if the name or directory is given it uses
74
+ # those params. If not it uses the drawing name
75
+ # and the drawing directory
76
+ # @param name - the name of the file
77
+ # @param dir - the directory to save the drawing
78
+ # @return [void]
79
+ def save_as_pdf(name: nil, dir: nil)
80
+ out_name = pdf_path(name: name, dir: dir)
81
+ windows_name = app.windows_path(out_name)
82
+ loop do
83
+ print_pdf(windows_name)
84
+ break if out_name.file?
85
+ end
86
+ puts "saved #{windows_name}"
87
+ end
88
+
89
+ #
90
+ # Save the drawing under a different name
91
+ #
92
+ # @param [String,Pathname] name name to change to
93
+ # @param [Boolean] overwrite - whether to overwrite if file exists
94
+ # @param [<Type>] format <description>
95
+ #
96
+ # @return [void]
97
+ #
98
+ def save_as(name, overwrite: false, format: 0)
99
+ @drawing_saved = false
100
+ path = Pathname(name).expand_path
101
+ wpath = app.windows_path(name)
102
+ begin
103
+ ole_obj.SaveAs(wpath, overwrite, format)
104
+ wait_save_event(10)
105
+ raise "drawing not saved in 10 seconds" unless @drawing_saved
106
+ rescue => e
107
+ binding.pry
108
+ end
109
+ end
110
+
111
+ def wait_save_event(secs, interval = 0.5)
112
+ elapsed = 0
113
+ while (!@drawing_saved && elapsed <= 5)
114
+ elapsed += interval
115
+ sleep(interval)
116
+ WIN32OLE_EVENT.message_loop
117
+ end
118
+ end
119
+
120
+ # @return [Boolean] is the drawing readonly?
121
+ def read_only?
122
+ active_model_reference.IsReadOnly
123
+ end
124
+
125
+ # Scan the drawing. It takes a criteria and an optional model
126
+ # scan the drawing
127
+ # @param [Scan::Criteria] criteria - the criteria
128
+ # @param [Model]
129
+ # @criteria [Scan::Criteria]
130
+ # @yield
131
+ def scan_model(criteria, model: default_model_reference, &block)
132
+ criteria = criteria || create_scan_criteria
133
+ model = model || default_model_reference
134
+ model.scan_model(criteria, &block)
135
+ end
136
+
137
+ # scans all the drawing models with criteria
138
+ # @param [Scan::Criteria] criteria
139
+ #
140
+ # calls scan_all_with_block
141
+ # calls scal_all_with_hash
142
+ def scan_all(criteria,&block)
143
+ return to_enum(__callee__, criteria) unless block_given?
144
+ each_model do |m|
145
+ m.scan_model(criteria) do |r|
146
+ if block_given?
147
+ yield r
148
+ else
149
+ result << r
150
+ end
151
+ end
152
+
153
+ end
154
+ end
155
+
156
+ def get_text(&block)
157
+ result = []
158
+ scan_text do |te|
159
+ if block_given?
160
+ yield te.to_s
161
+ else
162
+ result << te.to_s
163
+ end
164
+ end
165
+ result
166
+ end
167
+
168
+ # scan all text and text regions in all
169
+ # models
170
+ # @yield [String] text that is found
171
+ def scan_text(&block)
172
+ scan_all(text_criteria, &block)
173
+ end
174
+
175
+ # scan all tags in drawing and
176
+ # @yield [Tag] to the block
177
+ def scan_tags(&block)
178
+ scan_all(tags_criteria, &block)
179
+ end
180
+
181
+ # scan all cells in drawing and
182
+ # @yield [Cell] to the block
183
+ def scan_cells(&block)
184
+ scan_all(cells_criteria, &block)
185
+ end
186
+
187
+ def scan_text_in_cells(&block)
188
+ scan_cells do |c|
189
+ c.text_elements(&block)
190
+ end
191
+ end
192
+
193
+ # @return [Model] the ole.DefaultModelReference
194
+ def default_model_reference
195
+ Model.new(app, self, ole_obj.DefaultModelReference)
196
+ end
197
+
198
+ def active_model
199
+ return nil unless has_active_model?
200
+
201
+ Model.new(app, self, app_ole_obj.ActiveModelReference)
202
+ end
203
+
204
+ # @return [Boolean] true if drawing has an active model
205
+ def has_active_model?
206
+ app_ole_obj.HasActiveModelReference
207
+ end
208
+
209
+ # @return [Date] date last modified
210
+ def modified_date
211
+ ole_obj.DateLastSaved
212
+ end
213
+ # alias_method :keywords , :keywords=x
214
+
215
+ def dimensions
216
+ eval_cexpression("tcb->ndices")
217
+ end
218
+
219
+ # def fullname
220
+ # ole_obj.FullName
221
+ # end
222
+
223
+ # @return [Boolean] true if a 2d drawing
224
+ def two_d?
225
+ dimensions == 2
226
+ end
227
+
228
+ # @return [Boolean] true if a 3d drawing
229
+ def three_d?
230
+ dimensions == 3
231
+ end
232
+
233
+ # @return [String] the name of the drawing
234
+ def name
235
+ ole_obj.Name
236
+ end
237
+
238
+ # @return [Pathname] the name as Pathname
239
+ def basename
240
+ Pathname(name)
241
+ end
242
+
243
+ # @return [Pathname] the directory of the file
244
+ def dirname
245
+ Pathname(ole_obj.Path).expand_path
246
+ end
247
+
248
+ # @return [Pathname] the complete path of file
249
+ def path
250
+ dirname + basename
251
+ end
252
+
253
+ def revision_count
254
+ ole_obj.DesignRevisionCount
255
+ end
256
+
257
+ def eval_cexpression(string)
258
+ app.eval_cexpression(string)
259
+ end
260
+
261
+ def close
262
+ @drawing_closed = true
263
+ ole_obj.Close rescue nil
264
+ @ole_obj = nil
265
+ end
266
+
267
+ def drawing_closed?
268
+ @drawing_closed
269
+ end
270
+
271
+ def pdf_name(name = nil)
272
+ name = self.name unless name
273
+ return Pathname(name).sub_ext(".pdf")
274
+ end
275
+
276
+ def pdf_driver
277
+ app.windows_path( (::Microstation.plot_driver_directory + "pdf-bw.plt").to_s)
278
+ end
279
+
280
+ def pen_table
281
+ app.windows_path( (::Microstation.plot_driver_directory + 'wmbw.tbl'))
282
+ end
283
+
284
+ # iterate through each model in the drawing
285
+ # and yield them
286
+ # @yield [Model] model
287
+ def each_model
288
+ result = []
289
+ ole_obj.Models.each do |el|
290
+ model = model_from_ole(el)
291
+ if block_given?
292
+ yield model
293
+ else
294
+ result << model
295
+ end
296
+ end
297
+ result unless block_given?
298
+ end
299
+
300
+ # Create a new model
301
+ # @param [String] name - the name of the model
302
+ # @param [String] template - the template to use for the model
303
+ def new_model(name,template = nil)
304
+ template_ole = template ? template.ole_obj : app.ole_obj.ActiveDesignFile.DefaultModelReference
305
+ el = app.ole_obj.ActiveDesignFile.Models.Add(template_ole,name,"Added ")
306
+ m = model_from_ole(el).activate
307
+ m
308
+ end
309
+
310
+ # Active a model
311
+ # @param name [String] a
312
+ def activate_model(name)
313
+ model = find_model(name)
314
+ model.activate if model
315
+ end
316
+
317
+ # Find the model in the drawing
318
+ # @param [String] name - the name of the model
319
+ # @return [Model, nil] the model or nil if not found
320
+ def find_model(name)
321
+ ole = ole_obj.Models(name)
322
+ model_from_ole(ole)
323
+ rescue
324
+ puts "model #{name} not found"
325
+ nil
326
+ end
327
+
328
+ # @return [Boolean] true if drawing has more than 1 model
329
+ def multiple_models?
330
+ ole_obj.Models.Count > 1
331
+ end
332
+
333
+ def models
334
+ @models ||= each_model
335
+ end
336
+
337
+ def get_selected_elements
338
+ return [] unless has_active_model?
339
+ active_model.get_selected_elements
340
+ end
341
+
342
+ def get_selected_text
343
+ active_model.get_selected_text
344
+ end
345
+
346
+ def get_matching_text(re,&block)
347
+ active_model.get_matching_text(re,&block)
348
+ end
349
+
350
+ def change_text_suffix(reg,offset)
351
+ active_model.change_text_suffix(reg,offset)
352
+ end
353
+
354
+ # activate the model with name
355
+ # param name [String] name the name of the model
356
+ # activate the model found and return the model
357
+ # @return [Model, nil]
358
+ def change_model(name)
359
+ model = find_model(name)
360
+
361
+ return unless model
362
+ model.activate
363
+ end
364
+
365
+ alias :activate_model :change_model
366
+
367
+ #
368
+ # Returns the model names
369
+ #
370
+ # @return [Array<String>] the names of the models
371
+ def model_names
372
+ result = []
373
+ ole_obj.Models.each do |el|
374
+ result << el.name
375
+ end
376
+ result
377
+ end
378
+
379
+ # Iterates through all the models and finds the
380
+ # ole_el with id
381
+ # @param [String] -id
382
+ # @return Element
383
+ def find_by_id(id)
384
+ models.each do |model|
385
+ el = model.find_by_id(id)
386
+ return el if el
387
+ end
388
+ nil
389
+ end
390
+
391
+ def zoom_to_element(target, n_view)
392
+ return nil unless target.graphical?
393
+
394
+ zoom = 4
395
+ range = target.Range
396
+ oview = app_ole_obj.ActiveDesignFile.Views.Item(n_view)
397
+ range_diff = app_ole_obj.Point3dSubtract(range.High, range.Low)
398
+ extent = app_ole_obj.Point3dScale(range_diff, zoom)
399
+
400
+ oview_origin = app_ole_obj.Point3dSubtract(range.Low, app_ole_obj.Point3dScale(extent,0.5))
401
+ oview.Origin = oview_origin
402
+ oview.Extents = extent
403
+ oview.Redraw
404
+ target.IsHighlighted = true
405
+ end
406
+
407
+ #
408
+ # Save the drawing
409
+ #
410
+ # @return [void]
411
+ #
412
+ def save
413
+ ole_obj.Save
414
+ end
415
+
416
+ def add_element(line)
417
+ active_model.add_element(line)
418
+ end
419
+
420
+ def create_scanner(name,&block)
421
+ app.create_scanner(name,&block)
422
+ end
423
+
424
+ # used
425
+ def create_tagset_instances_bak()
426
+ result = []
427
+ @find_tagset_instances_called = true
428
+ filtered = if block_given?
429
+ get_tagsets_in_drawing_hash.select(&filter)
430
+ else
431
+ get_tagsets_in_drawing_hash
432
+ end
433
+ binding.pry
434
+ filtered.map do |h|
435
+ element_id = h[:base_element_id]
436
+ result << tagset.create_instance(element_id, h[:tags], h[model])
437
+ end
438
+ result
439
+ end
440
+
441
+ def create_tagset_instances(ts_name: nil, base_element_id: nil)
442
+ result = []
443
+ @find_tagset_instances_called = true
444
+ get_tagsets_in_drawing_hash(ts_name: ts_name, base_element_id: base_element_id) do |h|
445
+ result << create_tagset_instance_from_tagset_hash(h)
446
+ end
447
+ result
448
+ end
449
+
450
+ def tagsets_in_drawing
451
+ @tagset_instances ||= create_tagset_instances
452
+ end
453
+
454
+ def tagsets_in_drawing!
455
+ @tagset_instances = nil
456
+ tagsets_in_drawing
457
+ end
458
+
459
+ def create_tagset_instance_from_tagset_hash(h)
460
+ ts = tagsets[h[:name]]
461
+ ts.create_instance( h[:base_element_id], h[:tags], h[:model])
462
+ end
463
+
464
+ def save_tagsets_to_file(name)
465
+ require 'json'
466
+ ::File.open(name, 'w'){ |f| f.write get_tagsets_in_drawing_hash.to_a.to_json }
467
+ end
468
+
469
+ #used
470
+ def get_tagsets_in_drawing_hash(ts_name: nil, base_element_id: nil)
471
+ return to_enum(__callee__, ts_name: ts_name, base_element_id: base_element_id) unless block_given?
472
+ each_model do |m|
473
+ m.get_tagsets_in_model_hash(ts_name: ts_name, base_element_id: base_element_id) do |tsi|
474
+ yield tsi
475
+ end
476
+ end
477
+ end
478
+
479
+ def select_tagset_instances_by_name(name)
480
+ create_tagset_instances(ts_name: name)
481
+ end
482
+
483
+ def find_tagset_instance_by_name(name)
484
+ create_tagset_instances(ts_name: name).first
485
+ end
486
+
487
+ def find_tagset_instance_by_name_and_id(name,id)
488
+ create_tagset_instances(ts_name: name, base_element_id: id).first
489
+ end
490
+
491
+ def find_tagsets
492
+ results = []
493
+ each_model do |m|
494
+ m.find_tagsets.each do |ts|
495
+ if block_given?
496
+ yield ts
497
+ else
498
+ results << ts
499
+ end
500
+ end
501
+
502
+ end
503
+ return results unless block_given?
504
+ end
505
+
506
+ def update_tagset(name,h_local={})
507
+ tset_instances = select_tagset_instances_by_name(name)
508
+ case tset_instances.size
509
+ when 0
510
+ raise 'no tagset found'
511
+ when 1
512
+ ts = tset_instances.first
513
+ ts.update(h_local)
514
+ else
515
+ if (h_local.class == Array && h_local.all?{|l| l.class == Hash})
516
+ h_local.each do |update_hash|
517
+ ts = find_tagset_instance_from_hash(tset_instances, update_hash)
518
+ ts.update(update_hash)
519
+ end
520
+ elsif h_local.class == Hash
521
+ ts = find_tagset_instance_from_hash(tset_instances, h_local)
522
+ ts.update(h_local)
523
+ else
524
+ raise ArgumentError, "don't know how to update tagset"
525
+ end
526
+ end
527
+ end
528
+
529
+ def find_tagset_instance_from_hash(ti_array, h_local)
530
+ id = h_local.fetch('microstation_id', :not_found)
531
+ if id == :not_found || id.nil?
532
+ name = ti_array.first.name
533
+
534
+ raise MultipleUpdateError, "found #{ti_array.size} instances for tagset #{name}; Need a microstation_id for hash"
535
+ end
536
+ ts = ti_array.find{|ti| ti.microstation_id == id}
537
+ end
538
+
539
+ def update_tagsets(ts_arg)
540
+ return if ts_arg == []
541
+ return if ts_arg == {}
542
+ ts_array = [ts_arg] if ts_arg.class == Hash
543
+ ts_array.each do |hash_pair|
544
+ update_tagset(hash_pair.keys[0], hash_pair.values[0])
545
+ end
546
+ end
547
+
548
+ def update_error
549
+ raise ArgumentError, 'Argument must be an array of hashes'
550
+ end
551
+
552
+ def update_tagsets_from_template_structure(ts_arg)
553
+ ts_arg.each do |h|
554
+ inst_array = h['instances']
555
+ inst_array.each do |ts_hash|
556
+ update_tagset(ts_hash['tagset_name'], ts_hash['attributes'])
557
+ end
558
+ end
559
+ end
560
+
561
+ #
562
+ # returns the internal ole_obj
563
+ #
564
+ # @return [WIN32OLE]
565
+ #
566
+ def ole_obj
567
+ is_ok = true
568
+ begin
569
+ @ole_obj.Name
570
+ rescue StandardError => e
571
+ is_ok = false
572
+ end
573
+
574
+ unless is_ok || drawing_closed?
575
+ binding.pry
576
+ end
577
+
578
+ @ole_obj
579
+ end
580
+
581
+ def find_line_element
582
+ line = nil
583
+ self.scan_lines do |el|
584
+ line = el if el.microstation_type == MSD::MsdElementTypeLine
585
+ end
586
+ line
587
+ end
588
+
589
+ def to_ole_point3d(pt)
590
+ app.to_ole_point3d(pt)
591
+ end
592
+
593
+ def create_line(p1,p2,el = nil)
594
+ # el = find_line_element
595
+ pt1,pt2 = [p1,p2].map{ |p| to_ole_point3d(p) }
596
+ el = WIN32OLE_VARIANT::Nothing unless el
597
+ el = el.ole_obj if el.respond_to? :ole_obj
598
+ begin
599
+ ole = app.ole_obj.CreateLineElement2(el, pt1,pt2)
600
+ return nil unless ole
601
+ app.wrap(ole)
602
+ rescue Exception => ex
603
+ puts ex.message bb
604
+ puts "class: #{el.class}"
605
+ return nil
606
+ end
607
+ end
608
+
609
+
610
+ def to_point(pt)
611
+ app.to_point(pt)
612
+ end
613
+
614
+
615
+ protected
616
+
617
+ def normalize_update_hash(h)
618
+ h = h.to_h if h.respond_to?(:to_h)
619
+ if h.kind_of? Hash
620
+ h = h.map_keys{|k| k.to_s}
621
+ end
622
+ h
623
+ end
624
+
625
+ def print_pdf(windows_path)
626
+ cad_input_queue do |q|
627
+ q << "Print Driver #{pdf_driver}"
628
+ q << "Print Papername ANSI D"
629
+ q << "Print BOUNDARY FIT ALL"
630
+ q << "Print ATTRIBUTES BORDER OUTLINE OFF"
631
+ q << "Print Attributes Fenceboundary Off"
632
+ q << "Print pentable attach #{pen_table}"
633
+ q << "Print colormode monochrome"
634
+ q << "Print Execute #{windows_path}"
635
+ end
636
+
637
+ end
638
+
639
+ def get_model_for_scan(model = nil)
640
+ model = find_model(model) if model.is_a? String
641
+ model ||= active_model || default_model_reference
642
+ model
643
+ end
644
+
645
+ def model_from_ole(ole)
646
+ Model.new(app,self,ole)
647
+ end
648
+
649
+ def copy_name(backup_str = '.copy')
650
+ lname = self.name.dup
651
+ ext = File.extname(lname)
652
+ name = "#{File.basename(lname, ext)}#{backup_str}#{ext}"
653
+ end
654
+
655
+ def pdf_path(name: nil, dir: nil)
656
+ name = name || self.name
657
+ dir = Pathname(dir || self.dirname).expand_path
658
+ dir.mkpath unless dir.directory?
659
+ dir + pdf_name(name)
660
+ end
661
+
662
+ def ole_line_element_klass
663
+ @line_element ||= ole_classes.find{|c| c.name == '_LineElement'}
664
+ end
665
+
666
+ def ole_element_klass
667
+ @element_class ||= ole_classes.find{|c| c.name == '_Element'}
668
+ end
669
+
670
+ def app_ole_obj
671
+ @app_ole_obj ||= app.ole_obj
672
+ end
673
+
674
+ def typelib
675
+ @typelib ||= app_ole_obj.ole_typelib
676
+ end
677
+
678
+ def ole_classes
679
+ @ole_classes ||= typelib.ole_classes
680
+ end
681
+
682
+
683
+
684
+ end
685
+
686
+ end