Skip to content

Commit

Permalink
Receive value for 'Reset zoom' option from settings saved by user (#5908
Browse files Browse the repository at this point in the history
)

<!-- Raise an issue to propose your change
(https://github.com/opencv/cvat/issues).
It helps to avoid duplication of efforts from multiple independent
contributors.
Discuss your ideas with maintainers to be sure that changes will be
approved and merged.
Read the [Contribution
guide](https://opencv.github.io/cvat/docs/contributing/). -->

<!-- Provide a general summary of your changes in the Title above -->

### Motivation and context
Resolved #4289

### How has this been tested?
<!-- Please describe in detail how you tested your changes.
Include details of your testing environment, and the tests you ran to
see how your change affects other areas of the code, etc. -->

### Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply.
If an item isn't applicable for some reason, then ~~explicitly
strikethrough~~ the whole
line. If you don't do that, GitHub will show incorrect progress for the
pull request.
If you're unsure about any of these, don't hesitate to ask. We're here
to help! -->
- [x] I submit my changes into the `develop` branch
- [x] I have added a description of my changes into the
[CHANGELOG](https://github.com/opencv/cvat/blob/develop/CHANGELOG.md)
file
- [ ] I have updated the documentation accordingly
- [x] I have added tests to cover my changes
- [x] I have linked related issues (see [GitHub docs](

https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword))
- [x] I have increased versions of npm packages if it is necessary

([cvat-canvas](https://github.com/opencv/cvat/tree/develop/cvat-canvas#versioning),

[cvat-core](https://github.com/opencv/cvat/tree/develop/cvat-core#versioning),

[cvat-data](https://github.com/opencv/cvat/tree/develop/cvat-data#versioning)
and

[cvat-ui](https://github.com/opencv/cvat/tree/develop/cvat-ui#versioning))

### License

- [x] I submit _my code changes_ under the same [MIT License](
https://github.com/opencv/cvat/blob/develop/LICENSE) that covers the
project.
  Feel free to contact the maintainers if that's a concern.
  • Loading branch information
bsekachev authored Mar 23, 2023
1 parent 90ad0d1 commit 97461ea
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 77 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- An invalid project/org handling in webhooks (<https://github.com/opencv/cvat/pull/5707>)
- Warning `key` is undefined on project page (<https://github.com/opencv/cvat/pull/5876>)
- Invalid mask when running automatic annotation on a task (<https://github.com/opencv/cvat/pull/5883>)
- Option 'Reset zoom' now restored as user specified when reload CVAT (<https://github.com/opencv/cvat/pull/5908>)
- Cloud storage content listing when the manifest name contains special characters
(<https://github.com/opencv/cvat/pull/5873>)
- Width and height in CVAT dataset format mask annotations (<https://github.com/opencv/cvat/pull/5905>)
Expand Down
2 changes: 1 addition & 1 deletion cvat-canvas3d/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-canvas3d",
"version": "0.0.7",
"version": "0.0.8",
"description": "Part of Computer Vision Annotation Tool which presents its canvas3D library",
"main": "src/canvas3d.ts",
"scripts": {
Expand Down
5 changes: 0 additions & 5 deletions cvat-canvas3d/src/typescript/canvas3d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
MouseInteraction,
ShapeProperties,
GroupData,
Configuration,
SplitData,
MergeData,
} from './canvas3dModel';
Expand Down Expand Up @@ -108,10 +107,6 @@ 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(typeof clientID === 'number' ? String(clientID) : null, attributeID);
}
Expand Down
7 changes: 1 addition & 6 deletions cvat-canvas3d/src/typescript/canvas3dController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
import { ObjectState } from '.';
import {
Canvas3dModel, Mode, DrawData, ActiveElement,
GroupData, Configuration, MergeData, SplitData,
GroupData, MergeData, SplitData,
} from './canvas3dModel';

export interface Canvas3dController {
readonly drawData: DrawData;
readonly activeElement: ActiveElement;
readonly groupData: GroupData;
readonly configuration: Configuration;
readonly imageIsDeleted: boolean;
readonly objects: ObjectState[];
mode: Mode;
Expand Down Expand Up @@ -53,10 +52,6 @@ export class Canvas3dControllerImpl implements Canvas3dController {
return this.model.groupData;
}

public get configuration(): Configuration {
return this.model.configuration;
}

public get objects(): ObjectState[] {
return this.model.objects;
}
Expand Down
23 changes: 0 additions & 23 deletions cvat-canvas3d/src/typescript/canvas3dModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ export interface SplitData {
enabled: boolean;
}

export interface Configuration {
resetZoom?: boolean;
}

export interface Image {
renderWidth: number;
renderHeight: number;
Expand Down Expand Up @@ -90,7 +86,6 @@ export enum UpdateReasons {
MERGE = 'merge',
SPLIT = 'split',
FITTED_CANVAS = 'fitted_canvas',
CONFIG_UPDATED = 'config_updated',
SHAPES_CONFIG_UPDATED = 'shapes_config_updated',
}

Expand Down Expand Up @@ -119,7 +114,6 @@ export interface Canvas3dDataModel {
groupData: GroupData;
mergeData: MergeData;
splitData: SplitData;
configuration: Configuration;
isFrameUpdating: boolean;
nextSetupRequest: {
frameData: any;
Expand All @@ -133,7 +127,6 @@ export interface Canvas3dModel {
readonly imageIsDeleted: boolean;
readonly groupData: GroupData;
readonly mergeData: MergeData;
readonly configuration: Configuration;
readonly objects: ObjectState[];
setup(frameData: any, objectStates: ObjectState[]): void;
isAbleToChangeFrame(): boolean;
Expand All @@ -142,7 +135,6 @@ export interface Canvas3dModel {
dragCanvas(enable: boolean): void;
activate(clientID: string | null, attributeID: number | null): void;
configureShapes(shapeProperties: ShapeProperties): void;
configure(configuration: Configuration): void;
fit(): void;
group(groupData: GroupData): void;
split(splitData: SplitData): void;
Expand Down Expand Up @@ -196,9 +188,6 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel {
selectedOpacity: 60,
colorBy: 'Label',
},
configuration: {
resetZoom: false,
},
isFrameUpdating: false,
nextSetupRequest: null,
};
Expand Down Expand Up @@ -388,14 +377,6 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel {
this.notify(UpdateReasons.MERGE);
}

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 {
if (typeof shapeProperties.opacity === 'number') {
this.data.shapeProperties.opacity = Math.max(0, Math.min(shapeProperties.opacity, 100));
Expand Down Expand Up @@ -424,10 +405,6 @@ 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 };
}
Expand Down
32 changes: 15 additions & 17 deletions cvat-canvas3d/src/typescript/canvas3dView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,9 +458,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
viewType.rayCaster.renderer.setFromCamera(viewType.rayCaster.mouseVector, viewType.camera);
const intersects = viewType.rayCaster.renderer.intersectObjects(this.getAllVisibleCuboids(), false);
if (!intersects.length) {
const { x, y, z } = this.action.frameCoordinates;
this.positionAllViews(x, y, z, true);
this.updateCameraFrustrumPlane();
this.fitCanvas(true);
}
return;
}
Expand Down Expand Up @@ -606,6 +604,12 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
model.subscribe(this);
}

private fitCanvas(animation: boolean): void {
const { x, y, z } = this.action.frameCoordinates;
this.positionAllViews(x, y, z, animation);
this.updateCameraFrustrumPlane();
}

private getAllVisibleCuboids(view: ViewType = ViewType.PERSPECTIVE): THREE.Mesh[] {
return Object.values(this.drawnObjects)
.map(({ cuboid }) => cuboid[view]).filter((mesh: THREE.Mesh) => mesh.visible);
Expand Down Expand Up @@ -1155,6 +1159,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
model.updateCanvasObjects();
} finally {
model.unlockFrameUpdating();
this.dispatchEvent(new CustomEvent('canvas.setup'));
}
};

Expand Down Expand Up @@ -1192,6 +1197,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
canvasContext.strokeText('IMAGE REMOVED', width / 2, height / 2);
canvasContext.fillStyle = 'black';
canvasContext.fillText('IMAGE REMOVED', width / 2, height / 2);
this.dispatchEvent(new CustomEvent('canvas.setup'));
} finally {
model.unlockFrameUpdating();
}
Expand All @@ -1202,8 +1208,6 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
overlay.remove();
}
}

this.dispatchEvent(new CustomEvent('canvas.setup'));
} finally {
URL.revokeObjectURL(objectURL);
}
Expand Down Expand Up @@ -1322,6 +1326,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
this.mode = Mode.IDLE;
this.dispatchEvent(new CustomEvent('canvas.canceled'));
} else if (reason === UpdateReasons.FITTED_CANVAS) {
this.fitCanvas(false);
this.dispatchEvent(new CustomEvent('canvas.fit'));
} else if (reason === UpdateReasons.GROUP) {
if (!model.groupData.enabled && this.statesToBeGrouped.length) {
Expand Down Expand Up @@ -1459,18 +1464,11 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener {
const material = points.material.clone();
if (!this.views.perspective.camera) return;

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,
);
}
// updating correct camera settings
points.geometry.computeBoundingBox();
this.cameraSettings.perspective.position = getCameraSettingsToFitScene(
this.views.perspective.camera as THREE.PerspectiveCamera, points.geometry.boundingBox,
);

this.sceneBBox = new THREE.Box3().setFromObject(points);
this.views.perspective.scene.add(points.clone());
Expand Down
2 changes: 1 addition & 1 deletion cvat-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-ui",
"version": "1.50.2",
"version": "1.50.3",
"description": "CVAT single-page application",
"main": "src/index.tsx",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,11 +489,13 @@ const Canvas3DWrapperComponent = React.memo((props: Props): ReactElement => {

const initialSetup = (): void => {
const canvasInstanceDOM = canvasInstance.html() as ViewsDOM;
canvasInstanceDOM.perspective.addEventListener('canvas.setup', () => {
canvasInstance.fit();
}, { once: true });
canvasInstanceDOM.perspective.addEventListener('canvas.setup', onCanvasSetup);
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 => {
Expand Down Expand Up @@ -547,7 +549,17 @@ const Canvas3DWrapperComponent = React.memo((props: Props): ReactElement => {
}, [activatedStateID]);

useEffect(() => {
canvasInstance.configure({ resetZoom });
let listener: EventListener | null = null;
if (resetZoom) {
listener = () => canvasInstance.fit();
canvasInstance.html().perspective.addEventListener('canvas.setup', listener);
}

return () => {
if (listener) {
canvasInstance.html().perspective.removeEventListener('canvas.setup', listener);
}
};
}, [resetZoom]);

const updateShapesView = (): void => {
Expand Down
6 changes: 5 additions & 1 deletion cvat-ui/src/components/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ function HeaderContainer(props: Props): JSX.Element {
});
}, [tool]);

const closeSettings = useCallback(() => {
switchSettingsDialog(false);
}, []);

const resetOrganization = (): void => {
localStorage.removeItem('currentOrganization');
if (/(webhooks)|(\d+)/.test(window.location.pathname)) {
Expand Down Expand Up @@ -536,7 +540,7 @@ function HeaderContainer(props: Props): JSX.Element {
</span>
</Dropdown>
</div>
<SettingsModal visible={settingsDialogShown} onClose={() => switchSettingsDialog(false)} />
<SettingsModal visible={settingsDialogShown} onClose={closeSettings} />
{renderChangePasswordItem && <ChangePasswordDialog onClose={() => switchChangePasswordDialog(false)} />}
</Layout.Header>
);
Expand Down
24 changes: 14 additions & 10 deletions cvat-ui/src/components/header/settings-modal/settings-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Copyright (C) 2020-2022 Intel Corporation
// Copyright (C) 2023 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT

import './styles.scss';
import React, { useEffect } from 'react';
import _ from 'lodash';
import React, { useCallback, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import Tabs from 'antd/lib/tabs';
import Text from 'antd/lib/typography/Text';
Expand All @@ -29,34 +31,36 @@ const SettingsModal = (props: SettingsModalProps): JSX.Element => {
const settings = useSelector((state: CombinedState) => state.settings);
const dispatch = useDispatch();

const onSaveSettings = (): void => {
const onSaveSettings = useCallback(() => {
const settingsForSaving: any = {};
for (const [key, value] of Object.entries(settings)) {
if (typeof value === 'object') {
if (['player', 'workspace'].includes(key)) {
settingsForSaving[key] = value;
}
}

localStorage.setItem('clientSettings', JSON.stringify(settingsForSaving));
notification.success({
message: 'Settings was successfully saved',
message: 'Settings were successfully saved',
className: 'cvat-notification-notice-save-settings-success',
});
};

onClose();
}, [onClose, settings]);

useEffect(() => {
try {
const newSettings: any = {};
const newSettings = _.pick(settings, 'player', 'workspace');
const settingsString = localStorage.getItem('clientSettings') as string;
if (!settingsString) return;
const loadedSettings = JSON.parse(settingsString);
for (const [sectionKey, section] of Object.entries(settings)) {
for (const [sectionKey, section] of Object.entries(newSettings)) {
for (const [key, value] of Object.entries(section)) {
let settedValue = value;
if (sectionKey in loadedSettings && key in loadedSettings[sectionKey]) {
settedValue = loadedSettings[sectionKey][key];
Object.defineProperty(newSettings[(sectionKey as 'player' | 'workspace')], key, { value: settedValue });
}
if (!(sectionKey in newSettings)) newSettings[sectionKey] = {};
newSettings[sectionKey][key] = settedValue;
}
}
dispatch(setSettings(newSettings));
Expand All @@ -77,7 +81,7 @@ const SettingsModal = (props: SettingsModalProps): JSX.Element => {
className='cvat-settings-modal'
footer={(
<>
<Tooltip title='Will save settings from this page and appearance settings on standard workspace page in browser'>
<Tooltip title='Will save settings to restore them after the app is reopened'>
<Button className='cvat-save-settings-button' type='primary' onClick={onSaveSettings}>
Save
</Button>
Expand Down
2 changes: 1 addition & 1 deletion cvat-ui/src/reducers/settings-reducer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (C) 2020-2022 Intel Corporation
// Copyright (C) 2023 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT

Expand Down Expand Up @@ -412,7 +413,6 @@ export default (state = defaultState, action: AnyAction): SettingsState => {
...state,
player: {
...state.player,
resetZoom: job && job.mode === 'annotation',
},
shapes: {
...defaultState.shapes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ context('Settings. Default number of points in polygon approximation.', () => {
const sliderAttrValuemax = slider.attr('aria-valuemax');
cy.saveSettings();
cy.closeNotification('.cvat-notification-notice-save-settings-success');
cy.closeSettings();
cy.reload();
testCheckSliderAttrValuenow(sliderAttrValueNow);
cy.contains('strong', 'less').click();
Expand Down
Loading

0 comments on commit 97461ea

Please sign in to comment.