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