ASM-o2.1-Multiimage / bottom_block.txt
arabago96's picture
Port Local BiRefNet: Fix ZeroGPU Quota & Remove API Dependency
7b4973f
# === PREVIEW IMAGES ===
if images:
preview_header = doc.add_paragraph()
run = preview_header.add_run("PREVIEW RENDERS")
run.font.size = Pt(12)
run.font.bold = True
run.font.color.rgb = RGBColor(70, 70, 70)
doc.add_paragraph() # spacing
# Only include HDRI Forest textured renders (shaded_forest key)
if 'shaded_forest' in images:
forest_images = images['shaded_forest']
# Create a table to arrange images horizontally
img_table = doc.add_table(rows=1, cols=len(forest_images))
img_table.alignment = WD_ALIGN_PARAGRAPH.CENTER
for idx, img_array in enumerate(forest_images):
# Convert numpy array to PIL Image
img_pil = Image.fromarray(img_array.astype('uint8'))
# Save to temp file
temp_img = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
img_pil.save(temp_img.name)
# Add to table cell
cell = img_table.rows[0].cells[idx]
cell_para = cell.paragraphs[0]
cell_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = cell_para.add_run()
run.add_picture(temp_img.name, width=Inches(6.5 / len(forest_images))) # Divide page width
os.unlink(temp_img.name)
doc.add_paragraph() # spacing
doc.add_paragraph() # spacing
# Model details
doc.add_paragraph()
details_header = doc.add_paragraph()
run = details_header.add_run("MODEL DETAILS")
run.font.size = Pt(12)
run.font.bold = True
run.font.color.rgb = RGBColor(70, 70, 70)
doc.add_paragraph() # spacing
doc.add_paragraph() # spacing
details = doc.add_paragraph()
details.add_run(f"File Size: {file_size:.1f} MB\n")
# Handle mesh info with proper N/A formatting
verts_before = mesh_info.get('vertices_before', 'N/A')
faces_before = mesh_info.get('faces_before', 'N/A')
verts_final = mesh_info.get('final_vertices', 'N/A')
faces_final = mesh_info.get('final_faces', 'N/A')
if verts_before != 'N/A':
details.add_run(f"Vertices (before export): {verts_before:,}\n")
else:
details.add_run(f"Vertices (before export): N/A\n")
if faces_before != 'N/A':
details.add_run(f"Faces (before export): {faces_before:,}\n")
else:
details.add_run(f"Faces (before export): N/A\n")
if verts_final != 'N/A':
details.add_run(f"Final Vertices: {verts_final:,}\n")
else:
details.add_run(f"Final Vertices: N/A\n")
if faces_final != 'N/A':
details.add_run(f"Final Faces: {faces_final:,}")
else:
details.add_run(f"Final Faces: N/A")
doc.add_paragraph() # spacing
# === DETAILED TIMING BREAKDOWN ===
timing_header = doc.add_paragraph()
run = timing_header.add_run("DETAILED TIMING BREAKDOWN")
run.font.size = Pt(12)
run.font.bold = True
run.font.color.rgb = RGBColor(70, 70, 70)
timing_details = doc.add_paragraph()
run = timing_details.add_run(f"STEP 1 ({step1_time:.2f}s total)\n")
run.font.bold = True
run.font.size = Pt(11)
timing_details.add_run(f" Pipeline Total: {timings.get('pipeline_total', 0):.2f}s\n")
timing_details.add_run(f" • Sparse Structure: {timings.get('sparse_structure', 0):.2f}s\n")
timing_details.add_run(f" • Shape SLat: {timings.get('shape_slat', 0):.2f}s\n")
timing_details.add_run(f" • Texture SLat: {timings.get('texture_slat', 0):.2f}s\n")
timing_details.add_run(f" Mesh Simplification: {timings.get('mesh_simplify', 0):.2f}s\n")
timing_details.add_run(f" Preview Rendering: {timings.get('rendering', 0):.2f}s\n")
if step2_time > 0:
timing_details.add_run("\n")
run = timing_details.add_run(f"STEP 2 ({step2_time:.2f}s total)\n")
run.font.bold = True
run.font.size = Pt(11)
timing_details.add_run(f" Decode Latent: {timings.get('decode', 0):.2f}s\n")
timing_details.add_run(f" Mesh Simplification: {timings.get('simplify', 0):.2f}s\n")
timing_details.add_run(f" to_glb (remesh+texture baking): {timings.get('to_glb', 0):.2f}s\n")
timing_details.add_run(f" Save to File: {timings.get('save_file', 0):.2f}s\n")
doc.add_paragraph() # spacing
doc.add_paragraph() # spacing
# Quality rating section
rating_header = doc.add_paragraph()
run = rating_header.add_run("QUALITY RATING")
run.font.size = Pt(12)
run.font.bold = True
run.font.color.rgb = RGBColor(70, 70, 70)
doc.add_paragraph() # spacing
rating_categories = [
("Accuracy", "accuracy"),
("Realism", "realism"),
("Geometry Quality", "geometry_quality"),
("Texture Quality", "texture_quality"),
("Topology", "topology"),
("Detail Preservation", "detail_preservation")
]
for category_name, category_key in rating_categories:
rating_value = ratings.get(category_key, [])
# rating_value is a list of checked numbers
highest_rating = max(rating_value) if rating_value else 0
p = doc.add_paragraph()
p.add_run(f"{category_name}: ")
if highest_rating > 0:
# Show checkboxes with X for selected
checkbox_str = " ".join([f"[{'X' if i in rating_value else ' '}] {i}" for i in range(1, 6)])
run = p.add_run(checkbox_str)
run.font.bold = True
p.add_run(f" → Score: {highest_rating}/5")
else:
p.add_run("[ ] 1 [ ] 2 [ ] 3 [ ] 4 [ ] 5")
p = doc.add_paragraph()
p.add_run("\nFAVORITE: ")
if ratings.get('favorite', False):
p.add_run("[X]").font.bold = True
else:
p.add_run("[ ]")
doc.add_paragraph("=" * 80)
# Notes section
notes_header = doc.add_paragraph()
notes_header.add_run("NOTES").font.bold = True
doc.add_paragraph("=" * 80)
notes_p = doc.add_paragraph(notes if notes else "\n\n\n")
doc.add_paragraph("=" * 80)
# Save DOCX