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.
- checksums.yaml +7 -0
- data/.autotest +23 -23
- data/.rspec +2 -2
- data/Gemfile +28 -10
- data/History.txt +6 -6
- data/LICENSE.adoc +22 -0
- data/Manifest.txt +81 -60
- data/README.adoc +131 -0
- data/Rakefile +71 -30
- data/bin/dgn2pdf +36 -37
- data/bin/dgn_template +107 -0
- data/bin/microstation +231 -0
- data/bin/pw_print +35 -0
- data/cad_files/drawing_faatitle_in_non_default_model.dgn +0 -0
- data/cad_files/drawing_no_block.dgn +0 -0
- data/cad_files/drawing_with_3_block.dgn +0 -0
- data/cad_files/drawing_with_block.dgn +0 -0
- data/cad_files/seed2d.dgn +0 -0
- data/cad_files/test.dgn +0 -0
- data/lib/microstation.rb +252 -88
- data/lib/microstation/app.rb +781 -286
- data/lib/microstation/cad_input_queue.rb +100 -25
- data/lib/microstation/cell.rb +191 -0
- data/lib/microstation/changer.rb +70 -0
- data/lib/microstation/configuration.rb +193 -57
- data/lib/microstation/criteria_creation_t.rb +23 -0
- data/lib/microstation/dir.rb +252 -252
- data/lib/microstation/directory.rb +46 -0
- data/lib/microstation/drawing.rb +690 -189
- data/lib/microstation/element.rb +311 -0
- data/lib/microstation/enumerator.rb +32 -29
- data/lib/microstation/errors.rb +17 -0
- data/lib/microstation/event_handler.rb +28 -0
- data/lib/microstation/ext/pathname.rb +23 -25
- data/lib/microstation/ext/win32ole.rb +7 -0
- data/lib/microstation/extensions/faa.rb +124 -0
- data/lib/microstation/file_tests.rb +68 -0
- data/lib/microstation/functions.rb +60 -0
- data/lib/microstation/graphics.rb +35 -0
- data/lib/microstation/line.rb +19 -0
- data/lib/microstation/model.rb +45 -0
- data/lib/microstation/model_trait.rb +189 -0
- data/lib/microstation/ole_cad_input_message.rb +101 -0
- data/lib/microstation/ole_helper.rb +152 -0
- data/lib/microstation/pdf_support.rb +40 -40
- data/lib/microstation/point3d.rb +71 -0
- data/lib/microstation/primitive_command_interface.rb +66 -0
- data/lib/microstation/properties.rb +61 -57
- data/lib/microstation/property_handler.rb +48 -0
- data/lib/microstation/scan/color.rb +38 -38
- data/lib/microstation/scan/criteria.rb +89 -85
- data/lib/microstation/scan/klass.rb +43 -43
- data/lib/microstation/scan/level.rb +38 -38
- data/lib/microstation/scan/line_style.rb +45 -45
- data/lib/microstation/scan/line_weight.rb +33 -33
- data/lib/microstation/scan/range.rb +19 -0
- data/lib/microstation/scan/scan_trait.rb +51 -0
- data/lib/microstation/scan/subtype.rb +40 -40
- data/lib/microstation/scan/type.rb +134 -109
- data/lib/microstation/scan_trait.rb +62 -0
- data/lib/microstation/scanner.rb +24 -24
- data/lib/microstation/tag.rb +87 -58
- data/lib/microstation/tag_set.rb +385 -280
- data/lib/microstation/tag_set_trait.rb +51 -0
- data/lib/microstation/tagged_element.rb +105 -0
- data/lib/microstation/template.rb +90 -84
- data/lib/microstation/template_info.rb +172 -0
- data/lib/microstation/template_runner.rb +65 -0
- data/lib/microstation/text.rb +79 -54
- data/lib/microstation/text_node.rb +124 -74
- data/lib/microstation/ts/attribute.rb +140 -139
- data/lib/microstation/ts/instance.rb +146 -112
- data/lib/microstation/ts/tagset_trait.rb +49 -0
- data/lib/microstation/types.rb +91 -91
- data/lib/microstation/version.rb +5 -0
- data/lib/microstation/wrap.rb +28 -214
- data/plot/pdf-bw.plt +164 -164
- data/plot/pdf.plt +163 -163
- data/plot/png.plt +383 -383
- data/plot/tiff.plt +384 -384
- data/plot/wmbw.tbl +324 -66
- data/plot/wmcolor.tbl +62 -62
- metadata +301 -86
- data/.gemtest +0 -0
- data/README.txt +0 -75
- data/lib/microstation/attributes.rb +0 -35
- data/lib/microstation/extensions/hash.rb +0 -27
- data/spec/app_spec.rb +0 -267
- data/spec/configuration_spec.rb +0 -122
- data/spec/drawing_spec.rb +0 -247
- data/spec/drawings/new_drawing.dgn +0 -0
- data/spec/drawings/test.dgn +0 -0
- data/spec/drawings/test1.dgn +0 -0
- data/spec/drawings/testfile.pdf +0 -0
- data/spec/enumerator_spec.rb +0 -60
- data/spec/microstation_spec.rb +0 -36
- data/spec/scanner_spec.rb +0 -155
- data/spec/spec_app.rb +0 -11
- data/spec/spec_helper.rb +0 -31
- data/spec/tag_set_spec.rb +0 -123
- data/spec/text_node_spec.rb +0 -92
- data/spec/text_spec.rb +0 -62
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/cad_files/test.dgn
ADDED
|
Binary file
|
data/lib/microstation.rb
CHANGED
|
@@ -1,88 +1,252 @@
|
|
|
1
|
-
require '
|
|
2
|
-
require '
|
|
3
|
-
require 'microstation/
|
|
4
|
-
require 'microstation/
|
|
5
|
-
require 'microstation/
|
|
6
|
-
require 'microstation/
|
|
7
|
-
require 'microstation/
|
|
8
|
-
require 'microstation/
|
|
9
|
-
require 'microstation/
|
|
10
|
-
require 'microstation/
|
|
11
|
-
require 'microstation/
|
|
12
|
-
require 'microstation/
|
|
13
|
-
require 'microstation/
|
|
14
|
-
require 'microstation/
|
|
15
|
-
|
|
16
|
-
require '
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
1
|
+
require 'microstation/version'
|
|
2
|
+
require 'win32ole'
|
|
3
|
+
require 'microstation/file_tests'
|
|
4
|
+
require 'microstation/app'
|
|
5
|
+
require 'microstation/drawing'
|
|
6
|
+
require 'microstation/configuration'
|
|
7
|
+
require 'microstation/ext/pathname'
|
|
8
|
+
require 'microstation/cad_input_queue'
|
|
9
|
+
require 'microstation/scan/criteria'
|
|
10
|
+
require 'microstation/enumerator'
|
|
11
|
+
require 'microstation/line'
|
|
12
|
+
require 'microstation/text'
|
|
13
|
+
require 'microstation/text_node'
|
|
14
|
+
require 'microstation/template'
|
|
15
|
+
require 'microstation/tag_set'
|
|
16
|
+
require 'microstation/cell'
|
|
17
|
+
require 'microstation/tag'
|
|
18
|
+
require 'microstation/dir'
|
|
19
|
+
require 'microstation/ext/win32ole'
|
|
20
|
+
require 'microstation/template_info'
|
|
21
|
+
require 'microstation/template_runner'
|
|
22
|
+
require 'erb'
|
|
23
|
+
|
|
24
|
+
module Microstation
|
|
25
|
+
|
|
26
|
+
ROOT = Pathname(__dir__).parent
|
|
27
|
+
|
|
28
|
+
TEMPLATES_PATH = ROOT + 'templates'
|
|
29
|
+
|
|
30
|
+
class << self
|
|
31
|
+
|
|
32
|
+
def save_as_pdf(d)
|
|
33
|
+
run do |app|
|
|
34
|
+
drawing = app.current_drawing
|
|
35
|
+
drawing.save_as_pdf(dir: d)
|
|
36
|
+
drawing.close
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def default_error_proc
|
|
41
|
+
@default_error_proc ||= ->(e,f){ puts "Couldn't open drawing #{f}" }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def default_drawing_options
|
|
45
|
+
{read_only: true, error_proc: default_error_proc}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def default_error_proc=(p)
|
|
49
|
+
@default_error_proc = p
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def default_app_options
|
|
53
|
+
@default_app_options
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def default_app_options=(opts)
|
|
57
|
+
@default_app_options = opts
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
default_app_options = {visible: false}
|
|
61
|
+
|
|
62
|
+
def root
|
|
63
|
+
ROOT
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def plot_driver_directory
|
|
67
|
+
root + "plot"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def use_template(template,context, options ={} )
|
|
71
|
+
def context.binding
|
|
72
|
+
binding
|
|
73
|
+
end
|
|
74
|
+
options = {readonly: true}
|
|
75
|
+
App.run do |app|
|
|
76
|
+
tmpfile = Tempfile.new('drawing')
|
|
77
|
+
app.new_drawing(tmpfile,template) do |drawing|
|
|
78
|
+
drawing.scan_text do |text|
|
|
79
|
+
compiled_template = ERB.new(text)
|
|
80
|
+
new_text = compiled_template.result(context.binding)
|
|
81
|
+
text = new_text
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
tempfile.read
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# starts an app with drawing, opens a temp
|
|
89
|
+
# copy of the drawing and yields it
|
|
90
|
+
# saves the drawing with with name or output_dir
|
|
91
|
+
# same name
|
|
92
|
+
#
|
|
93
|
+
# @param dgn
|
|
94
|
+
# @yield [Drawing]
|
|
95
|
+
def change_drawing(...)
|
|
96
|
+
App.change_drawing(...)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# gets all dwg and dgn dfiles in a directory
|
|
100
|
+
# @param dir
|
|
101
|
+
def drawings_in_dir(dir)
|
|
102
|
+
dirpath = Pathname.new(dir).expand_path
|
|
103
|
+
drawings = Pathname.glob("#{dirpath}/*.d{gn,wg,xf}")
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def dump_template_info_for_dir(dir, options={})
|
|
107
|
+
drawings = drawings_in_dir(dir)
|
|
108
|
+
raise "no drawings in dir #{dir}" if drawings.empty?
|
|
109
|
+
with_drawings(drawings) do |drawing|
|
|
110
|
+
template = TemplateInfo.new(drawing,options)
|
|
111
|
+
template.dump(dir)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def dump_template_info(dgn, dir: nil, tagset_filter: nil, visible: false)
|
|
116
|
+
drawing = Pathname(dgn).expand_path
|
|
117
|
+
output_dir = dir || drawing.parent
|
|
118
|
+
template = TemplateInfo.new(drawing,tagset_filter: tagset_filter, visible: visible)
|
|
119
|
+
template.dump(output_dir)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# @param dir [String] the directory of drawing [dgn,dwg] to convert
|
|
123
|
+
# @param outdir [String] the output dir for converted pdf files
|
|
124
|
+
def dgn2pdf(dir,outdir = dir)
|
|
125
|
+
drawings = drawings_in_dir(dir)
|
|
126
|
+
with_drawings(drawings) do |drawing|
|
|
127
|
+
drawing.save_as_pdf(name: drawing.name,dir: outdir)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def run_templates_in_dir(...)
|
|
132
|
+
App.run_templates_in_dir(...)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# starts app, opens drawing, and yields
|
|
136
|
+
# the drawing before closing drawing and
|
|
137
|
+
# quitting the app
|
|
138
|
+
def open_drawing(...)
|
|
139
|
+
App.open_drawing(...)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# opens all the drawings in a drawing
|
|
143
|
+
# by calling open drawing
|
|
144
|
+
def with_drawings_in_dir(dir,...)
|
|
145
|
+
drawings = drawings_in_dir(dir)
|
|
146
|
+
with_drawings(drawings,...)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def with_drawings(...)
|
|
151
|
+
App.with_drawings(...)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def scan_text(file,&block)
|
|
155
|
+
App.open_drawing(file) do |d|
|
|
156
|
+
d.scan_text(&block)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def get_text(file, &block)
|
|
161
|
+
App.open_drawing(file) do |d|
|
|
162
|
+
d.get_text(&block)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def get_all_text(file)
|
|
167
|
+
App.open_drawing(file) do |d|
|
|
168
|
+
d.get_all_text
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def save_current_drawing(dir, exit: true)
|
|
173
|
+
if exit
|
|
174
|
+
run do |app|
|
|
175
|
+
drawing = app.current_drawing
|
|
176
|
+
drawing.copy(dir: dir)
|
|
177
|
+
drawing.save_as_pdf(dir: dir)
|
|
178
|
+
drawing.close
|
|
179
|
+
end
|
|
180
|
+
else
|
|
181
|
+
app = App.new
|
|
182
|
+
drawing = app.current_drawing
|
|
183
|
+
drawing.copy(dir: dir)
|
|
184
|
+
drawing.save_as_pdf(dir: dir)
|
|
185
|
+
app
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def save_current_drawing_as_pdf(dir)
|
|
190
|
+
App.run do |app|
|
|
191
|
+
drawing = app.current_drawing
|
|
192
|
+
drawing.save_as_pdf(dir: dir)
|
|
193
|
+
drawing.close
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def run(...)
|
|
198
|
+
App.run(...)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
if $0 == __FILE__
|
|
206
|
+
|
|
207
|
+
require 'pry'
|
|
208
|
+
|
|
209
|
+
app = Microstation::App.new
|
|
210
|
+
require 'microstation/ole_helper'
|
|
211
|
+
|
|
212
|
+
File.open('app_methods.txt','w') do |f|
|
|
213
|
+
f.write app.ole_obj.ole_methods_detail
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
tlib = app.ole_obj.ole_typelib
|
|
217
|
+
File.open('microstation_classes.txt','w') do |f|
|
|
218
|
+
f.write app.ole_obj.ole_classes_detail
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
ole_obj = app.ole_obj
|
|
222
|
+
|
|
223
|
+
event_classes = ole_obj.select_ole_type('event')
|
|
224
|
+
puts event_classes
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
# drawing = app.new_drawing('mynew.dgn')
|
|
228
|
+
|
|
229
|
+
# le =tlib.ole_classes.find{|c| c.name == 'LineElement'}
|
|
230
|
+
# #puts drawing.model_names
|
|
231
|
+
|
|
232
|
+
# VT = WIN32OLE::VARIANT
|
|
233
|
+
# # Type.Missing equivalent
|
|
234
|
+
|
|
235
|
+
# e1 = WIN32OLE_VARIANT::NoParam
|
|
236
|
+
# e2 = WIN32OLE_VARIANT.new(nil, VT::VT_VARIANT|VT::VT_BYREF)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
# drawing.change_model('Default')
|
|
240
|
+
# line = drawing.create_line [1,0.5],[1,1,0],e1
|
|
241
|
+
# drawing.add_line line if line
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
binding.pry
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
app.quit
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
end
|
data/lib/microstation/app.rb
CHANGED
|
@@ -1,286 +1,781 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
@
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
@
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
def
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'wrap'
|
|
4
|
+
require_relative 'point3d'
|
|
5
|
+
require_relative 'event_handler'
|
|
6
|
+
require_relative 'functions'
|
|
7
|
+
require 'pry'
|
|
8
|
+
|
|
9
|
+
class WIN32OLE
|
|
10
|
+
def ole_obj
|
|
11
|
+
self
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module Windows
|
|
16
|
+
class FileSystem
|
|
17
|
+
def self.windows_path(path)
|
|
18
|
+
obj = new
|
|
19
|
+
obj.windows_path(path)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def fs_object
|
|
23
|
+
@fs_object ||= WIN32OLE.new('Scripting.FileSystemObject')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def windows_path(path)
|
|
27
|
+
path = path.to_path if path.respond_to? :to_path
|
|
28
|
+
fs_object.GetAbsolutePathName(path.to_str)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
module Microstation
|
|
34
|
+
module MSD
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.win_fs
|
|
38
|
+
@windows_fs ||= Windows::FileSystem.new
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class App
|
|
42
|
+
include Functions
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@default_app_options = { visible: false }
|
|
46
|
+
|
|
47
|
+
class << self
|
|
48
|
+
|
|
49
|
+
attr_accessor :default_app_options
|
|
50
|
+
|
|
51
|
+
# include Wrap
|
|
52
|
+
|
|
53
|
+
# Initialize an instance of app with the options
|
|
54
|
+
# @param [Hash] options the options to create the app with
|
|
55
|
+
# @option options [Boolean] :visible Is the app visible
|
|
56
|
+
#
|
|
57
|
+
# [source]
|
|
58
|
+
# ----
|
|
59
|
+
# App.run do |app|
|
|
60
|
+
# drawing = app.open_drawing('test.dgn')
|
|
61
|
+
# drawing.scan_all_text do |model,text|
|
|
62
|
+
# puts "#{model} #{text}"
|
|
63
|
+
# end
|
|
64
|
+
# end
|
|
65
|
+
#
|
|
66
|
+
# @yield [App] the_app yields the instanciated app
|
|
67
|
+
# @return [void]
|
|
68
|
+
def run(options = {})
|
|
69
|
+
opts = self.default_app_options.merge(options)
|
|
70
|
+
begin
|
|
71
|
+
the_app = new(**opts)
|
|
72
|
+
binding.pry if the_app.nil?
|
|
73
|
+
yield the_app
|
|
74
|
+
rescue StandardError
|
|
75
|
+
binding.pry
|
|
76
|
+
ensure
|
|
77
|
+
the_app.quit if the_app.respond_to? :quit
|
|
78
|
+
the_app = nil
|
|
79
|
+
GC.start
|
|
80
|
+
nil
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Calls #run to get an app instance then call open drawing with
|
|
85
|
+
# that app
|
|
86
|
+
# (see #open_drawing)
|
|
87
|
+
# @yield Drawing
|
|
88
|
+
# @return [void]
|
|
89
|
+
def open_drawing(drawing, app_options: {}, options: {}, &block)
|
|
90
|
+
run(**app_options) do |app|
|
|
91
|
+
app.open_drawing(drawing, **options, &block)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Runs the app, opening the filenames
|
|
96
|
+
# and yielding each open drawing to the
|
|
97
|
+
# supplied block
|
|
98
|
+
# it automatically closes the drawing and
|
|
99
|
+
# the app when done
|
|
100
|
+
#
|
|
101
|
+
# [source]
|
|
102
|
+
# dir = Pathname('C:/templates')
|
|
103
|
+
# drawings = Pathname.glob(dir + '/**/*.dgn')
|
|
104
|
+
# App.with_drawings(drawings) do |drawing|
|
|
105
|
+
# drawing.save_as_pdf(dir: 'c:/output/')
|
|
106
|
+
# end
|
|
107
|
+
#
|
|
108
|
+
# @param files [Array<String,Pathname>]
|
|
109
|
+
# @param visible [Boolean]
|
|
110
|
+
# @param readonly [Boolean]
|
|
111
|
+
# @param error_proc [Proc]
|
|
112
|
+
# @yield [Drawing]
|
|
113
|
+
# @return [void]
|
|
114
|
+
def with_drawings(*files, visible: true, readonly: false, error_proc: ::Microstation.default_error_proc, &block)
|
|
115
|
+
# drawing_options = default_drawing_options.merge(options)
|
|
116
|
+
# app_options = default_app_options
|
|
117
|
+
errors = []
|
|
118
|
+
files = files[0] if files[0].is_a? Array
|
|
119
|
+
begin
|
|
120
|
+
the_app = new(visible: visible)
|
|
121
|
+
files_enum = files.each
|
|
122
|
+
loop do
|
|
123
|
+
file = files_enum.next
|
|
124
|
+
puts "opening #{file}.."
|
|
125
|
+
begin
|
|
126
|
+
the_app.open_drawing(file, readonly: readonly, error_proc: error_proc, &block)
|
|
127
|
+
the_app.ole_obj.ole_methods # check if server still open
|
|
128
|
+
rescue StandardError => e
|
|
129
|
+
error_proc.call(e, file)
|
|
130
|
+
the_app = new(app_options)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
ensure
|
|
134
|
+
the_app&.quit
|
|
135
|
+
the_app = nil
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
attr_reader :scanners, :visible, :app_event, :project_dir
|
|
141
|
+
|
|
142
|
+
# Constructor for app
|
|
143
|
+
# @param [Boolean] visible
|
|
144
|
+
# @param event_handler [EventHandler]
|
|
145
|
+
def initialize(visible: false, event_handler: default_event_handler)
|
|
146
|
+
@visible = visible
|
|
147
|
+
@event_handler = event_handler
|
|
148
|
+
@ole_obj, @app_event = init_ole_and_app_event(visible: @visible, event_handler: @event_handler, tries: 5,
|
|
149
|
+
sleep_duration: 0.5)
|
|
150
|
+
@run_loop = true
|
|
151
|
+
@windows = Windows::FileSystem.new
|
|
152
|
+
# make_visible(visible)
|
|
153
|
+
@scanners = {}
|
|
154
|
+
rescue StandardError => e
|
|
155
|
+
binding.pry
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def run_templates_in_dir(dir, options = {})
|
|
159
|
+
yaml_files = Pathname.glob("#{Pathname(dir).expand_path}*.yaml")
|
|
160
|
+
yaml_files.each do |f|
|
|
161
|
+
TemplateRunner.new(f).run_with_app(self, options)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def change_drawing(dgn, output_dir: nil, name: nil, options: {}, &block)
|
|
166
|
+
changer = Changer.new(dgn, name: name, output_dir: output_dir, app: self)
|
|
167
|
+
changer.run(&block)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def render_template(drawing, output_dir: nil, locals: {}, name: nil)
|
|
171
|
+
temp = Template.new(drawing, output_dir: output_dir, app: self, name: name)
|
|
172
|
+
temp.render(output_dir: output_dir, locals: locals)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
#
|
|
176
|
+
# the default EventHandler
|
|
177
|
+
#
|
|
178
|
+
# @return [EventHandler] returns the default EventHandler
|
|
179
|
+
#
|
|
180
|
+
def default_event_handler
|
|
181
|
+
event_handler = EventHandler.new
|
|
182
|
+
event_handler.add_handler('OnDesignFileOpened') do |*_args|
|
|
183
|
+
puts 'drawing opened'
|
|
184
|
+
@drawing_opened = true
|
|
185
|
+
end
|
|
186
|
+
event_handler.add_handler('OnDesignFileClosed') do |*_args|
|
|
187
|
+
@drawing_opened = false
|
|
188
|
+
puts 'drawing closed'
|
|
189
|
+
end
|
|
190
|
+
event_handler
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
#
|
|
194
|
+
# register an handler
|
|
195
|
+
#
|
|
196
|
+
# @param [String] event key for handler
|
|
197
|
+
# @param [<Type>] &block <description>
|
|
198
|
+
#
|
|
199
|
+
# @return [<Type>] <description>
|
|
200
|
+
#
|
|
201
|
+
def register_handler(event, &block)
|
|
202
|
+
@event_handler.add_handler(event, &block) unless event == 'OnQuit'
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
#
|
|
206
|
+
# return a Handler
|
|
207
|
+
#
|
|
208
|
+
# @param [String,Symbol] event the event key
|
|
209
|
+
#
|
|
210
|
+
# @return [Proc] returns the Proc given by event name
|
|
211
|
+
#
|
|
212
|
+
def get_handler(event)
|
|
213
|
+
@event_handler.get_handler(event)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def exit_message_looop
|
|
217
|
+
puts 'Microstation exiting...'
|
|
218
|
+
@run_loop = false
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def wait_drawing_opened(secs, interval = 1)
|
|
222
|
+
elapsed = 0
|
|
223
|
+
while !drawing_opened? && elapsed <= secs
|
|
224
|
+
elapsed += interval
|
|
225
|
+
sleep(interval)
|
|
226
|
+
WIN32OLE_EVENT.message_loop
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def init_ole_and_app_event(visible: @visible, event_handler: @event_handler, tries: 5, sleep_duration: 1)
|
|
231
|
+
ole = WIN32OLE.new('MicrostationDGN.Application')
|
|
232
|
+
sleep(sleep_duration)
|
|
233
|
+
ole.Visible = visible
|
|
234
|
+
ole.IsProcessLocked = true
|
|
235
|
+
load_constants(ole)
|
|
236
|
+
app_event = WIN32OLE_EVENT.new(ole)
|
|
237
|
+
app_event.handler = event_handler
|
|
238
|
+
[ole, app_event]
|
|
239
|
+
rescue StandardError => e
|
|
240
|
+
tries -= 1
|
|
241
|
+
sleep_duration += 1.5
|
|
242
|
+
puts "Error: #{e}. #{tries} tries left."
|
|
243
|
+
retry if tries.positive?
|
|
244
|
+
raise e, 'unable to init ole app'
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# @return [Boolean] whether the app is visible
|
|
248
|
+
def visible?
|
|
249
|
+
@visible
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
#
|
|
253
|
+
# Change the visible attribute
|
|
254
|
+
#
|
|
255
|
+
# @param [Boolean] bool true or false to make it visible
|
|
256
|
+
#
|
|
257
|
+
# @return [void]
|
|
258
|
+
#
|
|
259
|
+
def visible=(bool)
|
|
260
|
+
ole_obj.Visible = bool
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def project_dir=(dir)
|
|
264
|
+
@project_dir = dir ? Pathname.new(dir) : dir
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def base_dir
|
|
268
|
+
project_dir || Pathname.getwd
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def wrap(item, cell = nil)
|
|
272
|
+
Element.convert_item(item, self, cell)
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def normalize_name(name)
|
|
276
|
+
name = Pathname.new(name) unless name.is_a? Pathname
|
|
277
|
+
name = name.ext('.dgn') unless name.extname.to_s == /\.(dgn|dwg)$/
|
|
278
|
+
(base_dir + name).expand_path
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def make_visible(visible)
|
|
282
|
+
@visible = visible
|
|
283
|
+
begin
|
|
284
|
+
ole_obj.Visible = @visible
|
|
285
|
+
true
|
|
286
|
+
rescue Exception => e
|
|
287
|
+
false
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def ole_obj
|
|
292
|
+
is_ok = true
|
|
293
|
+
begin
|
|
294
|
+
@ole_obj.Visible
|
|
295
|
+
rescue StandardError => e
|
|
296
|
+
is_ok = false
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
@ole_obj, @app_event = init_ole_and_app_event(tries: 3) unless is_ok
|
|
300
|
+
|
|
301
|
+
@ole_obj
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def with_drawing(drawing)
|
|
305
|
+
yield drawing
|
|
306
|
+
ensure
|
|
307
|
+
drawing.close
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def with_template(template)
|
|
311
|
+
template = Template.new(template, self)
|
|
312
|
+
yield template
|
|
313
|
+
template = nil
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# open the drawing
|
|
317
|
+
# @param filename [String] the name of the file to open
|
|
318
|
+
# @param [Boolean] :readonly (false)
|
|
319
|
+
# @param [Proc] :error_proc (raise) a proc to run
|
|
320
|
+
# @param wait_time [Integer] the total amount of time to wait to open file (500)
|
|
321
|
+
# @param wait_interval [Float] the amount of time in seconds to wait before retry (0.5)
|
|
322
|
+
# @yield [Drawing] drawing
|
|
323
|
+
# @return [void]
|
|
324
|
+
def open_drawing(filename, readonly: false, error_proc: nil, wait_time: 500, wait_interval: 0.5)
|
|
325
|
+
filename = Pathname(filename)
|
|
326
|
+
raise FileNotFound unless filename.file?
|
|
327
|
+
|
|
328
|
+
begin
|
|
329
|
+
ole = ole_open_drawing(windows_path(filename), readonly: readonly, wait_time: wait_time,
|
|
330
|
+
wait_interval: wait_interval)
|
|
331
|
+
rescue StandardError => e
|
|
332
|
+
if error_proc
|
|
333
|
+
error_proc.call(filename)
|
|
334
|
+
return
|
|
335
|
+
else
|
|
336
|
+
raise e
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
drawing = drawing_from_ole(ole)
|
|
340
|
+
return drawing unless block_given?
|
|
341
|
+
|
|
342
|
+
begin
|
|
343
|
+
yield drawing
|
|
344
|
+
ensure
|
|
345
|
+
drawing.close
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
def drawing_opened?
|
|
350
|
+
@drawing_opened
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def windows_path(path)
|
|
354
|
+
@windows.windows_path(path)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
def active_workspace
|
|
358
|
+
ole_obj.ActiveWorkspace
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
# @return the [Configuration]
|
|
362
|
+
def configuration
|
|
363
|
+
@config ||= ::Microstation::Configuration.new(self)
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
# @return [String] the configuration variable USERNAME
|
|
367
|
+
def username
|
|
368
|
+
configuration['USERNAME']
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
# create a new drawing
|
|
372
|
+
# @param filename [String,Pathname] the name of the file
|
|
373
|
+
# @param seedfile [String] The name of the seed file.
|
|
374
|
+
# should not include a path. The default extension is ".dgn".
|
|
375
|
+
# Typical values are "seed2d" or "seed3d".
|
|
376
|
+
# @param open [Boolean] .If the open argument is True,
|
|
377
|
+
# CreateDesignFile returns the newly-opened DesignFile object;
|
|
378
|
+
# this is the same value as ActiveDesignFile. If the Open argument is False,
|
|
379
|
+
# CreateDesignFile returns Nothing.
|
|
380
|
+
# @return [Drawing]
|
|
381
|
+
def new_drawing(filename, seedfile: nil, open: true, wait_time: 500, wait_interval: 1, &block)
|
|
382
|
+
file_path = Pathname(filename).expand_path
|
|
383
|
+
raise ExistingFile, file_path if file_path.exist?
|
|
384
|
+
|
|
385
|
+
# drawing_name = normalize_name(filename)
|
|
386
|
+
seedfile = determine_seed(seedfile)
|
|
387
|
+
binding.pry unless seedfile
|
|
388
|
+
windows_name = windows_path(filename)
|
|
389
|
+
ole = new_ole_drawing(seedfile, windows_name, open: open, wait_time: wait_time, wait_interval: wait_interval)
|
|
390
|
+
drawing = drawing_from_ole(ole)
|
|
391
|
+
return drawing unless block_given?
|
|
392
|
+
|
|
393
|
+
begin
|
|
394
|
+
yield drawing
|
|
395
|
+
rescue StandardError => e
|
|
396
|
+
'puts error in new drawing'
|
|
397
|
+
raise e
|
|
398
|
+
ensure
|
|
399
|
+
drawing.close
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
def new_ole_drawing(seedfile, new_design_file_name, open: true, wait_time: 500, wait_interval: 0.5)
|
|
404
|
+
ole = ole_obj.CreateDesignFile(seedfile, new_design_file_name, open)
|
|
405
|
+
wait_drawing_opened(wait_time, wait_interval)
|
|
406
|
+
raise "drawing not opened in #{wait_time}" unless drawing_opened?
|
|
407
|
+
|
|
408
|
+
ole
|
|
409
|
+
rescue StandardError => e
|
|
410
|
+
raise e
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
def has_current_drawing?
|
|
414
|
+
ole_obj.HasActiveDesignFile
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
# prepend a dir to the MS_SEEDFILES configuration
|
|
418
|
+
# @param dir [String,Pathname]
|
|
419
|
+
def prepend_seed_path(dir)
|
|
420
|
+
configuration.prepend('MS_SEEDFILES', windows_path(dir))
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
def drawing_from_ole(ole)
|
|
424
|
+
Drawing.new(self, ole)
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def determine_seed(seedfile)
|
|
428
|
+
return configuration['MS_DESIGNSEED'] unless seedfile
|
|
429
|
+
|
|
430
|
+
seed = find_seed(seedfile)
|
|
431
|
+
return seed.to_s if seed
|
|
432
|
+
|
|
433
|
+
raise "Seedfile #{seedfile} not found in #{configured_seed_paths}"
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
# @return [String] the configuration variable MS_SEEDFILES
|
|
437
|
+
def configured_seed_paths
|
|
438
|
+
configuration['MS_SEEDFILES']
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
# find the seedfile
|
|
442
|
+
# @param [String,Pathname] seedfile
|
|
443
|
+
#
|
|
444
|
+
# * If the seed file is absolute and found the return the
|
|
445
|
+
# seedfile.
|
|
446
|
+
# * If the seed file is not found search MS_SEEDFILES
|
|
447
|
+
# @return [Pathname] seedfile the found seedfile
|
|
448
|
+
def find_seed(seedfile)
|
|
449
|
+
seed = Pathname(seedfile).expand_path.sub_ext('.dgn')
|
|
450
|
+
return seed if seed.file?
|
|
451
|
+
|
|
452
|
+
find_seed_in_seed_dirs(seed.basename)
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
def find_seed_in_seed_dirs(seedfile)
|
|
456
|
+
seed_dir = seed_paths.find { |p| (p + seedfile).file? }
|
|
457
|
+
return (seed_dir + seedfile) if seed_dir
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
# @return [Array] returns the MS_SEEDFILES as Pathnames Array
|
|
461
|
+
def seed_paths
|
|
462
|
+
configured_seed_paths.split(';').map { |d| Pathname(d) }
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def eval_cexpression(string)
|
|
466
|
+
ole_obj.GetCExpressionValue(string)
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
#
|
|
470
|
+
# quit the app
|
|
471
|
+
#
|
|
472
|
+
# @return [void]
|
|
473
|
+
#
|
|
474
|
+
def quit
|
|
475
|
+
close_active_drawing
|
|
476
|
+
@scanners.each { |_name, sc| sc.close }
|
|
477
|
+
begin
|
|
478
|
+
ole_obj.Quit
|
|
479
|
+
rescue StandardError
|
|
480
|
+
nil
|
|
481
|
+
end
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
# the active design file
|
|
485
|
+
# @return [Drawing]
|
|
486
|
+
def active_design_file
|
|
487
|
+
if active_design_file?
|
|
488
|
+
ole = ole_obj.ActiveDesignFile
|
|
489
|
+
drawing_from_ole(ole)
|
|
490
|
+
end
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
alias active_drawing active_design_file
|
|
494
|
+
alias current_drawing active_design_file
|
|
495
|
+
|
|
496
|
+
#
|
|
497
|
+
# close the active_design_file
|
|
498
|
+
#
|
|
499
|
+
# @return [void]
|
|
500
|
+
#
|
|
501
|
+
def close_active_drawing
|
|
502
|
+
active_design_file.close if active_design_file?
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
alias close_current_drawing close_active_drawing
|
|
506
|
+
|
|
507
|
+
#
|
|
508
|
+
#
|
|
509
|
+
#
|
|
510
|
+
# @return [Boolean] true if app has an active design file open
|
|
511
|
+
#
|
|
512
|
+
def active_design_file?
|
|
513
|
+
ole_obj.HasActiveDesignFile
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
alias current_design_file? active_design_file?
|
|
517
|
+
|
|
518
|
+
#
|
|
519
|
+
# <Description>
|
|
520
|
+
#
|
|
521
|
+
# @param [String,Pathname] file name of file to search for
|
|
522
|
+
#
|
|
523
|
+
# @return [Boolean] true if file exists
|
|
524
|
+
#
|
|
525
|
+
def file_exists?(file)
|
|
526
|
+
Pathname(file).expand_path.file?
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
def create_scanner(name = nil, &block)
|
|
530
|
+
::Microstation::Scan::Criteria.create_scanner(name, self, &block)
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
def text_criteria
|
|
534
|
+
scanners[:textual] || create_scanner(:textual) { include_textual }
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
def tags_criteria
|
|
538
|
+
sc = scanners[:tags] || create_scanner(:tags) { include_tags }
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
def create_scan_criteria(name = nil, &block)
|
|
542
|
+
::Microstation::Scan::Criteria.create_scanner(name, self, &block)
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
# def find_by_id(id)
|
|
546
|
+
# active_design_file.find_by_id(id)
|
|
547
|
+
# wrap(model) if el
|
|
548
|
+
# end
|
|
549
|
+
|
|
550
|
+
def scan_model(criteria = nil, model = nil)
|
|
551
|
+
model ||= active_model_reference
|
|
552
|
+
model.scan(criteria)
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
def get_ole_element_enumerator(model:, criteria: nil)
|
|
556
|
+
criteria ||= create_scan_criteria
|
|
557
|
+
criteria.resolve
|
|
558
|
+
model.scan(criteria.ole_obj)
|
|
559
|
+
rescue Exception
|
|
560
|
+
# binding.pry
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
# lets you interact with the cad_input_queue
|
|
564
|
+
# @yield [CadInputQueue]
|
|
565
|
+
# @return [void]
|
|
566
|
+
def cad_input_queue
|
|
567
|
+
queue = init_cad_input_queue
|
|
568
|
+
return queue unless block_given?
|
|
569
|
+
|
|
570
|
+
begin
|
|
571
|
+
yield queue
|
|
572
|
+
rescue StandardError
|
|
573
|
+
ensure
|
|
574
|
+
queue.close
|
|
575
|
+
queue = nil
|
|
576
|
+
@cad_input_queue = nil
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
def show_command(text)
|
|
581
|
+
ole_obj.ShowCommand(text)
|
|
582
|
+
end
|
|
583
|
+
|
|
584
|
+
def show_prompt(text)
|
|
585
|
+
ole_obj.ShowPrompt(text)
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
def show_message(text)
|
|
589
|
+
ole_obj.ShowMessage(text)
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
#
|
|
593
|
+
#
|
|
594
|
+
# @param [String] text text to show
|
|
595
|
+
# @param [Symbol] location (one of :left, :middle)
|
|
596
|
+
#
|
|
597
|
+
# @return [void]
|
|
598
|
+
#
|
|
599
|
+
def show_temp_message(text, location: nil)
|
|
600
|
+
loc = case location
|
|
601
|
+
when :left
|
|
602
|
+
MSD::MsdStatusBarAreaLeft
|
|
603
|
+
when :middle
|
|
604
|
+
MSD::MsdStatusBarAreaMiddle
|
|
605
|
+
else
|
|
606
|
+
MSD::MsdStatusBarAreaLeft
|
|
607
|
+
end
|
|
608
|
+
ole_obj.ShowTempMessage(loc, text)
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
def can_open?(filename)
|
|
612
|
+
ext = File.extname(filename)
|
|
613
|
+
(ext == '.dwg') || (ext == '.dgn')
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
def active_model_reference
|
|
617
|
+
DefaultModel.new(self, ole_obj.ActiveModelReference)
|
|
618
|
+
rescue StandardError
|
|
619
|
+
nil
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
def default_model
|
|
623
|
+
DefaultModel.new(self, ole_obj.DefaultModelReference)
|
|
624
|
+
rescue StandardError
|
|
625
|
+
nil
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
def ole_point
|
|
629
|
+
::WIN32OLE_RECORD.new('Point3d', ole_obj)
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
def ole_rotation
|
|
633
|
+
::WIN32OLE_RECORD.new('Rotation', ole_obj)
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
def ole_matrix
|
|
637
|
+
::WIN32OLE_RECORD.new('Matrix', ole_obj)
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
#
|
|
641
|
+
# Create an WIN32OLE_RECORD of type Point3d
|
|
642
|
+
#
|
|
643
|
+
# @param [Numeric] x coordinate in x axis
|
|
644
|
+
# @param [Numeric] y coordinate in y axis
|
|
645
|
+
# @param [Numeric] z coordinate in z direction (0.0)
|
|
646
|
+
#
|
|
647
|
+
# @return [WIN32OLE_RECORD] record of type Point3d
|
|
648
|
+
#
|
|
649
|
+
def create_ole_point(x, y, z = 0)
|
|
650
|
+
ole = ole_point
|
|
651
|
+
ole.X = x
|
|
652
|
+
ole.Y = y
|
|
653
|
+
ole.Z = z
|
|
654
|
+
ole
|
|
655
|
+
end
|
|
656
|
+
|
|
657
|
+
def to_ole_matrix3d(vec)
|
|
658
|
+
if vec.instance_of?(WIN32OLE_RECORD) && vec.typename == 'Matrix3d'
|
|
659
|
+
vec
|
|
660
|
+
else
|
|
661
|
+
binding.pry
|
|
662
|
+
end
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
#
|
|
666
|
+
# Conversion to WIN32OLE_RECORD of type Point3d
|
|
667
|
+
#
|
|
668
|
+
# @param [WIN32OLE_RECORD, Point3d, Array<Numeric>] pt Point to normalize to ole point
|
|
669
|
+
# @return [WIN32OLE_RECORD] 'Point3d' WIN32OLE_RECORD
|
|
670
|
+
#
|
|
671
|
+
def to_ole_point3d(pt)
|
|
672
|
+
case pt
|
|
673
|
+
when ole_point3d?(pt)
|
|
674
|
+
pt
|
|
675
|
+
when Point3d
|
|
676
|
+
create_ole_point(pt.x, pt.y, pt.z)
|
|
677
|
+
when Array
|
|
678
|
+
pt1 = pt.map(&:to_f)
|
|
679
|
+
x, y, z = pt1
|
|
680
|
+
z ||= 0.0
|
|
681
|
+
create_ole_point(x, y, z)
|
|
682
|
+
end
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
#
|
|
686
|
+
# <Description>
|
|
687
|
+
#
|
|
688
|
+
# @param [Object] pt pt object to test if it is a WIN32OLE_RECORD of 'Point3d'
|
|
689
|
+
#
|
|
690
|
+
# @return [Boolean] true if pt is WIN32OLE_RECORD of 'Point3d'
|
|
691
|
+
#
|
|
692
|
+
def ole_point3d?(pt)
|
|
693
|
+
pt.instance_of?(WIN32OLE_RECORD) && pt.typename == 'Point3d'
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
def create_text_node(origin, rotation, temp = nil)
|
|
697
|
+
ole_origin = to_ole_point3d(origin)
|
|
698
|
+
ole_rotation = to_ole_matrix3d(rotation)
|
|
699
|
+
temp ||= WIN32OLE_VARIANT::Nothing
|
|
700
|
+
ole = ole_obj.CreateTextNodeElement1(temp, ole_origin, ole_rotation)
|
|
701
|
+
rescue Exception => e
|
|
702
|
+
puts e.message
|
|
703
|
+
nil
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
#
|
|
707
|
+
# convert pt to Point3d
|
|
708
|
+
#
|
|
709
|
+
# @param [Array<Numeric,Numeric,Numeric>, Point3d, WIN32OLE_RECORD] pt Point to convert
|
|
710
|
+
#
|
|
711
|
+
# @return [Point3d]
|
|
712
|
+
#
|
|
713
|
+
def to_point3d(pt)
|
|
714
|
+
case pt
|
|
715
|
+
when Array
|
|
716
|
+
pt_a = pt.map(&:to_f)
|
|
717
|
+
x, y, z = pt_a
|
|
718
|
+
z ||= 0.0
|
|
719
|
+
Point3d.new(x, y, z)
|
|
720
|
+
when Point3d
|
|
721
|
+
pt
|
|
722
|
+
when WIN32OLE_RECORD
|
|
723
|
+
Point3d.from_ole(pt) if pt.typename == 'Point3d'
|
|
724
|
+
end
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
def to_point(pt)
|
|
728
|
+
to_point3d(pt)
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
def start_primitive(klass)
|
|
732
|
+
ole_obj.CommandState.StartPrimitive klass.new(self)
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
def my_place_line
|
|
736
|
+
require_relative 'primitive_command_interface'
|
|
737
|
+
start_primitive LineCreation
|
|
738
|
+
end
|
|
739
|
+
|
|
740
|
+
def method_missing(meth, *args, &block)
|
|
741
|
+
if meth.to_s =~ /^[A-Z]/
|
|
742
|
+
require 'pry'; binding.pry
|
|
743
|
+
result = ole_obj.send(meth, *args, &block)
|
|
744
|
+
else
|
|
745
|
+
super(meth, *args, &block)
|
|
746
|
+
end
|
|
747
|
+
rescue StandardError => e
|
|
748
|
+
binding.pry
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
protected
|
|
752
|
+
|
|
753
|
+
def ole_open_drawing(path, readonly: false, wait_time: 500, wait_interval: 0.5)
|
|
754
|
+
ole = ole_obj.OpenDesignFile(windows_path(path), 'ReadOnly' => readonly)
|
|
755
|
+
wait_drawing_opened(wait_time, wait_interval)
|
|
756
|
+
raise "drawing not opened in #{wait_time}" unless drawing_opened?
|
|
757
|
+
|
|
758
|
+
ole
|
|
759
|
+
rescue StandardError => e
|
|
760
|
+
raise e
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
def load_constants(ole_obj)
|
|
764
|
+
WIN32OLE.const_load(ole_obj, MSD) unless MSD.constants.size.positive?
|
|
765
|
+
end
|
|
766
|
+
|
|
767
|
+
def run_loop
|
|
768
|
+
WIN32OLE_EVENT.message_loop while @run_loop
|
|
769
|
+
end
|
|
770
|
+
|
|
771
|
+
def stop_loop
|
|
772
|
+
@run_loop = false
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
private
|
|
776
|
+
|
|
777
|
+
def init_cad_input_queue
|
|
778
|
+
::Microstation::CadInputQueue.new(ole_obj.CadInputQueue, self)
|
|
779
|
+
end
|
|
780
|
+
end
|
|
781
|
+
end
|