프로젝트

일반

사용자정보

개정판 26ec4aef

ID26ec4aefe39db8853958673e70998299f6992ad7
상위 1b8f2469
하위 4a6bef3f

백흠경이(가) 약 5년 전에 추가함

issue #663: 개별, 배치 인식 모드 통합

Change-Id: Id2f6f056199617c02ae465d27e8d3c9570c6fe17

차이점 보기:

DTI_PID/DTI_PID/AppDocData.py
915 915
        if self._titleBlockProperties is None:
916 916
            self._titleBlockProperties = []
917 917

  
918
            # Creates or opens a file called mydb with a SQLite3 DB
919
            conn = self.project.database.connect()
920
            with conn:
918
            with self.project.database.connect() as conn:
921 919
                try:
922 920
                    # Get a cursor object
923 921
                    cursor = conn.cursor()
DTI_PID/DTI_PID/Commands/SaveWorkCommand.py
94 94
                    resultStr += "\r\n" + uid
95 95

  
96 96
        return resultStr
97

  
98
    @staticmethod
99
    def save_to_database():
100
        """db update when save or recognition"""
101
        from AppDocData import AppDocData
102
        from AppDocData import MessageType
103
        from EngineeringAbstractItem import QEngineeringAbstractItem
104
        from EngineeringErrorItem import QEngineeringErrorItem
105
        from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
106
        from EngineeringTextItem import QEngineeringTextItem
107
        from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem
108
        from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
109
        from EngineeringUnknownItem import QEngineeringUnknownItem
110

  
111
        try:
112
            app_doc_data = AppDocData.instance()
113
            items = app_doc_data.allItems
114

  
115
            # unknown item is not saved now for performance
116
            db_items = [item for item in items if issubclass(type(item), QEngineeringAbstractItem) and
117
                        type(item) is not QGraphicsBoundingBoxItem and
118
                        type(item) is not QEngineeringErrorItem and
119
                        type(item) is not QEngineeringLineNoTextItem and
120
                        type(item) is not QEngineeringUnknownItem]
121
            db_items.extend([item for item in items if type(item) is QEngineeringLineNoTextItem])
122
            db_items.extend([line for line in app_doc_data.tracerLineNos if type(line) is QEngineeringTrimLineNoTextItem])
123
            # db_items.extend(titleBlockItems)
124
            configs = app_doc_data.getConfigs('Data Save', 'Unknown Xml Only')
125
            if configs and int(configs[0].value) is -1:
126
                db_items.extend([item for item in items if type(item) is QEngineeringUnknownItem])
127

  
128
            app_doc_data.saveToDatabase(db_items)
129
        except Exception as ex:
130
            from App import App
131
            from AppDocData import MessageType
132

  
133
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
134
                                                           sys.exc_info()[-1].tb_lineno)
135
            App.mainWnd().addMessage.emit(MessageType.Error, message)
DTI_PID/DTI_PID/LibraryItem.py
39 39

  
40 40
            idx = 0
41 41
            for _, symbol in enumerate(self._symbol_tree_widget.symbols):
42
                matches = [favorite for favorite in self.favorites if symbol.getUid() == favorite[1]]
42
                matches = [favorite for favorite in self.favorites if symbol.getUid() == favorite['Symbol_UID']]
43 43
                if matches:
44 44
                    self.layout.addWidget(LibraryItem(symbol), idx // LibraryItemWidget.COLUMN, \
45 45
                                          idx % LibraryItemWidget.COLUMN)
......
64 64
                    cursor.execute(sql, param)
65 65
                    conn.commit()
66 66

  
67
                    '''
68
                    layout_item = self.layout.takeAt(matches[0])
69
                    self.layout.removeWidget(item)
70
                    item.deleteLater()
71
                    del item
72
                    self.layout.removeItem(layout_item)
73
                    del layout_item
74
                    '''
75 67
                    self.make_grid()
76 68

  
77 69
                    self.layout.update()
DTI_PID/DTI_PID/MainWindow.py
226 226
        self.actionExportAsImage.triggered.connect(self.export_as_image)
227 227
        self.actionLine.triggered.connect(self.onPlaceLine)
228 228
        self.actionRecognition.triggered.connect(self.recognize)
229
        self.pushButtonBatchRecognition.clicked.connect(self.recognizeBatch)
230 229
        self.pushButtonRefreshDrawings.clicked.connect(self.load_drawing_list)
231 230
        self.actionLineRecognition.triggered.connect(self.connect_attributes)
232 231
        self.actionArea.triggered.connect(self.areaConfiguration)
......
282 281
            self.menu_2.setEnabled(False)  # Data
283 282
            self.menu_4.setEnabled(False)  # Tool
284 283
            self.actionConfiguration.setVisible(False)
285
            self.pushButtonBatchRecognition.setVisible(False)
286 284
            self.pushButtonCreateSymbol.setVisible(False)
287 285
            self.pushButtonDetectSymbol.setVisible(False)
288 286

  
......
572 570
        app_doc_data = AppDocData.instance()
573 571
        drawing = item.data(Qt.UserRole, 0)
574 572
        if drawing:
573
            # uncheck all drawing tree item
574
            drawing_top = self.treeWidgetDrawingList.topLevelItem(0)
575
            count = drawing_top.childCount()
576
            for idx in range(count):
577
                child = drawing_top.child(idx)
578
                child.setCheckState(column, Qt.Unchecked)
579
            # up to here
580

  
575 581
            drawing.image = None
576 582
            self.open_image_drawing(drawing)
583
            item.setCheckState(column, Qt.Checked)
577 584

  
578 585
    def show_detect_symbol_dialog(self):
579 586
        from DetectSymbolDialog import QDetectSymbolDialog
......
1419 1426
                self.itemTreeWidget.setCurrentPID(app_doc_data.activeDrawing.name)
1420 1427

  
1421 1428
                drawingList = self.treeWidgetDrawingList.topLevelItem(0)
1422
                for childIdex in range(drawingList.childCount()):
1423
                    drawingList.child(childIdex).setCheckState(0, Qt.Unchecked)
1424
                for childIdex in range(drawingList.childCount()):
1425
                    child = drawingList.child(childIdex)
1426
                    if child.text(0).replace('.png', '') == app_doc_data.activeDrawing.name:
1429
                for idx in range(drawingList.childCount()):
1430
                    child = drawingList.child(idx)
1431
                    if child.data(Qt.UserRole, 0) is drawing:
1427 1432
                        child.setCheckState(0, Qt.Checked)
1428
                        break
1433
                    else:
1434
                        child.setCheckState(0, Qt.Unchecked)
1429 1435

  
1430 1436
                try:
1431 1437
                    self.show_Progress_bar()
......
2037 2043
                                                           sys.exc_info()[-1].tb_lineno)
2038 2044
            self.addMessage.emit(MessageType.Error, message)
2039 2045

  
2040
    def recognizeBatch(self, MainWindow):
2041
        '''
2042
            @brief      batch recognize symbol, text and line
2043
            @author     euisung
2044
            @date       2018.11.23
2045
        
2046
        '''
2046
    def recognize(self):
2047
        """recognize symbol, text and line for selected drawings"""
2047 2048
        from datetime import datetime
2048 2049
        from RecognitionDialog import QRecognitionDialog
2049 2050

  
2050 2051
        app_doc_data = AppDocData.instance()
2051
        project = app_doc_data.getCurrentProject()
2052
        app_doc_data.needReOpening = None
2053 2052
        current_drawing, currentPid = None, None
2054 2053

  
2055 2054
        if self.graphicsView.hasImage():
2056 2055
            current_drawing = app_doc_data.activeDrawing
2057 2056
            currentPid = app_doc_data.activeDrawing.name
2058 2057

  
2059
        # TODO: 무슨 의미인지 주석 필요
2060
        drawingTop = self.treeWidgetDrawingList.topLevelItem(0)
2061
        drawingCount = drawingTop.childCount()
2062
        checkedTreeItems = []
2063
        checkedDrawingPath = []
2064
        for drawing in range(drawingCount):
2065
            drawingChild = drawingTop.child(drawing)
2066
            if drawingChild.checkState(0) == 2:
2067
                checkedTreeItems.append(drawingChild)
2068
                checkedDrawingPath.append(os.path.join(project.getDrawingFilePath(), drawingChild.data(0, 0)))
2069
                if currentPid is not None and drawingChild.data(0, 0).find(currentPid) is 0:
2070
                    app_doc_data.needReOpening = False  # later check need reopening at drawUnknownItems()
2071
                    currentPid = drawingChild.data(0, 0)
