2026-05-07-17-05-43 增加3D实体显示档位
This commit is contained in:
@@ -26,7 +26,7 @@ import { api, downloadDicomArchive, downloadMask } from '../lib/api';
|
||||
|
||||
type Plane = 'axial' | 'sagittal' | 'coronal';
|
||||
type DisplayMode = DicomPreview['mode'];
|
||||
type SolidityLevel = 'preview' | 'standard' | 'fine' | 'ultra';
|
||||
type SolidityLevel = 'standard' | 'fine' | 'ultra' | 'solid';
|
||||
|
||||
interface ModuleStyle {
|
||||
visible: boolean;
|
||||
@@ -59,10 +59,10 @@ type ModelPoseKey = keyof ModelPose;
|
||||
|
||||
const defaultModuleColors = ['#3b82f6', '#22c55e', '#f59e0b', '#ef4444', '#8b5cf6', '#14b8a6', '#f97316', '#64748b', '#ec4899'];
|
||||
const solidityOptions: Array<{ id: SolidityLevel; label: string; limit: number }> = [
|
||||
{ id: 'preview', label: '预览', limit: 6000 },
|
||||
{ id: 'standard', label: '标准', limit: 16000 },
|
||||
{ id: 'fine', label: '精细', limit: 36000 },
|
||||
{ id: 'ultra', label: '超精细', limit: 72000 },
|
||||
{ id: 'solid', label: '实体', limit: 200000 },
|
||||
];
|
||||
const defaultModelPose: ModelPose = {
|
||||
rotateX: 0,
|
||||
@@ -291,6 +291,7 @@ function NativeStlViewer({
|
||||
files,
|
||||
styles,
|
||||
detailLimit,
|
||||
solidMode,
|
||||
pose,
|
||||
onPoseChange,
|
||||
}: {
|
||||
@@ -298,6 +299,7 @@ function NativeStlViewer({
|
||||
files: string[];
|
||||
styles: Record<string, ModuleStyle>;
|
||||
detailLimit: number;
|
||||
solidMode: boolean;
|
||||
pose: ModelPose;
|
||||
onPoseChange: React.Dispatch<React.SetStateAction<ModelPose>>;
|
||||
}) {
|
||||
@@ -491,13 +493,14 @@ function NativeStlViewer({
|
||||
geometry.setAttribute('position', new THREE.Float32BufferAttribute(payload.vertices, 3));
|
||||
geometry.computeVertexNormals();
|
||||
const style = styles[fileName] ?? { color: '#3b82f6', opacity: 0.72, visible: true };
|
||||
const materialOpacity = solidMode ? Math.max(style.opacity, 0.94) : style.opacity;
|
||||
const mesh = new THREE.Mesh(
|
||||
geometry,
|
||||
new THREE.MeshStandardMaterial({
|
||||
color: style.color,
|
||||
opacity: style.opacity,
|
||||
transparent: style.opacity < 1,
|
||||
roughness: 0.42,
|
||||
opacity: materialOpacity,
|
||||
transparent: materialOpacity < 1,
|
||||
roughness: solidMode ? 0.56 : 0.42,
|
||||
metalness: 0.04,
|
||||
side: THREE.DoubleSide,
|
||||
}),
|
||||
@@ -600,7 +603,7 @@ function NativeStlViewer({
|
||||
});
|
||||
container.innerHTML = '';
|
||||
};
|
||||
}, [projectId, files.join('|'), JSON.stringify(styles), detailLimit]);
|
||||
}, [projectId, files.join('|'), JSON.stringify(styles), detailLimit, solidMode]);
|
||||
|
||||
return (
|
||||
<div className="h-full w-full relative cursor-grab active:cursor-grabbing">
|
||||
@@ -696,7 +699,7 @@ export default function ProjectLibrary({ onReverse }: { onReverse: (projId: stri
|
||||
];
|
||||
const allModulesVisible = stlFiles.length > 0 && stlFiles.every((file) => moduleStyles[file]?.visible !== false);
|
||||
const sliceTotal = dicomPreview?.total ?? selectedProject?.dicomCount ?? 0;
|
||||
const selectedSolidity = solidityOptions.find((option) => option.id === solidityLevel) ?? solidityOptions[1];
|
||||
const selectedSolidity = solidityOptions.find((option) => option.id === solidityLevel) ?? solidityOptions[0];
|
||||
|
||||
useEffect(() => {
|
||||
const next: Record<string, ModuleStyle> = {};
|
||||
@@ -1235,6 +1238,7 @@ export default function ProjectLibrary({ onReverse }: { onReverse: (projId: stri
|
||||
files={stlFiles}
|
||||
styles={moduleStyles}
|
||||
detailLimit={selectedSolidity.limit}
|
||||
solidMode={solidityLevel === 'solid'}
|
||||
pose={modelPose}
|
||||
onPoseChange={setModelPose}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user