Skip to content

Commit

Permalink
feat(pointcloud): Highlighting support for all views of PointCloud
Browse files Browse the repository at this point in the history
  • Loading branch information
laoluo committed Aug 7, 2023
1 parent 1dbd271 commit 9d2701c
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 11 deletions.
70 changes: 70 additions & 0 deletions packages/lb-annotation/src/core/pointCloud/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ export class PointCloud extends EventListener {

private rangeObjectName = 'range';

private highlightGroupName = 'highlightBoxes';

private cacheInstance: PointCloudCache; // PointCloud Cache Map

private showDirection: boolean = true; // Whether to display the direction of box
Expand Down Expand Up @@ -1025,6 +1027,74 @@ export class PointCloud extends EventListener {
});
}

/**
* Clean all highlightBox
*/
public clearHighlightBoxes() {
this.removeObjectByName(this.highlightGroupName);
}

public clearHighlightBoxesAndRender() {
this.clearHighlightBoxes();
this.render();
}

public highlightBoxes(boxes: IPointCloudBox[]) {
const group = new THREE.Group();

// 1. Highlight all box.
boxes.forEach((box) => {
const {
center: { x, y, z },
width,
height,
depth,
rotation,
} = box;
const { fill } = toolStyleConverter.getColorFromConfig(
{ attribute: box.attribute },
{ ...this.config, attributeConfigurable: true },
{},
);

// 1-1. Add Transparent Box.
const geometry = new THREE.BoxGeometry(width, height, depth);
const material = new THREE.MeshBasicMaterial({
color: fill,
transparent: true,
opacity: 0.2,
depthTest: false,
});
geometry.rotateZ(rotation);
geometry.translate(x, y, z);
const mesh = new THREE.Mesh(geometry, material);
group.add(mesh);

// 1-2. Add plane for direction.
const planeGeo = new THREE.PlaneGeometry(depth, height);
planeGeo.rotateY(Math.PI / 2);
planeGeo.rotateZ(rotation);
// The plane center Offset
const vector = new THREE.Vector3(width / 2, 0, 0);
const rM = new THREE.Matrix4().makeRotationY(Math.PI / 2).makeRotationZ(rotation);
vector.applyMatrix4(rM);
planeGeo.translate(x + vector.x, y + vector.y, z + vector.z);
const plainMaterial = new THREE.MeshBasicMaterial({
color: fill,
side: THREE.DoubleSide,
transparent: true,
opacity: 0.8,
depthTest: false,
});
const plainMesh = new THREE.Mesh(planeGeo, plainMaterial);
group.add(plainMesh);
});

group.name = this.highlightGroupName;
this.scene.add(group);
this.render();
}