2058
        # get checked drawings
2059
        drawing_top = self.treeWidgetDrawingList.topLevelItem(0)
2060
        count = drawing_top.childCount()
2061
        checked_drawings = {}
2062
        for idx in range(count):
2063
            child = drawing_top.child(idx)
2064
            if child.checkState(0) == Qt.Checked and child.data(Qt.UserRole, 0):
2065
                checked_drawings[child.data(Qt.UserRole, 0)] = child
2072 2066
        # up to here
2073 2067

  
2074
        if len(checkedDrawingPath) == 0:
2068
        if not checked_drawings:
2075 2069
            self.showImageSelectionMessageBox()
2076 2070
            return
2077 2071

  
2078 2072
        try:
2079 2073
            self.onClearLog()
2080
            self.dlg = QRecognitionDialog(self, checkedDrawingPath, True)
2081
            self.dlg.exec_()
2082
            if self.dlg.isAccepted == True:
2083
                pass
2074
            dlg = QRecognitionDialog(self, [drawing.file_path for drawing in checked_drawings.keys()])
2075
            dlg.exec_()
2084 2076

  
2085
            if app_doc_data.needReOpening == True:
2077
            if current_drawing and current_drawing in checked_drawings.keys():
2086 2078
                self.open_image_drawing(current_drawing)
2087 2079

  
2088 2080
            # save working date-time
2089
            drawings = app_doc_data.getDrawings()
2090
            checkedDrawings = []
2091
            for checkedTreeItem in checkedTreeItems:
2092
                for drawing in drawings:
2093
                    if checkedTreeItem.data(0, 0) == drawing.name:
2094
                        if drawing:
2095
                            drawing.datetime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
2096
                            checkedDrawings.append(drawing)
2097
                            checkedTreeItem.setText(1, datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
2098
            app_doc_data.saveDrawings(checkedDrawings)
2081
            _now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
2082
            for drawing, tree_item in checked_drawings.items():
2083
                drawing.datetime = _now
2084
                tree_item.setText(1, _now)
2085
            app_doc_data.saveDrawings(checked_drawings.keys())
2099 2086
            self.changeViewCheckedState(True)
2100 2087
            # up to here
2101 2088
        except Exception as ex:
......
2104 2091
            self.addMessage.emit(MessageType.Error, message)
2105 2092

  
2106 2093
    '''
2107
        @brief      recognize symbol and text
2108
        @author     humkyung
2109
        @date       2018.04.??
2110
        @history    2018.04.16  humkyung    execute line no tracing
2111
                    2018.05.02  Jeongwoo    Show MessageBox when imageviewer doesn't have image
2112
                    2018.05.25  Jeongwoo    Add parameter on QRecognitionDialog.__init__() and Move thread to QRecognitionDialog
2113
                                            Remove codes below if self.dlg.isAccepted == True
2114
                    2018.05.29  Jeongwoo    Remove connects and comments
2115
                    humkyung 2018.11.05 save working date-time
2116
    '''
2117

  
2118
    def recognize(self, MainWindow):
2119
        from datetime import datetime
2120
        from RecognitionDialog import QRecognitionDialog
2121

  
2122
        if not self.graphicsView.hasImage():
2123
            self.showImageSelectionMessageBox()
2124
            return
2125

  
2126
        # save alarm
2127
        self.save_alarm_enable(False)
2128

  
2129
        try:
2130
            appDocData = AppDocData.instance()
2131

  
2132
            self.onClearLog()
2133
            appDocData.needReOpening = False
2134
            drawingList = []
2135
            drawingList.append(self.path)
2136
            self.dlg = QRecognitionDialog(self, drawingList, False)
2137
            self.dlg.exec_()
2138

  
2139
            if appDocData.needReOpening:
2140
                self.itemTreeWidget.setCurrentPID(appDocData.activeDrawing.name)
2141
                self.drawDetectedItemsToScene()
2142

  
2143
                # save working date-time
2144
                drawings = appDocData.getDrawings()
2145
                drawing = [drawing for drawing in drawings if appDocData.imgName == os.path.splitext(drawing.name)[0]]
2146
                if drawing[0]:
2147
                    drawing[0].datetime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
2148
                    appDocData.saveDrawings(drawing)
2149

  
2150
                currentPid = appDocData.activeDrawing.name
2151

  
2152
                drawingTop = self.treeWidgetDrawingList.topLevelItem(0)
2153
                drawingCount = drawingTop.childCount()
2154

  
2155
                for drawing in range(drawingCount):
2156
                    drawingChild = drawingTop.child(drawing)
2157
                    if drawingChild.data(0, 0).find(currentPid) is 0:
2158
                        drawingChild.setText(1, datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
2159
                self.changeViewCheckedState(True)
2160
                # up to here
2161
        except Exception as ex:
2162
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2163
                                                           sys.exc_info()[-1].tb_lineno)
2164
            self.addMessage.emit(MessageType.Error, message)
2165
        finally:
2166
            # save alarm
2167
            self.save_alarm_enable(True)
2168

  
2169
    '''
2170 2094
        @brief      remove item from tree widget and then remove from scene
2171 2095
        @date       2018.05.25
2172 2096
        @author     Jeongwoo
......
2253 2177
                                                           sys.exc_info()[-1].tb_lineno)
2254 2178
            self.addMessage.emit(MessageType.Error, message)
2255 2179

  
2256
    '''
2257
        @brief      recognize line
2258
        @author     humkyung
2259
        @date       2018.04.19
2260
        @history    Jeongwoo 2018.04.26 Variable name changed (texts → lineNos)
2261
                                        TextItem type changed (QEngineeringTextItem → QEngineeringLineNoTextItem)
2262
                    humkyung 2018.04.26 remove small objects before recognizing line
2263
                    Jeongwoo 2018.05.02 Show MessageBox when imageviewer doesn't have image
2264
                    Jeongwoo 2018.05.25 Move codes about LineDetector
2265
                    humkyung 2018.06.17 show progress dialog
2266
    '''
2267

  
2268 2180
    def connect_attributes(self, MainWindow):
2181
        """connect attributes to symbol"""
2269 2182
        from LineNoTracer import LineNoTracer
2270 2183
        from ConnectAttrDialog import QConnectAttrDialog
2271 2184

  
......
2305 2218
            # save alarm
2306 2219
            self.save_alarm_enable(True)
2307 2220

  
2308
    '''
2309
        @history    2018.05.25  Jeongwoo    Moved from MainWindow
2310
                                            SvgItem and TextItem Connect with method in this class
2311
                                            Change method to add GraphicsItem
2312
                    2018.05.28  Jeongwoo    Make QGraphicsItem by symbol, text object. Not xml
2313
                    2018.05.29  Jeongwoo    Change method name and Moved from QRecognitionDialog
2314
                    2018.05.30  Jeongwoo    Add parameters on SymbolSvgItem.__init__() (parentSymbol, childSymbol)
2315
                                            Change Method name and seperate each item
2316
                    humkyung 2018.06.11     display difference between original and recognized image
2317
                    Jeongwoo 2018.06.18     Update Scene after all item added
2318
                    2018.11.05  euisung     add save note item because of dependency
2319
                    2018.11.05  euisung     add db delete process before save
2320
                    2018.11.12  euisung     add title block properties
2321
                    2018.11.12  euisung     db part move new method to dbUpdate
2322
                    2018.11.26  euisung     isolate scene adding part -> drawDetectedItemsToScene()
2323
                    2018.11.29  euisung     change name drawDetectedItems() -> createDetectedItems
2324
    '''
2325

  
2326
    def createDetectedItems(self, symbolList, textInfoList, otherTextInfoList, titleBlockTextInfoList):
2327
        try:
2328
            QApplication.processEvents()
2329
            self.createDetectedSymbolItem(symbolList)
2330
            QApplication.processEvents()
2331
            self.createDetectedTextItem(textInfoList)
2332
            QApplication.processEvents()
2333
            self.createDetectedOtherTextItem(otherTextInfoList)
2334
            QApplication.processEvents()
2335
            self.createDetectedTitleBlockTextItem(titleBlockTextInfoList)
2336

  
2337
            # update scene
2338
            # self.graphicsView.scene().update(self.graphicsView.sceneRect())
2339
        except Exception as ex:
2340
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2341
                                                           sys.exc_info()[-1].tb_lineno)
2342
            self.addMessage.emit(MessageType.Error, message)
2343

  
2344
    def drawDetectedItemsToScene(self):
2345
        """add detected items to scene"""
2346
        from SaveWorkCommand import SaveWorkCommand
2347

  
2348
        app_doc_data = AppDocData.instance()
2349

  
2350
        try:
2351
            for symbol in app_doc_data.symbols:
2352
                if issubclass(type(symbol), SymbolSvgItem):
2353
                    symbol.addSvgItemToScene(self.graphicsView.scene())
2354
                else:
2355
                    self.graphicsView.scene().addItem(symbol)
2356

  
2357
            for text in app_doc_data.texts:
2358
                self.addTextItemToScene(text)
2359

  
2360
            for lineNo in app_doc_data.tracerLineNos:
2361
                self.addTextItemToScene(lineNo)
2362

  
2363
            # remove lines which is located inside symbol
2364
            for symbol in app_doc_data.symbols:
2365
                rect = symbol.sceneBoundingRect()
2366
                rect.adjust(-10, -10, 10, 10)
2367
                matches = [line for line in app_doc_data.lines if rect.contains(line.line().p1()) and
2368
                           rect.contains(line.line().p2()) and
2369
                           not line.has_connection]
2370
                app_doc_data.lines = [line for line in app_doc_data.lines if line not in matches]
2371
            # up to here
2372

  
2373
            for line in app_doc_data.lines:
2374
                self.graphicsView.scene().addItem(line)
2375
                line.transfer.onRemoved.connect(self.itemRemoved)
2376
                for conn in line.connectors:
2377
                    conn.transfer.onPosChanged.connect(line.onConnectorPosChaned)
2378

  
2379
            for unknown in app_doc_data.unknowns + app_doc_data.lineIndicators:
2380
                self.graphicsView.scene().addItem(unknown)
2381

  
2382
            # save scene
2383
            self.dbUpdate()
2384
            SaveWorkCommand.save_to_xml()
2385
        finally:
2386
            # update scene
2387
            self.graphicsView.scene().update(self.graphicsView.sceneRect())
2388

  
2389 2221
    def postDetectLineProcess(self):
2390 2222
        '''
2391 2223
            @brief  check allowables among undetected items
......
2428 2260
                item.transfer.onRemoved.emit(item)
2429 2261
                appDocData.lineNos.append(lineItem)
2430 2262

  
2431
    def createDetectedTitleBlockTextItem(self, textInfoList):
2432
        '''
2433
            @brief  draw title block
2434
            @author euisung
2435
            @date   2018.11.12
2436
            @history    2018.11.26  euisung     remove scene dependency
2437
                        2018.11.29  euisung     change name drawDetectedTitleBlockTextItem() -> createDetectedTitleBlockTextItem
2438
        '''
2439
        from TextItemFactory import TextItemFactory
2440
        import math
2441

  
2442
        try:
2443
            appDocData = AppDocData.instance()
2444

  
2445
            # parse texts
2446
            for textInfos in textInfoList:
2447
                if len(textInfos[1]) is 0:
2448
                    continue
2449

  
2450
                for textInfo in textInfos[1]:
2451
                    x = textInfo.getX()
2452
                    y = textInfo.getY()
2453
                    width = textInfo.getW()
2454
                    height = textInfo.getH()
2455
                    angle = round(math.radians(textInfo.getAngle()), 2)
2456
                    text = textInfo.getText()
2457
                    if not text: continue
2458
                    item = TextItemFactory.instance().createTextItem(textInfo)
2459

  
2460
                    if item is not None:
2461
                        item.loc = [x, y]
2462
                        item.size = (width, height)
2463
                        item.angle = angle
2464
                        item.area = textInfos[0]
2465
                        # self.addTextItemToScene(item)
2466
                        # appDocData.texts.append(item)
2467
                        appDocData.allItems.append(item)
2468
        except Exception as ex:
2469
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2470
                                                           sys.exc_info()[-1].tb_lineno)
2471
            self.addMessage.emit(MessageType.Error, message)
2472

  
2473
    '''
2474
        @brief      
2475
        @author     humkyung
2476
        @date       2018.08.23
2477
        @history    2018.11.26  euisung     remove scene dependency
2478
                    2018.11.26  euisung     isolate scene adding part -> drawDetectedItemsToScene()
2479
                    2018.11.    euisung     no more used
2480
                    2018.11.29  euisung     change name drawDetectedLines() -> createDetectedLines
2481
    '''
2482

  
2483
    def createDetectedLines(self, lineList, worker):
2484
        appDocData = AppDocData.instance()
2485
        area = appDocData.getArea('Drawing')
2486

  
2487
        for pts in lineList:
2488
            processLine = QEngineeringLineItem(vertices=[(area.x + param[0], area.y + param[1]) for param in pts])
2489
            processLine.area = 'Drawing'
2490
            # self.graphicsView.scene().addItem(processLine)
2491
            appDocData.lines.append(processLine)
2492
            appDocData.allItems.append(processLine)
2493

  
2494
            # if processLine.length() > 100: # TODO: check critical length
2495
            #    processLine.addFlowArrow()
2496

  
2497
        # re-order process line's start,end according to flow mark
2498
        # worker.arrangeLinePosition(lines, symbols, listWidget)
2499
        # up to here
2500

  
2501
    '''
2502
        history     2018.06.09  humkyung    check length of original and connection point is 2 while parsing
2503
                    2018.11.26  euisung     remove scene dependency
2504
                    2018.11.29  euisung     change name drawDetectedSymbolItem() -> createDetectedSymbolItem
2505
    '''
2506

  
2507
    def createDetectedSymbolItem(self, symbolList):
2508
        from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
2509
        from SymbolSvgItem import SymbolSvgItem
2510
        import math
2511

  
2512
        try:
2513
            appDocData = AppDocData.instance()
2514
            project = appDocData.getCurrentProject()
2515

  
2516
            searchedMap = []
2517
            for symbol in symbolList:
2518
                pt = [float(x) for x in symbol.getSp()]
2519
                size = [symbol.getWidth(), symbol.getHeight()]
2520
                name = symbol.getName()
2521
                angle = round(math.radians(symbol.getRotatedAngle()), 2)
2522
                _type = symbol.getType()
2523
                flip = symbol.getDetectFlip()
2524
                origin = [0, 0]
2525
                if 2 == len(symbol.getOriginalPoint().split(',')):
2526
                    tokens = symbol.getOriginalPoint().split(',')
2527
                    origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])]
2528
                connPts = []
2529
                if symbol.getConnectionPoint() is not None and symbol.getConnectionPoint() != '':
2530
                    for param in symbol.getConnectionPoint().split('/'):
2531
                        tokens = param.split(',')
2532
                        connPts.append(
2533
                            ('AUTO', pt[0] + float(tokens[0]), pt[1] + float(tokens[1]), '0') if len(tokens) == 2 else \
2534
                                (tokens[0], pt[0] + float(tokens[1]), pt[1] + float(tokens[2]), '0') if len(
2535
                                    tokens) == 3 else \
2536
                                    (tokens[0], pt[0] + float(tokens[1]), pt[1] + float(tokens[2]), tokens[3]) if len(
2537
                                        tokens) == 4 else None)
2538

  
2539
                parentSymbol = symbol.getBaseSymbol()
2540
                childSymbol = symbol.getAdditionalSymbol()
2541
                hasInstrumentLabel = symbol.getHasInstrumentLabel()
2542

  
2543
                svgFilePath = os.path.join(project.getSvgFilePath(), _type, name + '.svg')
2544
                if os.path.isfile(svgFilePath):
2545
                    svg = SymbolSvgItem.createItem(_type, None, svgFilePath, owner=None, flip=flip)
2546
                    svg.hit_ratio = symbol.hitRate
2547
                    svg.buildItem(name, _type, angle, pt, size, origin, connPts, parentSymbol, childSymbol,
2548
                                  hasInstrumentLabel)
2549
                    # svg.reCalculationRotatedItem()
2550
                    svg.area = 'Drawing'
2551

  
2552
                    # set owner - 2018.07.20 added by humkyung                   
2553
                    matches = [searched for searched in searchedMap if searched[0] == symbol.owner]
2554
                    if len(matches) == 1:
2555
                        svg.owner = matches[0][1]
2556
                    searchedMap.append((symbol, svg))
2557
                    # up to here
2558

  
2559
                    svg.transfer.onRemoved.connect(self.itemRemoved)
2560
                    # self.addSvgItemToScene(svg)
2561
                    appDocData.symbols.append(svg)
2562
                    appDocData.allItems.append(svg)
2563
                else:
2564
                    item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1])
2565
                    item.isSymbol = True
2566
                    item.angle = angle
2567
                    item.setPen(QPen(Qt.red, 5, Qt.SolidLine))
