hytos / DTI_PID / DTI_PID / LineNoTracer.py @ dc379815
이력 | 보기 | 이력해설 | 다운로드 (85.1 KB)
1 |
# coding: utf-8
|
---|---|
2 |
""" This is line no tracer module """
|
3 |
|
4 |
import sys |
5 |
import math |
6 |
import asyncio |
7 |
import shapely |
8 |
from AppDocData import AppDocData, MessageType |
9 |
from EngineeringLineItem import QEngineeringLineItem |
10 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
11 |
from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem |
12 |
from SymbolSvgItem import SymbolSvgItem |
13 |
from EngineeringTextItem import QEngineeringTextItem |
14 |
from EngineeringUnknownItem import QEngineeringUnknownItem |
15 |
|
16 |
try:
|
17 |
from PyQt5.QtCore import * |
18 |
from PyQt5.QtGui import * |
19 |
from PyQt5.QtWidgets import * |
20 |
except ImportError: |
21 |
try:
|
22 |
from PyQt4.QtCore import * |
23 |
from PyQt4.QtGui import * |
24 |
except ImportError: |
25 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
26 |
|
27 |
|
28 |
class LineNoTracer: |
29 |
'''
|
30 |
@history 2018.04.26 Jeongwoo Variable name changed (texts → lineNos)
|
31 |
'''
|
32 |
|
33 |
def __init__(self, symbols, lines, lineNos, specBreaks, lineIndicators, vendors, end_breaks): |
34 |
try:
|
35 |
self._symbols = symbols
|
36 |
self._lines = lines
|
37 |
self._lineNos = lineNos
|
38 |
self._spec_breaks = specBreaks
|
39 |
self._lineIndicator = lineIndicators
|
40 |
self._end_breaks = end_breaks
|
41 |
self.maxValue = None |
42 |
|
43 |
"""
|
44 |
for spec in self._specBreak:
|
45 |
for attr in spec.attrs:
|
46 |
if type(attr) is tuple and attr[1] != '':
|
47 |
self._specBreakUID.append(attr[1])
|
48 |
"""
|
49 |
except Exception as ex: |
50 |
from App import App |
51 |
|
52 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
53 |
sys.exc_info()[-1].tb_lineno)
|
54 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
55 |
|
56 |
'''
|
57 |
@brief find primary lines connected to given line no
|
58 |
@author humkyung
|
59 |
'''
|
60 |
|
61 |
def find_primary_lines(self, lineno, include_signal=True): |
62 |
from EngineeringLineItem import QEngineeringLineItem |
63 |
from EngineeringRunItem import QEngineeringRunItem |
64 |
|
65 |
connected_items = [] |
66 |
|
67 |
_from = lineno.prop('From')
|
68 |
_to = lineno.prop('To')
|
69 |
if _from and _to and lineno.empty(): |
70 |
connected_items = self.find_connected_objects(_from, to=_to, primary=True, include_signal=include_signal) |
71 |
if _from in connected_items and _to in connected_items: |
72 |
start = connected_items.index(_from) |
73 |
end = connected_items.index(_to) |
74 |
if start < end:
|
75 |
connected_items = connected_items[start:end + 1]
|
76 |
else:
|
77 |
connected_items = connected_items[end:start + 1]
|
78 |
connected_items.reverse() |
79 |
elif (not _from or not _to) and (1 == len(lineno.conns)): |
80 |
connected_items = self.find_connected_objects(lineno.conns[0], include_signal=include_signal) |
81 |
|
82 |
# print(connected_items)
|
83 |
if connected_items:
|
84 |
for item in connected_items: |
85 |
item.owner = lineno # set item's owner
|
86 |
|
87 |
line_run = QEngineeringRunItem() |
88 |
line_run.items = connected_items |
89 |
line_run.arrange_flow_direction() |
90 |
line_run.owner = lineno |
91 |
lineno.runs.append(line_run) |
92 |
|
93 |
lineno.set_property('From', connected_items[0]) |
94 |
lineno.set_property('To', connected_items[-1]) |
95 |
|
96 |
if _to is not None and connected_items and connected_items[-1] is not _to: |
97 |
_to.owner = None
|
98 |
|
99 |
return connected_items
|
100 |
|
101 |
'''
|
102 |
@brief find secondary lines
|
103 |
@author humkyung
|
104 |
'''
|
105 |
|
106 |
def find_secondary_lines(self, lines_and_symbols, include_signal=True, is_trim=False): |
107 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
108 |
from EngineeringLineItem import QEngineeringLineItem |
109 |
from EngineeringRunItem import QEngineeringRunItem |
110 |
from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem |
111 |
|
112 |
try:
|
113 |
foundCount = 1
|
114 |
while foundCount:
|
115 |
foundCount = 0
|
116 |
notMatches = [] |
117 |
for line in lines_and_symbols: |
118 |
if line.owner is not None: continue |
119 |
|
120 |
if not include_signal and type(line) is QEngineeringLineItem and not line.is_piping(): continue |
121 |
|
122 |
if not is_trim: |
123 |
line_matches = [x for x in self._lines if |
124 |
x.owner and line.is_connected(x, QEngineeringAbstractItem.CONNECTED_AT_BODY)]
|
125 |
symbol_matches = [x for x in self._symbols if |
126 |
x.owner and line.is_connected(x) and x.canBeSecondary(line)] |
127 |
else:
|
128 |
line_matches = [x for x in self._lines if x.owner and type( |
129 |
x.owner) is QEngineeringTrimLineNoTextItem and line.is_connected(x, |
130 |
QEngineeringAbstractItem.CONNECTED_AT_BODY)] |
131 |
symbol_matches = [x for x in self._symbols if x.owner and type( |
132 |
x.owner) is QEngineeringTrimLineNoTextItem and line.is_connected(x) and x.canBeSecondary( |
133 |
line)] |
134 |
|
135 |
if line_matches or symbol_matches: |
136 |
foundCount += 1
|
137 |
connected_items = self.find_connected_objects(line, include_signal=include_signal)
|
138 |
|
139 |
owner = line_matches[0].owner if line_matches else symbol_matches[0].owner |
140 |
for item in connected_items: |
141 |
item.owner = owner # set item's owner
|
142 |
|
143 |
if connected_items:
|
144 |
line_run = QEngineeringRunItem() |
145 |
line_run.items = connected_items |
146 |
line_run.arrange_flow_direction() |
147 |
if line_run.items is not None and len(line_run.items) > 0: |
148 |
line_run.owner = owner |
149 |
owner.runs.append(line_run) |
150 |
else:
|
151 |
notMatches.append(line) |
152 |
# lines_and_symbols = notMatches
|
153 |
except Exception as ex: |
154 |
from App import App |
155 |
|
156 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
157 |
sys.exc_info()[-1].tb_lineno)
|
158 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
159 |
|
160 |
'''
|
161 |
@brief trace line no
|
162 |
@author humkyung
|
163 |
@date 2018.04.16
|
164 |
@history 2018.04.26 Jeongwoo docDatalineNos = self.lineNos, Not For loop
|
165 |
humkyung 2018.05.08 add flow arrow
|
166 |
Jeongwoo 2018.05.14 Add [runs] on Primary/Secondary Line - Need to modify Secondary Line
|
167 |
Jeongwoo 2018.05.15 Make Comments [lineno.conns[0].owner = lineno]
|
168 |
Jeongwoo 2018.05.17 Modify find secondary lines with 'while'
|
169 |
Modify find secondary lines with 'while' used sublist for unconnected line
|
170 |
humkyung 2018.05.18 set start line's owner before tracing
|
171 |
'''
|
172 |
|
173 |
def execute(self, displayMessage, updateProgress, toler=600): |
174 |
from EngineeringLineItem import QEngineeringLineItem |
175 |
from SymbolSvgItem import SymbolSvgItem |
176 |
from EngineeringRunItem import QEngineeringRunItem |
177 |
from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem |
178 |
from EngineeringEquipmentItem import QEngineeringEquipmentItem |
179 |
|
180 |
try:
|
181 |
app_doc_data = AppDocData.instance() |
182 |
|
183 |
configs = app_doc_data.getConfigs('Line No', 'Delimiter') |
184 |
if 1 == len(configs): |
185 |
#configs = app_doc_data.getConfigs('Line No', 'Configuration')
|
186 |
|
187 |
for line_no in self._lineNos: |
188 |
_from = line_no.prop('From')
|
189 |
_to = line_no.prop('To')
|
190 |
|
191 |
line_no.conns.clear() |
192 |
minDist = None
|
193 |
startLine = None
|
194 |
for line in [line for line in self._lines if line.owner is None and line.is_piping(strong=True)]: |
195 |
dist = line.distanceTo((line_no.center().x(), line_no.center().y())) |
196 |
if (minDist is None) or (dist < minDist): |
197 |
minDist = dist |
198 |
startLine = line |
199 |
if (startLine is not None) and (minDist < toler): |
200 |
line_no.conns.append(startLine) |
201 |
if not _from or not _to: |
202 |
startLine.owner = line_no |
203 |
|
204 |
if _from and _to and \ |
205 |
(type(_from) is QEngineeringLineItem or issubclass(type(_from), SymbolSvgItem)) and \ |
206 |
(type(_to) is QEngineeringLineItem or issubclass(type(_to), SymbolSvgItem)): |
207 |
_from.owner = line_no |
208 |
_to.owner = line_no |
209 |
line_no._fixed = True
|
210 |
else:
|
211 |
line_no.set_property('From', None) |
212 |
line_no.set_property('To', None) |
213 |
line_no._fixed = False
|
214 |
|
215 |
self.maxValue = len(self._lineNos) + 1 # line no's count + secondary line |
216 |
|
217 |
# find primary lines
|
218 |
# sort line no with from,to value
|
219 |
self._lineNos.sort(
|
220 |
key=lambda line_no: (1 if line_no.prop('From') else 0) + (1 if line_no.prop('To') else 0), |
221 |
reverse=True)
|
222 |
for lineno in self._lineNos: |
223 |
if displayMessage: displayMessage.emit('{} {}'.format(lineno.text(), 'Topology Construction')) |
224 |
self.find_primary_lines(lineno, include_signal=False) |
225 |
if updateProgress: updateProgress.emit(self.maxValue) |
226 |
|
227 |
# find secondary lines
|
228 |
lines_and_symbols = self._lines + self._symbols |
229 |
self.find_secondary_lines(lines_and_symbols, include_signal=False) |
230 |
|
231 |
# double check conn line cuz startLine may need at first step
|
232 |
for lineno in self._lineNos: |
233 |
lineno.conns.clear() |
234 |
minDist = None
|
235 |
startLine = None
|
236 |
if len(lineno.runs) is 0: |
237 |
continue
|
238 |
for line in [line for line in lineno.runs[0].items if |
239 |
type(line) is QEngineeringLineItem and line.is_piping(strong=True)]: |
240 |
dist = line.distanceTo((lineno.center().x(), lineno.center().y())) |
241 |
if (minDist is None) or (dist < minDist): |
242 |
minDist = dist |
243 |
startLine = line |
244 |
if (startLine is not None): # and (minDist < toler): |
245 |
lineno.conns.append(startLine) |
246 |
|
247 |
if updateProgress: updateProgress.emit(self.maxValue) |
248 |
|
249 |
# make trim lines
|
250 |
updateProgress.emit(-1) # reset progressbar |
251 |
displayMessage.emit('Unknown line Topology Construction')
|
252 |
orphanLines = [line for line in self._lines if line.owner is None] |
253 |
orphanSymbols = [symbol for symbol in self._symbols if |
254 |
symbol.owner is None and type(symbol) is not QEngineeringEquipmentItem] |
255 |
if orphanLines + orphanSymbols:
|
256 |
self.maxValue = len(orphanLines) + 1 |
257 |
orphanLines = sorted(orphanLines, key=lambda param: param.length(), reverse=True) |
258 |
orphans = orphanLines + orphanSymbols |
259 |
while len(orphans) > 0: |
260 |
trimLineNo = QEngineeringTrimLineNoTextItem() |
261 |
trimLineNo.conns.append(orphans[0])
|
262 |
orphans[0].owner = trimLineNo
|
263 |
# orphanLines[0].linkedItem = trimLineNo
|
264 |
|
265 |
connectedItems = self.find_primary_lines(trimLineNo)
|
266 |
for item in connectedItems: |
267 |
if item in orphans: |
268 |
orphans.remove(item) |
269 |
updateProgress.emit(self.maxValue)
|
270 |
|
271 |
self.find_secondary_lines(orphans, is_trim=True) |
272 |
for item_index in reversed(range(len(orphans))): |
273 |
item = orphans[item_index] |
274 |
if item.owner is not None: |
275 |
orphans.remove(item) |
276 |
updateProgress.emit(self.maxValue)
|
277 |
|
278 |
app_doc_data.tracerLineNos.append(trimLineNo) |
279 |
|
280 |
if updateProgress: updateProgress.emit(self.maxValue) |
281 |
except Exception as ex: |
282 |
from App import App |
283 |
|
284 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
285 |
sys.exc_info()[-1].tb_lineno)
|
286 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
287 |
|
288 |
'''
|
289 |
@brief find objects connected to given line while loop
|
290 |
@author humkyung
|
291 |
@date 2018.04.16
|
292 |
@history humkyung 2018.05.08 find symbol or line connected to given object
|
293 |
humkyung 2018.05.10 set found object's owner
|
294 |
humkyung 2018.05.17 try to connect both symbol and line
|
295 |
humkyung 2018.06.22 order connected objects
|
296 |
'''
|
297 |
|
298 |
def find_connected_objects(self, start, to=None, primary=False, include_signal=True): |
299 |
from EngineeringLineItem import QEngineeringLineItem |
300 |
from EngineeringEquipmentItem import QEngineeringEquipmentItem |
301 |
from EngineeringInstrumentItem import QEngineeringInstrumentItem |
302 |
from SymbolSvgItem import SymbolSvgItem |
303 |
|
304 |
visited = [start] |
305 |
break_at_first = None
|
306 |
|
307 |
try:
|
308 |
pool = [] |
309 |
pool.append((0, start))
|
310 |
|
311 |
while len(pool) > 0: |
312 |
sign, obj = pool.pop() |
313 |
|
314 |
# """ check obj is upstream or downstream of spec break """
|
315 |
# matches = [spec_break for spec_break in self._spec_breaks if spec_break.is_connected(obj)]
|
316 |
# if matches or issubclass(type(obj), QEngineeringEquipmentItem):
|
317 |
# visited.pop(visited.index(obj))
|
318 |
# continue
|
319 |
# print('obj={} pool={}'.format(obj, pool))
|
320 |
|
321 |
match = False
|
322 |
if not primary: |
323 |
for end_break in self._end_breaks: |
324 |
if obj is end_break.owner or obj is end_break.prop('Connected Item'): |
325 |
if end_break.owner.is_connected(end_break.prop('Connected Item')) and \ |
326 |
end_break.prop('Connected Item').is_connected(end_break.owner) and \ |
327 |
len(visited) is not 1: |
328 |
match = True
|
329 |
if obj.is_connected(break_at_first):
|
330 |
visited.pop(visited.index(obj)) |
331 |
break
|
332 |
elif end_break.owner.is_connected(end_break.prop('Connected Item')) and \ |
333 |
end_break.prop('Connected Item').is_connected(end_break.owner):
|
334 |
break_at_first = obj |
335 |
break
|
336 |
|
337 |
if issubclass(type(obj), QEngineeringEquipmentItem): |
338 |
visited.pop(visited.index(obj)) |
339 |
continue
|
340 |
elif match:
|
341 |
continue
|
342 |
|
343 |
""" end loop if obj is to """
|
344 |
if to is not None and str(obj.uid) == str(to.uid): break |
345 |
|
346 |
# nextmatches list always has one item
|
347 |
if type(obj) is QEngineeringLineItem: |
348 |
symbolMatches = [x for x in self._symbols if (x.owner is None or x.owner == start.owner) and ( |
349 |
x not in visited) and obj.is_connected(x)] |
350 |
if include_signal:
|
351 |
lineMatches = [x for x in self._lines if |
352 |
(x.owner is None or x.owner == start.owner) and (x is not obj) and ( |
353 |
x not in visited) and obj.is_connected(x)] |
354 |
else:
|
355 |
lineMatches = [x for x in self._lines if |
356 |
x.is_piping() and (x.owner is None or x.owner == start.owner) and ( |
357 |
x is not obj) and (x not in visited) and obj.is_connected(x)] |
358 |
nextMatches = symbolMatches + lineMatches |
359 |
|
360 |
elif issubclass(type(obj), SymbolSvgItem): |
361 |
# symbol can be connected with line and another symbol at the same time
|
362 |
if include_signal:
|
363 |
lineMatches = [x for x in self._lines if (x.owner is None or x.owner == start.owner) and ( |
364 |
x not in visited) and obj.is_connected(x)] |
365 |
else:
|
366 |
lineMatches = [x for x in self._lines if |
367 |
x.is_piping() and (x.owner is None or x.owner == start.owner) and ( |
368 |
x not in visited) and obj.is_connected(x)] |
369 |
symbolMatches = [x for x in self._symbols if |
370 |
(x.owner is None or x.owner == start.owner) and (x is not obj) and ( |
371 |
x not in visited) and obj.is_connected(x, None)] |
372 |
nextMatches = symbolMatches + lineMatches |
373 |
|
374 |
if len(nextMatches) > 1: # choose one if connected items are more than 2 |
375 |
matches = [x for x in visited if obj.is_connected(x)] |
376 |
if matches:
|
377 |
next_connected = [x for x in nextMatches if obj.next_connected(x, matches[0])] |
378 |
|
379 |
if next_connected:
|
380 |
nextMatches = next_connected |
381 |
else:
|
382 |
nextMatches = [] |
383 |
|
384 |
# if obj symbol has break connector and nextMatch connected that connector than break line group
|
385 |
if nextMatches and obj.break_connector and [index for index in obj.break_connector if |
386 |
obj.connectors[index].connectedItem is nextMatches[0]]: |
387 |
match = True
|
388 |
break
|
389 |
|
390 |
# if obj item connected symbol that has break connector then break line group
|
391 |
if nextMatches:
|
392 |
pop_index = [] |
393 |
index = 0
|
394 |
for nextMatch in nextMatches: |
395 |
if hasattr(nextMatch, 'break_connector'): |
396 |
if [index for index in nextMatch.break_connector if |
397 |
nextMatch.connectors[index].connectedItem is obj]:
|
398 |
pop_index.append(index) |
399 |
index += 1
|
400 |
|
401 |
for index in reversed(pop_index): |
402 |
nextMatches.pop(index) |
403 |
|
404 |
# order connected objects
|
405 |
matches = [] |
406 |
matches.extend(nextMatches) |
407 |
|
408 |
if sign == 0 and len(matches) > 1: |
409 |
mid = int(len(matches) * 0.5) |
410 |
lhs = matches[0:mid]
|
411 |
rhs = matches[mid:] |
412 |
elif sign == -1: |
413 |
lhs = matches |
414 |
rhs = [] |
415 |
else:
|
416 |
lhs = [] |
417 |
rhs = matches |
418 |
|
419 |
for match in lhs: |
420 |
# print(match)
|
421 |
pool.append((-1, match))
|
422 |
visited.insert(0, match)
|
423 |
|
424 |
for match in rhs: |
425 |
# print(match)
|
426 |
pool.append((1, match))
|
427 |
visited.append(match) |
428 |
# up to here
|
429 |
|
430 |
except Exception as ex: |
431 |
from App import App |
432 |
|
433 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
434 |
sys.exc_info()[-1].tb_lineno)
|
435 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
436 |
|
437 |
# print(visited)
|
438 |
return visited
|
439 |
|
440 |
|
441 |
'''
|
442 |
@brief connect attributes
|
443 |
@author humkyung
|
444 |
@date 2018.06.17
|
445 |
@history humkyung 2018.06.21 paste connect attributes codes from recognizeLine function
|
446 |
kyouho 2018.09.14 clear Item's owner
|
447 |
'''
|
448 |
async def connectAttrImpl(worker, update_line_type, update_flow_mark, update_spec): |
449 |
from App import App |
450 |
import uuid |
451 |
from LineNoTracer import LineNoTracer |
452 |
from AppDocData import AppDocData |
453 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
454 |
from EngineeringSpecBreakItem import QEngineeringSpecBreakItem |
455 |
from EngineeringInstrumentItem import QEngineeringInstrumentItem |
456 |
from EngineeringReducerItem import QEngineeringReducerItem |
457 |
from EngineeringEquipmentItem import QEngineeringEquipmentItem |
458 |
from QEngineeringOPCItem import QEngineeringOPCItem |
459 |
from EngineeringSpecBreakItem import QEngineeringSpecBreakItem |
460 |
from EngineeringVendorItem import QEngineeringVendorItem |
461 |
from EngineeringEndBreakItem import QEngineeringEndBreakItem |
462 |
from EngineeringFlowMarkItem import QEngineeringFlowMarkItem |
463 |
from EngineeringReservedWordTextItem import QEngineeringReservedWordTextItem |
464 |
from QEngineeringSizeTextItem import QEngineeringSizeTextItem |
465 |
from EngineeringValveOperCodeTextItem import QEngineeringValveOperCodeTextItem |
466 |
from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem |
467 |
from QEngineeringTagNoTextItem import QEngineeringTagNoTextItem |
468 |
from EngineeringErrorItem import QEngineeringErrorItem |
469 |
from EngineeringTextItem import QEngineeringTextItem |
470 |
from SpecialItemTypesDialog import SpecialItemTracer |
471 |
|
472 |
try:
|
473 |
docdata = AppDocData.instance() |
474 |
worker.display_message.emit('Initializing...')
|
475 |
|
476 |
ALL_ITEM = [item for item in worker.scene.items() if issubclass(type(item), QEngineeringAbstractItem)] |
477 |
for item in ALL_ITEM: |
478 |
item.setVisible(False)
|
479 |
QApplication.processEvents() |
480 |
|
481 |
symbols = [] |
482 |
lines = [item for item in worker.scene.items() if type(item) is QEngineeringLineItem] |
483 |
lineNos = [] |
484 |
spec_breaks = [] |
485 |
lineIndicator = [] |
486 |
vendor_packages = [item for item in worker.scene.items() if |
487 |
type(item) is QEngineeringVendorItem and item.pack_type == 'Vendor Package'] |
488 |
equip_packages = [item for item in worker.scene.items() if |
489 |
type(item) is QEngineeringVendorItem and item.pack_type == 'Equipment Package'] |
490 |
end_breaks = [] |
491 |
notes = [] |
492 |
flow_marks = [] |
493 |
|
494 |
for error_item in [item for item in worker.scene.items() if type(item) is QEngineeringErrorItem]: |
495 |
error_item.transfer.onRemoved.emit(error_item) |
496 |
|
497 |
for end_break in [item for item in worker.scene.items() if type(item) is QEngineeringEndBreakItem]: |
498 |
if not end_break.prop('Freeze'): |
499 |
end_break.transfer.onRemoved.emit(end_break) |
500 |
else:
|
501 |
end_breaks.append(end_break) |
502 |
|
503 |
QApplication.processEvents() |
504 |
|
505 |
'''
|
506 |
for flow_mark in [item for item in worker.scene.items() if type(item) is QEngineeringFlowMarkItem]:
|
507 |
if not flow_mark.prop('Freeze'):
|
508 |
flow_mark.transfer.onRemoved.emit(flow_mark)
|
509 |
else:
|
510 |
flow_marks.append(flow_mark)
|
511 |
'''
|
512 |
|
513 |
configs = docdata.getConfigs('Supplied by Tag Rule', 'by Vendor') |
514 |
vendorTag = configs[0].value if configs else 'By Vendor' |
515 |
for item in worker.scene.items(): |
516 |
if type(item) is QEngineeringSpecBreakItem: |
517 |
spec_breaks.append(item) |
518 |
elif issubclass(type(item), SymbolSvgItem) and not (type(item) is QEngineeringErrorItem) and not ( |
519 |
type(item) is QEngineeringUnknownItem) and item.type != 'Notes' and not ( |
520 |
type(item) is QEngineeringEndBreakItem): |
521 |
matches = [vendor_package for vendor_package in vendor_packages if vendor_package.includes(item)] |
522 |
if matches:
|
523 |
item.set_property('Supplied By', vendorTag)
|
524 |
else:
|
525 |
item.set_property('Supplied By', '') |
526 |
symbols.append(item) |
527 |
elif type(item) is QEngineeringLineNoTextItem: |
528 |
lineNos.append(item) |
529 |
elif type(item) is QEngineeringLineItem: |
530 |
# matches = [vendor_package for vendor_package in vendor_packages if vendor_package.includes(item)]
|
531 |
# if not matches: lines.append(item)
|
532 |
# for check line disappear bug
|
533 |
pass
|
534 |
# lines.append(item)
|
535 |
elif type(item) is QEngineeringUnknownItem and item.lineIndicator != 'False': |
536 |
lineIndicator.append(item) |
537 |
elif issubclass(type(item), QEngineeringTextItem): |
538 |
item.owner = None
|
539 |
elif item.type == 'Notes': |
540 |
notes.append(item) |
541 |
|
542 |
QApplication.processEvents() |
543 |
|
544 |
# remove unknown line's
|
545 |
pastTrim = docdata.tracerLineNos |
546 |
treeWidget = App.mainWnd().itemTreeWidget |
547 |
for pastTrimIndex in reversed(range(len(pastTrim))): |
548 |
if type(pastTrim[pastTrimIndex]) is QEngineeringTrimLineNoTextItem: |
549 |
try:
|
550 |
connected_items = pastTrim[pastTrimIndex].getConnectedItems() |
551 |
for item in connected_items: |
552 |
treeWidget.addTreeItem(treeWidget.SymbolsTreeItem, item) |
553 |
pastTrim[pastTrimIndex].explode() |
554 |
finally:
|
555 |
pass
|
556 |
|
557 |
# trace line no
|
558 |
tracer = LineNoTracer(symbols, lines, lineNos, spec_breaks, lineIndicator, vendor_packages, end_breaks) |
559 |
tracer.execute(worker.display_message, worker.updateProgress) |
560 |
# up to here
|
561 |
|
562 |
# connect attribute
|
563 |
worker.display_message.emit('Connecting Attribute...')
|
564 |
QApplication.processEvents() |
565 |
texts = [item for item in worker.scene.items() if issubclass(type(item), QEngineeringTextItem)] |
566 |
for symbol in symbols: |
567 |
try:
|
568 |
symbol.connectAttribute(texts) |
569 |
except Exception as ex: |
570 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
571 |
sys.exc_info()[-1].tb_lineno)
|
572 |
worker.display_message.emit(message) |
573 |
|
574 |
""" try to connect label to valve """
|
575 |
labels = [symbol for symbol in symbols if symbol.iType == 19] # Labels - Symbol => Instrument |
576 |
valves = [symbol for symbol in symbols if |
577 |
symbol.iType == 34 or symbol.iType == 17 or symbol.iType == 22] # Specialty Components, In-Line, Relief Devices |
578 |
for label in labels: |
579 |
label.connectAttribute(valves, clear=False)
|
580 |
|
581 |
# for slope, etc.., symbol to line
|
582 |
labels = [symbol for symbol in symbols if symbol.iType == 30] # Labels - Line => Piping |
583 |
for label in labels: |
584 |
label.connectAttribute(lines, clear=False)
|
585 |
|
586 |
'''
|
587 |
# for alarm, symbol to symbol : no more used
|
588 |
labels = [symbol for symbol in symbols if symbol.iType == 29] # Labels - Piping Components => Instrument
|
589 |
valves = [symbol for symbol in symbols if symbol.iType == 25] # System Functions
|
590 |
for label in labels:
|
591 |
label.connectAttribute(valves, clear=False)
|
592 |
'''
|
593 |
|
594 |
QApplication.processEvents() |
595 |
for symbol in symbols: |
596 |
for assoc in symbol.associations(): |
597 |
if assoc.owner is None: |
598 |
assoc.owner = symbol |
599 |
|
600 |
""" restore note text item owner """
|
601 |
for note in notes: |
602 |
for noteText in note.associations(): |
603 |
noteText.owner = note |
604 |
|
605 |
""" try to find text item's owner """
|
606 |
texts = [item for item in worker.scene.items() if type(item) is QEngineeringReservedWordTextItem] |
607 |
for text in texts: |
608 |
text.findOwner(lines) |
609 |
|
610 |
QApplication.processEvents() |
611 |
# restore and save manual edited attr's text item
|
612 |
texts = [item for item in worker.scene.items() if issubclass(type(item), QEngineeringTextItem)] |
613 |
targetText = [] |
614 |
for text in texts: |
615 |
found = False
|
616 |
for symbol in symbols + lines: |
617 |
for attr in list(symbol.attrs.keys()): |
618 |
# skip freezed attr or already consumed by symbol
|
619 |
if attr.AssocItem == text:
|
620 |
text.owner = symbol |
621 |
found = True
|
622 |
break
|
623 |
# restore missing attr
|
624 |
elif type(attr.AssocItem) is str or type(attr.AssocItem) is uuid.UUID: |
625 |
if str(attr.AssocItem) == str(text.uid): |
626 |
symbol.add_assoc_item(text) |
627 |
attr.AssocItem = text |
628 |
text.owner = symbol |
629 |
found = True
|
630 |
break
|
631 |
if found: break |
632 |
if not found and ( |
633 |
type(text) is QEngineeringSizeTextItem or type(text) is QEngineeringValveOperCodeTextItem or \ |
634 |
type(text) is QEngineeringTagNoTextItem or type(text) is QEngineeringTextItem): |
635 |
targetText.append(text) |
636 |
|
637 |
worker.need_update_texts = [] |
638 |
targetText = sorted(targetText, key=lambda param: len(param.text()), reverse=True) |
639 |
for symbol in symbols + equip_packages: |
640 |
symbol._skip = False
|
641 |
for text in targetText: |
642 |
ret = text.findOwner(symbols) if type(text) is not QEngineeringTagNoTextItem else text.findOwner( |
643 |
symbols + equip_packages) |
644 |
if ret:
|
645 |
worker.need_update_texts.append([text, ret]) |
646 |
|
647 |
""" update line type """
|
648 |
if update_line_type:
|
649 |
worker.display_message.emit('Updating Line Type...')
|
650 |
for line in lines: |
651 |
line.update_line_type() |
652 |
|
653 |
QApplication.processEvents() |
654 |
""" make end break """
|
655 |
make_end_break(worker, end_breaks, lineNos) |
656 |
|
657 |
QApplication.processEvents() |
658 |
""" update spec break """
|
659 |
if update_spec:
|
660 |
make_spec(worker, spec_breaks, lines, lineNos) |
661 |
|
662 |
worker.updateProgress.emit(tracer.maxValue) |
663 |
|
664 |
# trace special item
|
665 |
worker.display_message.emit('Finding line for special item...')
|
666 |
QApplication.processEvents() |
667 |
tracer = SpecialItemTracer([item for item in worker.scene.items() if |
668 |
(type(item) is SymbolSvgItem or type(item) is QEngineeringTextItem) and |
669 |
item.special_item_type], lines) |
670 |
tracer.execute(worker.display_message, worker.updateProgress) |
671 |
# up to here
|
672 |
|
673 |
''' sort run flow order '''
|
674 |
worker.display_message.emit('Sorting Lines...')
|
675 |
QApplication.processEvents() |
676 |
sort_run_flow(worker) |
677 |
|
678 |
QApplication.processEvents() |
679 |
""" make flow mark """
|
680 |
if update_flow_mark:
|
681 |
make_flow_mark(worker, lines) |
682 |
|
683 |
''' get line no's from/to equipment '''
|
684 |
for lineNo in lineNos: |
685 |
lineNo.clear_attr_and_assoc_item() |
686 |
lineNo.EvaluatedEQ() |
687 |
|
688 |
ALL_ITEM = [item for item in worker.scene.items() if issubclass(type(item), QEngineeringAbstractItem)] |
689 |
for item in ALL_ITEM: |
690 |
item.setVisible(True)
|
691 |
|
692 |
except Exception as ex: |
693 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
694 |
sys.exc_info()[-1].tb_lineno)
|
695 |
worker.display_message.emit(message) |
696 |
except:
|
697 |
(type1, value, traceback) = sys.exc_info() |
698 |
sys.excepthook(type1, value, traceback) |
699 |
|
700 |
|
701 |
def make_end_break(worker, end_breaks, lineNos): |
702 |
''' make end break '''
|
703 |
|
704 |
from App import App |
705 |
import os |
706 |
|
707 |
try:
|
708 |
docdata = AppDocData.instance() |
709 |
|
710 |
end_break_names = docdata.getSymbolListByType('type', 'End Break') |
711 |
if len(end_break_names) is not 0: |
712 |
svgFileName = end_break_names[0].sName
|
713 |
symbol = end_break_names[0]
|
714 |
svgFilePath = os.path.join(docdata.getCurrentProject().getSvgFilePath(), symbol.getType(), |
715 |
svgFileName + '.svg')
|
716 |
|
717 |
lineNo_froms = [] |
718 |
lineNo_tos = [] |
719 |
|
720 |
for lineNo in lineNos: |
721 |
# lineNo_froms.append(lineNo.prop('From')) if lineNo.prop('From') is not None else None
|
722 |
# lineNo_tos.append(lineNo.prop('To')) if lineNo.prop('To') is not None else None
|
723 |
|
724 |
for run in lineNo.runs: |
725 |
start = [run.items[0]]
|
726 |
end = [run.items[-1]] if run.items[0] is not run.items[-1] else [] |
727 |
lineNo_froms.extend(start) |
728 |
lineNo_tos.extend(end) |
729 |
|
730 |
for line_end in lineNo_froms + lineNo_tos: |
731 |
# print(type(line_end))
|
732 |
for connector in line_end.connectors: |
733 |
if connector.connectedItem is not None and type( |
734 |
connector.connectedItem.owner) is QEngineeringLineNoTextItem and connector.connectedItem.owner is not line_end.owner: |
735 |
end_break = SymbolSvgItem.createItem(symbol.getType(), None, svgFilePath)
|
736 |
pt = [connector.center()[0] - float(symbol.getOriginalPoint().split(',')[0]), |
737 |
connector.center()[1] - float(symbol.getOriginalPoint().split(',')[1])] |
738 |
origin = [0, 0] |
739 |
if 2 == len(symbol.getOriginalPoint().split(',')): |
740 |
tokens = symbol.getOriginalPoint().split(',')
|
741 |
origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])] |
742 |
end_break.buildItem(svgFileName, symbol.getType(), 3.83, pt,
|
743 |
[end_break.boundingRect().width(), end_break.boundingRect().height()], |
744 |
origin, [], symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), |
745 |
symbol.getHasInstrumentLabel()) |
746 |
|
747 |
end_break.set_property('Connected Item', connector.connectedItem)
|
748 |
end_break.setToolTip('owner : ' + str(line_end)) |
749 |
end_break.area = 'Drawing'
|
750 |
end_break.owner = line_end |
751 |
end_breaks.append(end_break) |
752 |
|
753 |
if end_breaks:
|
754 |
# check duplication
|
755 |
dupl = set()
|
756 |
for i in range(len(end_breaks)): |
757 |
for j in range(len(end_breaks)): |
758 |
if i == j:
|
759 |
continue
|
760 |
else:
|
761 |
setI = set([end_breaks[i].owner, end_breaks[i].prop('Connected Item')]) |
762 |
setJ = set([end_breaks[j].owner, end_breaks[j].prop('Connected Item')]) |
763 |
if not (setI - setJ): |
764 |
index = [i, j] |
765 |
index.sort() |
766 |
index = tuple(index)
|
767 |
dupl.add(index) |
768 |
# print(dupl)
|
769 |
dupl = list(set( |
770 |
[(indexSet[1] if not end_breaks[indexSet[1]].prop('Freeze') else indexSet[0]) for indexSet in |
771 |
list(dupl)]))
|
772 |
dupl.sort(reverse=True)
|
773 |
# print(dupl)
|
774 |
for index in dupl: |
775 |
end_breaks.pop(index) |
776 |
|
777 |
for end_break in end_breaks: |
778 |
if not end_break.prop('Freeze'): |
779 |
end_break.transfer.onRemoved.connect(App.mainWnd().itemRemoved) |
780 |
# end break can be modeled only piping line
|
781 |
if (type(end_break.owner) is not QEngineeringLineItem or ( |
782 |
type(end_break.owner) is QEngineeringLineItem and ( |
783 |
end_break.owner.lineType == 'Secondary' or end_break.owner.lineType == 'Primary'))) \ |
784 |
and (type(end_break.prop('Connected Item')) is not QEngineeringLineItem or ( |
785 |
type(end_break.prop('Connected Item')) is QEngineeringLineItem and ( |
786 |
end_break.prop('Connected Item').lineType == 'Secondary' or end_break.prop( |
787 |
'Connected Item').lineType == 'Primary'))): |
788 |
end_break.addSvgItemToScene(worker.scene) |
789 |
|
790 |
except Exception as ex: |
791 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
792 |
sys.exc_info()[-1].tb_lineno)
|
793 |
worker.display_message.emit(message) |
794 |
|
795 |
|
796 |
def make_spec(worker, spec_breaks, lines, lineNos): |
797 |
''' update spec break '''
|
798 |
|
799 |
from App import App |
800 |
import os, math |
801 |
|
802 |
try:
|
803 |
docdata = AppDocData.instance() |
804 |
|
805 |
freezed_spec_breaks = [] |
806 |
for spec_break in spec_breaks: |
807 |
if not spec_break.prop('Freeze'): |
808 |
spec_break.transfer.onRemoved.emit(spec_break) |
809 |
else:
|
810 |
freezed_spec_breaks.append(spec_break) |
811 |
|
812 |
for line in lines: |
813 |
line.clear_labels() |
814 |
|
815 |
spec_break_names = docdata.getSymbolListByType('type', 'Segment Breaks') |
816 |
if len(spec_break_names) is not 0: |
817 |
configs = docdata.getConfigs('Range', 'Detection Ratio') |
818 |
ratio = float(configs[0].value) if 1 == len(configs) else 1.5 |
819 |
ratio *= 2
|
820 |
|
821 |
svgFileName = spec_break_names[0].sName
|
822 |
symbol = spec_break_names[0]
|
823 |
svgFilePath = os.path.join(docdata.getCurrentProject().getSvgFilePath(), symbol.getType(), |
824 |
svgFileName + '.svg')
|
825 |
|
826 |
specBreakAttrsFull = [attr for attr in docdata.getSymbolAttribute('Segment Breaks') if |
827 |
attr.Target == 'ALL' and ( |
828 |
attr.AttributeType == 'Spec' or attr.AttributeType == 'String')] |
829 |
specBreakAttrs = [attr.Attribute for attr in specBreakAttrsFull] |
830 |
|
831 |
line_ends = [] |
832 |
# append upstream first and append downstream
|
833 |
for lineNo in lineNos: |
834 |
for run in lineNo.runs: |
835 |
line_ends.append(run.items[0]) if issubclass(type(run.items[0]), SymbolSvgItem) or ( |
836 |
type(run.items[0]) is QEngineeringLineItem and ( |
837 |
run.items[0].lineType == 'Secondary' or run.items[ |
838 |
0].lineType == 'Primary')) else None |
839 |
for lineNo in lineNos: |
840 |
for run in lineNo.runs: |
841 |
if run.items[0] is not run.items[-1]: |
842 |
line_ends.append(run.items[-1]) if issubclass(type(run.items[-1]), SymbolSvgItem) or ( |
843 |
type(run.items[-1]) is QEngineeringLineItem and ( |
844 |
run.items[-1].lineType == 'Secondary' or run.items[ |
845 |
-1].lineType == 'Primary')) else None |
846 |
|
847 |
spec_breaks = [] |
848 |
for line_end in line_ends: |
849 |
for connector in line_end.connectors: |
850 |
if connector.connectedItem is not None and type( |
851 |
connector.connectedItem.owner) is QEngineeringLineNoTextItem and connector.connectedItem.owner is not line_end.owner: |
852 |
spec_break = [] # upstream, downstream, [spec, up value, down value], ... , [ ... ]
|
853 |
match = False
|
854 |
for prop, value in [[prop, value] for prop, value in line_end.owner.getAttributes().items() |
855 |
if prop.Attribute in specBreakAttrs]: |
856 |
for prop2, value2 in [[prop2, value2] for prop2, value2 in |
857 |
connector.connectedItem.owner.getAttributes().items() if
|
858 |
prop2.Attribute in specBreakAttrs and prop2.UID == prop.UID]: |
859 |
if str(prop.UID) == str(prop2.UID) and value != value2: |
860 |
if not match: |
861 |
spec_break.extend([line_end, connector.connectedItem]) |
862 |
match = True
|
863 |
spec_break.append([prop.Attribute, value, value2]) |
864 |
if match:
|
865 |
spec_breaks.append(spec_break) |
866 |
|
867 |
if spec_breaks:
|
868 |
# check duplication
|
869 |
dupl = set()
|
870 |
for i in range(len(spec_breaks)): |
871 |
for j in range(len(spec_breaks)): |
872 |
if i == j:
|
873 |
continue
|
874 |
else:
|
875 |
setI = set([spec_breaks[i][0], spec_breaks[i][1]]) |
876 |
setJ = set([spec_breaks[j][0], spec_breaks[j][1]]) |
877 |
if not (setI - setJ): |
878 |
index = [i, j] |
879 |
index.sort() |
880 |
index = tuple(index)
|
881 |
dupl.add(index) |
882 |
dupl = list(set([(indexSet[1]) for indexSet in list(dupl)])) |
883 |
dupl.sort(reverse=True)
|
884 |
for index in dupl: |
885 |
spec_breaks.pop(index) |
886 |
# up to here
|
887 |
|
888 |
spec_break_items = [] |
889 |
for spec in spec_breaks: |
890 |
dupl = False
|
891 |
for freezed in freezed_spec_breaks: |
892 |
freezed_attrs = freezed.getAttributes() |
893 |
up = [attr.AssocItem for attr in freezed_attrs if attr.Attribute == 'UpStream'] |
894 |
down = [attr.AssocItem for attr in freezed_attrs if attr.Attribute == 'DownStream'] |
895 |
if up and down: |
896 |
if (up[0] is spec[0] and down[0] is spec[1]) or ( |
897 |
up[0] is spec[1] and down[0] is spec[0]): |
898 |
dupl = True
|
899 |
break
|
900 |
if dupl:
|
901 |
continue
|
902 |
|
903 |
for connector in spec[0].connectors: |
904 |
if connector.connectedItem is spec[1]: |
905 |
spec_break = SymbolSvgItem.createItem(symbol.getType(), None, svgFilePath)
|
906 |
pt = [40 + connector.center()[0] - float(symbol.getOriginalPoint().split(',')[0]), |
907 |
60 + connector.center()[1] - float(symbol.getOriginalPoint().split(',')[1])] |
908 |
origin = [0, 0] |
909 |
if 2 == len(symbol.getOriginalPoint().split(',')): |
910 |
tokens = symbol.getOriginalPoint().split(',')
|
911 |
origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])] |
912 |
spec_break.buildItem(svgFileName, symbol.getType(), 3.14, pt,
|
913 |
[spec_break.boundingRect().width(), |
914 |
spec_break.boundingRect().height()], origin, [], |
915 |
symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), |
916 |
symbol.getHasInstrumentLabel()) |
917 |
|
918 |
attrs = spec_break.getAttributes() |
919 |
for key in attrs.keys(): |
920 |
if key.Attribute == 'UpStream': |
921 |
attrs[key] = str(spec[0]) |
922 |
spec_break.add_assoc_item(spec[0], key.AttrAt, force=True) |
923 |
key.AssocItem = spec[0]
|
924 |
elif key.Attribute == 'DownStream': |
925 |
attrs[key] = str(spec[1]) |
926 |
spec_break.add_assoc_item(spec[1], key.AttrAt, force=True) |
927 |
key.AssocItem = spec[1]
|
928 |
|
929 |
for attr, value, value2 in spec[2:]: |
930 |
for full in specBreakAttrsFull: |
931 |
if full.Attribute == attr:
|
932 |
attrs[full] = [value, value2] |
933 |
|
934 |
# find label text for spec break line
|
935 |
stream_line = [spec[0], spec[1]] |
936 |
stream_track = [spec[1], spec[0]] |
937 |
stream_res = [False, False] |
938 |
for index in range(len(stream_line)): |
939 |
while True: |
940 |
if type(stream_line[index]) is QEngineeringLineItem: |
941 |
stream_res[index] = True
|
942 |
break
|
943 |
else:
|
944 |
find_next = False
|
945 |
connected_count = 0
|
946 |
for connectorr in stream_line[index].connectors: |
947 |
connected_count += 1
|
948 |
if connectorr.connectedItem and stream_track[ |
949 |
index] is not connectorr.connectedItem and stream_line[ |
950 |
index].next_connected(stream_track[index], |
951 |
connectorr.connectedItem): |
952 |
stream_track[index] = stream_line[index] |
953 |
stream_line[index] = connectorr.connectedItem |
954 |
find_next = True
|
955 |
break
|
956 |
|
957 |
if not find_next: |
958 |
# prevent infinite loop
|
959 |
if connected_count == 2: |
960 |
for connectorr in stream_line[index].connectors: |
961 |
if connectorr.connectedItem and not connectorr.connectedItem is \ |
962 |
stream_track[index]: |
963 |
stream_line[index] = connectorr.connectedItem |
964 |
stream_track[index] = stream_line[index] |
965 |
find_next = True
|
966 |
break
|
967 |
if not find_next: |
968 |
break
|
969 |
else:
|
970 |
break
|
971 |
|
972 |
if stream_res[0] and stream_res[1]: |
973 |
texts = [item for item in worker.scene.items() if |
974 |
type(item) is QEngineeringTextItem and item.owner is None] |
975 |
positioning = False
|
976 |
|
977 |
for attr, value, value2 in spec[2:]: |
978 |
up_texts = [text for text in texts if text.text() == value] |
979 |
down_texts = [text for text in texts if text.text() == value2] |
980 |
up_down_texts = [up_texts, down_texts] |
981 |
up_down_find = [None, None] |
982 |
|
983 |
for index in range(len(up_down_texts)): |
984 |
minDist = sys.maxsize |
985 |
|
986 |
for up_down_text in up_down_texts[index]: |
987 |
dx = connector.center()[0] - up_down_text.center().x()
|
988 |
dy = connector.center()[1] - up_down_text.center().y()
|
989 |
dist = ( |
990 |
up_down_text.sceneBoundingRect().height() + up_down_text.sceneBoundingRect().width()) * ratio / 2
|
991 |
length = math.sqrt(dx * dx + dy * dy) |
992 |
if length < dist and length < minDist: |
993 |
up_down_find[index] = up_down_text |
994 |
|
995 |
if up_down_find[0] and up_down_find[1]: |
996 |
for index in range(len(stream_line)): |
997 |
attrs = stream_line[index].getAttributes() |
998 |
for key in attrs.keys(): |
999 |
if key.Attribute == attr:
|
1000 |
attrs[key] = up_down_find[index].text() |
1001 |
key.AssocItem = up_down_find[index] |
1002 |
stream_line[index].add_assoc_item(up_down_find[index], |
1003 |
key.AttrAt, force=True)
|
1004 |
up_down_find[index].owner = stream_line[index] |
1005 |
break
|
1006 |
|
1007 |
if not positioning: |
1008 |
# set spec break position between
|
1009 |
positioning = True
|
1010 |
new_x = round(
|
1011 |
(up_down_find[0].center().x() + up_down_find[1].center().x()) / 2) |
1012 |
new_y = round(
|
1013 |
(up_down_find[0].center().y() + up_down_find[1].center().y()) / 2) |
1014 |
spec_break.loc = [new_x - spec_break.symbolOrigin[0],
|
1015 |
new_y - spec_break.symbolOrigin[1]]
|
1016 |
spec_break.origin = [new_x, new_y] |
1017 |
|
1018 |
pivot = None
|
1019 |
for connector in spec[0].connectors: |
1020 |
if connector.connectedItem is spec[1]: |
1021 |
pivot = connector.sceneBoundingRect().center() |
1022 |
break
|
1023 |
|
1024 |
if abs(up_down_find[0].center().x() - up_down_find[ |
1025 |
1].center().x()) < abs( |
1026 |
up_down_find[0].center().y() - up_down_find[1].center().y()): |
1027 |
if new_x > pivot.x():
|
1028 |
spec_break.angle = 1.57
|
1029 |
else:
|
1030 |
spec_break.angle = 4.71239
|
1031 |
else:
|
1032 |
if new_y > pivot.y():
|
1033 |
spec_break.angle = 3.14
|
1034 |
else:
|
1035 |
spec_break.angle = 0
|
1036 |
|
1037 |
# make show prop true
|
1038 |
spec_break.set_property('Show', True) |
1039 |
|
1040 |
spec_break_items.append(spec_break) |
1041 |
|
1042 |
for spec_break_item in spec_break_items: |
1043 |
spec_break_item.transfer.onRemoved.connect(App.mainWnd().itemRemoved) |
1044 |
spec_break_item.addSvgItemToScene(worker.scene) |
1045 |
|
1046 |
spec_break_items.extend(freezed_spec_breaks) |
1047 |
except Exception as ex: |
1048 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
1049 |
sys.exc_info()[-1].tb_lineno)
|
1050 |
worker.display_message.emit(message) |
1051 |
|
1052 |
|
1053 |
def make_flow_mark(worker, lines): |
1054 |
''' make flow mark '''
|
1055 |
|
1056 |
try:
|
1057 |
docdata = AppDocData.instance() |
1058 |
|
1059 |
for line in lines: |
1060 |
line.flowMark = None
|
1061 |
# line.update_arrow()
|
1062 |
|
1063 |
configs = docdata.getConfigs('Flow Mark', 'Position') |
1064 |
position = int(configs[0].value) if 1 == len(configs) else 100 |
1065 |
configs = docdata.getConfigs('Flow Mark', 'Length') |
1066 |
length = int(configs[0].value) if 1 == len(configs) else 200 |
1067 |
|
1068 |
for line in [line for line in lines if line.is_piping(True)]: |
1069 |
line.update_flow_mark(position, length) |
1070 |
line.update_arrow() |
1071 |
# for lineNo in docdata.tracerLineNos:
|
1072 |
# lineNo.update_flow_mark(position, length)
|
1073 |
|
1074 |
except Exception as ex: |
1075 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
1076 |
sys.exc_info()[-1].tb_lineno)
|
1077 |
worker.display_message.emit(message) |
1078 |
|
1079 |
|
1080 |
def sort_run_flow(worker): |
1081 |
''' sort runs '''
|
1082 |
|
1083 |
from EngineeringLineTracerRunItem import QEngineeringLineTracerRunItem |
1084 |
|
1085 |
try:
|
1086 |
docdata = AppDocData.instance() |
1087 |
|
1088 |
fixed_run_infos = [] # QEngineeringLineTracerRunItem s
|
1089 |
waiting_run_infos = [] # QEngineeringLineTracerRunItem s
|
1090 |
runs = [] |
1091 |
# first step : make fixed run using symbol info
|
1092 |
for lineNo in [lineNo for lineNo in docdata.tracerLineNos if len(lineNo.runs) > 0]: |
1093 |
not_trim = True if type(lineNo) is QEngineeringLineNoTextItem else False |
1094 |
run_index = 0
|
1095 |
for run in lineNo.runs: |
1096 |
not_secondary = True if run_index is 0 else False |
1097 |
|
1098 |
# if from and to info already was entered, fix run flow
|
1099 |
if hasattr(lineNo, '_fixed') and lineNo._fixed and not_secondary: |
1100 |
fixed_run_infos.append(QEngineeringLineTracerRunItem(run, lineNo, not_trim, not_secondary)) |
1101 |
run_index += 1
|
1102 |
continue
|
1103 |
|
1104 |
reference_symbols = [item for item in run.items if |
1105 |
issubclass(type(item), SymbolSvgItem) and item.has_in_out_connector()] |
1106 |
# runs can know flow directly
|
1107 |
if len(run.items) > 1 and len(reference_symbols) > 0: |
1108 |
for reference_symbol in reference_symbols: |
1109 |
# place at first
|
1110 |
if reference_symbol is run.items[0]: |
1111 |
if len([connector_index for connector_index in reference_symbol.in_out_connector[0] \ |
1112 |
if reference_symbol.connectors[connector_index].connectedItem is run.items[1]]) > 0: |
1113 |
info = QEngineeringLineTracerRunItem(run, lineNo, not_trim, not_secondary) |
1114 |
info.reverse() |
1115 |
fixed_run_infos.append(info) |
1116 |
break
|
1117 |
elif len([connector_index for connector_index in reference_symbol.in_out_connector[1] \ |
1118 |
if
|
1119 |
reference_symbol.connectors[connector_index].connectedItem is run.items[1]]) > 0: |
1120 |
info = QEngineeringLineTracerRunItem(run, lineNo, not_trim, not_secondary) |
1121 |
fixed_run_infos.append(info) |
1122 |
break
|
1123 |
# place at last
|
1124 |
elif reference_symbol is run.items[-1]: |
1125 |
if len([connector_index for connector_index in reference_symbol.in_out_connector[1] \ |
1126 |
if
|
1127 |
reference_symbol.connectors[connector_index].connectedItem is run.items[-2]]) > 0: |
1128 |
info = QEngineeringLineTracerRunItem(run, lineNo, not_trim, not_secondary) |
1129 |
info.reverse() |
1130 |
fixed_run_infos.append(info) |
1131 |
break
|
1132 |
elif len([connector_index for connector_index in reference_symbol.in_out_connector[0] \ |
1133 |
if
|
1134 |
reference_symbol.connectors[connector_index].connectedItem is run.items[-2]]) > 0: |
1135 |
info = QEngineeringLineTracerRunItem(run, lineNo, not_trim, not_secondary) |
1136 |
fixed_run_infos.append(info) |
1137 |
break
|
1138 |
# place at middle
|
1139 |
else:
|
1140 |
in_items = [reference_symbol.connectors[connector_index].connectedItem for connector_index
|
1141 |
in reference_symbol.in_out_connector[0] \ |
1142 |
if reference_symbol.connectors[connector_index].connectedItem in run.items] |
1143 |
out_items = [reference_symbol.connectors[connector_index].connectedItem for connector_index
|
1144 |
in reference_symbol.in_out_connector[1] \ |
1145 |
if reference_symbol.connectors[connector_index].connectedItem in run.items] |
1146 |
in_item = in_items[0] if in_items else None |
1147 |
out_item = out_items[0] if out_items else None |
1148 |
if in_item and out_item: |
1149 |
in_item_index = run.items.index(in_item) |
1150 |
out_item_index = run.items.index(out_item) |
1151 |
if out_item_index < in_item_index:
|
1152 |
info = QEngineeringLineTracerRunItem(run, lineNo, not_trim, not_secondary) |
1153 |
info.reverse() |
1154 |
fixed_run_infos.append(info) |
1155 |
break
|
1156 |
else:
|
1157 |
info = QEngineeringLineTracerRunItem(run, lineNo, not_trim, not_secondary) |
1158 |
fixed_run_infos.append(info) |
1159 |
break
|
1160 |
# only symbol runs doesn't need flow
|
1161 |
elif len(run.items) is 1 and issubclass(type(run.items[0]), SymbolSvgItem): |
1162 |
runs.append(QEngineeringLineTracerRunItem(run, lineNo, not_trim, not_secondary)) |
1163 |
# runs can't know flow directly
|
1164 |
else:
|
1165 |
waiting_run_infos.append(QEngineeringLineTracerRunItem(run, lineNo, not_trim, not_secondary)) |
1166 |
|
1167 |
run_index += 1
|
1168 |
|
1169 |
QApplication.processEvents() |
1170 |
# second step : determine waiting run flow, connected by point
|
1171 |
remain_count_past = len(waiting_run_infos)
|
1172 |
while True: |
1173 |
remain_count = 0
|
1174 |
for run_index in reversed(range(len(waiting_run_infos))): |
1175 |
waiting_run_info = waiting_run_infos[run_index] |
1176 |
waiting_run = waiting_run_info.run |
1177 |
|
1178 |
find = False
|
1179 |
for fixed_run_info in fixed_run_infos: |
1180 |
fixed_run = fixed_run_info.run |
1181 |
if len(waiting_run.items) > 1 and len(fixed_run.items) > 1: |
1182 |
# waiting_run and fix_run have items more than 2
|
1183 |
if waiting_run.items[0].is_connected(fixed_run.items[0]): |
1184 |
waiting_run_info.reverse() |
1185 |
fixed_run_infos.append(waiting_run_info) |
1186 |
waiting_run_infos.pop(run_index) |
1187 |
find = True
|
1188 |
break
|
1189 |
elif waiting_run.items[0].is_connected(fixed_run.items[-1]): |
1190 |
fixed_run_infos.append(waiting_run_info) |
1191 |
waiting_run_infos.pop(run_index) |
1192 |
find = True
|
1193 |
break
|
1194 |
elif waiting_run.items[-1].is_connected(fixed_run.items[-1]): |
1195 |
waiting_run_info.reverse() |
1196 |
fixed_run_infos.append(waiting_run_info) |
1197 |
waiting_run_infos.pop(run_index) |
1198 |
find = True
|
1199 |
break
|
1200 |
elif waiting_run.items[-1].is_connected(fixed_run.items[0]): |
1201 |
fixed_run_infos.append(waiting_run_info) |
1202 |
waiting_run_infos.pop(run_index) |
1203 |
find = True
|
1204 |
break
|
1205 |
elif len(fixed_run.items) > 1: |
1206 |
# waiting_run is single line
|
1207 |
if waiting_run.items[0].connectors[0].connectedItem is fixed_run.items[0]: |
1208 |
waiting_run_info.reverse() |
1209 |
fixed_run_infos.append(waiting_run_info) |
1210 |
waiting_run_infos.pop(run_index) |
1211 |
find = True
|
1212 |
break
|
1213 |
elif waiting_run.items[0].connectors[0].connectedItem is fixed_run.items[-1]: |
1214 |
fixed_run_infos.append(waiting_run_info) |
1215 |
waiting_run_infos.pop(run_index) |
1216 |
find = True
|
1217 |
break
|
1218 |
elif waiting_run.items[0].connectors[1].connectedItem is fixed_run.items[-1]: |
1219 |
waiting_run_info.reverse() |
1220 |
fixed_run_infos.append(waiting_run_info) |
1221 |
waiting_run_infos.pop(run_index) |
1222 |
find = True
|
1223 |
break
|
1224 |
elif waiting_run.items[0].connectors[1].connectedItem is fixed_run.items[0]: |
1225 |
fixed_run_infos.append(waiting_run_info) |
1226 |
waiting_run_infos.pop(run_index) |
1227 |
find = True
|
1228 |
break
|
1229 |
else:
|
1230 |
if waiting_run.items[0].is_connected(fixed_run.items[0]) and fixed_run.items[0].connectors[ |
1231 |
0].connectedItem is waiting_run.items[0]: |
1232 |
waiting_run.reverse() |
1233 |
fixed_run_infos.append(waiting_run_info) |
1234 |
waiting_run_infos.pop(run_index) |
1235 |
find = True
|
1236 |
break
|
1237 |
elif waiting_run.items[0].is_connected(fixed_run.items[0]) and fixed_run.items[0].connectors[ |
1238 |
1].connectedItem is waiting_run.items[0]: |
1239 |
fixed_run_infos.append(waiting_run_info) |
1240 |
waiting_run_infos.pop(run_index) |
1241 |
find = True
|
1242 |
break
|
1243 |
elif waiting_run.items[0].is_connected(fixed_run.items[0]) and fixed_run.items[0].connectors[ |
1244 |
1].connectedItem is waiting_run.items[0]: |
1245 |
waiting_run.reverse() |
1246 |
fixed_run_infos.append(waiting_run_info) |
1247 |
waiting_run_infos.pop(run_index) |
1248 |
find = True
|
1249 |
break
|
1250 |
elif waiting_run.items[0].is_connected(fixed_run.items[0]) and fixed_run.items[0].connectors[ |
1251 |
0].connectedItem is waiting_run.items[0]: |
1252 |
fixed_run_infos.append(waiting_run_info) |
1253 |
waiting_run_infos.pop(run_index) |
1254 |
find = True
|
1255 |
break
|
1256 |
if not find: |
1257 |
remain_count += 1
|
1258 |
|
1259 |
if remain_count_past == remain_count:
|
1260 |
break
|
1261 |
else:
|
1262 |
remain_count_past = remain_count |
1263 |
|
1264 |
QApplication.processEvents() |
1265 |
# third step : body connected run sort, not split
|
1266 |
remain_count_past = len(waiting_run_infos)
|
1267 |
while True: |
1268 |
remain_count = 0
|
1269 |
for run_index in reversed(range(len(waiting_run_infos))): |
1270 |
waiting_run_info = waiting_run_infos[run_index] |
1271 |
waiting_run = waiting_run_info.run |
1272 |
|
1273 |
find = False
|
1274 |
for fixed_run_info in fixed_run_infos: |
1275 |
fixed_run = fixed_run_info.run |
1276 |
if len(waiting_run.items) > 1 and len(fixed_run.items) > 1 and type( |
1277 |
waiting_run.items[0]) is QEngineeringLineItem and type( |
1278 |
waiting_run.items[-1]) is QEngineeringLineItem: |
1279 |
if waiting_run.items[0].connectors[0].connectedItem in fixed_run.items and \ |
1280 |
waiting_run.items[-1].connectors[1].connectedItem in fixed_run.items: |
1281 |
if fixed_run.items.index(
|
1282 |
waiting_run.items[0].connectors[0].connectedItem) > fixed_run.items.index( |
1283 |
waiting_run.items[-1].connectors[1].connectedItem): |
1284 |
waiting_run.reverse() |
1285 |
fixed_run_infos.append(waiting_run_info) |
1286 |
waiting_run_infos.pop(run_index) |
1287 |
find = True
|
1288 |
break
|
1289 |
else:
|
1290 |
fixed_run_infos.append(waiting_run_info) |
1291 |
waiting_run_infos.pop(run_index) |
1292 |
find = True
|
1293 |
break
|
1294 |
|
1295 |
if not find: |
1296 |
remain_count += 1
|
1297 |
|
1298 |
if remain_count_past == remain_count:
|
1299 |
break
|
1300 |
else:
|
1301 |
remain_count_past = remain_count |
1302 |
|
1303 |
# fourth step : body connected split run or split owner run sort
|
1304 |
fixed_merged_run_infos = [] # [[run_info1, run_info2, ... in order], [merged run with items]]
|
1305 |
waiting_merged_run_infos = [] # [[run_info1, run_info2, ... in order], [merged run with items]]
|
1306 |
|
1307 |
QApplication.processEvents() |
1308 |
# waiting run merge and sort
|
1309 |
consumed_count_past = 0
|
1310 |
for index1 in range(len(waiting_run_infos)): |
1311 |
if waiting_run_infos[index1].consumed:
|
1312 |
continue
|
1313 |
for index2 in range(len(waiting_run_infos)): |
1314 |
if index1 == index2 or waiting_run_infos[index2].consumed: |
1315 |
continue
|
1316 |
|
1317 |
result, merged_run_info, header, reverse = QEngineeringLineTracerRunItem.merge_and_sort_if_possible( |
1318 |
waiting_run_infos[index1], waiting_run_infos[index2]) |
1319 |
if result:
|
1320 |
waiting_run_infos[index1].consumed = True
|
1321 |
waiting_run_infos[index2].consumed = True
|
1322 |
consumed_count_past += 2
|
1323 |
if header:
|
1324 |
waiting_merged_run_infos.append( |
1325 |
[[waiting_run_infos[index2], waiting_run_infos[index1]], merged_run_info]) |
1326 |
else:
|
1327 |
waiting_merged_run_infos.append( |
1328 |
[[waiting_run_infos[index1], waiting_run_infos[index2]], merged_run_info]) |
1329 |
break
|
1330 |
|
1331 |
QApplication.processEvents() |
1332 |
while True: |
1333 |
consumed_count = 0
|
1334 |
for index in range(len(waiting_run_infos)): |
1335 |
if waiting_run_infos[index].consumed:
|
1336 |
consumed_count += 1
|
1337 |
continue
|
1338 |
|
1339 |
for waiting_merged_run_info in waiting_merged_run_infos: |
1340 |
result, merged_run_info, header, reverse = QEngineeringLineTracerRunItem.merge_and_sort_if_possible( |
1341 |
waiting_merged_run_info[1], waiting_run_infos[index])
|
1342 |
if result:
|
1343 |
waiting_run_infos[index].consumed = True
|
1344 |
consumed_count += 1
|
1345 |
if header:
|
1346 |
waiting_merged_run_info[0].insert(0, waiting_run_infos[index]) |
1347 |
waiting_merged_run_info[1] = merged_run_info
|
1348 |
else:
|
1349 |
waiting_merged_run_info[0].append(waiting_run_infos[index])
|
1350 |
waiting_merged_run_info[1] = merged_run_info
|
1351 |
break
|
1352 |
|
1353 |
if consumed_count_past == consumed_count:
|
1354 |
break
|
1355 |
else:
|
1356 |
consumed_count_past = consumed_count |
1357 |
|
1358 |
QApplication.processEvents() |
1359 |
while True: |
1360 |
merged = False
|
1361 |
for index1 in range(len(waiting_merged_run_infos)): |
1362 |
waiting_merged_run_info1 = waiting_merged_run_infos[index1] |
1363 |
for index2 in range(len(waiting_merged_run_infos)): |
1364 |
if index1 == index2:
|
1365 |
continue
|
1366 |
waiting_merged_run_info2 = waiting_merged_run_infos[index2] |
1367 |
result, merged_run_info, header, reverse = QEngineeringLineTracerRunItem.merge_and_sort_if_possible( |
1368 |
waiting_merged_run_info1[1], waiting_merged_run_info2[1], sort_connect_info=False) |
1369 |
if result:
|
1370 |
if header:
|
1371 |
if reverse:
|
1372 |
for waiting_run_info in waiting_merged_run_info2[0]: |
1373 |
waiting_run_info.reverse() |
1374 |
waiting_merged_run_info2[0].reverse()
|
1375 |
waiting_merged_run_info2[0].extend(waiting_merged_run_info1[0]) |
1376 |
waiting_merged_run_info1[0] = waiting_merged_run_info2[0] |
1377 |
waiting_merged_run_info1[1] = merged_run_info
|
1378 |
else:
|
1379 |
if reverse:
|
1380 |
for waiting_run_info in waiting_merged_run_info2[0]: |
1381 |
waiting_run_info.reverse() |
1382 |
waiting_merged_run_info2[0].reverse()
|
1383 |
waiting_merged_run_info1[0].extend(waiting_merged_run_info2[0]) |
1384 |
waiting_merged_run_info1[1] = merged_run_info
|
1385 |
merged = True
|
1386 |
break
|
1387 |
if merged:
|
1388 |
waiting_merged_run_infos.pop(index2) |
1389 |
break
|
1390 |
if not merged: |
1391 |
break
|
1392 |
|
1393 |
QApplication.processEvents() |
1394 |
# fixed run merge
|
1395 |
consumed_count_past = 0
|
1396 |
for index1 in range(len(fixed_run_infos)): |
1397 |
if fixed_run_infos[index1].consumed:
|
1398 |
continue
|
1399 |
for index2 in range(len(fixed_run_infos)): |
1400 |
if index1 == index2 or fixed_run_infos[index2].consumed: |
1401 |
continue
|
1402 |
|
1403 |
result, merged_run_info, header, reverse = QEngineeringLineTracerRunItem.merge_and_sort_if_possible( |
1404 |
fixed_run_infos[index1], fixed_run_infos[index2], sort=False)
|
1405 |
if result:
|
1406 |
fixed_run_infos[index1].consumed = True
|
1407 |
fixed_run_infos[index2].consumed = True
|
1408 |
consumed_count_past += 2
|
1409 |
if header:
|
1410 |
fixed_merged_run_infos.append( |
1411 |
[[fixed_run_infos[index2], fixed_run_infos[index1]], merged_run_info]) |
1412 |
else:
|
1413 |
fixed_merged_run_infos.append( |
1414 |
[[fixed_run_infos[index1], fixed_run_infos[index2]], merged_run_info]) |
1415 |
break
|
1416 |
|
1417 |
QApplication.processEvents() |
1418 |
while True: |
1419 |
consumed_count = 0
|
1420 |
for index in range(len(fixed_run_infos)): |
1421 |
if fixed_run_infos[index].consumed:
|
1422 |
consumed_count += 1
|
1423 |
continue
|
1424 |
|
1425 |
for fixed_merged_run_info in fixed_merged_run_infos: |
1426 |
result, merged_run_info, header, reverse = QEngineeringLineTracerRunItem.merge_and_sort_if_possible( |
1427 |
fixed_merged_run_info[1], fixed_run_infos[index], sort=False) |
1428 |
if result:
|
1429 |
fixed_run_infos[index].consumed = True
|
1430 |
consumed_count += 1
|
1431 |
if header:
|
1432 |
fixed_merged_run_info[0].insert(0, fixed_run_infos[index]) |
1433 |
fixed_merged_run_info[1] = merged_run_info
|
1434 |
else:
|
1435 |
fixed_merged_run_info[0].append(fixed_run_infos[index])
|
1436 |
fixed_merged_run_info[1] = merged_run_info
|
1437 |
break
|
1438 |
|
1439 |
if consumed_count_past == consumed_count:
|
1440 |
break
|
1441 |
else:
|
1442 |
consumed_count_past = consumed_count |
1443 |
|
1444 |
QApplication.processEvents() |
1445 |
while True: |
1446 |
merged = False
|
1447 |
for index1 in range(len(fixed_merged_run_infos)): |
1448 |
fixed_merged_run_info1 = fixed_merged_run_infos[index1] |
1449 |
for index2 in range(len(fixed_merged_run_infos)): |
1450 |
if index1 == index2:
|
1451 |
continue
|
1452 |
fixed_merged_run_info2 = fixed_merged_run_infos[index2] |
1453 |
result, merged_run_info, header, reverse = QEngineeringLineTracerRunItem.merge_and_sort_if_possible( |
1454 |
fixed_merged_run_info1[1], fixed_merged_run_info2[1], sort=False) |
1455 |
if result:
|
1456 |
if header:
|
1457 |
fixed_merged_run_info1[0] = fixed_merged_run_info2[0] |
1458 |
fixed_merged_run_info1[1] = merged_run_info
|
1459 |
else:
|
1460 |
fixed_merged_run_info1[0].extend(fixed_merged_run_info2[0]) |
1461 |
fixed_merged_run_info1[1] = merged_run_info
|
1462 |
merged = True
|
1463 |
break
|
1464 |
if merged:
|
1465 |
fixed_merged_run_infos.pop(index2) |
1466 |
break
|
1467 |
if not merged: |
1468 |
break
|
1469 |
|
1470 |
for fixed_run_info in fixed_run_infos: |
1471 |
if fixed_run_info.consumed:
|
1472 |
continue
|
1473 |
else:
|
1474 |
fixed_merged_run_infos.append([[fixed_run_info], fixed_run_info]) |
1475 |
|
1476 |
QApplication.processEvents() |
1477 |
# sort merged waiting runs by using merged fixed runs
|
1478 |
remain_count_past = len(waiting_merged_run_infos)
|
1479 |
while True: |
1480 |
remain_count = 0
|
1481 |
for run_index in reversed(range(len(waiting_merged_run_infos))): |
1482 |
waiting_run_info = waiting_merged_run_infos[run_index][0]
|
1483 |
waiting_merged_run = waiting_merged_run_infos[run_index][1].run
|
1484 |
|
1485 |
find = False
|
1486 |
for fixed_merged_run_info in fixed_merged_run_infos: |
1487 |
fixed_merged_run = fixed_merged_run_info[1].run
|
1488 |
if len(waiting_merged_run.items) > 1 and len(fixed_merged_run.items) > 1 and type( |
1489 |
waiting_merged_run.items[0]) is QEngineeringLineItem and type( |
1490 |
waiting_merged_run.items[-1]) is QEngineeringLineItem: |
1491 |
if waiting_merged_run.items[0].connectors[0].connectedItem in fixed_merged_run.items and \ |
1492 |
waiting_merged_run.items[-1].connectors[1].connectedItem in fixed_merged_run.items: |
1493 |
if fixed_merged_run.items.index(waiting_merged_run.items[0].connectors[ |
1494 |
0].connectedItem) > fixed_merged_run.items.index(
|
1495 |
waiting_merged_run.items[-1].connectors[1].connectedItem): |
1496 |
for waiting_run_info in waiting_merged_run_infos[run_index][0]: |
1497 |
waiting_run_info.reverse() |
1498 |
waiting_merged_run_infos[run_index][0].reverse()
|
1499 |
reverse_order = [] |
1500 |
for index in reversed(range(len(waiting_merged_run_infos[run_index][1].run.items))): |
1501 |
reverse_order.append(waiting_merged_run_infos[run_index][1].run.items[index])
|
1502 |
waiting_merged_run_infos[run_index][1].run.items = reverse_order
|
1503 |
fixed_merged_run_infos.append(waiting_merged_run_infos[run_index]) |
1504 |
waiting_merged_run_infos.pop(run_index) |
1505 |
find = True
|
1506 |
break
|
1507 |
else:
|
1508 |
fixed_merged_run_infos.append(waiting_merged_run_infos[run_index]) |
1509 |
waiting_merged_run_infos.pop(run_index) |
1510 |
find = True
|
1511 |
break
|
1512 |
|
1513 |
if not find: |
1514 |
remain_count += 1
|
1515 |
|
1516 |
if remain_count_past == remain_count:
|
1517 |
break
|
1518 |
else:
|
1519 |
remain_count_past = remain_count |
1520 |
except Exception as ex: |
1521 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
1522 |
sys.exc_info()[-1].tb_lineno)
|
1523 |
worker.display_message.emit(message) |
1524 |
|
1525 |
async def connectAttrImpl_inst(worker, update_line_type, update_flow_mark, update_spec): |
1526 |
from App import App |
1527 |
import uuid |
1528 |
from LineNoTracer import LineNoTracer |
1529 |
from AppDocData import AppDocData |
1530 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
1531 |
from EngineeringSpecBreakItem import QEngineeringSpecBreakItem |
1532 |
from EngineeringInstrumentItem import QEngineeringInstrumentItem |
1533 |
from EngineeringReducerItem import QEngineeringReducerItem |
1534 |
from EngineeringEquipmentItem import QEngineeringEquipmentItem |
1535 |
from QEngineeringOPCItem import QEngineeringOPCItem |
1536 |
from EngineeringSpecBreakItem import QEngineeringSpecBreakItem |
1537 |
from EngineeringVendorItem import QEngineeringVendorItem |
1538 |
from EngineeringEndBreakItem import QEngineeringEndBreakItem |
1539 |
from EngineeringFlowMarkItem import QEngineeringFlowMarkItem |
1540 |
from EngineeringReservedWordTextItem import QEngineeringReservedWordTextItem |
1541 |
from QEngineeringSizeTextItem import QEngineeringSizeTextItem |
1542 |
from EngineeringValveOperCodeTextItem import QEngineeringValveOperCodeTextItem |
1543 |
from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem |
1544 |
from QEngineeringTagNoTextItem import QEngineeringTagNoTextItem |
1545 |
from EngineeringErrorItem import QEngineeringErrorItem |
1546 |
from EngineeringTextItem import QEngineeringTextItem |
1547 |
from SpecialItemTypesDialog import SpecialItemTracer |
1548 |
|
1549 |
try:
|
1550 |
docdata = AppDocData.instance() |
1551 |
worker.display_message.emit('Initializing...')
|
1552 |
|
1553 |
ALL_ITEM = [item for item in worker.scene.items() if issubclass(type(item), QEngineeringAbstractItem)] |
1554 |
for item in ALL_ITEM: |
1555 |
item.setVisible(False)
|
1556 |
QApplication.processEvents() |
1557 |
|
1558 |
symbols = [] |
1559 |
lines = [item for item in worker.scene.items() if type(item) is QEngineeringLineItem] |
1560 |
lineNos = [] |
1561 |
equip_packages = [] |
1562 |
end_breaks = [] |
1563 |
|
1564 |
for error_item in [item for item in worker.scene.items() if type(item) is QEngineeringErrorItem]: |
1565 |
error_item.transfer.onRemoved.emit(error_item) |
1566 |
|
1567 |
for end_break in [item for item in worker.scene.items() if type(item) is QEngineeringEndBreakItem]: |
1568 |
if not end_break.prop('Freeze'): |
1569 |
end_break.transfer.onRemoved.emit(end_break) |
1570 |
else:
|
1571 |
end_breaks.append(end_break) |
1572 |
|
1573 |
QApplication.processEvents() |
1574 |
|
1575 |
for item in worker.scene.items(): |
1576 |
if issubclass(type(item), SymbolSvgItem) and not (type(item) is QEngineeringErrorItem) and not ( |
1577 |
type(item) is QEngineeringUnknownItem) and item.type != 'Notes' and not ( |
1578 |
type(item) is QEngineeringEndBreakItem): |
1579 |
symbols.append(item) |
1580 |
elif type(item) is QEngineeringLineNoTextItem: |
1581 |
lineNos.append(item) |
1582 |
elif issubclass(type(item), QEngineeringTextItem): |
1583 |
item.owner = None
|
1584 |
|
1585 |
QApplication.processEvents() |
1586 |
|
1587 |
# trace connected items
|
1588 |
docdata._connected_items_lists.clear() |
1589 |
connected_items_lists = docdata._connected_items_lists |
1590 |
|
1591 |
items = symbols + lines |
1592 |
|
1593 |
while items:
|
1594 |
connected_items_list = [items[0]]
|
1595 |
connected_items_count = 0
|
1596 |
while True: |
1597 |
if connected_items_count == len(connected_items_list): |
1598 |
break
|
1599 |
else:
|
1600 |
connected_items_count = len(connected_items_list)
|
1601 |
|
1602 |
for item in items: |
1603 |
if item in connected_items_list: |
1604 |
continue
|
1605 |
else:
|
1606 |
matches = [conn for conn in item.connectors if conn.connectedItem and conn.connectedItem in connected_items_list] |
1607 |
if matches:
|
1608 |
connected_items_list.append(item) |
1609 |
break
|
1610 |
|
1611 |
for item in connected_items_list: |
1612 |
items.remove(item) |
1613 |
|
1614 |
connected_items_lists.append(connected_items_list) |
1615 |
# up to here
|
1616 |
|
1617 |
# connect attribute
|
1618 |
worker.display_message.emit('Connecting Attribute...')
|
1619 |
QApplication.processEvents() |
1620 |
texts = [item for item in worker.scene.items() if issubclass(type(item), QEngineeringTextItem)] |
1621 |
for symbol in symbols: |
1622 |
try:
|
1623 |
symbol.connectAttribute(texts) |
1624 |
except Exception as ex: |
1625 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
1626 |
sys.exc_info()[-1].tb_lineno)
|
1627 |
worker.display_message.emit(message) |
1628 |
|
1629 |
""" try to connect label to valve """
|
1630 |
labels = [symbol for symbol in symbols if symbol.iType == 19] # Labels - Symbol => Instrument |
1631 |
valves = [symbol for symbol in symbols if |
1632 |
symbol.iType == 34 or symbol.iType == 17 or symbol.iType == 22] # Specialty Components, In-Line, Relief Devices |
1633 |
for label in labels: |
1634 |
label.connectAttribute(valves, clear=False)
|
1635 |
|
1636 |
# for slope, etc.., symbol to line
|
1637 |
labels = [symbol for symbol in symbols if symbol.iType == 30] # Labels - Line => Piping |
1638 |
for label in labels: |
1639 |
label.connectAttribute(lines, clear=False)
|
1640 |
|
1641 |
QApplication.processEvents() |
1642 |
for symbol in symbols: |
1643 |
for assoc in symbol.associations(): |
1644 |
if assoc.owner is None: |
1645 |
assoc.owner = symbol |
1646 |
|
1647 |
""" try to find text item's owner """
|
1648 |
texts = [item for item in worker.scene.items() if type(item) is QEngineeringReservedWordTextItem] |
1649 |
for text in texts: |
1650 |
text.findOwner(lines) |
1651 |
|
1652 |
QApplication.processEvents() |
1653 |
# restore and save manual edited attr's text item
|
1654 |
texts = [item for item in worker.scene.items() if issubclass(type(item), QEngineeringTextItem)] |
1655 |
targetText = [] |
1656 |
for text in texts: |
1657 |
found = False
|
1658 |
for symbol in symbols + lines: |
1659 |
for attr in list(symbol.attrs.keys()): |
1660 |
# skip freezed attr or already consumed by symbol
|
1661 |
if attr.AssocItem == text:
|
1662 |
text.owner = symbol |
1663 |
found = True
|
1664 |
break
|
1665 |
# restore missing attr
|
1666 |
elif type(attr.AssocItem) is str or type(attr.AssocItem) is uuid.UUID: |
1667 |
if str(attr.AssocItem) == str(text.uid): |
1668 |
symbol.add_assoc_item(text) |
1669 |
attr.AssocItem = text |
1670 |
text.owner = symbol |
1671 |
found = True
|
1672 |
break
|
1673 |
if found: break |
1674 |
if not found and ( |
1675 |
type(text) is QEngineeringSizeTextItem or type(text) is QEngineeringValveOperCodeTextItem or \ |
1676 |
type(text) is QEngineeringTagNoTextItem or type(text) is QEngineeringTextItem): |
1677 |
targetText.append(text) |
1678 |
|
1679 |
worker.need_update_texts = [] |
1680 |
targetText = sorted(targetText, key=lambda param: len(param.text()), reverse=True) |
1681 |
for symbol in symbols + equip_packages: |
1682 |
symbol._skip = False
|
1683 |
for text in targetText: |
1684 |
ret = text.findOwner(symbols) if type(text) is not QEngineeringTagNoTextItem else text.findOwner( |
1685 |
symbols + equip_packages) |
1686 |
if ret:
|
1687 |
worker.need_update_texts.append([text, ret]) |
1688 |
|
1689 |
QApplication.processEvents() |
1690 |
|
1691 |
worker.updateProgress.emit(tracer.maxValue) |
1692 |
|
1693 |
ALL_ITEM = [item for item in worker.scene.items() if issubclass(type(item), QEngineeringAbstractItem)] |
1694 |
for item in ALL_ITEM: |
1695 |
item.setVisible(True)
|
1696 |
|
1697 |
except Exception as ex: |
1698 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
1699 |
sys.exc_info()[-1].tb_lineno)
|
1700 |
worker.display_message.emit(message) |
1701 |
except:
|
1702 |
(type1, value, traceback) = sys.exc_info() |
1703 |
sys.excepthook(type1, value, traceback) |