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

React UI: cuboids #1451

Merged
merged 50 commits into from
Apr 30, 2020
Merged
Changes from 1 commit
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
514b0e8
Added cuboid creation to canvas
ActiveChooN Mar 31, 2020
ae79dc9
wip
ActiveChooN Apr 2, 2020
fa23628
Added cube icon
ActiveChooN Apr 3, 2020
3fb6a04
Merge branch 'develop' into dk/cuboids
ActiveChooN Apr 6, 2020
da987d3
added cuboid core model
ActiveChooN Apr 7, 2020
eb22e02
wip
ActiveChooN Apr 8, 2020
3a16189
wip
ActiveChooN Apr 8, 2020
f23e354
transfer to actual points in cuboids
ActiveChooN Apr 13, 2020
7c8340d
transfer to actual points in cuboids
ActiveChooN Apr 13, 2020
8b646cb
wip
ActiveChooN Apr 14, 2020
fb5bf71
WIP: cuboid on canvas points only,
ActiveChooN Apr 15, 2020
6a5ef5c
drag events with redispatching
ActiveChooN Apr 16, 2020
c6bb483
Added additional grab points
ActiveChooN Apr 17, 2020
73e8988
Resizing using front face
bsekachev Apr 17, 2020
a34bb5d
Merged main branch
bsekachev Apr 17, 2020
24fc773
Fixed typos
bsekachev Apr 17, 2020
b8a21c8
Dorsal right edge resizing
bsekachev Apr 17, 2020
aa611bb
Updated comments
bsekachev Apr 17, 2020
e8c6e39
Fixed resize of objects with not standard perspective
bsekachev Apr 17, 2020
e0426d6
Little refactoring, removed commented code
bsekachev Apr 17, 2020
1ec859a
Little name refactoring
bsekachev Apr 17, 2020
5af3b61
Added orientation
bsekachev Apr 18, 2020
b203a1c
Code refactoring, added resize constraints
bsekachev Apr 20, 2020
c199860
Changing perspective
bsekachev Apr 20, 2020
64ec0e9
fixed merge
ActiveChooN Apr 21, 2020
435db42
fixed cuboid figure updating
ActiveChooN Apr 21, 2020
63ef6be
cuboids: fixed draggable,
ActiveChooN Apr 21, 2020
6b8290e
added cuboid copy/paste
ActiveChooN Apr 22, 2020
a2a845a
fixed cuboid undo/redo
ActiveChooN Apr 22, 2020
ad600ce
fixed cuboid merge and cuboid partly outside
ActiveChooN Apr 23, 2020
379dfd3
added cuboid edge resize points
ActiveChooN Apr 27, 2020
c8616b5
added test for cuboid in cvat-core
ActiveChooN Apr 27, 2020
d027d3a
added CHANGELOG.md
ActiveChooN Apr 27, 2020
394ad05
Merge branch 'develop' into dk/cuboids
ActiveChooN Apr 27, 2020
cc18b0a
fixed merge
ActiveChooN Apr 27, 2020
45f84e1
Merge branch 'develop' into dk/cuboids
ActiveChooN Apr 27, 2020
364bf1f
added cursors for cuboid
ActiveChooN Apr 27, 2020
b596847
cuboid control points fixes
ActiveChooN Apr 28, 2020
130b5e3
cuboid unpinned by default
ActiveChooN Apr 28, 2020
cf7899b
cuboid drawing fixes
ActiveChooN Apr 29, 2020
4df4fd5
added cuboid interpolation for client side
ActiveChooN Apr 29, 2020
8ffa020
deleted comments
ActiveChooN Apr 29, 2020
11e9470
added cuboid reset perspective
ActiveChooN Apr 29, 2020
dc450b3
wip cuboid zOrder
ActiveChooN Apr 29, 2020
10b97d2
fixed cuboid drawing
ActiveChooN Apr 29, 2020
8c2e520
Fixed zOrder for cuboids
bsekachev Apr 30, 2020
69ef609
added top and bottom faces to cuboid
ActiveChooN Apr 30, 2020
674b53c
Merge branch 'dk/cuboids' of https://github.com/opencv/cvat into dk/c…
ActiveChooN Apr 30, 2020
86a7a89
fixed faces order and edge color
ActiveChooN Apr 30, 2020
8dd786f
disabled cuboid tracks
ActiveChooN Apr 30, 2020
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
Prev Previous commit
Next Next commit
fixed cuboid merge and cuboid partly outside
ActiveChooN committed Apr 23, 2020
commit ad600cea523d98eccf4b59f3737f5159b3cc6b72
84 changes: 82 additions & 2 deletions cvat-canvas/src/typescript/drawHandler.ts
Original file line number Diff line number Diff line change
@@ -103,6 +103,84 @@ export class DrawHandlerImpl implements DrawHandler {
};
}

