From 943c2b0dbb025c983352f12d16793b508b4c15ce Mon Sep 17 00:00:00 2001 From: laoluo Date: Thu, 23 Mar 2023 14:54:32 +0800 Subject: [PATCH 01/41] fix(view-operation): Update the range of direction judgement --- .../lb-annotation/src/core/toolOperation/ViewOperation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/lb-annotation/src/core/toolOperation/ViewOperation.ts b/packages/lb-annotation/src/core/toolOperation/ViewOperation.ts index 3d9761d74..e5623c610 100644 --- a/packages/lb-annotation/src/core/toolOperation/ViewOperation.ts +++ b/packages/lb-annotation/src/core/toolOperation/ViewOperation.ts @@ -385,7 +385,7 @@ export default class ViewOperation extends BasicToolOperation { newPointList = DrawUtils.drawPolygon(this.canvas, renderLineWithZoom, lineRenderOptions); } - const isShowDirection = line?.showDirection === true && line?.pointList?.length > 2; + const isShowDirection = line?.showDirection === true && line?.pointList?.length >= 2; // 是否展示方向 if (isShowDirection) { @@ -460,7 +460,7 @@ export default class ViewOperation extends BasicToolOperation { newPointList = DrawUtils.drawPolygon(this.canvas, renderPolygon, polygonRenderOptions); } - const isShowDirection = polygon?.showDirection === true && polygon?.pointList?.length > 2; + const isShowDirection = polygon?.showDirection === true && polygon?.pointList?.length >= 2; // 是否展示方向 if (isShowDirection) { From dbd080f9e650d926be5729713b19217f36bcfc82 Mon Sep 17 00:00:00 2001 From: laoluo Date: Thu, 23 Mar 2023 15:04:23 +0800 Subject: [PATCH 02/41] chore: Update offical version --- packages/lb-annotation/package.json | 2 +- packages/lb-components/package.json | 4 ++-- packages/lb-demo/package.json | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/lb-annotation/package.json b/packages/lb-annotation/package.json index 9a2780bdc..ae6e6c742 100644 --- a/packages/lb-annotation/package.json +++ b/packages/lb-annotation/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-annotation", - "version": "1.12.0", + "version": "1.12.1", "description": "Annotation tool collection", "keywords": [ "annotation", diff --git a/packages/lb-components/package.json b/packages/lb-components/package.json index 0135f1cda..223359764 100644 --- a/packages/lb-components/package.json +++ b/packages/lb-components/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-components", - "version": "1.8.0", + "version": "1.8.1", "description": "Provide a complete library of annotation components", "main": "./dist/index.js", "es": "./es/index.js", @@ -41,7 +41,7 @@ }, "dependencies": { "@ant-design/icons": "^4.6.2", - "@labelbee/lb-annotation": "^1.12.0", + "@labelbee/lb-annotation": "^1.12.1", "@labelbee/lb-utils": "^1.5.0", "ahooks": "^3.4.0", "classnames": "^2.3.0", diff --git a/packages/lb-demo/package.json b/packages/lb-demo/package.json index 1362eb5be..88fd806ca 100644 --- a/packages/lb-demo/package.json +++ b/packages/lb-demo/package.json @@ -3,8 +3,8 @@ "version": "1.9.0", "private": true, "dependencies": { - "@labelbee/lb-annotation": "^1.12.0", - "@labelbee/lb-components": "^1.8.0", + "@labelbee/lb-annotation": "^1.12.1", + "@labelbee/lb-components": "^1.8.1", "@labelbee/lb-utils": "^1.5.0", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", From 91e090e48fe82a99087f8a25c17aa481b830522a Mon Sep 17 00:00:00 2001 From: laoluo Date: Thu, 23 Mar 2023 15:09:22 +0800 Subject: [PATCH 03/41] chore(release): 1.12.1 --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b21164913..5e156a7cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [1.12.1](https://github.com/open-mmlab/labelbee/compare/v1.12.0...v1.12.1) (2023-03-23) + + +### Bug Fixes + +* **view-operation:** Update the range of direction judgement ([943c2b0](https://github.com/open-mmlab/labelbee/commit/943c2b0dbb025c983352f12d16793b508b4c15ce)) + ## [1.12.0](https://github.com/open-mmlab/labelbee/compare/v1.11.0...v1.12.0) (2023-03-09) diff --git a/package.json b/package.json index 6ef81880c..7cb61bd1a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "labelbee", "private": true, - "version": "1.12.0", + "version": "1.12.1", "scripts": { "start": "lerna run build:type && lerna run --parallel --stream start", "start:quick": "lerna run --parallel --stream start", From e9187ef6810e0475ee96c00da542e74aca2c0110 Mon Sep 17 00:00:00 2001 From: laoluo Date: Thu, 23 Mar 2023 15:25:45 +0800 Subject: [PATCH 04/41] chore: Hide unused function --- .../src/components/Annotation/index.jsx | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/lb-demo/src/components/Annotation/index.jsx b/packages/lb-demo/src/components/Annotation/index.jsx index 58c2a5cd0..5c2f56324 100644 --- a/packages/lb-demo/src/components/Annotation/index.jsx +++ b/packages/lb-demo/src/components/Annotation/index.jsx @@ -57,26 +57,26 @@ const Annotation = (props) => { }; }; - const loadFileList = (page, pageSize) => { - return new Promise((resolve) => { - const fileList = []; - const total = 105; - for (let i = 0; i < pageSize; i++) { - if (page * pageSize + i >= total) { - break; - } - fileList.push({ - id: Number(`${page}${i}`), - result: '', - url: urlList[i % urlList.length], - }); - } - console.log('loadFileList', fileList); - setTimeout(() => { - resolve({ fileList, total }); - }, 500); - }); - }; + // const loadFileList = (page, pageSize) => { + // return new Promise((resolve) => { + // const fileList = []; + // const total = 105; + // for (let i = 0; i < pageSize; i++) { + // if (page * pageSize + i >= total) { + // break; + // } + // fileList.push({ + // id: Number(`${page}${i}`), + // result: '', + // url: urlList[i % urlList.length], + // }); + // } + // console.log('loadFileList', fileList); + // setTimeout(() => { + // resolve({ fileList, total }); + // }, 500); + // }); + // }; // const renderEnhance = { // staticRender: (canvas, rect, style) => { From c7b426a6b75b458f4e126cee1df923c44255f5f0 Mon Sep 17 00:00:00 2001 From: lijingchi Date: Thu, 23 Mar 2023 15:57:25 +0800 Subject: [PATCH 05/41] fix(pointcloud): Fix applyCameraTarget not to apply zoom --- packages/lb-annotation/src/core/pointCloud/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/lb-annotation/src/core/pointCloud/index.ts b/packages/lb-annotation/src/core/pointCloud/index.ts index 798897148..d6a484df6 100644 --- a/packages/lb-annotation/src/core/pointCloud/index.ts +++ b/packages/lb-annotation/src/core/pointCloud/index.ts @@ -443,7 +443,7 @@ export class PointCloud { if (camera) { const cameraTarget = this.getOrthographicCameraTarget(camera as OrthographicCamera); - this.camera.zoom = camera.zoom; + this.updateCameraZoom(camera.zoom); this.updateCamera(camera.position, cameraTarget); } }; From f6a0f9eb04f706717c0b8b110f2b7e01ac313be4 Mon Sep 17 00:00:00 2001 From: lijingchi Date: Thu, 23 Mar 2023 16:26:01 +0800 Subject: [PATCH 06/41] chore: Update version --- packages/lb-annotation/package.json | 4 ++-- packages/lb-components/package.json | 6 +++--- packages/lb-demo/package.json | 8 ++++---- packages/lb-utils/package.json | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/lb-annotation/package.json b/packages/lb-annotation/package.json index 6f5f93bb3..649187888 100644 --- a/packages/lb-annotation/package.json +++ b/packages/lb-annotation/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-annotation", - "version": "1.13.0-alpha.1", + "version": "1.13.0-alpha.2", "description": "Annotation tool collection", "keywords": [ "annotation", @@ -92,7 +92,7 @@ "typescript": "^4.2.3" }, "dependencies": { - "@labelbee/lb-utils": "^1.6.0-alpha.1", + "@labelbee/lb-utils": "^1.6.0-alpha.2", "@turf/turf": "5.1.6", "color-rgba": "^2.3.0", "lodash": "^4.17.20", diff --git a/packages/lb-components/package.json b/packages/lb-components/package.json index 508dc2c07..a4257b5fa 100644 --- a/packages/lb-components/package.json +++ b/packages/lb-components/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-components", - "version": "1.9.0-alpha.1", + "version": "1.9.0-alpha.2", "description": "Provide a complete library of annotation components", "main": "./dist/index.js", "es": "./es/index.js", @@ -41,8 +41,8 @@ }, "dependencies": { "@ant-design/icons": "^4.6.2", - "@labelbee/lb-annotation": "^1.13.0-alpha.1", - "@labelbee/lb-utils": "^1.6.0-alpha.1", + "@labelbee/lb-annotation": "^1.13.0-alpha.2", + "@labelbee/lb-utils": "^1.6.0-alpha.2", "ahooks": "^3.4.0", "classnames": "^2.3.0", "lodash": "^4.17.21", diff --git a/packages/lb-demo/package.json b/packages/lb-demo/package.json index 904c3cbcf..8456aab76 100644 --- a/packages/lb-demo/package.json +++ b/packages/lb-demo/package.json @@ -1,11 +1,11 @@ { "name": "lb-demo", - "version": "1.10.1-alpha.0", + "version": "1.10.1-alpha.1", "private": true, "dependencies": { - "@labelbee/lb-annotation": "^1.13.0-alpha.1", - "@labelbee/lb-components": "^1.9.0-alpha.1", - "@labelbee/lb-utils": "^1.6.0-alpha.1", + "@labelbee/lb-annotation": "^1.13.0-alpha.2", + "@labelbee/lb-components": "^1.9.0-alpha.2", + "@labelbee/lb-utils": "^1.6.0-alpha.2", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", diff --git a/packages/lb-utils/package.json b/packages/lb-utils/package.json index 3a8e3a4ac..3e41e8852 100644 --- a/packages/lb-utils/package.json +++ b/packages/lb-utils/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-utils", - "version": "1.6.0-alpha.1", + "version": "1.6.0-alpha.2", "description": "utils for label-bee", "author": "Glenfiddish ", "license": "Apache-2.0", From e90548ab59d716c51f0df44d9ad635090c7e4239 Mon Sep 17 00:00:00 2001 From: Ron-LaoLuo Date: Fri, 24 Mar 2023 08:02:11 +0800 Subject: [PATCH 07/41] chore: Update the github action --- .github/workflows/labelbee-publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/labelbee-publish.yml b/.github/workflows/labelbee-publish.yml index c31ec516e..688ca0d0c 100644 --- a/.github/workflows/labelbee-publish.yml +++ b/.github/workflows/labelbee-publish.yml @@ -3,6 +3,8 @@ name: Publish on: release: types: [published] + push: + branches: ["release", "beta", "alpha"] jobs: publish: From f0c360e4fbffa6b9ecf7bb10dfc3e0a7a5221bc0 Mon Sep 17 00:00:00 2001 From: lijingchi Date: Sun, 26 Mar 2023 12:36:45 +0800 Subject: [PATCH 08/41] feat(pointcloud): Follow top add tooltip --- .../pointCloudView/PointCloud3DView.tsx | 17 ++++++++++------- packages/lb-utils/src/i18n/resources.json | 6 ++++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/lb-components/src/components/pointCloudView/PointCloud3DView.tsx b/packages/lb-components/src/components/pointCloudView/PointCloud3DView.tsx index 8a23f04ef..04b583179 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloud3DView.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloud3DView.tsx @@ -21,7 +21,7 @@ import { a2MapStateToProps, IA2MapStateProps } from '@/store/annotation/map'; import { connect } from 'react-redux'; import { jsonParser } from '@/utils'; import { useSingleBox } from './hooks/useSingleBox'; -import { Switch } from 'antd'; +import { Switch, Tooltip } from 'antd'; import useSize from '@/hooks/useSize'; import { usePointCloudViews } from './hooks/usePointCloudViews'; import { useTranslation } from 'react-i18next'; @@ -66,6 +66,7 @@ const PointCloudViewIcon = ({ const PointCloud3DSideBar = () => { const { reset3DView, followTopView } = useContext(PointCloud3DContext); + const { t } = useTranslation(); return (
@@ -76,12 +77,14 @@ const PointCloud3DSideBar = () => { - { - followTopView(); - }} - className={getClassName('point-cloud-3d-view', 'followTop')} - /> + + { + followTopView(); + }} + className={getClassName('point-cloud-3d-view', 'followTop')} + /> + { diff --git a/packages/lb-utils/src/i18n/resources.json b/packages/lb-utils/src/i18n/resources.json index 57d8faf13..3111047ba 100644 --- a/packages/lb-utils/src/i18n/resources.json +++ b/packages/lb-utils/src/i18n/resources.json @@ -197,7 +197,8 @@ "CancelFixed": "Cancel Fixed", "FixedOnLeft": "Fixed On Left", "FixedOnRight": "Fixed On Right", - "AnnotatedResult": "Annotated Result" + "AnnotatedResult": "Annotated Result", + "CameraFollowTopView": "Positioned by top view" }, "cn": { "TextInput": "文本输入", @@ -397,6 +398,7 @@ "CancelFixed": "取消固定", "FixedOnLeft": "固定在左侧", "FixedOnRight": "固定在右侧", - "AnnotatedResult": "标注结果" + "AnnotatedResult": "标注结果", + "CameraFollowTopView": "按俯视图定位" } } From cf2d147005911fb58c497e1e25b0bc4675fc61af Mon Sep 17 00:00:00 2001 From: lijingchi Date: Sun, 26 Mar 2023 14:04:56 +0800 Subject: [PATCH 09/41] fix(pointcloud): Prevent default event on ctrl + a --- .../src/components/pointCloudView/PointCloudListener.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/lb-components/src/components/pointCloudView/PointCloudListener.tsx b/packages/lb-components/src/components/pointCloudView/PointCloudListener.tsx index 8d37880d9..d96bf73c5 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloudListener.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloudListener.tsx @@ -182,6 +182,7 @@ const PointCloudListener: React.FC = ({ pasteSelectedBoxes(); break; case 'a': + e.preventDefault(); ptCtx.selectedAllBoxes(); break; case 'z': { From f940e42d16f66394469e2b46264937418d136856 Mon Sep 17 00:00:00 2001 From: lijingchi Date: Sun, 26 Mar 2023 14:05:36 +0800 Subject: [PATCH 10/41] fix(pointcloud): Fix size changed and init point cloud result --- .../pointCloudView/PointCloud3DView.tsx | 15 ++++--- packages/lb-components/src/index.scss | 1 + .../toolFooter/AnnotatedAttributes/index.tsx | 44 +++++++++++-------- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/packages/lb-components/src/components/pointCloudView/PointCloud3DView.tsx b/packages/lb-components/src/components/pointCloudView/PointCloud3DView.tsx index 04b583179..f1058b892 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloud3DView.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloud3DView.tsx @@ -131,9 +131,6 @@ const PointCloud3D: React.FC = ({ currentData, config }) => { } }; - /** - * Listen for data changes. - */ useEffect(() => { if (ref.current && currentData?.url) { let pointCloud = ptCtx.mainViewInstance; @@ -156,8 +153,16 @@ const PointCloud3D: React.FC = ({ currentData, config }) => { }); ptCtx.setMainViewInstance(pointCloud); } + } + }, [size]); - if (currentData.result) { + /** + * Listen for data changes. + */ + useEffect(() => { + if (ref.current && currentData?.url) { + if (currentData.result && ptCtx.mainViewInstance) { + let pointCloud = ptCtx.mainViewInstance; const boxParamsList = PointCloudUtils.getBoxParamsFromResultList(currentData.result); // Add Init Box @@ -175,7 +180,7 @@ const PointCloud3D: React.FC = ({ currentData, config }) => { ptCtx.setPointCloudValid(jsonParser(currentData.result)?.valid); } } - }, [currentData, size]); + }, [currentData, ptCtx.mainViewInstance]); /** * Observe selectedID and reset camera to target top-view diff --git a/packages/lb-components/src/index.scss b/packages/lb-components/src/index.scss index 116588536..35d12c4dd 100644 --- a/packages/lb-components/src/index.scss +++ b/packages/lb-components/src/index.scss @@ -1253,6 +1253,7 @@ $hotkey-container-padding: 7px; .#{$prefix}-annotated-attribute { width: 240px; background: white; + padding-bottom: 12px; &__popover .ant-popover-inner-content { padding: 0; diff --git a/packages/lb-components/src/views/MainView/toolFooter/AnnotatedAttributes/index.tsx b/packages/lb-components/src/views/MainView/toolFooter/AnnotatedAttributes/index.tsx index 284daf71e..1a842b9c4 100644 --- a/packages/lb-components/src/views/MainView/toolFooter/AnnotatedAttributes/index.tsx +++ b/packages/lb-components/src/views/MainView/toolFooter/AnnotatedAttributes/index.tsx @@ -1,6 +1,6 @@ import { PointCloudContext } from '@/components/pointCloudView/PointCloudContext'; import { Modal } from 'antd'; -import React, { useContext, useState } from 'react'; +import React, { useContext, useMemo, useState } from 'react'; import { stepConfigSelector } from '@/store/annotation/selectors'; import { useSelector } from '@/store/ctx'; import { i18n, IPointCloudConfig } from '@labelbee/lb-utils'; @@ -22,7 +22,6 @@ import FooterPopover from '../FooterPopover'; const AnnotatedAttributesItem = ({ attribute }: { attribute: IInputList }) => { const pointCloudCtx = useContext(PointCloudContext); - const { t } = useTranslation(); const { pointCloudBoxList, hideAttributes, @@ -33,7 +32,7 @@ const AnnotatedAttributesItem = ({ attribute }: { attribute: IInputList }) => { reRender, } = pointCloudCtx; - const [expanded, setExpanded] = useState(false); + const [expanded, setExpanded] = useState(true); const { pushHistoryWithList } = useHistory(); @@ -102,26 +101,33 @@ const AnnotatedAttributesItem = ({ attribute }: { attribute: IInputList }) => {
{expanded && - (pointCloudListForSpecAttribute.length > 0 ? ( - pointCloudListForSpecAttribute.map((box) => { - return ( -
- {`${getBoxID(box)}.${attribute.key}`} -
- ); - }) - ) : ( -
{t('NoData')}
- ))} + pointCloudListForSpecAttribute.map((box) => { + return ( +
+ {`${getBoxID(box)}.${attribute.key}`} +
+ ); + })} ); }; export const AnnotatedAttributesPanel = () => { const stepConfig: IPointCloudConfig = useSelector(stepConfigSelector); - const { attrPanelLayout, setAttrPanelLayout } = useContext(PointCloudContext); + const { attrPanelLayout, setAttrPanelLayout, pointCloudBoxList, polygonList } = + useContext(PointCloudContext); const { t } = useTranslation(); + const existAttributes = useMemo(() => { + return [...pointCloudBoxList, ...polygonList].map((i) => i.attribute); + }, [pointCloudBoxList, polygonList]); + + const displayAttrList = useMemo(() => { + return (stepConfig.attributeList as IInputList[]).filter((i) => + existAttributes.includes(i.value), + ); + }, [existAttributes]); + return (
{attrPanelLayout ? ( @@ -161,9 +167,11 @@ export const AnnotatedAttributesPanel = () => { )}
- {stepConfig.attributeList.map((i) => ( - - ))} + {displayAttrList.length > 0 ? ( + displayAttrList.map((i) => ) + ) : ( +
{t('NoData')}
+ )}
); From 2e79e5bbe864685517aa87fc87fe7c26ea56744c Mon Sep 17 00:00:00 2001 From: lijingchi Date: Sun, 26 Mar 2023 15:26:02 +0800 Subject: [PATCH 11/41] chore: Update version --- packages/lb-annotation/package.json | 4 ++-- packages/lb-components/package.json | 6 +++--- packages/lb-demo/package.json | 8 ++++---- packages/lb-utils/package.json | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/lb-annotation/package.json b/packages/lb-annotation/package.json index 649187888..4094f856e 100644 --- a/packages/lb-annotation/package.json +++ b/packages/lb-annotation/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-annotation", - "version": "1.13.0-alpha.2", + "version": "1.13.0-alpha.3", "description": "Annotation tool collection", "keywords": [ "annotation", @@ -92,7 +92,7 @@ "typescript": "^4.2.3" }, "dependencies": { - "@labelbee/lb-utils": "^1.6.0-alpha.2", + "@labelbee/lb-utils": "^1.6.0-alpha.3", "@turf/turf": "5.1.6", "color-rgba": "^2.3.0", "lodash": "^4.17.20", diff --git a/packages/lb-components/package.json b/packages/lb-components/package.json index a4257b5fa..4e6c3e9bb 100644 --- a/packages/lb-components/package.json +++ b/packages/lb-components/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-components", - "version": "1.9.0-alpha.2", + "version": "1.9.0-alpha.3", "description": "Provide a complete library of annotation components", "main": "./dist/index.js", "es": "./es/index.js", @@ -41,8 +41,8 @@ }, "dependencies": { "@ant-design/icons": "^4.6.2", - "@labelbee/lb-annotation": "^1.13.0-alpha.2", - "@labelbee/lb-utils": "^1.6.0-alpha.2", + "@labelbee/lb-annotation": "^1.13.0-alpha.3", + "@labelbee/lb-utils": "^1.6.0-alpha.3", "ahooks": "^3.4.0", "classnames": "^2.3.0", "lodash": "^4.17.21", diff --git a/packages/lb-demo/package.json b/packages/lb-demo/package.json index 8456aab76..a188a8443 100644 --- a/packages/lb-demo/package.json +++ b/packages/lb-demo/package.json @@ -1,11 +1,11 @@ { "name": "lb-demo", - "version": "1.10.1-alpha.1", + "version": "1.10.1-alpha.2", "private": true, "dependencies": { - "@labelbee/lb-annotation": "^1.13.0-alpha.2", - "@labelbee/lb-components": "^1.9.0-alpha.2", - "@labelbee/lb-utils": "^1.6.0-alpha.2", + "@labelbee/lb-annotation": "^1.13.0-alpha.3", + "@labelbee/lb-components": "^1.9.0-alpha.3", + "@labelbee/lb-utils": "^1.6.0-alpha.3", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", diff --git a/packages/lb-utils/package.json b/packages/lb-utils/package.json index 3e41e8852..b2491e0cf 100644 --- a/packages/lb-utils/package.json +++ b/packages/lb-utils/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-utils", - "version": "1.6.0-alpha.2", + "version": "1.6.0-alpha.3", "description": "utils for label-bee", "author": "Glenfiddish ", "license": "Apache-2.0", From 05228c5c66bb73166e486b51bab151e204176687 Mon Sep 17 00:00:00 2001 From: lijingchi Date: Mon, 27 Mar 2023 16:22:45 +0800 Subject: [PATCH 12/41] feat(pointcloud): Support select spec attribute boxes --- .../components/pointCloudView/PointCloudContext.tsx | 7 +++++++ packages/lb-components/src/index.scss | 1 + .../MainView/toolFooter/AnnotatedAttributes/index.tsx | 10 +++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/lb-components/src/components/pointCloudView/PointCloudContext.tsx b/packages/lb-components/src/components/pointCloudView/PointCloudContext.tsx index 922325c38..b468af531 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloudContext.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloudContext.tsx @@ -55,6 +55,7 @@ export interface IPointCloudContext extends IPointCloudContextInstances { pointCloudPattern: EToolName.Rect | EToolName.Polygon; setPointCloudPattern: (toolName: EToolName.Rect | EToolName.Polygon) => void; + selectSpecAttr: (attr: string) => void; } export const PointCloudContext = React.createContext({ @@ -94,6 +95,7 @@ export const PointCloudContext = React.createContext({ pointCloudPattern: EToolName.Rect, setPointCloudPattern: () => {}, + selectSpecAttr: () => {}, }); export const PointCloudProvider: React.FC<{}> = ({ children }) => { @@ -162,6 +164,10 @@ export const PointCloudProvider: React.FC<{}> = ({ children }) => { setSelectedIDs(pointCloudBoxList.map((i) => i.id)); }; + const selectSpecAttr = (attr: string) => { + setSelectedIDs(pointCloudBoxList.filter((i) => i.attribute === attr).map((i) => i.id)); + }; + const displayPointCloudList = pointCloudBoxList.filter( (i) => !hideAttributes.includes(i.attribute), ); @@ -245,6 +251,7 @@ export const PointCloudProvider: React.FC<{}> = ({ children }) => { setDefaultAttribute, pointCloudPattern, setPointCloudPattern, + selectSpecAttr, }; }, [ valid, diff --git a/packages/lb-components/src/index.scss b/packages/lb-components/src/index.scss index 35d12c4dd..d900d7f51 100644 --- a/packages/lb-components/src/index.scss +++ b/packages/lb-components/src/index.scss @@ -1272,6 +1272,7 @@ $hotkey-container-padding: 7px; justify-content: space-between; padding: 8px 12px; color: #333; + cursor: pointer; } &__item { diff --git a/packages/lb-components/src/views/MainView/toolFooter/AnnotatedAttributes/index.tsx b/packages/lb-components/src/views/MainView/toolFooter/AnnotatedAttributes/index.tsx index 1a842b9c4..bac70ff75 100644 --- a/packages/lb-components/src/views/MainView/toolFooter/AnnotatedAttributes/index.tsx +++ b/packages/lb-components/src/views/MainView/toolFooter/AnnotatedAttributes/index.tsx @@ -30,6 +30,7 @@ const AnnotatedAttributesItem = ({ attribute }: { attribute: IInputList }) => { setPolygonList, setPointCloudResult, reRender, + selectSpecAttr, } = pointCloudCtx; const [expanded, setExpanded] = useState(true); @@ -95,7 +96,14 @@ const AnnotatedAttributesItem = ({ attribute }: { attribute: IInputList }) => { setExpanded(!expanded); }} /> - {attribute.key} + { + selectSpecAttr(attribute.value); + }} + > + {attribute.key} + onDeleteGraphByAttr(attribute)} /> From 9a348d54c0c974d871839d71271cc2f91249a4c3 Mon Sep 17 00:00:00 2001 From: lijingchi Date: Mon, 27 Mar 2023 16:23:50 +0800 Subject: [PATCH 13/41] chore: Update version --- packages/lb-annotation/package.json | 4 ++-- packages/lb-components/package.json | 6 +++--- packages/lb-demo/package.json | 8 ++++---- packages/lb-utils/package.json | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/lb-annotation/package.json b/packages/lb-annotation/package.json index 4094f856e..7d188410d 100644 --- a/packages/lb-annotation/package.json +++ b/packages/lb-annotation/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-annotation", - "version": "1.13.0-alpha.3", + "version": "1.13.0-alpha.4", "description": "Annotation tool collection", "keywords": [ "annotation", @@ -92,7 +92,7 @@ "typescript": "^4.2.3" }, "dependencies": { - "@labelbee/lb-utils": "^1.6.0-alpha.3", + "@labelbee/lb-utils": "^1.6.0-alpha.4", "@turf/turf": "5.1.6", "color-rgba": "^2.3.0", "lodash": "^4.17.20", diff --git a/packages/lb-components/package.json b/packages/lb-components/package.json index 4e6c3e9bb..0b710ef57 100644 --- a/packages/lb-components/package.json +++ b/packages/lb-components/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-components", - "version": "1.9.0-alpha.3", + "version": "1.9.0-alpha.4", "description": "Provide a complete library of annotation components", "main": "./dist/index.js", "es": "./es/index.js", @@ -41,8 +41,8 @@ }, "dependencies": { "@ant-design/icons": "^4.6.2", - "@labelbee/lb-annotation": "^1.13.0-alpha.3", - "@labelbee/lb-utils": "^1.6.0-alpha.3", + "@labelbee/lb-annotation": "^1.13.0-alpha.4", + "@labelbee/lb-utils": "^1.6.0-alpha.4", "ahooks": "^3.4.0", "classnames": "^2.3.0", "lodash": "^4.17.21", diff --git a/packages/lb-demo/package.json b/packages/lb-demo/package.json index a188a8443..a10a1fabb 100644 --- a/packages/lb-demo/package.json +++ b/packages/lb-demo/package.json @@ -1,11 +1,11 @@ { "name": "lb-demo", - "version": "1.10.1-alpha.2", + "version": "1.10.1-alpha.3", "private": true, "dependencies": { - "@labelbee/lb-annotation": "^1.13.0-alpha.3", - "@labelbee/lb-components": "^1.9.0-alpha.3", - "@labelbee/lb-utils": "^1.6.0-alpha.3", + "@labelbee/lb-annotation": "^1.13.0-alpha.4", + "@labelbee/lb-components": "^1.9.0-alpha.4", + "@labelbee/lb-utils": "^1.6.0-alpha.4", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", diff --git a/packages/lb-utils/package.json b/packages/lb-utils/package.json index b2491e0cf..6004f9be7 100644 --- a/packages/lb-utils/package.json +++ b/packages/lb-utils/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-utils", - "version": "1.6.0-alpha.3", + "version": "1.6.0-alpha.4", "description": "utils for label-bee", "author": "Glenfiddish ", "license": "Apache-2.0", From 8a28ad8822f52613823740234d97bf0b616d8186 Mon Sep 17 00:00:00 2001 From: laoluo Date: Mon, 27 Mar 2023 16:54:36 +0800 Subject: [PATCH 14/41] chore(lb-demo): Update the script of build --- packages/lb-demo/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/lb-demo/package.json b/packages/lb-demo/package.json index a10a1fabb..2bcd810ce 100644 --- a/packages/lb-demo/package.json +++ b/packages/lb-demo/package.json @@ -21,7 +21,7 @@ "scripts": { "start": "react-scripts start", "dev": "npm run start", - "build": "react-scripts build", + "build:frontend": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, From 26b30624c23267deb262417d4a103c71dee90f7d Mon Sep 17 00:00:00 2001 From: laoluo Date: Mon, 27 Mar 2023 20:16:27 +0800 Subject: [PATCH 15/41] fix(pointcloud): Fix the feature of COPY_BACKWARD_RESULT --- .../pointCloudView/PointCloudListener.tsx | 8 ++++++++ .../pointCloudView/hooks/usePointCloudViews.ts | 16 ++++++++-------- .../src/store/annotation/reducer.ts | 5 +++++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/packages/lb-components/src/components/pointCloudView/PointCloudListener.tsx b/packages/lb-components/src/components/pointCloudView/PointCloudListener.tsx index d96bf73c5..d66a5682d 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloudListener.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloudListener.tsx @@ -18,6 +18,7 @@ import { ICoordinate } from '@labelbee/lb-utils/dist/types/types/common'; import { useConfig } from './hooks/useConfig'; import { usePolygon } from './hooks/usePolygon'; import { useTranslation } from 'react-i18next'; +import { IFileItem } from '@/types/data'; const { EPolygonPattern } = cTool; @@ -329,6 +330,13 @@ const PointCloudListener: React.FC = ({ toolInstanceRef.current.setShowDefaultCursor = (showDefaultCursor: boolean) => { ptCtx.topViewInstance?.pointCloud2dOperation?.setShowDefaultCursor(showDefaultCursor); }; + + toolInstanceRef.current.asyncData = (newData: IFileItem) => { + // Next Tick to update. + setTimeout(() => { + updatePointCloudData?.(newData); + }); + }; }, [ ptCtx.pointCloudBoxList, ptCtx.selectedID, diff --git a/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts b/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts index 14b12e5ee..11ddbe825 100644 --- a/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts +++ b/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts @@ -678,13 +678,13 @@ export const usePointCloudViews = () => { * Update the data of pointCloudView when the page change. * @returns */ - const updatePointCloudData = async () => { - if (!currentData?.url || !mainViewInstance) { + const updatePointCloudData = async (newData = currentData) => { + if (!newData?.url || !mainViewInstance) { return; } SetPointCloudLoading(dispatch, true); - await mainViewInstance.loadPCDFile(currentData.url, config?.radius ?? DEFAULT_RADIUS); + await mainViewInstance.loadPCDFile(newData.url, config?.radius ?? DEFAULT_RADIUS); // Clear All Data pointCloudBoxList.forEach((v) => { @@ -693,9 +693,9 @@ export const usePointCloudViews = () => { let boxParamsList: any[] = []; let polygonList = []; - if (currentData.result) { - boxParamsList = PointCloudUtils.getBoxParamsFromResultList(currentData.result); - polygonList = PointCloudUtils.getPolygonListFromResultList(currentData.result); + if (newData.result) { + boxParamsList = PointCloudUtils.getBoxParamsFromResultList(newData.result); + polygonList = PointCloudUtils.getPolygonListFromResultList(newData.result); // Add Init Box boxParamsList.forEach((v: IPointCloudBox) => { @@ -713,7 +713,7 @@ export const usePointCloudViews = () => { mainViewInstance.updateTopCamera(); - const valid = jsonParser(currentData.result)?.valid ?? true; + const valid = jsonParser(newData.result)?.valid ?? true; ptCtx.setPointCloudValid(valid); // Clear other view data during initialization @@ -727,7 +727,7 @@ export const usePointCloudViews = () => { * 2. Reload PointCloud * 3. Clear Polygon */ - topViewInstance.updateData(currentData.url, currentData.result, { + topViewInstance.updateData(newData.url, newData.result, { radius: config?.radius ?? DEFAULT_RADIUS, }); SetPointCloudLoading(dispatch, false); diff --git a/packages/lb-components/src/store/annotation/reducer.ts b/packages/lb-components/src/store/annotation/reducer.ts index b27a752c5..234c404c7 100644 --- a/packages/lb-components/src/store/annotation/reducer.ts +++ b/packages/lb-components/src/store/annotation/reducer.ts @@ -699,6 +699,11 @@ export const annotationReducer = ( toolInstance?.setResult(result); toolInstance?.history.pushHistory(result); + /** + * Async PointCloud Data. + */ + // @ts-ignore + toolInstance?.asyncData(imgList[imgIndex]); return { ...state, imgList: [...imgList], From d35c00ab722d16881106f45dc1cbcbb6257687a8 Mon Sep 17 00:00:00 2001 From: lijingchi Date: Tue, 28 Mar 2023 14:59:59 +0800 Subject: [PATCH 16/41] ci: Add prerelease command --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 7cb61bd1a..7fbb7fcef 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "version": "lerna version --conventional-graduate --yes", "publish": "lerna publish from-package --yes", "commit": "cz", - "release": "standard-version" + "release": "standard-version", + "prerelease": "lerna version prerelease --conventional-graduate --yes" }, "main": "index.js", "license": "Apache-2.0", From 4b65cf4fc97a570f3e73b7654450e334b8210a4e Mon Sep 17 00:00:00 2001 From: lijingchi Date: Tue, 28 Mar 2023 15:07:18 +0800 Subject: [PATCH 17/41] chore: Update version --- packages/lb-annotation/package.json | 4 ++-- packages/lb-components/package.json | 6 +++--- packages/lb-demo/package.json | 8 ++++---- packages/lb-utils/package.json | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/lb-annotation/package.json b/packages/lb-annotation/package.json index 7d188410d..d24b396a8 100644 --- a/packages/lb-annotation/package.json +++ b/packages/lb-annotation/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-annotation", - "version": "1.13.0-alpha.4", + "version": "1.13.0-alpha.5", "description": "Annotation tool collection", "keywords": [ "annotation", @@ -92,7 +92,7 @@ "typescript": "^4.2.3" }, "dependencies": { - "@labelbee/lb-utils": "^1.6.0-alpha.4", + "@labelbee/lb-utils": "^1.6.0-alpha.5", "@turf/turf": "5.1.6", "color-rgba": "^2.3.0", "lodash": "^4.17.20", diff --git a/packages/lb-components/package.json b/packages/lb-components/package.json index 0b710ef57..1a40d5335 100644 --- a/packages/lb-components/package.json +++ b/packages/lb-components/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-components", - "version": "1.9.0-alpha.4", + "version": "1.9.0-alpha.5", "description": "Provide a complete library of annotation components", "main": "./dist/index.js", "es": "./es/index.js", @@ -41,8 +41,8 @@ }, "dependencies": { "@ant-design/icons": "^4.6.2", - "@labelbee/lb-annotation": "^1.13.0-alpha.4", - "@labelbee/lb-utils": "^1.6.0-alpha.4", + "@labelbee/lb-annotation": "^1.13.0-alpha.5", + "@labelbee/lb-utils": "^1.6.0-alpha.5", "ahooks": "^3.4.0", "classnames": "^2.3.0", "lodash": "^4.17.21", diff --git a/packages/lb-demo/package.json b/packages/lb-demo/package.json index 2bcd810ce..c46eaf00e 100644 --- a/packages/lb-demo/package.json +++ b/packages/lb-demo/package.json @@ -1,11 +1,11 @@ { "name": "lb-demo", - "version": "1.10.1-alpha.3", + "version": "1.10.1-alpha.4", "private": true, "dependencies": { - "@labelbee/lb-annotation": "^1.13.0-alpha.4", - "@labelbee/lb-components": "^1.9.0-alpha.4", - "@labelbee/lb-utils": "^1.6.0-alpha.4", + "@labelbee/lb-annotation": "^1.13.0-alpha.5", + "@labelbee/lb-components": "^1.9.0-alpha.5", + "@labelbee/lb-utils": "^1.6.0-alpha.5", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", diff --git a/packages/lb-utils/package.json b/packages/lb-utils/package.json index 6004f9be7..6434fedf4 100644 --- a/packages/lb-utils/package.json +++ b/packages/lb-utils/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-utils", - "version": "1.6.0-alpha.4", + "version": "1.6.0-alpha.5", "description": "utils for label-bee", "author": "Glenfiddish ", "license": "Apache-2.0", From 17dc99a7633e01541650e948d7eeb436a83c1691 Mon Sep 17 00:00:00 2001 From: laoluo Date: Wed, 29 Mar 2023 14:23:17 +0800 Subject: [PATCH 18/41] fix(copy-result): AsyncData needs to determine if it exists --- packages/lb-components/src/store/annotation/reducer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/lb-components/src/store/annotation/reducer.ts b/packages/lb-components/src/store/annotation/reducer.ts index 234c404c7..0fe311131 100644 --- a/packages/lb-components/src/store/annotation/reducer.ts +++ b/packages/lb-components/src/store/annotation/reducer.ts @@ -703,7 +703,7 @@ export const annotationReducer = ( * Async PointCloud Data. */ // @ts-ignore - toolInstance?.asyncData(imgList[imgIndex]); + toolInstance?.asyncData?.(imgList[imgIndex]); return { ...state, imgList: [...imgList], From a12901e208bed684561ede01d154195a9c7a5680 Mon Sep 17 00:00:00 2001 From: laoluo Date: Wed, 29 Mar 2023 15:33:11 +0800 Subject: [PATCH 19/41] feat(pointcloud): Hide the operation in checkmode(side&backView) --- .../lb-components/src/components/pointCloudView/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/lb-components/src/components/pointCloudView/index.tsx b/packages/lb-components/src/components/pointCloudView/index.tsx index 9c3438494..0bc3c5fa6 100644 --- a/packages/lb-components/src/components/pointCloudView/index.tsx +++ b/packages/lb-components/src/components/pointCloudView/index.tsx @@ -56,8 +56,8 @@ const PointCloudView: React.FC = ({ imgList, drawLayerSlot, checkMode })
- - + +
From 17c60b81d403c9a179f945a5f9003c2688423a65 Mon Sep 17 00:00:00 2001 From: laoluo Date: Wed, 29 Mar 2023 15:36:24 +0800 Subject: [PATCH 20/41] chore(lb-components): Update the version --- packages/lb-components/package.json | 2 +- packages/lb-demo/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/lb-components/package.json b/packages/lb-components/package.json index 1a40d5335..522cbc7de 100644 --- a/packages/lb-components/package.json +++ b/packages/lb-components/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-components", - "version": "1.9.0-alpha.5", + "version": "1.9.0-alpha.6", "description": "Provide a complete library of annotation components", "main": "./dist/index.js", "es": "./es/index.js", diff --git a/packages/lb-demo/package.json b/packages/lb-demo/package.json index c46eaf00e..e938b3cfc 100644 --- a/packages/lb-demo/package.json +++ b/packages/lb-demo/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@labelbee/lb-annotation": "^1.13.0-alpha.5", - "@labelbee/lb-components": "^1.9.0-alpha.5", + "@labelbee/lb-components": "^1.9.0-alpha.6", "@labelbee/lb-utils": "^1.6.0-alpha.5", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", From df3d850ac379ff8f4516ceda3b0d2f130769cab5 Mon Sep 17 00:00:00 2001 From: lihqi <455711093@qq.com> Date: Tue, 4 Apr 2023 17:05:22 +0800 Subject: [PATCH 21/41] feat(pointcloud): Add predict tracking actions and reducers --- packages/lb-components/src/store/Actions.ts | 5 +++ .../src/store/annotation/actionCreators.ts | 35 +++++++++++++++++++ .../src/store/annotation/reducer.ts | 25 +++++++++++++ 3 files changed, 65 insertions(+) diff --git a/packages/lb-components/src/store/Actions.ts b/packages/lb-components/src/store/Actions.ts index 98b469c33..8768718df 100644 --- a/packages/lb-components/src/store/Actions.ts +++ b/packages/lb-components/src/store/Actions.ts @@ -38,6 +38,11 @@ export const ANNOTATION_ACTIONS = { BATCH_UPDATE_TRACK_ID: '@@BATCH_UPDATE_TRACK_ID', BATCH_UPDATE_RESULT_BY_TRACK_ID: '@@BATCH_UPDATE_RESULT_BY_TRACK_ID', + + BATCH_UPDATE_IMG_LIST_RESULT: '@@BATCH_UPDATE_IMG_LIST_RESULT', + + SET_PREDICT_RESULT_VISIBLE: '@@SET_PREDICT_RESULT_VISIBLE', + SET_PREDICT_RESULT: '@@SET_PREDICT_RESULT', }; export const IMAGE_ATTRIBUTE_ACTIONS = { diff --git a/packages/lb-components/src/store/annotation/actionCreators.ts b/packages/lb-components/src/store/annotation/actionCreators.ts index bb5a5b15f..e8bcb236c 100644 --- a/packages/lb-components/src/store/annotation/actionCreators.ts +++ b/packages/lb-components/src/store/annotation/actionCreators.ts @@ -16,6 +16,7 @@ import { EPageTurningOperation } from '@/data/enums/AnnotationSize'; import PageOperator from '@/utils/PageOperator'; import { jsonParser } from '@/utils'; import { IPointCloudBox } from '@labelbee/lb-utils'; +import { getBoxesByTrackID } from '@/components/predictTracking/previewResult/util'; const dispatchTasks = (dispatch: any, tasks: any[]) => tasks.map((task) => dispatch(task)); @@ -237,6 +238,15 @@ export function BatchUpdateResultByTrackID( }; } +export function BatchUpdateImgListResult(nextImgList: any): AnnotationActionTypes { + return { + type: ANNOTATION_ACTIONS.BATCH_UPDATE_IMG_LIST_RESULT, + payload: { + nextImgList, + }, + }; +} + export const UpdateCheckMode = (checkMode: boolean): AnnotationActionTypes => { return { type: ANNOTATION_ACTIONS.SET_CHECK_MODE, @@ -614,3 +624,28 @@ export const InitAnnotationState = (dispatch: Function) => { payload: {}, }); }; + +export const SetPredictResult = (dispatch: Function, result: any) => { + dispatch({ + type: ANNOTATION_ACTIONS.SET_PREDICT_RESULT, + payload: { + result, + }, + }); +}; + +export const SetPredictResultVisible = (dispatch: Function, visible: boolean) => { + dispatch({ + type: ANNOTATION_ACTIONS.SET_PREDICT_RESULT_VISIBLE, + payload: { + visible, + }, + }); +}; + +export const GetBoxesByID = + (selectedBoxTrackID: number) => + (dispatch: any, getState: any): IPointCloudBox[] => { + const { imgList, step } = getState().annotation; + return getBoxesByTrackID(imgList, step, selectedBoxTrackID); + }; diff --git a/packages/lb-components/src/store/annotation/reducer.ts b/packages/lb-components/src/store/annotation/reducer.ts index b27a752c5..8a4b20108 100644 --- a/packages/lb-components/src/store/annotation/reducer.ts +++ b/packages/lb-components/src/store/annotation/reducer.ts @@ -40,6 +40,8 @@ const initialState: AnnotationState = { pointCloudLoading: false, checkMode: false, + predictionResult: [], + predictionResultVisible: false, }; /** @@ -581,6 +583,20 @@ export const annotationReducer = ( }; } + case ANNOTATION_ACTIONS.SET_PREDICT_RESULT: { + return { + ...state, + predictionResult: action.payload.result, + }; + } + + case ANNOTATION_ACTIONS.SET_PREDICT_RESULT_VISIBLE: { + return { + ...state, + predictionResultVisible: action.payload.visible, + }; + } + case ANNOTATION_ACTIONS.UPDATE_ON_STEP_CHANGE: { return { ...state, @@ -820,6 +836,15 @@ export const annotationReducer = ( }; } + case ANNOTATION_ACTIONS.BATCH_UPDATE_IMG_LIST_RESULT: { + const { nextImgList } = action.payload; + + return { + ...state, + imgList: nextImgList, + }; + } + // eslint-disable-next-line no-fallthrough default: return state; From 0be69d7a307ebf28f81e9e1febbff619ccf96b53 Mon Sep 17 00:00:00 2001 From: lihqi <455711093@qq.com> Date: Tue, 4 Apr 2023 17:09:55 +0800 Subject: [PATCH 22/41] feat(pointcloud): Add predict tracking features and styles --- .../src/assets/predictTracking/icon.svg | 20 +++ .../predictTrackingIcon/index.tsx | 90 +++++++++++ .../predictTracking/previewResult/util.ts | 142 ++++++++++++++++++ packages/lb-components/src/index.scss | 93 +++++++++++- packages/lb-components/src/index.tsx | 3 +- .../src/store/annotation/types.ts | 17 ++- .../src/views/MainView/toolHeader/index.tsx | 12 +- 7 files changed, 366 insertions(+), 11 deletions(-) create mode 100644 packages/lb-components/src/assets/predictTracking/icon.svg create mode 100644 packages/lb-components/src/components/predictTracking/predictTrackingIcon/index.tsx create mode 100644 packages/lb-components/src/components/predictTracking/previewResult/util.ts diff --git a/packages/lb-components/src/assets/predictTracking/icon.svg b/packages/lb-components/src/assets/predictTracking/icon.svg new file mode 100644 index 000000000..02ada3d40 --- /dev/null +++ b/packages/lb-components/src/assets/predictTracking/icon.svg @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/packages/lb-components/src/components/predictTracking/predictTrackingIcon/index.tsx b/packages/lb-components/src/components/predictTracking/predictTrackingIcon/index.tsx new file mode 100644 index 000000000..d360e4c78 --- /dev/null +++ b/packages/lb-components/src/components/predictTracking/predictTrackingIcon/index.tsx @@ -0,0 +1,90 @@ +import { Button, message } from 'antd'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { connect } from 'react-redux'; + +import icon from '@/assets/predictTracking/icon.svg'; +import { useSingleBox } from '@/components/pointCloudView/hooks/useSingleBox'; +import { AppState } from '@/store'; +import { + ChangeSave, GetBoxesByID, SetPointCloudLoading, SetPredictResult, SetPredictResultVisible +} from '@/store/annotation/actionCreators'; +import { LabelBeeContext, useDispatch } from '@/store/ctx'; + +import { predict } from '../previewResult/util'; + +const PredictTrackingIcon = (props: { loading: boolean }) => { + const dispatch = useDispatch(); + const { t } = useTranslation(); + + const { loading } = props; + const { selectedBox } = useSingleBox(); + + const handler = async () => { + if (loading) { + return; + } + + const selectedBoxTrackID = selectedBox?.info.trackID; + + if (!selectedBoxTrackID) { + message.error('未找到当前标注框ID'); + return; + } + + await dispatch(ChangeSave); + + const boxes: any = await dispatch(GetBoxesByID(selectedBoxTrackID)); + + if (boxes.length < 2) { + message.error('请至少标记两个目标'); + return; + } + + const start = boxes[boxes.length - 2]; + const end = boxes[boxes.length - 1]; + + const difference = end.index - start.index; + + if (difference < 2) { + message.error('不需要进行补全'); + return; + } + + if (difference > 8) { + message.error('需要补全的数据不能大于10个'); + return; + } + + SetPointCloudLoading(dispatch, true); + const result = predict(start, end); + SetPredictResult(dispatch, result); + SetPredictResultVisible(dispatch, true); + }; + + return ( + + ); +}; + +const mapStateToProps = (state: AppState) => { + return { + loading: state.annotation.loading, + }; +}; + +export default connect(mapStateToProps, null, null, { context: LabelBeeContext })( + PredictTrackingIcon, +); diff --git a/packages/lb-components/src/components/predictTracking/previewResult/util.ts b/packages/lb-components/src/components/predictTracking/previewResult/util.ts new file mode 100644 index 000000000..a1f6e9401 --- /dev/null +++ b/packages/lb-components/src/components/predictTracking/previewResult/util.ts @@ -0,0 +1,142 @@ +import { IPointCloudBoxWithIndex } from '@/store/annotation/types'; +import { IFileItem } from '@/types/data'; +import { jsonParser } from '@/utils'; +import { PointCloud, uuid } from '@labelbee/lb-annotation'; +import { EPerspectiveView, IPointCloudBox } from '@labelbee/lb-utils'; + +const getDataUrl = async (renderer: PointCloud['renderer'], zoom = 2) => { + return cropAndEnlarge(renderer.domElement, 160, 110, zoom); +}; + +export const sleep = (time = 300) => { + return new Promise((resolve) => { + setTimeout(() => { + resolve(''); + }, time); + }); +}; + +export const views: [EPerspectiveView.Top, EPerspectiveView.Left, EPerspectiveView.Back] = [ + EPerspectiveView.Top, + EPerspectiveView.Left, + EPerspectiveView.Back, +]; + +interface viewDataUrl { + [EPerspectiveView.Top]?: string; + [EPerspectiveView.Left]?: string; + [EPerspectiveView.Back]?: string; +} + +export type IBox = IPointCloudBoxWithIndex & viewDataUrl; + +export const getViewsDataUrl = async (pointCloud: PointCloud, box: IBox, zoom: number) => { + for (const view of views) { + await pointCloud.updateCameraByBox(box, view); + box[view] = await getDataUrl(pointCloud.renderer, zoom); + } +}; + +const cropAndEnlarge = ( + canvas: HTMLCanvasElement, + width: number, + height: number, + scale: number, +): string => { + if (!canvas) { + return ''; + } + const centerX = canvas.width / 2; + const centerY = canvas.height / 2; + // Calculate starting coordinates for cropping + const sx = centerX - width / 2; + const sy = centerY - height / 2; + + // Create a new canvas for the cropped and enlarged image + const newCanvas = document.createElement('canvas'); + newCanvas.width = width * scale; + newCanvas.height = height * scale; + + // Draw the cropped and enlarged image onto the new canvas + const newCtx = newCanvas.getContext('2d'); + newCtx?.drawImage(canvas, sx, sy, width, height, 0, 0, width * scale, height * scale); + + // Convert the new canvas to a data URL and return it + return newCanvas.toDataURL(); +}; + +export const getBoxesByTrackID = ( + imageList: IFileItem[], + targetStep: number, + selectedBoxTrackID: number, +) => { + const matchingBoxes: IPointCloudBoxWithIndex[] = []; + imageList.forEach((element, index) => { + const fileResult = jsonParser(element?.result); + const stepResult = fileResult?.[`step_${targetStep}`]?.result; + const box = stepResult?.find((item: IPointCloudBox) => item.trackID === selectedBoxTrackID); + if (box) { + matchingBoxes.push({ ...box, index }); + } + }); + + return matchingBoxes; +}; + +export const predict = (start: IPointCloudBoxWithIndex, end: IPointCloudBoxWithIndex) => { + const diff = end.index - start.index; + const len = diff - 1; + const result: IPointCloudBox[] = []; + const map: { [key: string]: number[] } = {}; + const centerKeys: ['x', 'y', 'z'] = ['x', 'y', 'z']; + const predictKeys: ['center', 'depth', 'height', 'index', 'rotation', 'width'] = [ + 'center', + 'depth', + 'height', + 'index', + 'rotation', + 'width', + ]; + + centerKeys.forEach((key) => { + map[key] = getInteriorNumbersByStartAndEnd(start.center[key], end.center[key], len); + }); + + predictKeys.forEach((key) => { + if (key === 'center') { + return; + } + map[key] = getInteriorNumbersByStartAndEnd(start[key], end[key], len); + }); + + for (let i = 0; i < len; i++) { + const nextCenter: Partial = {}; + centerKeys.forEach((key) => { + nextCenter[key] = map[key][i]; + }); + let nextValue: IPointCloudBoxWithIndex = Object.assign( + {}, + start, + { id: uuid() }, + { center: nextCenter }, + ); + predictKeys.forEach((key) => { + if (key === 'center') { + return; + } + nextValue[key] = map[key][i]; + }); + result.push(nextValue); + } + + return result; +}; + +const getInteriorNumbersByStartAndEnd = (start = 0, end = 0, length = 0): number[] => { + const step = (end - start) / (length + 1); + const resultArr = new Array(length); + for (let i = 0; i < length; i++) { + resultArr[i] = start + step * (i + 1); + } + return resultArr; +}; diff --git a/packages/lb-components/src/index.scss b/packages/lb-components/src/index.scss index 116588536..9dc6a2ca7 100644 --- a/packages/lb-components/src/index.scss +++ b/packages/lb-components/src/index.scss @@ -902,7 +902,10 @@ $hotkey-container-padding: 7px; padding: 0 3px 0 8px; } - .ant-collapse-borderless > .ant-collapse-item > .ant-collapse-content > .ant-collapse-content-box { + .ant-collapse-borderless + > .ant-collapse-item + > .ant-collapse-content + > .ant-collapse-content-box { padding-top: 4px; } @@ -1716,3 +1719,91 @@ $headerHeight: 40px; } } /** PointCloud样式 end */ + +$predictTrackingPrefix: #{$prefix}-point-cloud-predict-tracking; +.#{$predictTrackingPrefix}-container { + .#{$predictTrackingPrefix}-container__bar { + position: fixed; + z-index: 100; + left: 0; + right: $menuWidth; + bottom: 40px; + background: #444; + // background: rgba(0, 0, 0, 0.6); + color: white; + padding: 20px 24px; + display: flex; + flex-flow: column; + + .#{$predictTrackingPrefix}-container__title { + font-size: 24px; + color: #fff; + display: flex; + justify-content: space-between; + .#{$predictTrackingPrefix}-container__option { + display: flex; + .#{$predictTrackingPrefix}-container__button { + background: red; + display: flex; + justify-content: center; + align-items: center; + width: 88px; + height: 32px; + color: white; + border-radius: 4px; + border: 1px solid transparent; + cursor: pointer; + font-size: 14px; + } + .#{$predictTrackingPrefix}-container__okOption { + color: #555350; + background: white; + } + .#{$predictTrackingPrefix}-container__cancelOption { + margin-right: 16px; + color: white; + background: transparent; + border: 1px solid white; + } + } + } + .#{$predictTrackingPrefix}-container__content { + display: flex; + flex: 1; + .#{$predictTrackingPrefix}-container__left { + width: 140px; + div { + height: 33.3%; + align-items: center; + } + } + .#{$predictTrackingPrefix}-container__right { + display: flex; + gap: 40px; + flex: 1; + overflow: auto; + .#{$predictTrackingPrefix}-container__item { + display: flex; + flex-direction: column; + gap: 20px; + .#{$predictTrackingPrefix}-container__view { + width: 180px; + height: 110px; + background-color: palegreen; + img { + width: 100%; + height: 100%; + } + } + } + } + } + } +} + +.generate-view { + position: fixed; + bottom: 0; + right: 0; + z-index: -200; +} diff --git a/packages/lb-components/src/index.tsx b/packages/lb-components/src/index.tsx index 5bf1f5545..a6976152e 100644 --- a/packages/lb-components/src/index.tsx +++ b/packages/lb-components/src/index.tsx @@ -15,6 +15,7 @@ import './index.scss'; import { PointCloudProvider } from './components/pointCloudView/PointCloudContext'; import { AppState } from './store'; import { LabelBeeContext } from '@/store/ctx'; +import PredictTracking from '@/components/predictTracking'; export const store = configureStore(); @@ -52,6 +53,6 @@ const OutputApp = (props: AppProps, ref: any) => { export default React.forwardRef(OutputApp); -export { AnnotationView, PointCloudAnnotationView, i18n, VideoTagTool }; +export { AnnotationView, PointCloudAnnotationView, i18n, VideoTagTool, PredictTracking }; export * from './constant'; diff --git a/packages/lb-components/src/store/annotation/types.ts b/packages/lb-components/src/store/annotation/types.ts index 25c9cfa2a..423485ede 100644 --- a/packages/lb-components/src/store/annotation/types.ts +++ b/packages/lb-components/src/store/annotation/types.ts @@ -34,6 +34,7 @@ interface CommonActions { payload?: any; } +export type IPointCloudBoxWithIndex = IPointCloudBox & { index: number }; export interface AnnotationState { toolInstance: ToolInstance | null; @@ -65,6 +66,8 @@ export interface AnnotationState { pointCloudLoading: boolean; checkMode: boolean; // Judge current Mode is checkMode or not. + predictionResult: IPointCloudBoxWithIndex[]; + predictionResultVisible: boolean; } interface UpdateToolInstance { @@ -173,22 +176,22 @@ interface InitAnnotationState extends CommonActions { type: typeof ANNOTATION_ACTIONS.INIT_ALL_STATE; } interface BatchUpdateTrackID { - type: typeof ANNOTATION_ACTIONS.BATCH_UPDATE_TRACK_ID, + type: typeof ANNOTATION_ACTIONS.BATCH_UPDATE_TRACK_ID; payload: { id: number; newID: number; - range: [number, number], - imgList: IFileItem[], - } + range: [number, number]; + imgList: IFileItem[]; + }; } interface BatchUpdateResultByTrackID { - type: typeof ANNOTATION_ACTIONS.BATCH_UPDATE_RESULT_BY_TRACK_ID, + type: typeof ANNOTATION_ACTIONS.BATCH_UPDATE_RESULT_BY_TRACK_ID; payload: { id: number; newData: Partial; - range: [number, number], - } + range: [number, number]; + }; } export type AnnotationActionTypes = diff --git a/packages/lb-components/src/views/MainView/toolHeader/index.tsx b/packages/lb-components/src/views/MainView/toolHeader/index.tsx index 8abb85f51..5952d738c 100644 --- a/packages/lb-components/src/views/MainView/toolHeader/index.tsx +++ b/packages/lb-components/src/views/MainView/toolHeader/index.tsx @@ -20,6 +20,7 @@ import { store } from '@/index'; import ExportData from './ExportData'; import HeaderOption from './headerOption'; import StepSwitch from './StepSwitch'; +import PredictTrackingIcon from '@/components/predictTracking/predictTrackingIcon'; interface INextStep { stepProgress: number; @@ -174,6 +175,13 @@ const ToolHeader: React.FC = ({ ); + const rightActions = ( + <> + + {langNode} + + ); + if (header) { if (typeof header === 'function') { return ( @@ -184,7 +192,7 @@ const ToolHeader: React.FC = ({ headerNameNode, stepListNode, headerOptionNode, - langNode, + langNode: rightActions, })} @@ -209,7 +217,7 @@ const ToolHeader: React.FC = ({ {headerOptionNode}
- {langNode} + {rightActions}
); From 9e170453c34dd5aa14bdcbf05d63e303476cbcd7 Mon Sep 17 00:00:00 2001 From: lihqi <455711093@qq.com> Date: Tue, 4 Apr 2023 17:12:00 +0800 Subject: [PATCH 23/41] feat(pointcloud): Finish previewing the results and apply --- .../src/components/predictTracking/index.tsx | 3 + .../predictTracking/previewResult/index.tsx | 269 ++++++++++++++++++ .../src/views/MainView/index.tsx | 2 + packages/lb-utils/src/i18n/resources.json | 10 +- 4 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 packages/lb-components/src/components/predictTracking/index.tsx create mode 100644 packages/lb-components/src/components/predictTracking/previewResult/index.tsx diff --git a/packages/lb-components/src/components/predictTracking/index.tsx b/packages/lb-components/src/components/predictTracking/index.tsx new file mode 100644 index 000000000..2350c7e6f --- /dev/null +++ b/packages/lb-components/src/components/predictTracking/index.tsx @@ -0,0 +1,3 @@ +import PredictTrackingIcon from './predictTrackingIcon'; + +export default PredictTrackingIcon; diff --git a/packages/lb-components/src/components/predictTracking/previewResult/index.tsx b/packages/lb-components/src/components/predictTracking/previewResult/index.tsx new file mode 100644 index 000000000..233f6b673 --- /dev/null +++ b/packages/lb-components/src/components/predictTracking/previewResult/index.tsx @@ -0,0 +1,269 @@ +import classNames from 'classnames'; +import _ from 'lodash'; +import React, { useEffect, useRef, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { connect } from 'react-redux'; + +import { PointCloudContext } from '@/components/pointCloudView/PointCloudContext'; +import { AppState } from '@/store'; +import { + BatchUpdateImgListResult, + SetPointCloudLoading, + SetPredictResult, + SetPredictResultVisible, +} from '@/store/annotation/actionCreators'; +import { IPointCloudBoxWithIndex } from '@/store/annotation/types'; +import { LabelBeeContext, useDispatch } from '@/store/ctx'; +import { IFileItem } from '@/types/data'; +import { IStepInfo } from '@/types/step'; +import { jsonParser } from '@/utils'; +import { composeResult } from '@/utils/data'; +import { getClassName } from '@/utils/dom'; +import { PointCloud } from '@labelbee/lb-annotation'; +import { toolStyleConverter } from '@labelbee/lb-utils'; + +import { getViewsDataUrl, IBox, sleep, views } from './util'; + +interface IProps { + stepList: IStepInfo[]; + step: number; + imgList: IFileItem[]; + predictionResultVisible: boolean; + predictionResult: IPointCloudBoxWithIndex[]; +} + +const PreviewResult = (props: IProps) => { + const { predictionResult, predictionResultVisible, imgList, step, stepList } = props; + + const [list, setList] = useState([]); + const dispatch = useDispatch(); + const { t } = useTranslation(); + + const close = () => { + SetPredictResultVisible(dispatch, false); + SetPredictResult(dispatch, []); + setList([]); + }; + + const apply = async () => { + SetPointCloudLoading(dispatch, true); + const tmpMap: { + [key: number]: any; + } = {}; + predictionResult.forEach((element) => { + const { index } = element; + tmpMap[index] = _.pick(element, [ + 'center', + 'width', + 'height', + 'depth', + 'rotation', + 'id', + 'attribute', + 'valid', + 'trackID', + ]); + }); + + const stepName = `step_${step}`; + + const nextImgList = imgList.map((element, index) => { + if (tmpMap[index]) { + const elementResult = + element.result === '{}' + ? jsonParser(composeResult('', { step, stepList }, { rect: [] }, {})) + : jsonParser(element.result); + + elementResult[stepName].result.push(tmpMap[index]); + + return { + ...element, + result: JSON.stringify(elementResult), + }; + } + return element; + }); + await dispatch(BatchUpdateImgListResult(nextImgList)); + SetPointCloudLoading(dispatch, false); + close(); + }; + + return ( + predictionResultVisible && ( + <> + {list.length > 0 && ( +
+
+
+
+ {t('ComplementaryTrackingPrediction')} + {list.length > 0 ? `(${list.length})` : ''} +
+
+
+ {t('Cancel')} +
+ +
+ {t('Apply')} +
+
+
+ +
+ +
+
+
+ )} + {predictionResult.length > 0 && ( + + )} + + ) + ); +}; + +const Result = (props: { list: IBox[] }) => { + const { list } = props; + const { t } = useTranslation(); + const viewsTitle = [t('TopView'), t('SideView'), t('BackView')]; + + return ( + <> +
+ {viewsTitle.map((i) => ( +
+ {i} +
+ ))} +
+
+ {list.map((i) => { + return ( +
+ {views.map((view) => { + const url = i[view]; + return ( +
+ +
+ ); + })} +
+ ); + })} +
+ + ); +}; + +const GenerateViewsDataUrl = (props: { + result: IPointCloudBoxWithIndex[]; + imgList: IFileItem[]; + setList: (list: IBox[]) => void; +}) => { + const ptCtx = React.useContext(PointCloudContext); + const dispatch = useDispatch(); + + const { result, imgList, setList } = props; + + const ref = useRef(null); + + const size = { + width: 600, + height: 600, + }; + + useEffect(() => { + const generate = async () => { + const config = ptCtx.mainViewInstance?.config; + + if (config && ref.current) { + const orthographicParams = { + left: -size.width / 2, + right: size.width / 2, + top: size.height / 2, + bottom: -size.height / 2, + near: 200, + far: -200, + }; + + const pointCloud = new PointCloud({ + container: ref.current, + isOrthographicCamera: true, + orthographicParams, + config, + }); + + pointCloud.setShowDirection(false); + + for (const item of result) { + const { index } = item; + + const url = imgList[index].url + ? imgList[index].url + : //@ts-ignore + imgList[index].webPointCloudFile.lidar.url; + + await pointCloud.loadPCDFileByBox(url, item, { + width: 2, + height: 2, + depth: 2, + }); + + await pointCloud.updateCameraZoom(ptCtx.zoom); + + const hex = toolStyleConverter.getColorFromConfig( + { attribute: item.attribute }, + { ...config, attributeConfigurable: true }, + {}, + )?.hex; + + pointCloud.generateBox(item, hex); + // TODO + await sleep(500); + await getViewsDataUrl(pointCloud, item, ptCtx.zoom); + await pointCloud.removeObjectByName(item.id); + await pointCloud.clearPointCloudAndRender(); + } + + setList(result); + SetPointCloudLoading(dispatch, false); + } + }; + + generate(); + }, []); + + return
; +}; + +function mapStateToProps(state: AppState) { + return { + predictionResult: state.annotation.predictionResult, + predictionResultVisible: state.annotation.predictionResultVisible, + imgList: state.annotation.imgList, + step: state.annotation.step, + stepList: state.annotation.stepList, + }; +} +export default connect(mapStateToProps, null, null, { context: LabelBeeContext })(PreviewResult); diff --git a/packages/lb-components/src/views/MainView/index.tsx b/packages/lb-components/src/views/MainView/index.tsx index 047210307..8b866f4c4 100644 --- a/packages/lb-components/src/views/MainView/index.tsx +++ b/packages/lb-components/src/views/MainView/index.tsx @@ -20,6 +20,7 @@ import PointCloudView from '@/components/pointCloudView'; import { getClassName } from '@/utils/dom'; import { classnames } from '@/utils'; import { LabelBeeContext } from '@/store/ctx'; +import PreviewResult from '@/components/predictTracking/previewResult'; interface IProps { path: string; @@ -94,6 +95,7 @@ const MainView: React.FC = (props) => { > + diff --git a/packages/lb-utils/src/i18n/resources.json b/packages/lb-utils/src/i18n/resources.json index 57d8faf13..81008d600 100644 --- a/packages/lb-utils/src/i18n/resources.json +++ b/packages/lb-utils/src/i18n/resources.json @@ -197,7 +197,10 @@ "CancelFixed": "Cancel Fixed", "FixedOnLeft": "Fixed On Left", "FixedOnRight": "Fixed On Right", - "AnnotatedResult": "Annotated Result" + "AnnotatedResult": "Annotated Result", + "ComplementaryTracking": "Complementary tracking", + "ComplementaryTrackingPrediction": "Complementary tracking prediction", + "Apply": "Apply" }, "cn": { "TextInput": "文本输入", @@ -397,6 +400,9 @@ "CancelFixed": "取消固定", "FixedOnLeft": "固定在左侧", "FixedOnRight": "固定在右侧", - "AnnotatedResult": "标注结果" + "AnnotatedResult": "标注结果", + "ComplementaryTracking": "补全跟踪", + "ComplementaryTrackingPrediction": "补全跟踪预测", + "Apply": "应用" } } From 66160177fe8e0dc78afb8074d45a6e45e3475166 Mon Sep 17 00:00:00 2001 From: lihqi <455711093@qq.com> Date: Tue, 4 Apr 2023 19:04:17 +0800 Subject: [PATCH 24/41] fix(pointcloud): Fix submit error --- .../predictTracking/previewResult/index.tsx | 97 +++++++++---------- .../predictTracking/previewResult/util.ts | 44 ++++----- 2 files changed, 67 insertions(+), 74 deletions(-) diff --git a/packages/lb-components/src/components/predictTracking/previewResult/index.tsx b/packages/lb-components/src/components/predictTracking/previewResult/index.tsx index 233f6b673..dc5fdd101 100644 --- a/packages/lb-components/src/components/predictTracking/previewResult/index.tsx +++ b/packages/lb-components/src/components/predictTracking/previewResult/index.tsx @@ -88,52 +88,50 @@ const PreviewResult = (props: IProps) => { close(); }; - return ( - predictionResultVisible && ( - <> - {list.length > 0 && ( -
-
-
-
- {t('ComplementaryTrackingPrediction')} - {list.length > 0 ? `(${list.length})` : ''} + return predictionResultVisible ? ( + <> + {list.length > 0 && ( +
+
+
+
+ {t('ComplementaryTrackingPrediction')} + {list.length > 0 ? `(${list.length})` : ''} +
+
+
+ {t('Cancel')}
-
-
- {t('Cancel')} -
-
- {t('Apply')} -
+
+ {t('Apply')}
+
-
- -
+
+
- )} - {predictionResult.length > 0 && ( - - )} - - ) - ); +
+ )} + {predictionResult.length > 0 && ( + + )} + + ) : null; }; const Result = (props: { list: IBox[] }) => { @@ -221,7 +219,7 @@ const GenerateViewsDataUrl = (props: { const url = imgList[index].url ? imgList[index].url - : //@ts-ignore + : // @ts-ignore imgList[index].webPointCloudFile.lidar.url; await pointCloud.loadPCDFileByBox(url, item, { @@ -254,16 +252,15 @@ const GenerateViewsDataUrl = (props: { generate(); }, []); - return
; + return
; }; -function mapStateToProps(state: AppState) { - return { - predictionResult: state.annotation.predictionResult, - predictionResultVisible: state.annotation.predictionResultVisible, - imgList: state.annotation.imgList, - step: state.annotation.step, - stepList: state.annotation.stepList, - }; -} +const mapStateToProps = (state: AppState) => ({ + predictionResult: state.annotation.predictionResult, + predictionResultVisible: state.annotation.predictionResultVisible, + imgList: state.annotation.imgList, + step: state.annotation.step, + stepList: state.annotation.stepList, +}); + export default connect(mapStateToProps, null, null, { context: LabelBeeContext })(PreviewResult); diff --git a/packages/lb-components/src/components/predictTracking/previewResult/util.ts b/packages/lb-components/src/components/predictTracking/previewResult/util.ts index a1f6e9401..bf5a8836b 100644 --- a/packages/lb-components/src/components/predictTracking/previewResult/util.ts +++ b/packages/lb-components/src/components/predictTracking/previewResult/util.ts @@ -88,15 +88,8 @@ export const predict = (start: IPointCloudBoxWithIndex, end: IPointCloudBoxWithI const len = diff - 1; const result: IPointCloudBox[] = []; const map: { [key: string]: number[] } = {}; - const centerKeys: ['x', 'y', 'z'] = ['x', 'y', 'z']; - const predictKeys: ['center', 'depth', 'height', 'index', 'rotation', 'width'] = [ - 'center', - 'depth', - 'height', - 'index', - 'rotation', - 'width', - ]; + const centerKeys = ['x', 'y', 'z'] as const; + const predictKeys = ['center', 'depth', 'height', 'index', 'rotation', 'width'] as const; centerKeys.forEach((key) => { map[key] = getInteriorNumbersByStartAndEnd(start.center[key], end.center[key], len); @@ -110,22 +103,25 @@ export const predict = (start: IPointCloudBoxWithIndex, end: IPointCloudBoxWithI }); for (let i = 0; i < len; i++) { - const nextCenter: Partial = {}; - centerKeys.forEach((key) => { - nextCenter[key] = map[key][i]; - }); - let nextValue: IPointCloudBoxWithIndex = Object.assign( - {}, - start, - { id: uuid() }, - { center: nextCenter }, + const nextCenter = centerKeys.reduce( + (acc, key) => { + acc[key] = map[key][i]; + return acc; + }, + { x: 0, y: 0, z: 0 }, ); - predictKeys.forEach((key) => { - if (key === 'center') { - return; - } - nextValue[key] = map[key][i]; - }); + + const nextValue = predictKeys.reduce( + (acc, key) => { + if (key === 'center') { + return acc; + } + acc[key] = map[key][i]; + return acc; + }, + { ...start, id: uuid(), center: nextCenter }, + ); + result.push(nextValue); } From a724c664a0de04572a574dfe2f62ffad511d017d Mon Sep 17 00:00:00 2001 From: lihqi <455711093@qq.com> Date: Tue, 4 Apr 2023 19:38:42 +0800 Subject: [PATCH 25/41] fix(pointcloud): Replacement translation --- .../predictTracking/predictTrackingIcon/index.tsx | 14 +++++++++----- .../predictTracking/previewResult/util.ts | 6 +----- packages/lb-utils/src/i18n/resources.json | 8 ++++++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/lb-components/src/components/predictTracking/predictTrackingIcon/index.tsx b/packages/lb-components/src/components/predictTracking/predictTrackingIcon/index.tsx index d360e4c78..8c4c27906 100644 --- a/packages/lb-components/src/components/predictTracking/predictTrackingIcon/index.tsx +++ b/packages/lb-components/src/components/predictTracking/predictTrackingIcon/index.tsx @@ -7,7 +7,11 @@ import icon from '@/assets/predictTracking/icon.svg'; import { useSingleBox } from '@/components/pointCloudView/hooks/useSingleBox'; import { AppState } from '@/store'; import { - ChangeSave, GetBoxesByID, SetPointCloudLoading, SetPredictResult, SetPredictResultVisible + ChangeSave, + GetBoxesByID, + SetPointCloudLoading, + SetPredictResult, + SetPredictResultVisible, } from '@/store/annotation/actionCreators'; import { LabelBeeContext, useDispatch } from '@/store/ctx'; @@ -28,7 +32,7 @@ const PredictTrackingIcon = (props: { loading: boolean }) => { const selectedBoxTrackID = selectedBox?.info.trackID; if (!selectedBoxTrackID) { - message.error('未找到当前标注框ID'); + message.error(t('BeforePredictStarting')); return; } @@ -37,7 +41,7 @@ const PredictTrackingIcon = (props: { loading: boolean }) => { const boxes: any = await dispatch(GetBoxesByID(selectedBoxTrackID)); if (boxes.length < 2) { - message.error('请至少标记两个目标'); + message.error(t('BeforePredictStarting')); return; } @@ -47,12 +51,12 @@ const PredictTrackingIcon = (props: { loading: boolean }) => { const difference = end.index - start.index; if (difference < 2) { - message.error('不需要进行补全'); + message.error(t('BeforePredictStarting')); return; } if (difference > 8) { - message.error('需要补全的数据不能大于10个'); + message.error(t('ThePredictedPointCloud')); return; } diff --git a/packages/lb-components/src/components/predictTracking/previewResult/util.ts b/packages/lb-components/src/components/predictTracking/previewResult/util.ts index bf5a8836b..053c1f290 100644 --- a/packages/lb-components/src/components/predictTracking/previewResult/util.ts +++ b/packages/lb-components/src/components/predictTracking/previewResult/util.ts @@ -16,11 +16,7 @@ export const sleep = (time = 300) => { }); }; -export const views: [EPerspectiveView.Top, EPerspectiveView.Left, EPerspectiveView.Back] = [ - EPerspectiveView.Top, - EPerspectiveView.Left, - EPerspectiveView.Back, -]; +export const views = [EPerspectiveView.Top, EPerspectiveView.Left, EPerspectiveView.Back] as const; interface viewDataUrl { [EPerspectiveView.Top]?: string; diff --git a/packages/lb-utils/src/i18n/resources.json b/packages/lb-utils/src/i18n/resources.json index 81008d600..ec7f1b54c 100644 --- a/packages/lb-utils/src/i18n/resources.json +++ b/packages/lb-utils/src/i18n/resources.json @@ -200,7 +200,9 @@ "AnnotatedResult": "Annotated Result", "ComplementaryTracking": "Complementary tracking", "ComplementaryTrackingPrediction": "Complementary tracking prediction", - "Apply": "Apply" + "Apply": "Apply", + "BeforePredictStarting": "Before starting, please mark the first and last box, need the same trackID", + "ThePredictedPointCloud": "The predicted point cloud now needs to be less than 10 frames" }, "cn": { "TextInput": "文本输入", @@ -403,6 +405,8 @@ "AnnotatedResult": "标注结果", "ComplementaryTracking": "补全跟踪", "ComplementaryTrackingPrediction": "补全跟踪预测", - "Apply": "应用" + "Apply": "应用", + "BeforePredictStarting": "启动前,请先标出首尾的框,需同序号", + "ThePredictedPointCloud": "现预测点云需要小于 10 帧" } } From 102d70656a9b435b67157b37237cc7f1f06ffc4f Mon Sep 17 00:00:00 2001 From: lihqi <455711093@qq.com> Date: Thu, 6 Apr 2023 15:45:38 +0800 Subject: [PATCH 26/41] feat(pointcloud): Add batch update ImgList by predict result --- packages/lb-components/docs/annotation.md | 2 + .../lb-components/docs/annotation_en-US.md | 1 + .../predictTracking/previewResult/index.tsx | 53 ++---------------- packages/lb-components/src/constant/index.tsx | 1 + packages/lb-components/src/store/Actions.ts | 2 +- .../src/store/annotation/actionCreators.ts | 8 +-- .../src/store/annotation/reducer.ts | 55 ++++++++++++++++++- 7 files changed, 64 insertions(+), 58 deletions(-) diff --git a/packages/lb-components/docs/annotation.md b/packages/lb-components/docs/annotation.md index 782b3f2ef..98980ce91 100644 --- a/packages/lb-components/docs/annotation.md +++ b/packages/lb-components/docs/annotation.md @@ -17,6 +17,7 @@ enum ESubmitType { StepChanged = 6, // 切换步骤 Save = 7, // 点击保存 BatchUpdateTrackID = 8, // 批量更改 TrackID (PointCloud) + BatchUpdateImgList = 9, // 批量更改 ImgList (PointCloud) SyncImgList = 10001, // 仅更改数据 SyncCurrentPageData = 10002, // 同步当页数据 } @@ -519,6 +520,7 @@ enum ESubmitType { StepChanged = 6, // 切换步骤 Save = 7, // 点击保存 BatchUpdateTrackID = 8, // 批量更改 TrackID (PointCloud) + BatchUpdateImgList = 9, // 批量更改 ImgList (PointCloud) SyncImgList = 10001, // 仅更改数据 SyncCurrentPageData = 10002, // 同步当页数据 } diff --git a/packages/lb-components/docs/annotation_en-US.md b/packages/lb-components/docs/annotation_en-US.md index 6c8ac96ab..30ad60ec8 100644 --- a/packages/lb-components/docs/annotation_en-US.md +++ b/packages/lb-components/docs/annotation_en-US.md @@ -16,6 +16,7 @@ enum ESubmitType { StepChanged = 6, Save = 7, BatchUpdateTrackID = 8, + BatchUpdateImgList = 9, SyncImgList = 10001, SyncCurrentPageData = 10002, // 同步当页数据 } diff --git a/packages/lb-components/src/components/predictTracking/previewResult/index.tsx b/packages/lb-components/src/components/predictTracking/previewResult/index.tsx index dc5fdd101..04ca0dc93 100644 --- a/packages/lb-components/src/components/predictTracking/previewResult/index.tsx +++ b/packages/lb-components/src/components/predictTracking/previewResult/index.tsx @@ -7,17 +7,12 @@ import { connect } from 'react-redux'; import { PointCloudContext } from '@/components/pointCloudView/PointCloudContext'; import { AppState } from '@/store'; import { - BatchUpdateImgListResult, - SetPointCloudLoading, - SetPredictResult, - SetPredictResultVisible, + BatchUpdateImgListResultByPredictResult, SetPointCloudLoading, SetPredictResult, + SetPredictResultVisible } from '@/store/annotation/actionCreators'; import { IPointCloudBoxWithIndex } from '@/store/annotation/types'; import { LabelBeeContext, useDispatch } from '@/store/ctx'; import { IFileItem } from '@/types/data'; -import { IStepInfo } from '@/types/step'; -import { jsonParser } from '@/utils'; -import { composeResult } from '@/utils/data'; import { getClassName } from '@/utils/dom'; import { PointCloud } from '@labelbee/lb-annotation'; import { toolStyleConverter } from '@labelbee/lb-utils'; @@ -25,15 +20,13 @@ import { toolStyleConverter } from '@labelbee/lb-utils'; import { getViewsDataUrl, IBox, sleep, views } from './util'; interface IProps { - stepList: IStepInfo[]; - step: number; imgList: IFileItem[]; predictionResultVisible: boolean; predictionResult: IPointCloudBoxWithIndex[]; } const PreviewResult = (props: IProps) => { - const { predictionResult, predictionResultVisible, imgList, step, stepList } = props; + const { predictionResult, predictionResultVisible, imgList } = props; const [list, setList] = useState([]); const dispatch = useDispatch(); @@ -47,43 +40,7 @@ const PreviewResult = (props: IProps) => { const apply = async () => { SetPointCloudLoading(dispatch, true); - const tmpMap: { - [key: number]: any; - } = {}; - predictionResult.forEach((element) => { - const { index } = element; - tmpMap[index] = _.pick(element, [ - 'center', - 'width', - 'height', - 'depth', - 'rotation', - 'id', - 'attribute', - 'valid', - 'trackID', - ]); - }); - - const stepName = `step_${step}`; - - const nextImgList = imgList.map((element, index) => { - if (tmpMap[index]) { - const elementResult = - element.result === '{}' - ? jsonParser(composeResult('', { step, stepList }, { rect: [] }, {})) - : jsonParser(element.result); - - elementResult[stepName].result.push(tmpMap[index]); - - return { - ...element, - result: JSON.stringify(elementResult), - }; - } - return element; - }); - await dispatch(BatchUpdateImgListResult(nextImgList)); + await dispatch(BatchUpdateImgListResultByPredictResult()); SetPointCloudLoading(dispatch, false); close(); }; @@ -259,8 +216,6 @@ const mapStateToProps = (state: AppState) => ({ predictionResult: state.annotation.predictionResult, predictionResultVisible: state.annotation.predictionResultVisible, imgList: state.annotation.imgList, - step: state.annotation.step, - stepList: state.annotation.stepList, }); export default connect(mapStateToProps, null, null, { context: LabelBeeContext })(PreviewResult); diff --git a/packages/lb-components/src/constant/index.tsx b/packages/lb-components/src/constant/index.tsx index df81ace03..b50f8bbf0 100644 --- a/packages/lb-components/src/constant/index.tsx +++ b/packages/lb-components/src/constant/index.tsx @@ -15,6 +15,7 @@ export enum ESubmitType { StepChanged = 6, // 切换步骤 Save = 7, // 点击保存 BatchUpdateTrackID = 8, // 批量更改 TrackID (PointCloud) + BatchUpdateImgList = 9, // 批量更改 ImgList (PointCloud) SyncImgList = 10001, // 仅更改数据 SyncCurrentPageData = 10002, // 同步当页数据 } diff --git a/packages/lb-components/src/store/Actions.ts b/packages/lb-components/src/store/Actions.ts index 8768718df..4c8abfb1a 100644 --- a/packages/lb-components/src/store/Actions.ts +++ b/packages/lb-components/src/store/Actions.ts @@ -39,7 +39,7 @@ export const ANNOTATION_ACTIONS = { BATCH_UPDATE_RESULT_BY_TRACK_ID: '@@BATCH_UPDATE_RESULT_BY_TRACK_ID', - BATCH_UPDATE_IMG_LIST_RESULT: '@@BATCH_UPDATE_IMG_LIST_RESULT', + BATCH_UPDATE_IMG_LIST_RESULT_BY_PREDICT_RESULT: '@@BATCH_UPDATE_IMG_LIST_RESULT_BY_PREDICT_RESULT', SET_PREDICT_RESULT_VISIBLE: '@@SET_PREDICT_RESULT_VISIBLE', SET_PREDICT_RESULT: '@@SET_PREDICT_RESULT', diff --git a/packages/lb-components/src/store/annotation/actionCreators.ts b/packages/lb-components/src/store/annotation/actionCreators.ts index e8bcb236c..5c2c84925 100644 --- a/packages/lb-components/src/store/annotation/actionCreators.ts +++ b/packages/lb-components/src/store/annotation/actionCreators.ts @@ -238,12 +238,10 @@ export function BatchUpdateResultByTrackID( }; } -export function BatchUpdateImgListResult(nextImgList: any): AnnotationActionTypes { +export function BatchUpdateImgListResultByPredictResult(): AnnotationActionTypes { return { - type: ANNOTATION_ACTIONS.BATCH_UPDATE_IMG_LIST_RESULT, - payload: { - nextImgList, - }, + type: ANNOTATION_ACTIONS.BATCH_UPDATE_IMG_LIST_RESULT_BY_PREDICT_RESULT, + payload: {}, }; } diff --git a/packages/lb-components/src/store/annotation/reducer.ts b/packages/lb-components/src/store/annotation/reducer.ts index 8a4b20108..e205e721c 100644 --- a/packages/lb-components/src/store/annotation/reducer.ts +++ b/packages/lb-components/src/store/annotation/reducer.ts @@ -11,7 +11,7 @@ import { composeResult, composeResultWithBasicImgInfo } from '@/utils/data'; import StepUtils from '@/utils/StepUtils'; import ToolUtils from '@/utils/ToolUtils'; import { AnnotationEngine, CommonToolUtils, ImgUtils, MathUtils } from '@labelbee/lb-annotation'; -import { i18n, PointCloudUtils } from '@labelbee/lb-utils'; +import { i18n, IPointCloudBox, PointCloudUtils } from '@labelbee/lb-utils'; import { Modal } from 'antd'; import { message } from 'antd/es'; import _ from 'lodash'; @@ -836,9 +836,58 @@ export const annotationReducer = ( }; } - case ANNOTATION_ACTIONS.BATCH_UPDATE_IMG_LIST_RESULT: { - const { nextImgList } = action.payload; + case ANNOTATION_ACTIONS.BATCH_UPDATE_IMG_LIST_RESULT_BY_PREDICT_RESULT: { + const { onSubmit, imgList, stepList, step, predictionResult } = state; + const tmpMap: { + [key: number]: IPointCloudBox; + } = {}; + + predictionResult.forEach((element) => { + const { index } = element; + tmpMap[index] = _.pick(element, [ + 'center', + 'width', + 'height', + 'depth', + 'rotation', + 'id', + 'attribute', + 'valid', + 'trackID', + ]); + }); + + const stepName = `step_${step}`; + const updateImgList: Array<{ newInfo: IFileItem; imgIndex: number }> = []; + + const nextImgList = imgList.map((element, index) => { + if (tmpMap[index]) { + const elementResult = + element.result === '{}' + ? jsonParser(composeResult('', { step, stepList }, { rect: [] }, {})) + : jsonParser(element.result); + + elementResult[stepName].result.push(tmpMap[index]); + + const newInfo = { + ...element, + result: JSON.stringify(elementResult), + }; + + updateImgList.push({ + imgIndex: index, + newInfo, + }); + + return newInfo; + } + return element; + }); + + onSubmit?.(nextImgList, ESubmitType.BatchUpdateImgList, -1, nextImgList, { + updateImgList, + }); return { ...state, imgList: nextImgList, From bfe634a5f57e6e1ca33547e7b950f7612a6fe449 Mon Sep 17 00:00:00 2001 From: laoluo Date: Tue, 11 Apr 2023 11:04:58 +0800 Subject: [PATCH 27/41] fix(pointcloud): Repeated updates of pointCloudBackView --- .../pointCloudView/PointCloudBackView.tsx | 98 +------------------ 1 file changed, 4 insertions(+), 94 deletions(-) diff --git a/packages/lb-components/src/components/pointCloudView/PointCloudBackView.tsx b/packages/lb-components/src/components/pointCloudView/PointCloudBackView.tsx index a37960613..0db148fcd 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloudBackView.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloudBackView.tsx @@ -4,32 +4,17 @@ * @LastEditors: Laoluo luozefeng@sensetime.com * @LastEditTime: 2022-07-08 11:08:02 */ -import { - getCuboidFromPointCloudBox, - MathUtils, - PointCloud, - PointCloudAnnotation, -} from '@labelbee/lb-annotation'; +import { PointCloud, PointCloudAnnotation } from '@labelbee/lb-annotation'; import { getClassName } from '@/utils/dom'; import { PointCloudContainer } from './PointCloudLayout'; import React, { useEffect, useRef } from 'react'; import { PointCloudContext } from './PointCloudContext'; -import { - EPerspectiveView, - IPointCloudBox, - IPolygonData, - IPolygonPoint, - UpdatePolygonByDragList, -} from '@labelbee/lb-utils'; +import { EPerspectiveView, IPointCloudBox, UpdatePolygonByDragList } from '@labelbee/lb-utils'; import { useSingleBox } from './hooks/useSingleBox'; import { SizeInfoForView } from './PointCloudInfos'; import { connect } from 'react-redux'; import { a2MapStateToProps, IA2MapStateProps } from '@/store/annotation/map'; -import { - synchronizeSideView, - synchronizeTopView, - usePointCloudViews, -} from './hooks/usePointCloudViews'; +import { usePointCloudViews } from './hooks/usePointCloudViews'; import useSize from '@/hooks/useSize'; import EmptyPage from './components/EmptyPage'; import { useTranslation } from 'react-i18next'; @@ -94,84 +79,10 @@ const PointCloudSideView = ({ currentData, config, checkMode }: IA2MapStateProps const ptCtx = React.useContext(PointCloudContext); const ref = useRef(null); const size = useSize(ref); - const { selectedBox, updateSelectedBox } = useSingleBox(); + const { selectedBox } = useSingleBox(); const { t } = useTranslation(); const { backViewUpdateBox } = usePointCloudViews(); - const transferPolygonDataToBoxParams = ( - newPolygon: IPolygonData, - originPolygon: IPolygonData, - ) => { - if ( - !ptCtx.selectedPointCloudBox || - !ptCtx.mainViewInstance || - !currentData.url || - !ptCtx.backViewInstance - ) { - return; - } - - const { pointCloudInstance: backPointCloud } = ptCtx.backViewInstance; - - // Notice. The sort of polygon is important. - const [point1, point2, point3] = newPolygon.pointList; - const [op1, op2, op3] = originPolygon.pointList; - - // 2D centerPoint => 3D x & z - const newCenterPoint = MathUtils.getLineCenterPoint([point1, point3]); - const oldCenterPoint = MathUtils.getLineCenterPoint([op1, op3]); - - const offset = { - x: newCenterPoint.x - oldCenterPoint.x, - y: newCenterPoint.y - oldCenterPoint.y, - }; - - const offsetCenterPoint = { - x: offset.x, - y: 0, // Not be used. - z: newCenterPoint.y - oldCenterPoint.y, - }; - - // 2D height => 3D depth - const height = MathUtils.getLineLength(point1, point2); - const oldHeight = MathUtils.getLineLength(op1, op2); - const offsetHeight = height - oldHeight; // 3D depth - - // 2D width => 3D width - const width = MathUtils.getLineLength(point2, point3); - const oldWidth = MathUtils.getLineLength(op2, op3); - const offsetWidth = width - oldWidth; // 3D width - - let { newBoxParams } = backPointCloud.getNewBoxByBackUpdate( - offsetCenterPoint, - offsetWidth, - offsetHeight, - ptCtx.selectedPointCloudBox, - ); - - // Update count - if (ptCtx.mainViewInstance) { - const { count } = ptCtx.mainViewInstance.getSensesPointZAxisInPolygon( - getCuboidFromPointCloudBox(newBoxParams).polygonPointList as IPolygonPoint[], - [ - newBoxParams.center.z - newBoxParams.depth / 2, - newBoxParams.center.z + newBoxParams.depth / 2, - ], - ); - - newBoxParams = { - ...newBoxParams, - count, - }; - } - - synchronizeTopView(newBoxParams, newPolygon, ptCtx.topViewInstance, ptCtx.mainViewInstance); - synchronizeSideView(newBoxParams, newPolygon, ptCtx.sideViewInstance, currentData.url); - ptCtx.mainViewInstance.highlightOriginPointCloud([newBoxParams]); - - updateSelectedBox(newBoxParams); - }; - useEffect(() => { if (ref.current) { const size = { @@ -228,7 +139,6 @@ const PointCloudSideView = ({ currentData, config, checkMode }: IA2MapStateProps const { newPolygon, originPolygon } = updateList[0]; if (newPolygon && originPolygon) { - transferPolygonDataToBoxParams(newPolygon, originPolygon); backViewUpdateBox(newPolygon, originPolygon); } } From 7ed285580defef82c75cb404cf42d5df66bc3bba Mon Sep 17 00:00:00 2001 From: laoluo Date: Tue, 11 Apr 2023 12:47:24 +0800 Subject: [PATCH 28/41] feat(pointcloud): 3Dview sync the direction with topview after selected --- packages/lb-annotation/src/core/pointCloud/index.ts | 11 ++++++++++- .../components/pointCloudView/PointCloud3DView.tsx | 12 +++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/lb-annotation/src/core/pointCloud/index.ts b/packages/lb-annotation/src/core/pointCloud/index.ts index d6a484df6..ab1007ca6 100644 --- a/packages/lb-annotation/src/core/pointCloud/index.ts +++ b/packages/lb-annotation/src/core/pointCloud/index.ts @@ -376,10 +376,19 @@ export class PointCloud { * Update Camera position & target * @param boxParams * @param perspectiveView + * @param customCameraVector Provide a custom way. */ - public updateCameraByBox(boxParams: IPointCloudBox, perspectiveView: EPerspectiveView) { + public updateCameraByBox( + boxParams: IPointCloudBox, + perspectiveView: EPerspectiveView, + customCameraVector?: I3DSpaceCoord, + ) { const { center, width, height, depth, rotation } = boxParams; const cameraPositionVector = this.getCameraVector(center, rotation, { width, height, depth }, perspectiveView); + if (customCameraVector) { + this.updateCamera(customCameraVector, center); + return new THREE.Vector3(customCameraVector.x, customCameraVector.y, customCameraVector.z); + } this.updateCamera(cameraPositionVector, center); return cameraPositionVector; } diff --git a/packages/lb-components/src/components/pointCloudView/PointCloud3DView.tsx b/packages/lb-components/src/components/pointCloudView/PointCloud3DView.tsx index f1058b892..090ba901e 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloud3DView.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloud3DView.tsx @@ -116,7 +116,17 @@ const PointCloud3D: React.FC = ({ currentData, config }) => { const box = selectedBox?.info; if (box) { - ptCtx.mainViewInstance?.updateCameraByBox(box, perspectiveView); + // Business Logic: If the updated view is top, need to sync with topView Direction in 3dView. + const topViewVector = { ...box.center }; + topViewVector.x = topViewVector.x - 0.01; + topViewVector.z = 10; + const isTopView = perspectiveView === EPerspectiveView.Top; + + ptCtx.mainViewInstance?.updateCameraByBox( + box, + perspectiveView, + isTopView ? topViewVector : undefined, + ); } }; From 634ca6196e95a710b762e419ad5800044eab9d24 Mon Sep 17 00:00:00 2001 From: laoluo Date: Tue, 11 Apr 2023 12:47:33 +0800 Subject: [PATCH 29/41] fix(pointcloud): SyncTopview doesn't need to update camera --- .../src/components/pointCloudView/hooks/usePointCloudViews.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts b/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts index 11ddbe825..498f24fc9 100644 --- a/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts +++ b/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts @@ -329,7 +329,6 @@ export const synchronizeTopView = ( // Control the 3D view data to create box mainViewInstance.generateBox(newBoxParams, newPolygon.id); - mainViewInstance.updateCameraByBox(newBoxParams, EPerspectiveView.Top); mainViewInstance.render(); const { pointCloud2dOperation, pointCloudInstance } = topViewInstance; From 35db95544bf54f87590389c67dd775d08c30750e Mon Sep 17 00:00:00 2001 From: laoluo Date: Tue, 11 Apr 2023 12:49:50 +0800 Subject: [PATCH 30/41] chore: Update version --- packages/lb-annotation/package.json | 2 +- packages/lb-components/package.json | 4 ++-- packages/lb-demo/package.json | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/lb-annotation/package.json b/packages/lb-annotation/package.json index d24b396a8..900eafead 100644 --- a/packages/lb-annotation/package.json +++ b/packages/lb-annotation/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-annotation", - "version": "1.13.0-alpha.5", + "version": "1.13.0-alpha.6", "description": "Annotation tool collection", "keywords": [ "annotation", diff --git a/packages/lb-components/package.json b/packages/lb-components/package.json index 522cbc7de..24ef95487 100644 --- a/packages/lb-components/package.json +++ b/packages/lb-components/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-components", - "version": "1.9.0-alpha.6", + "version": "1.9.0-alpha.7", "description": "Provide a complete library of annotation components", "main": "./dist/index.js", "es": "./es/index.js", @@ -41,7 +41,7 @@ }, "dependencies": { "@ant-design/icons": "^4.6.2", - "@labelbee/lb-annotation": "^1.13.0-alpha.5", + "@labelbee/lb-annotation": "^1.13.0-alpha.6", "@labelbee/lb-utils": "^1.6.0-alpha.5", "ahooks": "^3.4.0", "classnames": "^2.3.0", diff --git a/packages/lb-demo/package.json b/packages/lb-demo/package.json index e938b3cfc..8ff9531c2 100644 --- a/packages/lb-demo/package.json +++ b/packages/lb-demo/package.json @@ -1,10 +1,10 @@ { "name": "lb-demo", - "version": "1.10.1-alpha.4", + "version": "1.10.1-alpha.5", "private": true, "dependencies": { - "@labelbee/lb-annotation": "^1.13.0-alpha.5", - "@labelbee/lb-components": "^1.9.0-alpha.6", + "@labelbee/lb-annotation": "^1.13.0-alpha.6", + "@labelbee/lb-components": "^1.9.0-alpha.7", "@labelbee/lb-utils": "^1.6.0-alpha.5", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", From df16fdc87df911088e800527274cf36cb492da99 Mon Sep 17 00:00:00 2001 From: laoluo Date: Tue, 11 Apr 2023 19:49:54 +0800 Subject: [PATCH 31/41] feat(pointcloud): Update the backgroundColor of pointCloud --- packages/lb-annotation/src/core/pointCloud/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/lb-annotation/src/core/pointCloud/index.ts b/packages/lb-annotation/src/core/pointCloud/index.ts index ab1007ca6..ba4c97551 100644 --- a/packages/lb-annotation/src/core/pointCloud/index.ts +++ b/packages/lb-annotation/src/core/pointCloud/index.ts @@ -104,7 +104,7 @@ export class PointCloud { noAppend, isOrthographicCamera, orthographicParams, - backgroundColor = 'black', + backgroundColor = '#4C4C4C', // GRAY_BACKGROUND config, }: IProps) { this.container = container; From 95a39c945895bb420d8ab7485e7a49176dae2a76 Mon Sep 17 00:00:00 2001 From: laoluo Date: Tue, 11 Apr 2023 19:52:29 +0800 Subject: [PATCH 32/41] chore: Update version --- packages/lb-annotation/package.json | 2 +- packages/lb-components/package.json | 4 ++-- packages/lb-demo/package.json | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/lb-annotation/package.json b/packages/lb-annotation/package.json index 900eafead..126c3d55d 100644 --- a/packages/lb-annotation/package.json +++ b/packages/lb-annotation/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-annotation", - "version": "1.13.0-alpha.6", + "version": "1.13.0-alpha.7", "description": "Annotation tool collection", "keywords": [ "annotation", diff --git a/packages/lb-components/package.json b/packages/lb-components/package.json index 24ef95487..6c826d042 100644 --- a/packages/lb-components/package.json +++ b/packages/lb-components/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-components", - "version": "1.9.0-alpha.7", + "version": "1.9.0-alpha.8", "description": "Provide a complete library of annotation components", "main": "./dist/index.js", "es": "./es/index.js", @@ -41,7 +41,7 @@ }, "dependencies": { "@ant-design/icons": "^4.6.2", - "@labelbee/lb-annotation": "^1.13.0-alpha.6", + "@labelbee/lb-annotation": "^1.13.0-alpha.7", "@labelbee/lb-utils": "^1.6.0-alpha.5", "ahooks": "^3.4.0", "classnames": "^2.3.0", diff --git a/packages/lb-demo/package.json b/packages/lb-demo/package.json index 8ff9531c2..d7cf82b23 100644 --- a/packages/lb-demo/package.json +++ b/packages/lb-demo/package.json @@ -3,8 +3,8 @@ "version": "1.10.1-alpha.5", "private": true, "dependencies": { - "@labelbee/lb-annotation": "^1.13.0-alpha.6", - "@labelbee/lb-components": "^1.9.0-alpha.7", + "@labelbee/lb-annotation": "^1.13.0-alpha.7", + "@labelbee/lb-components": "^1.9.0-alpha.8", "@labelbee/lb-utils": "^1.6.0-alpha.5", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", From e10b30283372302bbbef454d9b80f66efe57e411 Mon Sep 17 00:00:00 2001 From: "lixinghua.vendor" Date: Mon, 27 Mar 2023 16:05:43 +0800 Subject: [PATCH 33/41] feat: Tool custom colours --- .../core/toolOperation/basicToolOperation.ts | 19 ++--- .../src/utils/tool/AttributeUtils.ts | 24 +++++- packages/lb-components/src/data/Style.ts | 3 + packages/lb-utils/src/index.ts | 11 ++- .../lb-utils/src/toolStyle/ToolStyleUtils.ts | 74 ++++++++++++++++++- packages/lb-utils/src/toolStyle/index.ts | 58 +++++++++++++-- 6 files changed, 167 insertions(+), 22 deletions(-) diff --git a/packages/lb-annotation/src/core/toolOperation/basicToolOperation.ts b/packages/lb-annotation/src/core/toolOperation/basicToolOperation.ts index 1c0c4126c..93c78734d 100644 --- a/packages/lb-annotation/src/core/toolOperation/basicToolOperation.ts +++ b/packages/lb-annotation/src/core/toolOperation/basicToolOperation.ts @@ -1,6 +1,5 @@ -import { IBasicText } from '@labelbee/lb-utils'; +import { IBasicText, toolStyleConverter } from '@labelbee/lb-utils'; import { isNumber } from 'lodash'; -import { styleDefaultConfig } from '@/constant/defaultConfig'; import { EOperationMode, EToolName } from '@/constant/tool'; import { IPolygonConfig, IPolygonData } from '@/types/tool/polygon'; import MathUtils from '@/utils/MathUtils'; @@ -1175,22 +1174,18 @@ class BasicToolOperation extends EventListener { this.emit('updateResult'); } - /** 获取当前属性颜色 */ + /** Get the current property color */ public getColor(attribute = '', config = this.config) { - if (config?.attributeConfigurable === true && this.style.attributeColor) { - const attributeIndex = AttributeUtils.getAttributeIndex(attribute, config.attributeList ?? []) + 1; - return this.style.attributeColor[attributeIndex]; - } - const { color, toolColor } = this.style; - if (toolColor) { - return toolColor[color]; - } - return styleDefaultConfig.toolColor['1']; + return toolStyleConverter.getColorByConfig({ attribute, config, style: this.style }); } public getLineColor(attribute = '') { if (this.config?.attributeConfigurable === true) { const attributeIndex = AttributeUtils.getAttributeIndex(attribute, this.config?.attributeList ?? []) + 1; + const color = this.config?.attributeList?.find((i: any) => i.value === attribute)?.color; + if (color) { + return toolStyleConverter.getColorByConfig({ attribute, config: this.config })?.valid?.stroke; + } return this.style.attributeLineColor ? this.style.attributeLineColor[attributeIndex] : ''; } const { color, lineColor } = this.style; diff --git a/packages/lb-annotation/src/utils/tool/AttributeUtils.ts b/packages/lb-annotation/src/utils/tool/AttributeUtils.ts index c8dd79df4..3324ac7ac 100644 --- a/packages/lb-annotation/src/utils/tool/AttributeUtils.ts +++ b/packages/lb-annotation/src/utils/tool/AttributeUtils.ts @@ -1,4 +1,5 @@ import { isNumber } from 'lodash'; +import { ToolStyleUtils } from '@labelbee/lb-utils'; import { ELang } from '../../constant/annotation'; import { IPolygonData } from '../../types/tool/polygon'; import { COLORS_ARRAY, ICON_ARRAY, INVALID_ICON, NULL_COLOR, NULL_ICON } from '../../constant/style'; @@ -254,14 +255,35 @@ export default class AttributeUtils { baseIcon: any, ) { if (attributeConfigurable === true) { - // 含有属性配置 + // Open attribute configuration const attributeIndex = (attributeList?.findIndex((i: any) => i?.value === attribute) % COLORS_ARRAY.length) + 1; + const color = attributeList?.find((i: any) => i.value === attribute)?.color; + if (color) { + const getHexColor = ToolStyleUtils.rgbaStringToHex(color); + return this.generateIconAttribute({ fill: getHexColor }); + } return ICON_ARRAY[attributeIndex]; } return baseIcon; } + public static generateIconAttribute({ + fill, + width = 16, + height = 16, + xmlns = 'http://www.w3.org/2000/svg', + xlink = 'http://www.w3.org/1999/xlink', + }: { + fill?: string; + width?: number; + height?: number; + xmlns?: string; + xlink?: string; + }) { + return ``; + } + /** * 根据keycode返回attribute, 没有匹配到时为undefined * @param keyCode diff --git a/packages/lb-components/src/data/Style.ts b/packages/lb-components/src/data/Style.ts index eb5246c94..5d4b4eecc 100644 --- a/packages/lb-components/src/data/Style.ts +++ b/packages/lb-components/src/data/Style.ts @@ -88,11 +88,13 @@ export const CHANGE_COLOR: { [a: number]: any } = { }; export const BORDER_OPACITY_LEVEL: { [a: number]: number } = { + 0: 0, 1: 0.2, 3: 0.4, 5: 0.6, 7: 0.8, 9: 1.0, + 10: 1.0, }; export const FILL_OPACITY_LEVEL: { [a: number]: number } = { @@ -101,4 +103,5 @@ export const FILL_OPACITY_LEVEL: { [a: number]: number } = { 5: 0.4, 7: 0.6, 9: 0.8, + 10: 1.0, }; diff --git a/packages/lb-utils/src/index.ts b/packages/lb-utils/src/index.ts index b7c9ea627..9f745a343 100644 --- a/packages/lb-utils/src/index.ts +++ b/packages/lb-utils/src/index.ts @@ -5,7 +5,7 @@ * @LastEditTime: 2022-06-16 19:32:34 */ import i18n from './i18n/index'; -import toolStyleConverter from './toolStyle'; +import toolStyleConverter, { ToolStyleUtils } from './toolStyle'; import PerspectiveShiftUtils from './PerspectiveShiftUtils'; import PointCloudUtils from './PointCloudUtils'; import MatrixUtils from './MatrixUtils'; @@ -17,7 +17,14 @@ export * from './constant/pointCloud'; export * from './types/index'; // Utils -export { i18n, toolStyleConverter, PerspectiveShiftUtils, PointCloudUtils, MatrixUtils }; +export { + i18n, + toolStyleConverter, + ToolStyleUtils, + PerspectiveShiftUtils, + PointCloudUtils, + MatrixUtils, +}; export * from './annotation'; diff --git a/packages/lb-utils/src/toolStyle/ToolStyleUtils.ts b/packages/lb-utils/src/toolStyle/ToolStyleUtils.ts index 72e63d843..143babdf6 100644 --- a/packages/lb-utils/src/toolStyle/ToolStyleUtils.ts +++ b/packages/lb-utils/src/toolStyle/ToolStyleUtils.ts @@ -1,3 +1,4 @@ +import { INVALID_COLOR } from './index'; interface IInfoList { key: string; value: string; @@ -10,10 +11,28 @@ interface IInputList { isMulti?: boolean; subSelected?: IInfoList[]; } +const BORDER_OPACITY_LEVEL: { [a: number]: number } = { + 0: 0, + 1: 0.2, + 3: 0.4, + 5: 0.6, + 7: 0.8, + 9: 1.0, + 10: 1.0, +}; +const FILL_OPACITY_LEVEL: { [a: number]: number } = { + 0: 0, + 1: 0, + 3: 0.2, + 5: 0.4, + 7: 0.6, + 9: 0.8, + 10: 1, +}; class ToolStyleUtils { /** - * 替换 RGBA 透明度值 + * Replace RGBA transparency value * @param rgba * @param opacity * @returns @@ -34,6 +53,29 @@ class ToolStyleUtils { } }; + /** + * Transformer rgba to hex + * @param rgba + * @returns + */ + public static rgbaStringToHex(rgbaString: string) { + const rgbaArr = rgbaString + .substring(5, rgbaString.length - 1) + .replace(/ /g, '') + .split(','); + const r = parseInt(rgbaArr[0]); + const g = parseInt(rgbaArr[1]); + const b = parseInt(rgbaArr[2]); + const a = parseFloat(rgbaArr[3]); + const hexR = r.toString(16).padStart(2, '0'); + const hexG = g.toString(16).padStart(2, '0'); + const hexB = b.toString(16).padStart(2, '0'); + const hexA = Math.round(a * 255) + .toString(16) + .padStart(2, '0'); + return '#' + hexR + hexG + hexB + hexA; + } + /** * 获取当前状态下的 stroke & fill * @param color @@ -75,6 +117,36 @@ class ToolStyleUtils { }; }; + public static getStrokeAndFill = (color: string, opacity = 1, fillOpacity = 1) => { + return { + stroke: this.replaceAFromRGBA(color, opacity), + fill: this.replaceAFromRGBA(color, fillOpacity), + }; + }; + + /** + * Dynamic color table generation + * @param color + * @returns + */ + public static getToolColorList = ( + color: string, + borderOpacityParam = 9, + fillOpacityParam = 9, + ) => { + const borderOpacity = BORDER_OPACITY_LEVEL[borderOpacityParam]; + const fillOpacity = FILL_OPACITY_LEVEL[fillOpacityParam]; + + return { + valid: this.getStrokeAndFill(color, 1 * borderOpacity, 0.4 * fillOpacity), + invalid: this.getStrokeAndFill(INVALID_COLOR, 1 * borderOpacity, 0.8 * fillOpacity), + validSelected: this.getStrokeAndFill(color, 1 * borderOpacity, 0.8 * fillOpacity), + invalidSelected: this.getStrokeAndFill(INVALID_COLOR, 1 * borderOpacity, 0.24 * fillOpacity), + validHover: this.getStrokeAndFill(color, 1 * borderOpacity, 0.64 * fillOpacity), + invalidHover: this.getStrokeAndFill(INVALID_COLOR, 1 * borderOpacity, 0.4 * fillOpacity), + }; + }; + /** * 获取属性标注的索引 * @param attribute diff --git a/packages/lb-utils/src/toolStyle/index.ts b/packages/lb-utils/src/toolStyle/index.ts index cc9e0891a..a62b17a21 100644 --- a/packages/lb-utils/src/toolStyle/index.ts +++ b/packages/lb-utils/src/toolStyle/index.ts @@ -161,16 +161,23 @@ class ToolStyleConverter { config?.attributeList, ); - let color = colorList[attributeIndex % colorList.length]; + let color = config?.attributeList?.find((i: any) => i.value === result?.attribute)?.color; + let hexColor = ''; + if (!color && attributeIndex !== -1) { + color = colorList[attributeIndex % colorList.length]; + } // 找不到则开启为无属性 if (attributeIndex === -1) { color = NULL_COLOR; } + hexColor = ToolStyleUtils.rgbaStringToHex(color).toString().substring(1); + const colorDecimal = parseInt(hexColor, 16); // 十进制 + const colorHex = COLORS_ARRAY_MULTI[attributeIndex % colorList.length]?.hex ?? ''; return { ...ToolStyleUtils.getToolStrokeAndFill(color, defaultStatus), - hex: COLORS_ARRAY_MULTI[attributeIndex % colorList.length]?.hex ?? '', + hex: colorDecimal || colorHex, }; } @@ -188,15 +195,54 @@ class ToolStyleConverter { defaultStatus, ); } + + /** + * Get the color under the configuration (dynamically generate the activation color for hover) + * @param attribute + * @param config + * @param style + * @returns + */ + public getColorByConfig({ + attribute, + config, + style, + }: { + attribute: string; + config: any; + style?: any; + }) { + if (config?.attributeConfigurable === true) { + const color = config?.attributeList?.find((i: any) => i.value === attribute)?.color; + + if (color) { + return ToolStyleUtils.getToolColorList(color, style?.borderOpacity, style?.fillOpacity); + } + + // If the property does not have a custom color (color), then use a default Attribute Color + if (style?.attributeColor) { + const attributeIndex = + ToolStyleUtils.getAttributeIndex(attribute, config?.attributeList ?? []) + 1; + return style.attributeColor[attributeIndex]; + } + } + if (style) { + const { color, toolColor } = style; + if (toolColor) { + return toolColor[color]; + } + } + return ToolStyleUtils.getToolColorList(NULL_COLOR); + } } /** * Create ColorMap - JET - * + * * Different ranges of colors can be obtained with different indexes. - * + * * https://docs.opencv.org/3.4/d3/d50/group__imgproc__colormap.html - * @returns + * @returns */ function createColorMapJet() { let s; @@ -244,4 +290,4 @@ const COLOR_MAP_JET = createColorMapJet(); export default new ToolStyleConverter(); -export { ToolStyleConverter, COLOR_MAP_JET }; +export { ToolStyleConverter, ToolStyleUtils, COLOR_MAP_JET }; From 8dd19129b8e8d154b91bfffc2abc273c0202171c Mon Sep 17 00:00:00 2001 From: liuyong1_vendor Date: Mon, 3 Apr 2023 19:16:38 +0800 Subject: [PATCH 34/41] feat(pointcloud): Add intelligent fit --- .../src/core/pointCloud/index.ts | 96 +++++++++++++++---- .../pointCloudView/PointCloudTopView.tsx | 2 +- .../hooks/usePointCloudViews.ts | 30 ++++-- packages/lb-utils/src/PointCloudUtils.ts | 24 +++++ packages/lb-utils/src/types/pointCloud.ts | 2 + 5 files changed, 124 insertions(+), 30 deletions(-) diff --git a/packages/lb-annotation/src/core/pointCloud/index.ts b/packages/lb-annotation/src/core/pointCloud/index.ts index 798897148..14989e441 100644 --- a/packages/lb-annotation/src/core/pointCloud/index.ts +++ b/packages/lb-annotation/src/core/pointCloud/index.ts @@ -15,6 +15,7 @@ import { I3DSpaceCoord, IPointCloudConfig, toolStyleConverter, + PointCloudUtils, } from '@labelbee/lb-utils'; import { BufferAttribute, OrthographicCamera, PerspectiveCamera, PointsMaterial, Shader } from 'three'; import HighlightWorker from 'web-worker:./highlightWorker.js'; @@ -26,6 +27,7 @@ import { PCDLoader } from './PCDLoader'; import { OrbitControls } from './OrbitControls'; import { PointCloudCache } from './cache'; import { getCuboidFromPointCloudBox } from './matrix'; +import MathUtils from '@/utils/MathUtils'; interface IOrthographicCamera { left: number; @@ -812,39 +814,93 @@ export class PointCloud { return canvas; } + // Filter road points and noise in all directions + public filterNoise(pointList: I3DSpaceCoord[]) { + let newPointList = [...pointList]; + newPointList.sort((a, b) => a.z - b.z); + + const startIndexZ = Math.floor(newPointList.length * 0.05); + const roadPoint = newPointList[startIndexZ]; + newPointList = newPointList.filter(({ z }) => z > roadPoint.z + 0.1); + + const noisePercent = 0.005; + const endIndexZ = Math.floor(newPointList.length * (1 - noisePercent)); + newPointList = newPointList.slice(0, endIndexZ); + + newPointList.sort((a, b) => a.x - b.x); + const startIndexX = Math.floor(newPointList.length * noisePercent); + const endIndexX = Math.floor(newPointList.length * (1 - noisePercent)); + newPointList = newPointList.slice(startIndexX, endIndexX); + + newPointList.sort((a, b) => a.y - b.y); + const startIndexY = Math.floor(newPointList.length * noisePercent); + const endIndexY = Math.floor(newPointList.length * (1 - noisePercent)); + newPointList = newPointList.slice(startIndexY, endIndexY); + + return newPointList.length > 100 ? newPointList : pointList; + } + public getSensesPointZAxisInPolygon(polygon: IPolygonPoint[], zScope?: [number, number]) { const points = this.scene.children.find((i) => i.uuid === this.pointsUuid) as THREE.Points; let minZ = 0; let maxZ = 0; let count = 0; // The count of scope let zCount = 0; // The Count of Polygon range + let worldPointList: ICoordinate[] = []; // Vertex coordinates after fitting(ThreeJs coordinates) + let inPolygonList: I3DSpaceCoord[] = []; // Points within the polygon range - if (points && points?.geometry) { - const pointPosArray = points?.geometry.attributes.position.array; - - for (let idx = 0; idx < pointPosArray.length; idx += 3) { - const x = pointPosArray[idx]; - const y = pointPosArray[idx + 1]; - const z = pointPosArray[idx + 2]; + if (!points?.geometry) { + return { maxZ, minZ, count, zCount, worldPointList }; + } - const inPolygon = isInPolygon({ x, y }, polygon); + const pointPosArray = points?.geometry.attributes.position.array; - if (inPolygon && z) { - maxZ = Math.max(z, maxZ); - minZ = Math.min(z, minZ); + for (let idx = 0; idx < pointPosArray.length; idx += 3) { + const x = pointPosArray[idx]; + const y = pointPosArray[idx + 1]; + const z = pointPosArray[idx + 2]; + const inPolygon = isInPolygon({ x, y }, polygon); + if (inPolygon && (z || z === 0)) { + inPolygonList.push({ x, y, z }); + } + } - zCount++; + inPolygonList = this.filterNoise(inPolygonList).sort((a, b) => a.z - b.z); + minZ = inPolygonList[0].z - 0.01; + maxZ = inPolygonList[inPolygonList.length - 1].z + 0.01; + zCount = inPolygonList.length; + const minDistanceList: Array<{ distance: number; point: ICoordinate }> = []; - if (zScope) { - if (z >= zScope[0] && z <= zScope[1]) { - count++; - } - } - } + inPolygonList.forEach(({ x, y, z }) => { + if (zScope && z >= zScope[0] && z <= zScope[1]) { + count++; } - } + polygon.forEach((p1, index) => { + const _polygon = [...polygon, polygon[0]]; + const p2 = _polygon[index + 1]; + const distance = MathUtils.getFootOfPerpendicular({ x, y }, p1, p2).length; + if (!minDistanceList[index] || distance < minDistanceList[index].distance) { + minDistanceList[index] = { distance, point: { x, y } }; + } + }); + }); + + // todo should leave a little margin + worldPointList = polygon.map((_, index) => { + const _polygon = [polygon[polygon.length - 1], ...polygon, polygon[0]]; + const _minDistanceList = [minDistanceList[minDistanceList.length - 1], ...minDistanceList]; + const p1 = _polygon[index]; + const p2 = _polygon[index + 1]; + const p3 = _polygon[index + 2]; + return PointCloudUtils.getIntersectionBySlope({ + p1: _minDistanceList[index].point, + k1: (p1.y - p2.y) / (p1.x - p2.x), + p2: _minDistanceList[index + 1].point, + k2: (p2.y - p3.y) / (p2.x - p3.x), + }); + }); - return { maxZ, minZ, count, zCount }; + return { maxZ, minZ, count, zCount, worldPointList }; } /** diff --git a/packages/lb-components/src/components/pointCloudView/PointCloudTopView.tsx b/packages/lb-components/src/components/pointCloudView/PointCloudTopView.tsx index e3447a268..a3644bc34 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloudTopView.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloudTopView.tsx @@ -215,7 +215,7 @@ const PointCloudTopView: React.FC = ({ } pointCloudViews.topViewAddBox({ - newPolygon: polygon, + polygon, size, imgList, trackConfigurable: config.trackConfigurable, diff --git a/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts b/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts index 14b12e5ee..c5a5d948a 100644 --- a/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts +++ b/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts @@ -31,6 +31,7 @@ import { useTranslation } from 'react-i18next'; import { useHistory } from './useHistory'; import { usePolygon } from './usePolygon'; import { IFileItem } from '@/types/data'; +import { ICoordinate } from '@labelbee/lb-utils/src/types/common'; const DEFAULT_SCOPE = 5; const DEFAULT_RADIUS = 90; @@ -49,28 +50,33 @@ export const topViewPolygon2PointCloud = ( selectedPointCloudBox?: IPointCloudBox, defaultValue?: { [v: string]: any }, ) => { - const [point1, point2, point3, point4] = newPolygon.pointList.map((v: any) => + let worldPointList = newPolygon.pointList.map((v: any) => PointCloudUtils.transferCanvas2World(v, size), ); - - const centerPoint = MathUtils.getLineCenterPoint([point1, point3]); - const height = MathUtils.getLineLength(point1, point2); - const width = MathUtils.getLineLength(point2, point3); - const rotation = MathUtils.getRadiusFromQuadrangle(newPolygon.pointList); let z = 0; let depth = 1; let extraData = {}; // Init PointCloud Data if (pointCloud) { - const zInfo = pointCloud.getSensesPointZAxisInPolygon([point1, point2, point3, point4]); + const zInfo = pointCloud.getSensesPointZAxisInPolygon(worldPointList); + worldPointList = zInfo.worldPointList; z = (zInfo.maxZ + zInfo.minZ) / 2; depth = zInfo.maxZ - zInfo.minZ; extraData = { count: zInfo.zCount, + newPointList: worldPointList.map((v: ICoordinate) => + PointCloudUtils.transferWorld2Canvas(v, size), + ), }; } + const [point1, point2, point3] = worldPointList; + const centerPoint = MathUtils.getLineCenterPoint([point1, point3]); + const height = MathUtils.getLineLength(point1, point2); + const width = MathUtils.getLineLength(point2, point3); + const rotation = MathUtils.getRadiusFromQuadrangle(newPolygon.pointList); + if (selectedPointCloudBox) { z = selectedPointCloudBox.center.z; depth = selectedPointCloudBox.depth; @@ -403,13 +409,13 @@ export const usePointCloudViews = () => { /** Top-view create box from 2D */ const topViewAddBox = ({ - newPolygon, + polygon, size, imgList, trackConfigurable, zoom, }: { - newPolygon: any; + polygon: any; size: ISize; imgList: IFileItem[]; trackConfigurable?: boolean; @@ -428,6 +434,7 @@ export const usePointCloudViews = () => { }); } + const newPolygon = { ...polygon }; const newParams = topViewPolygon2PointCloud( newPolygon, size, @@ -450,6 +457,10 @@ export const usePointCloudViews = () => { return; } + if (newParams.newPointList?.length) { + newPolygon.pointList = newParams.newPointList; + } + const isBoxHidden = hideAttributes.includes(newPolygon.attribute); const newPointCloudList = addPointCloudBox(boxParams); @@ -460,6 +471,7 @@ export const usePointCloudViews = () => { setSelectedIDs(boxParams.id); polygonOperation.setSelectedIDs([newPolygon.id]); syncPointCloudViews(PointCloudView.Top, newPolygon, boxParams, zoom, newPointCloudList); + synchronizeTopView(boxParams, newPolygon, topViewInstance, mainViewInstance); } addHistory({ newBoxParams: boxParams }); diff --git a/packages/lb-utils/src/PointCloudUtils.ts b/packages/lb-utils/src/PointCloudUtils.ts index 4197c56f6..d3ed00c0e 100644 --- a/packages/lb-utils/src/PointCloudUtils.ts +++ b/packages/lb-utils/src/PointCloudUtils.ts @@ -5,6 +5,7 @@ */ import { IPolygonData } from './types'; +import { ICoordinate } from './types/common'; import { IPointCloudBox, IPointCloudConfig } from './types/pointCloud'; class PointCloudUtils { @@ -533,6 +534,29 @@ class PointCloudUtils { }; }); } + + /** + * Get intersection coordinates by slope + * @param p1 A point on line1 + * @param k1 The slope of line1 + * @param p2 A point on line2 + * @param k2 The slope of line2 + */ + static getIntersectionBySlope(params: { + p1: ICoordinate; + k1: number; + p2: ICoordinate; + k2: number; + }) { + const { p1, k1, p2, k2 } = params; + if (p1.x === p2.x && p1.y === p2.y) { + return p1; + } + const x = (p1.y - p2.y - k1 * p1.x + k2 * p2.x) / (k2 - k1); + const y = p1.y - k1 * (p1.x - x); + + return { x, y }; + } } export default PointCloudUtils; diff --git a/packages/lb-utils/src/types/pointCloud.ts b/packages/lb-utils/src/types/pointCloud.ts index 12f4ef5df..b4c9c81be 100644 --- a/packages/lb-utils/src/types/pointCloud.ts +++ b/packages/lb-utils/src/types/pointCloud.ts @@ -8,6 +8,7 @@ import { IInputList } from './base'; import { IPolygonData } from './polygon'; +import { ICoordinate } from "./common"; export type TMatrix4Tuple = [ number, @@ -85,6 +86,7 @@ export interface IPointCloudBox extends IVolume { [k: string]: string; }; count?: number; + newPointList?: ICoordinate[]; } /** IPointCloudBox */ From 11371272dc4e60200644020e5c760b4de441db4c Mon Sep 17 00:00:00 2001 From: liuyong1_vendor Date: Wed, 12 Apr 2023 14:34:09 +0800 Subject: [PATCH 35/41] feat(pointcloud): Add intelligent fit switch --- .../src/core/pointCloud/index.ts | 97 +++++++++++-------- packages/lb-components/src/App.tsx | 8 +- .../pointCloudView/PointCloudTopView.tsx | 3 + .../hooks/usePointCloudViews.ts | 20 +++- .../src/components/pointCloudView/index.tsx | 14 ++- .../src/views/MainView/index.tsx | 6 +- 6 files changed, 96 insertions(+), 52 deletions(-) diff --git a/packages/lb-annotation/src/core/pointCloud/index.ts b/packages/lb-annotation/src/core/pointCloud/index.ts index 14989e441..686d21313 100644 --- a/packages/lb-annotation/src/core/pointCloud/index.ts +++ b/packages/lb-annotation/src/core/pointCloud/index.ts @@ -23,11 +23,11 @@ import FilterBoxWorker from 'web-worker:./filterBoxWorker.js'; import { isInPolygon } from '@/utils/tool/polygonTool'; import { IPolygonPoint } from '@/types/tool/polygon'; import uuid from '@/utils/uuid'; +import MathUtils from '@/utils/MathUtils'; import { PCDLoader } from './PCDLoader'; import { OrbitControls } from './OrbitControls'; import { PointCloudCache } from './cache'; import { getCuboidFromPointCloudBox } from './matrix'; -import MathUtils from '@/utils/MathUtils'; interface IOrthographicCamera { left: number; @@ -814,7 +814,12 @@ export class PointCloud { return canvas; } - // Filter road points and noise in all directions + /** + * Filter road points and noise in all directions + * 1. The first 5% of the z-axis is used as the road coordinate + * 2. Filter out points 10cm above the road surface. + * 3. Filter out the first 0.5% of noise points in other directions + */ public filterNoise(pointList: I3DSpaceCoord[]) { let newPointList = [...pointList]; newPointList.sort((a, b) => a.z - b.z); @@ -840,43 +845,12 @@ export class PointCloud { return newPointList.length > 100 ? newPointList : pointList; } - public getSensesPointZAxisInPolygon(polygon: IPolygonPoint[], zScope?: [number, number]) { - const points = this.scene.children.find((i) => i.uuid === this.pointsUuid) as THREE.Points; - let minZ = 0; - let maxZ = 0; - let count = 0; // The count of scope - let zCount = 0; // The Count of Polygon range - let worldPointList: ICoordinate[] = []; // Vertex coordinates after fitting(ThreeJs coordinates) - let inPolygonList: I3DSpaceCoord[] = []; // Points within the polygon range - - if (!points?.geometry) { - return { maxZ, minZ, count, zCount, worldPointList }; - } - - const pointPosArray = points?.geometry.attributes.position.array; - - for (let idx = 0; idx < pointPosArray.length; idx += 3) { - const x = pointPosArray[idx]; - const y = pointPosArray[idx + 1]; - const z = pointPosArray[idx + 2]; - const inPolygon = isInPolygon({ x, y }, polygon); - if (inPolygon && (z || z === 0)) { - inPolygonList.push({ x, y, z }); - } - } - - inPolygonList = this.filterNoise(inPolygonList).sort((a, b) => a.z - b.z); - minZ = inPolygonList[0].z - 0.01; - maxZ = inPolygonList[inPolygonList.length - 1].z + 0.01; - zCount = inPolygonList.length; + // Get the polygon coordinates after fitting + public getFittedCoordinates(polygon: IPolygonPoint[], innerPointList: ICoordinate[]) { const minDistanceList: Array<{ distance: number; point: ICoordinate }> = []; - - inPolygonList.forEach(({ x, y, z }) => { - if (zScope && z >= zScope[0] && z <= zScope[1]) { - count++; - } + let _polygon = [...polygon, polygon[0]]; + innerPointList.forEach(({ x, y }) => { polygon.forEach((p1, index) => { - const _polygon = [...polygon, polygon[0]]; const p2 = _polygon[index + 1]; const distance = MathUtils.getFootOfPerpendicular({ x, y }, p1, p2).length; if (!minDistanceList[index] || distance < minDistanceList[index].distance) { @@ -885,10 +859,10 @@ export class PointCloud { }); }); - // todo should leave a little margin - worldPointList = polygon.map((_, index) => { - const _polygon = [polygon[polygon.length - 1], ...polygon, polygon[0]]; - const _minDistanceList = [minDistanceList[minDistanceList.length - 1], ...minDistanceList]; + // todo: should leave a little margin + _polygon = [polygon[polygon.length - 1], ...polygon, polygon[0]]; + const _minDistanceList = [minDistanceList[minDistanceList.length - 1], ...minDistanceList]; + const fittedCoordinates = polygon.map((_, index) => { const p1 = _polygon[index]; const p2 = _polygon[index + 1]; const p3 = _polygon[index + 2]; @@ -899,8 +873,47 @@ export class PointCloud { k2: (p2.y - p3.y) / (p2.x - p3.x), }); }); + return fittedCoordinates; + } + + public getSensesPointZAxisInPolygon(polygon: IPolygonPoint[], zScope?: [number, number], intelligentFit?: boolean) { + const points = this.scene.children.find((i) => i.uuid === this.pointsUuid) as THREE.Points; + let minZ = 0; + let maxZ = 0; + let count = 0; // The count of scope + let zCount = 0; // The Count of Polygon range + let fittedCoordinates: ICoordinate[] = []; // Vertex coordinates after fitting(ThreeJs coordinates) + let innerPointList: I3DSpaceCoord[] = []; // Points within the polygon range + + if (!points?.geometry) { + return { maxZ, minZ, count, zCount, fittedCoordinates: [] }; + } + + const pointPosArray = points?.geometry.attributes.position.array; + + for (let idx = 0; idx < pointPosArray.length; idx += 3) { + const x = pointPosArray[idx]; + const y = pointPosArray[idx + 1]; + const z = pointPosArray[idx + 2]; + const inPolygon = isInPolygon({ x, y }, polygon); + if (inPolygon && (z || z === 0)) { + innerPointList.push({ x, y, z }); + } + } + + if (intelligentFit) { + innerPointList = this.filterNoise(innerPointList); + fittedCoordinates = this.getFittedCoordinates(polygon, innerPointList); + } + innerPointList.sort((a, b) => a.z - b.z); + minZ = innerPointList[0].z - 0.01; + maxZ = innerPointList[innerPointList.length - 1].z + 0.01; + zCount = innerPointList.length; + if (zScope) { + count = innerPointList.filter(({ z }) => z >= zScope[0] && z <= zScope[1]).length; + } - return { maxZ, minZ, count, zCount, worldPointList }; + return { maxZ, minZ, count, zCount, fittedCoordinates }; } /** diff --git a/packages/lb-components/src/App.tsx b/packages/lb-components/src/App.tsx index 090cd3786..8241893fe 100644 --- a/packages/lb-components/src/App.tsx +++ b/packages/lb-components/src/App.tsx @@ -90,6 +90,7 @@ export interface AppProps { customRenderStyle?: (data: any) => IAnnotationStyle; checkMode?: boolean; + intelligentFit?: boolean; } const App: React.FC = (props) => { @@ -111,7 +112,8 @@ const App: React.FC = (props) => { defaultLang = 'cn', skipBeforePageTurning, beforeRotate, - checkMode = false + checkMode = false, + intelligentFit = true, } = props; useEffect(() => { @@ -128,7 +130,7 @@ const App: React.FC = (props) => { onStepChange, skipBeforePageTurning, beforeRotate, - checkMode + checkMode, }), ); @@ -204,7 +206,7 @@ const App: React.FC = (props) => { return (
- +
); diff --git a/packages/lb-components/src/components/pointCloudView/PointCloudTopView.tsx b/packages/lb-components/src/components/pointCloudView/PointCloudTopView.tsx index a3644bc34..fefde6876 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloudTopView.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloudTopView.tsx @@ -145,6 +145,7 @@ const ZAxisSlider = ({ interface IProps extends IA2MapStateProps { drawLayerSlot?: TDrawLayerSlot; checkMode?: boolean; + intelligentFit?: boolean; } const PointCloudTopView: React.FC = ({ @@ -153,6 +154,7 @@ const PointCloudTopView: React.FC = ({ stepInfo, drawLayerSlot, checkMode, + intelligentFit, }) => { const [annotationPos, setAnnotationPos] = useState({ zoom: 1, currentPos: { x: 0, y: 0 } }); const ref = useRef(null); @@ -220,6 +222,7 @@ const PointCloudTopView: React.FC = ({ imgList, trackConfigurable: config.trackConfigurable, zoom, + intelligentFit, }); }); diff --git a/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts b/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts index c5a5d948a..f34e9b985 100644 --- a/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts +++ b/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts @@ -49,6 +49,7 @@ export const topViewPolygon2PointCloud = ( pointCloud?: PointCloud, selectedPointCloudBox?: IPointCloudBox, defaultValue?: { [v: string]: any }, + intelligentFit?: boolean, ) => { let worldPointList = newPolygon.pointList.map((v: any) => PointCloudUtils.transferCanvas2World(v, size), @@ -59,8 +60,14 @@ export const topViewPolygon2PointCloud = ( // Init PointCloud Data if (pointCloud) { - const zInfo = pointCloud.getSensesPointZAxisInPolygon(worldPointList); - worldPointList = zInfo.worldPointList; + const zInfo = pointCloud.getSensesPointZAxisInPolygon( + worldPointList, + undefined, + intelligentFit, + ); + if (intelligentFit) { + worldPointList = zInfo.fittedCoordinates; + } z = (zInfo.maxZ + zInfo.minZ) / 2; depth = zInfo.maxZ - zInfo.minZ; extraData = { @@ -414,12 +421,14 @@ export const usePointCloudViews = () => { imgList, trackConfigurable, zoom, + intelligentFit, }: { polygon: any; size: ISize; imgList: IFileItem[]; trackConfigurable?: boolean; zoom: number; + intelligentFit?: boolean; }) => { const extraData = { attribute: topViewInstance.pointCloud2dOperation.defaultAttribute ?? '', @@ -441,6 +450,7 @@ export const usePointCloudViews = () => { topViewPointCloud, undefined, extraData, + intelligentFit, ); const polygonOperation = topViewInstance?.pointCloud2dOperation; @@ -457,7 +467,7 @@ export const usePointCloudViews = () => { return; } - if (newParams.newPointList?.length) { + if (intelligentFit && newParams.newPointList?.length) { newPolygon.pointList = newParams.newPointList; } @@ -471,7 +481,9 @@ export const usePointCloudViews = () => { setSelectedIDs(boxParams.id); polygonOperation.setSelectedIDs([newPolygon.id]); syncPointCloudViews(PointCloudView.Top, newPolygon, boxParams, zoom, newPointCloudList); - synchronizeTopView(boxParams, newPolygon, topViewInstance, mainViewInstance); + if (intelligentFit) { + synchronizeTopView(boxParams, newPolygon, topViewInstance, mainViewInstance); + } } addHistory({ newBoxParams: boxParams }); diff --git a/packages/lb-components/src/components/pointCloudView/index.tsx b/packages/lb-components/src/components/pointCloudView/index.tsx index 9c3438494..ca8a0ec7a 100644 --- a/packages/lb-components/src/components/pointCloudView/index.tsx +++ b/packages/lb-components/src/components/pointCloudView/index.tsx @@ -33,9 +33,15 @@ interface IProps { imgList: IFileItem[]; drawLayerSlot?: TDrawLayerSlot; checkMode?: boolean; + intelligentFit?: boolean; } -const PointCloudView: React.FC = ({ imgList, drawLayerSlot, checkMode }) => { +const PointCloudView: React.FC = ({ + imgList, + drawLayerSlot, + checkMode, + intelligentFit, +}) => { if (imgList.length === 0) { return null; } @@ -54,7 +60,11 @@ const PointCloudView: React.FC = ({ imgList, drawLayerSlot, checkMode })
- +
diff --git a/packages/lb-components/src/views/MainView/index.tsx b/packages/lb-components/src/views/MainView/index.tsx index 047210307..6343ba873 100644 --- a/packages/lb-components/src/views/MainView/index.tsx +++ b/packages/lb-components/src/views/MainView/index.tsx @@ -43,7 +43,11 @@ const ImageAnnotate: React.FC = (props) => { const PointCloudAnnotate: React.FC = (props) => { return ( <> - + ); From 980a5265a55fcef5191e881c198654f4b1ce1dc0 Mon Sep 17 00:00:00 2001 From: lihqi <455711093@qq.com> Date: Wed, 12 Apr 2023 14:38:17 +0800 Subject: [PATCH 36/41] feat(pointcloud): Add comments --- .../predictTracking/previewResult/index.tsx | 9 ++- .../predictTracking/previewResult/util.ts | 62 ++++++++++++++++++- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/packages/lb-components/src/components/predictTracking/previewResult/index.tsx b/packages/lb-components/src/components/predictTracking/previewResult/index.tsx index 04ca0dc93..4925cdee1 100644 --- a/packages/lb-components/src/components/predictTracking/previewResult/index.tsx +++ b/packages/lb-components/src/components/predictTracking/previewResult/index.tsx @@ -7,8 +7,10 @@ import { connect } from 'react-redux'; import { PointCloudContext } from '@/components/pointCloudView/PointCloudContext'; import { AppState } from '@/store'; import { - BatchUpdateImgListResultByPredictResult, SetPointCloudLoading, SetPredictResult, - SetPredictResultVisible + BatchUpdateImgListResultByPredictResult, + SetPointCloudLoading, + SetPredictResult, + SetPredictResultVisible, } from '@/store/annotation/actionCreators'; import { IPointCloudBoxWithIndex } from '@/store/annotation/types'; import { LabelBeeContext, useDispatch } from '@/store/ctx'; @@ -177,7 +179,7 @@ const GenerateViewsDataUrl = (props: { const url = imgList[index].url ? imgList[index].url : // @ts-ignore - imgList[index].webPointCloudFile.lidar.url; + imgList[index]?.webPointCloudFile?.lidar?.url ?? ''; await pointCloud.loadPCDFileByBox(url, item, { width: 2, @@ -195,6 +197,7 @@ const GenerateViewsDataUrl = (props: { pointCloud.generateBox(item, hex); // TODO + // getViewsDataUrl requires pointCloud to finish loading the 3D view, otherwise it will not capture the correct image await sleep(500); await getViewsDataUrl(pointCloud, item, ptCtx.zoom); await pointCloud.removeObjectByName(item.id); diff --git a/packages/lb-components/src/components/predictTracking/previewResult/util.ts b/packages/lb-components/src/components/predictTracking/previewResult/util.ts index 053c1f290..115b41acf 100644 --- a/packages/lb-components/src/components/predictTracking/previewResult/util.ts +++ b/packages/lb-components/src/components/predictTracking/previewResult/util.ts @@ -4,10 +4,31 @@ import { jsonParser } from '@/utils'; import { PointCloud, uuid } from '@labelbee/lb-annotation'; import { EPerspectiveView, IPointCloudBox } from '@labelbee/lb-utils'; +const EXAMPLE_IMAGE_SIZE = { + width: 160, + height: 110, +} as const; + +/** + * Returns a data URL for an image of the rendered point cloud. + * @param renderer - The PointCloud renderer to use. + * @param zoom - The zoom level of the image. Defaults to 2. + * @returns A Promise resolving to a string data URL of the rendered image. + */ const getDataUrl = async (renderer: PointCloud['renderer'], zoom = 2) => { - return cropAndEnlarge(renderer.domElement, 160, 110, zoom); + return cropAndEnlarge( + renderer.domElement, + EXAMPLE_IMAGE_SIZE.width, + EXAMPLE_IMAGE_SIZE.height, + zoom, + ); }; +/** + * Returns a Promise that resolves after the specified duration. + * @param ms - The duration to sleep, in milliseconds. + * @returns A Promise that resolves after `ms` milliseconds. + */ export const sleep = (time = 300) => { return new Promise((resolve) => { setTimeout(() => { @@ -26,6 +47,14 @@ interface viewDataUrl { export type IBox = IPointCloudBoxWithIndex & viewDataUrl; +/** + * Generates data URLs for each view of a given point cloud object using the provided box and zoom level. + * + * @param {PointCloud} pointCloud - The point cloud object to generate data URLs for. + * @param {IBox} box - An object representing the bounding box to use for calculating camera position. + * @param {number} zoom - The zoom level to use when generating data URLs. + * @returns {Promise} - A promise that resolves once all data URLs have been generated. + */ export const getViewsDataUrl = async (pointCloud: PointCloud, box: IBox, zoom: number) => { for (const view of views) { await pointCloud.updateCameraByBox(box, view); @@ -33,6 +62,16 @@ export const getViewsDataUrl = async (pointCloud: PointCloud, box: IBox, zoom: n } }; +/** + * Creates a new canvas, crops and enlarges an existing canvas, draws the cropped and enlarged image onto the new canvas, + * and returns the data URL of the new canvas. + * + * @param {HTMLCanvasElement} canvas - The original canvas to be cropped and enlarged + * @param {number} width - The width of the area to be cropped from the center of the original canvas + * @param {number} height - The height of the area to be cropped from the center of the original canvas + * @param {number} scale - The amount by which to enlarge the cropped area + * @returns {string} - A data URL of the cropped and enlarged image + */ const cropAndEnlarge = ( canvas: HTMLCanvasElement, width: number, @@ -61,6 +100,14 @@ const cropAndEnlarge = ( return newCanvas.toDataURL(); }; +/** + * Retrieve boxes with a specific trackID from an array of file items. + * + * @param {Array} imageList - An array of file items to search through. + * @param {Number} targetStep - The step number within the result object to retrieve boxes from. + * @param {Number} selectedBoxTrackID - The trackID to match when searching for boxes. + * @return {Array} An array of point cloud boxes that match the provided trackID, along with their index in the original array. + */ export const getBoxesByTrackID = ( imageList: IFileItem[], targetStep: number, @@ -79,6 +126,12 @@ export const getBoxesByTrackID = ( return matchingBoxes; }; +/** + * Calculate predicted values for each field in between the start and end points. + * @param {IPointCloudBoxWithIndex} start - The starting point, should have the same properties as IPointCloudBoxWithIndex. + * @param {IPointCloudBoxWithIndex} end - The ending point, should have the same properties as IPointCloudBoxWithIndex. + * @returns {IPointCloudBox[]} An array of objects with the same properties as IPointCloudBox, containing interpolated values between the start and end points for each field. + */ export const predict = (start: IPointCloudBoxWithIndex, end: IPointCloudBoxWithIndex) => { const diff = end.index - start.index; const len = diff - 1; @@ -124,6 +177,13 @@ export const predict = (start: IPointCloudBoxWithIndex, end: IPointCloudBoxWithI return result; }; +/** + * Calculate an array of numbers between the start and end values. + * @param {number} [start=0] - The starting value. Defaults to 0 if not specified. + * @param {number} [end=0] - The ending value. Defaults to 0 if not specified. + * @param {number} [length=0] - The number of values to calculate between the start and end points. Defaults to 0 if not specified. + * @returns {number[]} An array of numbers, containing interpolated values between the start and end points. + */ const getInteriorNumbersByStartAndEnd = (start = 0, end = 0, length = 0): number[] => { const step = (end - start) / (length + 1); const resultArr = new Array(length); From 1d06628dbde7f60de1c30403cb96fbbdf78cdf5a Mon Sep 17 00:00:00 2001 From: liuyong1_vendor Date: Wed, 12 Apr 2023 15:14:27 +0800 Subject: [PATCH 37/41] feat(pointcloud): The function getFootOfPerpendicular allows over range --- packages/lb-annotation/src/core/pointCloud/index.ts | 2 +- packages/lb-annotation/src/utils/MathUtils.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/lb-annotation/src/core/pointCloud/index.ts b/packages/lb-annotation/src/core/pointCloud/index.ts index 686d21313..4c57093bb 100644 --- a/packages/lb-annotation/src/core/pointCloud/index.ts +++ b/packages/lb-annotation/src/core/pointCloud/index.ts @@ -852,7 +852,7 @@ export class PointCloud { innerPointList.forEach(({ x, y }) => { polygon.forEach((p1, index) => { const p2 = _polygon[index + 1]; - const distance = MathUtils.getFootOfPerpendicular({ x, y }, p1, p2).length; + const distance = MathUtils.getFootOfPerpendicular({ x, y }, p1, p2, false, true).length; if (!minDistanceList[index] || distance < minDistanceList[index].distance) { minDistanceList[index] = { distance, point: { x, y } }; } diff --git a/packages/lb-annotation/src/utils/MathUtils.ts b/packages/lb-annotation/src/utils/MathUtils.ts index eeeb5eb27..7b71d60b2 100644 --- a/packages/lb-annotation/src/utils/MathUtils.ts +++ b/packages/lb-annotation/src/utils/MathUtils.ts @@ -150,6 +150,7 @@ export default class MathUtils { end: ICoordinate, /* 使用坐标范围 */ useAxisRange = false, + allowOverRange = false, ) => { // 直线结束点 let retVal: any = { x: 0, y: 0 }; @@ -183,7 +184,7 @@ export default class MathUtils { const isOverRange = useAxisRange ? allAxisOverRange : someAxisOverRange; - if (isOverRange) { + if (!allowOverRange && isOverRange) { return { footPoint: retVal, length: Infinity, From a6fbe77be2503c5ae9a2fe69c2ead166ed96a8a4 Mon Sep 17 00:00:00 2001 From: liuyong1_vendor Date: Wed, 12 Apr 2023 16:50:04 +0800 Subject: [PATCH 38/41] feat(pointcloud): Export the polygon coordinates after fitting --- .../hooks/usePointCloudViews.ts | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts b/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts index f34e9b985..04f8a534d 100644 --- a/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts +++ b/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts @@ -72,9 +72,6 @@ export const topViewPolygon2PointCloud = ( depth = zInfo.maxZ - zInfo.minZ; extraData = { count: zInfo.zCount, - newPointList: worldPointList.map((v: ICoordinate) => - PointCloudUtils.transferWorld2Canvas(v, size), - ), }; } @@ -121,7 +118,12 @@ export const topViewPolygon2PointCloud = ( Object.assign(boxParams, defaultValue); } - return boxParams; + // Polygon coordinates after fitting + const newPointList = worldPointList.map((v: ICoordinate) => + PointCloudUtils.transferWorld2Canvas(v, size), + ); + + return { boxParams, newPointList }; }; const sideViewPolygon2PointCloud = ( @@ -444,7 +446,7 @@ export const usePointCloudViews = () => { } const newPolygon = { ...polygon }; - const newParams = topViewPolygon2PointCloud( + const { boxParams, newPointList } = topViewPolygon2PointCloud( newPolygon, size, topViewPointCloud, @@ -454,21 +456,19 @@ export const usePointCloudViews = () => { ); const polygonOperation = topViewInstance?.pointCloud2dOperation; - const boxParams: IPointCloudBox = newParams; - // If the count is less than lowerLimitPointsNumInBox, needs to delete it if ( config?.lowerLimitPointsNumInBox && - typeof newParams.count === 'number' && - newParams.count < config.lowerLimitPointsNumInBox + typeof boxParams.count === 'number' && + boxParams.count < config.lowerLimitPointsNumInBox ) { message.info(t('LowerLimitPointsNumInBox', { num: config.lowerLimitPointsNumInBox })); - polygonOperation.deletePolygon(newParams.id); + polygonOperation.deletePolygon(boxParams.id); return; } - if (intelligentFit && newParams.newPointList?.length) { - newPolygon.pointList = newParams.newPointList; + if (intelligentFit && newPointList?.length) { + newPolygon.pointList = newPointList; } const isBoxHidden = hideAttributes.includes(newPolygon.attribute); @@ -595,14 +595,14 @@ export const usePointCloudViews = () => { const updatePointCloudList: IPointCloudBox[] = updateList.map(({ newPolygon: polygon }) => { const pointCloudBox = getPointCloudByID(polygon.id); - const newBoxParams = topViewPolygon2PointCloud( + const { boxParams } = topViewPolygon2PointCloud( polygon, size, topViewInstance.pointCloudInstance, pointCloudBox, ); - return newBoxParams; + return boxParams; }); /** From f9691a88b822eef339127f12a5b8f676cfbc59df Mon Sep 17 00:00:00 2001 From: laoluo Date: Wed, 12 Apr 2023 16:50:59 +0800 Subject: [PATCH 39/41] chore: Update offical version --- packages/lb-annotation/package.json | 4 ++-- packages/lb-components/package.json | 6 +++--- packages/lb-demo/package.json | 8 ++++---- packages/lb-utils/package.json | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/lb-annotation/package.json b/packages/lb-annotation/package.json index 126c3d55d..722f56720 100644 --- a/packages/lb-annotation/package.json +++ b/packages/lb-annotation/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-annotation", - "version": "1.13.0-alpha.7", + "version": "1.13.0", "description": "Annotation tool collection", "keywords": [ "annotation", @@ -92,7 +92,7 @@ "typescript": "^4.2.3" }, "dependencies": { - "@labelbee/lb-utils": "^1.6.0-alpha.5", + "@labelbee/lb-utils": "^1.6.0", "@turf/turf": "5.1.6", "color-rgba": "^2.3.0", "lodash": "^4.17.20", diff --git a/packages/lb-components/package.json b/packages/lb-components/package.json index 6c826d042..5f7992218 100644 --- a/packages/lb-components/package.json +++ b/packages/lb-components/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-components", - "version": "1.9.0-alpha.8", + "version": "1.9.0", "description": "Provide a complete library of annotation components", "main": "./dist/index.js", "es": "./es/index.js", @@ -41,8 +41,8 @@ }, "dependencies": { "@ant-design/icons": "^4.6.2", - "@labelbee/lb-annotation": "^1.13.0-alpha.7", - "@labelbee/lb-utils": "^1.6.0-alpha.5", + "@labelbee/lb-annotation": "^1.13.0", + "@labelbee/lb-utils": "^1.6.0", "ahooks": "^3.4.0", "classnames": "^2.3.0", "lodash": "^4.17.21", diff --git a/packages/lb-demo/package.json b/packages/lb-demo/package.json index d7cf82b23..fd0df3e36 100644 --- a/packages/lb-demo/package.json +++ b/packages/lb-demo/package.json @@ -1,11 +1,11 @@ { "name": "lb-demo", - "version": "1.10.1-alpha.5", + "version": "1.10.1", "private": true, "dependencies": { - "@labelbee/lb-annotation": "^1.13.0-alpha.7", - "@labelbee/lb-components": "^1.9.0-alpha.8", - "@labelbee/lb-utils": "^1.6.0-alpha.5", + "@labelbee/lb-annotation": "^1.13.0", + "@labelbee/lb-components": "^1.9.0", + "@labelbee/lb-utils": "^1.6.0", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", diff --git a/packages/lb-utils/package.json b/packages/lb-utils/package.json index 6434fedf4..2ade1e8d5 100644 --- a/packages/lb-utils/package.json +++ b/packages/lb-utils/package.json @@ -1,6 +1,6 @@ { "name": "@labelbee/lb-utils", - "version": "1.6.0-alpha.5", + "version": "1.6.0", "description": "utils for label-bee", "author": "Glenfiddish ", "license": "Apache-2.0", From 9be3cbf1aa9560340678721703ab9c137b9d91f5 Mon Sep 17 00:00:00 2001 From: laoluo Date: Wed, 12 Apr 2023 16:55:27 +0800 Subject: [PATCH 40/41] chore(release): 1.13.0 --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e156a7cd..dd84c857c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,40 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.13.0](https://github.com/open-mmlab/labelbee/compare/v1.12.1...v1.13.0) (2023-04-12) + + +### Features + +* Extract "FooterPopover" component and uses in annotatedList ([753a7b2](https://github.com/open-mmlab/labelbee/commit/753a7b24f7848bb7e32fa8c85b50cfb2e2fd8351)) +* **pointcloud:** 3Dview sync the direction with topview after selected ([7ed2855](https://github.com/open-mmlab/labelbee/commit/7ed285580defef82c75cb404cf42d5df66bc3bba)) +* **pointcloud:** Adding component for selecting boxes by attribute ([5e6b648](https://github.com/open-mmlab/labelbee/commit/5e6b6487d4c3e30e6dccd8673d60e285ab6119b7)) +* **pointcloud:** Annotated-Attributes-Panel supports fixed layout ([f698cf1](https://github.com/open-mmlab/labelbee/commit/f698cf1fc77769eeaedff3e2f920e04947a0a56f)) +* **pointcloud:** Confirm before deleteGraphByAttr ([e8759ac](https://github.com/open-mmlab/labelbee/commit/e8759acd88c7476348ae6031d1d00ad9eac6ea5b)) +* **pointcloud:** Follow top add tooltip ([f0c360e](https://github.com/open-mmlab/labelbee/commit/f0c360e4fbffa6b9ecf7bb10dfc3e0a7a5221bc0)) +* **pointcloud:** Hide the operation in checkmode(side&backView) ([a12901e](https://github.com/open-mmlab/labelbee/commit/a12901e208bed684561ede01d154195a9c7a5680)) +* **pointcloud:** MainView support to follow top view ([81fba17](https://github.com/open-mmlab/labelbee/commit/81fba17476d3f458f38293fe921058118cb4fbb0)) +* **pointcloud:** Support select spec attribute boxes ([05228c5](https://github.com/open-mmlab/labelbee/commit/05228c5c66bb73166e486b51bab151e204176687)) +* **pointcloud:** Support selecting polygons by attributes ([b0b4a43](https://github.com/open-mmlab/labelbee/commit/b0b4a431a79ebeb6e0e368a18071fdd916f601a5)) +* **pointcloud:** Support updating position by keydown events ([12e6d68](https://github.com/open-mmlab/labelbee/commit/12e6d686a598f64e1ef3da4c4b3db56b90055c58)) +* **pointcloud:** Supports moving multiple selected rects ([dbfa665](https://github.com/open-mmlab/labelbee/commit/dbfa6652bf54eba141799681bf7eb1b74294c178)) +* **pointcloud:** Supports rendering after moving multi-boxes ([4228988](https://github.com/open-mmlab/labelbee/commit/42289888e0883ccdc8a07cfb3c9b42fd8c4f944c)) +* **pointcloud:** Update the backgroundColor of pointCloud ([df16fdc](https://github.com/open-mmlab/labelbee/commit/df16fdc87df911088e800527274cf36cb492da99)) + + +### Bug Fixes + +* **copy-result:** AsyncData needs to determine if it exists ([17dc99a](https://github.com/open-mmlab/labelbee/commit/17dc99a7633e01541650e948d7eeb436a83c1691)) +* **pointcloud:** Fix applyCameraTarget not to apply zoom ([c7b426a](https://github.com/open-mmlab/labelbee/commit/c7b426a6b75b458f4e126cee1df923c44255f5f0)) +* **pointcloud:** Fix attribute list hide attr fail ([7d4d28d](https://github.com/open-mmlab/labelbee/commit/7d4d28d51c7bf49c92b05d9a9957fdb21471f72e)) +* **pointcloud:** Fix size changed and init point cloud result ([f940e42](https://github.com/open-mmlab/labelbee/commit/f940e42d16f66394469e2b46264937418d136856)) +* **pointcloud:** Fix the feature of COPY_BACKWARD_RESULT ([26b3062](https://github.com/open-mmlab/labelbee/commit/26b30624c23267deb262417d4a103c71dee90f7d)) +* **pointcloud:** Init hideAttr while imgIndex changed ([99e5642](https://github.com/open-mmlab/labelbee/commit/99e5642d435f62332434c81537ad5360f48e73cf)) +* **pointcloud:** Prevent default event on ctrl + a ([cf2d147](https://github.com/open-mmlab/labelbee/commit/cf2d147005911fb58c497e1e25b0bc4675fc61af)) +* **pointcloud:** Repeated updates of pointCloudBackView ([bfe634a](https://github.com/open-mmlab/labelbee/commit/bfe634a5f57e6e1ca33547e7b950f7612a6fe449)) +* **pointcloud:** SyncTopview doesn't need to update camera ([634ca61](https://github.com/open-mmlab/labelbee/commit/634ca6196e95a710b762e419ad5800044eab9d24)) +* **pointcloud:** Update attr list style ([d26691e](https://github.com/open-mmlab/labelbee/commit/d26691ec248fc940e63e53850fb2c0ba5ae42e17)) + ### [1.12.1](https://github.com/open-mmlab/labelbee/compare/v1.12.0...v1.12.1) (2023-03-23) diff --git a/package.json b/package.json index 7fbb7fcef..34121260a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "labelbee", "private": true, - "version": "1.12.1", + "version": "1.13.0", "scripts": { "start": "lerna run build:type && lerna run --parallel --stream start", "start:quick": "lerna run --parallel --stream start", From 581a682c1b07daa2c7044073744b34077f7f36be Mon Sep 17 00:00:00 2001 From: laoluo Date: Wed, 12 Apr 2023 21:14:52 +0800 Subject: [PATCH 41/41] refactor(lb-components): Delete the unused function --- .../src/components/pointCloudView/PointCloudBackView.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/lb-components/src/components/pointCloudView/PointCloudBackView.tsx b/packages/lb-components/src/components/pointCloudView/PointCloudBackView.tsx index 09422a197..f9d13b9e6 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloudBackView.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloudBackView.tsx @@ -5,8 +5,6 @@ * @LastEditTime: 2022-07-08 11:08:02 */ import { - getCuboidFromPointCloudBox, - MathUtils, PointCloud, PointCloudAnnotation, THybridToolName,