Skip to content

Commit 48a94c4

Browse files
committed
[ui] Intersect segment with 2 points instead of using a Rect diagonal
Fix a bug related to the SelectionLine, as the Rect was converted within a mapItem to use positive width/height. As a result the wrong diagonal of the Rect was sometimes used for the intersection test.
1 parent af273fe commit 48a94c4

File tree

4 files changed

+19
-18
lines changed

4 files changed

+19
-18
lines changed

meshroom/ui/components/edge.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,16 @@ def setContainsMouse(self, value):
110110
self._containsMouse = value
111111
self.containsMouseChanged.emit()
112112

113-
@Slot(QRectF, result=bool)
114-
def intersects(self, rect):
115-
""" Checks whether the given rectangle's diagonal intersects with the Path. """
113+
@Slot(QPointF, QPointF, result=bool)
114+
def intersectsSegment(self, p1, p2):
115+
""" Checks whether the given segment (p1, p2) intersects with the Path. """
116116
path = QPainterPath()
117117
# Starting point
118-
path.moveTo(QPointF(rect.x(), rect.y()))
118+
path.moveTo(p1)
119119
# Create a diagonal line to the other end of the rect
120-
path.lineTo(QPointF(rect.width() + rect.x(), rect.height() + rect.y()))
121-
122-
return self._path.intersects(path)
120+
path.lineTo(p2)
121+
v = self._path.intersects(path)
122+
return v
123123

124124
thicknessChanged = Signal()
125125
thickness = Property(float, getThickness, setThickness, notify=thicknessChanged)

meshroom/ui/qml/Controls/DelegateSelectionLine.qml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ SelectionLine {
1717
// Emitted when the selection has ended, with the list of selected indices and modifiers.
1818
signal delegateSelectionEnded(list<int> indices, int modifiers)
1919

20-
onSelectionEnded: function(selectionRect, modifiers) {
20+
onSelectionEnded: function(selectionP1, selectionP2, modifiers) {
2121
let selectedIndices = [];
22-
const mappedSelectionRect = mapToItem(container, selectionRect);
22+
const mappedP1 = mapToItem(container, selectionP1);
23+
const mappedP2 = mapToItem(container, selectionP2);
2324
for (var i = 0; i < modelInstantiator.count; ++i) {
2425
const delegate = modelInstantiator.itemAt(i);
25-
if (delegate.intersects(mappedSelectionRect)) {
26+
if (delegate.intersectsSegment(mappedP1, mappedP2)) {
2627
selectedIndices.push(i);
2728
}
2829
}

meshroom/ui/qml/Controls/SelectionLine.qml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Usage:
99
2. Bind the selectionShape to the MouseArea by setting the `mouseArea` property.
1010
3. Call startSelection() with coordinates when the selection starts.
1111
4. Call endSelection() when the selection ends.
12-
5. Listen to the selectionEnded signal to get the rectangle whose Diagonal is the selection line.
12+
5. Listen to the selectionEnded signal to get the segment (defined by 2 points).
1313
*/
1414

1515
Item {
@@ -19,7 +19,7 @@ Item {
1919

2020
readonly property bool active: mouseArea.drag.target == dragTarget
2121

22-
signal selectionEnded(rect selectionRect, int modifiers)
22+
signal selectionEnded(point selectionP1, point selectionP2, int modifiers)
2323

2424
function startSelection(mouse) {
2525
dragTarget.startPos.x = dragTarget.x = mouse.x;
@@ -33,8 +33,9 @@ Item {
3333
return;
3434
}
3535
mouseArea.drag.target = null;
36-
const rect = Qt.rect(selectionShape.x, selectionShape.y, selectionShape.width, selectionShape.height)
37-
selectionEnded(rect, dragTarget.modifiers);
36+
const p1 = Qt.point(selectionShape.x, selectionShape.y);
37+
const p2 = Qt.point(selectionShape.x + selectionShape.width, selectionShape.y + selectionShape.height);
38+
selectionEnded(p1, p2, dragTarget.modifiers);
3839
}
3940

4041
visible: active

meshroom/ui/qml/GraphEditor/Edge.qml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Item {
2323
property int loopSize: 0
2424
property int iteration: 0
2525

26-
// BUG: edgeArea is destroyed before path, need to test if not null to avoid warnings
26+
// Note: edgeArea is destroyed before path, so we need to test if not null to avoid warnings.
2727
readonly property bool containsMouse: (loopArea && loopArea.containsMouse) || (edgeArea && edgeArea.containsMouse)
2828

2929
signal pressed(var event)
@@ -40,15 +40,14 @@ Item {
4040
property real endY: height
4141

4242

43-
function intersects(rect) {
43+
function intersectsSegment(p1, p2) {
4444
/**
4545
* Detects whether a line along the given rects diagonal intersects with the edge mouse area.
4646
*/
4747
// The edgeArea is within the parent Item and its bounds and position are relative to its parent
4848
// Map the original rect to the coordinates of the edgeArea by subtracting the parent's coordinates from the rect
4949
// This mapped rect would ensure that the rect coordinates map to 0 of the edge area
50-
const mappedRect = Qt.rect(rect.x - x, rect.y - y, rect.width, rect.height);
51-
return edgeArea.intersects(mappedRect);
50+
return edgeArea.intersectsSegment(Qt.point(p1.x - x, p1.y - y), Qt.point(p2.x - x, p2.y - y));
5251
}
5352

5453
Shape {

0 commit comments

Comments
 (0)