2568
                    # self.graphicsView.scene().addItem(item)
2569
                    # appDocData.symbols.append(item)
2570
                    appDocData.allItems.append(item)
2571
            # up to here
2572
        except Exception as ex:
2573
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2574
                                                           sys.exc_info()[-1].tb_lineno)
2575
            self.addMessage.emit(MessageType.Error, message)
2576

  
2577
    '''
2578
        @history    2018.06.08  Jeongwoo    Add parameter on round method
2579
        @history    2018.11.02  euisung     Add save note text item
2580
        @history    2018.11.05  euisung     delete save note text item and move to drawDetectedItems()
2581
                    2018.11.26  euisung     remove scene dependency
2582
                    2018.11.29  euisung     change name drawDetectedTextItem() -> createDetectedTextItem
2583
    '''
2584

  
2585
    def createDetectedTextItem(self, textInfoList):
2586
        from TextItemFactory import TextItemFactory
2587
        import math
2588

  
2589
        try:
2590
            appDocData = AppDocData.instance()
2591

  
2592
            # parse texts
2593
            for textInfo in textInfoList:
2594
                x = textInfo.getX()
2595
                y = textInfo.getY()
2596
                width = textInfo.getW()
2597
                height = textInfo.getH()
2598
                angle = round(math.radians(textInfo.getAngle()), 2)
2599
                text = textInfo.getText()
2600
                if not text: continue
2601

  
2602
                item = TextItemFactory.instance().createTextItem(textInfo)
2603
                if item is not None:
2604
                    item.loc = [x, y]
2605
                    item.size = (width, height)
2606
                    item.angle = angle
2607
                    item.area = 'Drawing'
2608
                    item.transfer.onRemoved.connect(self.itemRemoved)
2609
                    # self.addTextItemToScene(item)
2610
                    # appDocData.texts.append(item)
2611
                    appDocData.allItems.append(item)
2612
        except Exception as ex:
2613
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2614
                                                           sys.exc_info()[-1].tb_lineno)
2615
            self.addMessage.emit(MessageType.Error, message)
2616

  
2617
    '''
2618
        @brief      draw detected texts except which in drawing area
2619
        @history    2018.11.29  euisung     change name drawDetectedOtherTextItem() -> createDetectedOtherTextItem
2620
    '''
2621

  
2622
    def createDetectedOtherTextItem(self, otherTextInfoList):
2623
        from TextItemFactory import TextItemFactory
2624
        import math
2625

  
2626
        try:
2627
            appDocData = AppDocData.instance()
2628

  
2629
            # parse notes
2630
            for textInfoMap in otherTextInfoList:
2631
                if textInfoMap[0] == 'Note' or textInfoMap[1] is None:
2632
                    pass
2633

  
2634
                for textInfo in textInfoMap[1]:
2635
                    x = textInfo.getX()
2636
                    y = textInfo.getY()
2637
                    width = textInfo.getW()
2638
                    height = textInfo.getH()
2639
                    angle = round(math.radians(textInfo.getAngle()))
2640
                    text = textInfo.getText()
2641

  
2642
                    item = TextItemFactory.instance().createTextItem(textInfo)
2643

  
2644
                    item.loc = [x, y]
2645
                    item.size = (width, height)
2646
                    item.angle = angle
2647
                    item.area = textInfoMap[0]
2648
                    item.transfer.onRemoved.connect(self.itemRemoved)
2649
                    # appDocData.texts.append(item)
2650
                    appDocData.allItems.append(item)
2651
        except Exception as ex:
2652
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2653
                                                           sys.exc_info()[-1].tb_lineno)
2654
            self.addMessage.emit(MessageType.Error, message)
2655

  
2656
    '''
2657
        @brief  draw unknown items 
2658
        @author humkyung
2659
        @date   2018.06.12
2660
        @history    2018.06.14  Jeongwoo    Change method to add unknown item
2661
                    2018.06.18  Jeongwoo    Add connect on unknown item
2662
                                            Add [transfer] for using pyqtSignal
2663
                    2018.11.26  euisung     remove scene dependency
2664
                    2018.11.26  euisung     isolate scene adding part -> drawDetectedItemsToScene()
2665
                    2018.11.27  euisung     add save to xml
2666
                    2018.11.29  euisung     change name drawUnknownItems() -> createUnknownItems
2667
    '''
2668

  
2669
    def createUnknownItems(self, path):
2670
        from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem
2671
        from EngineeringLineItem import QEngineeringLineItem
2672
        from EngineeringUnknownItem import QEngineeringUnknownItem
2673

  
2674
        try:
2675
            docData = AppDocData.instance()
2676
            project = docData.getCurrentProject()
2677
            windowSize = docData.getSlidingWindowSize()
2678

  
2679
            thickness = int(windowSize[1] / 2)
2680

  
2681
            if docData.needReOpening is not None:
2682
                docData.needReOpening = True
2683

  
2684
            diffFilePath = os.path.join(project.getTempPath(), "DIFF_" + os.path.basename(path))
2685
            if os.path.isfile(diffFilePath):
