88import os
99import sys
1010import threading
11+ import types
1112from pathlib import Path
1213from types import ModuleType
1314
@@ -100,6 +101,35 @@ def _module_file(module: ModuleType | None) -> Path | None:
100101 return Path (module .__file__ ).resolve ()
101102
102103
104+ def _ensure_torchmcubes_compat () -> None :
105+ try :
106+ import torchmcubes # noqa: F401
107+
108+ return
109+ except ImportError :
110+ pass
111+
112+ try :
113+ import mcubes
114+ import torch
115+ except ImportError as exc :
116+ raise ImportError (
117+ "3D reconstruction requires torchmcubes or PyMCubes for marching cubes."
118+ ) from exc
119+
120+ module = types .ModuleType ("torchmcubes" )
121+
122+ def marching_cubes (volume , threshold ):
123+ vertices , faces = mcubes .marching_cubes (volume .detach ().cpu ().numpy (), threshold )
124+ return (
125+ torch .as_tensor (vertices , dtype = volume .dtype , device = volume .device ),
126+ torch .as_tensor (faces , dtype = torch .long , device = volume .device ),
127+ )
128+
129+ module .marching_cubes = marching_cubes
130+ sys .modules ["torchmcubes" ] = module
131+
132+
103133def _import_tsr_from_bundle (root : Path ):
104134 source = (root / "TripoSR" ).resolve ()
105135 system_py = source / "tsr" / "system.py"
@@ -117,6 +147,7 @@ def _import_tsr_from_bundle(root: Path):
117147 if source_str in sys .path :
118148 sys .path .remove (source_str )
119149 sys .path .insert (0 , source_str )
150+ _ensure_torchmcubes_compat ()
120151
121152 try :
122153 from tsr .system import TSR
@@ -172,7 +203,8 @@ def _load_model(self, model_bundle: str | None, requested_device: str):
172203 import trimesh
173204 except ImportError as exc :
174205 raise ImportError (
175- "3D reconstruction requires torch, trimesh, einops, omegaconf, and PyMCubes."
206+ "3D reconstruction requires torch, trimesh, einops, omegaconf, "
207+ "and PyMCubes or torchmcubes."
176208 ) from exc
177209
178210 triposr = root / "TripoSR"
0 commit comments