Skip to content

Commit 79808da

Browse files
author
Boris Sekachev
committed
Merged develop
2 parents 3455585 + c58e915 commit 79808da

28 files changed

+1717
-159
lines changed

cvat-canvas3d/src/typescript/canvas3dModel.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export enum Mode {
9191
INTERACT = 'interact',
9292
DRAG_CANVAS = 'drag_canvas',
9393
GROUP = 'group',
94+
BUSY = 'busy',
9495
}
9596

9697
export interface Canvas3dDataModel {
@@ -102,6 +103,7 @@ export interface Canvas3dDataModel {
102103
imageSize: Size;
103104
drawData: DrawData;
104105
mode: Mode;
106+
objectUpdating: boolean;
105107
exception: Error | null;
106108
objects: any[];
107109
groupedObjects: any[];
@@ -140,6 +142,7 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel {
140142
height: 0,
141143
width: 0,
142144
},
145+
objectUpdating: false,
143146
objects: [],
144147
groupedObjects: [],
145148
image: null,
@@ -179,13 +182,16 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel {
179182
throw Error(`Canvas is busy. Action: ${this.data.mode}`);
180183
}
181184
}
182-
183-
if ([Mode.EDIT].includes(this.data.mode)) {
185+
if ([Mode.EDIT, Mode.BUSY].includes(this.data.mode)) {
184186
return;
185187
}
186188

187189
if (frameData.number === this.data.imageID) {
190+
if (this.data.objectUpdating) {
191+
return;
192+
}
188193
this.data.objects = objectStates;
194+
this.data.objectUpdating = true;
189195
this.notify(UpdateReasons.OBJECTS_UPDATED);
190196
return;
191197
}
@@ -228,16 +234,16 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel {
228234
}
229235

230236
public isAbleToChangeFrame(): boolean {
231-
const isUnable = [Mode.DRAG, Mode.EDIT, Mode.RESIZE, Mode.INTERACT].includes(this.data.mode)
237+
const isUnable = [Mode.DRAG, Mode.EDIT, Mode.RESIZE, Mode.INTERACT, Mode.BUSY].includes(this.data.mode)
232238
|| (this.data.mode === Mode.DRAW && typeof this.data.drawData.redraw === 'number');
233239
return !isUnable;
234240
}
235241

236242
public draw(drawData: DrawData): void {
237-
if (drawData.enabled && this.data.drawData.enabled) {
243+
if (drawData.enabled && this.data.drawData.enabled && !drawData.initialState) {
238244
throw new Error('Drawing has been already started');
239245
}
240-
if ([Mode.DRAW, Mode.EDIT].includes(this.data.mode)) {
246+
if ([Mode.DRAW, Mode.EDIT].includes(this.data.mode) && !drawData.initialState) {
241247
return;
242248
}
243249
this.data.drawData.enabled = drawData.enabled;
@@ -318,6 +324,9 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel {
318324
}
319325

320326
public configureShapes(shapeProperties: ShapeProperties): void {
327+
this.data.drawData.enabled = false;
328+
this.data.mode = Mode.IDLE;
329+
this.cancel();
321330
this.data.shapeProperties = {
322331
...shapeProperties,
323332
};

cvat-canvas3d/src/typescript/canvas3dView.ts

Lines changed: 101 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
111111
},
112112
};
113113
this.action = {
114+
loading: false,
115+
oldState: '',
114116
scan: null,
115117
selectable: true,
116118
frameCoordinates: {
@@ -216,6 +218,35 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
216218
}),
217219
);
218220
}
221+
if (this.model.mode === Mode.DRAW && e.ctrlKey && this.model.data.drawData.initialState) {
222+
const { x, y, z } = this.cube.perspective.position;
223+
const { x: width, y: height, z: depth } = this.cube.perspective.scale;
224+
const { x: rotationX, y: rotationY, z: rotationZ } = this.cube.perspective.rotation;
225+
const points = [x, y, z, rotationX, rotationY, rotationZ, width, height, depth, 0, 0, 0, 0, 0, 0, 0];
226+
const initState = this.model.data.drawData.initialState;
227+
let label;
228+
if (initState) {
229+
({ label } = initState);
230+
}
231+
this.dispatchEvent(
232+
new CustomEvent('canvas.drawn', {
233+
bubbles: false,
234+
cancelable: true,
235+
detail: {
236+
state: {
237+
...initState,
238+
shapeType: 'cuboid',
239+
frame: this.model.data.imageID,
240+
points,
241+
label,
242+
},
243+
continue: true,
244+
duration: 0,
245+
},
246+
}),
247+
);
248+
this.action.oldState = Mode.DRAW;
249+
}
219250
});
220251

