Summary
• Implemented robust model and scene reference validations in both the FastAPI backend and frontend to prevent empty, corrupt, or missing files from silently failing or producing duplicated background fallbacks. • Enhanced scenery prompt translation on the backend to dynamically map user-specified "Image" numbers e.g. Image 1, Image 2 to Qwen-specific "Picture" placeholders Picture 1, Picture 2, avoiding template mismatch desyncs. Changes • File & Path Validation: Added detailed validations to the /generate-scenery endpoint to ensure model_filename and scene_image paths exist on disk, are resolved without query parameters stripping ?t=..., are not directories, and are openable and verifiable as PIL images. • Identical Reference Checks: Introduced checks in both the backend and frontend submitGenerateScenery inside car.html to raise an HTTP 400 exception / display a toast warning if the model and scene references point to the same image. • Dynamic Prompt Mapping: Configured the backend to auto-translate occurrences of image 1/2/3 in custom scenery prompts to Picture 1/2/3, facilitating correct Qwen layout hint targeting. • Regression Unit Tests: Wrote comprehensive unit tests test_13b_scenery_validation_checks in test_regression_api.py verifying file checking, duplicate reference detection, and query parameter stripping. Verification • Executed test_regression_api.py simulated API testing with 100% success 19/19 tests passed. • Executed test_regression_qwen.py end-to-end model/hardware integration test suite successfully 2/2 tests passed.
This commit is contained in:
@@ -2556,34 +2556,66 @@
|
||||
|
||||
// --- HYDRATION_START ---
|
||||
const PRELOADED_IMAGES = [
|
||||
"20260701_064213_sc_pad_view_000_000deg.png",
|
||||
"20260701_113041_sc_3_20260628_205049_image.png",
|
||||
"20260701_112945_sc_3_20260628_205049_image.png",
|
||||
"20260701_112713_sc_3_20260628_205049_image.png",
|
||||
"20260701_112118_sc_image.nobg.png",
|
||||
"20260701_111927_sc_image.nobg.png",
|
||||
"20260701_111515_sc_image.nobg.png",
|
||||
"20260701_111415_sc_image.png",
|
||||
"20260701_111333_image.png",
|
||||
"20260701_111102_sc_image.png",
|
||||
"20260701_111027_image.png",
|
||||
"20260701_110958_test_upload_image.png",
|
||||
"20260701_110930_test_upload_image.png",
|
||||
"20260701_110842_test_upload_image.png",
|
||||
"20260701_110730_image.png",
|
||||
"20260701_110604_sc_image.png",
|
||||
"20260701_110400_sc_image.png",
|
||||
"20260701_105852_sc_image.nobg.png",
|
||||
"20260701_105307_sc_image.nobg.nobg.png",
|
||||
"20260701_105019_sc_image.nobg.nobg.png",
|
||||
"20260701_105003_sc_image.nobg.png",
|
||||
"20260701_104901_sc_image.nobg.png",
|
||||
"20260701_064734_sc_image.nobg.nobg.png",
|
||||
"20260701_104623_sc_image.nobg.png",
|
||||
"20260701_104606_sc_image.nobg.png",
|
||||
"20260701_104550_sc_image.nobg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_023_345deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_022_330deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_021_315deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_020_300deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_019_285deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_018_270deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_017_255deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_016_240deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_015_225deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_014_210deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_013_195deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_012_180deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_011_165deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_010_150deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_009_135deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_008_120deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_007_105deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_006_090deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_005_075deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_004_060deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_003_045deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_002_030deg.png",
|
||||
"20260701_065556_sc_3_20260628_205049_image.nobg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_001_015deg.png",
|
||||
"_turntable/cg_9aadaf6d/views/view_000_000deg.png",
|
||||
"20260701_064913_sc_1_20260618_053458_image.png",
|
||||
"20260701_064840_mr_1_20260618_053458_image.png",
|
||||
"20260701_064828_sc_image.png",
|
||||
"20260701_064812_test_upload_image.png",
|
||||
"20260701_064734_test_upload_image.png",
|
||||
"20260701_064603_sc_image.png",
|
||||
"20260701_064521_sc_image.png",
|
||||
"20260701_064420_sc_image.png",
|
||||
"20260701_063422_sc_2_20260618_052526_image.nobg.nobg.png",
|
||||
"20260701_062850_sc_pad_view_000_000deg.png",
|
||||
"20260701_062218_pad_view_000_000deg.png",
|
||||
"20260701_062201_pad_view_000_000deg.png",
|
||||
"20260701_062144_pad_view_000_000deg.png",
|
||||
"20260701_062128_pad_view_000_000deg.png",
|
||||
"20260701_062111_pad_view_000_000deg.png",
|
||||
"20260701_062054_pad_view_000_000deg.png",
|
||||
"20260701_062037_pad_view_000_000deg.png",
|
||||
"20260701_061913_pad_view_000_000deg.png",
|
||||
"20260701_061854_pad_view_000_000deg.png",
|
||||
"20260701_061837_pad_view_000_000deg.png",
|
||||
"20260701_061814_pad_view_000_000deg.png",
|
||||
"20260701_060854_pad_view_000_000deg.png",
|
||||
"20260701_060215_pad_view_000_000deg.png",
|
||||
"20260701_060110_pad_view_000_000deg.png",
|
||||
"20260701_060054_pad_view_000_000deg.png",
|
||||
"20260701_055944_pad_view_000_000deg.png",
|
||||
"20260701_055727_pad_view_000_000deg.png",
|
||||
"20260701_055710_pad_view_000_000deg.png",
|
||||
"20260701_055654_pad_view_000_000deg.png",
|
||||
"20260701_055637_pad_view_000_000deg.png",
|
||||
"20260701_055621_pad_view_000_000deg.png",
|
||||
"20260701_055605_pad_view_000_000deg.png",
|
||||
"20260701_055542_pad_view_000_000deg.png",
|
||||
"up_f475c600_face.png",
|
||||
"20260701_055451_pad_view_000_000deg.png",
|
||||
"20260701_051754_image.png",
|
||||
"20260701_051737_image.png",
|
||||
"20260701_051721_image.png",
|
||||
@@ -3265,7 +3297,6 @@
|
||||
"20260628_205348_9_20260628_205049_image.png",
|
||||
"20260628_205336_8_20260628_205049_image.png",
|
||||
"20260628_205325_7_20260628_205049_image.png",
|
||||
"20260628_205302_5_20260628_205049_image.png",
|
||||
"20260628_205240_3_20260628_205049_image.png",
|
||||
"20260628_205229_2_20260628_205049_image.png",
|
||||
"20260628_205217_1_20260628_205049_image.png",
|
||||
@@ -16035,6 +16066,30 @@
|
||||
if (!bg) { showToast('Set a background (Image 1) — capture, upload, or Shift+Click', 'error'); return; }
|
||||
if (!person || person.kind !== 'file') { showToast('Set a person image (Image 2) from the filmstrip', 'error'); return; }
|
||||
if (extra && extra.kind !== 'file') { showToast('Image 3 must be a gallery image', 'error'); return; }
|
||||
|
||||
// Validate distinct files
|
||||
if (bg.kind === 'file' && person.kind === 'file' && bg.name === person.name) {
|
||||
showToast('Image 1 (scenery) and Image 2 (person) cannot be the same image.', 'error');
|
||||
return;
|
||||
}
|
||||
if (bg.kind === 'wireframe' && person.kind === 'file' && bg.name === person.name) {
|
||||
showToast('Image 1 (scenery) and Image 2 (person) cannot be the same image.', 'error');
|
||||
return;
|
||||
}
|
||||
if (extra && extra.kind === 'file') {
|
||||
if (person.kind === 'file' && extra.name === person.name) {
|
||||
showToast('Image 3 (extra reference) and Image 2 (person) cannot be the same image.', 'error');
|
||||
return;
|
||||
}
|
||||
if (bg.kind === 'file' && extra.name === bg.name) {
|
||||
showToast('Image 3 (extra reference) and Image 1 (scenery) cannot be the same image.', 'error');
|
||||
return;
|
||||
}
|
||||
if (bg.kind === 'wireframe' && extra.name === bg.name) {
|
||||
showToast('Image 3 (extra reference) and Image 1 (scenery) cannot be the same image.', 'error');
|
||||
return;
|
||||
}
|
||||
}
|
||||
const prompt = (document.getElementById('scenePromptInput')?.value || '').trim() || null;
|
||||
const btn = document.getElementById('sceneGenBtn');
|
||||
const statusEl = document.getElementById('sceneJobStatus');
|
||||
@@ -16051,11 +16106,23 @@
|
||||
let sceneImage = null;
|
||||
if (bg.kind === 'bytes') {
|
||||
sceneBytes = bg.data;
|
||||
if (bg.filename) {
|
||||
sceneImage = bg.filename;
|
||||
}
|
||||
} else if (bg.kind === 'wireframe') {
|
||||
sceneImage = bg.name;
|
||||
} else if (bg.kind === 'file') {
|
||||
sceneImage = bg.name;
|
||||
try {
|
||||
sceneBytes = await _fetchAsBase64(_sceneUrlForName(bg.name));
|
||||
} catch (e) {
|
||||
showToast('Could not read background image: ' + e, 'error');
|
||||
if (btn) btn.disabled = false; if (statusEl) statusEl.style.display = 'none'; return;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
sceneBytes = await _fetchAsBase64(_sceneUrlForName(bg.name));
|
||||
sceneImage = bg.name;
|
||||
} catch (e) {
|
||||
showToast('Could not read background image: ' + e, 'error');
|
||||
if (btn) btn.disabled = false; if (statusEl) statusEl.style.display = 'none'; return;
|
||||
|
||||
Reference in New Issue
Block a user