Skip to content

Commit

Permalink
Semi-automatic tools enhancements (Non-blocking UI, tips) (#3473)
Browse files Browse the repository at this point in the history
  • Loading branch information
Boris Sekachev authored Aug 6, 2021
1 parent d773f8c commit 59af610
Show file tree
Hide file tree
Showing 22 changed files with 400 additions and 142 deletions.
16 changes: 9 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Notification if the browser does not support nesassary API
- Additional inline tips in interactors with demo gifs (<https://github.com/openvinotoolkit/cvat/pull/3473>)

### Changed

- TDB
- Non-blocking UI when using interactors (<https://github.com/openvinotoolkit/cvat/pull/3473>)
- "Selected opacity" slider now defines opacity level for shapes being drawnSelected opacity (<https://github.com/openvinotoolkit/cvat/pull/3473>)

### Deprecated

Expand Down Expand Up @@ -874,20 +876,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
```
## [Unreleased]
### Added
-
- TDB
### Changed
-
- TDB
### Deprecated
-
- TDB
### Removed
-
- TDB
### Fixed
-
- TDB
### Security
-
- TDB
```
2 changes: 1 addition & 1 deletion cvat-canvas/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cvat-canvas/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-canvas",
"version": "2.5.0",
"version": "2.6.0",
"description": "Part of Computer Vision Annotation Tool which presents its canvas library",
"main": "src/canvas.ts",
"scripts": {
Expand Down
6 changes: 2 additions & 4 deletions cvat-canvas/src/scss/canvas.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ polyline.cvat_shape_action_opacity {
}

.cvat_shape_drawing_opacity {
fill-opacity: 0.2;
stroke-opacity: 1;
}

Expand Down Expand Up @@ -161,9 +160,8 @@ polyline.cvat_canvas_shape_splitting {

.cvat_canvas_removable_interaction_point {
cursor:
url(
'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAxMCAxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEgMUw5IDlNMSA5TDkgMSIgc3Ryb2tlPSJibGFjayIvPgo8L3N2Zz4K'
) 10 10,
url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAxMCAxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEgMUw5IDlNMSA5TDkgMSIgc3Ryb2tlPSJibGFjayIvPgo8L3N2Zz4K')
10 10,
auto;
}

Expand Down
15 changes: 15 additions & 0 deletions cvat-canvas/src/typescript/canvasModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export interface Configuration {
forceDisableEditing?: boolean;
intelligentPolygonCrop?: boolean;
forceFrameUpdate?: boolean;
creationOpacity?: number;
}

export interface DrawData {
Expand Down Expand Up @@ -547,6 +548,16 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
}
}

// install default values for drawing method
if (drawData.enabled) {
if (drawData.shapeType === 'rectangle') {
this.data.drawData.rectDrawingMethod = drawData.rectDrawingMethod || RectDrawingMethod.CLASSIC;
}
if (drawData.shapeType === 'cuboid') {
this.data.drawData.cuboidDrawingMethod = drawData.cuboidDrawingMethod || CuboidDrawingMethod.CLASSIC;
}
}

this.notify(UpdateReasons.DRAW);
}

Expand Down Expand Up @@ -656,6 +667,10 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
this.data.configuration.forceFrameUpdate = configuration.forceFrameUpdate;
}

if (typeof configuration.creationOpacity === 'number') {
this.data.configuration.creationOpacity = configuration.creationOpacity;
}

this.notify(UpdateReasons.CONFIG_UPDATED);
}

Expand Down
4 changes: 4 additions & 0 deletions cvat-canvas/src/typescript/canvasView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.adoptedContent,
this.adoptedText,
this.autoborderHandler,
this.geometry,
this.configuration,
);
this.editHandler = new EditHandlerImpl(this.onEditDone.bind(this), this.adoptedContent, this.autoborderHandler);
this.mergeHandler = new MergeHandlerImpl(
Expand Down Expand Up @@ -1026,6 +1028,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.onInteraction.bind(this),
this.adoptedContent,
this.geometry,
this.configuration,
);

// Setup event handlers
Expand Down Expand Up @@ -1117,6 +1120,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.activate(activeElement);
this.editHandler.configurate(this.configuration);
this.drawHandler.configurate(this.configuration);
this.interactionHandler.configurate(this.configuration);

// remove if exist and not enabled
// this.setupObjects([]);
Expand Down
26 changes: 25 additions & 1 deletion cvat-canvas/src/typescript/drawHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export class DrawHandlerImpl implements DrawHandler {
private crosshair: Crosshair;
private drawData: DrawData;
private geometry: Geometry;
private configuration: Configuration;
private autoborderHandler: AutoborderHandler;
private autobordersEnabled: boolean;

Expand Down Expand Up @@ -371,6 +372,7 @@ export class DrawHandlerImpl implements DrawHandler {
.addClass('cvat_canvas_shape_drawing')
.attr({
'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale,
'fill-opacity': this.configuration.creationOpacity,
});
}

Expand Down Expand Up @@ -527,6 +529,7 @@ export class DrawHandlerImpl implements DrawHandler {
.addClass('cvat_canvas_shape_drawing')
.attr({
'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale,
'fill-opacity': this.configuration.creationOpacity,
});

this.drawPolyshape();
Expand Down Expand Up @@ -597,6 +600,7 @@ export class DrawHandlerImpl implements DrawHandler {
.addClass('cvat_canvas_shape_drawing')
.attr({
'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale,
'fill-opacity': this.configuration.creationOpacity,
});
}

Expand Down Expand Up @@ -654,6 +658,7 @@ export class DrawHandlerImpl implements DrawHandler {
.addClass('cvat_canvas_shape_drawing')
.attr({
'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale,
'fill-opacity': this.configuration.creationOpacity,
});
this.pasteShape();

Expand Down Expand Up @@ -686,6 +691,7 @@ export class DrawHandlerImpl implements DrawHandler {
.addClass('cvat_canvas_shape_drawing')
.attr({
'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale,
'fill-opacity': this.configuration.creationOpacity,
});
this.pasteShape();
this.pastePolyshape();
Expand All @@ -709,6 +715,7 @@ export class DrawHandlerImpl implements DrawHandler {
.attr({
'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale,
'face-stroke': 'black',
'fill-opacity': this.configuration.creationOpacity,
});
this.pasteShape();
this.pastePolyshape();
Expand Down Expand Up @@ -845,6 +852,8 @@ export class DrawHandlerImpl implements DrawHandler {
canvas: SVG.Container,
text: SVG.Container,
autoborderHandler: AutoborderHandler,
geometry: Geometry,
configuration: Configuration,
) {
this.autoborderHandler = autoborderHandler;
this.autobordersEnabled = false;
Expand All @@ -855,7 +864,8 @@ export class DrawHandlerImpl implements DrawHandler {
this.initialized = false;
this.canceled = false;
this.drawData = null;
this.geometry = null;
this.geometry = geometry;
this.configuration = configuration;
this.crosshair = new Crosshair();
this.drawInstance = null;
this.pointsGroup = null;
Expand All @@ -874,6 +884,20 @@ export class DrawHandlerImpl implements DrawHandler {
}

public configurate(configuration: Configuration): void {
this.configuration = configuration;

const isFillableRect = this.drawData
&& this.drawData.shapeType === 'rectangle'
&& (this.drawData.rectDrawingMethod === RectDrawingMethod.CLASSIC || this.drawData.initialState);
const isFillableCuboid = this.drawData
&& this.drawData.shapeType === 'cuboid'
&& (this.drawData.cuboidDrawingMethod === CuboidDrawingMethod.CLASSIC || this.drawData.initialState);
const isFilalblePolygon = this.drawData && this.drawData.shapeType === 'polygon';

if (this.drawInstance && (isFillableRect || isFillableCuboid || isFilalblePolygon)) {
this.drawInstance.fill({ opacity: configuration.creationOpacity });
}

if (typeof configuration.autoborders === 'boolean') {
this.autobordersEnabled = configuration.autoborders;
if (this.drawInstance) {
Expand Down
32 changes: 29 additions & 3 deletions cvat-canvas/src/typescript/interactionHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@ import Crosshair from './crosshair';
import {
translateToSVG, PropType, stringifyPoints, translateToCanvas,
} from './shared';
import { InteractionData, InteractionResult, Geometry } from './canvasModel';
import {
InteractionData, InteractionResult, Geometry, Configuration,
} from './canvasModel';

export interface InteractionHandler {
transform(geometry: Geometry): void;
interact(interactData: InteractionData): void;
configurate(config: Configuration): void;
cancel(): void;
}

export class InteractionHandlerImpl implements InteractionHandler {
private onInteraction: (shapes: InteractionResult[] | null, shapesUpdated?: boolean, isDone?: boolean) => void;
private configuration: Configuration;
private geometry: Geometry;
private canvas: SVG.Container;
private interactionData: InteractionData;
Expand Down Expand Up @@ -196,7 +200,8 @@ export class InteractionHandlerImpl implements InteractionHandler {
.addClass('cvat_canvas_shape_drawing')
.attr({
'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale,
});
})
.fill({ opacity: this.configuration.creationOpacity, color: 'white' });
}

private initInteraction(): void {
Expand Down Expand Up @@ -286,8 +291,8 @@ export class InteractionHandlerImpl implements InteractionHandler {
'shape-rendering': 'geometricprecision',
'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale,
stroke: erroredShape ? 'red' : 'black',
fill: 'none',
})
.fill({ opacity: this.configuration.creationOpacity, color: 'white' })
.addClass('cvat_canvas_interact_intermediate_shape');
this.selectize(true, this.drawnIntermediateShape, erroredShape);
} else {
Expand Down Expand Up @@ -339,12 +344,14 @@ export class InteractionHandlerImpl implements InteractionHandler {
) => void,
canvas: SVG.Container,
geometry: Geometry,
configuration: Configuration,
) {
this.onInteraction = (shapes: InteractionResult[] | null, shapesUpdated?: boolean, isDone?: boolean): void => {
this.shapesWereUpdated = false;
onInteraction(shapes, shapesUpdated, isDone, this.threshold ? this.thresholdRectSize / 2 : null);
};
this.canvas = canvas;
this.configuration = configuration;
this.geometry = geometry;
this.shapesWereUpdated = false;
this.interactionShapes = [];
Expand Down Expand Up @@ -465,6 +472,25 @@ export class InteractionHandlerImpl implements InteractionHandler {
}
}

public configurate(configuration: Configuration): void {
this.configuration = configuration;
if (this.drawnIntermediateShape) {
this.drawnIntermediateShape.fill({
opacity: configuration.creationOpacity,
});
}

// when interactRectangle
if (this.currentInteractionShape && this.currentInteractionShape.type === 'rect') {
this.currentInteractionShape.fill({ opacity: configuration.creationOpacity });
}

// when interactPoints with startwithbbox
if (this.interactionShapes[0] && this.interactionShapes[0].type === 'rect') {
this.interactionShapes[0].fill({ opacity: configuration.creationOpacity });
}
}

public cancel(): void {
this.release();
this.onInteraction(null);
Expand Down
8 changes: 6 additions & 2 deletions cvat-canvas/src/typescript/svg.patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -958,8 +958,12 @@ function getTopDown(edgeIndex: EdgeIndex): number[] {
},

paintOrientationLines() {
const fillColor = this.attr('fill');
const strokeColor = this.attr('stroke');
// style has higher priority than attr, so then try to fetch it if exists
// https://stackoverflow.com/questions/47088409/svg-attributes-beaten-by-cssstyle-in-priority]
// we use getComputedStyle to get actual, not-inlined css property (come from the corresponding css class)
const computedStyles = getComputedStyle(this.node);
const fillColor = computedStyles['fill'] || this.attr('fill');
const strokeColor = computedStyles['stroke'] || this.attr('stroke');
const selectedColor = this.attr('face-stroke') || '#b0bec5';
this.frontTopEdge.stroke({ color: selectedColor });
this.frontLeftEdge.stroke({ color: selectedColor });
Expand Down
15 changes: 15 additions & 0 deletions cvat-core/src/ml-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ class MLModel {
this._framework = data.framework;
this._description = data.description;
this._type = data.type;
this._tip = {
message: data.help_message,
gif: data.animated_gif,
};
this._params = {
canvas: {
minPosVertices: data.min_pos_points,
Expand Down Expand Up @@ -84,6 +88,17 @@ class MLModel {
canvas: { ...this._params.canvas },
};
}

/**
* @typedef {Object} MlModelTip
* @property {string} message A short message for a user about the model
* @property {string} gif A gif URL to be shawn to a user as an example
* @returns {MlModelTip}
* @readonly
*/
get tip() {
return { ...this._tip };
}
}

module.exports = MLModel;
2 changes: 1 addition & 1 deletion cvat-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cvat-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-ui",
"version": "1.21.3",
"version": "1.22.0",
"description": "CVAT single-page application",
"main": "src/index.tsx",
"scripts": {
Expand Down
Loading

0 comments on commit 59af610

Please sign in to comment.