feat: 板换
This commit is contained in:
parent
69ff7dfa88
commit
a033c83cff
|
@ -4,10 +4,12 @@ import * as THREE from "three";
|
|||
import useMultiResizeObserver from "../useMultiResizeObserver";
|
||||
import { loadModels, SegmentMapping } from "./util";
|
||||
import { InferStructuralEnum } from "./type";
|
||||
import { valveMapping } from "./aorta.config";
|
||||
|
||||
interface AortaViewerProps {
|
||||
SeriesInstanceUID: string;
|
||||
stlFiles: { fileName: string; data: ArrayBuffer }[];
|
||||
measurement: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export const AortaViewer = (props: AortaViewerProps) => {
|
||||
|
@ -18,7 +20,7 @@ export const AortaViewer = (props: AortaViewerProps) => {
|
|||
const controlsRef = useRef<TrackballControls>();
|
||||
const groupRef = useRef(new THREE.Group());
|
||||
const viewer3DContainer = useRef<HTMLDivElement | null>(null);
|
||||
const { SeriesInstanceUID, stlFiles } = props;
|
||||
const { SeriesInstanceUID, stlFiles, measurement } = props;
|
||||
|
||||
// autosize
|
||||
useMultiResizeObserver([viewer3DContainer], () => {
|
||||
|
@ -58,6 +60,31 @@ export const AortaViewer = (props: AortaViewerProps) => {
|
|||
});
|
||||
}, [stlFiles]);
|
||||
|
||||
const initMeasurement = useCallback(() => {
|
||||
for (const prop in measurement) {
|
||||
if (prop in valveMapping) {
|
||||
const pointArray = measurement[prop].points;
|
||||
const curve = new THREE.CatmullRomCurve3(
|
||||
pointArray.map((p) => new THREE.Vector3(p[0], p[1], p[2]))
|
||||
);
|
||||
curve.curveType = "chordal"; // 曲线类型
|
||||
curve.closed = true; // 曲线是否闭合
|
||||
// 50等分获取曲线点数组
|
||||
const points = curve.getPoints(50);
|
||||
const [r, g, b] = valveMapping[prop].color;
|
||||
const line = new THREE.LineLoop(
|
||||
new THREE.BufferGeometry().setFromPoints(points),
|
||||
new THREE.LineBasicMaterial({
|
||||
color: new THREE.Color(r, g, b),
|
||||
linewidth: 2,
|
||||
})
|
||||
);
|
||||
line.name = valveMapping[prop].name;
|
||||
groupRef.current.add(line);
|
||||
}
|
||||
}
|
||||
}, [measurement]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!SeriesInstanceUID || !canvasRef.current) return;
|
||||
|
||||
|
@ -69,11 +96,13 @@ export const AortaViewer = (props: AortaViewerProps) => {
|
|||
initControls();
|
||||
initLights();
|
||||
initScene();
|
||||
initMeasurement();
|
||||
initSTLGroup();
|
||||
|
||||
// 开始渲染循环
|
||||
startRenderLoop();
|
||||
}
|
||||
}, [SeriesInstanceUID, initSTLGroup]);
|
||||
}, [SeriesInstanceUID, initMeasurement, initSTLGroup]);
|
||||
|
||||
// 初始化渲染器
|
||||
const initRenderer = (width: number, height: number) => {
|
||||
|
|
|
@ -96,27 +96,27 @@ export const Segments = [
|
|||
* 瓣环配置映射
|
||||
*/
|
||||
export const valveMapping = {
|
||||
Annulus: {
|
||||
annulus_plane: {
|
||||
color: [143 / 255, 6 / 255, 3 / 255],
|
||||
name: "瓣环平面",
|
||||
},
|
||||
LVOT: {
|
||||
LVOT_plane: {
|
||||
color: [84 / 255, 187 / 255, 184 / 255],
|
||||
name: "左室流出道平面",
|
||||
},
|
||||
"Sinus Of Valsalva": {
|
||||
SOV_plane: {
|
||||
color: [87 / 255, 231 / 255, 149 / 255],
|
||||
name: "瓦式窦",
|
||||
},
|
||||
"Sinotubular Junction": {
|
||||
STJ_plane: {
|
||||
color: [213 / 255, 198 / 255, 117 / 255],
|
||||
name: "窦管交界",
|
||||
},
|
||||
"Ascending Aorta": {
|
||||
cor_mid_plane: {
|
||||
color: [182 / 255, 113 / 255, 205 / 255],
|
||||
name: "瓣环上4cm平面",
|
||||
},
|
||||
"Actual Aorta": {
|
||||
actual_aorta_plane: {
|
||||
color: [215 / 255, 136 / 255, 49 / 255],
|
||||
name: "升主动脉最宽处",
|
||||
},
|
||||
|
|
|
@ -30,6 +30,7 @@ export const Model3DViewer = (props: Model3DViewerProps) => {
|
|||
<AortaViewer
|
||||
SeriesInstanceUID={SeriesInstanceUID}
|
||||
stlFiles={algAssets.stlFiles}
|
||||
measurement={algAssets.measurement!}
|
||||
/>
|
||||
)}
|
||||
{algAssets.module === InferStructuralEnum.PERI && (
|
||||
|
|
Loading…
Reference in New Issue
Block a user