Skip to content

Commit

Permalink
Merge branch 'develop' into az/fix_dextr
Browse files Browse the repository at this point in the history
  • Loading branch information
nmanovic committed Apr 3, 2020
2 parents b445ab1 + be2ec3a commit b783851
Show file tree
Hide file tree
Showing 16 changed files with 181 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Special behaviour for attribute value ``__undefined__`` (invisibility, no shortcuts to be set in AAM)
- Dialog window with some helpful information about using filters
- Ability to display a bitmap in the new UI

### Changed
-
Expand All @@ -21,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- New shape is added when press ``esc`` when drawing instead of cancellation
- Fixed dextr segmentation.
- Fixed `FileNotFoundError` during dump after moving format files

### Security
-
Expand Down
2 changes: 2 additions & 0 deletions cvat-canvas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Canvas itself handles:
select(objectState: any): void;

fitCanvas(): void;
bitmap(enabled: boolean): void;
dragCanvas(enable: boolean): void;
zoomCanvas(enable: boolean): void;

Expand Down Expand Up @@ -189,4 +190,5 @@ Standard JS events are used.
| dragCanvas() | + | - | - | - | - | - | + | - |
| zoomCanvas() | + | - | - | - | - | - | - | + |
| cancel() | - | + | + | + | + | + | + | + |
| bitmap() | + | + | + | + | + | + | + | + |
| setZLayer() | + | + | + | + | + | + | + | + |
10 changes: 10 additions & 0 deletions cvat-canvas/src/scss/canvas.scss
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,16 @@ polyline.cvat_canvas_shape_splitting {
box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75);
}

#cvat_canvas_bitmap {
pointer-events: none;
position: absolute;
z-index: 4;
background: black;
width: 100%;
height: 100%;
box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75);
}

#cvat_canvas_grid {
position: absolute;
z-index: 2;
Expand Down
5 changes: 5 additions & 0 deletions cvat-canvas/src/typescript/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ interface Canvas {
select(objectState: any): void;

fitCanvas(): void;
bitmap(enable: boolean): void;
dragCanvas(enable: boolean): void;
zoomCanvas(enable: boolean): void;

Expand Down Expand Up @@ -86,6 +87,10 @@ class CanvasImpl implements Canvas {
);
}

public bitmap(enable: boolean): void {
this.model.bitmap(enable);
}

public dragCanvas(enable: boolean): void {
this.model.dragCanvas(enable);
}
Expand Down
16 changes: 15 additions & 1 deletion cvat-canvas/src/typescript/canvasModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ export enum UpdateReasons {
GROUP = 'group',
SELECT = 'select',
CANCEL = 'cancel',
BITMAP = 'bitmap',
DRAG_CANVAS = 'drag_canvas',
ZOOM_CANVAS = 'ZOOM_CANVAS',
ZOOM_CANVAS = 'zoom_canvas',
}

