2026-05-24-16-28-58 修正可见构件导出与高精度映射

This commit is contained in:
2026-05-24 16:42:37 +08:00
parent 3bedf204c8
commit d9572e6966
9 changed files with 246 additions and 22 deletions

View File

@@ -142,6 +142,7 @@ const dicomVolumeCache = new Map<string, {
}>();
const modelPreviewCache = new Map<string, unknown>();
const defaultModuleColors = ['#3b82f6', '#22c55e', '#f59e0b', '#ef4444', '#8b5cf6', '#14b8a6', '#f97316', '#64748b', '#ec4899'];
const maxPreviewTriangles = 500000;
const defaultModelPose: ModelPoseValue = {
rotateX: 0,
rotateY: 0,
@@ -1601,6 +1602,22 @@ function parseModelPoseQuery(raw: unknown) {
}
}
function parseModuleStylesQuery(raw: unknown) {
if (typeof raw !== 'string' || !raw.trim()) {
return undefined;
}
try {
const parsed = JSON.parse(raw) as unknown;
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
return undefined;
}
return parsed as Record<string, Partial<ModuleStyleRecord>>;
} catch {
return undefined;
}
}
function parseSegmentationScope(raw: unknown): SegmentationExportScope {
return raw === 'all' ? 'all' : 'visible';
}
@@ -1613,15 +1630,20 @@ function latestSegmentationResult(project: ProjectRecord) {
return project.segmentationResults?.[project.segmentationResults.length - 1];
}
function projectWithSegmentationResultStyles(project: ProjectRecord): ProjectRecord {
function projectWithSegmentationResultStyles(
project: ProjectRecord,
requestedModuleStyles?: Record<string, Partial<ModuleStyleRecord>>,
): ProjectRecord {
const latestResult = latestSegmentationResult(project);
if (!latestResult) {
return project;
}
const mergedStyles = buildModuleStyles(project.stlFiles, {
...(latestResult?.moduleStyles ?? {}),
...(project.moduleStyles ?? {}),
...(requestedModuleStyles ?? {}),
});
return {
...project,
moduleStyles: latestResult.moduleStyles,
moduleStyles: mergedStyles,
};
}
@@ -2385,7 +2407,7 @@ function createStlPreview(filePath: string, fileName: string, limit: number): Mo
throw new Error('当前仅支持二进制 STL 预览');
}
const sampleLimit = Math.max(100, Math.min(limit, 200000));
const sampleLimit = Math.max(100, Math.min(limit, maxPreviewTriangles));
const step = Math.max(1, Math.ceil(triangleCount / sampleLimit));
const vertices: number[] = [];
let sampledTriangles = 0;
@@ -3234,7 +3256,7 @@ async function startServer() {
const requestedTarget = targetOverride ?? String(req.query.target ?? 'segmentation');
const target = requestedTarget === 'dicom' || requestedTarget === 'pose' ? requestedTarget : 'segmentation';
const exportProject = projectWithSegmentationResultStyles(project);
const exportProject = projectWithSegmentationResultStyles(project, parseModuleStylesQuery(req.query.moduleStyles));
const latestResult = latestSegmentationResult(project);
const activePose = parseModelPoseQuery(req.query.pose) ?? latestResult?.pose;
const segmentationScope = req.query.segmentationScope === undefined
@@ -3286,7 +3308,7 @@ async function startServer() {
return;
}
const exportProject = projectWithSegmentationResultStyles(project);
const exportProject = projectWithSegmentationResultStyles(project, parseModuleStylesQuery(req.query.moduleStyles));
const latestResult = latestSegmentationResult(project);
const activePose = parseModelPoseQuery(req.query.pose) ?? latestResult?.pose;
const segmentationScope = req.query.segmentationScope === undefined