221252
canvasTopView.addEventListener('mousedown', this.startAction.bind(this, 'top'));
@@ -293,7 +324,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
293324
this.views.perspective.scene.children[0].children,
294325
false,
295326
);
296-
if (intersects.length !== 0) {
327+
if (intersects.length !== 0 || this.controller.focused.clientID !== null) {
297328
this.setDefaultZoom();
298329
} else {
299330
const { x, y, z } = this.action.frameCoordinates;
@@ -417,6 +448,12 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
417448
viewType.controls.mouseButtons.right = CameraControls.ACTION.NONE;
418449
} else {
419450
viewType.controls = new CameraControls(viewType.camera, viewType.renderer.domElement);
451+
viewType.controls.mouseButtons.left = CameraControls.ACTION.NONE;
452+
viewType.controls.mouseButtons.right = CameraControls.ACTION.NONE;
453+
viewType.controls.mouseButtons.wheel = CameraControls.ACTION.NONE;
454+
viewType.controls.touches.one = CameraControls.ACTION.NONE;
455+
viewType.controls.touches.two = CameraControls.ACTION.NONE;
456+
viewType.controls.touches.three = CameraControls.ACTION.NONE;
420457
}
421458
viewType.controls.minDistance = CONST.MIN_DISTANCE;
422459
viewType.controls.maxDistance = CONST.MAX_DISTANCE;
@@ -493,6 +530,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
493530

494531
private startAction(view: any, event: MouseEvent): void {
495532
if (event.detail !== 1) return;
533+
if (this.model.mode === Mode.DRAG_CANVAS) return;
496534
const { clientID } = this.model.data.activeElement;
497535
if (clientID === 'null') return;
498536
const canvas = this.views[view as keyof Views].renderer.domElement;
@@ -517,6 +555,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
517555

518556
private moveAction(view: any, event: MouseEvent): void {
519557
event.preventDefault();
558+
if (this.model.mode === Mode.DRAG_CANVAS) return;
520559
const { clientID } = this.model.data.activeElement;
521560
if (clientID === 'null') return;
522561
const canvas = this.views[view as keyof Views].renderer.domElement;
@@ -571,10 +610,13 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
571610
recentMouseVector: new THREE.Vector2(0, 0),
572611
},
573612
};
613+
this.model.mode = Mode.IDLE;
614+
this.action.selectable = true;
574615
}
575616

576617
private completeActions(): void {
577618
const { scan, detected } = this.action;
619+
if (this.model.mode === Mode.DRAG_CANVAS) return;
578620
if (!detected) {
579621
this.resetActions();
580622
return;
@@ -604,8 +646,6 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
604646
this.adjustPerspectiveCameras();
605647
this.translateReferencePlane(new THREE.Vector3(x, y, z));
606648
this.resetActions();
607-
this.model.mode = Mode.IDLE;
608-
this.action.selectable = true;
609649
}
610650

611651
private onGroupDone(objects?: any[]): void {
@@ -718,6 +758,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
718758
const object = this.model.data.objects[i];
719759
this.setupObject(object, true);
720760
}
761+
this.action.loading = false;
721762
}
722763
}
723764

@@ -735,6 +776,13 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
735776
public notify(model: Canvas3dModel & Master, reason: UpdateReasons): void {
736777
if (reason === UpdateReasons.IMAGE_CHANGED) {
737778
if (!model.data.image) return;
779+
this.dispatchEvent(new CustomEvent('canvas.canceled'));
780+
if (this.model.mode === Mode.DRAW) {
781+
this.model.data.drawData.enabled = false;
782+
}
783+
this.views.perspective.renderer.dispose();
784+
this.model.mode = Mode.BUSY;
785+
this.action.loading = true;
738786
const loader = new PCDLoader();
739787
const objectURL = URL.createObjectURL(model.data.image.imageData);
740788
this.clearScene();
@@ -766,12 +814,21 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
766814
this.setupObjects();
767815
} else if (reason === UpdateReasons.DRAG_CANVAS) {
768816
this.dispatchEvent(
769-
new CustomEvent(this.mode === Mode.DRAG_CANVAS ? 'canvas.dragstart' : 'canvas.dragstop', {
817+
new CustomEvent(this.model.mode === Mode.DRAG_CANVAS ? 'canvas.dragstart' : 'canvas.dragstop', {
770818
bubbles: false,
771819
cancelable: true,
772820
}),
773821
);
774822
this.model.data.activeElement.clientID = 'null';
823+
if (this.model.mode === Mode.DRAG_CANVAS) {
824+
const { controls } = this.views.perspective;
825+
controls.mouseButtons.left = CameraControls.ACTION.ROTATE;
826+
controls.mouseButtons.right = CameraControls.ACTION.TRUCK;
827+
controls.mouseButtons.wheel = CameraControls.ACTION.DOLLY;
828+
controls.touches.one = CameraControls.ACTION.TOUCH_ROTATE;
829+
controls.touches.two = CameraControls.ACTION.TOUCH_DOLLY_TRUCK;
830+
controls.touches.three = CameraControls.ACTION.TOUCH_TRUCK;
831+
}
775832
this.setupObjects();
776833
} else if (reason === UpdateReasons.CANCEL) {
777834
if (this.mode === Mode.DRAW) {
@@ -783,7 +840,14 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
783840
}
784841
this.model.data.groupData.grouped = [];
785842
this.setHelperVisibility(false);
786-
this.mode = Mode.IDLE;
843+
this.model.mode = Mode.IDLE;
844+
const { controls } = this.views.perspective;
845+
controls.mouseButtons.left = CameraControls.ACTION.NONE;
846+
controls.mouseButtons.right = CameraControls.ACTION.NONE;
847+
controls.mouseButtons.wheel = CameraControls.ACTION.NONE;
848+
controls.touches.one = CameraControls.ACTION.NONE;
849+
controls.touches.two = CameraControls.ACTION.NONE;
850+
controls.touches.three = CameraControls.ACTION.NONE;
787851
this.dispatchEvent(new CustomEvent('canvas.canceled'));
788852
} else if (reason === UpdateReasons.FITTED_CANVAS) {
789853
this.dispatchEvent(new CustomEvent('canvas.fit'));
@@ -1153,6 +1217,8 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
11531217
}
11541218
this.updateRotationHelperPos();
11551219
this.updateResizeHelperPos();
1220+
} else {
1221+
this.resetActions();
11561222
}
11571223
}
11581224
}
@@ -1166,6 +1232,16 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
11661232
this.action.detachCam = false;
11671233
}
11681234
}
1235+
if (this.model.mode === Mode.BUSY && !this.action.loading) {
1236+
if (this.action.oldState !== '') {
1237+
this.model.mode = this.action.oldState;
1238+
this.action.oldState = '';
1239+
} else {
1240+
this.model.mode = Mode.IDLE;
1241+
}
1242+
} else if (this.model.data.objectUpdating && !this.action.loading) {
1243+
this.model.data.objectUpdating = false;
1244+
}
11691245
}
11701246