2686
                imgDiff = cv2.threshold(cv2.cvtColor(cv2.imread(diffFilePath, 1), cv2.COLOR_BGR2GRAY), 0, 255,
2687
                                        cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
2688

  
2689
                # remove line from image
2690
                lines = docData.lines
2691
                for line in lines:
2692
                    line.drawToImage(imgDiff, 255, thickness) if line.thickness is None else \
2693
                        line.drawToImage(imgDiff, 255, line.thickness)
2694
                cv2.imwrite(diffFilePath, imgDiff)
2695
                # up to here
2696

  
2697
                imgNot = np.ones(imgDiff.shape, np.uint8)
2698
                cv2.bitwise_not(imgDiff, imgNot)
2699
                configs = docData.getConfigs('Filter', 'ErodeSize')
2700
                kernel = int(configs[0].value) if 1 == len(configs) else 3
2701
                imgNot = cv2.erode(imgNot, np.ones((kernel, kernel), np.uint8))
2702
                imgNot = cv2.dilate(imgNot, np.ones((8 + kernel, 8 + kernel), np.uint8))
2703

  
2704
                contours, hierarchy = cv2.findContours(imgNot, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
2705

  
2706
                ##
2707
                idx = 0
2708
                ##
2709
                smallContours = []
2710
                minimumSize = docData.getConfigs('Filter', 'MinimumSize')
2711
                for contour in contours:
2712
                    [x, y, w, h] = cv2.boundingRect(contour)
2713

  
2714
                    # remove too small one
2715
                    if len(minimumSize) is 1:
2716
                        if (w * h < int(minimumSize[0].value) * int(minimumSize[0].value)):
2717
                            smallContours.append(contour)
2718
                            idx += 1
2719
                            continue
2720

  
2721
                    '''
2722
                    rect = QRectF(x, y, w, h)
2723
                    items = [item for item in diffItems if item.boundingRect().contains(rect)]
2724
                    if len(items) > 0: continue
2725
                    
2726
                    items = [item for item in diffItems if rect.contains(item.boundingRect())]
2727
                    for item in items:
2728
                        diffItems.remove(item)
2729
                    '''
2730

  
2731
                    # create unknown item
2732
                    epsilon = cv2.arcLength(contour, True) * 0.001
2733
                    approx = cv2.approxPolyDP(contour, epsilon, True)
2734
                    approx = [pt[0] for pt in approx]
2735
                    resultStr, resultList = self.determineRemainObject(idx, contours, imgNot)
2736
                    if resultStr == 'LineIndicator':
2737
                        item = QEngineeringUnknownItem(approx, 'True', resultList[0], resultList[1])
2738
                        docData.lineIndicators.append(item)
2739
                    elif resultStr == 'MissingLine':
2740
                        pass
2741
                    elif resultStr == 'Unknown':
2742
                        item = QEngineeringUnknownItem(approx, 'False')
2743
                        docData.unknowns.append(item)
2744
                    item.area = 'Drawing'
2745
                    docData.allItems.append(item)
2746
                    item.transfer.onRemoved.connect(self.itemRemoved)
2747
                    idx += 1
2748
                    # up to here                    
2749

  
2750
                imgNotRemoveSmall = cv2.drawContours(imgNot, smallContours, -1, 0, -1)
2751
                notFilePath = os.path.join(project.getTempPath(), "NOT_" + os.path.basename(path))
2752
                cv2.imwrite(notFilePath, imgNotRemoveSmall)
2753
            else:
2754
                message = 'can\'t found {}'.format(diffFilePath)
2755
                self.addMessage.emit(MessageType.Normal, message)
2756
        except Exception as ex:
2757
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2758
                                                           sys.exc_info()[-1].tb_lineno)
2759
            self.addMessage.emit(MessageType.Error, message)
2760

  
2761
    def determineRemainObject(self, idx, contours, imgNot):
2762
        '''
2763
            @brief      determine remain objects -> line no indicator or unknown
2764
            @author     euisung
2765
            @date       2018.12.26
2766
            @history    2019.03.25  euisung    Change name isLineNoIndicator -> determineRemainObject
2767
        '''
2768
        import math
2769
        [x, y, w, h] = cv2.boundingRect(contours[idx])
2770

  
2771
        if (w < 250 and h < 250):
2772
            return ('Unknown', [])
2773

  
2774
        fLines = []
2775
        maxDifAngle = 3
2776
        mask = np.zeros_like(imgNot)
2777
        cv2.drawContours(mask, contours, idx, 123, -1)  # Draw filled contour in mask
2778
        out = np.zeros_like(imgNot)  # Extract out the object and place into output image
2779
        out[mask == 123] = imgNot[mask == 123]
2780

  
2781
        # Now crop
2782
        ##print(out)
2783
        (x, y) = np.where(mask == 123)
2784
        (topx, topy) = (np.min(x), np.min(y))
2785
        (bottomx, bottomy) = (np.max(x), np.max(y))
2786
        out = out[topx:bottomx + 1, topy:bottomy + 1]
2787
        h, w = out.shape[0], out.shape[1]
2788
        maxDifH, maxDifW = math.ceil(math.tan(4 * math.pi / 180) / 2 * w), math.ceil(
2789
            math.tan(4 * math.pi / 180) / 2 * h)
2790

  
2791
        # detection lines
2792
        edged2 = cv2.Canny(out, 100, 200)
2793
        lines = cv2.HoughLinesP(image=edged2, rho=1, theta=np.pi / 180, threshold=25, minLineLength=30, maxLineGap=25)
2794
        # lines = cv2.HoughLines(edged2, 1, np.pi/180, 60)
2795
        if lines is None:
2796
            return ('Unknown', [])
2797
        for line in lines:
2798
            # r, theta = line[0]
2799
            # a, b = np.cos(theta), np.sin(theta)
2800
            # x0, y0 = a * r, b * r
2801
            # x1, y1 = int(x0 + 1000 * (-b)), int(y0 + 1000 * a)
2802
            # x2, y2 = int(x0 - 1000 * (-b)), int(y0 - 1000 * a)
2803
            # cv2.line(out, (x1, y1), (x2, y2), (0, 255, 0), 3)
2804
            x1, y1, x2, y2 = line[0]
2805
            degree = math.atan2(y2 - y1, x2 - x1) * 180 / math.pi
2806
            fLine = [x1, y1, x2, y2, degree]
2807
            # print(fLine)
2808
            fLines.append(fLine)
2809

  
2810
        horLines = []
2811
        verLines = []
2812
        otherLines = []
2813
        isVH = None
2814
        for fLine in fLines:
2815
            degree = math.fabs(fLine[4])
2816
            if degree >= 90 - maxDifAngle:
2817
                verLines.append(fLine)
2818
            elif degree <= maxDifAngle:
2819
                horLines.append(fLine)
2820
            else:
2821
                otherLines.append(fLine)
2822

  
2823
        baseLines = []
2824
        baseDifV = 0
2825
        if len(horLines):
2826
            x, y = w / 2, 0
2827
            baseDifV = maxDifH
2828
            for horLine in horLines:
2829
                x1, y1, x2, y2 = horLine[0], horLine[1], horLine[2], horLine[3]
2830
                y = ((y2 - y1) / (x2 - x1)) * x + y1 - ((y2 - y1) / (x2 - x1)) * x1
2831
                horLine.append(y)
2832
            baseLines = horLines
2833
            isVH = 'H'
2834
        if len(verLines):
2835
            x, y = 0, h / 2
2836
            baseDifV = maxDifW
2837
            for verLine in verLines:
2838
                x1, y1, x2, y2 = verLine[0], verLine[1], verLine[2], verLine[3]
2839
                x = ((x2 - x1) / (y2 - y1)) * y + x1 - ((x2 - x1) / (y2 - y1)) * y1
2840
                verLine.append(x)
2841
            baseLines = verLines
2842
            isVH = 'V'
2843

  
2844
        for otherLine in otherLines:
2845
            x, y = w / 2, 0
2846
            x1, y1, x2, y2 = otherLine[0], otherLine[1], otherLine[2], otherLine[3]
2847
            y = ((y2 - y1) / (x2 - x1)) * x + y1 - ((y2 - y1) / (x2 - x1)) * x1
2848
            otherLine.append(y)
2849

  
2850
        # determine line no indicator 
2851
        if not ((len(horLines) > 0 and len(verLines) > 0) or len(otherLines) is 0 or (
2852
                len(horLines) == 0 and len(verLines) == 0)):
2853
            result, mergedOtherLine = self.isLineNoIndicator(w, h, maxDifAngle, baseDifV, baseLines, otherLines)
2854
            if result:
2855
                # print(fLines)
2856
                return ('LineIndicator', [isVH, mergedOtherLine])
2857

  
2858
        return ('Unknown', [])
2859

  
2860
    def isLineNoIndicator(self, w, h, maxDifAngle, baseDifV, baseLines, otherLines):
2861
        '''
2862
            @brief      determine line no indicator
2863
            @author     euisung
2864
            @date       2019.03.25
2865
        '''
2866
        import math
2867

  
2868
        if (w < 250 and h < 250):
2869
            return (False, None)
2870

  
2871
        isSameLine = True
2872
        i = 0
2873
        for baseLine in baseLines:
2874
            if not isSameLine: break
2875
            j = 0
2876
            for baseLinee in baseLines:
2877
                if i == j:
2878
                    j += 1
2879
                    continue
2880
                difV = math.fabs(baseLine[5] - baseLinee[5])
2881
                if difV > baseDifV:
2882
                    isSameLine = False
2883
                    break
2884
                j += 1
2885
            i += 1
2886
        if not isSameLine:
2887
            return (False, None)
2888

  
2889
        isSameLine = True
2890
        i = 0
2891
        maxY = 0
2892
        for otherLine in otherLines:
2893
            y = otherLine[5]
2894
            if math.fabs(y) > maxY:
2895
                maxY = math.fabs(y)
2896
            if not isSameLine: break
2897
            j = 0
2898
            for otherLinee in otherLines:
2899
                if i == j:
2900
                    j += 1
2901
                    continue
2902
                difV = math.fabs(otherLine[4] - otherLinee[4])
2903
                if difV > maxDifAngle:
2904
                    isSameLine = False
2905
                    break
2906
                j += 1
2907
            i += 1
2908
        if not isSameLine:
2909
            return (False, None)
2910

  
2911
        isSameLine = True
2912
        mergedOtherLine = [0, 0, 0, 0]
2913
        i = 0
2914
        maxDif = math.ceil(math.tan(4 * math.pi / 180) * maxY)
2915
        for otherLine in otherLines:
2916
            if not isSameLine: break
2917
            j = 0
2918
            for otherLinee in otherLines:
2919
                if i == j:
2920
                    j += 1
2921
                    continue
2922
                angle = math.fabs(otherLine[4] + otherLinee[4]) / 2
2923
                difV = math.fabs(otherLine[5] - otherLinee[5])
2924
                dist = math.sin((90 - angle) * math.pi / 180) * difV
2925
                if dist > maxDif:
2926
                    isSameLine = False
2927
                    break
2928
                j += 1
2929
            i += 1
2930
            mergedOtherLine[0] += otherLine[0]
2931
            mergedOtherLine[1] += otherLine[1]
2932
            mergedOtherLine[2] += otherLine[2]
2933
            mergedOtherLine[3] += otherLine[3]
2934
        if not isSameLine:
2935
            (False, None)
2936

  
2937
        # Show the output image
2938
        # print('line no indicator')
2939
        mergedOtherLine[0] = round(mergedOtherLine[0] / len(otherLines))
2940
        mergedOtherLine[1] = round(mergedOtherLine[1] / len(otherLines))
2941
        mergedOtherLine[2] = round(mergedOtherLine[2] / len(otherLines))
2942
        mergedOtherLine[3] = round(mergedOtherLine[3] / len(otherLines))
2943
        # cv2.line(out, (mergedOtherLine[0], mergedOtherLine[1]), (mergedOtherLine[2], mergedOtherLine[3]), (255, 255, 255), 3)
2944
        # cv2.imshow('Output', out)
2945
        # cv2.waitKey(0)
2946
        # cv2.destroyAllWindows()
2947
        return (True, mergedOtherLine)
2948

  
2949 2263
    def init_add_tree_item(self, line_no_tree_item, run_item):
2950 2264
        """ insert symbol item and find line no as owner """
2951 2265
        # insert
......
2999 2313
                    item.attribute = text['Value']
3000 2314
                    name = text['Name']
3001 2315
                    item.transfer.onRemoved.connect(self.itemRemoved)
3002
                    self.addTextItemToScene(item)
2316
                    item.addTextItemToScene(self.graphicsView.scene())
3003 2317

  
3004 2318
                self.progress.setValue(self.progress.value() + 1)
3005 2319

  
......
3014 2328
                    attributeValue = note['Value']
3015 2329
                    name = note['Name']
3016 2330
                    item.transfer.onRemoved.connect(self.itemRemoved)
3017
                    self.addTextItemToScene(item)
2331
                    item.addTextItemToScene(self.graphicsView.scene())
3018 2332

  
3019 2333
                self.progress.setValue(self.progress.value() + 1)
3020 2334

  
......
3284 2598
                    attributeValue = text.find('ATTRIBUTEVALUE')
3285 2599
                    name = text.find('NAME').text
3286 2600
                    item.transfer.onRemoved.connect(self.itemRemoved)
3287
                    self.addTextItemToScene(item)
2601
                    item.addTextItemToScene(self.graphicsView.scene())
3288 2602
                    # docData.texts.append(item)
3289 2603

  
3290 2604
                    if name == 'TEXT':
......
3304 2618
                    attributeValue = text.find('ATTRIBUTEVALUE')
3305 2619
                    name = text.find('NAME').text
3306 2620
                    item.transfer.onRemoved.connect(self.itemRemoved)
3307
                    self.addTextItemToScene(item)
2621
                    item.addTextItemToScene(self.graphicsView.scene())
3308 2622

  
3309 2623
                    if name == 'NOTE':
3310 2624
                        if uid is not None:
......
3353 2667
                line_no = QEngineeringLineNoTextItem.fromXml(line_no_node)
3354 2668
                if line_no is None: continue
3355 2669
                line_no.transfer.onRemoved.connect(self.itemRemoved)
3356
                self.addTextItemToScene(line_no)
2670
                line_no.addTextItemToScene(self.graphicsView.scene())
3357 2671
                line_no_tree_item = self.itemTreeWidget.addTreeItem(self.itemTreeWidget.root, line_no)
3358 2672
                if type(line_no) is not QEngineeringLineNoTextItem: continue
3359 2673

  
......
3479 2793
    '''
3480 2794
        @brief      Remove added item on same place and Add GraphicsItem
3481 2795
        @author     Jeongwoo
3482
        @date       2018.05.25
3483
        @history    2018.05.29  Jeongwoo    Moved from QRecognitionDialog
3484
                    2018.06.05  Jeongwoo    Remove Size condition
3485
                    2018.06.18  Jeongwoo    Set Z-index
3486
    '''
3487

  
3488
    def addTextItemToScene(self, textItem):
3489
        textItem.addTextItemToScene(self.graphicsView.scene())
3490

  
3491
    '''
3492
        @brief      Remove added item on same place and Add GraphicsItem
3493
        @author     Jeongwoo
3494 2796
        @date       2018.05.29
3495 2797
        @history    2018.06.18  Jeongwoo    Set Z-index
3496 2798
    '''
DTI_PID/DTI_PID/MainWindow_UI.py
1 1
# -*- coding: utf-8 -*-
2 2

  
3
# Form implementation generated from reading ui file './UI/MainWindow.ui'
3
# Form implementation generated from reading ui file '.\UI\MainWindow.ui'
4 4
#
5
# Created by: PyQt5 UI code generator 5.11.3
5
# Created by: PyQt5 UI code generator 5.14.2
6 6
#
7 7
# WARNING! All changes made in this file will be lost!
8 8

  
9

  
9 10
from PyQt5 import QtCore, QtGui, QtWidgets
10 11

  
12

  
11 13
class Ui_MainWindow(object):
12 14
    def setupUi(self, MainWindow):
13 15
        MainWindow.setObjectName("MainWindow")
......
181 183
        self.verticalLayoutDrawingList.setObjectName("verticalLayoutDrawingList")
182 184
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
183 185
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
184
        self.pushButtonBatchRecognition = QtWidgets.QPushButton(self.tabDrawingList)
185
        self.pushButtonBatchRecognition.setMaximumSize(QtCore.QSize(80, 16777215))
186
        self.pushButtonBatchRecognition.setObjectName("pushButtonBatchRecognition")
187
        self.horizontalLayout_4.addWidget(self.pushButtonBatchRecognition)
188 186
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
189 187
        self.horizontalLayout_4.addItem(spacerItem1)
190 188
        self.pushButtonRefreshDrawings = QtWidgets.QPushButton(self.tabDrawingList)
......
655 653
        self.retranslateUi(MainWindow)
656 654
        self.tabWidget.setCurrentIndex(0)
657 655
        self.tabWidgetSymbolProperty.setCurrentIndex(0)
658
        self.tabWidgetItemExplorer.setCurrentIndex(0)
656
        self.tabWidgetItemExplorer.setCurrentIndex(1)
659 657
        self.tabWidget_2.setCurrentIndex(0)
660 658
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
661 659

  
......
680 678
        self.tabWidgetSymbolProperty.setTabText(self.tabWidgetSymbolProperty.indexOf(self.tabSymbolProperty), _translate("MainWindow", "Property"))
681 679
        self.dockWidgetObjectExplorer.setWindowTitle(_translate("MainWindow", "Object Explorer"))
682 680
        self.tabWidgetItemExplorer.setTabText(self.tabWidgetItemExplorer.indexOf(self.tabItemProperty), _translate("MainWindow", "Object Explorer"))
683
        self.pushButtonBatchRecognition.setText(_translate("MainWindow", "Batch Job"))
684 681
        self.pushButtonRefreshDrawings.setText(_translate("MainWindow", "Refresh Drawing List"))
685 682
        self.treeWidgetDrawingList.setSortingEnabled(True)
686 683
        self.tabWidgetItemExplorer.setTabText(self.tabWidgetItemExplorer.indexOf(self.tabDrawingList), _translate("MainWindow", "Drawing List"))
......
777 774
        self.actionUndo.setToolTip(_translate("MainWindow", "Undo"))
778 775
        self.actionRedo.setText(_translate("MainWindow", "Redo"))
779 776
        self.actionRedo.setToolTip(_translate("MainWindow", "Redo"))
780

  
781 777
import MainWindow_rc
782

  
783
if __name__ == "__main__":
784
    import sys
785
    app = QtWidgets.QApplication(sys.argv)
786
    MainWindow = QtWidgets.QMainWindow()
787
    ui = Ui_MainWindow()
788
    ui.setupUi(MainWindow)
789
    MainWindow.show()
790
    sys.exit(app.exec_())
791

  
DTI_PID/DTI_PID/QtImageViewerScene.py
114 114

  
115 115
        super(QtImageViewerScene, self).keyReleaseEvent(event)
116 116

  
117
    def mousePressEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
118
        if self.selectedItems():
119
            self._pressed_position = event.scenePos()
120
        elif not self.selectedItems() and self.items(event.scenePos()):
121
            self._pressed_position = event.scenePos()
122

  
123
        super(QtImageViewerScene, self).mousePressEvent(event)
124

  
125
    def mouseReleaseEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
126
        from MoveCommand import MoveCommand
127

  
128
        if self._pressed_position and self._pressed_position != event.scenePos() and self.selectedItems():
129
            self._undo_stack.push(MoveCommand(self, event.scenePos() - self._pressed_position))
130

  
131
        self._pressed_position = None
132
        super(QtImageViewerScene, self).mouseReleaseEvent(event)
133

  
117 134
    def clear(self):
118 135
        """clear undo stack"""
119 136
        self._undo_stack.clear()
DTI_PID/DTI_PID/RecognitionDialog.py
92 92
    def procCounter(self):  # A slot takes no params
93 93
        try:
94 94
            if self.isSymbolChecked or self.isTrainingChecked:
95
                Worker.executeRecognition(self.createDetectedItems, self.path, self.listWidget, self.isLineChecked,
96
                                          self, self.batch, self.createUnknownItems)
95
                Worker.executeRecognition(self.path, self.listWidget, self.isLineChecked, self)
97 96
        except Exception as ex:
98 97
            from App import App
99 98
            from AppDocData import MessageType
......
201 200
                                                           sys.exc_info()[-1].tb_lineno)
