Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add extreme clicking method in cvat-canvas and cvat-ui #1127

Merged
merged 3 commits into from
Feb 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cvat-canvas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Canvas itself handles:
interface DrawData {
enabled: boolean;
shapeType?: string;
rectDrawingMethod?: string;
numberOfPoints?: number;
initialState?: any;
crosshair?: boolean;
Expand Down
1 change: 1 addition & 0 deletions cvat-canvas/src/typescript/canvasModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export interface ActiveElement {
export interface DrawData {
enabled: boolean;
shapeType?: string;
rectDrawingMethod?: string;
numberOfPoints?: number;
initialState?: any;
crosshair?: boolean;
Expand Down
56 changes: 50 additions & 6 deletions cvat-canvas/src/typescript/drawHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ export class DrawHandlerImpl implements DrawHandler {
if (!this.drawData.initialState) {
const { drawInstance } = this;
this.drawInstance = null;
if (this.drawData.shapeType === 'rectangle') {
if (this.drawData.shapeType === 'rectangle'
&& this.drawData.rectDrawingMethod !== 'by_four_points') {
drawInstance.draw('cancel');
} else {
drawInstance.draw('done');
Expand Down Expand Up @@ -200,6 +201,45 @@ export class DrawHandlerImpl implements DrawHandler {
});
}

private drawBoxBy4Points(): void {
let numberOfPoints = 0;
this.drawInstance = (this.canvas as any).polygon()
.addClass('cvat_canvas_shape_drawing').attr({
'stroke-width': 0,
opacity: 0,
}).on('drawstart', () => {
// init numberOfPoints as one on drawstart
numberOfPoints = 1;
}).on('drawpoint', (e: CustomEvent) => {
// increase numberOfPoints by one on drawpoint
numberOfPoints += 1;

// finish if numberOfPoints are exactly four
if (numberOfPoints === 4) {
const bbox = (e.target as SVGPolylineElement).getBBox();
const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(bbox);

if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) {
this.onDrawDone({
shapeType: this.drawData.shapeType,
points: [xtl, ytl, xbr, ybr],
});
} else {
this.onDrawDone(null);
}
}
}).on('undopoint', () => {
if (numberOfPoints > 0) {
numberOfPoints -= 1;
}
}).off('drawdone').on('drawdone', () => {
// close drawing mode without drawing rect
this.onDrawDone(null);
});

this.drawPolyshape();
}

private drawPolyshape(): void {
this.drawInstance.attr({
z_order: Number.MAX_SAFE_INTEGER,
Expand Down Expand Up @@ -536,21 +576,25 @@ export class DrawHandlerImpl implements DrawHandler {
this.pastePoints(stringifiedPoints);
}
}

this.setupPasteEvents();
} else {
if (this.drawData.shapeType === 'rectangle') {
this.drawBox();
// Draw instance was initialized after drawBox();
this.shapeSizeElement = displayShapeSize(this.canvas, this.text);
if (this.drawData.rectDrawingMethod === 'by_four_points') {
// draw box by extreme clicking
this.drawBoxBy4Points();
} else {
// default box drawing
this.drawBox();
// Draw instance was initialized after drawBox();
this.shapeSizeElement = displayShapeSize(this.canvas, this.text);
}
} else if (this.drawData.shapeType === 'polygon') {
this.drawPolygon();
} else if (this.drawData.shapeType === 'polyline') {
this.drawPolyline();
} else if (this.drawData.shapeType === 'points') {
this.drawPoints();
}

this.setupDrawEvents();
}
}
Expand Down
2 changes: 2 additions & 0 deletions cvat-ui/src/actions/annotation-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,7 @@ export function drawShape(
labelID: number,
objectType: ObjectType,
points?: number,
rectDrawingMethod?: string,
): AnyAction {
let activeControl = ActiveControl.DRAW_RECTANGLE;
if (shapeType === ShapeType.POLYGON) {
Expand All @@ -601,6 +602,7 @@ export function drawShape(
objectType,
points,
activeControl,
rectDrawingMethod,
},
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,27 @@ import {
Select,
Button,
InputNumber,
Radio,
} from 'antd';

import { RadioChangeEvent } from 'antd/lib/radio';
import Text from 'antd/lib/typography/Text';

import {
ShapeType,
RectDrawingMethod,
} from 'reducers/interfaces';

interface Props {
shapeType: ShapeType;
rectDrawingMethod: RectDrawingMethod;
labels: any[];
minimumPoints: number;
numberOfPoints?: number;
selectedLabeID: number;
onChangeLabel(value: string): void;
onChangePoints(value: number | undefined): void;
onChangeRectDrawingMethod(event: RadioChangeEvent): void;
onDrawTrack(): void;
onDrawShape(): void;
}
Expand All @@ -37,6 +42,7 @@ function DrawShapePopoverComponent(props: Props): JSX.Element {
onDrawShape,
onChangeLabel,
onChangePoints,
onChangeRectDrawingMethod,
} = props;

return (
Expand Down Expand Up @@ -71,7 +77,37 @@ function DrawShapePopoverComponent(props: Props): JSX.Element {
</Col>
</Row>
{
shapeType !== ShapeType.RECTANGLE && (
shapeType === ShapeType.RECTANGLE ? (
<>
<Row>
<Col>
<Text className='cvat-text-color'> Drawing method </Text>
</Col>
</Row>
<Row type='flex' justify='space-around'>
<Col>
<Radio.Group
style={{ display: 'flex' }}
defaultValue={RectDrawingMethod.BY_TWO_POINTS}
onChange={onChangeRectDrawingMethod}
>
<Radio
value={RectDrawingMethod.BY_TWO_POINTS}
style={{ width: 'auto' }}
>
By 2 Points
</Radio>
<Radio
value={RectDrawingMethod.BY_FOUR_POINTS}
style={{ width: 'auto' }}
>
By 4 Points
</Radio>
</Radio.Group>
</Col>
</Row>
</>
) : (
<Row type='flex' justify='space-around' align='middle'>
<Col span={14}>
<Text className='cvat-text-color'> Number of points: </Text>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from 'react';
import { connect } from 'react-redux';
import { RadioChangeEvent } from 'antd/lib/radio';

import {
CombinedState,
ShapeType,
ObjectType,
RectDrawingMethod,
} from 'reducers/interfaces';

import {
Expand All @@ -23,6 +25,7 @@ interface DispatchToProps {
labelID: number,
objectType: ObjectType,
points?: number,
rectDrawingMethod?: string,
): void;
}

Expand All @@ -39,8 +42,9 @@ function mapDispatchToProps(dispatch: any): DispatchToProps {
labelID: number,
objectType: ObjectType,
points?: number,
rectDrawingMethod?: string,
): void {
dispatch(drawShape(shapeType, labelID, objectType, points));
dispatch(drawShape(shapeType, labelID, objectType, points, rectDrawingMethod));
},
};
}
Expand All @@ -67,6 +71,7 @@ function mapStateToProps(state: CombinedState, own: OwnProps): StateToProps {
type Props = StateToProps & DispatchToProps;

interface State {
bsekachev marked this conversation as resolved.
Show resolved Hide resolved
rectDrawingMethod?: string;
numberOfPoints?: number;
selectedLabelID: number;
}
Expand All @@ -77,6 +82,7 @@ class DrawShapePopoverContainer extends React.PureComponent<Props, State> {
super(props);

const defaultLabelID = props.labels[0].id;
const defaultRectDrawingMethod = RectDrawingMethod.BY_TWO_POINTS;
this.state = {
selectedLabelID: defaultLabelID,
};
Expand All @@ -91,6 +97,9 @@ class DrawShapePopoverContainer extends React.PureComponent<Props, State> {
if (shapeType === ShapeType.POINTS) {
this.minimumPoints = 1;
}
if (shapeType === ShapeType.RECTANGLE) {
this.state.rectDrawingMethod = defaultRectDrawingMethod;
}
}

private onDraw(objectType: ObjectType): void {
Expand All @@ -101,13 +110,15 @@ class DrawShapePopoverContainer extends React.PureComponent<Props, State> {
} = this.props;

const {
rectDrawingMethod,
numberOfPoints,
selectedLabelID,
} = this.state;

canvasInstance.cancel();
canvasInstance.draw({
enabled: true,
rectDrawingMethod,
numberOfPoints,
shapeType,
crosshair: shapeType === ShapeType.RECTANGLE,
Expand All @@ -117,6 +128,12 @@ class DrawShapePopoverContainer extends React.PureComponent<Props, State> {
objectType, numberOfPoints);
}

private onChangeRectDrawingMethod = (event: RadioChangeEvent): void => {
this.setState({
rectDrawingMethod: event.target.value,
});
};

private onDrawShape = (): void => {
this.onDraw(ObjectType.SHAPE);
};
Expand Down Expand Up @@ -163,6 +180,7 @@ class DrawShapePopoverContainer extends React.PureComponent<Props, State> {
numberOfPoints={numberOfPoints}
onChangeLabel={this.onChangeLabel}
onChangePoints={this.onChangePoints}
onChangeRectDrawingMethod={this.onChangeRectDrawingMethod}
onDrawTrack={this.onDrawTrack}
onDrawShape={this.onDrawShape}
/>
Expand Down
2 changes: 2 additions & 0 deletions cvat-ui/src/reducers/annotation-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ export default (state = defaultState, action: AnyAction): AnnotationState => {
objectType,
points,
activeControl,
rectDrawingMethod,
} = action.payload;

return {
Expand All @@ -355,6 +356,7 @@ export default (state = defaultState, action: AnyAction): AnnotationState => {
activeNumOfPoints: points,
activeObjectType: objectType,
activeShapeType: shapeType,
activeRectDrawingMethod: rectDrawingMethod,
},
};
}
Expand Down
6 changes: 6 additions & 0 deletions cvat-ui/src/reducers/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,11 @@ export enum ActiveControl {
EDIT = 'edit',
}

export enum RectDrawingMethod {
BY_TWO_POINTS = 'by_two_points',
BY_FOUR_POINTS = 'by_four_points'
}

export enum ShapeType {
RECTANGLE = 'rectangle',
POLYGON = 'polygon',
Expand Down Expand Up @@ -297,6 +302,7 @@ export interface AnnotationState {
};
drawing: {
activeShapeType: ShapeType;
activeRectDrawingMethod?: RectDrawingMethod;
activeNumOfPoints?: number;
activeLabelID: number;
activeObjectType: ObjectType;
Expand Down