hytos / DTI_PID / DTI_PID / LineNoTracer.py @ 0b8b80ed
이력 | 보기 | 이력해설 | 다운로드 (30.3 KB)
1 |
# coding: utf-8
|
---|---|
2 |
""" This is line no tracer module """
|
3 |
|
4 |
import sys |
5 |
import math |
6 |
import shapely |
7 |
from AppDocData import AppDocData, MessageType |
8 |
from EngineeringLineItem import QEngineeringLineItem |
9 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
10 |
from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem |
11 |
from SymbolSvgItem import SymbolSvgItem |
12 |
from EngineeringTextItem import QEngineeringTextItem |
13 |
from EngineeringUnknownItem import QEngineeringUnknownItem |
14 |
try:
|
15 |
from PyQt5.QtCore import * |
16 |
from PyQt5.QtGui import * |
17 |
from PyQt5.QtWidgets import * |
18 |
except ImportError: |
19 |
try:
|
20 |
from PyQt4.QtCore import * |
21 |
from PyQt4.QtGui import * |
22 |
except ImportError: |
23 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
24 |
|
25 |
class LineNoTracer: |
26 |
'''
|
27 |
@history 2018.04.26 Jeongwoo Variable name changed (texts → lineNos)
|
28 |
'''
|
29 |
def __init__(self, symbols, lines, lineNos, specBreaks, lineIndicators, vendors, end_breaks): |
30 |
try:
|
31 |
self._symbols = symbols
|
32 |
self._lines = lines
|
33 |
self._lineNos = lineNos
|
34 |
self._spec_breaks = specBreaks
|
35 |
self._lineIndicator = lineIndicators
|
36 |
self._end_breaks = end_breaks
|
37 |
|
38 |
"""
|
39 |
for spec in self._specBreak:
|
40 |
for attr in spec.attrs:
|
41 |
if type(attr) is tuple and attr[1] != '':
|
42 |
self._specBreakUID.append(attr[1])
|
43 |
"""
|
44 |
except Exception as ex: |
45 |
from App import App |
46 |
|
47 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, 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 |
def find_primary_lines(self, lineno): |
55 |
from EngineeringLineItem import QEngineeringLineItem |
56 |
from EngineeringRunItem import QEngineeringRunItem |
57 |
|
58 |
connected_items = [] |
59 |
|
60 |
_from = lineno.prop('From')
|
61 |
_to = lineno.prop('To')
|
62 |
if _from and _to and lineno.empty(): |
63 |
connected_items = self.find_connected_objects(_from, to=_to, primary=True) |
64 |
if _from in connected_items and _to in connected_items: |
65 |
start = connected_items.index(_from) |
66 |
end = connected_items.index(_to) |
67 |
if start < end:
|
68 |
connected_items = connected_items[start:end+1]
|
69 |
else:
|
70 |
connected_items = connected_items[end:start+1]
|
71 |
connected_items.reverse() |
72 |
elif (not _from or not _to) and (1 == len(lineno.conns)): |
73 |
connected_items = self.find_connected_objects(lineno.conns[0]) |
74 |
|
75 |
#print(connected_items)
|
76 |
if connected_items:
|
77 |
for item in connected_items: |
78 |
item.owner = lineno # set item's owner
|
79 |
|
80 |
line_run = QEngineeringRunItem() |
81 |
line_run.items = connected_items |
82 |
line_run.arrange_flow_direction() |
83 |
line_run.owner = lineno |
84 |
lineno.runs.append(line_run) |
85 |
|
86 |
lineno.set_property('From', connected_items[0]) |
87 |
lineno.set_property('To', connected_items[-1]) |
88 |
|
89 |
if _to is not None and connected_items and connected_items[-1] is not _to: |
90 |
_to.owner = None
|
91 |
|
92 |
return connected_items
|
93 |
|
94 |
'''
|
95 |
@brief find secondary lines
|
96 |
@author humkyung
|
97 |
'''
|
98 |
def find_secondary_lines(self, lines_and_symbols): |
99 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
100 |
from EngineeringLineItem import QEngineeringLineItem |
101 |
from EngineeringRunItem import QEngineeringRunItem |
102 |
|
103 |
try:
|
104 |
foundCount = 1
|
105 |
while foundCount:
|
106 |
foundCount = 0
|
107 |
notMatches = [] |
108 |
for line in lines_and_symbols: |
109 |
if line.owner is not None: continue |
110 |
|
111 |
line_matches = [x for x in self._lines if x.owner and line.is_connected(x, QEngineeringAbstractItem.CONNECTED_AT_BODY)] |
112 |
symbol_matches = [x for x in self._symbols if x.owner and line.is_connected(x) and x.canBeSecondary(line)] |
113 |
if line_matches or symbol_matches: |
114 |
foundCount += 1
|
115 |
connected_items = self.find_connected_objects(line)
|
116 |
|
117 |
owner = line_matches[0].owner if line_matches else symbol_matches[0].owner |
118 |
for item in connected_items: |
119 |
item.owner = owner # set item's owner
|
120 |
|
121 |
line_run = QEngineeringRunItem() |
122 |
line_run.items = connected_items |
123 |
line_run.arrange_flow_direction() |
124 |
if line_run.items is not None and len(line_run.items) > 0: |
125 |
line_run.owner = owner |
126 |
owner.runs.append(line_run) |
127 |
else:
|
128 |
notMatches.append(line) |
129 |
#lines_and_symbols = notMatches
|
130 |
except Exception as ex: |
131 |
from App import App |
132 |
|
133 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
134 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
135 |
|
136 |
'''
|
137 |
@brief trace line no
|
138 |
@author humkyung
|
139 |
@date 2018.04.16
|
140 |
@history 2018.04.26 Jeongwoo docDatalineNos = self.lineNos, Not For loop
|
141 |
humkyung 2018.05.08 add flow arrow
|
142 |
Jeongwoo 2018.05.14 Add [runs] on Primary/Secondary Line - Need to modify Secondary Line
|
143 |
Jeongwoo 2018.05.15 Make Comments [lineno.conns[0].owner = lineno]
|
144 |
Jeongwoo 2018.05.17 Modify find secondary lines with 'while'
|
145 |
Modify find secondary lines with 'while' used sublist for unconnected line
|
146 |
humkyung 2018.05.18 set start line's owner before tracing
|
147 |
'''
|
148 |
def execute(self, displayMessage, updateProgress, toler=600): |
149 |
from EngineeringLineItem import QEngineeringLineItem |
150 |
from SymbolSvgItem import SymbolSvgItem |
151 |
from EngineeringRunItem import QEngineeringRunItem |
152 |
from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem |
153 |
|
154 |
try:
|
155 |
docData = AppDocData.instance() |
156 |
|
157 |
configs = docData.getConfigs('Line No', 'Delimiter') |
158 |
if 1 == len(configs): |
159 |
configs = docData.getConfigs('Line No', 'Configuration') |
160 |
|
161 |
for lineno in self._lineNos: |
162 |
_from = lineno.prop('From')
|
163 |
_to = lineno.prop('To')
|
164 |
|
165 |
lineno.conns.clear() |
166 |
minDist = None
|
167 |
startLine = None
|
168 |
for line in self._lines: |
169 |
dist = line.distanceTo((lineno.center().x(), lineno.center().y())) |
170 |
if (minDist is None) or (dist < minDist): |
171 |
minDist = dist |
172 |
startLine = line |
173 |
if (startLine is not None) and (minDist < toler): |
174 |
lineno.conns.append(startLine) |
175 |
|
176 |
if _from and _to and (type(_from) is QEngineeringLineItem or issubclass(type(_from), SymbolSvgItem)) and (type(_to) is QEngineeringLineItem or issubclass(type(_to), SymbolSvgItem)): |
177 |
_from.owner = lineno |
178 |
_to.owner = lineno |
179 |
continue
|
180 |
else:
|
181 |
lineno.set_property('From', None) |
182 |
lineno.set_property('To', None) |
183 |
|
184 |
maxValue = len(self._lineNos) + 1 ## line no's count + secondary line |
185 |
|
186 |
# find primary lines
|
187 |
# sort line no with from,to value
|
188 |
self._lineNos.sort(key=lambda line_no:(1 if line_no.prop('From') else 0)+(1 if line_no.prop('To') else 0),reverse=True) |
189 |
for lineno in self._lineNos: |
190 |
if displayMessage: displayMessage.emit('{} {}'.format(lineno.text(), 'Topology Construction')) |
191 |
self.find_primary_lines(lineno)
|
192 |
if updateProgress: updateProgress.emit(maxValue)
|
193 |
|
194 |
# find secondary lines
|
195 |
lines_and_symbols = self._lines + self._symbols |
196 |
self.find_secondary_lines(lines_and_symbols)
|
197 |
|
198 |
# double check conn line cuz startLine may need at first step
|
199 |
for lineno in self._lineNos: |
200 |
lineno.conns.clear() |
201 |
minDist = None
|
202 |
startLine = None
|
203 |
for line in [line for line in lineno.runs[0].items if type(line) is QEngineeringLineItem and (line._lineType == 'Primary' or line._lineType == 'Secondary')]: |
204 |
dist = line.distanceTo((lineno.center().x(), lineno.center().y())) |
205 |
if (minDist is None) or (dist < minDist): |
206 |
minDist = dist |
207 |
startLine = line |
208 |
if (startLine is not None) and (minDist < toler): |
209 |
lineno.conns.append(startLine) |
210 |
|
211 |
if updateProgress: updateProgress.emit(maxValue)
|
212 |
|
213 |
### make trim lines
|
214 |
updateProgress.emit(-1) # reset progressbar |
215 |
displayMessage.emit('Unknown line Topology Construction')
|
216 |
orphanLines = [line for line in self._lines if line.owner is None] |
217 |
orphanSymbols = [symbol for symbol in self._symbols if symbol.owner is None] |
218 |
if orphanLines + orphanSymbols:
|
219 |
maxValue = len(orphanLines)
|
220 |
orphanLines = sorted(orphanLines, key=lambda param:param.length(), reverse=True) |
221 |
orphans = orphanLines + orphanSymbols |
222 |
while len(orphans) > 0: |
223 |
trimLineNo = QEngineeringTrimLineNoTextItem() |
224 |
trimLineNo.conns.append(orphans[0])
|
225 |
orphans[0].owner = trimLineNo
|
226 |
#orphanLines[0].linkedItem = trimLineNo
|
227 |
|
228 |
connectedItems = self.find_primary_lines(trimLineNo)
|
229 |
for item in connectedItems: |
230 |
if item in orphanLines: |
231 |
orphanLines.remove(item) |
232 |
updateProgress.emit(maxValue) |
233 |
|
234 |
self.find_secondary_lines(orphans)
|
235 |
for item in orphans[:]: |
236 |
if item.owner is not None: |
237 |
orphans.remove(item) |
238 |
updateProgress.emit(maxValue) |
239 |
|
240 |
docData.tracerLineNos.append(trimLineNo) |
241 |
|
242 |
#(docData.tracerLineNos))
|
243 |
if updateProgress: updateProgress.emit(maxValue)
|
244 |
except Exception as ex: |
245 |
from App import App |
246 |
|
247 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
248 |
AppDocData.instance().ex.logger.critical('message')
|
249 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
250 |
|
251 |
'''
|
252 |
@brief find objects connected to given line while loop
|
253 |
@author humkyung
|
254 |
@date 2018.04.16
|
255 |
@history humkyung 2018.05.08 find symbol or line connected to given object
|
256 |
humkyung 2018.05.10 set found object's owner
|
257 |
humkyung 2018.05.17 try to connect both symbol and line
|
258 |
humkyung 2018.06.22 order connected objects
|
259 |
'''
|
260 |
def find_connected_objects(self, start, to=None, primary=False): |
261 |
from EngineeringLineItem import QEngineeringLineItem |
262 |
from EngineeringEquipmentItem import QEngineeringEquipmentItem |
263 |
from SymbolSvgItem import SymbolSvgItem |
264 |
|
265 |
visited = [start] |
266 |
|
267 |
try:
|
268 |
pool = [] |
269 |
pool.append((0, start))
|
270 |
|
271 |
while len(pool) > 0: |
272 |
sign, obj = pool.pop() |
273 |
|
274 |
#""" check obj is upstream or downstream of spec break """
|
275 |
#matches = [spec_break for spec_break in self._spec_breaks if spec_break.is_connected(obj)]
|
276 |
#if matches or issubclass(type(obj), QEngineeringEquipmentItem):
|
277 |
# visited.pop(visited.index(obj))
|
278 |
# continue
|
279 |
#print('obj={} pool={}'.format(obj, pool))
|
280 |
|
281 |
match = False
|
282 |
if not primary: |
283 |
for end_break in self._end_breaks: |
284 |
if obj is end_break.owner or obj is end_break.prop('Connected Item'): |
285 |
match = True
|
286 |
break
|
287 |
|
288 |
if issubclass(type(obj), QEngineeringEquipmentItem): |
289 |
visited.pop(visited.index(obj)) |
290 |
continue
|
291 |
elif match:
|
292 |
continue
|
293 |
|
294 |
""" end loop if obj is to """
|
295 |
if to is not None and str(obj.uid) == str(to.uid): break |
296 |
|
297 |
# nextmatches list always has one item
|
298 |
if type(obj) is QEngineeringLineItem: |
299 |
symbolMatches = [x for x in self._symbols if (x.owner is None or x.owner == start.owner) and (x not in visited) and obj.is_connected(x)] |
300 |
lineMatches = [x for x in self._lines if (x.owner is None or x.owner == start.owner) and (x is not obj) and (x not in visited) and obj.is_connected(x)] |
301 |
nextMatches = symbolMatches + lineMatches |
302 |
|
303 |
elif issubclass(type(obj), SymbolSvgItem): |
304 |
# symbol can be connected with line and another symbol at the same time
|
305 |
lineMatches = [x for x in self._lines if (x.owner is None or x.owner == start.owner) and (x not in visited) and obj.is_connected(x)] |
306 |
symbolMatches = [x for x in self._symbols if (x.owner is None or x.owner == start.owner) and (x is not obj) and (x not in visited) and obj.is_connected(x, None)] |
307 |
nextMatches = symbolMatches + lineMatches |
308 |
|
309 |
if len(nextMatches) > 1: # choose one if connected items are more than 2 |
310 |
matches = [x for x in visited if obj.is_connected(x)] |
311 |
if matches:
|
312 |
next_connected = [x for x in nextMatches if obj.next_connected(x, matches[0])] |
313 |
|
314 |
if next_connected:
|
315 |
nextMatches = next_connected |
316 |
else:
|
317 |
nextMatches = [lineMatches[0]]
|
318 |
|
319 |
# order connected objects
|
320 |
matches = [] |
321 |
matches.extend(nextMatches) |
322 |
|
323 |
if sign == 0 and len(matches) > 1: |
324 |
mid = int(len(matches)*0.5) |
325 |
lhs = matches[0:mid]
|
326 |
rhs = matches[mid:] |
327 |
elif sign == -1: |
328 |
lhs = matches |
329 |
rhs = [] |
330 |
else:
|
331 |
lhs = [] |
332 |
rhs = matches |
333 |
|
334 |
for match in lhs: |
335 |
#print(match)
|
336 |
pool.append((-1, match))
|
337 |
visited.insert(0, match)
|
338 |
|
339 |
for match in rhs: |
340 |
#print(match)
|
341 |
pool.append((1, match))
|
342 |
visited.append(match) |
343 |
# up to here
|
344 |
|
345 |
except Exception as ex: |
346 |
from App import App |
347 |
|
348 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
349 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
350 |
|
351 |
#print(visited)
|
352 |
return visited
|
353 |
|
354 |
'''
|
355 |
@brief connect attributes
|
356 |
@author humkyung
|
357 |
@date 2018.06.17
|
358 |
@history humkyung 2018.06.21 paste connect attributes codes from recognizeLine function
|
359 |
kyouho 2018.09.14 clear Item's owner
|
360 |
'''
|
361 |
def connectAttrImpl(worker, update_line_type): |
362 |
import os, math |
363 |
from App import App |
364 |
from LineNoTracer import LineNoTracer |
365 |
from AppDocData import AppDocData |
366 |
from EngineeringSpecBreakItem import QEngineeringSpecBreakItem |
367 |
from EngineeringInstrumentItem import QEngineeringInstrumentItem |
368 |
from EngineeringReducerItem import QEngineeringReducerItem |
369 |
from EngineeringEquipmentItem import QEngineeringEquipmentItem |
370 |
from QEngineeringOPCItem import QEngineeringOPCItem |
371 |
from EngineeringSpecBreakItem import QEngineeringSpecBreakItem |
372 |
from EngineeringVendorItem import QEngineeringVendorItem |
373 |
from EngineeringEndBreakItem import QEngineeringEndBreakItem |
374 |
from EngineeringFlowMarkItem import QEngineeringFlowMarkItem |
375 |
from EngineeringReservedWordTextItem import QEngineeringReservedWordTextItem |
376 |
from QEngineeringSizeTextItem import QEngineeringSizeTextItem |
377 |
from EngineeringValveOperCodeTextItem import QEngineeringValveOperCodeTextItem |
378 |
from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem |
379 |
from QEngineeringTagNoTextItem import QEngineeringTagNoTextItem |
380 |
|
381 |
try:
|
382 |
worker.displayMessage.emit('Initiating...')
|
383 |
docdata = AppDocData.instance() |
384 |
symbols = [] |
385 |
lines = [] |
386 |
lineNos = [] |
387 |
specBreak = [] |
388 |
lineIndicator = [] |
389 |
vendor_packages = [item for item in worker.graphicsView.scene.items() if type(item) is QEngineeringVendorItem] |
390 |
end_breaks = [] |
391 |
#flow_marks = []
|
392 |
|
393 |
for end_break in [item for item in worker.graphicsView.scene.items() if type(item) is QEngineeringEndBreakItem]: |
394 |
if not end_break.prop('Freeze'): |
395 |
end_break.transfer.onRemoved.emit(end_break) |
396 |
#worker.graphicsView.scene.removeItem(end_break)
|
397 |
else:
|
398 |
end_breaks.append(end_break) |
399 |
|
400 |
for flow_mark in [item for item in worker.graphicsView.scene.items() if type(item) is QEngineeringFlowMarkItem]: |
401 |
if not flow_mark.prop('Freeze'): |
402 |
flow_mark.transfer.onRemoved.emit(flow_mark) |
403 |
#worker.graphicsView.scene.removeItem(end_break)
|
404 |
else:
|
405 |
flow_marks.append(flow_mark) |
406 |
|
407 |
configs = docdata.getConfigs('Supplied by Tag Rule', 'by Vendor') |
408 |
vendorTag = configs[0].value if configs else 'By Vendor' |
409 |
for item in worker.graphicsView.scene.items(): |
410 |
if type(item) is QEngineeringSpecBreakItem: |
411 |
specBreak.append(item) |
412 |
elif issubclass(type(item), SymbolSvgItem) and not type(item) is QEngineeringUnknownItem: |
413 |
matches = [vendor_package for vendor_package in vendor_packages if vendor_package.includes(item)] |
414 |
if matches:
|
415 |
item.set_property('Supplied By', vendorTag)
|
416 |
else:
|
417 |
item.set_property('Supplied By', '') |
418 |
symbols.append(item) |
419 |
elif type(item) is QEngineeringLineNoTextItem: |
420 |
lineNos.append(item) |
421 |
elif type(item) is QEngineeringLineItem: |
422 |
#matches = [vendor_package for vendor_package in vendor_packages if vendor_package.includes(item)]
|
423 |
#if not matches: lines.append(item)
|
424 |
lines.append(item) |
425 |
elif type(item) is QEngineeringUnknownItem and item.lineIndicator != 'False': |
426 |
lineIndicator.append(item) |
427 |
elif issubclass(type(item), QEngineeringTextItem): |
428 |
item.owner = None
|
429 |
|
430 |
# remove unknown line's
|
431 |
pastTrim = docdata.tracerLineNos |
432 |
treeWidget = App.mainWnd().itemTreeWidget |
433 |
for pastTrimIndex in reversed(range(len(pastTrim))): |
434 |
if type(pastTrim[pastTrimIndex]) is QEngineeringTrimLineNoTextItem: |
435 |
try:
|
436 |
connected_items = pastTrim[pastTrimIndex].getConnectedItems() |
437 |
for item in connected_items: |
438 |
treeWidget.addTreeItem(treeWidget.SymbolsTreeItem, item) |
439 |
pastTrim[pastTrimIndex].explode() |
440 |
finally:
|
441 |
pass
|
442 |
|
443 |
# trace line no
|
444 |
tracer = LineNoTracer(symbols, lines, lineNos, specBreak, lineIndicator, vendor_packages, end_breaks) |
445 |
tracer.execute(worker.displayMessage, worker.updateProgress) |
446 |
# up to here
|
447 |
|
448 |
# connect attribute
|
449 |
worker.displayMessage.emit('Connecting Attribute...')
|
450 |
texts = [item for item in worker.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem)] |
451 |
for text in texts: |
452 |
text.onwer = None
|
453 |
for symbol in symbols: |
454 |
try:
|
455 |
symbol.connectAttribute(texts) |
456 |
except Exception as ex: |
457 |
from App import App |
458 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
459 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
460 |
|
461 |
""" try to connect label to valve """
|
462 |
labels = [symbol for symbol in symbols if type(symbol) is QEngineeringInstrumentItem and not symbol.has_connection] |
463 |
#print(labels[0])
|
464 |
valves = [symbol for symbol in symbols if (type(symbol) is QEngineeringInstrumentItem and symbol.has_connection) and type(symbol) is not QEngineeringReducerItem and type(symbol) is not QEngineeringEquipmentItem \ |
465 |
and type(symbol) is not QEngineeringOPCItem and type(symbol) is not QEngineeringSpecBreakItem] |
466 |
#print(valves[0])
|
467 |
for valve in valves: |
468 |
valve.connectAttribute(labels, clear=False)
|
469 |
|
470 |
for symbol in symbols: |
471 |
for assoc in symbol.associations(): |
472 |
if assoc.owner is None: |
473 |
assoc.owner = symbol |
474 |
|
475 |
""" try to find text item's owner """
|
476 |
texts = [item for item in worker.graphicsView.scene.items() if type(item) is QEngineeringReservedWordTextItem] |
477 |
for text in texts: |
478 |
text.findOwner(lines) |
479 |
texts = [item for item in worker.graphicsView.scene.items() if type(item) is QEngineeringSizeTextItem or type(item) is QEngineeringValveOperCodeTextItem or type(item) is QEngineeringTagNoTextItem] |
480 |
for text in texts: |
481 |
text.findOwner(symbols) |
482 |
|
483 |
""" update line type """
|
484 |
if update_line_type == True: |
485 |
worker.displayMessage.emit('Updating Line Type...')
|
486 |
#lines = [line for line in worker.graphicsView.scene.items() if type(line) is QEngineeringLineItem]
|
487 |
#for line in lines: line.lineType = 'Primary'
|
488 |
for line in lines: line.update_line_type() |
489 |
|
490 |
"""make end break"""
|
491 |
end_break_names = docdata.getSymbolListByType('type', 'End Break') |
492 |
if len(end_break_names) is not 0: |
493 |
|
494 |
svgFileName = end_break_names[0].sName
|
495 |
symbol = docdata.getSymbolByQuery('name', svgFileName)
|
496 |
svgFilePath = os.path.join(docdata.getCurrentProject().getSvgFilePath(), symbol.getType(), svgFileName+'.svg')
|
497 |
|
498 |
#end_breaks = []
|
499 |
lineNo_froms = [] |
500 |
lineNo_tos = [] |
501 |
|
502 |
for lineNo in lineNos: |
503 |
lineNo_froms.append(lineNo.prop('From')) if lineNo.prop('From') is not None else None |
504 |
lineNo_tos.append(lineNo.prop('To')) if lineNo.prop('To') is not None else None |
505 |
#end_breaks.extend(lineNo.end_break())
|
506 |
|
507 |
for line_end in lineNo_froms + lineNo_tos: |
508 |
#print(type(line_end))
|
509 |
for connector in line_end.connectors: |
510 |
if connector.connectedItem is not None and connector.connectedItem.owner is not line_end.owner: |
511 |
end_break = SymbolSvgItem.createItem(symbol.getType(), svgFilePath) |
512 |
pt = [connector.center()[0] - float(symbol.getOriginalPoint().split(',')[0]), connector.center()[1] - float(symbol.getOriginalPoint().split(',')[1])] |
513 |
origin = [0,0] |
514 |
if 2 == len(symbol.getOriginalPoint().split(',')): |
515 |
tokens = symbol.getOriginalPoint().split(',')
|
516 |
origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])] |
517 |
end_break.buildItem(svgFileName, symbol.getType(), 5.7, pt, [end_break.boundingRect().width(), end_break.boundingRect().height()], origin, [], symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), symbol.getHasInstrumentLabel())
|
518 |
|
519 |
end_break.set_property('Connected Item', connector.connectedItem)
|
520 |
end_break.setToolTip('owner : ' + str(line_end)) |
521 |
end_break.area = 'Drawing'
|
522 |
end_break.owner = line_end |
523 |
end_breaks.append(end_break) |
524 |
|
525 |
if end_breaks:
|
526 |
# check dulplication
|
527 |
dupl = set()
|
528 |
for i in range(len(end_breaks)): |
529 |
for j in range(len(end_breaks)): |
530 |
if i == j: continue |
531 |
else:
|
532 |
setI = set([end_breaks[i].owner, end_breaks[i].prop('Connected Item')]) |
533 |
setJ = set([end_breaks[j].owner, end_breaks[j].prop('Connected Item')]) |
534 |
if not (setI - setJ): |
535 |
index = [i, j] |
536 |
index.sort() |
537 |
index = tuple(index)
|
538 |
dupl.add(index) |
539 |
#print(dupl)
|
540 |
dupl = list(set([(indexSet[1] if not end_breaks[indexSet[1]].prop('Freeze') else indexSet[0]) for indexSet in list(dupl)])) |
541 |
dupl.sort(reverse=True)
|
542 |
#print(dupl)
|
543 |
for index in dupl: |
544 |
end_breaks.pop(index) |
545 |
|
546 |
for end_break in end_breaks: |
547 |
if not end_break.prop('Freeze'): |
548 |
end_break.transfer.onRemoved.connect(App.mainWnd().itemRemoved) |
549 |
end_break.addSvgItemToScene(worker.graphicsView.scene) |
550 |
|
551 |
"""make flow mark"""
|
552 |
for line in lines: |
553 |
line.flowMark = None
|
554 |
line.update_arrow() |
555 |
|
556 |
configs = docdata.getConfigs('Flow Mark')
|
557 |
position = int(configs[0].value) if 2 == len(configs) else 100 |
558 |
length = int(configs[1].value) if 2 == len(configs) else 200 |
559 |
for lineNo in lineNos + docdata.tracerLineNos: |
560 |
lineNo.update_flow_mark(position, length) |
561 |
|
562 |
'''
|
563 |
line_names = docdata.getSymbolListByType('type', 'Flow Mark')
|
564 |
if len(line_names) is not 0:
|
565 |
|
566 |
svgFileName = line_names[0].sName
|
567 |
symbol = docdata.getSymbolByQuery('name', svgFileName)
|
568 |
svgFilePath = os.path.join(docdata.getCurrentProject().getSvgFilePath(), symbol.getType(), svgFileName+'.svg')
|
569 |
|
570 |
allowed_error = 0.000001
|
571 |
|
572 |
for lineNo in lineNos + docdata.tracerLineNos:
|
573 |
for run in lineNo.runs:
|
574 |
pre = None
|
575 |
preRadian = None
|
576 |
for item in run.items:
|
577 |
if pre is None and type(item) is QEngineeringLineItem and (item._lineType == 'Primary' or item._lineType == 'Secondary'):
|
578 |
pre = item
|
579 |
start = item.line().p1()
|
580 |
end = item.line().p2()
|
581 |
_dir = [(end.x() - start.x())/item.length(), (end.y() - start.y())/item.length()]
|
582 |
radian = math.atan2(_dir[0], _dir[1]) - math.pi / 2
|
583 |
preRadian = radian if radian >= 0 else radian + 2 * math.pi
|
584 |
preDir = _dir
|
585 |
#print(_dir)
|
586 |
continue
|
587 |
elif type(item) is QEngineeringLineItem and (item._lineType == 'Primary' or item._lineType == 'Secondary'):
|
588 |
pre._flowMark = []
|
589 |
start = item.line().p1()
|
590 |
end = item.line().p2()
|
591 |
_dir = [(end.x() - start.x())/item.length(), (end.y() - start.y())/item.length()]
|
592 |
radian = math.atan2(_dir[0], _dir[1]) - math.pi / 2
|
593 |
currRadian = radian if radian >= 0 else radian + 2 * math.pi
|
594 |
if abs(currRadian - preRadian) > allowed_error:
|
595 |
# insert flow mark at pre line
|
596 |
#print(currRadian)
|
597 |
flow_mark = SymbolSvgItem.createItem(symbol.getType(), svgFilePath)
|
598 |
pt = [pre.connectors[1].center()[0] - float(symbol.getOriginalPoint().split(',')[0]) - preDir[0] * 20, pre.connectors[1].center()[1] - float(symbol.getOriginalPoint().split(',')[1]) - preDir[1] * 20]
|
599 |
origin = [0,0]
|
600 |
if 2 == len(symbol.getOriginalPoint().split(',')):
|
601 |
tokens = symbol.getOriginalPoint().split(',')
|
602 |
origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])]
|
603 |
flow_mark.buildItem(svgFileName, symbol.getType(), preRadian, pt, [flow_mark.boundingRect().width(), flow_mark.boundingRect().height()], origin, [], symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), symbol.getHasInstrumentLabel())
|
604 |
flow_mark.setToolTip('owner : ' + str(pre))
|
605 |
flow_mark.area = 'Drawing'
|
606 |
flow_mark.owner = pre
|
607 |
flow_mark.setParentItem(pre)
|
608 |
pre._flowMark.append(flow_mark)
|
609 |
flow_marks.append(flow_mark)
|
610 |
|
611 |
pre = item
|
612 |
preDir = _dir
|
613 |
preRadian = currRadian
|
614 |
|
615 |
for flow_mark in flow_marks:
|
616 |
if not flow_mark.prop('Freeze'):
|
617 |
flow_mark.transfer.onRemoved.connect(App.mainWnd().itemRemoved)
|
618 |
flow_mark.addSvgItemToScene(worker.graphicsView.scene)
|
619 |
'''
|
620 |
|
621 |
except Exception as ex: |
622 |
from App import App |
623 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
624 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
625 |
except:
|
626 |
(type1, value, traceback) = sys.exc_info() |
627 |
sys.excepthook(type1, value, traceback) |
628 |
finally:
|
629 |
worker.finished.emit() |
630 |
|