diff --git a/CHANGELOG.md b/CHANGELOG.md index fa8174d1c880..db179a472cbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ from online detectors & interactors) ( - 3D canvas now can be dragged in IDLE mode () - Datumaro version is upgraded to 0.3 (dev) () - Allowed trailing slashes in the SDK host address () +- Adjusted initial camera position, enabled 'Reset zoom' option for 3D canvas () - Enabled authentication via email () ### Deprecated diff --git a/cvat-canvas3d/package.json b/cvat-canvas3d/package.json index fc5f1b3094e0..3f7ccb36ce98 100644 --- a/cvat-canvas3d/package.json +++ b/cvat-canvas3d/package.json @@ -1,6 +1,6 @@ { "name": "cvat-canvas3d", - "version": "0.0.2", + "version": "0.0.3", "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 faa79b03bcb0..0677e87d187a 100644 --- a/cvat-canvas3d/src/typescript/canvas3d.ts +++ b/cvat-canvas3d/src/typescript/canvas3d.ts @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2022 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -13,6 +14,7 @@ import { MouseInteraction, ShapeProperties, GroupData, + Configuration, } from './canvas3dModel'; import { Canvas3dView, Canvas3dViewImpl, ViewsDOM, CameraAction, @@ -94,6 +96,10 @@ class Canvas3dImpl implements Canvas3d { this.model.configureShapes(shapeProperties); } + public configure(configuration: Configuration): void { + this.model.configure(configuration); + } + public activate(clientID: number | null, attributeID: number | null = null): void { this.model.activate(String(clientID), attributeID); } diff --git a/cvat-canvas3d/src/typescript/canvas3dController.ts b/cvat-canvas3d/src/typescript/canvas3dController.ts index 4dc8818603c5..fadcfc606943 100644 --- a/cvat-canvas3d/src/typescript/canvas3dController.ts +++ b/cvat-canvas3d/src/typescript/canvas3dController.ts @@ -1,9 +1,10 @@ // Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2022 CVAT.ai Corporation // // SPDX-License-Identifier: MIT import { - Canvas3dModel, Mode, DrawData, ActiveElement, FocusData, GroupData, + Canvas3dModel, Mode, DrawData, ActiveElement, FocusData, GroupData, Configuration, } from './canvas3dModel'; export interface Canvas3dController { @@ -12,6 +13,7 @@ export interface Canvas3dController { readonly selected: any; readonly focused: FocusData; readonly groupData: GroupData; + readonly configuration: Configuration; readonly imageIsDeleted: boolean; mode: Mode; group(groupData: GroupData): void; @@ -56,6 +58,10 @@ export class Canvas3dControllerImpl implements Canvas3dController { return this.model.groupData; } + public get configuration(): Configuration { + return this.model.configuration; + } + public group(groupData: GroupData): void { this.model.group(groupData); } diff --git a/cvat-canvas3d/src/typescript/canvas3dModel.ts b/cvat-canvas3d/src/typescript/canvas3dModel.ts index 85dcfb06dbd4..2065d7bc8aa8 100644 --- a/cvat-canvas3d/src/typescript/canvas3dModel.ts +++ b/cvat-canvas3d/src/typescript/canvas3dModel.ts @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2022 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -19,6 +20,10 @@ export interface GroupData { grouped?: []; } +export interface Configuration { + resetZoom?: boolean; +} + export interface Image { renderWidth: number; renderHeight: number; @@ -80,6 +85,7 @@ export enum UpdateReasons { SHAPE_ACTIVATED = 'shape_activated', GROUP = 'group', FITTED_CANVAS = 'fitted_canvas', + CONFIG_UPDATED = 'config_updated', } export enum Mode { @@ -112,6 +118,7 @@ export interface Canvas3dDataModel { selected: any; shapeProperties: ShapeProperties; groupData: GroupData; + configuration: Configuration; } export interface Canvas3dModel { @@ -119,6 +126,7 @@ export interface Canvas3dModel { data: Canvas3dDataModel; readonly imageIsDeleted: boolean; readonly groupData: GroupData; + readonly configuration: Configuration; setup(frameData: any, objectStates: any[]): void; isAbleToChangeFrame(): boolean; draw(drawData: DrawData): void; @@ -126,6 +134,7 @@ export interface Canvas3dModel { dragCanvas(enable: boolean): void; activate(clientID: string | null, attributeID: number | null): void; configureShapes(shapeProperties: any): void; + configure(configuration: Configuration): void; fit(): void; group(groupData: GroupData): void; destroy(): void; @@ -177,6 +186,9 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel { selectedOpacity: 60, colorBy: 'Label', }, + configuration: { + resetZoom: false, + }, }; } @@ -327,6 +339,14 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel { this.notify(UpdateReasons.GROUP); } + public configure(configuration: Configuration): void { + if (typeof configuration.resetZoom === 'boolean') { + this.data.configuration.resetZoom = configuration.resetZoom; + } + + this.notify(UpdateReasons.CONFIG_UPDATED); + } + public configureShapes(shapeProperties: ShapeProperties): void { this.data.drawData.enabled = false; this.data.mode = Mode.IDLE; @@ -341,6 +361,10 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel { this.notify(UpdateReasons.FITTED_CANVAS); } + public get configuration(): Configuration { + return { ...this.data.configuration }; + } + public get groupData(): GroupData { return { ...this.data.groupData }; } diff --git a/cvat-canvas3d/src/typescript/canvas3dView.ts b/cvat-canvas3d/src/typescript/canvas3dView.ts index 120ed5b2f1aa..4b45c05aac46 100644 --- a/cvat-canvas3d/src/typescript/canvas3dView.ts +++ b/cvat-canvas3d/src/typescript/canvas3dView.ts @@ -40,19 +40,17 @@ export interface RayCast { mouseVector: THREE.Vector2; } -export interface Views { - perspective: RenderView; - top: RenderView; - side: RenderView; - front: RenderView; -} +export type Views = { + [key in ViewType]: RenderView; +}; -export interface CubeObject { - perspective: THREE.Mesh; - top: THREE.Mesh; - side: THREE.Mesh; - front: THREE.Mesh; -} +export type CubeObject = { + [key in ViewType]: THREE.Mesh; +}; + +export type ViewsDOM = { + [key in ViewType]: HTMLCanvasElement; +}; export interface RenderView { renderer: THREE.WebGLRenderer; @@ -62,25 +60,23 @@ export interface RenderView { rayCaster?: RayCast; } -export interface ViewsDOM { - perspective: HTMLCanvasElement; - top: HTMLCanvasElement; - side: HTMLCanvasElement; - front: HTMLCanvasElement; -} - export class Canvas3dViewImpl implements Canvas3dView, Listener { private controller: Canvas3dController; private views: Views; private clock: THREE.Clock; private speed: number; private cube: CuboidModel; - private highlighted: boolean; - private selected: CubeObject; private isPerspectiveBeingDragged: boolean; private model: Canvas3dModel & Master; private action: any; private globalHelpers: any; + private cameraSettings: { + [key in ViewType]: { + position: [number, number, number], + lookAt: [number, number, number], + up: [number, number, number], + } + }; private set mode(value: Mode) { this.controller.mode = value; @@ -95,9 +91,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { this.clock = new THREE.Clock(); this.speed = CONST.MOVEMENT_FACTOR; this.cube = new CuboidModel('line', '#ffffff'); - this.highlighted = false; this.isPerspectiveBeingDragged = false; - this.selected = this.cube; this.model = model; this.globalHelpers = { top: { @@ -113,6 +107,30 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { rotate: [], }, }; + + this.cameraSettings = { + perspective: { + position: [-15, 0, 8], + lookAt: [10, 0, 0], + up: [0, 0, 1], + }, + top: { + position: [0, 0, 8], + lookAt: [0, 0, 0], + up: [0, 0, 1], + }, + side: { + position: [0, 8, 0], + lookAt: [0, 0, 0], + up: [0, 0, 1], + }, + front: { + position: [8, 0, 0], + lookAt: [0, 0, 0], + up: [0, 0, 1], + }, + }; + this.action = { loading: false, oldState: '', @@ -408,11 +426,6 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { // setting up the camera and adding it in the scene this.views.perspective.camera = new THREE.PerspectiveCamera(50, aspectRatio, 1, 500); - this.views.perspective.camera.position.set(-15, 0, 4); - this.views.perspective.camera.up.set(0, 0, 1); - this.views.perspective.camera.lookAt(10, 0, 0); - this.views.perspective.camera.name = 'cameraPerspective'; - this.views.top.camera = new THREE.OrthographicCamera( (-aspectRatio * viewSize) / 2 - 2, (aspectRatio * viewSize) / 2 + 2, @@ -421,12 +434,6 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { -50, 50, ); - - this.views.top.camera.position.set(0, 0, 5); - this.views.top.camera.lookAt(0, 0, 0); - this.views.top.camera.up.set(0, 0, 1); - this.views.top.camera.name = 'cameraTop'; - this.views.side.camera = new THREE.OrthographicCamera( (-aspectRatio * viewSize) / 2, (aspectRatio * viewSize) / 2, @@ -435,11 +442,6 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { -50, 50, ); - this.views.side.camera.position.set(0, 5, 0); - this.views.side.camera.lookAt(0, 0, 0); - this.views.side.camera.up.set(0, 0, 1); - this.views.side.camera.name = 'cameraSide'; - this.views.front.camera = new THREE.OrthographicCamera( (-aspectRatio * viewSize) / 2, (aspectRatio * viewSize) / 2, @@ -448,10 +450,18 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { -50, 50, ); - this.views.front.camera.position.set(3, 0, 0); - this.views.front.camera.up.set(0, 0, 1); - this.views.front.camera.lookAt(0, 0, 0); - this.views.front.camera.name = 'cameraFront'; + + for (const cameraType of [ + ViewType.PERSPECTIVE, + ViewType.TOP, + ViewType.SIDE, + ViewType.FRONT, + ]) { + this.views[cameraType].camera.position.set(...this.cameraSettings[cameraType].position); + this.views[cameraType].camera.lookAt(...this.cameraSettings[cameraType].lookAt); + this.views[cameraType].camera.up.set(...this.cameraSettings[cameraType].up); + this.views[cameraType].camera.name = `camera${cameraType[0].toUpperCase()}${cameraType.slice(1)}`; + } Object.keys(this.views).forEach((view: string): void => { const viewType = this.views[view as keyof Views]; @@ -1024,6 +1034,26 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { } private addScene(points: any): void { + const getcameraSettingsToFitScene = ( + camera: THREE.PerspectiveCamera, + boundingBox: THREE.Box3, + ): [number, number, number] => { + const offset = 5; + const width = boundingBox.max.x - boundingBox.min.x; + const height = boundingBox.max.y - boundingBox.min.y; + + // find the maximum width or height, compute z to approximately fit the scene + const maxDim = Math.max(width, height); + const fov = camera.fov * (Math.PI / 180); + const cameraZ = Math.abs((maxDim / 8) * Math.tan(fov * 2)); + + return [ + boundingBox.min.x + offset, + boundingBox.max.y + offset, + cameraZ + offset, + ]; + }; + // eslint-disable-next-line no-param-reassign points.material.size = 0.05; points.material.color.set(new THREE.Color(0xffffff)); @@ -1032,30 +1062,20 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { controls.mouseButtons.wheel = CameraControls.ACTION.DOLLY; const material = points.material.clone(); - const sphereCenter = points.geometry.boundingSphere.center; - const { radius } = points.geometry.boundingSphere; + // const { radius, center: sphereCenter } = points.geometry.boundingSphere; if (!this.views.perspective.camera) return; - const xRange = -radius / 2 < this.views.perspective.camera.position.x - sphereCenter.x && - radius / 2 > this.views.perspective.camera.position.x - sphereCenter.x; - const yRange = -radius / 2 < this.views.perspective.camera.position.y - sphereCenter.y && - radius / 2 > this.views.perspective.camera.position.y - sphereCenter.y; - const zRange = -radius / 2 < this.views.perspective.camera.position.z - sphereCenter.z && - radius / 2 > this.views.perspective.camera.position.z - sphereCenter.z; - let newX = 0; - let newY = 0; - let newZ = 0; - if (!xRange) { - newX = sphereCenter.x; - } - if (!yRange) { - newY = sphereCenter.y; - } - if (!zRange) { - newZ = sphereCenter.z; - } - if (newX || newY || newZ) { - this.action.frameCoordinates = { x: newX, y: newY, z: newZ }; - this.positionAllViews(newX, newY, newZ, false); + + if (this.model.configuration.resetZoom) { + points.geometry.computeBoundingBox(); + this.cameraSettings.perspective.position = getcameraSettingsToFitScene( + this.views.perspective.camera as THREE.PerspectiveCamera, points.geometry.boundingBox, + ); + this.positionAllViews( + this.action.frameCoordinates.x, + this.action.frameCoordinates.y, + this.action.frameCoordinates.z, + false, + ); } [ViewType.TOP, ViewType.SIDE, ViewType.FRONT].forEach((view: ViewType): void => { @@ -1161,16 +1181,26 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { this.views.side.controls && this.views.front.controls ) { - this.views.perspective.controls.setLookAt(x - 8, y - 8, z + 3, x, y, z, animation); - this.views.top.camera.position.set(x, y, z + 8); - this.views.top.camera.lookAt(x, y, z); - this.views.top.camera.zoom = CONST.FOV_DEFAULT; - this.views.side.camera.position.set(x, y + 8, z); - this.views.side.camera.lookAt(x, y, z); - this.views.side.camera.zoom = CONST.FOV_DEFAULT; - this.views.front.camera.position.set(x + 8, y, z); - this.views.front.camera.lookAt(x, y, z); - this.views.front.camera.zoom = CONST.FOV_DEFAULT; + this.views.perspective.controls.setLookAt( + x + this.cameraSettings.perspective.position[0], + y - this.cameraSettings.perspective.position[1], + z + this.cameraSettings.perspective.position[2], + x, y, z, animation, + ); + + for (const cameraType of [ + ViewType.TOP, + ViewType.SIDE, + ViewType.FRONT, + ]) { + this.views[cameraType].camera.position.set( + x + this.cameraSettings[cameraType].position[0], + y + this.cameraSettings[cameraType].position[1], + z + this.cameraSettings[cameraType].position[2], + ); + this.views[cameraType].camera.lookAt(x, y, z); + this.views[cameraType].camera.zoom = CONST.FOV_DEFAULT; + } } } @@ -1298,8 +1328,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { try { this.detachCamera(null); // eslint-disable-next-line no-empty - } catch (e) { - } finally { + } catch (e) { } finally { this.action.detachCam = false; } } diff --git a/cvat-ui/package.json b/cvat-ui/package.json index 3220aa1c25de..c5200faa5f53 100644 --- a/cvat-ui/package.json +++ b/cvat-ui/package.json @@ -1,6 +1,6 @@ { "name": "cvat-ui", - "version": "1.44.3", + "version": "1.44.4", "description": "CVAT single-page application", "main": "src/index.tsx", "scripts": { diff --git a/cvat-ui/src/components/annotation-page/canvas/canvas-wrapper3D.tsx b/cvat-ui/src/components/annotation-page/canvas/canvas-wrapper3D.tsx index 1b8f57bb0f69..6add2289b7bb 100644 --- a/cvat-ui/src/components/annotation-page/canvas/canvas-wrapper3D.tsx +++ b/cvat-ui/src/components/annotation-page/canvas/canvas-wrapper3D.tsx @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2022 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -34,11 +35,9 @@ interface Props { canvasInstance: Canvas3d | Canvas; jobInstance: any; frameData: any; - curZLayer: number; annotations: any[]; contextMenuVisibility: boolean; activeLabelID: number; - activatedStateID: number | null; activeObjectType: ObjectType; onSetupCanvas: () => void; onGroupObjects: (enabled: boolean) => void; @@ -52,9 +51,8 @@ interface Props { onDragCanvas: (enabled: boolean) => void; onShapeDrawn: () => void; workspace: Workspace; - automaticBordering: boolean; - showObjectsTextAlways: boolean; frame: number; + resetZoom: boolean; } interface ViewSize { @@ -184,6 +182,7 @@ const CanvasWrapperComponent = (props: Props): ReactElement => { frame, jobInstance, activeLabelID, + resetZoom, activeObjectType, onShapeDrawn, onCreateAnnotations, @@ -258,6 +257,7 @@ const CanvasWrapperComponent = (props: Props): ReactElement => { canvasInstanceDOM.perspective.addEventListener('canvas.canceled', onCanvasCancel); canvasInstanceDOM.perspective.addEventListener('canvas.dragstart', onCanvasDragStart); canvasInstanceDOM.perspective.addEventListener('canvas.dragstop', onCanvasDragDone); + canvasInstance.configure({ resetZoom }); }; const keyControlsKeyDown = (key: KeyboardEvent): void => { @@ -336,6 +336,10 @@ const CanvasWrapperComponent = (props: Props): ReactElement => { }; }, []); + useEffect(() => { + canvasInstance.configure({ resetZoom }); + }, [resetZoom]); + const updateShapesView = (): void => { (canvasInstance as Canvas3d).configureShapes({ opacity, diff --git a/cvat-ui/src/containers/annotation-page/canvas/canvas-wrapper3D.tsx b/cvat-ui/src/containers/annotation-page/canvas/canvas-wrapper3D.tsx index 12da11198f6f..c4587457587b 100644 --- a/cvat-ui/src/containers/annotation-page/canvas/canvas-wrapper3D.tsx +++ b/cvat-ui/src/containers/annotation-page/canvas/canvas-wrapper3D.tsx @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2022 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -20,60 +21,33 @@ import { } from 'actions/annotation-actions'; import { - ActiveControl, ColorBy, CombinedState, ContextMenuType, - GridColor, ObjectType, Workspace, } from 'reducers'; import { Canvas3d } from 'cvat-canvas3d-wrapper'; import { Canvas } from 'cvat-canvas-wrapper'; -import { KeyMap } from '../../../utils/mousetrap-react'; interface StateToProps { - canvasInstance: Canvas3d | Canvas; - jobInstance: any; - frameData: any; - curZLayer: number; - annotations: any[]; - sidebarCollapsed: boolean; - activatedStateID: number | null; - activatedAttributeID: number | null; - frameIssues: any[] | null; - frameAngle: number; - frameFetching: boolean; - frame: number; opacity: number; - colorBy: ColorBy; selectedOpacity: number; outlined: boolean; outlineColor: string; - showBitmap: boolean; - showProjections: boolean; - grid: boolean; - gridSize: number; - gridColor: GridColor; - gridOpacity: number; + colorBy: ColorBy; + frameFetching: boolean; + canvasInstance: Canvas3d | Canvas; + jobInstance: any; + frameData: any; + annotations: any[]; + contextMenuVisibility: boolean; activeLabelID: number; activeObjectType: ObjectType; - brightnessLevel: number; - contrastLevel: number; - saturationLevel: number; - resetZoom: boolean; - aamZoomMargin: number; - contextMenuVisibility: boolean; - showObjectsTextAlways: boolean; - showAllInterpolationTracks: boolean; workspace: Workspace; - minZLayer: number; - maxZLayer: number; - automaticBordering: boolean; - switchableAutomaticBordering: boolean; - keyMap: KeyMap; - canvasBackgroundColor: string; + frame: number; + resetZoom: boolean; } interface DispatchToProps { @@ -94,7 +68,6 @@ function mapStateToProps(state: CombinedState): StateToProps { const { annotation: { canvas: { - activeControl, instance: canvasInstance, contextMenu: { visible: contextMenuVisibility }, }, @@ -102,85 +75,39 @@ function mapStateToProps(state: CombinedState): StateToProps { job: { instance: jobInstance }, player: { frame: { data: frameData, number: frame, fetching: frameFetching }, - frameAngles, }, annotations: { states: annotations, - activatedStateID, - activatedAttributeID, - zLayer: { cur: curZLayer, min: minZLayer, max: maxZLayer }, }, - sidebarCollapsed, workspace, }, settings: { player: { - canvasBackgroundColor, - grid, - gridSize, - gridColor, - gridOpacity, - brightnessLevel, - contrastLevel, - saturationLevel, resetZoom, }, - workspace: { - aamZoomMargin, showObjectsTextAlways, showAllInterpolationTracks, automaticBordering, - }, shapes: { - opacity, colorBy, selectedOpacity, outlined, outlineColor, showBitmap, showProjections, + opacity, colorBy, selectedOpacity, outlined, outlineColor, }, }, - review: { frameIssues, issuesHidden }, - shortcuts: { keyMap }, } = state; return { canvasInstance, jobInstance, frameData, - curZLayer, contextMenuVisibility, annotations, - sidebarCollapsed, - frameIssues: - issuesHidden || ![Workspace.REVIEW_WORKSPACE, Workspace.STANDARD].includes(workspace) ? null : frameIssues, - frameAngle: frameAngles[frame - jobInstance.startFrame], frameFetching, frame, - activatedStateID, - activatedAttributeID, opacity, colorBy, selectedOpacity, outlined, outlineColor, - showBitmap, - showProjections, - grid, - gridSize, - gridColor, - gridOpacity, activeLabelID, activeObjectType, - brightnessLevel, - contrastLevel, - saturationLevel, resetZoom, - aamZoomMargin, - showObjectsTextAlways, - showAllInterpolationTracks, - minZLayer, - maxZLayer, - automaticBordering, workspace, - keyMap, - canvasBackgroundColor, - switchableAutomaticBordering: - activeControl === ActiveControl.DRAW_POLYGON || - activeControl === ActiveControl.DRAW_POLYLINE || - activeControl === ActiveControl.EDIT, }; } @@ -212,7 +139,7 @@ function mapDispatchToProps(dispatch: any): DispatchToProps { dispatch(updateCanvasContextMenu(false, 0, 0)); } - dispatch(activateObject(activatedStateID, null)); + dispatch(activateObject(activatedStateID, null, null)); }, onEditShape(enabled: boolean): void { dispatch(editShape(enabled)); diff --git a/tests/cypress/integration/canvas3d_functionality/case_83_canvas3d_functionality_cuboid_grouping.js b/tests/cypress/integration/canvas3d_functionality/case_83_canvas3d_functionality_cuboid_grouping.js index bd820d27fce2..324ab9b66da4 100644 --- a/tests/cypress/integration/canvas3d_functionality/case_83_canvas3d_functionality_cuboid_grouping.js +++ b/tests/cypress/integration/canvas3d_functionality/case_83_canvas3d_functionality_cuboid_grouping.js @@ -1,7 +1,10 @@ // Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2022 CVAT.ai Corporation // // SPDX-License-Identifier: MIT +/* eslint-disable cypress/no-unnecessary-waiting */ + /// import { taskName, labelName } from '../../support/const_canvas3d'; @@ -10,24 +13,24 @@ context('Canvas 3D functionality. Grouping.', () => { const caseId = '83'; const screenshotsPath = 'cypress/screenshots/canvas3d_functionality/case_83_canvas3d_functionality_cuboid_grouping.js'; const firstCuboidCreationParams = { - labelName: labelName, + labelName, x: 480, - y: 160, + y: 150, }; const secondCuboidCreationParams = { - labelName: labelName, + labelName, x: 480, - y: 270, + y: 200, }; const thirdCuboidCreationParams = { - labelName: labelName, - x: 430, - y: 220, + labelName, + x: 530, + y: 150, }; const fourthCuboidCreationParams = { - labelName: labelName, + labelName, x: 530, - y: 220, + y: 200, }; const yellowHex = 'fcbe03'; const yellowRgb = '252, 190, 3'; @@ -48,7 +51,7 @@ context('Canvas 3D functionality. Grouping.', () => { } before(() => { - cy.openTask(taskName) + cy.openTask(taskName); cy.openJob(); cy.wait(1000); // Waiting for the point cloud to display cy.create3DCuboid(firstCuboidCreationParams); @@ -61,8 +64,8 @@ context('Canvas 3D functionality. Grouping.', () => { describe(`Testing case "${caseId}"`, () => { it('Grouping two cuboids.', () => { cy.get('.cvat-group-control').click(); - cy.get('.cvat-canvas3d-perspective').trigger('mousemove', 480, 270).click(480, 270); - cy.get('.cvat-canvas3d-perspective').trigger('mousemove', 430, 220).click(430, 220); + cy.get('.cvat-canvas3d-perspective').trigger('mousemove', 480, 200).click(480, 200); + cy.get('.cvat-canvas3d-perspective').trigger('mousemove', 530, 150).click(530, 150); cy.get('.cvat-group-control').click(); cy.changeAppearance('Group'); cy.get('#cvat-objects-sidebar-state-item-1').invoke('attr', 'style').then((bgColorItem1) => { @@ -102,8 +105,8 @@ context('Canvas 3D functionality. Grouping.', () => { it('Reset group.', () => { cy.customScreenshot('.cvat-canvas3d-perspective', 'canvas3d_perspective_before_reset_group'); cy.get('.cvat-group-control').click(); - cy.get('.cvat-canvas3d-perspective').trigger('mousemove', 480, 270).click(480, 270); - cy.get('.cvat-canvas3d-perspective').trigger('mousemove', 430, 220).click(430, 220); + cy.get('.cvat-canvas3d-perspective').trigger('mousemove', 480, 200).click(480, 200); + cy.get('.cvat-canvas3d-perspective').trigger('mousemove', 530, 150).click(530, 150); cy.get('body').type('{Shift}g'); cy.get('#cvat-objects-sidebar-state-item-2').invoke('attr', 'style').then((bgColorItem2) => { expect(bgColorItem).to.be.equal(bgColorItem2); diff --git a/tests/cypress/integration/canvas3d_functionality_2/case_82_canvas3d_functionality_cuboid_opacity_outlined_borders.js b/tests/cypress/integration/canvas3d_functionality_2/case_82_canvas3d_functionality_cuboid_opacity_outlined_borders.js index db7a6b3b1eb9..ffe705dddc07 100644 --- a/tests/cypress/integration/canvas3d_functionality_2/case_82_canvas3d_functionality_cuboid_opacity_outlined_borders.js +++ b/tests/cypress/integration/canvas3d_functionality_2/case_82_canvas3d_functionality_cuboid_opacity_outlined_borders.js @@ -1,7 +1,10 @@ // Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2022 CVAT.ai Corporation // // SPDX-License-Identifier: MIT +/* eslint-disable cypress/no-unnecessary-waiting */ + /// import { taskName, labelName } from '../../support/const_canvas3d'; @@ -10,13 +13,13 @@ context('Canvas 3D functionality. Opacity. Outlined borders.', () => { const caseId = '82'; const screenshotsPath = 'cypress/screenshots/canvas3d_functionality_2/case_82_canvas3d_functionality_cuboid_opacity_outlined_borders.js'; const cuboidCreationParams = { - labelName: labelName, + labelName, x: 500, y: 250, }; before(() => { - cy.openTask(taskName) + cy.openTask(taskName); cy.openJob(); cy.wait(1000); // Waiting for the point cloud to display cy.create3DCuboid(cuboidCreationParams); @@ -64,6 +67,11 @@ context('Canvas 3D functionality. Opacity. Outlined borders.', () => { it('Enable/disable outlined borders.', () => { cy.get('.cvat-appearance-outlinded-borders-checkbox').find('[type="checkbox"]').check().should('be.checked'); + cy.get('.cvat-appearance-outlined-borders-button').click(); + cy.get('.cvat-label-color-picker').should('exist').and('be.visible').within(() => { + cy.get('div[title="#ff007c"]').click(); + cy.contains('Ok').click(); + }); cy.customScreenshot('.cvat-canvas3d-perspective', 'canvas3d_perspective_enable_outlined_borders'); cy.compareImagesAndCheckResult( `${screenshotsPath}/canvas3d_perspective_enable_outlined_borders.png`,