Skip to content

Commit 8323104

Browse files
Merge pull request #8300 from cvat-ai/release-2.16.3
Release v2.16.3
2 parents 3811aed + 80d3999 commit 8323104

File tree

95 files changed

+2296
-1715
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+2296
-1715
lines changed

.github/workflows/full.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,18 +133,23 @@ jobs:
133133
- name: Verify API schema
134134
id: verify_schema
135135
run: |
136-
docker run --rm --entrypoint /bin/bash cvat/server:${CVAT_VERSION} \
136+
docker run --rm cvat/server:${CVAT_VERSION} bash \
137137
-c 'python manage.py spectacular' > cvat/schema-expected.yml
138138
139139
if ! git diff --no-index cvat/schema.yml cvat/schema-expected.yml; then
140140
echo
141141
echo 'API schema has changed! Please update cvat/schema.yml:'
142142
echo
143-
echo ' docker run --rm --entrypoint /bin/bash cvat/server:dev \'
143+
echo ' docker run --rm cvat/server:dev bash \'
144144
echo " -c 'python manage.py spectacular' > cvat/schema.yml"
145145
exit 1
146146
fi
147147
148+
- name: Verify migrations
149+
run: |
150+
docker run --rm cvat/server:${CVAT_VERSION} bash \
151+
-c 'python manage.py makemigrations --check'
152+
148153
- name: Upload expected schema as an artifact
149154
if: failure() && steps.verify_schema.conclusion == 'failure'
150155
uses: actions/[email protected]

.github/workflows/main.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,23 @@ jobs:
9595
id: verify_schema
9696
run: |
9797
docker load --input /tmp/cvat_server/image.tar
98-
docker run --rm --entrypoint /bin/bash cvat/server \
98+
docker run --rm cvat/server bash \
9999
-c 'python manage.py spectacular' > cvat/schema-expected.yml
100100
101101
if ! git diff --no-index cvat/schema.yml cvat/schema-expected.yml; then
102102
echo
103103
echo 'API schema has changed! Please update cvat/schema.yml:'
104104
echo
105-
echo ' docker run --rm --entrypoint /bin/bash cvat/server:dev \'
105+
echo ' docker run --rm cvat/server:dev bash \'
106106
echo " -c 'python manage.py spectacular' > cvat/schema.yml"
107107
exit 1
108108
fi
109109
110+
- name: Verify migrations
111+
run: |
112+
docker run --rm cvat/server bash \
113+
-c 'python manage.py makemigrations --check'
114+
110115
- name: Upload CVAT server artifact
111116
uses: actions/upload-artifact@v3
112117
with:

CHANGELOG.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616

1717
<!-- scriv-insert-here -->
1818

