From b543c51bbc601f28c46f9581968381efefa9614e Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Tue, 21 Jul 2020 13:18:32 +0300 Subject: [PATCH 1/3] Intelligent polygon ediing --- cvat-canvas/package-lock.json | 2 +- cvat-canvas/package.json | 2 +- cvat-canvas/src/typescript/editHandler.ts | 118 ++++++++++++++-------- 3 files changed, 78 insertions(+), 44 deletions(-) diff --git a/cvat-canvas/package-lock.json b/cvat-canvas/package-lock.json index c95854a0b06..6ea8a30fd99 100644 --- a/cvat-canvas/package-lock.json +++ b/cvat-canvas/package-lock.json @@ -1,6 +1,6 @@ { "name": "cvat-canvas", - "version": "2.0.1", + "version": "2.0.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/cvat-canvas/package.json b/cvat-canvas/package.json index 5d61f066310..8792ce08023 100644 --- a/cvat-canvas/package.json +++ b/cvat-canvas/package.json @@ -1,6 +1,6 @@ { "name": "cvat-canvas", - "version": "2.0.1", + "version": "2.0.2", "description": "Part of Computer Vision Annotation Tool which presents its canvas library", "main": "src/canvas.ts", "scripts": { diff --git a/cvat-canvas/src/typescript/editHandler.ts b/cvat-canvas/src/typescript/editHandler.ts index 3d64590269c..97c51583f61 100644 --- a/cvat-canvas/src/typescript/editHandler.ts +++ b/cvat-canvas/src/typescript/editHandler.ts @@ -180,23 +180,87 @@ export class EditHandlerImpl implements EditHandler { const [start, stop] = [this.editData.pointID, stopPointID] .sort((a, b): number => +a - +b); - if (this.editData.state.shapeType === 'polygon') { - if (start !== this.editData.pointID) { - linePoints.reverse(); + if (this.editData.state.shapeType !== 'polygon') { + let points = null; + const { offset } = this.geometry; + + if (this.editData.state.shapeType === 'polyline') { + if (start !== this.editData.pointID) { + linePoints.reverse(); + } + points = oldPoints.slice(0, start) + .concat(linePoints) + .concat(oldPoints.slice(stop + 1)); + } else { + points = oldPoints.concat(linePoints.slice(0, -1)); } - const firstPart = oldPoints.slice(0, start) - .concat(linePoints) - .concat(oldPoints.slice(stop + 1)); + points = pointsToNumberArray(points.join(' ')) + .map((coord: number): number => coord - offset); + + const { state } = this.editData; + this.edit({ + enabled: false, + }); + this.onEditDone(state, points); - const secondPart = oldPoints.slice(start, stop) - .concat(linePoints.slice(1).reverse()); + return; + } - if (firstPart.length < 3 || secondPart.length < 3) { - this.cancel(); - return; + const cutIndexes1 = oldPoints.reduce((acc: string[], _: string, i: number) => + i >= stop || i <= start ? [...acc, i] : acc, []); + const cutIndexes2 = oldPoints.reduce((acc: string[], _: string, i: number) => + i <= stop && i >= start ? [...acc, i] : acc, []); + + const curveLength = (indexes: number[]) => { + const points = indexes.map((index: number): string => oldPoints[index]) + .map((point: string): string[] => point.split(',')) + .map((point: string[]): number[] => [+point[0], +point[1]]); + let length = 0; + for (let i = 1; i < points.length; i++) { + length += Math.sqrt( + (points[i][0] - points[i - 1][0]) ** 2 + + (points[i][1] - points[i - 1][1]) ** 2, + ); } + return length; + } + + const pointsCriteria = cutIndexes1.length > cutIndexes2.length; + const lengthCriteria = curveLength(cutIndexes1) > curveLength(cutIndexes2); + + if (start !== this.editData.pointID) { + linePoints.reverse(); + } + + const firstPart = oldPoints.slice(0, start) + .concat(linePoints) + .concat(oldPoints.slice(stop + 1)); + const secondPart = oldPoints.slice(start, stop) + .concat(linePoints.slice(1).reverse()); + + if (firstPart.length < 3 || secondPart.length < 3) { + this.cancel(); + return; + } + + // We do not need these events any more + this.canvas.off('mousedown.edit'); + this.canvas.off('mousemove.edit'); + + (this.editLine as any).draw('stop'); + this.editLine.remove(); + this.editLine = null; + + if (pointsCriteria && lengthCriteria) { + this.clones.push(this.canvas.polygon(firstPart.join(' '))); + this.selectPolygon(this.clones[0]); + // left indexes1 and + } else if (!pointsCriteria && !lengthCriteria) { + this.clones.push(this.canvas.polygon(secondPart.join(' '))); + this.selectPolygon(this.clones[0]); + } else { for (const points of [firstPart, secondPart]) { this.clones.push(this.canvas.polygon(points.join(' ')) .attr('fill', this.editedShape.attr('fill')) @@ -212,39 +276,9 @@ export class EditHandlerImpl implements EditHandler { clone.removeClass('cvat_canvas_shape_splitting'); }); } - - // We do not need these events any more - this.canvas.off('mousedown.edit'); - this.canvas.off('mousemove.edit'); - - (this.editLine as any).draw('stop'); - this.editLine.remove(); - this.editLine = null; - - return; } - let points = null; - const { offset } = this.geometry; - if (this.editData.state.shapeType === 'polyline') { - if (start !== this.editData.pointID) { - linePoints.reverse(); - } - points = oldPoints.slice(0, start) - .concat(linePoints) - .concat(oldPoints.slice(stop + 1)); - } else { - points = oldPoints.concat(linePoints.slice(0, -1)); - } - - points = pointsToNumberArray(points.join(' ')) - .map((coord: number): number => coord - offset); - - const { state } = this.editData; - this.edit({ - enabled: false, - }); - this.onEditDone(state, points); + return; } private setupPoints(enabled: boolean): void { From 39c02ac0279c9450ed0609ba089cf43921c907b7 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Tue, 21 Jul 2020 13:32:17 +0300 Subject: [PATCH 2/3] Changed color --- cvat-canvas/src/typescript/editHandler.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cvat-canvas/src/typescript/editHandler.ts b/cvat-canvas/src/typescript/editHandler.ts index 97c51583f61..8cea079d148 100644 --- a/cvat-canvas/src/typescript/editHandler.ts +++ b/cvat-canvas/src/typescript/editHandler.ts @@ -104,7 +104,6 @@ export class EditHandlerImpl implements EditHandler { }); this.editLine = (this.canvas as any).polyline(); - if (this.editData.state.shapeType === 'polyline') { (this.editLine as any).on('drawpoint', (e: CustomEvent): void => { const circle = (e.target as any).instance.remember('_paintHandler').set.last(); @@ -112,9 +111,11 @@ export class EditHandlerImpl implements EditHandler { }); } + const strokeColor = this.editedShape.attr('stroke'); (this.editLine as any).addClass('cvat_canvas_shape_drawing').style({ 'pointer-events': 'none', 'fill-opacity': 0, + 'stroke': strokeColor, }).attr({ 'data-origin-client-id': this.editData.state.clientID, }).on('drawstart drawpoint', (e: CustomEvent): void => { From 3538b0d760edf07e863d8975d6be9447fdbc82dc Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Tue, 21 Jul 2020 13:37:45 +0300 Subject: [PATCH 3/3] Updated changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 431512d1eac..efb33673b14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.1.0-beta] - Unreleased ### Added -- +- Intelligent polygon editing () ### Changed - Smaller object details ()