Class: Microstation::Drawing

Inherits:
Object
  • Object
show all
Includes:
Properties, ScanTrait, TagSetTrait
Defined in:
lib/microstation/dir.rb,
lib/microstation/drawing.rb,
lib/microstation/extensions/faa.rb,
lib/microstation/extensions/faa.rb

Defined Under Namespace

Classes: File, Index, Number

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ScanTrait

#cells_criteria, #graphics_criteria, #lines_criteria, #scan, #scan_cell_with_name, #scan_graphical, #scan_lines, #tags_criteria, #text_criteria

Methods included from TagSetTrait

#create_tagset, #create_tagset!, #find_tagset, #remove_tagset, #reset_tagsets, #tagset_names, #tagsets

Methods included from Properties

#author=, #comments=, #keywords=, #subject=, #title=

Constructor Details

#initialize(app, ole) ⇒ Drawing

Initialize drawing

Parameters:

  • app (<Application>)

    the app instance

  • ole (<WIN32OLIE>)

    the ole object returned from app.ole_obj



29
30
31
32
33
34
35
36
# File 'lib/microstation/drawing.rb', line 29

def initialize(app, ole)
  @app = app
  @ole_obj = ole
  @find_tagset_instances_called = false
  @app.register_handler("ISaveAsEvents_AfterSaveAs") do |*_args|
    @drawing_saved = true
  end
end

Instance Attribute Details

#appObject (readonly)

Returns the value of attribute app.



21
22
23
# File 'lib/microstation/drawing.rb', line 21

def app
  @app
end

Instance Method Details

#active?Boolean

Returns is the drawing active?.

Returns:

  • (Boolean)

    is the drawing active?



47
48
49
# File 'lib/microstation/drawing.rb', line 47

def active?
  ole_obj.IsActive
end

#active_modelObject



198
199
200
201
202
# File 'lib/microstation/drawing.rb', line 198

def active_model
  return nil unless has_active_model?

  Model.new(app, self, app_ole_obj.ActiveModelReference)
end

#add_element(line) ⇒ Object



427
428
429
# File 'lib/microstation/drawing.rb', line 427

def add_element(line)
  active_model.add_element(line)
end

#basenamePathname

Returns the name as Pathname.

Returns:



239
240
241
# File 'lib/microstation/drawing.rb', line 239

def basename
  Pathname(name)
end

#cad_input_queue {|Microstation::CadInputQueue| ... } ⇒ Object

the block

Yields:



53
54
55
# File 'lib/microstation/drawing.rb', line 53

def cad_input_queue(&block)
  @app.cad_input_queue(&block)
end

#change_model(name) ⇒ Model? Also known as: activate_model

activate the model with name param name [String] name the name of the model activate the model found and return the model

Returns:



368
369
370
371
372
373
374
# File 'lib/microstation/drawing.rb', line 368

def change_model(name)
  model = find_model(name)

  return unless model

  model.activate
end

#change_text_suffix(reg, offset) ⇒ Object



360
361
362
# File 'lib/microstation/drawing.rb', line 360

def change_text_suffix(reg, offset)
  active_model.change_text_suffix(reg, offset)
end

#closeObject

Close the drawing



262
263
264
265
266
267
268
269
270
# File 'lib/microstation/drawing.rb', line 262

def close
  @drawing_closed = true
  begin
    ole_obj.Close
  rescue
    nil
  end
  @ole_obj = nil
end

#copy(name: nil, dir: nil) ⇒ Object

copy the drawing

Parameters:

  • name (String) (defaults to: nil)

    of the file

  • dir (String, Pathname) (defaults to: nil)


60
61
62
63
64
65
66
67
68
69
70
# File 'lib/microstation/drawing.rb', line 60

def copy(name: nil, dir: nil)
  if dir.nil?
    lname = name || copy_name
    dir_path = dirname
  else
    lname = name || self.name
    dir_path = Pathname(dir)
  end
  copy_path = dir_path + lname
  FileUtils.copy path.to_s, copy_path.to_s, verbose: true
end

