新增仿真执行过程回放
结论:真实浏览器仿真页面新增 G-code 执行过程和刀具运动回放,支持 reset、step、play、finish,逐帧高亮 G-code 与 motion row,并渲染已执行刀路和移动 toolhead。
This commit is contained in:
@@ -92,14 +92,56 @@
|
||||
if (!api?.getPrograms || !api?.runProgramById) {
|
||||
throw new Error("simulation API missing program controls");
|
||||
}
|
||||
if (!api?.resetPlayback || !api?.stepPlayback || !api?.finishPlayback) {
|
||||
throw new Error("simulation API missing playback controls");
|
||||
}
|
||||
const programs = api.getPrograms();
|
||||
if (programs.length < 5) {
|
||||
throw new Error("simulation test program inventory too small");
|
||||
}
|
||||
|
||||
api.resetPlayback();
|
||||
if (doc.body.dataset.playbackIndex !== "0") {
|
||||
throw new Error("simulation playback did not reset to first frame");
|
||||
}
|
||||
const firstHead = doc.querySelector("[data-toolpath-head]");
|
||||
const firstCx = firstHead?.getAttribute("cx");
|
||||
const firstCy = firstHead?.getAttribute("cy");
|
||||
const firstExecutedPoints = doc.querySelector("[data-toolpath-executed-polyline]")?.getAttribute("points") ?? "";
|
||||
if (!doc.querySelector('[data-program-line="1"]') || doc.querySelector('[data-program-line="2"]')?.dataset.active !== "false") {
|
||||
throw new Error("simulation reset playback did not render first active program line");
|
||||
}
|
||||
|
||||
const secondFrame = api.stepPlayback(1);
|
||||
if (secondFrame.index !== 1 || secondFrame.activeLine !== 2) {
|
||||
throw new Error(`simulation step playback drift: ${JSON.stringify(secondFrame)}`);
|
||||
}
|
||||
const secondExecutedPoints = doc.querySelector("[data-toolpath-executed-polyline]")?.getAttribute("points") ?? "";
|
||||
if (secondExecutedPoints === firstExecutedPoints || !secondExecutedPoints.includes("1,0")) {
|
||||
throw new Error("simulation executed toolpath did not advance on step");
|
||||
}
|
||||
if (firstHead?.getAttribute("cx") === firstCx && firstHead?.getAttribute("cy") === firstCy) {
|
||||
throw new Error("simulation toolhead did not move on playback step");
|
||||
}
|
||||
if (doc.querySelector('[data-program-line="2"]')?.dataset.active !== "true") {
|
||||
throw new Error("simulation step playback did not highlight active G-code line");
|
||||
}
|
||||
if (doc.querySelector('[data-motion-row="1"]')?.dataset.active !== "true") {
|
||||
throw new Error("simulation step playback did not highlight active motion row");
|
||||
}
|
||||
|
||||
const finishedFrame = api.finishPlayback();
|
||||
if (finishedFrame.index !== state.motion.length - 1 || doc.body.dataset.playbackComplete !== "true") {
|
||||
throw new Error("simulation finish playback did not reach final frame");
|
||||
}
|
||||
|
||||
for (const program of programs) {
|
||||
const nextState = await api.runProgramById(program.id);
|
||||
assertRenderedState(doc, nextState);
|
||||
const resetFrame = api.resetPlayback();
|
||||
if (resetFrame.index !== 0 || doc.body.dataset.playbackIndex !== "0") {
|
||||
throw new Error(`simulation playback reset failed for ${program.id}`);
|
||||
}
|
||||
if (nextState.program.id !== program.id) {
|
||||
throw new Error(`simulation API returned wrong program id for ${program.id}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user