Fixed issue 5256, improved 'occluded' visualization (#5259)

* Fixed issue 5256, improved 'occluded' visualization

* Updated version & added test

* Updated changelog

* Fixed tests
main
Boris Sekachev 3 years ago committed by GitHub
parent 92ba1ab845
commit 080755a8da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -69,6 +69,7 @@ non-ascii paths while adding files from "Connected file share" (issue #4428)
- Job assignee can not resolve an issue (<https://github.com/opencv/cvat/pull/5167>) - Job assignee can not resolve an issue (<https://github.com/opencv/cvat/pull/5167>)
- Create manifest with cvat/server docker container command (<https://github.com/opencv/cvat/pull/5172>) - Create manifest with cvat/server docker container command (<https://github.com/opencv/cvat/pull/5172>)
- Cannot assign a resource to a user who has an organization (<https://github.com/opencv/cvat/pull/5218>) - Cannot assign a resource to a user who has an organization (<https://github.com/opencv/cvat/pull/5218>)
- Occluded not applied on canvas instantly for a skeleton elements (<https://github.com/opencv/cvat/pull/5259>)
- Oriented bounding boxes broken with COCO format ss(<https://github.com/opencv/cvat/pull/5219>) - Oriented bounding boxes broken with COCO format ss(<https://github.com/opencv/cvat/pull/5219>)
- Fixed upload resumption in production environments - Fixed upload resumption in production environments
(<https://github.com/opencv/cvat/issues/4839>) (<https://github.com/opencv/cvat/issues/4839>)

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

@ -148,10 +148,23 @@ polyline.cvat_canvas_shape_splitting {
stroke-dasharray: 5; stroke-dasharray: 5;
} }
.cvat_canvas_shape_occluded_point {
stroke-dasharray: 1 !important;
stroke: white;
}
circle.cvat_canvas_shape_occluded {
@extend .cvat_canvas_shape_occluded_point;
}
g.cvat_canvas_shape_occluded { g.cvat_canvas_shape_occluded {
> rect { > rect {
stroke-dasharray: 5; stroke-dasharray: 5;
} }
> circle {
@extend .cvat_canvas_shape_occluded_point;
}
} }
.svg_select_points_rot { .svg_select_points_rot {

@ -1916,10 +1916,11 @@ export class CanvasViewImpl implements CanvasView, Listener {
} }
if (drawnState.occluded !== state.occluded) { if (drawnState.occluded !== state.occluded) {
const instance = state.shapeType === 'points' ? this.svgShapes[clientID].remember('_selectHandler').nested : shape;
if (state.occluded) { if (state.occluded) {
shape.addClass('cvat_canvas_shape_occluded'); instance.addClass('cvat_canvas_shape_occluded');
} else { } else {
shape.removeClass('cvat_canvas_shape_occluded'); instance.removeClass('cvat_canvas_shape_occluded');
} }
} }
@ -3388,6 +3389,10 @@ export class CanvasViewImpl implements CanvasView, Listener {
group.addClass('cvat_canvas_hidden'); group.addClass('cvat_canvas_hidden');
} }
if (state.occluded) {
group.addClass('cvat_canvas_shape_occluded');
}
shape.remove = (): SVG.PolyLine => { shape.remove = (): SVG.PolyLine => {
this.selectize(false, shape); this.selectize(false, shape);
shape.constructor.prototype.remove.call(shape); shape.constructor.prototype.remove.call(shape);

@ -1223,7 +1223,7 @@ export function updateAnnotationsAsync(statesToUpdate: any[]): ThunkAction {
const states = await Promise.all(promises); const states = await Promise.all(promises);
const needToUpdateAll = states const needToUpdateAll = states
.some((state: any) => [ShapeType.MASK, ShapeType.SKELETON].includes(state.shapeType)); .some((state: any) => state.shapeType === ShapeType.MASK || state.parentID !== null);
if (needToUpdateAll) { if (needToUpdateAll) {
dispatch(fetchAnnotationsAsync()); dispatch(fetchAnnotationsAsync());
return; return;

@ -319,12 +319,12 @@ class ObjectsListContainer extends React.PureComponent<Props, State> {
} }
}; };
const activatedState = (): ObjectState | null => { const activatedState = (ignoreElements = false): ObjectState | null => {
if (activatedStateID !== null) { if (activatedStateID !== null) {
const state = objectStates const state = objectStates
.find((objectState: ObjectState): boolean => objectState.clientID === activatedStateID); .find((objectState: ObjectState): boolean => objectState.clientID === activatedStateID);
if (state && activatedElementID !== null) { if (state && activatedElementID !== null && !ignoreElements) {
const element = state.elements const element = state.elements
.find((_element: ObjectState): boolean => _element.clientID === activatedElementID); .find((_element: ObjectState): boolean => _element.clientID === activatedElementID);
return element || null; return element || null;
@ -399,7 +399,7 @@ class ObjectsListContainer extends React.PureComponent<Props, State> {
}, },
DELETE_OBJECT: (event: KeyboardEvent | undefined) => { DELETE_OBJECT: (event: KeyboardEvent | undefined) => {
preventDefault(event); preventDefault(event);
const state = activatedState(); const state = activatedState(true);
if (state && !readonly) { if (state && !readonly) {
removeObject(state, event ? event.shiftKey : false); removeObject(state, event ? event.shiftKey : false);
} }

@ -4,7 +4,7 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
context('Manipulations with masks', () => { context('Manipulations with masks', { scrollBehavior: false }, () => {
const taskName = 'Basic actions with masks'; const taskName = 'Basic actions with masks';
const serverFiles = ['images/image_1.jpg', 'images/image_2.jpg', 'images/image_3.jpg']; const serverFiles = ['images/image_1.jpg', 'images/image_2.jpg', 'images/image_3.jpg'];
const drawingActions = [{ const drawingActions = [{

@ -4,7 +4,7 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
context('Manipulations with skeletons', () => { context('Manipulations with skeletons', { scrollBehavior: false }, () => {
const skeletonSize = 5; const skeletonSize = 5;
const labelName = 'skeleton'; const labelName = 'skeleton';
const taskName = 'skeletons main pipeline'; const taskName = 'skeletons main pipeline';
@ -169,8 +169,14 @@ context('Manipulations with skeletons', () => {
cy.get(selector).should('not.exist'); cy.get(selector).should('not.exist');
} }
it('Creating and removing a skeleton shape', () => { it('Creating, checking occluded for a single point, and removing a skeleton shape', () => {
createSkeletonObject('shape'); createSkeletonObject('shape');
cy.get('#cvat-objects-sidebar-state-item-element-2').within(() => {
cy.get('span[aria-label="user"]').click();
});
cy.get('#cvat_canvas_shape_2').should('have.class', 'cvat_canvas_shape_occluded');
deleteSkeleton('#cvat_canvas_shape_1', 'shape', false); deleteSkeleton('#cvat_canvas_shape_1', 'shape', false);
cy.removeAnnotations(); cy.removeAnnotations();
}); });

Loading…
Cancel
Save