private getFinalCuboidCoordinates(targetPoints: number[]): {
points: number[];
box: Box;
} {
const { offset } = this.geometry;
let points = targetPoints;

const box = {
xtl: 0,
ytl: 0,
xbr: Number.MAX_SAFE_INTEGER,
ybr: Number.MAX_SAFE_INTEGER,
};

const frameWidth = this.geometry.image.width;
const frameHeight = this.geometry.image.height;

const cuboidOffsets = [];
const minCuboidOffset = {
d: Number.MAX_SAFE_INTEGER,
dx: 0,
dy: 0,
};

for (let i = 0; i < points.length - 1; i += 2) {
const [x, y] = points.slice(i);

if (x >= offset && x <= offset + frameWidth
&& y >= offset && y <= offset + frameHeight) continue;

let xOffset = 0;
let yOffset = 0;

if (x < offset) {
xOffset = offset - x;
} else if (x > offset + frameWidth) {
xOffset = offset + frameWidth - x;
}

if (y < offset) {
yOffset = offset - y;
} else if (y > offset + frameHeight) {
yOffset = offset + frameHeight - y;
}

cuboidOffsets.push([xOffset, yOffset]);
}

if (cuboidOffsets.length === points.length / 2) {
cuboidOffsets.forEach((offsetCoords: number[]): void => {
if (Math.sqrt((offsetCoords[0] ** 2) + (offsetCoords[1] ** 2))
< minCuboidOffset.d) {
minCuboidOffset.d = Math.sqrt((offsetCoords[0] ** 2) + (offsetCoords[1] ** 2));
[minCuboidOffset.dx, minCuboidOffset.dy] = offsetCoords;
}
});

points = points.map((coord: number, i: number): number => {
const finalCoord = coord + (i % 2 === 0 ? minCuboidOffset.dx : minCuboidOffset.dy);

if (i % 2 === 0) {
box.xtl = Math.max(box.xtl, finalCoord);
box.xbr = Math.min(box.xbr, finalCoord);
} else {
box.ytl = Math.max(box.ytl, finalCoord);
box.ybr = Math.min(box.ybr, finalCoord);
}

return finalCoord;
});
}

return {
points: points.map((coord: number): number => coord - offset),
box,
};
}