19+
<a id='changelog-2.16.3'></a>
20+
## \[2.16.3\] - 2024-08-13
21+
22+
### Added
23+
24+
- Labels mapper on UI now supports attributes for skeleton points
25+
(<https://github.com/cvat-ai/cvat/pull/8251>)
26+
27+
- Segment Anything now supports bounding box input
28+
(<https://github.com/cvat-ai/cvat/pull/8270>)
29+
30+
### Changed
31+
32+
- Player navigation not blocked anymore if a frame is being loaded from the server
33+
(<https://github.com/cvat-ai/cvat/pull/8284>)
34+
35+
- Accelerated implementation of IntelligentScissors from OpenCV
36+
(<https://github.com/cvat-ai/cvat/pull/8293>)
37+
38+
### Fixed
39+
40+
- Issue tool was not reset after creating new issue
41+
(<https://github.com/cvat-ai/cvat/pull/8236>)
42+
43+
- Fixed issue with slices handling in `LazyList` which caused problems with exporting masks
44+
in `CVAT for images 1.1` format.
45+
(<https://github.com/cvat-ai/cvat/pull/8299>)
46+
1947
<a id='changelog-2.16.2'></a>
2048
## \[2.16.2\] - 2024-08-06
2149

cvat-canvas/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cvat-canvas",
3-
"version": "2.20.6",
3+
"version": "2.20.8",
44
"type": "module",
55
"description": "Part of Computer Vision Annotation Tool which presents its canvas library",
66
"main": "src/canvas.ts",

cvat-canvas/src/scss/canvas.scss

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,6 @@ polyline.cvat_shape_drawing_opacity {
6363
stroke: red;
6464
}
6565

66-
.cvat_canvas_threshold {
67-
stroke: red;
68-
}
69-
7066
.cvat_canvas_shape_selection {
7167
@extend .cvat_shape_action_dasharray;
7268
@extend .cvat_shape_action_opacity;
@@ -255,10 +251,6 @@ g.cvat_canvas_shape_occluded {
255251
auto;
256252
}
257253

258-
.cvat_canvas_interact_intermediate_shape_point {
259-
pointer-events: none;
260-
}
261-
262254
.svg_select_boundingRect {
263255
opacity: 0;
264256
pointer-events: none;

cvat-canvas/src/typescript/canvasModel.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,12 @@ export interface InteractionData {
129129
minPosVertices?: number;
130130
minNegVertices?: number;
131131
startWithBox?: boolean;
132-
enableThreshold?: boolean;
133132
enableSliding?: boolean;
134133
allowRemoveOnlyLast?: boolean;
135134
intermediateShape?: {
136135
shapeType: string;
137136
points: number[];
138137
};
139-
onChangeToolsBlockerState?: (event: string) => void;
140138
}
141139

142140
export interface InteractionResult {
@@ -549,14 +547,24 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
549547
) {
550548
this.data.zLayer = zLayer;
551549
this.data.objects = objectStates;
552-
this.notify(UpdateReasons.OBJECTS_UPDATED);
550+
if (this.data.image) {
551+
// display objects only if there is a drawn image
552+
// if there is not, UpdateReasons.OBJECTS_UPDATED will be triggered after image is set
553+
// it covers cases when annotations are changed while image is being received from the server
554+
// e.g. with UI buttons (lock, unlock), shortcuts, delete/restore frames,
555+
// and anytime when a list of objects updated in cvat-ui
556+
this.notify(UpdateReasons.OBJECTS_UPDATED);
557+
}
553558
return;
554559
}
555560

556561
this.data.imageID = frameData.number;
562+
this.data.imageIsDeleted = frameData.deleted;
563+
if (this.data.imageIsDeleted) {
564+
this.data.angle = 0;
565+
}
557566

558567
const { zLayer: prevZLayer, objects: prevObjects } = this.data;
559-
560568
frameData
561569
.data((): void => {
562570
this.data.image = null;
@@ -580,11 +588,6 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
580588
};
581589

582590
this.data.image = data;
583-
this.data.imageIsDeleted = frameData.deleted;
584-
if (this.data.imageIsDeleted) {
585-
this.data.angle = 0;
586-
}
587-
588591
this.fit();
589592

590593
// restore correct image position after switching to a new frame
@@ -811,11 +814,8 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
811814
if (![Mode.IDLE, Mode.INTERACT].includes(this.data.mode)) {
812815
throw Error(`Canvas is busy. Action: ${this.data.mode}`);
813816
}
814-
const thresholdChanged = this.data.interactionData.enableThreshold !== interactionData.enableThreshold;
815-
if (interactionData.enabled && !interactionData.intermediateShape && !thresholdChanged) {
816-
if (this.data.interactionData.enabled) {
817-
throw new Error('Interaction has been already started');
818-
} else if (!interactionData.shapeType) {
817+
if (interactionData.enabled) {
818+
if (!this.data.interactionData.enabled && !interactionData.shapeType) {
819819
throw new Error('A shape type was not specified');
820820
}
821821
}

cvat-canvas/src/typescript/canvasView.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
6262
private controller: CanvasController;
6363
private svgShapes: Record<number, SVG.Shape>;
6464
private svgTexts: Record<number, SVG.Text>;
65+
private isImageLoading: boolean;
6566
private issueRegionPattern_1: SVG.Pattern;
6667
private issueRegionPattern_2: SVG.Pattern;
6768
private drawnStates: Record<number, DrawnState>;
@@ -248,7 +249,6 @@ export class CanvasViewImpl implements CanvasView, Listener {
248249
shapes: InteractionResult[] | null,
249250
shapesUpdated = true,
250251
isDone = false,
251-
threshold: number | null = null,
252252
): void => {
253253
const { zLayer } = this.controller;
254254
if (Array.isArray(shapes)) {
@@ -260,7 +260,6 @@ export class CanvasViewImpl implements CanvasView, Listener {
260260
isDone,
261261
shapes,
262262
zOrder: zLayer || 0,
263-
threshold,
264263
},
265264
});
266265

@@ -1437,6 +1436,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
14371436
editHidden: {},
14381437
sliceHidden: {},
14391438
};
1439+
1440+
this.isImageLoading = true;
14401441
this.draggableShape = null;
14411442
this.resizableShape = null;
14421443

@@ -1643,19 +1644,21 @@ export class CanvasViewImpl implements CanvasView, Listener {
16431644
if (this.mode !== Mode.IDLE) return;
16441645
if (e.ctrlKey || e.altKey) return;
16451646

1646-
const { offset } = this.controller.geometry;
1647-
const [x, y] = translateToSVG(this.content, [e.clientX, e.clientY]);
1648-
const event: CustomEvent = new CustomEvent('canvas.moved', {
1649-
bubbles: false,
1650-
cancelable: true,
1651-
detail: {
1652-
x: x - offset,
1653-
y: y - offset,
1654-
states: this.controller.objects,
1655-
},
1656-
});
1647+
if (!this.isImageLoading) {
1648+
const { offset } = this.controller.geometry;
1649+
const [x, y] = translateToSVG(this.content, [e.clientX, e.clientY]);
1650+
const event: CustomEvent = new CustomEvent('canvas.moved', {
1651+
bubbles: false,
1652+
cancelable: true,
1653+
detail: {
1654+
x: x - offset,
1655+
y: y - offset,
1656+
states: this.controller.objects,
1657+
},
1658+
});
16571659

1658-
this.canvas.dispatchEvent(event);
1660+
this.canvas.dispatchEvent(event);
1661+
}
16591662
});
16601663

16611664
this.content.oncontextmenu = (): boolean => false;
@@ -1787,6 +1790,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
17871790
} else if (reason === UpdateReasons.IMAGE_CHANGED) {
17881791
const { image } = model;
17891792
if (image) {
1793+
this.isImageLoading = false;
17901794
const ctx = this.background.getContext('2d');
17911795
this.background.setAttribute('width', `${image.renderWidth}px`);
17921796
this.background.setAttribute('height', `${image.renderHeight}px`);
@@ -1819,6 +1823,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
18191823
this.moveCanvas();
18201824
this.resizeCanvas();
18211825
this.transformCanvas();
1826+
} else {
1827+
this.isImageLoading = true;
18221828
}
18231829
} else if (reason === UpdateReasons.FITTED_CANVAS) {
18241830
// Canvas geometry is going to be changed. Old object positions aren't valid any more
@@ -1875,6 +1881,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
18751881
this.canvas.style.cursor = 'pointer';
18761882
} else {
18771883
this.regionSelector.select(false);
1884+
this.canvas.style.cursor = '';
18781885
}
18791886
} else if (reason === UpdateReasons.DRAG_CANVAS) {
18801887
if (this.mode === Mode.DRAG_CANVAS) {

0 commit comments

Comments
 (0)