public updateColor(color: any[]) {
const oldPointCloud = this.scene.getObjectByName(this.pointCloudObjectName) as THREE.Points;
if (oldPointCloud) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class PointCloud2dOperation extends PolygonOperation {

private checkMode: boolean;

private highlightAttributeList: string[] = []; //

constructor(props: IPolygonOperationProps & IPointCloud2dOperationProps) {
super(props);

Expand Down Expand Up @@ -216,8 +218,10 @@ class PointCloud2dOperation extends PolygonOperation {
}
const lineColor = this.getPointCloudLineColor(polygon);
const transformPointList = AxisUtils.changePointListByZoom(polygon.pointList || [], this.zoom, this.currentPos);
const isHighlight = this.highlightAttributeList.includes(polygon.attribute);

DrawUtils.drawPolygonWithFillAndLine(this.canvas, transformPointList, {
fillColor: 'transparent',
fillColor: isHighlight ? lineColor : 'transparent',
strokeColor: lineColor,
pointColor: 'white',
thickness: this.style?.width ?? 2,
Expand Down Expand Up @@ -493,6 +497,11 @@ class PointCloud2dOperation extends PolygonOperation {
}
}
};

public setHighlightAttribute(attribute: string) {
this.highlightAttributeList = [attribute];
this.render();
}
}

export default PointCloud2dOperation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ interface IProps extends IA2MapStateProps {
thumbnailWidth?: number;
}

const PointCloud2DView = ({ currentData, config, thumbnailWidth }: IProps) => {
const PointCloud2DView = ({ currentData, config, thumbnailWidth, highlightAttribute }: IProps) => {
const [annotations2d, setAnnotations2d] = useState<IAnnotationData2dView[]>([]);
const { topViewInstance, displayPointCloudList } = useContext(PointCloudContext);
const [selectedID, setSelectedID] = useState<number | string>('');
Expand All @@ -67,9 +67,16 @@ const PointCloud2DView = ({ currentData, config, thumbnailWidth }: IProps) => {
currentData?.mappingImgList.forEach((mappingData: IMappingImg) => {
const newAnnotations2d: IAnnotationDataTemporarily[] = displayPointCloudList.reduce(
(acc: IAnnotationDataTemporarily[], pointCloudBox: IPointCloudBox) => {
/**
* Is need to create range.
* 1. pointCloudBox is selected;
* 2. HighlightAttribute is same with pointCloudBox's attribute.
*/
const createRange =
pointCloudBox.id === selectedID || highlightAttribute === pointCloudBox.attribute;
const { transferViewData: viewDataPointList, viewRangePointList } =
pointCloudLidar2image(pointCloudBox, mappingData.calib, {
createRange: pointCloudBox.id === selectedID,
createRange,
});

const stroke = toolStyleConverter.getColorFromConfig(
Expand All @@ -88,7 +95,7 @@ const PointCloud2DView = ({ currentData, config, thumbnailWidth }: IProps) => {
});
const newArr = [...acc, ...viewDataPointLists];

if (pointCloudBox.id === selectedID && viewRangePointList.length > 0) {
if (viewRangePointList?.length > 0) {
newArr.push({
type: 'polygon',
annotation: {
Expand All @@ -113,7 +120,7 @@ const PointCloud2DView = ({ currentData, config, thumbnailWidth }: IProps) => {
});
setAnnotations2d(newAnnotations2dList);
}
}, [displayPointCloudList, currentData?.mappingImgList, selectedID]);
}, [displayPointCloudList, currentData?.mappingImgList, selectedID, highlightAttribute]);

useEffect(() => {
window.addEventListener('keydown', onKeyDown);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const PointCloud3DSideBar = ({ isEnlarge }: { isEnlarge?: boolean }) => {
);
};

const PointCloud3D: React.FC<IA2MapStateProps> = ({ currentData, config }) => {
const PointCloud3D: React.FC<IA2MapStateProps> = ({ currentData, config, highlightAttribute }) => {
const ptCtx = useContext(PointCloudContext);
const [showDirection, setShowDirection] = useState(true);
const [isEnlarge, setIsEnlarge] = useState(false);
Expand Down Expand Up @@ -257,6 +257,22 @@ const PointCloud3D: React.FC<IA2MapStateProps> = ({ currentData, config }) => {
return { reset3DView, setTarget3DView, isActive: !!selectedBox, followTopView };
}, [selectedBox, ptCtx.mainViewInstance]);

// Highlight 3D Box when `highAttribute` updated.
useEffect(() => {
const highlightBoxes = ptCtx.pointCloudBoxList.filter(
(v) => v.attribute === highlightAttribute,
);

if (highlightBoxes?.length > 0) {
ptCtx.mainViewInstance?.clearHighlightBoxes();
ptCtx.mainViewInstance?.highlightBoxes(highlightBoxes);
}

if (highlightBoxes.length === 0) {
ptCtx.mainViewInstance?.clearHighlightBoxesAndRender();
}
}, [highlightAttribute, ptCtx.mainViewInstance]);

const PointCloud3DTitle = (
<>
<PointCloudSizeSlider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { PointCloudContext } from './PointCloudContext';
import { CommonToolUtils } from '@labelbee/lb-annotation';
import { EPointCloudSegmentMode, PointCloudUtils } from '@labelbee/lb-utils';
import { useAttribute } from './hooks/useAttribute';
import { IInputList } from '@/types/main';

interface IProps extends IA2MapStateProps {
checkMode?: boolean;
Expand Down Expand Up @@ -56,10 +55,7 @@ const PointCloudSegmentListener: React.FC<IProps> = ({
}, [imgIndex, ptSegmentInstance]);

useEffect(() => {
let attributeValue = config.attributeList.find(
(v: IInputList) => v?.key === highlightAttribute,
)?.value;
ptSegmentInstance?.store?.highlightPointsByAttribute(attributeValue ?? '');
ptSegmentInstance?.store?.highlightPointsByAttribute(highlightAttribute ?? '');
}, [highlightAttribute, ptSegmentInstance]);

const segmentKeydownEvents = (lowerCaseKey: string, e: KeyboardEvent) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ const PointCloudTopView: React.FC<IProps> = ({
setIsEnlargeTopView,
isEnlargeTopView,
onExitZoom,
highlightAttribute,
}) => {
const [annotationPos, setAnnotationPos] = useState({ zoom: 1, currentPos: { x: 0, y: 0 } });
const ref = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -435,6 +436,10 @@ const PointCloudTopView: React.FC<IProps> = ({
onExitZoom();
}
};
// Highlight TopView Box when `hightAttribute` updated.
useEffect(() => {
ptCtx.topViewInstance?.pointCloud2dOperation?.setHighlightAttribute?.(highlightAttribute);
}, [ptCtx.topViewInstance, highlightAttribute]);

return (
<PointCloudContainer
Expand Down

0 comments on commit 9d2701c

Please sign in to comment.