Skip to content

Commit

Permalink
Updated skeleton tracks
Browse files Browse the repository at this point in the history
  • Loading branch information
bsekachev committed May 27, 2024
1 parent 6e92d6d commit e7fff2a
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 51 deletions.
57 changes: 46 additions & 11 deletions cvat-core/src/annotations-objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ export class Shape extends Drawn {
throw new ScriptingError('Received frame is not equal to the frame of the shape');
}

if (this.lock && data.lock) {
if (data.lock) {
return new ObjectState(this.get(frame));
}

Expand Down Expand Up @@ -1332,7 +1332,7 @@ export class Track extends Drawn {
}

public save(frame: number, data: ObjectState): ObjectState {
if (this.lock && data.lock) {
if (data.lock) {
return new ObjectState(this.get(frame));
}

Expand Down Expand Up @@ -1495,7 +1495,7 @@ export class Tag extends Annotation {
throw new ScriptingError('Received frame is not equal to the frame of the tag');
}

if (this.lock && data.lock) {
if (data.lock) {
return new ObjectState(this.get(frame));
}

Expand Down Expand Up @@ -2120,7 +2120,7 @@ export class SkeletonShape extends Shape {
}

public save(frame: number, data: ObjectState): ObjectState {
if (this.lock && data.lock) {
if (data.lock) {
return new ObjectState(this.get(frame));
}

Expand Down Expand Up @@ -3070,7 +3070,7 @@ export class SkeletonTrack extends Track {
rotation: 0,
}));

return {
const result = {
...position,
parentID: null,
keyframe: position.keyframe || elements.some((el) => el.keyframe),
Expand All @@ -3095,6 +3095,13 @@ export class SkeletonTrack extends Track {
hidden: elements.every((el) => el.hidden),
...this.withContext(frame),
};

elements.forEach((el) => {
// illegal to update skeleton element if initial skeleton frame is earlier
el.lock = el.lock || el.frame < this.frame;
});

return result;
}

// finds keyframes considering keyframes of nested elements
Expand Down Expand Up @@ -3129,62 +3136,90 @@ export class SkeletonTrack extends Track {
}

public save(frame: number, data: ObjectState): ObjectState {
if (this.lock && data.lock) {
if (data.lock) {
return new ObjectState(this.get(frame));
}

const updateElements = (affectedElements, action, property: 'hidden' | 'lock' | null = null): void => {
const undoSkeletonProperties = this.elements.map((element) => element[property] || null);
const undoSkeletonProperties = this.elements.map((element) => element[property] ?? null);
const undoSkeletonShapes = this.elements.map((element) => element.shapes[frame]);
const undoSkeletonStartFrames = this.elements.map((element) => element.frame);
const undoSource = this.source;
const redoSource = this.readOnlyFields.includes('source') ? this.source : computeNewSource(this.source);

const errors = [];
try {
this.history.freeze(true);
affectedElements.forEach((element, idx) => {
// ignore element's locking here
const beforeLock = element.lock;
element.lock = false;

try {
const annotationContext = this.elements[idx];
annotationContext.save(frame, element);
} catch (error: any) {
errors.push(error);
} finally {
element.lock = beforeLock;
}
});
} finally {
this.history.freeze(false);
}

const redoSkeletonProperties = this.elements.map((element) => element[property] || null);
const undoFrame = this.frame;
const redoFrame = Math.min(...[
...this.elements.map((element) => element.frame), this.frame,
]);

const moveKeyframe = (from: number, to: number): void => {
if (from !== to && this.shapes[from]) {
this.shapes[to] = copyShape(this.shapes[from]);
delete this.shapes[from];
}
};

moveKeyframe(undoFrame, redoFrame);

const redoSkeletonProperties = this.elements.map((element) => element[property] ?? null);
const redoSkeletonShapes = this.elements.map((element) => element.shapes[frame]);
const redoSkeletonStartFrames = this.elements.map((element) => element.frame);

this.history.do(
action,
() => {
for (let i = 0; i < this.elements.length; i++) {
if (property) {
this.elements[i][property] = undoSkeletonProperties[i];
} if (undoSkeletonShapes[i]) {
this.elements[i].shapes[frame] = undoSkeletonShapes[i];
} else if (undoSkeletonShapes[i]) {
this.elements[i].shapes[frame] = copyShape(undoSkeletonShapes[i]);
} else if (redoSkeletonShapes[i]) {
delete this.elements[i].shapes[frame];
}
this.elements[i].frame = undoSkeletonStartFrames[i];
this.elements[i].updated = Date.now();
}
this.frame = undoFrame;
this.source = undoSource;
moveKeyframe(redoFrame, undoFrame);
this.updated = Date.now();
},
() => {
for (let i = 0; i < this.elements.length; i++) {
if (property) {
this.elements[i][property] = redoSkeletonProperties[i];
} else if (redoSkeletonShapes[i]) {
this.elements[i].shapes[frame] = redoSkeletonShapes[i];
this.elements[i].shapes[frame] = copyShape(redoSkeletonShapes[i]);
} else if (undoSkeletonShapes[i]) {
delete this.elements[i].shapes[frame];
}
this.elements[i].frame = redoSkeletonStartFrames[i];
this.elements[i].updated = Date.now();
}
this.frame = redoFrame;
this.source = redoSource;
moveKeyframe(undoFrame, redoFrame);
this.updated = Date.now();
},
[this.clientID, ...affectedElements.map((element) => element.clientID)],
Expand Down
47 changes: 7 additions & 40 deletions cvat-core/src/object-state.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 2019-2022 Intel Corporation
// Copyright (C) 2022-2023 CVAT.ai Corporation
// Copyright (C) 2022-2024 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT

Expand Down Expand Up @@ -227,13 +227,7 @@ export default class ObjectState {
},
},
hidden: {
get: () => {
if (data.shapeType === ShapeType.SKELETON) {
return data.elements.every((element: ObjectState) => element.hidden);
}

return data.hidden;
},
get: () => data.hidden,
set: (hidden) => {
if (data.shapeType === ShapeType.SKELETON) {
data.elements.forEach((element: ObjectState) => {
Expand Down Expand Up @@ -314,12 +308,7 @@ export default class ObjectState {
},
},
outside: {
get: () => {
if (data.shapeType === ShapeType.SKELETON) {
return data.elements.every((el) => el.outside);
}
return data.outside;
},
get: () => data.outside,
set: (outside) => {
if (data.shapeType === ShapeType.SKELETON) {
for (const element of this.elements) {
Expand All @@ -332,13 +321,7 @@ export default class ObjectState {
},
},
keyframe: {
get: () => {
if (data.shapeType === ShapeType.SKELETON) {
return data.keyframe || data.elements.some((el) => el.keyframe);
}

return data.keyframe;
},
get: () => data.keyframe,
set: (keyframe) => {
if (data.shapeType === ShapeType.SKELETON) {
for (const element of this.elements) {
Expand All @@ -360,12 +343,7 @@ export default class ObjectState {
},
},
occluded: {
get: () => {
if (data.shapeType === ShapeType.SKELETON) {
return data.elements.every((el) => el.occluded);
}
return data.occluded;
},
get: () => data.occluded,
set: (occluded) => {
if (data.shapeType === ShapeType.SKELETON) {
for (const element of this.elements) {
Expand All @@ -378,12 +356,7 @@ export default class ObjectState {
},
},
lock: {
get: () => {
if (data.shapeType === ShapeType.SKELETON) {
return data.elements.every((el) => el.lock);
}
return data.lock;
},
get: () => data.lock,
set: (lock) => {
if (data.shapeType === ShapeType.SKELETON) {
for (const element of this.elements) {
Expand All @@ -396,13 +369,7 @@ export default class ObjectState {
},
},
pinned: {
get: () => {
if (typeof data.pinned === 'boolean') {
return data.pinned;
}

return null;
},
get: () => data.pinned,
set: (pinned) => {
data.updateFlags.pinned = true;
data.pinned = pinned;
Expand Down

0 comments on commit e7fff2a

Please sign in to comment.