#create_line(p1, p2, el = nil) ⇒ Object



602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
# File 'lib/microstation/drawing.rb', line 602

def create_line(p1, p2, el = nil)
  #  el = find_line_element
  pt1, pt2 = [p1, p2].map { |p| to_ole_point3d(p) }
  el ||= WIN32OLE_VARIANT::Nothing
  el = el.ole_obj if el.respond_to? :ole_obj
  begin
    ole = app.ole_obj.CreateLineElement2(el, pt1, pt2)
    return nil unless ole

    app.wrap(ole)
  rescue Exception => e
    puts e.message bb
    puts "class: #{el.class}"
    nil
  end
end

#create_scanner(name, &block) ⇒ Object



431
432
433
# File 'lib/microstation/drawing.rb', line 431

def create_scanner(name, &block)
  app.create_scanner(name, &block)
end

#create_tagset_instance_from_tagset_hash(h) ⇒ Object



470
471
472
473
# File 'lib/microstation/drawing.rb', line 470

def create_tagset_instance_from_tagset_hash(h)
  ts = tagsets[h[:name]]
  ts.create_instance(h[:base_element_id], h[:tags], h[:model])
end

#create_tagset_instances(ts_name: nil, base_element_id: nil) ⇒ Object



452
453
454
455
456
457
458
459
# File 'lib/microstation/drawing.rb', line 452

def create_tagset_instances(ts_name: nil, base_element_id: nil)
  result = []
  @find_tagset_instances_called = true
  get_tagsets_in_drawing_hash(ts_name: ts_name, base_element_id: base_element_id) do |h|
    result << create_tagset_instance_from_tagset_hash(h)
  end
  result
end

#create_tagset_instances_bakObject

used



436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
# File 'lib/microstation/drawing.rb', line 436

def create_tagset_instances_bak
  result = []
  @find_tagset_instances_called = true
  filtered = if block_given?
    get_tagsets_in_drawing_hash.select(&filter)
  else
    get_tagsets_in_drawing_hash
  end
  binding.pry
  filtered.map do |h|
    element_id = h[:base_element_id]
    result << tagset.create_instance(element_id, h[:tags], h[model])
  end
  result
end

#default_model_referenceModel

Returns the ole.DefaultModelReference.

Returns:

  • (Model)

    the ole.DefaultModelReference



194
195
196
# File 'lib/microstation/drawing.rb', line 194

def default_model_reference
  Model.new(app, self, ole_obj.DefaultModelReference)
end

#dimensionsObject

alias_method :keywords , :keywords=x



215
216
217
# File 'lib/microstation/drawing.rb', line 215

def dimensions
  eval_cexpression("tcb->ndices")
end

#dirnamePathname

Returns the directory of the file.

Returns:

  • (Pathname)

    the directory of the file



244
245
246
# File 'lib/microstation/drawing.rb', line 244

def dirname
  Pathname(ole_obj.Path).expand_path
end

#drawing_closed?Boolean

Returns:

  • (Boolean)


272
273
274
# File 'lib/microstation/drawing.rb', line 272

def drawing_closed?
  @drawing_closed
end

#each_model {|Model| ... } ⇒ Object

iterate through each model in the drawing and yield them

Yields:



297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/microstation/drawing.rb', line 297

def each_model
  result = []
  ole_obj.Models.each do |el|
    model = model_from_ole(el)
    if block_given?
      yield model
    else
      result << model
    end
  end
  result unless block_given?
end

#eval_cexpression(string) ⇒ Object



257
258
259
# File 'lib/microstation/drawing.rb', line 257

def eval_cexpression(string)
  app.eval_cexpression(string)
end

#find_by_id(id) ⇒ Object

Iterates through all the models and finds the ole_el with id

Parameters:

  • -id (String)

Returns:

  • Element



394
395
396
397
398
399
400
# File 'lib/microstation/drawing.rb', line 394

def find_by_id(id)
  models.each do |model|
    el = model.find_by_id(id)
    return el if el
  end
  nil
end

#find_line_elementObject