private addCrosshair(): void {
const { x, y } = this.cursorPosition;
this.crosshair = {
@@ -312,8 +390,9 @@ export class DrawHandlerImpl implements DrawHandler {

this.drawInstance.on('drawdone', (e: CustomEvent): void => {
const targetPoints = pointsToArray((e.target as SVGElement).getAttribute('points'));
const { points, box } = this.getFinalPolyshapeCoordinates(targetPoints);
const { shapeType } = this.drawData;
const { points, box } = shapeType === 'cuboid' ? this.getFinalCuboidCoordinates(targetPoints)
: this.getFinalPolyshapeCoordinates(targetPoints);
this.release();

if (this.canceled) return;
@@ -393,7 +472,8 @@ export class DrawHandlerImpl implements DrawHandler {
.split(/[,\s]/g)
.map((coord: string): number => +coord);

const { points } = this.getFinalPolyshapeCoordinates(targetPoints);
const { points } = this.drawData.initialState.shapeType === 'cuboid' ? this.getFinalCuboidCoordinates(targetPoints)
: this.getFinalPolyshapeCoordinates(targetPoints);
this.release();
this.onDrawDone({
shapeType: this.drawData.initialState.shapeType,
4 changes: 4 additions & 0 deletions cvat-core/src/annotations-collection.js
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
PolygonTrack,
PolylineTrack,
PointsTrack,
CuboidTrack,
Track,
Shape,
Tag,
@@ -91,6 +92,9 @@
case 'points':
trackModel = new PointsTrack(trackData, clientID, color, injection);
break;
case 'cuboid':
trackModel = new CuboidTrack(trackData, clientID, color, injection);
break;
default:
throw new DataError(
`An unexpected type of track "${type}"`,
59 changes: 46 additions & 13 deletions cvat-core/src/annotations-objects.js
Original file line number Diff line number Diff line change
@@ -115,6 +115,35 @@
return area >= MIN_SHAPE_AREA;
}

function fitPoints(shapeType, points, maxX, maxY) {
const fittedPoints = [];

for (let i = 0; i < points.length - 1; i += 2) {
const x = points[i];
const y = points[i + 1];

checkObjectType('coordinate', x, 'number', null);
checkObjectType('coordinate', y, 'number', null);

fittedPoints.push(
Math.clamp(x, 0, maxX),
Math.clamp(y, 0, maxY),
);
}

return shapeType === ObjectShape.CUBOID ? points : fittedPoints;
}

function checkOutside(points, width, height) {
let inside = false;
for (let i = 0; i < points.length - 1; i += 2) {
const [x, y] = points.slice(i);
inside = inside || (x >= 0 && x <= width && y >= 0 && y <= height);
}

return !inside;
}

function validateAttributeValue(value, attr) {
const { values } = attr;
const type = attr.inputType;
@@ -292,20 +321,9 @@
checkNumberOfPoints(this.shapeType, data.points);
// cut points
const { width, height } = this.frameMeta[frame];
for (let i = 0; i < data.points.length - 1; i += 2) {
const x = data.points[i];
const y = data.points[i + 1];

checkObjectType('coordinate', x, 'number', null);
checkObjectType('coordinate', y, 'number', null);
fittedPoints = fitPoints(this.shapeType, data.points, width, height);

fittedPoints.push(
Math.clamp(x, 0, width),
Math.clamp(y, 0, height),
);
}

if (!checkShapeArea(this.shapeType, fittedPoints)) {
if ((!checkShapeArea(this.shapeType, fittedPoints)) || checkOutside(fittedPoints, width, height)) {
fittedPoints = [];
}
}
@@ -1361,6 +1379,7 @@
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
this.shapeType = ObjectShape.CUBOID;
checkNumberOfPoints(this.shapeType, this.points);
}

static makeHull(geoPoints) {
@@ -1925,10 +1944,23 @@
}
}

class CuboidTrack extends PolyTrack {
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
this.shapeType = ObjectShape.CUBOID;
for (const shape of Object.values(this.shapes)) {
checkNumberOfPoints(this.shapeType, shape.points);
}
}

// TODO: interpolation;
}

RectangleTrack.distance = RectangleShape.distance;
PolygonTrack.distance = PolygonShape.distance;
PolylineTrack.distance = PolylineShape.distance;
PointsTrack.distance = PointsShape.distance;
CuboidTrack.distance = CuboidShape.distance;

module.exports = {
RectangleShape,
@@ -1940,6 +1972,7 @@
PolygonTrack,
PolylineTrack,
PointsTrack,
CuboidTrack,
Track,
Shape,
Tag,