202 201
            App.mainWnd().addMessage.emit(MessageType.Error, message)
203 202

  
203
    def add_detected_items_to_scene(self, scene) -> None:
204
        """add detected items to scene"""
205
        from SaveWorkCommand import SaveWorkCommand
206

  
207
        app_doc_data = AppDocData.instance()
208

  
209
        try:
210
            for symbol in app_doc_data.symbols:
211
                if issubclass(type(symbol), SymbolSvgItem):
212
                    symbol.addSvgItemToScene(scene)
213
                else:
214
                    scene.addItem(symbol)
215

  
216
            for text in app_doc_data.texts:
217
                text.addTextItemToScene(scene)
218

  
219
            for lineNo in app_doc_data.tracerLineNos:
220
                lineNo.addTextItemToScene(scene)
221

  
222
            # remove lines which is located inside symbol
223
            for symbol in app_doc_data.symbols:
224
                rect = symbol.sceneBoundingRect()
225
                rect.adjust(-10, -10, 10, 10)
226
                matches = [line for line in app_doc_data.lines if rect.contains(line.line().p1()) and
227
                           rect.contains(line.line().p2()) and
228
                           not line.has_connection]
229
                app_doc_data.lines = [line for line in app_doc_data.lines if line not in matches]
230
            # up to here