590
591
592
593
594
595
596
# File 'lib/microstation/drawing.rb', line 590

def find_line_element
  line = nil
  scan_lines do |el|
    line = el if el.microstation_type == MSD::MsdElementTypeLine
  end
  line
end

#find_model(name) ⇒ Model?

Find the model in the drawing

Parameters:

  • name (String)
    • the name of the model

Returns:

  • (Model, nil)

    the model or nil if not found



329
330
331
332
333
334
335
# File 'lib/microstation/drawing.rb', line 329

def find_model(name)
  ole = ole_obj.Models(name)
  model_from_ole(ole)
rescue
  puts "model #{name} not found"
  nil
end

#find_tagset_instance_by_name(name) ⇒ Object



493
494
495
# File 'lib/microstation/drawing.rb', line 493

def find_tagset_instance_by_name(name)
  create_tagset_instances(ts_name: name).first
end

#find_tagset_instance_by_name_and_id(name, id) ⇒ Object



497
498
499
# File 'lib/microstation/drawing.rb', line 497

def find_tagset_instance_by_name_and_id(name, id)
  create_tagset_instances(ts_name: name, base_element_id: id).first
end

#find_tagset_instance_from_hash(ti_array, h_local) ⇒ Object



538
539
540
541
542
543
544
545
546
547
# File 'lib/microstation/drawing.rb', line 538

def find_tagset_instance_from_hash(ti_array, h_local)
  id = h_local.fetch("microstation_id", :not_found)
  if id == :not_found || id.nil?
    name = ti_array.first.name

    raise MultipleUpdateError,
      "found #{ti_array.size} instances for tagset #{name}; Need a microstation_id for hash"
  end
  ts = ti_array.find { |ti| ti.microstation_id == id }
end

#find_tagset_instances_called?Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/microstation/drawing.rb', line 38

def find_tagset_instances_called?
  @find_tagset_instances_called
end

#find_tagsetsObject



501
502
503
504
505
506
507
508
509
510
511
512
513
# File 'lib/microstation/drawing.rb', line 501

def find_tagsets
  results = []
  each_model do |m|
    m.find_tagsets.each do |ts|
      if block_given?
        yield ts
      else
        results << ts
      end
    end
  end
  return results unless block_given?
end

#get_matching_text(re, &block) ⇒ Object



356
357
358
# File 'lib/microstation/drawing.rb', line 356

def get_matching_text(re, &block)
  active_model.get_matching_text(re, &block)
end

#get_selected_elementsObject



346
347
348
349
350
# File 'lib/microstation/drawing.rb', line 346

def get_selected_elements
  return [] unless has_active_model?

  active_model.get_selected_elements
end

#get_selected_textObject



352
353
354
# File 'lib/microstation/drawing.rb', line 352

def get_selected_text
  active_model.get_selected_text
end

#get_tagsets_in_drawing_hash(ts_name: nil, base_element_id: nil, &block) ⇒ Object

used



481
482
483
484
485
486
487
# File 'lib/microstation/drawing.rb', line 481

def get_tagsets_in_drawing_hash(ts_name: nil, base_element_id: nil, &block)
  return to_enum(__callee__, ts_name: ts_name, base_element_id: base_element_id) unless block

  each_model do |m|
    m.get_tagsets_in_model_hash(ts_name: ts_name, base_element_id: base_element_id, &block)
  end
end

#get_textObject



156
157
158
159
160
161
162
163
164
165
166
# File 'lib/microstation/drawing.rb', line 156

def get_text
  result = []
  scan_text do |_model, te|
    if block_given?
      yield te.to_s
    else
      result << te.to_s
    end
  end
  result
end

#has_active_model?Boolean

Returns true if drawing has an active model.

Returns:

  • (Boolean)

    true if drawing has an active model



205
206
207
# File 'lib/microstation/drawing.rb', line 205

def has_active_model?
  app_ole_obj.HasActiveModelReference
end

#model_namesArray<String>

Returns the model names

Returns:

  • (Array<String>)

    the names of the models



