Skip to content

Commit

Permalink
React UI: cuboids (cvat-ai#1451)
Browse files Browse the repository at this point in the history
  • Loading branch information
ActiveChooN committed Apr 30, 2020
1 parent 227ab05 commit bf6f550
Show file tree
Hide file tree
Showing 31 changed files with 2,009 additions and 63 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@ __pycache__
# Ignore development npm files
node_modules

# Ignore npm logs file
npm-debug.log*
yarn-debug.log*
yarn-error.log*

.DS_Store
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Re-Identification algorithm to merging bounding boxes automatically to the new UI (<https://github.com/opencv/cvat/pull/1406>)
- Methods ``import`` and ``export`` to import/export raw annotations for Job and Task in ``cvat-core`` (<https://github.com/opencv/cvat/pull/1406>)
- Versioning of client packages (``cvat-core``, ``cvat-canvas``, ``cvat-ui``). Initial versions are set to 1.0.0 (<https://github.com/opencv/cvat/pull/1448>)
- Cuboids feature was migrated from old UI to new one. (<https://github.com/opencv/cvat/pull/1451>)

### Changed
-
Expand Down
3 changes: 2 additions & 1 deletion cvat-canvas/src/scss/canvas.scss
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ polyline.cvat_canvas_shape_splitting {
cursor: nwse-resize;
}

.svg_select_points_l:hover, .svg_select_points_r:hover {
.svg_select_points_l:hover, .svg_select_points_r:hover,
.svg_select_points_ew:hover {
cursor: ew-resize;
}

Expand Down
4 changes: 4 additions & 0 deletions cvat-canvas/src/typescript/canvasModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export interface Configuration {
autoborders?: boolean;
displayAllText?: boolean;
undefinedAttrValue?: string;
showProjections?: boolean;
}

export interface DrawData {
Expand Down Expand Up @@ -527,6 +528,9 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
this.data.configuration.displayAllText = configuration.displayAllText;
}

if (typeof (configuration.showProjections) !== 'undefined') {
this.data.configuration.showProjections = configuration.showProjections;
}
if (typeof (configuration.autoborders) !== 'undefined') {
this.data.configuration.autoborders = configuration.autoborders;
}
Expand Down
108 changes: 95 additions & 13 deletions cvat-canvas/src/typescript/canvasView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,10 @@ export class CanvasViewImpl implements CanvasView, Listener {
.filter((_state: any): boolean => (
_state.clientID === self.activeElement.clientID
));
if (['cuboid', 'rectangle'].includes(state.shapeType)) {
e.preventDefault();
return;
}
if (e.ctrlKey) {
const { points } = state;
self.onEditDone(
Expand Down Expand Up @@ -721,7 +725,10 @@ export class CanvasViewImpl implements CanvasView, Listener {
public notify(model: CanvasModel & Master, reason: UpdateReasons): void {
this.geometry = this.controller.geometry;
if (reason === UpdateReasons.CONFIG_UPDATED) {
const { activeElement } = this;
this.deactivate();
this.configuration = model.configuration;
this.activate(activeElement);
this.editHandler.configurate(this.configuration);
this.drawHandler.configurate(this.configuration);

Expand Down Expand Up @@ -939,26 +946,63 @@ export class CanvasViewImpl implements CanvasView, Listener {
for (const state of states) {
if (state.hidden || state.outside) continue;
ctx.fillStyle = 'white';
if (['rectangle', 'polygon'].includes(state.shapeType)) {
const points = state.shapeType === 'rectangle' ? [
state.points[0], // xtl
state.points[1], // ytl
state.points[2], // xbr
state.points[1], // ytl
state.points[2], // xbr
state.points[3], // ybr
state.points[0], // xtl
state.points[3], // ybr
] : state.points;
if (['rectangle', 'polygon', 'cuboid'].includes(state.shapeType)) {
let points = [];
if (state.shapeType === 'rectangle') {
points = [
state.points[0], // xtl
state.points[1], // ytl
state.points[2], // xbr
state.points[1], // ytl
state.points[2], // xbr
state.points[3], // ybr
state.points[0], // xtl
state.points[3], // ybr
];
} else if (state.shapeType === 'cuboid') {
points = [
state.points[0],
state.points[1],
state.points[4],
state.points[5],
state.points[8],
state.points[9],
state.points[12],
state.points[13],
];
} else {
points = [...state.points];
}
ctx.beginPath();
ctx.moveTo(points[0], points[1]);
for (let i = 0; i < points.length; i += 2) {
ctx.lineTo(points[i], points[i + 1]);
}
ctx.closePath();
ctx.fill();
}

ctx.fill();
if (state.shapeType === 'cuboid') {
for (let i = 0; i < 5; i++) {
const points = [
state.points[(0 + i * 4) % 16],
state.points[(1 + i * 4) % 16],
state.points[(2 + i * 4) % 16],
state.points[(3 + i * 4) % 16],
state.points[(6 + i * 4) % 16],
state.points[(7 + i * 4) % 16],
state.points[(4 + i * 4) % 16],
state.points[(5 + i * 4) % 16],
];
ctx.beginPath();
ctx.moveTo(points[0], points[1]);
for (let j = 0; j < points.length; j += 2) {
ctx.lineTo(points[j], points[j + 1]);
}
ctx.closePath();
ctx.fill();
}
}
}
}
}
Expand Down Expand Up @@ -1055,7 +1099,9 @@ export class CanvasViewImpl implements CanvasView, Listener {
return `${acc}${val},`;
}, '',
);
(shape as any).clear();
if (state.shapeType !== 'cuboid') {
(shape as any).clear();
}
shape.attr('points', stringified);

if (state.shapeType === 'points' && !isInvisible) {
Expand Down Expand Up @@ -1116,6 +1162,9 @@ export class CanvasViewImpl implements CanvasView, Listener {
} else if (state.shapeType === 'points') {
this.svgShapes[state.clientID] = this
.addPoints(stringified, state);
} else if (state.shapeType === 'cuboid') {
this.svgShapes[state.clientID] = this
.addCuboid(stringified, state);
}
}

Expand Down Expand Up @@ -1202,6 +1251,10 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.selectize(false, shape);
}

if (drawnState.shapeType === 'cuboid') {
(shape as any).attr('projections', false);
}

(shape as any).off('resizestart');
(shape as any).off('resizing');
(shape as any).off('resizedone');
Expand Down Expand Up @@ -1281,6 +1334,11 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.content.append(shape.node);
}

const { showProjections } = this.configuration;
if (state.shapeType === 'cuboid' && showProjections) {
(shape as any).attr('projections', true);
}

if (!state.pinned) {
shape.addClass('cvat_canvas_shape_draggable');
(shape as any).draggable().on('dragstart', (): void => {
Expand Down Expand Up @@ -1548,6 +1606,30 @@ export class CanvasViewImpl implements CanvasView, Listener {
return polyline;
}

private addCuboid(points: string, state: any): any {
const cube = (this.adoptedContent as any).cube(points)
.fill(state.color).attr({
clientID: state.clientID,
'color-rendering': 'optimizeQuality',
id: `cvat_canvas_shape_${state.clientID}`,
fill: state.color,
'shape-rendering': 'geometricprecision',
stroke: state.color,
'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale,
'data-z-order': state.zOrder,
}).addClass('cvat_canvas_shape');

if (state.occluded) {
cube.addClass('cvat_canvas_shape_occluded');
}

if (state.hidden || state.outside) {
cube.style('display', 'none');
}

return cube;
}

private setupPoints(basicPolyline: SVG.PolyLine, state: any): any {
this.selectize(true, basicPolyline);

Expand Down
2 changes: 2 additions & 0 deletions cvat-canvas/src/typescript/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const AREA_THRESHOLD = 9;
const SIZE_THRESHOLD = 3;
const POINTS_STROKE_WIDTH = 1.5;
const POINTS_SELECTED_STROKE_WIDTH = 4;
const MIN_EDGE_LENGTH = 3;
const UNDEFINED_ATTRIBUTE_VALUE = '__undefined__';

export default {
Expand All @@ -21,5 +22,6 @@ export default {
SIZE_THRESHOLD,
POINTS_STROKE_WIDTH,
POINTS_SELECTED_STROKE_WIDTH,
MIN_EDGE_LENGTH,
UNDEFINED_ATTRIBUTE_VALUE,
};
Loading

0 comments on commit bf6f550

Please sign in to comment.