11711247
private adjustPerspectiveCameras(): void {
@@ -1729,9 +1805,6 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
17291805
true,
17301806
);
17311807
if (intersectsBox.length !== 0) {
1732-
// const [state] = this.model.data.objects.filter(
1733-
// (_state: any): boolean => _state.clientID === Number(this.model.data.selected[view].name),
1734-
// );
17351808
if (state.pinned) return;
17361809
this.action.translation.helper = viewType.rayCaster.mouseVector.clone();
17371810
this.action.translation.inverseMatrix = intersectsBox[0].object.parent.matrixWorld.invert();
@@ -1749,26 +1822,24 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
17491822
public keyControls(key: any): void {
17501823
const { controls } = this.views.perspective;
17511824
if (!controls) return;
1752-
switch (key.code) {
1753-
case CameraAction.ROTATE_RIGHT:
1754-
controls.rotate(0.1 * THREE.MathUtils.DEG2RAD * this.speed, 0, true);
1755-
break;
1756-
case CameraAction.ROTATE_LEFT:
1757-
controls.rotate(-0.1 * THREE.MathUtils.DEG2RAD * this.speed, 0, true);
1758-
break;
1759-
case CameraAction.TILT_UP:
1760-
controls.rotate(0, -0.05 * THREE.MathUtils.DEG2RAD * this.speed, true);
1761-
break;
1762-
case CameraAction.TILT_DOWN:
1763-
controls.rotate(0, 0.05 * THREE.MathUtils.DEG2RAD * this.speed, true);
1764-
break;
1765-
case 'ControlLeft':
1766-
this.action.selectable = !key.ctrlKey;
1767-
break;
1768-
default:
1769-
break;
1770-
}
1771-
if (key.altKey === true) {
1825+
if (key.shiftKey) {
1826+
switch (key.code) {
1827+
case CameraAction.ROTATE_RIGHT:
1828+
controls.rotate(0.1 * THREE.MathUtils.DEG2RAD * this.speed, 0, true);
1829+
break;
1830+
case CameraAction.ROTATE_LEFT:
1831+
controls.rotate(-0.1 * THREE.MathUtils.DEG2RAD * this.speed, 0, true);
1832+
break;
1833+
case CameraAction.TILT_UP:
1834+
controls.rotate(0, -0.05 * THREE.MathUtils.DEG2RAD * this.speed, true);
1835+
break;
1836+
case CameraAction.TILT_DOWN:
1837+
controls.rotate(0, 0.05 * THREE.MathUtils.DEG2RAD * this.speed, true);
1838+
break;
1839+
default:
1840+
break;
1841+
}
1842+
} else if (key.altKey === true) {
17721843
switch (key.code) {
17731844
case CameraAction.ZOOM_IN:
17741845
controls.dolly(CONST.DOLLY_FACTOR, true);
@@ -1791,6 +1862,8 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
17911862
default:
17921863
break;
17931864
}
1865+
} else if (key.code === 'ControlLeft') {
1866+
this.action.selectable = !key.ctrlKey;
17941867
}
17951868
}
17961869

cvat-canvas3d/src/typescript/consts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const BASE_GRID_WIDTH = 2;
66
const MOVEMENT_FACTOR = 200;
77
const DOLLY_FACTOR = 5;
88
const MAX_DISTANCE = 100;
9-
const MIN_DISTANCE = 0;
9+
const MIN_DISTANCE = 0.3;
1010
const ZOOM_FACTOR = 7;
1111
const ROTATION_HELPER_OFFSET = 0.1;
1212
const CAMERA_REFERENCE = 'camRef';

0 commit comments

Comments
 (0)