382
383
384
385
386
387
388
# File 'lib/microstation/drawing.rb', line 382

def model_names
  result = []
  ole_obj.Models.each do |el|
    result << el.name
  end
  result
end

#modelsObject



342
343
344
# File 'lib/microstation/drawing.rb', line 342

def models
  @models ||= each_model
end

#modified_dateDate

Returns date last modified.

Returns:

  • (Date)

    date last modified



210
211
212
# File 'lib/microstation/drawing.rb', line 210

def modified_date
  ole_obj.DateLastSaved
end

#multiple_models?Boolean

Returns true if drawing has more than 1 model.

Returns:

  • (Boolean)

    true if drawing has more than 1 model



338
339
340
# File 'lib/microstation/drawing.rb', line 338

def multiple_models?
  ole_obj.Models.Count > 1
end

#nameString

Returns the name of the drawing.

Returns:

  • (String)

    the name of the drawing



234
235
236
# File 'lib/microstation/drawing.rb', line 234

def name
  ole_obj.Name
end

#new_model(name, template = nil) ⇒ Object

Create a new model

Parameters:

  • name (String)
    • the name of the model

  • template (String) (defaults to: nil)
    • the template to use for the model



313
314
315
316
317
# File 'lib/microstation/drawing.rb', line 313

def new_model(name, template = nil)
  template_ole = template ? template.ole_obj : app.ole_obj.ActiveDesignFile.DefaultModelReference
  el = app.ole_obj.ActiveDesignFile.Models.Add(template_ole, name, "Added ")
  model_from_ole(el).activate
end

#numberObject



10
11
12
13
# File 'lib/microstation/extensions/faa.rb', line 10

def number
  binding.pry
  Drawing::Number.from_string(basename)
end

#ole_objWIN32OLE

returns the internal ole_obj

Returns:



577
578
579
580
581
582
583
584
585
586
587
588
# File 'lib/microstation/drawing.rb', line 577

def ole_obj
  is_ok = true
  begin
    @ole_obj.Name
  rescue => e
    is_ok = false
  end

  binding.pry unless is_ok || drawing_closed?

  @ole_obj
end

#pathPathname

Returns the complete path of file.

Returns:

  • (Pathname)

    the complete path of file



249
250
251
# File 'lib/microstation/drawing.rb', line 249

def path
  dirname + basename
end

#pdf_driverObject



286
287
288
# File 'lib/microstation/drawing.rb', line 286

def pdf_driver
  app.windows_path((::Microstation.plot_driver_directory + "pdf-bw.plt").to_s)
end

#pdf_name(name = nil) ⇒ Object

Return the pdf name for the drawing.

If a name is provided use the name provided otherwise use the drawing name

Parameters:

  • name (String, nil) (defaults to: nil)

    @return a Pathname from the name or drawing name



281
282
283
284
# File 'lib/microstation/drawing.rb', line 281

def pdf_name(name = nil)
  name ||= self.name
  Pathname(name).sub_ext(".pdf")
end

#pen_tableObject



290
291
292
# File 'lib/microstation/drawing.rb', line 290

def pen_table
  app.windows_path((::Microstation.plot_driver_directory + "wmbw.tbl"))
end

#read_only?Boolean

Returns is the drawing readonly?.

Returns:

  • (Boolean)

    is the drawing readonly?



121
122
123
# File 'lib/microstation/drawing.rb', line 121

def read_only?
  active_model_reference.IsReadOnly
end

#reset_tagset_instancesObject



42
43
44
# File 'lib/microstation/drawing.rb', line 42

def reset_tagset_instances
  @find_tagset_instances_called = false
end

#revision_countObject



253
254
255
# File 'lib/microstation/drawing.rb', line 253

def revision_count
  ole_obj.DesignRevisionCount
end

#savevoid

This method returns an undefined value.

Save the drawing



423
424
425
# File 'lib/microstation/drawing.rb', line 423

def save
  ole_obj.Save
end

#save_as(name, overwrite: false, format: 0) ⇒ void

This method returns an undefined value.

Save the drawing under a different name