231

  
232
            for line in app_doc_data.lines:
233
                scene.addItem(line)
234
                # line.transfer.onRemoved.connect(self.itemRemoved)
235
                for conn in line.connectors:
236
                    conn.transfer.onPosChanged.connect(line.onConnectorPosChaned)
237

  
238
            for unknown in app_doc_data.unknowns + app_doc_data.lineIndicators:
239
                scene.addItem(unknown)
240

  
241
            # save scene
242
            SaveWorkCommand.save_to_database()
243
            SaveWorkCommand.save_to_xml()
244
        except Exception as ex:
245
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
246
                                                           sys.exc_info()[-1].tb_lineno)
247
            self.displayLog.emit(MessageType.Error, message)
248

  
249
    def create_detected_items(self, symbolList, textInfoList, otherTextInfoList, titleBlockTextInfoList):
250
        try:
251
            QApplication.processEvents()
252
            self.create_detected_symbol_item(symbolList)
253
            QApplication.processEvents()
254
            self.create_detected_text_item(textInfoList)
255
            QApplication.processEvents()
256
            self.create_detected_other_text_item(otherTextInfoList)
257
            QApplication.processEvents()
258
            self.create_detected_title_block_text_item(titleBlockTextInfoList)
259

  
260
            # update scene
261
            # self.graphicsView.scene().update(self.graphicsView.sceneRect())
262
        except Exception as ex:
263
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
264
                                                           sys.exc_info()[-1].tb_lineno)
265
            self.displayLog.emit(MessageType.Error, message)
266

  
267
    '''
268
            history     2018.06.09  humkyung    check length of original and connection point is 2 while parsing
269
                        2018.11.26  euisung     remove scene dependency
270
                        2018.11.29  euisung     change name drawDetectedSymbolItem() -> createDetectedSymbolItem
271
        '''
272

  
273
    def create_detected_symbol_item(self, symbolList):
274
        from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
275
        from SymbolSvgItem import SymbolSvgItem
276
        import math
277

  
278
        try:
279
            app_doc_data = AppDocData.instance()
280
            project = app_doc_data.getCurrentProject()
281

  
282
            searchedMap = []
283
            for symbol in symbolList:
284
                pt = [float(x) for x in symbol.getSp()]
285
                size = [symbol.getWidth(), symbol.getHeight()]
286
                name = symbol.getName()
287
                angle = round(math.radians(symbol.getRotatedAngle()), 2)
288
                _type = symbol.getType()
289
                flip = symbol.getDetectFlip()
290
                origin = [0, 0]
291
                if 2 == len(symbol.getOriginalPoint().split(',')):
292
                    tokens = symbol.getOriginalPoint().split(',')
293
                    origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])]
294
                connPts = []
295
                if symbol.getConnectionPoint() is not None and symbol.getConnectionPoint() != '':
296
                    for param in symbol.getConnectionPoint().split('/'):
297
                        tokens = param.split(',')
298
                        connPts.append(
299
                            ('AUTO', pt[0] + float(tokens[0]), pt[1] + float(tokens[1]), '0') if len(tokens) == 2 else \
300
                                (tokens[0], pt[0] + float(tokens[1]), pt[1] + float(tokens[2]), '0') if len(
301
                                    tokens) == 3 else \
302
                                    (tokens[0], pt[0] + float(tokens[1]), pt[1] + float(tokens[2]), tokens[3]) if len(
303
                                        tokens) == 4 else None)
304

  
305
                parentSymbol = symbol.getBaseSymbol()
306
                childSymbol = symbol.getAdditionalSymbol()
307
                hasInstrumentLabel = symbol.getHasInstrumentLabel()
308

  
309
                svgFilePath = os.path.join(project.getSvgFilePath(), _type, name + '.svg')
310
                if os.path.isfile(svgFilePath):
311
                    svg = SymbolSvgItem.createItem(_type, None, svgFilePath, owner=None, flip=flip)
312
                    svg.hit_ratio = symbol.hitRate
313
                    svg.buildItem(name, _type, angle, pt, size, origin, connPts, parentSymbol, childSymbol,
314
                                  hasInstrumentLabel)
315
                    svg.area = 'Drawing'
316

  
317
                    # set owner - 2018.07.20 added by humkyung
318
                    matches = [searched for searched in searchedMap if searched[0] == symbol.owner]
319
                    if len(matches) == 1:
320
                        svg.owner = matches[0][1]
321
                    searchedMap.append((symbol, svg))
322
                    # up to here
323

  
324
                    # self.addSvgItemToScene(svg)
325
                    app_doc_data.symbols.append(svg)
326
                    app_doc_data.allItems.append(svg)
327
                else:
328
                    item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1])
329
                    item.isSymbol = True
330
                    item.angle = angle
331
                    item.setPen(QPen(Qt.red, 5, Qt.SolidLine))
332
                    # self.graphicsView.scene().addItem(item)
333
                    # appDocData.symbols.append(item)
334
                    app_doc_data.allItems.append(item)
335
            # up to here
336
        except Exception as ex:
337
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
338
                                                           sys.exc_info()[-1].tb_lineno)
339
            self.displayLog.emit(MessageType.Error, message)
340

  
341
    '''
342
            @history    2018.06.08  Jeongwoo    Add parameter on round method
343
            @history    2018.11.02  euisung     Add save note text item
344
            @history    2018.11.05  euisung     delete save note text item and move to drawDetectedItems()
345
                        2018.11.26  euisung     remove scene dependency
346
                        2018.11.29  euisung     change name drawDetectedTextItem() -> createDetectedTextItem
347
        '''
348

  
349
    def create_detected_text_item(self, textInfoList):
350
        from TextItemFactory import TextItemFactory
351
        import math
352

  
353
        try:
354
            app_doc_data = AppDocData.instance()
355

  
356
            # parse texts
357
            for textInfo in textInfoList:
358
                x = textInfo.getX()
359
                y = textInfo.getY()
360
                width = textInfo.getW()
361
                height = textInfo.getH()
362
                angle = round(math.radians(textInfo.getAngle()), 2)
363
                text = textInfo.getText()
364
                if not text: continue
365

  
366
                item = TextItemFactory.instance().createTextItem(textInfo)
367
                if item is not None:
368
                    item.loc = [x, y]
369
                    item.size = (width, height)
370
                    item.angle = angle
371
                    item.area = 'Drawing'
372
                    #item.transfer.onRemoved.connect(self.itemRemoved)
373
                    # self.addTextItemToScene(item)
374
                    # appDocData.texts.append(item)
375
                    app_doc_data.allItems.append(item)
376
        except Exception as ex:
377
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
378
                                                           sys.exc_info()[-1].tb_lineno)
379
            self.displayLog.emit(MessageType.Error, message)
380

  
381
    '''
382
        @brief      draw detected texts except which in drawing area
383
        @history    2018.11.29  euisung     change name drawDetectedOtherTextItem() -> createDetectedOtherTextItem
384
    '''
385

  
386
    def create_detected_other_text_item(self, otherTextInfoList):
387
        from TextItemFactory import TextItemFactory
388
        import math
389

  
390
        try:
