-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfactory_importer.rb
More file actions
413 lines (362 loc) · 15.9 KB
/
factory_importer.rb
File metadata and controls
413 lines (362 loc) · 15.9 KB
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
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
157
158
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
220
221
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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# 工厂导入主模块:处理工厂布局导入的主要逻辑
require 'json'
require_relative 'coordinate_processor'
# 移除这里的ObjectBuilder引入,在实际使用时再引入
# require_relative 'ObjectBuilder/object_builder'
# TapeBuilder现在通过主插件的统一加载机制加载,不需要在这里单独加载
# 注释掉旧的加载代码
# begin
# require_relative 'TapeBuilder/main'
# puts "新胶带系统加载成功"
# rescue => e
# puts "警告:新胶带系统加载失败: #{e.message}"
# end
module FactoryImporter
# 导入工厂布局
def self.import_factory_layout
filter = "JSON文件 (*.json)|*.json|所有文件 (*.*)|*.*||"
file_path = UI.openpanel("选择工厂布局文件", "", filter)
return if file_path.nil?
begin
json_data = File.read(file_path)
layout_data = JSON.parse(json_data)
# 检查是否是有效的工厂布局文件
unless layout_data["site"]
UI.messagebox("无效的工厂布局文件: 缺少site属性")
return
end
# 应用坐标预处理,将整个工厂模型平移到第一象限
puts "开始坐标预处理..."
layout_data = CoordinateProcessor.process_factory_coordinates(layout_data)
puts "坐标预处理完成"
# 添加调试信息:检查窗户数据是否被修改
puts "=== 调试:检查坐标预处理后的窗户数据 ==="
layout_data["site"]["factories"].each do |factory|
walls = factory["walls"] || factory.dig("structures", "walls") || []
walls.each do |wall|
windows = wall["windows"] || []
windows.each do |window|
puts "窗户ID: #{window['id']}, size: #{window['size'].inspect}"
end
end
end
model = Sketchup.active_model
model.start_operation("导入工厂布局", true)
# 初始化实体存储器(独立功能,不影响主流程)
begin
EntityStorage.init
puts "实体存储器初始化成功"
rescue => e
puts "警告: 实体存储器初始化失败,继续执行主流程: #{e.message}"
end
# 初始化新胶带系统
begin
if defined?(TapeBuilder)
TapeBuilder.init
puts "新胶带系统初始化成功"
end
rescue => e
puts "警告: 新胶带系统初始化失败,继续执行主流程: #{e.message}"
end
main_group = model.entities.add_group
main_group.name = layout_data["site"]["name"] || "工厂布局"
factories_data = layout_data["site"]["factories"]
factories_data = [factories_data] unless factories_data.is_a?(Array)
# 记录导入前的工厂数据结构
puts "=== 导入前工厂数据结构检查 ==="
factories_data.each_with_index do |factory, idx|
puts "工厂 ##{idx + 1} ID: #{factory['id']}"
puts "工厂 ##{idx + 1} size: #{factory['size'].inspect}"
if factory['size'] && factory['size'].is_a?(Array) && factory['size'].size >= 2 &&
factory['size'][0].is_a?(Array) && factory['size'][1].is_a?(Array)
puts "工厂 ##{idx + 1} size格式正确"
else
puts "工厂 ##{idx + 1} size格式不正确"
end
end
# 创建工厂数据的深拷贝,用于后续比较
factories_data_before = Marshal.load(Marshal.dump(factories_data))
import_factory(factories_data, main_group,main_group)
# 比较导入前后的工厂数据结构
puts "=== 导入后工厂数据结构检查 ==="
factories_data.each_with_index do |factory, idx|
puts "工厂 ##{idx + 1} ID: #{factory['id']}"
puts "工厂 ##{idx + 1} size: #{factory['size'].inspect}"
if factory['size'] && factory['size'].is_a?(Array) && factory['size'].size >= 2 &&
factory['size'][0].is_a?(Array) && factory['size'][1].is_a?(Array)
puts "工厂 ##{idx + 1} size格式正确"
else
puts "工厂 ##{idx + 1} size格式不正确"
end
# 检查size是否被修改
if factories_data_before[idx]['size'] != factory['size']
puts "警告: 工厂 ##{idx + 1} 的size被修改了"
puts " 修改前: #{factories_data_before[idx]['size'].inspect}"
puts " 修改后: #{factory['size'].inspect}"
end
end
# 获取所有zones
all_zones = []
all_walls = []
factories_data.each do |f|
zs = f["zones"]
ws = f["walls"]
all_zones.concat(zs) if zs.is_a?(Array)
all_walls.concat(ws) if ws.is_a?(Array)
end
# 基于工厂size生成大地面,不再依赖围墙和区域数据
if defined?(ZoneBuilder.generate_factory_ground_from_size)
puts "【地面生成】开始基于工厂size生成大地面..."
ZoneBuilder.generate_factory_ground_from_size(main_group, factories_data)
else
puts "【警告】ZoneBuilder.generate_factory_ground_from_size 方法未定义"
# 回退到原来的方法
if defined?(ZoneBuilder.generate_factory_total_ground)
puts "【地面生成】回退到原方法:基于区域和墙体生成地面..."
ZoneBuilder.generate_factory_total_ground(main_group, all_zones, all_walls)
end
end
# 区域着色仍然需要区域数据
if defined?(ZoneBuilder.generate_zones_floor)
puts "【区域着色】开始生成区域地面着色..."
ZoneBuilder.generate_zones_floor(main_group, all_zones)
else
puts "【警告】ZoneBuilder.generate_zones_floor 方法未定义"
end
# 导入对象数据 - 移到最后执行
import_objects(factories_data, main_group)
# 导入设备数据 - 移到最后执行
# import_equipments(factories_data, main_group)
model.commit_operation
# 导入完成后刷新实体存储器菜单
begin
if defined?(EntityStorage)
EntityStorage.refresh_storage_menu
puts "实体存储器菜单已刷新"
end
rescue => e
puts "警告: 刷新实体存储器菜单失败: #{e.message}"
end
UI.messagebox("工厂布局导入成功!")
rescue JSON::ParserError => e
model.abort_operation if defined?(model) && model
UI.messagebox("JSON解析错误: #{e.message}")
puts Utils.ensure_utf8("JSON解析错误: #{e.message}")
rescue Exception => e
model.abort_operation if defined?(model) && model
UI.messagebox("导入过程中出错: #{e.message}")
puts Utils.ensure_utf8("导入错误: #{e.message}")
end
end
# 导入对象数据的单独方法
def self.import_objects(factories_data, main_group)
factories_data.each do |factory_data|
begin
# 创建工厂组
factory_group = main_group.entities.add_group
factory_group.name = "对象_#{factory_data["id"] || "工厂"}"
# 查找对象数据的多种可能路径
object_data = nil
if factory_data.dig("structures", "objects")
object_data = factory_data.dig("structures", "objects")
puts "在structures.objects路径找到对象数据"
elsif factory_data["objects"]
object_data = factory_data["objects"]
puts "在根级objects路径找到对象数据"
end
puts "=== 开始导入设备 ==="
# 使用ObjectBuilder导入对象
if object_data && !object_data.empty?
# 在实际需要使用ObjectBuilder时再引入
begin
# 检查ObjectBuilder模块是否已经加载
unless defined?(ObjectBuilder)
require_relative 'ObjectBuilder/object_builder'
puts "ObjectBuilder模块已加载"
else
puts "ObjectBuilder模块已经存在,无需重新加载"
end
if ObjectBuilder.respond_to?(:import_objects)
puts "使用ObjectBuilder导入对象..."
ObjectBuilder.import_objects(object_data, factory_group)
else
puts "警告: ObjectBuilder已引入但import_objects方法未定义"
# 如果ObjectBuilder未定义,使用原来的方法
StructureBuilder.import_objects(object_data || [], factory_group) if defined?(StructureBuilder.import_objects)
end
rescue LoadError => e
puts "警告: 无法加载ObjectBuilder模块: #{e.message}"
# 回退到使用StructureBuilder
StructureBuilder.import_objects(object_data || [], factory_group) if defined?(StructureBuilder.import_objects)
end
else
puts "没有对象数据需要导入"
end
rescue => e
error_msg = "对象导入警告: #{Utils.ensure_utf8(e.message)}"
puts Utils.ensure_utf8(error_msg)
end
end
end
# 导入设备数据的单独方法
def self.import_equipments(factories_data, main_group)
factories_data.each do |factory_data|
begin
# 查找对象数据的多种可能路径
object_data = nil
if factory_data.dig("structures", "objects")
object_data = factory_data.dig("structures", "objects")
puts "在structures.objects路径找到对象数据"
elsif factory_data["objects"]
object_data = factory_data["objects"]
puts "在根级objects路径找到对象数据"
end
# 检查设备数据
puts "=== 设备数据检查 ==="
equipment_data = nil
if factory_data["Equipments"]
equipment_data = factory_data["Equipments"]
puts "在Equipments键找到设备数据"
elsif factory_data["equipments"]
equipment_data = factory_data["equipments"]
puts "在equipments键找到设备数据"
elsif factory_data.dig("structures", "equipments")
equipment_data = factory_data.dig("structures", "equipments")
puts "在structures.equipments键找到设备数据"
end
# 如果没有找到设备数据,尝试使用objects数据作为设备数据
if equipment_data.nil? && object_data && !object_data.empty?
puts "未找到专门的设备数据,尝试使用对象数据作为设备"
# 创建对象数据的深拷贝,避免修改原始数据
equipment_data = Marshal.load(Marshal.dump(object_data))
end
if equipment_data
puts "设备数据: #{equipment_data.inspect}"
else
puts "未找到设备数据键"
end
# 导入设备 - 使用找到的设备数据
if equipment_data && !equipment_data.empty?
puts "发现设备数据,开始导入..."
# 设备的父组不应该是factory_group,而应该是main_group,不然无法对其进行增删改查
EquipmentBuilder.import_equipments(equipment_data, main_group)
else
puts "未找到设备数据"
end
rescue => e
error_msg = "设备导入警告: #{Utils.ensure_utf8(e.message)}"
puts Utils.ensure_utf8(error_msg)
end
end
end
# 导入工厂数据
# 这里加一个main_group的传参,方便防止组件在最基础的组上
def self.import_factory(factories_data, parent_group,main_group)
# 用于暂存所有门和窗户数据
all_door_data = []
all_window_data = []
factories_data.each do |factory_data|
begin
factory_group = parent_group.entities.add_group
factory_group.name = factory_data["id"] || "工厂"
# 调试信息:显示工厂数据结构
puts "=== 工厂数据结构调试 ==="
puts "工厂ID: #{factory_data['id']}"
puts "结构键: #{factory_data.keys.join(', ')}"
if factory_data["structures"]
puts "structures键: #{factory_data['structures'].keys.join(', ')}"
end
# 1. 先导入所有墙体
walls_data = fetch_walls_data(factory_data)
WallBuilder.import_walls(walls_data, factory_group) if walls_data
# 2. 再创建内部墙体
zones_data = factory_data["zones"] || []
# 2.1 导入外部区域及围墙
zones_out_factory_data = factory_data.dig("structures", "outdoor_appendix_zone") || []
# zone可能要经常地进行增删改查,将其直接放到main_group或许好点?
ZoneBuilder.import_zones_out_factory(zones_out_factory_data, main_group) if defined?(ZoneBuilder.import_zones_out_factory)
# 3. 导入其他结构(除了门)
column_data = factory_data.dig("structures", "columns") || []
puts "列数据:"
puts column_data.inspect
# # 查找对象数据的多种可能路径
# object_data = nil
# if factory_data.dig("structures", "objects")
# object_data = factory_data.dig("structures", "objects")
# puts "在structures.objects路径找到对象数据"
# elsif factory_data["objects"]
# object_data = factory_data["objects"]
# puts "在根级objects路径找到对象数据"
# end
# puts "对象数据:"
# puts object_data.inspect
StructureBuilder.import_columns(column_data || [], factory_group) if defined?(StructureBuilder.import_columns)
ZoneBuilder.import_zones(zones_data, factory_group)
#StructureBuilder.import_corridors(factory_data["flows"] || [], factory_group) if defined?(StructureBuilder.import_corridors)
# 4. 暂存门和窗户数据(不立即创建)
# 收集墙体上的门
if walls_data.is_a?(Array)
walls_data.each do |wall_data|
# 收集门数据
if wall_data.key?('doors') && !wall_data['doors'].empty?
wall_data['doors'].each do |door_data|
all_door_data << {
door_data: door_data,
wall_data: wall_data,
parent_group: factory_group
}
end
end
# 收集窗户数据
if wall_data.key?('windows') && !wall_data['windows'].empty?
wall_data['windows'].each do |window_data|
all_window_data << {
window_data: window_data,
wall_data: wall_data,
parent_group: factory_group
}
end
end
end
end
# 收集工厂门
factory_doors = factory_data["factory_doors"] || []
factory_doors.each do |door_data|
all_door_data << {
door_data: door_data,
parent_group: factory_group
}
end
# 收集工厂窗户
factory_windows = factory_data["factory_windows"] || []
factory_windows.each do |window_data|
all_window_data << {
window_data: window_data,
parent_group: factory_group
}
end
# 导入flow通道
if factory_data["flows"] && !factory_data["flows"].empty?
FlowBuilder.import_flows(factory_data["flows"], factory_group)
end
rescue => e
error_msg = "工厂导入警告: #{Utils.ensure_utf8(e.message)}"
puts Utils.ensure_utf8(error_msg)
end
end
# 5. 所有墙体创建完成后,统一创建门和窗户(核心滞后逻辑)
DoorBuilder.create_all_doors(all_door_data, parent_group)
WindowBuilder.create_all_windows(all_window_data, parent_group)
end
# 获取墙体数据
def self.fetch_walls_data(factory_data)
if factory_data.key?('structures') && factory_data['structures'].key?('walls')
return factory_data['structures']['walls']
elsif factory_data.key?('walls')
return factory_data['walls']
else
puts "警告: 未找到墙体数据"
return []
end
end
end