Fixed copy/paste for rotated shapes (#4061)

* Fixed copy/paste for rotated shapes

* Updated version

* Fixed issue with cropping rotated box after paste

* Checking constraints not only when create, but also when paste

* Do not enable autoborders when paste shape

* Fixed test. Getting circles coordinates is not correct way to check coordinates matching because they are in different coordinate spaces

* Using dedicated function to get points
main
Boris Sekachev 4 years ago committed by GitHub
parent 69d3ad79f6
commit 1cd2ea06b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -12,10 +12,10 @@ import {
displayShapeSize, displayShapeSize,
ShapeSizeElement, ShapeSizeElement,
stringifyPoints, stringifyPoints,
pointsToNumberArray,
BBox, BBox,
Box, Box,
Point, Point,
readPointsFromShape,
} from './shared'; } from './shared';
import Crosshair from './crosshair'; import Crosshair from './crosshair';
import consts from './consts'; import consts from './consts';
@ -37,6 +37,33 @@ interface FinalCoordinates {
box: Box; box: Box;
} }
function checkConstraint(shapeType: string, points: number[], box: Box | null = null): boolean {
if (shapeType === 'rectangle') {
const [xtl, ytl, xbr, ybr] = points;
return (xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD;
}
if (shapeType === 'polygon') {
return (box.xbr - box.xtl) * (box.ybr - box.ytl) >= consts.AREA_THRESHOLD && points.length >= 3 * 2;
}
if (shapeType === 'polyline') {
return (box.xbr - box.xtl >= consts.SIZE_THRESHOLD ||
box.ybr - box.ytl >= consts.SIZE_THRESHOLD) && points.length >= 2 * 2;
}
if (shapeType === 'points') {
return points.length > 2 || (points.length === 2 && points[0] !== 0 && points[1] !== 0);
}
if (shapeType === 'cuboid') {
return points.length === 4 * 2 || points.length === 8 * 2 ||
(points.length === 2 * 2 && (points[2] - points[0]) * (points[3] - points[1]) >= consts.AREA_THRESHOLD);
}
return false;
}
export class DrawHandlerImpl implements DrawHandler { export class DrawHandlerImpl implements DrawHandler {
// callback is used to notify about creating new shape // callback is used to notify about creating new shape
private onDrawDone: (data: object | null, duration?: number, continueDraw?: boolean) => void; private onDrawDone: (data: object | null, duration?: number, continueDraw?: boolean) => void;
@ -62,24 +89,24 @@ export class DrawHandlerImpl implements DrawHandler {
private pointsGroup: SVG.G | null; private pointsGroup: SVG.G | null;
private shapeSizeElement: ShapeSizeElement; private shapeSizeElement: ShapeSizeElement;
private getFinalRectCoordinates(bbox: BBox): number[] { private getFinalRectCoordinates(points: number[], fitIntoFrame: boolean): number[] {
const frameWidth = this.geometry.image.width; const frameWidth = this.geometry.image.width;
const frameHeight = this.geometry.image.height; const frameHeight = this.geometry.image.height;
const { offset } = this.geometry; const { offset } = this.geometry;
let [xtl, ytl, xbr, ybr] = [bbox.x, bbox.y, bbox.x + bbox.width, bbox.y + bbox.height].map( let [xtl, ytl, xbr, ybr] = points.map((coord: number): number => coord - offset);
(coord: number): number => coord - offset,
);
xtl = Math.min(Math.max(xtl, 0), frameWidth); if (fitIntoFrame) {
xbr = Math.min(Math.max(xbr, 0), frameWidth); xtl = Math.min(Math.max(xtl, 0), frameWidth);
ytl = Math.min(Math.max(ytl, 0), frameHeight); xbr = Math.min(Math.max(xbr, 0), frameWidth);
ybr = Math.min(Math.max(ybr, 0), frameHeight); ytl = Math.min(Math.max(ytl, 0), frameHeight);
ybr = Math.min(Math.max(ybr, 0), frameHeight);
}
return [xtl, ytl, xbr, ybr]; return [xtl, ytl, xbr, ybr];
} }
private getFinalPolyshapeCoordinates(targetPoints: number[]): FinalCoordinates { private getFinalPolyshapeCoordinates(targetPoints: number[], fitIntoFrame: boolean): FinalCoordinates {
const { offset } = this.geometry; const { offset } = this.geometry;
let points = targetPoints.map((coord: number): number => coord - offset); let points = targetPoints.map((coord: number): number => coord - offset);
const box = { const box = {
@ -184,8 +211,10 @@ export class DrawHandlerImpl implements DrawHandler {
return resultPoints; return resultPoints;
}; };
points = crop(points, Direction.Horizontal); if (fitIntoFrame) {
points = crop(points, Direction.Vertical); points = crop(points, Direction.Horizontal);
points = crop(points, Direction.Vertical);
}
for (let i = 0; i < points.length - 1; i += 2) { for (let i = 0; i < points.length - 1; i += 2) {
box.xtl = Math.min(box.xtl, points[i]); box.xtl = Math.min(box.xtl, points[i]);
@ -349,21 +378,19 @@ export class DrawHandlerImpl implements DrawHandler {
this.drawInstance = this.canvas.rect(); this.drawInstance = this.canvas.rect();
this.drawInstance this.drawInstance
.on('drawstop', (e: Event): void => { .on('drawstop', (e: Event): void => {
const bbox = (e.target as SVGRectElement).getBBox(); const points = readPointsFromShape((e.target as any as { instance: SVG.Rect }).instance);
const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(bbox); const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(points, true);
const { shapeType, redraw: clientID } = this.drawData; const { shapeType, redraw: clientID } = this.drawData;
this.release(); this.release();
if (this.canceled) return; if (this.canceled) return;
if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { if (checkConstraint('rectangle', [xtl, ytl, xbr, ybr])) {
this.onDrawDone( this.onDrawDone({
{ clientID,
clientID, shapeType,
shapeType, points: [xtl, ytl, xbr, ybr],
points: [xtl, ytl, xbr, ybr], },
}, Date.now() - this.startTimestamp);
Date.now() - this.startTimestamp,
);
} }
}) })
.on('drawupdate', (): void => { .on('drawupdate', (): void => {
@ -396,19 +423,18 @@ export class DrawHandlerImpl implements DrawHandler {
// finish if numberOfPoints are exactly four // finish if numberOfPoints are exactly four
if (numberOfPoints === 4) { if (numberOfPoints === 4) {
const bbox = (e.target as SVGPolylineElement).getBBox(); const bbox = (e.target as SVGPolylineElement).getBBox();
const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(bbox); const points = [bbox.x, bbox.y, bbox.x + bbox.width, bbox.y + bbox.height];
const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(points, true);
const { shapeType, redraw: clientID } = this.drawData; const { shapeType, redraw: clientID } = this.drawData;
this.cancel(); this.cancel();
if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { if (checkConstraint('rectangle', [xtl, ytl, xbr, ybr])) {
this.onDrawDone( this.onDrawDone({
{ shapeType,
shapeType, clientID,
clientID, points: [xtl, ytl, xbr, ybr],
points: [xtl, ytl, xbr, ybr], },
}, Date.now() - this.startTimestamp);
Date.now() - this.startTimestamp,
);
} }
} }
}) })
@ -487,38 +513,24 @@ export class DrawHandlerImpl implements DrawHandler {
}); });
this.drawInstance.on('drawdone', (e: CustomEvent): void => { this.drawInstance.on('drawdone', (e: CustomEvent): void => {
const targetPoints = pointsToNumberArray((e.target as SVGElement).getAttribute('points')); const targetPoints = readPointsFromShape((e.target as any as { instance: SVG.Shape }).instance);
const { shapeType, redraw: clientID } = this.drawData; const { shapeType, redraw: clientID } = this.drawData;
const { points, box } = shapeType === 'cuboid' ? const { points, box } = shapeType === 'cuboid' ?
this.getFinalCuboidCoordinates(targetPoints) : this.getFinalCuboidCoordinates(targetPoints) :
this.getFinalPolyshapeCoordinates(targetPoints); this.getFinalPolyshapeCoordinates(targetPoints, true);
this.release(); this.release();
if (this.canceled) return; if (this.canceled) return;
if ( if (checkConstraint(shapeType, points, box)) {
shapeType === 'polygon' && if (shapeType === 'cuboid') {
(box.xbr - box.xtl) * (box.ybr - box.ytl) >= consts.AREA_THRESHOLD && this.onDrawDone(
points.length >= 3 * 2 { clientID, shapeType, points: cuboidFrom4Points(points) },
) { Date.now() - this.startTimestamp,
this.onDrawDone({ clientID, shapeType, points }, Date.now() - this.startTimestamp); );
} else if ( return;
shapeType === 'polyline' && }
(box.xbr - box.xtl >= consts.SIZE_THRESHOLD || box.ybr - box.ytl >= consts.SIZE_THRESHOLD) &&
points.length >= 2 * 2
) {
this.onDrawDone({ clientID, shapeType, points }, Date.now() - this.startTimestamp);
} else if (shapeType === 'points' && (e.target as any).getAttribute('points') !== '0,0') {
this.onDrawDone({ clientID, shapeType, points }, Date.now() - this.startTimestamp); this.onDrawDone({ clientID, shapeType, points }, Date.now() - this.startTimestamp);
// TODO: think about correct constraign for cuboids
} else if (shapeType === 'cuboid' && points.length === 4 * 2) {
this.onDrawDone(
{
clientID,
shapeType,
points: cuboidFrom4Points(points),
},
Date.now() - this.startTimestamp,
);
} }
}); });
} }
@ -576,22 +588,20 @@ export class DrawHandlerImpl implements DrawHandler {
this.drawInstance = this.canvas.rect(); this.drawInstance = this.canvas.rect();
this.drawInstance this.drawInstance
.on('drawstop', (e: Event): void => { .on('drawstop', (e: Event): void => {
const bbox = (e.target as SVGRectElement).getBBox(); const points = readPointsFromShape((e.target as any as { instance: SVG.Rect }).instance);
const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(bbox); const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(points, true);
const { shapeType, redraw: clientID } = this.drawData; const { shapeType, redraw: clientID } = this.drawData;
this.release(); this.release();
if (this.canceled) return; if (this.canceled) return;
if ((xbr - xtl) * (ybr - ytl) >= consts.AREA_THRESHOLD) { if (checkConstraint('cuboid', [xtl, ytl, xbr, ybr])) {
const d = { x: (xbr - xtl) * 0.1, y: (ybr - ytl) * 0.1 }; const d = { x: (xbr - xtl) * 0.1, y: (ybr - ytl) * 0.1 };
this.onDrawDone( this.onDrawDone({
{ shapeType,
shapeType, points: cuboidFrom4Points([xtl, ybr, xbr, ybr, xbr, ytl, xbr + d.x, ytl - d.y]),
points: cuboidFrom4Points([xtl, ybr, xbr, ybr, xbr, ytl, xbr + d.x, ytl - d.y]), clientID,
clientID, },
}, Date.now() - this.startTimestamp);
Date.now() - this.startTimestamp,
);
} }
}) })
.on('drawupdate', (): void => { .on('drawupdate', (): void => {
@ -611,27 +621,30 @@ export class DrawHandlerImpl implements DrawHandler {
.split(/[,\s]/g) .split(/[,\s]/g)
.map((coord: string): number => +coord); .map((coord: string): number => +coord);
const { points } = this.drawData.initialState.shapeType === 'cuboid' ? const { shapeType } = this.drawData.initialState;
const { points, box } = shapeType === 'cuboid' ?
this.getFinalCuboidCoordinates(targetPoints) : this.getFinalCuboidCoordinates(targetPoints) :
this.getFinalPolyshapeCoordinates(targetPoints); this.getFinalPolyshapeCoordinates(targetPoints, true);
if (!e.detail.originalEvent.ctrlKey) { if (!e.detail.originalEvent.ctrlKey) {
this.release(); this.release();
} }
this.onDrawDone( if (checkConstraint(shapeType, points, box)) {
{ this.onDrawDone(
shapeType: this.drawData.initialState.shapeType, {
objectType: this.drawData.initialState.objectType, shapeType,
points, objectType: this.drawData.initialState.objectType,
occluded: this.drawData.initialState.occluded, points,
attributes: { ...this.drawData.initialState.attributes }, occluded: this.drawData.initialState.occluded,
label: this.drawData.initialState.label, attributes: { ...this.drawData.initialState.attributes },
color: this.drawData.initialState.color, label: this.drawData.initialState.label,
}, color: this.drawData.initialState.color,
Date.now() - this.startTimestamp, },
e.detail.originalEvent.ctrlKey, Date.now() - this.startTimestamp,
); e.detail.originalEvent.ctrlKey,
);
}
}); });
} }
@ -639,7 +652,10 @@ export class DrawHandlerImpl implements DrawHandler {
private pasteShape(): void { private pasteShape(): void {
function moveShape(shape: SVG.Shape, x: number, y: number): void { function moveShape(shape: SVG.Shape, x: number, y: number): void {
const bbox = shape.bbox(); const bbox = shape.bbox();
const { rotation } = shape.transform();
shape.untransform();
shape.move(x - bbox.width / 2, y - bbox.height / 2); shape.move(x - bbox.width / 2, y - bbox.height / 2);
shape.rotate(rotation);
} }
const { x: initialX, y: initialY } = this.cursorPosition; const { x: initialX, y: initialY } = this.cursorPosition;
@ -651,7 +667,7 @@ export class DrawHandlerImpl implements DrawHandler {
}); });
} }
private pasteBox(box: BBox): void { private pasteBox(box: BBox, rotation: number): void {
this.drawInstance = (this.canvas as any) this.drawInstance = (this.canvas as any)
.rect(box.width, box.height) .rect(box.width, box.height)
.move(box.x, box.y) .move(box.x, box.y)
@ -659,29 +675,32 @@ export class DrawHandlerImpl implements DrawHandler {
.attr({ .attr({
'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale, 'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale,
'fill-opacity': this.configuration.creationOpacity, 'fill-opacity': this.configuration.creationOpacity,
}); }).rotate(rotation);
this.pasteShape(); this.pasteShape();
this.drawInstance.on('done', (e: CustomEvent): void => { this.drawInstance.on('done', (e: CustomEvent): void => {
const bbox = this.drawInstance.node.getBBox(); const points = readPointsFromShape((e.target as any as { instance: SVG.Rect }).instance);
const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(bbox); const [xtl, ytl, xbr, ybr] = this.getFinalRectCoordinates(points, !this.drawData.initialState.rotation);
if (!e.detail.originalEvent.ctrlKey) { if (!e.detail.originalEvent.ctrlKey) {
this.release(); this.release();
} }
this.onDrawDone( if (checkConstraint('rectangle', [xtl, ytl, xbr, ybr])) {
{ this.onDrawDone(
shapeType: this.drawData.initialState.shapeType, {
objectType: this.drawData.initialState.objectType, shapeType: this.drawData.initialState.shapeType,
points: [xtl, ytl, xbr, ybr], objectType: this.drawData.initialState.objectType,
occluded: this.drawData.initialState.occluded, points: [xtl, ytl, xbr, ybr],
attributes: { ...this.drawData.initialState.attributes }, occluded: this.drawData.initialState.occluded,
label: this.drawData.initialState.label, attributes: { ...this.drawData.initialState.attributes },
color: this.drawData.initialState.color, label: this.drawData.initialState.label,
}, color: this.drawData.initialState.color,
Date.now() - this.startTimestamp, rotation: this.drawData.initialState.rotation,
e.detail.originalEvent.ctrlKey, },
); Date.now() - this.startTimestamp,
e.detail.originalEvent.ctrlKey,
);
}
}); });
} }
@ -799,7 +818,7 @@ export class DrawHandlerImpl implements DrawHandler {
y: ytl, y: ytl,
width: xbr - xtl, width: xbr - xtl,
height: ybr - ytl, height: ybr - ytl,
}); }, this.drawData.initialState.rotation);
} else { } else {
const points = this.drawData.initialState.points.map((coord: number): number => coord + offset); const points = this.drawData.initialState.points.map((coord: number): number => coord + offset);
const stringifiedPoints = stringifyPoints(points); const stringifiedPoints = stringifyPoints(points);
@ -900,7 +919,7 @@ export class DrawHandlerImpl implements DrawHandler {
if (typeof configuration.autoborders === 'boolean') { if (typeof configuration.autoborders === 'boolean') {
this.autobordersEnabled = configuration.autoborders; this.autobordersEnabled = configuration.autoborders;
if (this.drawInstance) { if (this.drawInstance && !this.drawData.initialState) {
if (this.autobordersEnabled) { if (this.autobordersEnabled) {
this.autoborderHandler.autoborder(true, this.drawInstance, this.drawData.redraw); this.autoborderHandler.autoborder(true, this.drawInstance, this.drawData.redraw);
} else { } else {

@ -188,6 +188,22 @@ export function parsePoints(source: string | number[]): Point[] {
); );
} }
export function readPointsFromShape(shape: SVG.Shape): number[] {
let points = null;
if (shape.type === 'ellipse') {
const [rx, ry] = [+shape.attr('rx'), +shape.attr('ry')];
const [cx, cy] = [+shape.attr('cx'), +shape.attr('cy')];
points = `${cx},${cy} ${cx + rx},${cy - ry}`;
} else if (shape.type === 'rect') {
points = `${shape.attr('x')},${shape.attr('y')} ` +
`${shape.attr('x') + shape.attr('width')},${shape.attr('y') + shape.attr('height')}`;
} else {
points = shape.attr('points');
}
return pointsToNumberArray(points);
}
export function stringifyPoints(points: (Point | number)[]): string { export function stringifyPoints(points: (Point | number)[]): string {
if (typeof points[0] === 'number') { if (typeof points[0] === 'number') {
return points.reduce((acc: string, val: number, idx: number): string => { return points.reduce((acc: string, val: number, idx: number): string => {

@ -1,12 +1,12 @@
{ {
"name": "cvat-core", "name": "cvat-core",
"version": "4.0.0", "version": "4.0.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "cvat-core", "name": "cvat-core",
"version": "4.0.0", "version": "4.0.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"axios": "^0.21.4", "axios": "^0.21.4",

@ -1,6 +1,6 @@
{ {
"name": "cvat-core", "name": "cvat-core",
"version": "4.0.0", "version": "4.0.1",
"description": "Part of Computer Vision Tool which presents an interface for client-side integration", "description": "Part of Computer Vision Tool which presents an interface for client-side integration",
"main": "babel.config.js", "main": "babel.config.js",
"scripts": { "scripts": {

@ -734,6 +734,7 @@
checkObjectType('object state', state, null, ObjectState); checkObjectType('object state', state, null, ObjectState);
checkObjectType('state client ID', state.clientID, 'undefined', null); checkObjectType('state client ID', state.clientID, 'undefined', null);
checkObjectType('state frame', state.frame, 'integer', null); checkObjectType('state frame', state.frame, 'integer', null);
checkObjectType('state rotation', state.rotation || 0, 'number', null);
checkObjectType('state attributes', state.attributes, null, Object); checkObjectType('state attributes', state.attributes, null, Object);
checkObjectType('state label', state.label, null, Label); checkObjectType('state label', state.label, null, Label);
@ -777,6 +778,7 @@
label_id: state.label.id, label_id: state.label.id,
occluded: state.occluded || false, occluded: state.occluded || false,
points: [...state.points], points: [...state.points],
rotation: state.rotation || 0,
type: state.shapeType, type: state.shapeType,
z_order: state.zOrder, z_order: state.zOrder,
source: state.source, source: state.source,
@ -796,6 +798,7 @@
occluded: state.occluded || false, occluded: state.occluded || false,
outside: false, outside: false,
points: [...state.points], points: [...state.points],
rotation: state.rotation || 0,
type: state.shapeType, type: state.shapeType,
z_order: state.zOrder, z_order: state.zOrder,
}, },

@ -1,12 +1,12 @@
{ {
"name": "cvat-ui", "name": "cvat-ui",
"version": "1.32.0", "version": "1.32.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "cvat-ui", "name": "cvat-ui",
"version": "1.32.0", "version": "1.32.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@ant-design/icons": "^4.6.3", "@ant-design/icons": "^4.6.3",

@ -1,6 +1,6 @@
{ {
"name": "cvat-ui", "name": "cvat-ui",
"version": "1.32.0", "version": "1.32.1",
"description": "CVAT single-page application", "description": "CVAT single-page application",
"main": "src/index.tsx", "main": "src/index.tsx",
"scripts": { "scripts": {

@ -392,6 +392,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
state.label = state.label || jobInstance.labels.filter((label: any) => label.id === activeLabelID)[0]; state.label = state.label || jobInstance.labels.filter((label: any) => label.id === activeLabelID)[0];
state.occluded = state.occluded || false; state.occluded = state.occluded || false;
state.frame = frame; state.frame = frame;
state.rotation = state.rotation || 0;
const objectState = new cvat.classes.ObjectState(state); const objectState = new cvat.classes.ObjectState(state);
onCreateAnnotations(jobInstance, frame, [objectState]); onCreateAnnotations(jobInstance, frame, [objectState]);
}; };

@ -39,23 +39,19 @@ context('Autoborder feature.', () => {
}; };
const keyCodeN = 78; const keyCodeN = 78;
const rectangleSvgJsCircleId = []; const rectanglePoints = [];
const rectangleSvgJsCircleIdSecond = []; const polygonPoints = [];
const polygonSvgJsCircleId = []; const polylinePoints = [];
const polylineSvgJsCircleId = [];
function testCollectCoord(type, id, arrToPush) {
function testCollectCxCircleCoord(arrToPush) { if (type === 'rect') {
cy.get('circle').then((circle) => { cy.get(id).invoke('attr', 'x').then((x) => arrToPush.push(+x));
for (let i = 0; i < circle.length; i++) { cy.get(id).invoke('attr', 'y').then((y) => arrToPush.push(+y));
if (circle[i].id.match(/^SvgjsCircle\d+$/)) { cy.get(id).invoke('attr', 'width').then((width) => arrToPush.push(arrToPush[0] + +width));
cy.get(`#${circle[i].id}`) cy.get(id).invoke('attr', 'height').then((height) => arrToPush.push(arrToPush[1] + +height));
.invoke('attr', 'cx') } else {
.then(($circleCx) => { cy.get(id).invoke('attr', 'points').then((points) => arrToPush.push(...points.split(/[\s]/)));
arrToPush.push($circleCx); }
});
}
}
});
} }
function testAutoborderPointsCount(expextedCount) { function testAutoborderPointsCount(expextedCount) {
@ -67,11 +63,6 @@ context('Autoborder feature.', () => {
}); });
} }
function testActivatingShape(x, y, expectedShape) {
cy.get('.cvat-canvas-container').trigger('mousemove', x, y);
cy.get(expectedShape).should('have.class', 'cvat_canvas_shape_activated');
}
before(() => { before(() => {
cy.openTaskJob(taskName); cy.openTaskJob(taskName);
cy.createRectangle(createRectangleShape2Points); cy.createRectangle(createRectangleShape2Points);
@ -86,10 +77,7 @@ context('Autoborder feature.', () => {
describe(`Testing case "${caseId}"`, () => { describe(`Testing case "${caseId}"`, () => {
it('Drawning a polygon with autoborder.', () => { it('Drawning a polygon with autoborder.', () => {
// Collect the rectagle points coordinates // Collect the rectagle points coordinates
testActivatingShape(450, 400, '#cvat_canvas_shape_1'); testCollectCoord('rect', '#cvat_canvas_shape_1', rectanglePoints);
testCollectCxCircleCoord(rectangleSvgJsCircleId);
testActivatingShape(650, 400, '#cvat_canvas_shape_2');
testCollectCxCircleCoord(rectangleSvgJsCircleIdSecond);
cy.interactControlButton('draw-polygon'); cy.interactControlButton('draw-polygon');
cy.get('.cvat-draw-polygon-popover').find('[type="button"]').contains('Shape').click(); cy.get('.cvat-draw-polygon-popover').find('[type="button"]').contains('Shape').click();
@ -101,8 +89,7 @@ context('Autoborder feature.', () => {
cy.get('.cvat_canvas_autoborder_point').should('not.exist'); cy.get('.cvat_canvas_autoborder_point').should('not.exist');
// Collect the polygon points coordinates // Collect the polygon points coordinates
testActivatingShape(450, 300, '#cvat_canvas_shape_4'); testCollectCoord('polygon', '#cvat_canvas_shape_4', polygonPoints);
testCollectCxCircleCoord(polygonSvgJsCircleId);
}); });
it('Start drawing a polyline with autobordering between the two shapes.', () => { it('Start drawing a polyline with autobordering between the two shapes.', () => {
@ -120,17 +107,19 @@ context('Autoborder feature.', () => {
cy.get('.cvat_canvas_autoborder_point').should('not.exist'); cy.get('.cvat_canvas_autoborder_point').should('not.exist');
// Collect the polygon points coordinates // Collect the polygon points coordinates
testActivatingShape(550, 350, '#cvat_canvas_shape_5'); testCollectCoord('polyline', '#cvat_canvas_shape_5', polylinePoints);
testCollectCxCircleCoord(polylineSvgJsCircleId);
}); });
it('Checking whether the coordinates of the contact points of the shapes match.', () => { it('Checking whether the coordinates of the contact points of the shapes match.', () => {
expect(polygonSvgJsCircleId[0]).to // The 1st point of the rect and the 1st polygon point
.be.equal(rectangleSvgJsCircleId[0]); // The 1st point of the rect and the 1st polygon point expect(polygonPoints[0]).to.be
expect(polygonSvgJsCircleId[2]).to .equal(`${rectanglePoints[0]},${rectanglePoints[1]}`);
.be.equal(rectangleSvgJsCircleId[1]); // The 2nd point of the rect and the 3rd polygon point // The 2nd point of the rect and the 3rd polygon point
expect(polylineSvgJsCircleId[1]).to expect(polygonPoints[2]).to
.be.equal(rectangleSvgJsCircleId[3]); // The 2nd point of the polyline and the 4th point rect .be.equal(`${rectanglePoints[2]},${rectanglePoints[1]}`);
// The 2nd point of the polyline and the 4th point rect
expect(polylinePoints[1]).to
.be.equal(`${rectanglePoints[0]},${rectanglePoints[3]}`);
}); });
}); });
}); });

Loading…
Cancel
Save