export enum Mode {
Expand All @@ -116,6 +117,7 @@ export enum Mode {
}

export interface CanvasModel {
readonly imageBitmap: boolean;
readonly image: Image | null;
readonly objects: any[];
readonly zLayer: number | null;
Expand Down Expand Up @@ -148,6 +150,7 @@ export interface CanvasModel {
select(objectState: any): void;

fitCanvas(width: number, height: number): void;
bitmap(enabled: boolean): void;
dragCanvas(enable: boolean): void;
zoomCanvas(enable: boolean): void;

Expand All @@ -159,6 +162,7 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
activeElement: ActiveElement;
angle: number;
canvasSize: Size;
imageBitmap: boolean;
image: Image | null;
imageID: number | null;
imageOffset: number;
Expand Down Expand Up @@ -191,6 +195,7 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
height: 0,
width: 0,
},
imageBitmap: false,
image: null,
imageID: null,
imageOffset: 0,
Expand Down Expand Up @@ -277,6 +282,11 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
this.notify(UpdateReasons.OBJECTS_UPDATED);
}

public bitmap(enabled: boolean): void {
this.data.imageBitmap = enabled;
this.notify(UpdateReasons.BITMAP);
}

public dragCanvas(enable: boolean): void {
if (enable && this.data.mode !== Mode.IDLE) {
throw Error(`Canvas is busy. Action: ${this.data.mode}`);
Expand Down Expand Up @@ -522,6 +532,10 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
return this.data.zLayer;
}

public get imageBitmap(): boolean {
return this.data.imageBitmap;
}

public get image(): Image | null {
return this.data.image;
}
Expand Down
69 changes: 65 additions & 4 deletions cvat-canvas/src/typescript/canvasView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
private text: SVGSVGElement;
private adoptedText: SVG.Container;
private background: HTMLCanvasElement;
private bitmap: HTMLCanvasElement;
private grid: SVGSVGElement;
private content: SVGSVGElement;
private adoptedContent: SVG.Container;
Expand Down Expand Up @@ -285,7 +286,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
}

private moveCanvas(): void {
for (const obj of [this.background, this.grid]) {
for (const obj of [this.background, this.grid, this.bitmap]) {
obj.style.top = `${this.geometry.top}px`;
obj.style.left = `${this.geometry.left}px`;
}
Expand All @@ -303,7 +304,7 @@ export class CanvasViewImpl implements CanvasView, Listener {

private transformCanvas(): void {
// Transform canvas
for (const obj of [this.background, this.grid, this.content]) {
for (const obj of [this.background, this.grid, this.content, this.bitmap]) {
obj.style.transform = `scale(${this.geometry.scale}) rotate(${this.geometry.angle}deg)`;
}

Expand Down Expand Up @@ -358,7 +359,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
}

private resizeCanvas(): void {
for (const obj of [this.background, this.grid]) {
for (const obj of [this.background, this.grid, this.bitmap]) {
obj.style.width = `${this.geometry.image.width}px`;
obj.style.height = `${this.geometry.image.height}px`;
}
Expand Down Expand Up @@ -546,6 +547,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.text = window.document.createElementNS('https://www.w3.org/2000/svg', 'svg');
this.adoptedText = (SVG.adopt((this.text as any as HTMLElement)) as SVG.Container);
this.background = window.document.createElement('canvas');
this.bitmap = window.document.createElement('canvas');
// window.document.createElementNS('https://www.w3.org/2000/svg', 'svg');

this.grid = window.document.createElementNS('https://www.w3.org/2000/svg', 'svg');
Expand Down Expand Up @@ -590,6 +592,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.text.setAttribute('id', 'cvat_canvas_text_content');
this.background.setAttribute('id', 'cvat_canvas_background');
this.content.setAttribute('id', 'cvat_canvas_content');
this.bitmap.setAttribute('id', 'cvat_canvas_bitmap');
this.bitmap.style.display = 'none';

// Setup wrappers
this.canvas.setAttribute('id', 'cvat_canvas_wrapper');
Expand All @@ -605,6 +609,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.canvas.appendChild(this.loadingAnimation);
this.canvas.appendChild(this.text);
this.canvas.appendChild(this.background);
this.canvas.appendChild(this.bitmap);
this.canvas.appendChild(this.grid);
this.canvas.appendChild(this.content);

Expand Down Expand Up @@ -702,7 +707,16 @@ export class CanvasViewImpl implements CanvasView, Listener {

public notify(model: CanvasModel & Master, reason: UpdateReasons): void {
this.geometry = this.controller.geometry;
if (reason === UpdateReasons.IMAGE_CHANGED) {

if (reason === UpdateReasons.BITMAP) {
const { imageBitmap } = model;
if (imageBitmap) {
this.bitmap.style.display = '';
this.redrawBitmap();
} else {
this.bitmap.style.display = 'none';
}
} else if (reason === UpdateReasons.IMAGE_CHANGED) {
const { image } = model;
if (!image) {
this.loadingAnimation.classList.remove('cvat_canvas_hidden');
Expand Down Expand Up @@ -875,12 +889,59 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.mode = Mode.IDLE;
this.canvas.style.cursor = '';
}

if (model.imageBitmap
&& [UpdateReasons.IMAGE_CHANGED,
UpdateReasons.OBJECTS_UPDATED,
UpdateReasons.SET_Z_LAYER,
].includes(reason)
) {
this.redrawBitmap();
}
}

public html(): HTMLDivElement {
return this.canvas;
}

private redrawBitmap(): void {
const width = +this.background.style.width.slice(0, -2);
const height = +this.background.style.height.slice(0, -2);
this.bitmap.setAttribute('width', `${width}px`);
this.bitmap.setAttribute('height', `${height}px`);
const states = this.controller.objects;

const ctx = this.bitmap.getContext('2d');
if (ctx) {
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, width, height);
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;
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();
}
}
}

private saveState(state: any): void {
this.drawnStates[state.clientID] = {
clientID: state.clientID,
Expand Down
10 changes: 10 additions & 0 deletions cvat-ui/src/actions/settings-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export enum SettingsActionTypes {
CHANGE_SELECTED_SHAPES_OPACITY = 'CHANGE_SELECTED_SHAPES_OPACITY',
CHANGE_SHAPES_COLOR_BY = 'CHANGE_SHAPES_COLOR_BY',
CHANGE_SHAPES_BLACK_BORDERS = 'CHANGE_SHAPES_BLACK_BORDERS',
CHANGE_SHOW_UNLABELED_REGIONS = 'CHANGE_SHOW_UNLABELED_REGIONS',
CHANGE_FRAME_STEP = 'CHANGE_FRAME_STEP',
CHANGE_FRAME_SPEED = 'CHANGE_FRAME_SPEED',
SWITCH_RESET_ZOOM = 'SWITCH_RESET_ZOOM',
Expand Down Expand Up @@ -66,6 +67,15 @@ export function changeShapesBlackBorders(blackBorders: boolean): AnyAction {
};
}

export function changeShowBitmap(showBitmap: boolean): AnyAction {
return {
type: SettingsActionTypes.CHANGE_SHOW_UNLABELED_REGIONS,
payload: {
showBitmap,
},
};
}

export function switchRotateAll(rotateAll: boolean): AnyAction {
return {
type: SettingsActionTypes.SWITCH_ROTATE_ALL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ interface Props {
colorBy: ColorBy;
selectedOpacity: number;
blackBorders: boolean;
showBitmap: boolean;
grid: boolean;
gridSize: number;
gridColor: GridColor;
Expand Down Expand Up @@ -112,6 +113,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
colorBy,
selectedOpacity,
blackBorders,
showBitmap,
frameData,
frameAngle,
annotations,
Expand Down Expand Up @@ -198,6 +200,10 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
this.updateShapesView();
}

if (prevProps.showBitmap !== showBitmap) {
canvasInstance.bitmap(showBitmap);
}

if (prevProps.frameAngle !== frameAngle) {
canvasInstance.rotate(frameAngle);
}
Expand Down Expand Up @@ -557,6 +563,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {

for (const state of annotations) {
let shapeColor = '';

if (colorBy === ColorBy.INSTANCE) {
shapeColor = state.color;
} else if (colorBy === ColorBy.GROUP) {
Expand All @@ -572,6 +579,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
if (handler && handler.nested) {
handler.nested.fill({ color: shapeColor });
}

(shapeView as any).instance.fill({ color: shapeColor, opacity: opacity / 100 });
(shapeView as any).instance.stroke({ color: blackBorders ? 'black' : shapeColor });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ interface Props {
opacity: number;
selectedOpacity: number;
blackBorders: boolean;
showBitmap: boolean;

collapseAppearance(): void;
changeShapesColorBy(event: RadioChangeEvent): void;
changeShapesOpacity(event: SliderValue): void;
changeSelectedShapesOpacity(event: SliderValue): void;
changeShapesBlackBorders(event: CheckboxChangeEvent): void;
changeShowBitmap(event: CheckboxChangeEvent): void;
}

function AppearanceBlock(props: Props): JSX.Element {
Expand All @@ -39,11 +41,13 @@ function AppearanceBlock(props: Props): JSX.Element {
opacity,
selectedOpacity,
blackBorders,
showBitmap,
collapseAppearance,
changeShapesColorBy,
changeShapesOpacity,
changeSelectedShapesOpacity,
changeShapesBlackBorders,
changeShowBitmap,
} = props;

return (
Expand Down Expand Up @@ -85,6 +89,12 @@ function AppearanceBlock(props: Props): JSX.Element {
>
Black borders
</Checkbox>
<Checkbox
onChange={changeShowBitmap}
checked={showBitmap}
>
Show bitmap
</Checkbox>
</div>
</Collapse.Panel>
</Collapse>
Expand Down
Loading

0 comments on commit b783851

Please sign in to comment.