fix: print3d_model 예상 출력시간이 항상 6666초로 나오는 CuraEngine CLI 버그 수정
CuraEngine 5.0.0 소스 확인 결과, CommandLine 백엔드는 isSequential()이 항상 true라 슬라이싱 "시작 전"에 G-code 헤더를 미리 써버리고(processStartingCode -> getFileHeader, print_time 인자 없음) 끝난 뒤 되돌아가 실제값으로 덮어쓰는 코드가 어디에도 없다. 그래서 ;TIME: 헤더는 항상 gcodeExport.cpp에 하드코딩된 더미값(6666)만 남는다 — 확률적 버그가 아니라 CLI 모드의 구조적 한계였음. 실제 값은 슬라이싱 완료 후 stderr(verbose 로그)에 "Print time (s): N"으로만 찍히므로, G-code 파일 헤더 대신 stderr를 파싱하도록 변경. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+13
-7
@@ -89,18 +89,20 @@ async function downloadStl(url: string, outPath: string): Promise<{ ok: true } |
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
function runCuraEngine(args: string[], timeoutMs: number): Promise<{ ok: true; stdout: string } | { ok: false; detail: string }> {
|
||||
function runCuraEngine(args: string[], timeoutMs: number): Promise<{ ok: true; stdout: string; stderr: string } | { ok: false; detail: string }> {
|
||||
return new Promise((resolve) => {
|
||||
const proc = spawn(CURA_ENGINE_BIN, args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
proc.stdout?.on('data', (d: Buffer) => { stdout += d.toString('utf8'); });
|
||||
proc.stderr?.on('data', (d: Buffer) => { stderr += d.toString('utf8'); if (stderr.length > 4000) stderr = stderr.slice(-4000); });
|
||||
// 실패시 에러메시지용으로 뒤쪽만 있으면 되지만, 성공시엔 "Print time (s): N" 요약 줄을
|
||||
// 파싱해야 하므로(아래 CLI 헤더 버그 설명 참고) 여기서는 자르지 않고 전체 보존한다.
|
||||
proc.stderr?.on('data', (d: Buffer) => { stderr += d.toString('utf8'); });
|
||||
const killTimer = setTimeout(() => { try { proc.kill('SIGKILL'); } catch { /* noop */ } }, timeoutMs);
|
||||
proc.on('error', (e) => { clearTimeout(killTimer); resolve({ ok: false, detail: String(e.message || e) }); });
|
||||
proc.on('close', (code) => {
|
||||
clearTimeout(killTimer);
|
||||
if (code === 0) resolve({ ok: true, stdout });
|
||||
if (code === 0) resolve({ ok: true, stdout, stderr });
|
||||
else resolve({ ok: false, detail: stderr.split('\n').filter(Boolean).slice(-10).join(' ') || `CuraEngine exit ${code}` });
|
||||
});
|
||||
});
|
||||
@@ -240,10 +242,14 @@ export const print3dModelTool = {
|
||||
return { success: false, error: '슬라이싱은 끝났는데 G-code 파일이 비정상입니다.' };
|
||||
}
|
||||
|
||||
// CuraEngine은 "Print time (s):" 요약을 stderr(verbose 로그)에 찍고, stdout엔 아무것도
|
||||
// 안 남긴다 — 대신 생성된 G-code 자체의 헤더 주석(;TIME:초)에서 직접 읽는 게 더 안정적.
|
||||
const gcodeHead = fs.readFileSync(gcodePath, 'utf8').slice(0, 2000);
|
||||
const timeMatch = gcodeHead.match(/;TIME:(\d+)/);
|
||||
// 주의: G-code 파일 자체의 ";TIME:" 헤더는 CLI 모드에서 절대 신뢰할 수 없다 — CuraEngine
|
||||
// CLI(CommandLine 백엔드)는 슬라이싱 "시작 전"에 헤더를 이미 써버리고(isSequential()이
|
||||
// 항상 true라 processStartingCode에서 print_time 없이 getFileHeader 호출) 끝난 뒤에도
|
||||
// 되돌아가 덮어쓰는 코드가 CuraEngine 소스 어디에도 없다 — 그래서 항상 코드에 하드코딩된
|
||||
// 더미값(gcodeExport.cpp의 `;TIME:6666`)이 그대로 남는다(2026-09-20 소스 확인, 5.0.0).
|
||||
// 실제 값은 슬라이싱이 끝난 뒤 stderr(verbose 로그, -v 필요)에 "Print time (s): N"으로만
|
||||
// 찍히므로 거기서 파싱해야 한다.
|
||||
const timeMatch = slice.stderr.match(/Print time \(s\):\s*(\d+)/);
|
||||
const printTimeSec = timeMatch ? Number(timeMatch[1]) : null;
|
||||
|
||||
const up = await uploadToMoonraker(gcodePath, gcodeFilename);
|
||||
|
||||
Reference in New Issue
Block a user