|
|
|
|
@ -341,8 +341,8 @@ class ShapeModel extends Listener {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switchOutside(frame) {
|
|
|
|
|
// Only for interpolation boxes
|
|
|
|
|
if (this._type != 'interpolation_box') {
|
|
|
|
|
// Only for interpolation shapes
|
|
|
|
|
if (this._type.split('_')[0] !== 'interpolation') {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -379,7 +379,7 @@ class ShapeModel extends Listener {
|
|
|
|
|
if (frame < this._frame) {
|
|
|
|
|
if (this._frame in this._attributes.mutable) {
|
|
|
|
|
this._attributes.mutable[frame] = this._attributes.mutable[this._frame];
|
|
|
|
|
delete(this._attributes.mutable[this._frame]);
|
|
|
|
|
delete (this._attributes.mutable[this._frame]);
|
|
|
|
|
}
|
|
|
|
|
this._frame = frame;
|
|
|
|
|
}
|
|
|
|
|
@ -388,17 +388,17 @@ class ShapeModel extends Listener {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switchKeyFrame(frame) {
|
|
|
|
|
// Only for interpolation boxes
|
|
|
|
|
if (this._type != 'interpolation_box') {
|
|
|
|
|
// Only for interpolation shapes
|
|
|
|
|
if (this._type.split('_')[0] !== 'interpolation') {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Undo/redo code
|
|
|
|
|
let oldPos = Object.assign({}, this._positions[frame]);
|
|
|
|
|
const oldPos = Object.assign({}, this._positions[frame]);
|
|
|
|
|
window.cvat.addAction('Change Keyframe', () => {
|
|
|
|
|
this.switchKeyFrame(frame);
|
|
|
|
|
if (Object.keys(oldPos).length && oldPos.outside) {
|
|
|
|
|
this.switchOutside(frame);
|
|
|
|
|
if (frame in this._positions) {
|
|
|
|
|
this.updatePosition(frame, oldPos);
|
|
|
|
|
}
|
|
|
|
|
}, () => {
|
|
|
|
|
this.switchKeyFrame(frame);
|
|
|
|
|
@ -411,19 +411,18 @@ class ShapeModel extends Listener {
|
|
|
|
|
this._frame = Object.keys(this._positions).map((el) => +el).sort((a,b) => a - b)[1];
|
|
|
|
|
if (frame in this._attributes.mutable) {
|
|
|
|
|
this._attributes.mutable[this._frame] = this._attributes.mutable[frame];
|
|
|
|
|
delete(this._attributes.mutable[frame]);
|
|
|
|
|
delete (this._attributes.mutable[frame]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete(this._positions[frame]);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
delete (this._positions[frame]);
|
|
|
|
|
} else {
|
|
|
|
|
let position = this._interpolatePosition(frame);
|
|
|
|
|
this.updatePosition(frame, position, true);
|
|
|
|
|
|
|
|
|
|
if (frame < this._frame) {
|
|
|
|
|
if (this._frame in this._attributes.mutable) {
|
|
|
|
|
this._attributes.mutable[frame] = this._attributes.mutable[this._frame];
|
|
|
|
|
delete(this._attributes.mutable[this._frame]);
|
|
|
|
|
delete (this._attributes.mutable[this._frame]);
|
|
|
|
|
}
|
|
|
|
|
this._frame = frame;
|
|
|
|
|
}
|
|
|
|
|
@ -917,7 +916,7 @@ class PolyShapeModel extends ShapeModel {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Object.assign({}, leftPos, {
|
|
|
|
|
outside: leftFrame != frame,
|
|
|
|
|
outside: leftPos.outside || leftFrame !== frame,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1145,6 +1144,60 @@ class PointsModel extends PolyShapeModel {
|
|
|
|
|
this._minPoints = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_interpolatePosition(frame) {
|
|
|
|
|
if (this._type.startsWith('annotation')) {
|
|
|
|
|
return Object.assign({}, this._positions[this._frame], {
|
|
|
|
|
outside: this._frame !== frame,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let [leftFrame, rightFrame] = this._neighboringFrames(frame);
|
|
|
|
|
if (frame in this._positions) {
|
|
|
|
|
leftFrame = frame;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let leftPos = null;
|
|
|
|
|
let rightPos = null;
|
|
|
|
|
|
|
|
|
|
if (leftFrame != null) leftPos = this._positions[leftFrame];
|
|
|
|
|
if (rightFrame != null) rightPos = this._positions[rightFrame];
|
|
|
|
|
|
|
|
|
|
if (!leftPos) {
|
|
|
|
|
if (rightPos) {
|
|
|
|
|
return Object.assign({}, rightPos, {
|
|
|
|
|
outside: true,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
outside: true,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (frame === leftFrame || leftPos.outside || !rightPos || rightPos.outside) {
|
|
|
|
|
return Object.assign({}, leftPos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const rightPoints = PolyShapeModel.convertStringToNumberArray(rightPos.points);
|
|
|
|
|
const leftPoints = PolyShapeModel.convertStringToNumberArray(leftPos.points);
|
|
|
|
|
|
|
|
|
|
if (rightPoints.length === leftPoints.length && leftPoints.length === 1) {
|
|
|
|
|
const moveCoeff = (frame - leftFrame) / (rightFrame - leftFrame);
|
|
|
|
|
const interpolatedPoints = [{
|
|
|
|
|
x: leftPoints[0].x + (rightPoints[0].x - leftPoints[0].x) * moveCoeff,
|
|
|
|
|
y: leftPoints[0].y + (rightPoints[0].y - leftPoints[0].y) * moveCoeff,
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
return Object.assign({}, leftPos, {
|
|
|
|
|
points: PolyShapeModel.convertNumberArrayToString(interpolatedPoints),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Object.assign({}, leftPos, {
|
|
|
|
|
outside: true,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
distance(mousePos, frame) {
|
|
|
|
|
let pos = this._interpolatePosition(frame);
|
|
|
|
|
if (pos.outside) return Number.MAX_SAFE_INTEGER;
|
|
|
|
|
@ -1958,19 +2011,17 @@ class ShapeView extends Listener {
|
|
|
|
|
if (type.split('_')[0] == 'interpolation') {
|
|
|
|
|
let interpolationCenter = document.createElement('center');
|
|
|
|
|
|
|
|
|
|
if (type.split('_')[1] == 'box') {
|
|
|
|
|
let outsideButton = document.createElement('button');
|
|
|
|
|
outsideButton.classList.add('graphicButton', 'outsideButton');
|
|
|
|
|
let outsideButton = document.createElement('button');
|
|
|
|
|
outsideButton.classList.add('graphicButton', 'outsideButton');
|
|
|
|
|
|
|
|
|
|
let keyframeButton = document.createElement('button');
|
|
|
|
|
keyframeButton.classList.add('graphicButton', 'keyFrameButton');
|
|
|
|
|
let keyframeButton = document.createElement('button');
|
|
|
|
|
keyframeButton.classList.add('graphicButton', 'keyFrameButton');
|
|
|
|
|
|
|
|
|
|
interpolationCenter.appendChild(outsideButton);
|
|
|
|
|
interpolationCenter.appendChild(keyframeButton);
|
|
|
|
|
interpolationCenter.appendChild(outsideButton);
|
|
|
|
|
interpolationCenter.appendChild(keyframeButton);
|
|
|
|
|
|
|
|
|
|
this._uis.buttons['outside'] = outsideButton;
|
|
|
|
|
this._uis.buttons['keyframe'] = keyframeButton;
|
|
|
|
|
}
|
|
|
|
|
this._uis.buttons['outside'] = outsideButton;
|
|
|
|
|
this._uis.buttons['keyframe'] = keyframeButton;
|
|
|
|
|
|
|
|
|
|
let prevKeyFrameButton = document.createElement('button');
|
|
|
|
|
prevKeyFrameButton.classList.add('graphicButton', 'prevKeyFrameButton');
|
|
|
|
|
@ -3125,7 +3176,7 @@ class PointsView extends PolyShapeView {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_drawPointMarkers(position) {
|
|
|
|
|
if (this._uis.points) {
|
|
|
|
|
if (this._uis.points || position.outside) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|