391
            app_doc_data = AppDocData.instance()
392

  
393
            # parse notes
394
            for textInfoMap in otherTextInfoList:
395
                if textInfoMap[0] == 'Note' or textInfoMap[1] is None:
396
                    pass
397

  
398
                for textInfo in textInfoMap[1]:
399
                    x = textInfo.getX()
400
                    y = textInfo.getY()
401
                    width = textInfo.getW()
402
                    height = textInfo.getH()
403
                    angle = round(math.radians(textInfo.getAngle()))
404
                    text = textInfo.getText()
405

  
406
                    item = TextItemFactory.instance().createTextItem(textInfo)
407

  
408
                    item.loc = [x, y]
409
                    item.size = (width, height)
410
                    item.angle = angle
411
                    item.area = textInfoMap[0]
412
                    item.transfer.onRemoved.connect(self.itemRemoved)
413
                    # appDocData.texts.append(item)
414
                    app_doc_data.allItems.append(item)
415
        except Exception as ex:
416
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
417
                                                           sys.exc_info()[-1].tb_lineno)
418
            self.displayLog.emit(MessageType.Error, message)
419

  
420
    def create_detected_title_block_text_item(self, textInfoList):
421
        """draw title block"""
422
        from TextItemFactory import TextItemFactory
423
        import math
424

  
425
        try:
426
            app_doc_data = AppDocData.instance()
427

  
428
            # parse texts
429
            for textInfos in textInfoList:
430
                if len(textInfos[1]) is 0:
431
                    continue
432

  
433
                for textInfo in textInfos[1]:
434
                    x = textInfo.getX()
435
                    y = textInfo.getY()
436
                    width = textInfo.getW()
437
                    height = textInfo.getH()
438
                    angle = round(math.radians(textInfo.getAngle()), 2)
439
                    text = textInfo.getText()
440
                    if not text: continue
441
                    item = TextItemFactory.instance().createTextItem(textInfo)
442

  
443
                    if item is not None:
444
                        item.loc = [x, y]
445
                        item.size = (width, height)
446
                        item.angle = angle
447
                        item.area = textInfos[0]
448
                        # self.addTextItemToScene(item)
449
                        # appDocData.texts.append(item)
450
                        app_doc_data.allItems.append(item)
451
        except Exception as ex:
452
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
453
                                                           sys.exc_info()[-1].tb_lineno)
454
            self.displayLog.emit(MessageType.Error, message)
455

  
456
    '''
457
        @brief  draw unknown items 
458
        @author humkyung
459
        @date   2018.06.12
460
        @history    2018.06.14  Jeongwoo    Change method to add unknown item
461
                    2018.06.18  Jeongwoo    Add connect on unknown item
462
                                            Add [transfer] for using pyqtSignal
463
                    2018.11.26  euisung     remove scene dependency
464
                    2018.11.26  euisung     isolate scene adding part -> drawDetectedItemsToScene()
465
                    2018.11.27  euisung     add save to xml
466
                    2018.11.29  euisung     change name drawUnknownItems() -> createUnknownItems
467
    '''
468

  
469
    def create_unknown_items(self, path):
470
        from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem
471
        from EngineeringLineItem import QEngineeringLineItem
472
        from EngineeringUnknownItem import QEngineeringUnknownItem
473

  
474
        try:
475
            app_doc_data = AppDocData.instance()
476
            project = app_doc_data.getCurrentProject()
477
            windowSize = app_doc_data.getSlidingWindowSize()
478

  
479
            thickness = int(windowSize[1] / 2)
480

  
481
            """
482
            if app_doc_data.needReOpening is not None:
483
                app_doc_data.needReOpening = True
484
            """
485

  
486
            diffFilePath = os.path.join(project.getTempPath(), "DIFF_" + os.path.basename(path))
487
            if os.path.isfile(diffFilePath):
488
                imgDiff = cv2.threshold(cv2.cvtColor(cv2.imread(diffFilePath, 1), cv2.COLOR_BGR2GRAY), 0, 255,
489
                                        cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
490

  
491
                # remove line from image
492
                lines = app_doc_data.lines
493
                for line in lines:
494
                    line.drawToImage(imgDiff, 255, thickness) if line.thickness is None else \
495
                        line.drawToImage(imgDiff, 255, line.thickness)
496
                cv2.imwrite(diffFilePath, imgDiff)
497
                # up to here
498

  
499
                imgNot = np.ones(imgDiff.shape, np.uint8)
500
                cv2.bitwise_not(imgDiff, imgNot)
501
                configs = app_doc_data.getConfigs('Filter', 'ErodeSize')
502
                kernel = int(configs[0].value) if 1 == len(configs) else 3
503
                imgNot = cv2.erode(imgNot, np.ones((kernel, kernel), np.uint8))
504
                imgNot = cv2.dilate(imgNot, np.ones((8 + kernel, 8 + kernel), np.uint8))
505

  
506
                contours, hierarchy = cv2.findContours(imgNot, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
507

  
508
                ##
509
                idx = 0
510
                ##
511
                smallContours = []
512
                minimumSize = app_doc_data.getConfigs('Filter', 'MinimumSize')
513
                for contour in contours:
514
                    [x, y, w, h] = cv2.boundingRect(contour)
515

  
516
                    # remove too small one
517
                    if len(minimumSize) is 1:
518
                        if w * h < int(minimumSize[0].value) * int(minimumSize[0].value):
519
                            smallContours.append(contour)
520
                            idx += 1
521
                            continue
522

  
523
                    '''
524
                    rect = QRectF(x, y, w, h)
525
                    items = [item for item in diffItems if item.boundingRect().contains(rect)]
526
                    if len(items) > 0: continue
527

  
528
                    items = [item for item in diffItems if rect.contains(item.boundingRect())]
529
                    for item in items:
530
                        diffItems.remove(item)
531
                    '''
532

  
533
                    # create unknown item
534
                    epsilon = cv2.arcLength(contour, True) * 0.001
535
                    approx = cv2.approxPolyDP(contour, epsilon, True)
536
                    approx = [pt[0] for pt in approx]
537
                    resultStr, resultList = self.determine_remain_object(idx, contours, imgNot)
538
                    if resultStr == 'LineIndicator':
539
                        item = QEngineeringUnknownItem(approx, 'True', resultList[0], resultList[1])
540
                        app_doc_data.lineIndicators.append(item)
541
                    elif resultStr == 'MissingLine':
542
                        pass
543
                    elif resultStr == 'Unknown':
544
                        item = QEngineeringUnknownItem(approx, 'False')
545
                        app_doc_data.unknowns.append(item)
546
                    item.area = 'Drawing'
547
                    app_doc_data.allItems.append(item)
548
                    #item.transfer.onRemoved.connect(self.itemRemoved)
549
                    idx += 1
550
                    # up to here
551

  
552
                imgNotRemoveSmall = cv2.drawContours(imgNot, smallContours, -1, 0, -1)
553
                notFilePath = os.path.join(project.getTempPath(), "NOT_" + os.path.basename(path))
554
                cv2.imwrite(notFilePath, imgNotRemoveSmall)
555
            else:
556
                message = 'can\'t found {}'.format(diffFilePath)
557
                self.displayLog.emit(MessageType.Normal, message)
558
        except Exception as ex:
559
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
560
                                                           sys.exc_info()[-1].tb_lineno)
561
            self.displayLog.emit(MessageType.Error, message)
562

  
563
    def determine_remain_object(self, idx, contours, imgNot):
564
        """determine remain objects -> line no indicator or unknown"""
565
        import math
566
        [x, y, w, h] = cv2.boundingRect(contours[idx])
567

  
568
        if w < 250 and h < 250:
569
            return ('Unknown', [])
570

  
571
        fLines = []
572
        maxDifAngle = 3
573
        mask = np.zeros_like(imgNot)
574
        cv2.drawContours(mask, contours, idx, 123, -1)  # Draw filled contour in mask
575
        out = np.zeros_like(imgNot)  # Extract out the object and place into output image
576
        out[mask == 123] = imgNot[mask == 123]
577

  
578
        # Now crop
579
        ##print(out)
580
        (x, y) = np.where(mask == 123)
581
        (topx, topy) = (np.min(x), np.min(y))
582
        (bottomx, bottomy) = (np.max(x), np.max(y))
583
        out = out[topx:bottomx + 1, topy:bottomy + 1]
... 이 차이점은 표시할 수 있는 최대 줄수를 초과해서 이 차이점은 잘렸습니다.

내보내기 Unified diff

클립보드 이미지 추가 (최대 크기: 500 MB)