Fixed redrawing a skeleton (Shift+N) (#4906)

* Fixed redrawing a skeleton (Shift+N)

* Updated version

* Added cypress test

* Enabled disabled tests

* Updated test IDs
main
Boris Sekachev 3 years ago committed by GitHub
parent 65a2610636
commit efd43637a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,6 +1,6 @@
{
"name": "cvat-canvas",
"version": "2.15.1",
"version": "2.15.2",
"description": "Part of Computer Vision Annotation Tool which presents its canvas library",
"main": "src/canvas.ts",
"scripts": {

@ -263,7 +263,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
}
if (data) {
const { clientID, points } = data as any;
const { clientID, elements } = data as any;
const points = data.points || elements.map((el: any) => el.points).flat();
if (typeof clientID === 'number') {
const event: CustomEvent = new CustomEvent('canvas.canceled', {
bubbles: false,

@ -1,6 +1,6 @@
{
"name": "cvat-ui",
"version": "1.41.3",
"version": "1.41.4",
"description": "CVAT single-page application",
"main": "src/index.tsx",
"scripts": {

@ -1,4 +1,5 @@
// Copyright (C) 2020-2022 Intel Corporation
// Copyright (C) 2022 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT
@ -1516,6 +1517,16 @@ export function searchEmptyFrameAsync(sessionInstance: any, frameFrom: number, f
};
}
const ShapeTypeToControl: Record<ShapeType, ActiveControl> = {
[ShapeType.RECTANGLE]: ActiveControl.DRAW_RECTANGLE,
[ShapeType.POLYLINE]: ActiveControl.DRAW_POLYLINE,
[ShapeType.POLYGON]: ActiveControl.DRAW_POLYGON,
[ShapeType.POINTS]: ActiveControl.DRAW_POINTS,
[ShapeType.CUBOID]: ActiveControl.DRAW_CUBOID,
[ShapeType.ELLIPSE]: ActiveControl.DRAW_ELLIPSE,
[ShapeType.SKELETON]: ActiveControl.DRAW_SKELETON,
};
export function pasteShapeAsync(): ThunkAction {
return async (dispatch: ActionCreator<Dispatch>): Promise<void> => {
const {
@ -1528,22 +1539,7 @@ export function pasteShapeAsync(): ThunkAction {
} = getStore().getState().annotation;
if (initialState && canvasInstance) {
let activeControl = ActiveControl.CURSOR;
if (initialState.shapeType === ShapeType.RECTANGLE) {
activeControl = ActiveControl.DRAW_RECTANGLE;
} else if (initialState.shapeType === ShapeType.POINTS) {
activeControl = ActiveControl.DRAW_POINTS;
} else if (initialState.shapeType === ShapeType.POLYGON) {
activeControl = ActiveControl.DRAW_POLYGON;
} else if (initialState.shapeType === ShapeType.POLYLINE) {
activeControl = ActiveControl.DRAW_POLYLINE;
} else if (initialState.shapeType === ShapeType.CUBOID) {
activeControl = ActiveControl.DRAW_CUBOID;
} else if (initialState.shapeType === ShapeType.ELLIPSE) {
activeControl = ActiveControl.DRAW_ELLIPSE;
} else if (initialState.shapeType === ShapeType.SKELETON) {
activeControl = ActiveControl.DRAW_SKELETON;
}
const activeControl = ShapeTypeToControl[initialState.shapeType as ShapeType] || ActiveControl.CURSOR;
dispatch({
type: AnnotationActionTypes.PASTE_SHAPE,
@ -1623,21 +1619,8 @@ export function repeatDrawShapeAsync(): ThunkAction {
return;
}
if (activeShapeType === ShapeType.RECTANGLE) {
activeControl = ActiveControl.DRAW_RECTANGLE;
} else if (activeShapeType === ShapeType.POINTS) {
activeControl = ActiveControl.DRAW_POINTS;
} else if (activeShapeType === ShapeType.POLYGON) {
activeControl = ActiveControl.DRAW_POLYGON;
} else if (activeShapeType === ShapeType.POLYLINE) {
activeControl = ActiveControl.DRAW_POLYLINE;
} else if (activeShapeType === ShapeType.CUBOID) {
activeControl = ActiveControl.DRAW_CUBOID;
} else if (activeShapeType === ShapeType.ELLIPSE) {
activeControl = ActiveControl.DRAW_ELLIPSE;
} else if (activeShapeType === ShapeType.SKELETON) {
activeControl = ActiveControl.DRAW_SKELETON;
}
activeControl = ShapeTypeToControl[activeShapeType];
dispatch({
type: AnnotationActionTypes.REPEAT_DRAW_SHAPE,
@ -1689,31 +1672,20 @@ export function redrawShapeAsync(): ThunkAction {
if (activatedStateID !== null) {
const [state] = states.filter((_state: any): boolean => _state.clientID === activatedStateID);
if (state && state.objectType !== ObjectType.TAG) {
let activeControl = ActiveControl.CURSOR;
if (state.shapeType === ShapeType.RECTANGLE) {
activeControl = ActiveControl.DRAW_RECTANGLE;
} else if (state.shapeType === ShapeType.POINTS) {
activeControl = ActiveControl.DRAW_POINTS;
} else if (state.shapeType === ShapeType.POLYGON) {
activeControl = ActiveControl.DRAW_POLYGON;
} else if (state.shapeType === ShapeType.POLYLINE) {
activeControl = ActiveControl.DRAW_POLYLINE;
} else if (state.shapeType === ShapeType.CUBOID) {
activeControl = ActiveControl.DRAW_CUBOID;
} else if (state.shapeType === ShapeType.SKELETON) {
activeControl = ActiveControl.DRAW_SKELETON;
}
const activeControl = ShapeTypeToControl[state.shapeType as ShapeType] || ActiveControl.CURSOR;
dispatch({
type: AnnotationActionTypes.REPEAT_DRAW_SHAPE,
payload: {
activeControl,
},
});
if (canvasInstance instanceof Canvas) {
canvasInstance.cancel();
}
canvasInstance.draw({
skeletonSVG: state.shapeType === ShapeType.SKELETON ? state.label.structure.svg : undefined,
enabled: true,
redraw: activatedStateID,
shapeType: state.shapeType,

@ -19,6 +19,12 @@ context('Manipulations with skeletons', () => {
text: 'skeletons pipeline',
count: 5,
};
const skeletonPosition = {
xtl: 100,
ytl: 100,
xbr: 300,
ybr: 300,
};
let taskID = null;
before(() => {
@ -135,11 +141,8 @@ context('Manipulations with skeletons', () => {
describe('Working with objects', () => {
function createSkeletonObject(shapeType) {
cy.createSkeleton({
...skeletonPosition,
labelName,
xtl: 100,
ytl: 100,
xbr: 300,
ybr: 300,
type: `${shapeType[0].toUpperCase()}${shapeType.slice(1).toLowerCase()}`,
});
cy.get('#cvat_canvas_shape_1').should('exist').and('be.visible');
@ -172,19 +175,43 @@ context('Manipulations with skeletons', () => {
cy.removeAnnotations();
});
it('Creating and removing a skeleton track', () => {
it('Creating, re-drawing, and removing a skeleton track', () => {
createSkeletonObject('track');
// redraw a tracked shape on the latest frame
const REDRAW_MARGIN = 400;
let prevX = Number.MAX_SAFE_INTEGER;
let prevY = Number.MAX_SAFE_INTEGER;
cy.goCheckFrameNumber(imageParams.count - 1);
cy.get('#cvat_canvas_shape_1').within(() => {
cy.get('rect').then(($rect) => {
prevX = +$rect[0].getAttribute('x');
prevY = +$rect[0].getAttribute('y');
});
});
cy.get('#cvat_canvas_shape_1').trigger('mousemove').should('have.class', 'cvat_canvas_shape_activated');
cy.get('body').trigger('keydown', { keyCode: 78, code: 'KeyN', shiftKey: true });
cy.get('.cvat-canvas-container')
.click(skeletonPosition.xtl + REDRAW_MARGIN, skeletonPosition.ytl + REDRAW_MARGIN)
.click(skeletonPosition.xbr + REDRAW_MARGIN, skeletonPosition.ybr + REDRAW_MARGIN);
cy.get('.cvat-cursor-control').should('have.class', 'cvat-active-canvas-control');
cy.get('#cvat_canvas_shape_1').within(() => {
cy.get('rect').then(($rect) => {
expect(+$rect[0].getAttribute('x')).to.be.gt(prevX);
expect(+$rect[0].getAttribute('y')).to.be.gt(prevY);
});
});
// and, finally delete the skeleton
deleteSkeleton('#cvat_canvas_shape_1', 'track', false);
cy.removeAnnotations();
cy.goCheckFrameNumber(0);
createSkeletonObject('track');
deleteSkeleton('#cvat_canvas_shape_1', 'track', true);
cy.removeAnnotations();
});
it('Splitting two skeletons and merge them back', () => {
cy.removeAnnotations();
createSkeletonObject('track');
const splittingFrame = Math.trunc(imageParams.count / 2);
@ -195,32 +222,32 @@ context('Manipulations with skeletons', () => {
// check objects after splitting
cy.get('#cvat_canvas_shape_1').should('not.exist');
cy.get('#cvat_canvas_shape_18').should('exist').and('not.be.visible');
cy.get('#cvat_canvas_shape_24').should('exist').and('be.visible');
cy.get('#cvat_canvas_shape_12').should('exist').and('not.be.visible');
cy.get('#cvat_canvas_shape_18').should('exist').and('be.visible');
cy.goToNextFrame(splittingFrame + 1);
cy.get('#cvat_canvas_shape_18').should('not.exist');
cy.get('#cvat_canvas_shape_24').should('exist').and('be.visible');
cy.get('#cvat_canvas_shape_12').should('not.exist');
cy.get('#cvat_canvas_shape_18').should('exist').and('be.visible');
// now merge them back
cy.get('.cvat-merge-control').click();
cy.get('#cvat_canvas_shape_24').click();
cy.get('#cvat_canvas_shape_18').click();
cy.goCheckFrameNumber(0);
cy.get('#cvat_canvas_shape_18').click();
cy.get('#cvat_canvas_shape_12').click();
cy.get('body').type('m');
// and check objects after merge
cy.get('#cvat_canvas_shape_12').should('not.exist');
cy.get('#cvat_canvas_shape_18').should('not.exist');
cy.get('#cvat_canvas_shape_24').should('not.exist');
cy.get('#cvat_canvas_shape_30').should('exist').and('be.visible');
cy.get('#cvat_canvas_shape_24').should('exist').and('be.visible');
cy.goCheckFrameNumber(splittingFrame + 1);
cy.get('#cvat_canvas_shape_30').should('exist').and('be.visible');
cy.get('#cvat_canvas_shape_24').should('exist').and('be.visible');
cy.goCheckFrameNumber(imageParams.count - 1);
cy.get('#cvat_canvas_shape_30').should('exist').and('be.visible');
cy.get('#cvat_canvas_shape_24').should('exist').and('be.visible');
cy.removeAnnotations();
});

Loading…
Cancel
Save