Parameters:

  • name (String, Pathname)

    name to change to

  • overwrite (Boolean) (defaults to: false)
    • whether to overwrite if file exists

  • format (<Type>) (defaults to: 0)

    <description>



98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/microstation/drawing.rb', line 98

def save_as(name, overwrite: false, format: 0)
  @drawing_saved = false
  path = Pathname(name).expand_path
  wpath = app.windows_path(name)
  begin
    ole_obj.SaveAs(wpath, overwrite, format)
    wait_save_event(10)
    raise "drawing not saved in 10 seconds" unless @drawing_saved
  rescue => e
    binding.pry
  end
end

#save_as_pdf(name: nil, dir: nil) ⇒ void

This method returns an undefined value.

save the drawing as a pdf file if the name or directory is given it uses those params. If not it uses the drawing name and the drawing directory

Parameters:

  • name (defaults to: nil)
    • the name of the file

  • dir (defaults to: nil)
    • the directory to save the drawing



79
80
81
82
83
84
85
86
87
# File 'lib/microstation/drawing.rb', line 79

def save_as_pdf(name: nil, dir: nil)
  out_name = pdf_path(name: name, dir: dir)
  windows_name = app.windows_path(out_name)
  loop do
    print_pdf(windows_name)
    break if out_name.file?
  end
  puts "saved #{windows_name}"
end

#save_tagsets_to_file(name) ⇒ Object



475
476
477
478
# File 'lib/microstation/drawing.rb', line 475

def save_tagsets_to_file(name)
  require "json"
  ::File.write(name, get_tagsets_in_drawing_hash.to_a.to_json)
end

#scan_all(criteria) ⇒ Object

scans all the drawing models with criteria calls scan_all_with_block calls scal_all_with_hash

Parameters:



142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/microstation/drawing.rb', line 142

def scan_all(criteria)
  return to_enum(__callee__, criteria) unless block_given?
  result = [] if block_given?
  each_model do |m|
    m.scan_model(criteria) do |r|
      if block_given?
        yield m, r
      else
        result << [m, r]
      end
    end
  end
end

#scan_cells {|Model, Cell| ... } ⇒ Object

scan all cells in drawing and

Yields:



183
184
185
# File 'lib/microstation/drawing.rb', line 183

def scan_cells(&block)
  scan_all(cells_criteria, &block)
end

#scan_model(criteria, model: default_model_reference) { ... } ⇒ Object

Scan the drawing. It takes a criteria and an optional model scan the drawing

Parameters:

Yields:



131
132
133
134
135
# File 'lib/microstation/drawing.rb', line 131

def scan_model(criteria, model: default_model_reference, &block)
  criteria ||= create_scan_criteria
  model ||= default_model_reference
  model.scan_model(criteria, &block)
end

#scan_tags {|Model, Tag| ... } ⇒ Object

scan all tags in drawing and

Yields:



177
178
179
# File 'lib/microstation/drawing.rb', line 177

def scan_tags(&block)
  scan_all(tags_criteria, &block)
end

#scan_text {|Model, String| ... } ⇒ Object

scan all text and text regions in all models

Yields:

  • (Model, String)

    text that is found



171
172
173
# File 'lib/microstation/drawing.rb', line 171

def scan_text(&block)
  scan_all(text_criteria, &block)
end

#scan_text_in_cells(&block) ⇒ Object



187
188
189
190
191
# File 'lib/microstation/drawing.rb', line 187

def scan_text_in_cells(&block)
  scan_cells do |_model, c|
    c.text_elements(&block)
  end
end

#select_tagset_instances_by_name(name) ⇒ Object



489
490
491
# File 'lib/microstation/drawing.rb', line 489

def select_tagset_instances_by_name(name)
  create_tagset_instances(ts_name: name)
end

#tagsets_in_drawingObject



461
462
463
# File 'lib/microstation/drawing.rb', line 461

def tagsets_in_drawing
  @tagset_instances ||= create_tagset_instances
end

#tagsets_in_drawing!Object



465
466
467
468
# File 'lib/microstation/drawing.rb', line 465

