[Windows] Fixes for extremely slow execution / pipeline hanging
Environment
- OS: Windows 11
- GPU: NVIDIA RTX 5060 (8GB VRAM)
- Python: 3.11
- PyTorch: 2.8.0+cu128
- xatlas: 0.0.11 (pip)
- Hunyuan3D-2 commit: [fill in your commit hash]
Summary
When running the full pipeline (shape + texture) on Windows, the texture generation stage encounters two severe performance bottlenecks. These issues prevent the pipeline from completing within a reasonable timeframe.
Bug 1: xatlas hangs on Windows when processing high-poly meshes
File: hy3dgen/texgen/utils/uv_warp_utils.py
Symptom: When xatlas.parametrize() attempts to process a mesh with 1.3 million faces, there is no terminal output, CPU utilization drops to extremely low levels (~10%), and the process becomes completely unresponsive even after waiting 7+ minutes.
Root Cause: The Python binding for xatlas seems to have a severe performance cliff on Windows for high-poly meshes (>100K faces). This is suspected to be related to debug compilation configurations or other platform-specific factors.
Fix: Replace xatlas with the Blender Python API. Blender's heavily battle-tested C++ implementation only takes ~1 second to complete UV unwrapping for a 1.3M face mesh on Windows.
Below is the complete implementation to replace the original xatlas code. It uses a temporary file approach to bridge trimesh and bpy:
import os
import tempfile
import bpy
import trimesh
# Original code to replace:
# vmapping, indices, uvs = xatlas.parametrize(mesh.vertices, mesh.faces)
# mesh.vertices = mesh.vertices[vmapping]
# mesh.faces = indices
# mesh.visual.uv = uvs
# --- Proposed Fix ---
def apply_blender_uv_mapping(mesh: trimesh.Trimesh) -> trimesh.Trimesh:
"""
Replaces xatlas parameterization with Blender's Smart UV Project.
"""
with tempfile.TemporaryDirectory() as temp_dir:
temp_in = os.path.join(temp_dir, "temp_in.obj")
temp_out = os.path.join(temp_dir, "temp_out.obj")
# 1. Export current mesh to a temporary OBJ
mesh.export(temp_in)
# 2. Clear existing mesh objects in the Blender scene
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.select_by_type(type='MESH')
bpy.ops.object.delete()
# 3. Import the OBJ into Blender (handles API differences across Blender versions)
if hasattr(bpy.ops.wm, 'obj_import'):
bpy.ops.wm.obj_import(filepath=temp_in)
else:
bpy.ops.import_scene.obj(filepath=temp_in)
obj = bpy.context.selected_objects[0]
bpy.context.view_layer.objects.active = obj
# 4. Perform Smart UV Project
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.uv.smart_project(angle_limit=66.0, island_margin=0.01)
bpy.ops.object.mode_set(mode='OBJECT')
# 5. Export the unwrapped mesh back to OBJ
if hasattr(bpy.ops.wm, 'obj_export'):
bpy.ops.wm.obj_export(filepath=temp_out, export_materials=False)
else:
bpy.ops.export_scene.obj(filepath=temp_out, use_materials=False)
# 6. Load the new mesh (process=False prevents trimesh from reordering/merging vertices, preserving UVs)
new_mesh = trimesh.load(temp_out, process=False)
# 7. Update the original mesh attributes
mesh.vertices = new_mesh.vertices
mesh.faces = new_mesh.faces
mesh.visual = new_mesh.visual
return mesh
# Usage:
# mesh = apply_blender_uv_mapping(mesh)
Bug 2: Severe redundancy in the uncolored_vtxs list in meshVerticeInpaint_smooth
File: hy3dgen/texgen/differentiable_renderer/mesh_processor.py (around line 42)
Symptom: During the texture inpainting stage, the while loop in meshVerticeInpaint_smooth iterates over ~1.83 million entries per round, taking 9+ minutes per round.
Root Cause: The uncolored_vtxs list is constructed by gathering "3 vertices per face." Consequently, a massive number of entries point to the exact same vertex. For example: a 600K face mesh results in 1.8M entries, but only ~58K unique vertices after deduplication. The loop currently processes 1.8M iterations per round for only 58K valid vertices.
Fix: Deduplicate the uncolored_vtxs list at the beginning of each while loop round.
# Around line 47 in mesh_processor.py
while smooth_count > 0:
uncolored_vtxs = list(set(uncolored_vtxs)) # Add this line to deduplicate
uncolored_vtx_count = 0
# ... rest of the loop ...
Disclaimer
- The above modifications have only been successfully tested on a single demo image (
assets/demo.png). - Comprehensive or batch regression testing has not yet been performed.
- These changes may have unknown impacts on other configurations or inputs.
- Blender's UV unwrapping island splitting strategy may differ from xatlas; final texture mapping results require manual visual comparison to ensure quality parity.
Source: Tencent-Hunyuan/Hunyuan3D-2