Skip to content

Commit

Permalink
Merge branch 'develop' into bs/polygon_editing
Browse files Browse the repository at this point in the history
  • Loading branch information
bsekachev authored Jul 24, 2020
2 parents 3538b0d + 6a1e7af commit 622d9bb
Show file tree
Hide file tree
Showing 29 changed files with 287 additions and 54 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [1.1.0-beta] - Unreleased
### Added
- Source type support for tags, shapes and tracks (<https://github.com/opencv/cvat/pull/1192>)
- Source type support for CVAT Dumper/Loader (<https://github.com/opencv/cvat/pull/1192>)
- Intelligent polygon editing (<https://github.com/opencv/cvat/pull/1921>)

### Changed
Expand All @@ -30,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Image compression` definition mismatch (<https://github.com/opencv/cvat/issues/1900>)
- Points are dublicated during polygon interpolation sometimes (<https://github.com/opencv/cvat/pull/1892>)
- When redraw a shape with activated autobordering, previous points are visible (<https://github.com/opencv/cvat/pull/1892>)
- No mapping between side object element and context menu in some attributes (<https://github.com/opencv/cvat/pull/1923>)

### Security
-
Expand Down
6 changes: 3 additions & 3 deletions cvat-canvas/src/typescript/canvasView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
}

private onEditDone(state: any, points: number[]): void {
if (state && points) {
if (state && points) {
const event: CustomEvent = new CustomEvent('canvas.edited', {
bubbles: false,
cancelable: true,
Expand Down Expand Up @@ -1732,14 +1732,14 @@ export class CanvasViewImpl implements CanvasView, Listener {

private addText(state: any): SVG.Text {
const { undefinedAttrValue } = this.configuration;
const { label, clientID, attributes } = state;
const { label, clientID, attributes, source } = state;
const attrNames = label.attributes.reduce((acc: any, val: any): void => {
acc[val.id] = val.name;
return acc;
}, {});

return this.adoptedText.text((block): void => {
block.tspan(`${label.name} ${clientID}`).style('text-transform', 'uppercase');
block.tspan(`${label.name} ${clientID} (${source})`).style('text-transform', 'uppercase');
for (const attrID of Object.keys(attributes)) {
const value = attributes[attrID] === undefinedAttrValue
? '' : attributes[attrID];
Expand Down
3 changes: 3 additions & 0 deletions cvat-core/src/annotations-collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@
frame: Math.min.apply(null, Object.keys(keyframes).map((frame) => +frame)),
shapes: Object.values(keyframes),
group: 0,
source: objectStates[0].source,
label_id: label.id,
attributes: Object.keys(objectStates[0].attributes)
.reduce((accumulator, attrID) => {
Expand Down Expand Up @@ -763,13 +764,15 @@
points: [...state.points],
type: state.shapeType,
z_order: state.zOrder,
source: state.source,
});
} else if (state.objectType === 'track') {
constructed.tracks.push({
attributes: attributes
.filter((attr) => !labelAttributes[attr.spec_id].mutable),
frame: state.frame,
group: 0,
source: state.source,
label_id: state.label.id,
shapes: [{
attributes: attributes
Expand Down
42 changes: 41 additions & 1 deletion cvat-core/src/annotations-objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@
this.removed = false;
this.lock = false;
this.color = color;
this.source = data.source;
this.updated = Date.now();
this.attributes = data.attributes.reduce((attributeAccumulator, attr) => {
attributeAccumulator[attr.spec_id] = attr.value;
Expand Down Expand Up @@ -295,6 +296,21 @@
}, [this.clientID], frame);
}

_saveSource(source, frame) {
const undoSource = this.source;
const redoSource = source;

this.history.do(HistoryActions.CHANGED_SOURCE, () => {
this.source = undoSource;
this.updated = Date.now();
}, () => {
this.source = redoSource;
this.updated = Date.now();
}, [this.clientID], frame);

this.source = source;
}

_validateStateBeforeSave(frame, data, updated) {
let fittedPoints = [];

Expand Down Expand Up @@ -381,6 +397,10 @@
}
}

if (updated.source) {
checkObjectType('source', data.source, 'string', null);
}

return fittedPoints;
}

Expand All @@ -396,7 +416,8 @@
updateTimestamp(updated) {
const anyChanges = updated.label || updated.attributes || updated.points
|| updated.outside || updated.occluded || updated.keyframe
|| updated.zOrder || updated.hidden || updated.lock || updated.pinned;
|| updated.zOrder || updated.hidden || updated.lock || updated.pinned
|| updated.source;

if (anyChanges) {
this.updated = Date.now();
Expand Down Expand Up @@ -492,6 +513,7 @@
frame: this.frame,
label_id: this.label.id,
group: this.group,
source: this.source,
};
}

Expand Down Expand Up @@ -520,6 +542,7 @@
updated: this.updated,
pinned: this.pinned,
frame,
source: this.source,
};
}

Expand Down Expand Up @@ -619,6 +642,10 @@
this._saveHidden(data.hidden, frame);
}

if (updated.source) {
this._saveSource(data.source, frame);
}

this.updateTimestamp(updated);
updated.reset();

Expand Down Expand Up @@ -659,6 +686,7 @@
frame: this.frame,
label_id: this.label.id,
group: this.group,
source: this.source,
attributes: Object.keys(this.attributes).reduce((attributeAccumulator, attrId) => {
if (!labelAttributes[attrId].mutable) {
attributeAccumulator.push({
Expand Down Expand Up @@ -726,6 +754,7 @@
last,
},
frame,
source: this.source,
};
}

Expand Down Expand Up @@ -1034,6 +1063,7 @@
outside: current.outside,
occluded: current.occluded,
attributes: {},
source: current.source,
} : undefined;

if (redoShape) {
Expand Down Expand Up @@ -1098,6 +1128,10 @@
this._saveAttributes(data.attributes, frame);
}

if (updated.source) {
this._saveSource(data.source, frame);
}

if (updated.keyframe) {
this._saveKeyframe(frame, data.keyframe);
}
Expand Down Expand Up @@ -1164,6 +1198,7 @@
frame: this.frame,
label_id: this.label.id,
group: this.group,
source: this.source,
attributes: Object.keys(this.attributes).reduce((attributeAccumulator, attrId) => {
attributeAccumulator.push({
spec_id: attrId,
Expand Down Expand Up @@ -1194,6 +1229,7 @@
color: this.color,
updated: this.updated,
frame,
source: this.source,
};
}

Expand Down Expand Up @@ -1228,6 +1264,10 @@
this._saveColor(data.color, frame);
}

if (updated.source) {
this._saveSource(data.source, frame);
}

this.updateTimestamp(updated);
updated.reset();

Expand Down
2 changes: 1 addition & 1 deletion cvat-core/src/annotations-saver.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@

const keys = ['id', 'label_id', 'group', 'frame',
'occluded', 'z_order', 'points', 'type', 'shapes',
'attributes', 'value', 'spec_id', 'outside'];
'attributes', 'value', 'spec_id', 'source', 'outside'];

// Find created and updated objects
for (const type of Object.keys(exported)) {
Expand Down
2 changes: 2 additions & 0 deletions cvat-core/src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ function build() {
LogType,
HistoryActions,
colors,
source,
} = require('./enums');

const {
Expand Down Expand Up @@ -531,6 +532,7 @@ function build() {
LogType,
HistoryActions,
colors,
source,
},
/**
* Namespace is used for access to exceptions
Expand Down
17 changes: 17 additions & 0 deletions cvat-core/src/enums.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@
CUBOID: 'cuboid',
});

/**
* Annotation type
* @enum {string}
* @name source
* @memberof module:API.cvat.enums
* @property {string} MANUAL 'manual'
* @property {string} AUTO 'auto'
* @readonly
*/
const source = Object.freeze({
MANUAL:'manual',
AUTO:'auto',
});

/**
* Logger event types
* @enum {string}
Expand Down Expand Up @@ -190,6 +204,7 @@
* @property {string} CHANGED_LOCK Changed lock
* @property {string} CHANGED_COLOR Changed color
* @property {string} CHANGED_HIDDEN Changed hidden
* @property {string} CHANGED_SOURCE Changed source
* @property {string} MERGED_OBJECTS Merged objects
* @property {string} SPLITTED_TRACK Splitted track
* @property {string} GROUPED_OBJECTS Grouped objects
Expand All @@ -209,6 +224,7 @@
CHANGED_PINNED: 'Changed pinned',
CHANGED_COLOR: 'Changed color',
CHANGED_HIDDEN: 'Changed hidden',
CHANGED_SOURCE: 'Changed source',
MERGED_OBJECTS: 'Merged objects',
SPLITTED_TRACK: 'Splitted track',
GROUPED_OBJECTS: 'Grouped objects',
Expand Down Expand Up @@ -241,5 +257,6 @@
LogType,
HistoryActions,
colors,
source,
};
})();
19 changes: 18 additions & 1 deletion cvat-core/src/object-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* </br> Necessary fields: objectType, shapeType, frame, updated, group
* </br> Optional fields: keyframes, clientID, serverID
* </br> Optional fields which can be set later: points, zOrder, outside,
* occluded, hidden, attributes, lock, label, color, keyframe
* occluded, hidden, attributes, lock, label, color, keyframe, source
*/
constructor(serialized) {
const data = {
Expand All @@ -39,6 +39,7 @@
color: null,
hidden: null,
pinned: null,
source: null,
keyframes: serialized.keyframes,
group: serialized.group,
updated: serialized.updated,
Expand Down Expand Up @@ -68,6 +69,7 @@
this.lock = false;
this.color = false;
this.hidden = false;
this.source = false;

return reset;
},
Expand Down Expand Up @@ -109,6 +111,20 @@
*/
get: () => data.shapeType,
},
source: {
/**
* @name source
* @type {module:API.cvat.enums.source}
* @memberof module:API.cvat.classes.ObjectState
* @readonly
* @instance
*/
get: () => data.source,
set: (source) => {
data.updateFlags.source = true;
data.source = source;
},
},
clientID: {
/**
* @name clientID
Expand Down Expand Up @@ -343,6 +359,7 @@

this.label = serialized.label;
this.lock = serialized.lock;
this.source = serialized.source;

if (typeof (serialized.zOrder) === 'number') {
this.zOrder = serialized.zOrder;
Expand Down
2 changes: 1 addition & 1 deletion cvat-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cvat-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-ui",
"version": "1.6.2",
"version": "1.6.3",
"description": "CVAT single-page application",
"main": "src/index.tsx",
"scripts": {
Expand Down
1 change: 1 addition & 0 deletions cvat-ui/src/actions/annotation-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ export function propagateObjectAsync(
label: objectState.label,
zOrder: objectState.zOrder,
frame: from,
source: objectState.source,
};

await sessionInstance.logger.log(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function CanvasContextMenu(props: Props): JSX.Element | null {

return ReactDOM.createPortal(
<div className='cvat-canvas-context-menu' style={{ top, left }}>
<ObjectItemContainer clientID={activatedStateID} />
<ObjectItemContainer key={activatedStateID} clientID={activatedStateID} />
</div>,
window.document.body,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
.filter((label: any) => label.id === activeLabelID)[0];
state.occluded = state.occluded || false;
state.frame = frame;
state.source = 'manual';
const objectState = new cvat.classes.ObjectState(state);
onCreateAnnotations(jobInstance, frame, [objectState]);
};
Expand Down Expand Up @@ -500,6 +501,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
points,
} = event.detail;
state.points = points;
state.source = 'manual';
onUpdateAnnotations([state]);
};

Expand Down
Loading

0 comments on commit 622d9bb

Please sign in to comment.