def tagsets_in_drawing!
  @tagset_instances = nil
  tagsets_in_drawing
end

#three_d?Boolean

Returns true if a 3d drawing.

Returns:

  • (Boolean)

    true if a 3d drawing



229
230
231
# File 'lib/microstation/drawing.rb', line 229

def three_d?
  dimensions == 3
end

#to_ole_point3d(pt) ⇒ Object



598
599
600
# File 'lib/microstation/drawing.rb', line 598

def to_ole_point3d(pt)
  app.to_ole_point3d(pt)
end

#to_point(pt) ⇒ Object



619
620
621
# File 'lib/microstation/drawing.rb', line 619

def to_point(pt)
  app.to_point(pt)
end

#two_d?Boolean

Returns true if a 2d drawing.

Returns:

  • (Boolean)

    true if a 2d drawing



224
225
226
# File 'lib/microstation/drawing.rb', line 224

def two_d?
  dimensions == 2
end

#update_errorObject

Raises:

  • (ArgumentError)


559
560
561
# File 'lib/microstation/drawing.rb', line 559

def update_error
  raise ArgumentError, "Argument must be an array of hashes"
end

#update_tagset(name, h_local = {}) ⇒ Object



515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File 'lib/microstation/drawing.rb', line 515

def update_tagset(name, h_local = {})
  tset_instances = select_tagset_instances_by_name(name)
  case tset_instances.size
  when 0
    raise "no tagset found"
  when 1
    ts = tset_instances.first
    ts.update(h_local)
  else
    if h_local.instance_of?(Array) && h_local.all? { |l| l.instance_of?(Hash) }
      h_local.each do |update_hash|
        ts = find_tagset_instance_from_hash(tset_instances, update_hash)
        ts.update(update_hash)
      end
    elsif h_local.instance_of?(Hash)
      ts = find_tagset_instance_from_hash(tset_instances, h_local)
      ts.update(h_local)
    else
      raise ArgumentError, "don't know how to update tagset"
    end
  end
end

#update_tagsets(ts_arg) ⇒ Object



549
550
551
552
553
554
555
556
557
# File 'lib/microstation/drawing.rb', line 549

def update_tagsets(ts_arg)
  return if ts_arg == []
  return if ts_arg == {}

  ts_array = [ts_arg] if ts_arg.instance_of?(Hash)
  ts_array.each do |hash_pair|
    update_tagset(hash_pair.keys[0], hash_pair.values[0])
  end
end

#update_tagsets_from_template_structure(ts_arg) ⇒ Object



563
564
565
566
567
568
569
570
# File 'lib/microstation/drawing.rb', line 563

def update_tagsets_from_template_structure(ts_arg)
  ts_arg.each do |h|
    inst_array = h["instances"]
    inst_array.each do |ts_hash|
      update_tagset(ts_hash["tagset_name"], ts_hash["attributes"])
    end
  end
end

#wait_save_event(_secs, interval = 0.5) ⇒ Object



111
112
113
114
115
116
117
118
# File 'lib/microstation/drawing.rb', line 111

def wait_save_event(_secs, interval = 0.5)
  elapsed = 0
  while !@drawing_saved && elapsed <= 5
    elapsed += interval
    sleep(interval)
    WIN32OLE_EVENT.message_loop
  end
end

#zoom_to_element(target, n_view) ⇒ Object



402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
# File 'lib/microstation/drawing.rb', line 402

def zoom_to_element(target, n_view)
  return nil unless target.graphical?

  zoom = 4
  range = target.Range
  oview = app_ole_obj.ActiveDesignFile.Views.Item(n_view)
  range_diff = app_ole_obj.Point3dSubtract(range.High, range.Low)
  extent = app_ole_obj.Point3dScale(range_diff, zoom)

  oview_origin = app_ole_obj.Point3dSubtract(range.Low, app_ole_obj.Point3dScale(extent, 0.5))
  oview.Origin = oview_origin
  oview.Extents = extent
  oview.Redraw
  target.IsHighlighted = true
end