microstation 0.4.1 → 0.8.3

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