Support long G-code preview and virtualized execution display

This commit is contained in:
2026-08-29 22:27:01 +08:00
parent 819015924b
commit d87366eb75
7 changed files with 179 additions and 35 deletions

View File

@@ -179,14 +179,36 @@ export function XyzacToolPreview({ visual, view = "p", zoom = 1, rotateMode = fa
if (nextPathKey !== pathKey) {
clearLines(pathGroup);
bounds = fit(segments);
// Long programs can contain thousands of linear blocks. Batch their
// vertices so preview loading does not block the UI on one WebGL
// object and geometry allocation per G-code line.
const batched = { rapid: [] as THREE.Vector3[], completed: [] as THREE.Vector3[] };
const sampledLines: Array<{ points: THREE.Vector3[]; rapid: boolean }> = [];
for (const segment of segments) {
const start = segment.start ?? {}; const end = segment.end ?? {};
const points = Array.isArray(segment.samples) && segment.samples.length > 1 ? segment.samples.map(sourcePoint) : [sourcePoint(start), sourcePoint(end)];
const line = new THREE.Line(new THREE.BufferGeometry().setFromPoints(points), segment.kind === "rapid" ? rapid : completed);
if (segment.kind === "rapid") line.computeLineDistances();
const sampled = Array.isArray(segment.samples) && segment.samples.length > 1;
const points = sampled ? segment.samples!.map(sourcePoint) : [sourcePoint(start), sourcePoint(end)];
const rapidPath = segment.kind === "rapid";
if (sampled) sampledLines.push({ points, rapid: rapidPath });
else (rapidPath ? batched.rapid : batched.completed).push(...points);
}
const addLine = (points: THREE.Vector3[], material: THREE.LineBasicMaterial | THREE.LineDashedMaterial, dashed = false) => {
if (points.length < 2) return;
const line = new THREE.Line(new THREE.BufferGeometry().setFromPoints(points), material);
if (dashed) line.computeLineDistances();
line.renderOrder = 10;
pathGroup.add(line);
}
};
const addSegments = (points: THREE.Vector3[], material: THREE.LineBasicMaterial | THREE.LineDashedMaterial, dashed = false) => {
if (points.length < 2) return;
const line = new THREE.LineSegments(new THREE.BufferGeometry().setFromPoints(points), material);
if (dashed) line.computeLineDistances();
line.renderOrder = 10;
pathGroup.add(line);
};
addSegments(batched.rapid, rapid, true);
addSegments(batched.completed, completed);
for (const sampled of sampledLines) addLine(sampled.points, sampled.rapid ? rapid : completed, sampled.rapid);
pathKey = nextPathKey;
liveKey = "";
}