Kaynağa Gözat

Fix various bugs with vertex selection/movement

The selection is now updated correctly even when moving inside the same
shape.

Also fix a bug when loading files whereby the shapes were not properly
closed.
Michael Pitidis 13 yıl önce
ebeveyn
işleme
d5e34931e8
2 değiştirilmiş dosya ile 50 ekleme ve 41 silme
  1. 49 41
      canvas.py
  2. 1 0
      labelme.py

+ 49 - 41
canvas.py

@@ -38,7 +38,6 @@ class Canvas(QWidget):
         self.selectedShapeCopy=None
         self.lineColor = QColor(0, 0, 255)
         self.line = Shape(line_color=self.lineColor)
-        self.mouseButtonIsPressed=False #when it is true and shape is selected , move the shape with the mouse move event
         self.prevPoint = QPointF()
         self.offsets = QPointF(), QPointF()
         self.scale = 1.0
@@ -46,8 +45,8 @@ class Canvas(QWidget):
         self.visible = {}
         self._hideBackround = False
         self.hideBackround = False
-        self.highlightedShape = None
-        self._nearest = None
+        self.hShape = None
+        self.hVertex = None
         self._painter = QPainter()
         self._cursor = CURSOR_DEFAULT
         # Menus:
@@ -76,10 +75,15 @@ class Canvas(QWidget):
 
     def setEditing(self, value=True):
         self.mode = self.EDIT if value else self.CREATE
-        if not value:
-            self.highlightedShape = None
+        if not value: # Create
+            self.unHighlight()
             self.deSelectShape()
 
+    def unHighlight(self):
+        self.hVertex = self.hShape = None
+
+    def selectedVertex(self):
+        return self.hVertex is not None
 
     def mouseMoveEvent(self, ev):
         """Update line with last point and current coordinates."""
@@ -119,10 +123,11 @@ class Canvas(QWidget):
                 self.repaint()
             return
 
-        # Polygon moving.
+        # Polygon/Vertex moving.
         if Qt.LeftButton & ev.buttons():
-            if self._nearest and self.prevPoint:
+            if self.selectedVertex():
                 self.boundedMoveVertex(pos)
+                self.shapeMoved.emit()
                 self.repaint()
             elif self.selectedShape and self.prevPoint:
                 self.overrideCursor(CURSOR_MOVE)
@@ -131,34 +136,37 @@ class Canvas(QWidget):
                 self.repaint()
             return
 
-        # Just hovering over the canvas:
-        # Update tooltip value and fill topmost shape.
+        # Just hovering over the canvas, 2 posibilities:
+        # - Highlight shapes
+        # - Highlight vertex
+        # Update shape/vertex fill and tooltip value accordingly.
         self.setToolTip("Image")
-        previous = self.highlightedShape
-        for shape in reversed(self.shapes):
-            if self.isVisible(shape):
-                v = shape.nearestVertex(pos, self.epsilon)
-                if v is not None:
-                    self._nearest = (v, shape)
-                    shape.highlightVertex(v, shape.MOVE_VERTEX)
-                    self.highlightedShape = shape
-                    self.overrideCursor(CURSOR_POINT)
-                    self.setStatusTip("Click & drag to move point")
-                    break
-                if shape.containsPoint(pos):
-                    self.setToolTip("Object '%s'" % shape.label)
-                    self.highlightedShape = shape
-                    self.overrideCursor(CURSOR_GRAB)
-                    break
-        else:
-            if self.highlightedShape:
-                self.highlightedShape.highlightClear()
-            self.highlightedShape = None
-            self._nearest = None
-
-        if previous != self.highlightedShape:
-            # Try to minimise repaints.
-            self.update()
+        for shape in reversed([s for s in self.shapes if self.isVisible(s)]):
+            # Look for a nearby vertex to highlight. If that fails,
+            # check if we happen to be inside a shape.
+            index = shape.nearestVertex(pos, self.epsilon)
+            if index is not None:
+                self.hVertex, self.hShape = index, shape
+                shape.highlightVertex(index, shape.MOVE_VERTEX)
+                self.overrideCursor(CURSOR_POINT)
+                self.setToolTip("Click & drag to move point")
+                self.setStatusTip(self.toolTip())
+                self.update()
+                break
+            elif shape.containsPoint(pos):
+                if self.selectedVertex():
+                    self.hShape.highlightClear()
+                self.hVertex, self.hShape = None, shape
+                self.setToolTip("Click & drag to move shape '%s'" % shape.label)
+                self.setStatusTip(self.toolTip())
+                self.overrideCursor(CURSOR_GRAB)
+                self.update()
+                break
+        else: # Nothing found, clear highlights, reset state.
+            if self.hShape:
+                self.hShape.highlightClear()
+                self.update()
+            self.hVertex, self.hShape = None, None
 
     def mousePressEvent(self, ev):
         pos = self.transformPos(ev.posF())
@@ -247,9 +255,9 @@ class Canvas(QWidget):
     def selectShapePoint(self, point):
         """Select the first shape created which contains this point."""
         self.deSelectShape()
-        if self._nearest:
-            i, s = self._nearest
-            s.highlightVertex(i, s.MOVE_VERTEX)
+        if self.selectedVertex(): # A vertex is marked for selection.
+            index, shape = self.hVertex, self.hShape
+            shape.highlightVertex(index, shape.MOVE_VERTEX)
             return
         for shape in reversed(self.shapes):
             if self.isVisible(shape) and shape.containsPoint(point):
@@ -269,11 +277,11 @@ class Canvas(QWidget):
         self.offsets = QPointF(x1, y1), QPointF(x2, y2)
 
     def boundedMoveVertex(self, pos):
-        i, shape = self._nearest
-        point = shape[i]
+        index, shape = self.hVertex, self.hShape
+        point = shape[index]
         if self.outOfPixmap(pos):
             pos = self.intersectionPoint(point, pos)
-        shape.moveVertexBy(i, pos - point)
+        shape.moveVertexBy(index, pos - point)
 
     def boundedMoveShape(self, shape, pos):
         if self.outOfPixmap(pos):
@@ -350,7 +358,7 @@ class Canvas(QWidget):
         Shape.scale = self.scale
         for shape in self.shapes:
             if (shape.selected or not self._hideBackround) and self.isVisible(shape):
-                shape.fill = shape.selected or self.highlightedShape == shape
+                shape.fill = shape.selected or shape == self.hShape
                 shape.paint(p)
         if self.current:
             self.current.paint(p)

+ 1 - 0
labelme.py

@@ -502,6 +502,7 @@ class MainWindow(QMainWindow, WindowMixin):
             shape = Shape(label=label)
             for x, y in points:
                 shape.addPoint(QPointF(x, y))
+            shape.addPoint(shape[0]) # Close shape
             s.append(shape)
             self.addLabel(shape)
             if line_color: