diff --git a/Dockerfile b/Dockerfile
index 2ce2cd35c95d..9323339310ba 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -73,6 +73,8 @@ RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -yq \
apache2 \
libapache2-mod-xsendfile \
+ libgomp1 \
+ libgl1 \
supervisor \
libldap-2.4-2 \
libsasl2-2 \
diff --git a/cvat-core/src/annotation-formats.js b/cvat-core/src/annotation-formats.js
index 795c98630e7e..0bad3b7fb8a2 100644
--- a/cvat-core/src/annotation-formats.js
+++ b/cvat-core/src/annotation-formats.js
@@ -15,6 +15,7 @@
format: initialData.ext,
version: initialData.version,
enabled: initialData.enabled,
+ dimension: initialData.dimension,
};
Object.defineProperties(this, {
@@ -58,6 +59,16 @@
*/
get: () => data.enabled,
},
+ dimension: {
+ /**
+ * @name dimension
+ * @type {string}
+ * @memberof module:API.cvat.enums.DimensionType
+ * @readonly
+ * @instance
+ */
+ get: () => data.dimension,
+ },
});
}
}
@@ -74,6 +85,7 @@
format: initialData.ext,
version: initialData.version,
enabled: initialData.enabled,
+ dimension: initialData.dimension,
};
Object.defineProperties(this, {
@@ -117,6 +129,16 @@
*/
get: () => data.enabled,
},
+ dimension: {
+ /**
+ * @name dimension
+ * @type {string}
+ * @memberof module:API.cvat.enums.DimensionType
+ * @readonly
+ * @instance
+ */
+ get: () => data.dimension,
+ },
});
}
}
diff --git a/cvat-core/src/api-implementation.js b/cvat-core/src/api-implementation.js
index f3e2aa26aa09..1d2dbff5c54c 100644
--- a/cvat-core/src/api-implementation.js
+++ b/cvat-core/src/api-implementation.js
@@ -10,7 +10,7 @@
isBoolean, isInteger, isEnum, isString, checkFilter,
} = require('./common');
- const { TaskStatus, TaskMode } = require('./enums');
+ const { TaskStatus, TaskMode, DimensionType } = require('./enums');
const User = require('./user');
const { AnnotationFormats } = require('./annotation-formats');
@@ -176,6 +176,7 @@
search: isString,
status: isEnum.bind(TaskStatus),
mode: isEnum.bind(TaskMode),
+ dimension: isEnum.bind(DimensionType),
});
if ('search' in filter && Object.keys(filter).length > 1) {
@@ -198,7 +199,7 @@
}
const searchParams = new URLSearchParams();
- for (const field of ['name', 'owner', 'assignee', 'search', 'status', 'mode', 'id', 'page', 'projectId']) {
+ for (const field of ['name', 'owner', 'assignee', 'search', 'status', 'mode', 'id', 'page', 'projectId', 'dimension']) {
if (Object.prototype.hasOwnProperty.call(filter, field)) {
searchParams.set(field, filter[field]);
}
diff --git a/cvat-core/src/enums.js b/cvat-core/src/enums.js
index 107bc86fcc5c..4ce6d80c08c6 100644
--- a/cvat-core/src/enums.js
+++ b/cvat-core/src/enums.js
@@ -33,6 +33,20 @@
COMPLETED: 'completed',
});
+ /**
+ * Task dimension
+ * @enum
+ * @name DimensionType
+ * @memberof module:API.cvat.enums
+ * @property {string} DIMENSION_2D '2d'
+ * @property {string} DIMENSION_3D '3d'
+ * @readonly
+ */
+ const DimensionType = Object.freeze({
+ DIMENSION_2D: '2d',
+ DIMENSION_3D: '3d',
+ });
+
/**
* Review statuses
* @enum {string}
@@ -333,5 +347,6 @@
RQStatus,
colors,
Source,
+ DimensionType,
};
})();
diff --git a/cvat-core/src/session.js b/cvat-core/src/session.js
index 19bc32df6014..5b6aa41fc466 100644
--- a/cvat-core/src/session.js
+++ b/cvat-core/src/session.js
@@ -974,6 +974,7 @@
use_zip_chunks: undefined,
use_cache: undefined,
copy_data: undefined,
+ dimension: undefined,
};
let updatedFields = {
@@ -1452,6 +1453,16 @@
updatedFields = fields;
},
},
+ dimension: {
+ /**
+ * @name enabled
+ * @type {string}
+ * @memberof module:API.cvat.enums.DimensionType
+ * @readonly
+ * @instance
+ */
+ get: () => data.dimension,
+ },
}),
);
diff --git a/cvat-ui/src/components/actions-menu/actions-menu.tsx b/cvat-ui/src/components/actions-menu/actions-menu.tsx
index 723bf68e1452..644f29454793 100644
--- a/cvat-ui/src/components/actions-menu/actions-menu.tsx
+++ b/cvat-ui/src/components/actions-menu/actions-menu.tsx
@@ -11,6 +11,7 @@ import { MenuInfo } from 'rc-menu/lib/interface';
import DumpSubmenu from './dump-submenu';
import LoadSubmenu from './load-submenu';
import ExportSubmenu from './export-submenu';
+import { DimensionType } from '../../reducers/interfaces';
interface Props {
taskID: number;
@@ -22,7 +23,7 @@ interface Props {
dumpActivities: string[] | null;
exportActivities: string[] | null;
inferenceIsActive: boolean;
-
+ taskDimension: DimensionType;
onClickMenu: (params: MenuInfo, file?: File) => void;
}
@@ -47,6 +48,7 @@ export default function ActionsMenuComponent(props: Props): JSX.Element {
dumpActivities,
exportActivities,
loadActivity,
+ taskDimension,
} = props;
let latestParams: MenuInfo | null = null;
@@ -102,6 +104,7 @@ export default function ActionsMenuComponent(props: Props): JSX.Element {
dumpers,
dumpActivities,
menuKey: Actions.DUMP_TASK_ANNO,
+ taskDimension,
})}
{LoadSubmenu({
loaders,
@@ -110,11 +113,13 @@ export default function ActionsMenuComponent(props: Props): JSX.Element {
onClickMenuWrapper(null, file);
},
menuKey: Actions.LOAD_TASK_ANNO,
+ taskDimension,
})}
{ExportSubmenu({
exporters: dumpers,
exportActivities,
menuKey: Actions.EXPORT_TASK_DATASET,
+ taskDimension,
})}
{!!bugTracker &&
Open bug tracker}
diff --git a/cvat-ui/src/components/actions-menu/dump-submenu.tsx b/cvat-ui/src/components/actions-menu/dump-submenu.tsx
index 5f71273f3d24..91721ac6bb81 100644
--- a/cvat-ui/src/components/actions-menu/dump-submenu.tsx
+++ b/cvat-ui/src/components/actions-menu/dump-submenu.tsx
@@ -6,6 +6,7 @@ import React from 'react';
import Menu from 'antd/lib/menu';
import { DownloadOutlined, LoadingOutlined } from '@ant-design/icons';
import Text from 'antd/lib/typography/Text';
+import { DimensionType } from '../../reducers/interfaces';
function isDefaultFormat(dumperName: string, taskMode: string): boolean {
return (
@@ -19,15 +20,19 @@ interface Props {
menuKey: string;
dumpers: any[];
dumpActivities: string[] | null;
+ taskDimension: DimensionType;
}
export default function DumpSubmenu(props: Props): JSX.Element {
- const { taskMode, menuKey, dumpers, dumpActivities } = props;
+ const {
+ taskMode, menuKey, dumpers, dumpActivities, taskDimension,
+ } = props;
return (
{dumpers
.sort((a: any, b: any) => a.name.localeCompare(b.name))
+ .filter((dumper: any): boolean => dumper.dimension === taskDimension)
.map(
(dumper: any): JSX.Element => {
const pending = (dumpActivities || []).includes(dumper.name);
diff --git a/cvat-ui/src/components/actions-menu/export-submenu.tsx b/cvat-ui/src/components/actions-menu/export-submenu.tsx
index 28affd5f7b05..683565009155 100644
--- a/cvat-ui/src/components/actions-menu/export-submenu.tsx
+++ b/cvat-ui/src/components/actions-menu/export-submenu.tsx
@@ -6,20 +6,25 @@ import React from 'react';
import Menu from 'antd/lib/menu';
import Text from 'antd/lib/typography/Text';
import { ExportOutlined, LoadingOutlined } from '@ant-design/icons';
+import { DimensionType } from '../../reducers/interfaces';
interface Props {
menuKey: string;
exporters: any[];
exportActivities: string[] | null;
+ taskDimension: DimensionType;
}
export default function ExportSubmenu(props: Props): JSX.Element {
- const { menuKey, exporters, exportActivities } = props;
+ const {
+ menuKey, exporters, exportActivities, taskDimension,
+ } = props;
return (
{exporters
.sort((a: any, b: any) => a.name.localeCompare(b.name))
+ .filter((exporter: any): boolean => exporter.dimension === taskDimension)
.map(
(exporter: any): JSX.Element => {
const pending = (exportActivities || []).includes(exporter.name);
diff --git a/cvat-ui/src/components/actions-menu/load-submenu.tsx b/cvat-ui/src/components/actions-menu/load-submenu.tsx
index 53bbe3c776b4..476e577fcb36 100644
--- a/cvat-ui/src/components/actions-menu/load-submenu.tsx
+++ b/cvat-ui/src/components/actions-menu/load-submenu.tsx
@@ -8,23 +8,26 @@ import Upload from 'antd/lib/upload';
import Button from 'antd/lib/button';
import Text from 'antd/lib/typography/Text';
import { UploadOutlined, LoadingOutlined } from '@ant-design/icons';
+import { DimensionType } from '../../reducers/interfaces';
interface Props {
menuKey: string;
loaders: any[];
loadActivity: string | null;
onFileUpload(file: File): void;
+ taskDimension: DimensionType;
}
export default function LoadSubmenu(props: Props): JSX.Element {
const {
- menuKey, loaders, loadActivity, onFileUpload,
+ menuKey, loaders, loadActivity, onFileUpload, taskDimension,
} = props;
return (
{loaders
.sort((a: any, b: any) => a.name.localeCompare(b.name))
+ .filter((loader: any): boolean => loader.dimension === taskDimension)
.map(
(loader: any): JSX.Element => {
const accept = loader.format
diff --git a/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx b/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx
index 3ac000f4c474..9400a20c2809 100644
--- a/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx
+++ b/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx
@@ -161,6 +161,7 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element {
dumpers,
dumpActivities,
menuKey: Actions.DUMP_TASK_ANNO,
+ taskDimension: jobInstance.task.dimension,
})}
{LoadSubmenu({
loaders,
@@ -169,11 +170,13 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element {
onClickMenuWrapper(null, file);
},
menuKey: Actions.LOAD_JOB_ANNO,
+ taskDimension: jobInstance.task.dimension,
})}
{ExportSubmenu({
exporters: dumpers,
exportActivities,
menuKey: Actions.EXPORT_TASK_DATASET,
+ taskDimension: jobInstance.task.dimension,
})}
Remove annotations
diff --git a/cvat-ui/src/components/model-runner-modal/detector-runner.tsx b/cvat-ui/src/components/model-runner-modal/detector-runner.tsx
index 8a000e1ad125..db757867c138 100644
--- a/cvat-ui/src/components/model-runner-modal/detector-runner.tsx
+++ b/cvat-ui/src/components/model-runner-modal/detector-runner.tsx
@@ -21,6 +21,7 @@ import { Model, StringObject } from 'reducers/interfaces';
import { clamp } from 'utils/math';
import consts from 'consts';
+import { DimensionType } from '../../reducers/interfaces';
interface Props {
withCleanup: boolean;
@@ -127,7 +128,8 @@ function DetectorRunner(props: Props): JSX.Element {
Model: