From 1f7ac06e340883e5106bcc049e5167a01f901f5a Mon Sep 17 00:00:00 2001 From: laoluo Date: Wed, 15 Feb 2023 19:02:59 +0800 Subject: [PATCH] feat(pointcloud): Highlighing pointCLoud by the attribute --- .../src/core/pointCloud/highlightWorker.js | 122 +++++++++++--- .../src/core/pointCloud/index.ts | 82 +++++---- .../src/core/pointCloud/matrix.ts | 1 + .../pointCloudView/PointCloudBackView.tsx | 1 - .../pointCloudView/PointCloudContext.tsx | 49 ++++-- .../pointCloudView/PointCloudListener.tsx | 16 +- .../pointCloudView/PointCloudProvider.tsx | 158 ------------------ .../pointCloudView/hooks/useHistory.ts | 4 +- .../hooks/usePointCloudViews.ts | 28 +++- .../pointCloudView/hooks/useRotate.ts | 6 +- .../pointCloudView/hooks/useSingleBox.ts | 11 +- packages/lb-utils/src/index.ts | 4 +- 12 files changed, 233 insertions(+), 249 deletions(-) delete mode 100644 packages/lb-components/src/components/pointCloudView/PointCloudProvider.tsx diff --git a/packages/lb-annotation/src/core/pointCloud/highlightWorker.js b/packages/lb-annotation/src/core/pointCloud/highlightWorker.js index ce2d292ab..701fc4074 100644 --- a/packages/lb-annotation/src/core/pointCloud/highlightWorker.js +++ b/packages/lb-annotation/src/core/pointCloud/highlightWorker.js @@ -1,26 +1,48 @@ -class PointCloudUtils { - static genColorByCoord(x, y, z) { - if (z <= 0) { - return [128, 128, 128]; +// COLOR_MAP_JET +function createColorMapJet() { + let s; + const p = new Array(256).fill('').map(() => new Array(3).fill('')); + for (let i = 0; i < 20; i++) { + for (s = 0; s < 32; s++) { + p[s][0] = 128 + 4 * s; + p[s][1] = 0; + p[s][2] = 0; } - - if (z < 5) { - return [255, 0, 0]; + p[32][0] = 255; + p[32][1] = 0; + p[32][2] = 0; + for (s = 0; s < 63; s++) { + p[33 + s][0] = 255; + p[33 + s][1] = 4 + 4 * s; + p[33 + s][2] = 0; } - - if (z < 10) { - return [0, 255, 0]; + p[96][0] = 254; + p[96][1] = 255; + p[96][2] = 2; + for (s = 0; s < 62; s++) { + p[97 + s][0] = 250 - 4 * s; + p[97 + s][1] = 255; + p[97 + s][2] = 6 + 4 * s; + } + p[159][0] = 1; + p[159][1] = 255; + p[159][2] = 254; + for (s = 0; s < 64; s++) { + p[160 + s][0] = 0; + p[160 + s][1] = 252 - s * 4; + p[160 + s][2] = 255; + } + for (s = 0; s < 32; s++) { + p[224 + s][0] = 0; + p[224 + s][1] = 0; + p[224 + s][2] = 252 - 4 * s; } - - return [0, 0, 255]; - } - - static getStandardColorByCoord(x, y, z) { - const pdColor = this.genColorByCoord(x, y, z); - return pdColor.map((hex) => hex / 255); } + return p; } +const COLOR_MAP_JET = createColorMapJet(); + export function isInPolygon(checkPoint, polygonPoints, lineType = 0) { let counter = 0; let i; @@ -63,29 +85,77 @@ export function isInPolygon(checkPoint, polygonPoints, lineType = 0) { return true; } +function getNewColorByBox({ zMin, zMax, polygonPointList, attribute, x, y, z, colorList }) { + const inPolygon = isInPolygon({ x, y }, polygonPointList); + if (inPolygon && z >= zMin && z <= zMax) { + if (colorList[attribute]) { + return colorList[attribute].rgba.slice(0, 3).map((v) => v / 255); + } + + return [1, 0, 0]; + } +} + onmessage = function onmessage(e) { - const { zMin, zMax, polygonPointList, position: points, color } = e.data; + const { position: points, color, cuboidList, colorList } = e.data; let num = 0; + let maxZ = -Number.MAX_SAFE_INTEGER; + let minZ = Number.MAX_SAFE_INTEGER; + for (let i = 0; i < points.length; i += 3) { + const z = points[i + 2]; + if (z) { + if (z < minZ) { + minZ = z; + } + if (z > maxZ) { + maxZ = z; + } + } + } + // Loop to determine if it is in range for (let i = 0; i < points.length; i += 3) { const x = points[i]; const y = points[i + 1]; const z = points[i + 2]; - const inPolygon = isInPolygon({ x, y }, polygonPointList); + const newColorInfo = cuboidList + .map((v) => { + return getNewColorByBox({ + polygonPointList: v.polygonPointList, + zMin: v.zMin, + zMax: v.zMax, + x, + y, + z, + attribute: v.attribute, + colorList, + }); + }) + .filter((v) => v) + .pop(); - if (inPolygon && z >= zMin && z <= zMax) { + // Notice. Scope: [0, 1]; + if (newColorInfo) { num++; - color[i] = 0; - color[i + 1] = 1; - color[i + 2] = 1; - } else { - // DEFAULT COLOR RENDERc - const [r, g, b] = PointCloudUtils.getStandardColorByCoord(x, y, z); + const [r, g, b] = newColorInfo; color[i] = r; color[i + 1] = g; color[i + 2] = b; + } else { + // // DEFAULT COLOR RENDERc + // Recover the originPoint + + // const [r, g, b] = PointCloudUtils.genColorByZ({ z, minZ, maxZ }); + const L = maxZ - minZ; + + const index = Math.floor(((z - minZ) / L) * 255); + const newColor = COLOR_MAP_JET[index]; + const [r, g, b] = newColor; + color[i] = r / 255; + color[i + 1] = g / 255; + color[i + 2] = b / 255; } } diff --git a/packages/lb-annotation/src/core/pointCloud/index.ts b/packages/lb-annotation/src/core/pointCloud/index.ts index 00a8e0017..37000f8ce 100644 --- a/packages/lb-annotation/src/core/pointCloud/index.ts +++ b/packages/lb-annotation/src/core/pointCloud/index.ts @@ -16,7 +16,7 @@ import { IPointCloudConfig, toolStyleConverter, } from '@labelbee/lb-utils'; -import { PointsMaterial, Shader } from 'three'; +import { BufferAttribute, PointsMaterial, Shader } from 'three'; import HighlightWorker from 'web-worker:./highlightWorker.js'; import FilterBoxWorker from 'web-worker:./filterBoxWorker.js'; import { isInPolygon } from '@/utils/tool/polygonTool'; @@ -47,7 +47,7 @@ interface IProps { } const DEFAULT_DISTANCE = 30; -const highlightWorker = new HighlightWorker(); +const highlightWorker = new HighlightWorker({ type: 'module' }); export class PointCloud { public renderer: THREE.WebGLRenderer; @@ -272,6 +272,17 @@ export class PointCloud { this.render(); } + public getAllAttributeColor(boxes: IPointCloudBox[]) { + return boxes.reduce((acc: { [k: string]: any }, box) => { + acc[box.attribute] = toolStyleConverter.getColorFromConfig( + { attribute: box.attribute }, + { ...this.config, attributeConfigurable: true }, + {}, + ); + return acc; + }, {}); + } + /* * Remove exist box and add new one to scene * @param boxParams @@ -598,40 +609,51 @@ export class PointCloud { }; /** - * It needs to be updated after load PointCLoud's data. + * It needs to be updated after load PointCloud's data. * @param boxParams * @returns */ - public highlightOriginPointCloud(boxParams: IPointCloudBox) { - if (boxParams && highlightWorker) { - // Temporarily turn off highlighting + public highlightOriginPointCloud(pointCloudBoxList?: IPointCloudBox[]) { + const oldPointCloud = this.scene.getObjectByName(this.pointCloudObjectName) as THREE.Points; + if (!oldPointCloud) { + return; } - // const oldPointCloud: any = this.scene.getObjectByName(this.pointCloudObjectName); - // if (!oldPointCloud) { - // return; - // } + return new Promise((resolve) => { + if (window.Worker) { + const newPointCloudBoxList = pointCloudBoxList ? [...pointCloudBoxList] : []; + + const cuboidList = newPointCloudBoxList.map((v) => getCuboidFromPointCloudBox(v)); + const colorList = this.getAllAttributeColor(cuboidList); + const params = { + cuboidList, + position: oldPointCloud.geometry.attributes.position.array, + color: oldPointCloud.geometry.attributes.color.array, + colorList, + }; - // if (window.Worker) { - // const { zMin, zMax, polygonPointList } = getCuboidFromPointCloudBox(boxParams); - - // const params = { - // boxParams, - // zMin, - // zMax, - // polygonPointList, - // position: oldPointCloud.geometry.attributes.position.array, - // color: oldPointCloud.geometry.attributes.color.array, - // }; - - // highlightWorker.postMessage(params); - // highlightWorker.onmessage = (e: any) => { - // const { color } = e.data; - // oldPointCloud.geometry.attributes.color.array = color; - // oldPointCloud.geometry.attributes.color.needsUpdate = true; - // this.render(); - // }; - // } + highlightWorker.postMessage(params); + highlightWorker.onmessage = (e: any) => { + const { color } = e.data; + const colorAttribute = new THREE.BufferAttribute(color, 3); + colorAttribute.needsUpdate = true; + oldPointCloud.geometry.setAttribute('color', colorAttribute); + resolve(color); + this.render(); + }; + } + }); + } + + public updateColor(color: any[]) { + const oldPointCloud = this.scene.getObjectByName(this.pointCloudObjectName) as THREE.Points; + if (oldPointCloud) { + const colorAttribute = new THREE.BufferAttribute(color, 3); + colorAttribute.needsUpdate = true; + oldPointCloud.geometry.setAttribute('color', colorAttribute); + + this.render(); + } } /** diff --git a/packages/lb-annotation/src/core/pointCloud/matrix.ts b/packages/lb-annotation/src/core/pointCloud/matrix.ts index 8cfbdae8a..023f0cb50 100644 --- a/packages/lb-annotation/src/core/pointCloud/matrix.ts +++ b/packages/lb-annotation/src/core/pointCloud/matrix.ts @@ -109,6 +109,7 @@ export function getCuboidFromPointCloudBox(boxParams: IPointCloudBox) { const zMin = center.z - depth / 2; return { + ...boxParams, polygonPointList, zMax, zMin, diff --git a/packages/lb-components/src/components/pointCloudView/PointCloudBackView.tsx b/packages/lb-components/src/components/pointCloudView/PointCloudBackView.tsx index 6c2aabea2..891008d51 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloudBackView.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloudBackView.tsx @@ -197,7 +197,6 @@ const PointCloudSideView = ({ currentData, config, checkMode }: IA2MapStateProps synchronizeTopView(newBoxParams, newPolygon, ptCtx.topViewInstance, ptCtx.mainViewInstance); synchronizeSideView(newBoxParams, newPolygon, ptCtx.sideViewInstance, currentData.url); - ptCtx.mainViewInstance.highlightOriginPointCloud(newBoxParams); updateSelectedBox(newBoxParams); }, ); diff --git a/packages/lb-components/src/components/pointCloudView/PointCloudContext.tsx b/packages/lb-components/src/components/pointCloudView/PointCloudContext.tsx index 5a2a85d5a..2ed0f2fe2 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloudContext.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloudContext.tsx @@ -24,7 +24,7 @@ export interface IPointCloudContext extends IPointCloudContextInstances { addSelectedID: (selectedID: string) => void; selectedAllBoxes: () => void; selectedID: string; - addPointCloudBox: (boxParams: IPointCloudBox) => void; + addPointCloudBox: (boxParams: IPointCloudBox) => IPointCloudBox[]; polygonList: IPolygonData[]; setPolygonList: (polygonList: IPolygonData[]) => void; @@ -33,6 +33,8 @@ export interface IPointCloudContext extends IPointCloudContextInstances { setZoom: (zoom: number) => void; history: ActionsHistory; // Operation History + + syncAllViewPointCloudColor: (newPointCloudList?: IPointCloudBox[]) => void; } export const PointCloudContext = React.createContext({ @@ -41,21 +43,22 @@ export const PointCloudContext = React.createContext({ selectedID: '', selectedIDs: [], valid: true, - setSelectedIDs: () => {}, - setPointCloudResult: () => {}, - setPointCloudValid: () => {}, - setTopViewInstance: () => {}, - setSideViewInstance: () => {}, - setBackViewInstance: () => {}, - setMainViewInstance: () => {}, - addSelectedID: () => {}, - selectedAllBoxes: () => {}, - addPointCloudBox: () => {}, - setPolygonList: () => {}, + setSelectedIDs: () => { }, + setPointCloudResult: () => { }, + setPointCloudValid: () => { }, + setTopViewInstance: () => { }, + setSideViewInstance: () => { }, + setBackViewInstance: () => { }, + setMainViewInstance: () => { }, + addSelectedID: () => { }, + selectedAllBoxes: () => { }, + addPointCloudBox: () => { return [] }, + setPolygonList: () => { }, zoom: 1, - setZoom: () => {}, + setZoom: () => { }, history: new ActionsHistory(), + syncAllViewPointCloudColor: () => { }, }); export const PointCloudProvider: React.FC<{}> = ({ children }) => { @@ -78,7 +81,9 @@ export const PointCloudProvider: React.FC<{}> = ({ children }) => { const selectedPointCloudBox = pointCloudBoxList.find((v) => v.id === selectedID); const addPointCloudBox = (box: IPointCloudBox) => { - setPointCloudResult(pointCloudBoxList.concat(box)); + const newPointCloudList = pointCloudBoxList.concat(box) + setPointCloudResult(newPointCloudList); + return newPointCloudList; }; const setPointCloudValid = (valid?: boolean) => { @@ -116,6 +121,21 @@ export const PointCloudProvider: React.FC<{}> = ({ children }) => { setSelectedIDs(pointCloudBoxList.map((i) => i.id)); }; + /** + * Synchronize the highlighted pointCloud for all views. + * @param pointCloudList + */ + const syncAllViewPointCloudColor = (pointCloudList?: IPointCloudBox[]) => { + const colorPromise = mainViewInstance?.highlightOriginPointCloud(pointCloudList); + colorPromise?.then((color) => { + [topViewInstance, sideViewInstance, backViewInstance].forEach(instance => { + if (color) { + instance?.pointCloudInstance?.updateColor(color); + } + }) + }) + } + return { selectedID, pointCloudBoxList, @@ -141,6 +161,7 @@ export const PointCloudProvider: React.FC<{}> = ({ children }) => { zoom, setZoom, history, + syncAllViewPointCloudColor, }; }, [ valid, diff --git a/packages/lb-components/src/components/pointCloudView/PointCloudListener.tsx b/packages/lb-components/src/components/pointCloudView/PointCloudListener.tsx index 4bd207ba2..f879f5b4f 100644 --- a/packages/lb-components/src/components/pointCloudView/PointCloudListener.tsx +++ b/packages/lb-components/src/components/pointCloudView/PointCloudListener.tsx @@ -175,7 +175,7 @@ const PointCloudListener: React.FC = ({ currentData, config }) return () => { window.removeEventListener('keydown', onKeyDown); }; - }, [ptCtx, copiedBoxes, config]); + }, [ptCtx, copiedBoxes, config, ptCtx.pointCloudBoxList, ptCtx.polygonList]); useEffect(() => { syncAllViewsConfig(config); @@ -210,8 +210,12 @@ const PointCloudListener: React.FC = ({ currentData, config }) if (selectBox) { selectBox.attribute = newAttribute; - updateSelectedBox(selectBox); + const newPointCloudList = updateSelectedBox(selectBox); reRenderPointCloud3DBox(selectBox); + + if (ptCtx.mainViewInstance) { + ptCtx.syncAllViewPointCloudColor(newPointCloudList); + } } if (selectedPolygon) { pushHistoryUnderUpdatePolygon({ ...selectedPolygon, attribute: newAttribute }); @@ -271,7 +275,13 @@ const PointCloudListener: React.FC = ({ currentData, config }) toolInstanceRef.current.setShowDefaultCursor = (showDefaultCursor: boolean) => { ptCtx.topViewInstance?.pointCloud2dOperation?.setShowDefaultCursor(showDefaultCursor); }; - }, [ptCtx.pointCloudBoxList, ptCtx.selectedID, ptCtx.valid, ptCtx.polygonList]); + }, [ + ptCtx.pointCloudBoxList, + ptCtx.selectedID, + ptCtx.valid, + ptCtx.polygonList, + ptCtx.mainViewInstance, + ]); useEffect(() => { toolInstanceRef.current.history = { diff --git a/packages/lb-components/src/components/pointCloudView/PointCloudProvider.tsx b/packages/lb-components/src/components/pointCloudView/PointCloudProvider.tsx deleted file mode 100644 index 5a2a85d5a..000000000 --- a/packages/lb-components/src/components/pointCloudView/PointCloudProvider.tsx +++ /dev/null @@ -1,158 +0,0 @@ -import { IPointCloudBox, IPointCloudBoxList, IPolygonData } from '@labelbee/lb-utils'; -import { PointCloud, PointCloudAnnotation, ActionsHistory } from '@labelbee/lb-annotation'; -import React, { useMemo, useRef, useState } from 'react'; - -interface IPointCloudContextInstances { - topViewInstance?: PointCloudAnnotation; - sideViewInstance?: PointCloudAnnotation; - backViewInstance?: PointCloudAnnotation; - mainViewInstance?: PointCloud; - setTopViewInstance: (instance: PointCloudAnnotation) => void; - setSideViewInstance: (instance: PointCloudAnnotation) => void; - setBackViewInstance: (instance: PointCloudAnnotation) => void; - setMainViewInstance: (instance: PointCloud) => void; -} - -export interface IPointCloudContext extends IPointCloudContextInstances { - pointCloudBoxList: IPointCloudBoxList; - selectedIDs: string[]; - setSelectedIDs: (ids?: string[] | string) => void; - valid: boolean; - setPointCloudResult: (resultList: IPointCloudBoxList) => void; - selectedPointCloudBox?: IPointCloudBox; - setPointCloudValid: (valid?: boolean) => void; - addSelectedID: (selectedID: string) => void; - selectedAllBoxes: () => void; - selectedID: string; - addPointCloudBox: (boxParams: IPointCloudBox) => void; - - polygonList: IPolygonData[]; - setPolygonList: (polygonList: IPolygonData[]) => void; - - zoom: number; - setZoom: (zoom: number) => void; - - history: ActionsHistory; // Operation History -} - -export const PointCloudContext = React.createContext({ - pointCloudBoxList: [], - polygonList: [], - selectedID: '', - selectedIDs: [], - valid: true, - setSelectedIDs: () => {}, - setPointCloudResult: () => {}, - setPointCloudValid: () => {}, - setTopViewInstance: () => {}, - setSideViewInstance: () => {}, - setBackViewInstance: () => {}, - setMainViewInstance: () => {}, - addSelectedID: () => {}, - selectedAllBoxes: () => {}, - addPointCloudBox: () => {}, - setPolygonList: () => {}, - - zoom: 1, - setZoom: () => {}, - history: new ActionsHistory(), -}); - -export const PointCloudProvider: React.FC<{}> = ({ children }) => { - const [pointCloudBoxList, setPointCloudResult] = useState([]); - const [polygonList, setPolygonList] = useState([]); - const [selectedIDs, setSelectedIDsState] = useState([]); - const [valid, setValid] = useState(true); - const [zoom, setZoom] = useState(1); - const [topViewInstance, setTopViewInstance] = useState(); - const [sideViewInstance, setSideViewInstance] = useState(); - const [backViewInstance, setBackViewInstance] = useState(); - const [mainViewInstance, setMainViewInstance] = useState(); - const history = useRef(new ActionsHistory()).current; - - const selectedID = useMemo(() => { - return selectedIDs.length === 1 ? selectedIDs[0] : ''; - }, [selectedIDs]); - - const ptCtx = useMemo(() => { - const selectedPointCloudBox = pointCloudBoxList.find((v) => v.id === selectedID); - - const addPointCloudBox = (box: IPointCloudBox) => { - setPointCloudResult(pointCloudBoxList.concat(box)); - }; - - const setPointCloudValid = (valid?: boolean) => { - setValid(valid === false ? false : true); - }; - - const setSelectedIDs = (selectedIDs?: string[] | string) => { - if (selectedIDs === undefined) { - setSelectedIDsState([]); - } - - if (typeof selectedIDs === 'string') { - setSelectedIDsState([selectedIDs]); - } - - if (Array.isArray(selectedIDs)) { - setSelectedIDsState(Array.from(new Set(selectedIDs))); - } - }; - - /** - * If selectedID existed, remove selectedID from selectedIDs - * If selectedID not existed, add selectedID to selectedIDs - * @param selectedID - */ - const addSelectedID = (selectedID: string) => { - if (selectedIDs.includes(selectedID)) { - setSelectedIDs(selectedIDs.filter((i) => i !== selectedID)); - } else { - setSelectedIDs([...selectedIDs, selectedID]); - } - }; - - const selectedAllBoxes = () => { - setSelectedIDs(pointCloudBoxList.map((i) => i.id)); - }; - - return { - selectedID, - pointCloudBoxList, - selectedIDs, - setPointCloudResult, - setSelectedIDs, - addPointCloudBox, - valid, - selectedPointCloudBox, - setPointCloudValid, - addSelectedID, - selectedAllBoxes, - topViewInstance, - setTopViewInstance, - sideViewInstance, - setSideViewInstance, - backViewInstance, - setBackViewInstance, - mainViewInstance, - setMainViewInstance, - polygonList, - setPolygonList, - zoom, - setZoom, - history, - }; - }, [ - valid, - selectedIDs, - pointCloudBoxList, - polygonList, - topViewInstance, - sideViewInstance, - backViewInstance, - mainViewInstance, - zoom, - ]); - - return {children}; -}; diff --git a/packages/lb-components/src/components/pointCloudView/hooks/useHistory.ts b/packages/lb-components/src/components/pointCloudView/hooks/useHistory.ts index e3807e381..9bd7ecad8 100644 --- a/packages/lb-components/src/components/pointCloudView/hooks/useHistory.ts +++ b/packages/lb-components/src/components/pointCloudView/hooks/useHistory.ts @@ -12,6 +12,7 @@ export const useHistory = () => { topViewInstance, polygonList, setPolygonList, + syncAllViewPointCloudColor, } = useContext(PointCloudContext); const addHistory = ({ @@ -97,7 +98,7 @@ export const useHistory = () => { return; } - const { pointCloudBoxList: newPointCloudBoxList, polygonList: newPolygonList } = params; + const { pointCloudBoxList: newPointCloudBoxList = [], polygonList: newPolygonList = [] } = params; if (newPointCloudBoxList) { if (pointCloudBoxList.length !== newPointCloudBoxList.length) { @@ -122,6 +123,7 @@ export const useHistory = () => { }); setPointCloudResult(newPointCloudBoxList); + syncAllViewPointCloudColor(newPointCloudBoxList); } if (newPolygonList) { diff --git a/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts b/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts index 4b6f22f20..d85c0d29d 100644 --- a/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts +++ b/packages/lb-components/src/components/pointCloudView/hooks/usePointCloudViews.ts @@ -425,8 +425,8 @@ export const usePointCloudViews = () => { polygonOperation.setSelectedIDs([newPolygon.id]); setSelectedIDs(boxParams.id); - syncPointCloudViews(PointCloudView.Top, newPolygon, boxParams, zoom); - addPointCloudBox(boxParams); + const newPointCloudList = addPointCloudBox(boxParams); + syncPointCloudViews(PointCloudView.Top, newPolygon, boxParams, zoom, newPointCloudList); addHistory({ newBoxParams: boxParams }); }; @@ -474,8 +474,9 @@ export const usePointCloudViews = () => { }; } - updateSelectedBox(newBoxParams); - syncPointCloudViews(fromView, newPolygon, newBoxParams); + const newPointCloudList = updateSelectedBox(newBoxParams); + syncPointCloudViews(fromView, newPolygon, newBoxParams, undefined, newPointCloudList); + return newPointCloudList; } }; @@ -519,8 +520,14 @@ export const usePointCloudViews = () => { _.pickBy(newBoxParams, (v, k) => ['width', 'height', 'x', 'y']), ); - updateSelectedBox(newBoxParams); - syncPointCloudViews(PointCloudView.Top, polygon, selectedPointCloudBox); + const newPointCloudBoxList = updateSelectedBox(newBoxParams); + syncPointCloudViews( + PointCloudView.Top, + polygon, + selectedPointCloudBox, + undefined, + newPointCloudBoxList, + ); } }; @@ -535,6 +542,7 @@ export const usePointCloudViews = () => { polygon: any, boxParams: IPointCloudBox, zoom?: number, + newPointCloudBoxList?: IPointCloudBox[], ) => { const dataUrl = currentData?.url; @@ -562,7 +570,9 @@ export const usePointCloudViews = () => { } mainViewGenBox(boxParams); - mainViewInstance?.highlightOriginPointCloud(boxParams); + if (newPointCloudBoxList) { + ptCtx.syncAllViewPointCloudColor(newPointCloudBoxList); + } }; const pointCloudBoxListUpdated = (newBoxes: IPointCloudBox[]) => { @@ -582,8 +592,8 @@ export const usePointCloudViews = () => { bottom: -size.height / 2, near: 100, far: -100, - } - + }; + mainViewInstance.initOrthographicCamera(orthographicParams); mainViewInstance.initRenderer(); mainViewInstance.render(); diff --git a/packages/lb-components/src/components/pointCloudView/hooks/useRotate.ts b/packages/lb-components/src/components/pointCloudView/hooks/useRotate.ts index c72eed895..f06ffa7a6 100644 --- a/packages/lb-components/src/components/pointCloudView/hooks/useRotate.ts +++ b/packages/lb-components/src/components/pointCloudView/hooks/useRotate.ts @@ -18,7 +18,7 @@ export const useRotate = ({ currentData }: IAnnotationStateProps) => { const updateRotate = useCallback( (angle: number) => { - const { topViewInstance, mainViewInstance } = ptCtx; + const { topViewInstance, mainViewInstance, syncAllViewPointCloudColor } = ptCtx; if (!topViewInstance || !mainViewInstance) { return; } @@ -31,7 +31,7 @@ export const useRotate = ({ currentData }: IAnnotationStateProps) => { return; } - updateSelectedBox({ + const newPointCloudList = updateSelectedBox({ rotation: PointCloudUtils.restrictAngleRange( selectedPointCloudBox.rotation + Number(Math.PI * angle) / 180, ), @@ -41,7 +41,7 @@ export const useRotate = ({ currentData }: IAnnotationStateProps) => { const selectedPolygon = TopPointCloudPolygonOperation.selectedPolygon; mainViewInstance.generateBox(selectedPointCloudBox); - mainViewInstance.highlightOriginPointCloud(selectedPointCloudBox); + syncAllViewPointCloudColor(newPointCloudList); synchronizeSideView( selectedPointCloudBox, selectedPolygon, diff --git a/packages/lb-components/src/components/pointCloudView/hooks/useSingleBox.ts b/packages/lb-components/src/components/pointCloudView/hooks/useSingleBox.ts index e1f76c529..3335c02b2 100644 --- a/packages/lb-components/src/components/pointCloudView/hooks/useSingleBox.ts +++ b/packages/lb-components/src/components/pointCloudView/hooks/useSingleBox.ts @@ -19,6 +19,7 @@ export const useSingleBox = () => { selectedID, mainViewInstance, setSelectedIDs, + syncAllViewPointCloudColor, } = useContext(PointCloudContext); const { pushHistoryWithList } = useHistory(); @@ -36,10 +37,13 @@ export const useSingleBox = () => { (params: Partial) => { if (selectedBox?.info) { pointCloudBoxList.splice(selectedBox.index, 1, _.merge(selectedBox.info, params)); - const newPointCloudBoxList = _.cloneDeep(pointCloudBoxList) + const newPointCloudBoxList = _.cloneDeep(pointCloudBoxList); setPointCloudResult(newPointCloudBoxList); pushHistoryWithList({ pointCloudBoxList: newPointCloudBoxList }); + return newPointCloudBoxList; } + + return pointCloudBoxList; }, [selectedID, pointCloudBoxList], ); @@ -119,10 +123,11 @@ export const useSingleBox = () => { }; const deletePointCloudBox = (id: string) => { - setPointCloudResult(pointCloudBoxList.filter((v) => v.id !== id)); + const newPointCloudList = pointCloudBoxList.filter((v) => v.id !== id); + setPointCloudResult(newPointCloudList); mainViewInstance?.removeObjectByName(id); mainViewInstance?.render(); - // TODO Clear Highlight. + syncAllViewPointCloudColor(newPointCloudList); }; return { diff --git a/packages/lb-utils/src/index.ts b/packages/lb-utils/src/index.ts index 3c67df472..b7c9ea627 100644 --- a/packages/lb-utils/src/index.ts +++ b/packages/lb-utils/src/index.ts @@ -19,4 +19,6 @@ export * from './types/index'; // Utils export { i18n, toolStyleConverter, PerspectiveShiftUtils, PointCloudUtils, MatrixUtils }; -export * from "./annotation"; +export * from './annotation'; + +export * from './toolStyle';