diff --git a/CHANGELOG.md b/CHANGELOG.md index c73067f0e91b5e212c9deee441864e5fa9925ee5..bc78e356c48732699e972db1d17031ec94451027 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,7 @@ non-ascii paths while adding files from "Connected file share" (issue #4428) - Fixed job exporting () - Visibility and ignored information fail to be loaded (MOT dataset format) () - Added force logout on CVAT app start if token is missing () +- Drawing issues on 3D canvas () - Missed token with using social account authentication () - An exception when run export for an empty task () - Fixed FBRS serverless function runtime error on images with alpha channel () diff --git a/cvat-canvas3d/package.json b/cvat-canvas3d/package.json index 3f7ccb36ce9851715cc1d89ee26fa7b75607ba7f..5191debd3d410ae93140781a4c5fda4babd47c5d 100644 --- a/cvat-canvas3d/package.json +++ b/cvat-canvas3d/package.json @@ -1,6 +1,6 @@ { "name": "cvat-canvas3d", - "version": "0.0.3", + "version": "0.0.4", "description": "Part of Computer Vision Annotation Tool which presents its canvas3D library", "main": "src/canvas3d.ts", "scripts": { diff --git a/cvat-canvas3d/src/typescript/canvas3d.ts b/cvat-canvas3d/src/typescript/canvas3d.ts index 0677e87d187a736b17ad0722473f906195ad5f6f..bf03acbcc521c8058b0ddfa11dc230136b8304d2 100644 --- a/cvat-canvas3d/src/typescript/canvas3d.ts +++ b/cvat-canvas3d/src/typescript/canvas3d.ts @@ -101,7 +101,7 @@ class Canvas3dImpl implements Canvas3d { } public activate(clientID: number | null, attributeID: number | null = null): void { - this.model.activate(String(clientID), attributeID); + this.model.activate(typeof clientID === 'number' ? String(clientID) : null, attributeID); } public fit(): void { diff --git a/cvat-canvas3d/src/typescript/canvas3dModel.ts b/cvat-canvas3d/src/typescript/canvas3dModel.ts index 2065d7bc8aa8deba17e606e1f63e8b15528be5c1..d9d6f6250ac1e09250484e1ac153ad1b21ef4eb9 100644 --- a/cvat-canvas3d/src/typescript/canvas3dModel.ts +++ b/cvat-canvas3d/src/typescript/canvas3dModel.ts @@ -110,7 +110,6 @@ export interface Canvas3dDataModel { imageIsDeleted: boolean; drawData: DrawData; mode: Mode; - objectUpdating: boolean; exception: Error | null; objects: any[]; groupedObjects: any[]; @@ -154,7 +153,6 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel { height: 0, width: 0, }, - objectUpdating: false, objects: [], groupedObjects: [], image: null, @@ -203,11 +201,7 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel { } if (frameData.number === this.data.imageID && frameData.deleted === this.data.imageIsDeleted) { - if (this.data.objectUpdating) { - return; - } this.data.objects = objectStates; - this.data.objectUpdating = true; this.notify(UpdateReasons.OBJECTS_UPDATED); return; } diff --git a/cvat-canvas3d/src/typescript/canvas3dView.ts b/cvat-canvas3d/src/typescript/canvas3dView.ts index 4b45c05aac465548412ffecb4182795c061aaabe..f959c314ca8f6dd84600170f8317d48118e7708b 100644 --- a/cvat-canvas3d/src/typescript/canvas3dView.ts +++ b/cvat-canvas3d/src/typescript/canvas3dView.ts @@ -133,7 +133,6 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { this.action = { loading: false, - oldState: '', scan: null, selectable: true, frameCoordinates: { @@ -255,9 +254,10 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { cancelable: true, detail: { state: { - ...initState, + attributes: { ...initState.attributes }, shapeType: 'cuboid', frame: this.model.data.imageID, + group: initState.group?.id || null, points, label, }, @@ -266,7 +266,6 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { }, }), ); - this.action.oldState = Mode.DRAW; } }); @@ -508,7 +507,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { } private setDefaultZoom(): void { - if (this.model.data.activeElement === 'null') { + if (this.model.data.activeElement === null) { Object.keys(this.views).forEach((view: string): void => { const viewType = this.views[view as keyof Views]; if (view !== ViewType.PERSPECTIVE) { @@ -580,7 +579,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { if (event.detail !== 1) return; if (this.model.mode === Mode.DRAG_CANVAS) return; const { clientID } = this.model.data.activeElement; - if (clientID === 'null') return; + if (clientID === null) return; const canvas = this.views[view as keyof Views].renderer.domElement; const rect = canvas.getBoundingClientRect(); const { mouseVector } = this.views[view as keyof Views].rayCaster as { mouseVector: THREE.Vector2 }; @@ -605,7 +604,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { event.preventDefault(); if (this.model.mode === Mode.DRAG_CANVAS) return; const { clientID } = this.model.data.activeElement; - if (clientID === 'null') return; + if (clientID === null) return; const canvas = this.views[view as keyof Views].renderer.domElement; const rect = canvas.getBoundingClientRect(); const { mouseVector } = this.views[view as keyof Views].rayCaster as { mouseVector: THREE.Vector2 }; @@ -664,7 +663,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { private completeActions(): void { const { scan, detected } = this.action; - if (this.model.mode === Mode.DRAG_CANVAS) return; + if (this.model.data.activeElement.clientID === null) return; if (!detected) { this.resetActions(); return; @@ -807,6 +806,11 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { this.setupObject(object, true); } this.action.loading = false; + + if (this.mode === Mode.DRAW) { + // if setupObjects was called during drawing, need to restore drawable object + this.views.perspective.scene.children[0].add(this.cube.perspective); + } } } @@ -871,23 +875,33 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { } else if (reason === UpdateReasons.SHAPE_ACTIVATED) { const { clientID } = this.model.data.activeElement; this.setupObjects(); - if (clientID !== 'null') { + if (clientID !== null) { this.setDefaultZoom(); } } else if (reason === UpdateReasons.DRAW) { const data: DrawData = this.controller.drawData; - this.cube = new CuboidModel('line', '#ffffff'); if (data.redraw) { const object = this.views.perspective.scene.getObjectByName(String(data.redraw)); if (object) { this.cube.perspective = object.clone() as THREE.Mesh; - object.visible = false; } } else if (data.initialState) { - this.model.data.activeElement.clientID = 'null'; - this.setupObjects(); this.cube = this.setupObject(data.initialState, false); + } else { + this.cube = new CuboidModel('line', '#ffffff'); + } + + this.cube.setName('drawTemplate'); + this.model.data.activeElement.clientID = null; + this.setupObjects(); + + if (data.redraw) { + const object = this.views.perspective.scene.getObjectByName(String(data.redraw)); + if (object) { + object.visible = false; + } } + this.setHelperVisibility(false); } else if (reason === UpdateReasons.OBJECTS_UPDATED) { this.setupObjects(); @@ -899,7 +913,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { cancelable: true, }), ); - this.model.data.activeElement.clientID = 'null'; + this.model.data.activeElement.clientID = null; this.setupObjects(); } else if (reason === UpdateReasons.CANCEL) { if (this.mode === Mode.DRAG_CANVAS) { @@ -933,7 +947,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { this.onGroupDone(this.model.data.groupData.grouped); } else { this.model.data.groupData.grouped = []; - this.model.data.activeElement.clientID = 'null'; + this.model.data.activeElement.clientID = null; this.setupObjects(); } } @@ -1235,15 +1249,11 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { private renderRayCaster = (viewType: RenderView): void => { viewType.rayCaster.renderer.setFromCamera(viewType.rayCaster.mouseVector, viewType.camera); if (this.mode === Mode.DRAW) { - const intersects = this.views.perspective.rayCaster.renderer.intersectObjects( - this.views.perspective.scene.children, - false, - ); - if (intersects.length > 0) { - this.views.perspective.scene.children[0].add(this.cube.perspective); - const newPoints = intersects[0].point; - this.cube.perspective.position.copy(newPoints); - this.views.perspective.renderer.domElement.style.cursor = 'default'; + const [intersection] = viewType.rayCaster.renderer.intersectObjects(this.views.perspective.scene.children); + if (intersection) { + const object = this.views.perspective.scene.getObjectByName('drawTemplate'); + const { x, y, z } = intersection.point; + object.position.set(x, y, z); } } else if (this.mode === Mode.IDLE && !this.isPerspectiveBeingDragged) { const { children } = this.views.perspective.scene.children[0]; @@ -1300,7 +1310,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { this.renderRayCaster(viewType); } const { clientID } = this.model.data.activeElement; - if (clientID !== 'null' && view !== ViewType.PERSPECTIVE) { + if (clientID !== null && view !== ViewType.PERSPECTIVE) { viewType.rayCaster.renderer.setFromCamera(viewType.rayCaster.mouseVector, viewType.camera); // First Scan if (this.action.scan === view) { @@ -1324,6 +1334,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { } } }); + if (this.action.detachCam && this.action.detachCamRef === this.model.data.activeElement.clientID) { try { this.detachCamera(null); @@ -1332,15 +1343,9 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { this.action.detachCam = false; } } + if (this.model.mode === Mode.BUSY && !this.action.loading) { - if (this.action.oldState !== '') { - this.model.mode = this.action.oldState; - this.action.oldState = ''; - } else { - this.model.mode = Mode.IDLE; - } - } else if (this.model.data.objectUpdating && !this.action.loading) { - this.model.data.objectUpdating = false; + this.model.mode = Mode.IDLE; } } diff --git a/cvat-canvas3d/src/typescript/consts.ts b/cvat-canvas3d/src/typescript/consts.ts index b386beff3bf67abed7ab75814d561b8e68e04e56..5b396051cad48a134dfe6486e7cc6eaeb14ee2ed 100644 --- a/cvat-canvas3d/src/typescript/consts.ts +++ b/cvat-canvas3d/src/typescript/consts.ts @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2022 CVAT.ai Corporation // // SPDX-License-Identifier: MIT