Spaces:
Running
on
Zero
Running
on
Zero
Commit
·
5c73419
1
Parent(s):
98cf79e
Fix CONDA_PREFIX env, add Open3D for GLB mesh export
Browse files- app.py +33 -7
- requirements.txt +1 -0
app.py
CHANGED
|
@@ -21,6 +21,12 @@ from PIL import Image
|
|
| 21 |
if os.environ.get("HF_TOKEN"):
|
| 22 |
login(token=os.environ.get("HF_TOKEN"))
|
| 23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
# Clone sam-3d-objects repo if not exists
|
| 25 |
SAM3D_PATH = Path("/home/user/app/sam-3d-objects")
|
| 26 |
if not SAM3D_PATH.exists():
|
|
@@ -142,27 +148,47 @@ def reconstruct_objects(image: np.ndarray):
|
|
| 142 |
if result is None:
|
| 143 |
return None, preview, "⚠️ 3D reconstruction failed"
|
| 144 |
|
| 145 |
-
# Export as
|
| 146 |
output_dir = tempfile.mkdtemp()
|
| 147 |
-
|
| 148 |
|
| 149 |
-
#
|
| 150 |
if hasattr(result, 'save_ply'):
|
|
|
|
|
|
|
| 151 |
result.save_ply(ply_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
elif 'gaussians' in result:
|
|
|
|
| 153 |
result['gaussians'].save_ply(ply_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
else:
|
| 155 |
-
# Try to extract vertices
|
| 156 |
vertices = result.get('xyz', result.get('points', None))
|
| 157 |
if vertices is not None:
|
| 158 |
if torch.is_tensor(vertices):
|
| 159 |
vertices = vertices.cpu().numpy()
|
| 160 |
-
|
| 161 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
else:
|
| 163 |
return None, preview, "⚠️ Could not extract 3D data"
|
| 164 |
|
| 165 |
-
return
|
| 166 |
|
| 167 |
except Exception as e:
|
| 168 |
import traceback
|
|
|
|
| 21 |
if os.environ.get("HF_TOKEN"):
|
| 22 |
login(token=os.environ.get("HF_TOKEN"))
|
| 23 |
|
| 24 |
+
# Set CUDA_HOME for sam-3d-objects (expects conda but we're not using it)
|
| 25 |
+
if "CUDA_HOME" not in os.environ:
|
| 26 |
+
os.environ["CUDA_HOME"] = "/usr/local/cuda"
|
| 27 |
+
if "CONDA_PREFIX" not in os.environ:
|
| 28 |
+
os.environ["CONDA_PREFIX"] = "/usr/local"
|
| 29 |
+
|
| 30 |
# Clone sam-3d-objects repo if not exists
|
| 31 |
SAM3D_PATH = Path("/home/user/app/sam-3d-objects")
|
| 32 |
if not SAM3D_PATH.exists():
|
|
|
|
| 148 |
if result is None:
|
| 149 |
return None, preview, "⚠️ 3D reconstruction failed"
|
| 150 |
|
| 151 |
+
# Export as GLB
|
| 152 |
output_dir = tempfile.mkdtemp()
|
| 153 |
+
glb_path = f"{output_dir}/object_{uuid.uuid4().hex[:8]}.glb"
|
| 154 |
|
| 155 |
+
# Extract point cloud from result and convert to mesh
|
| 156 |
if hasattr(result, 'save_ply'):
|
| 157 |
+
# Save temp PLY then convert
|
| 158 |
+
ply_path = f"{output_dir}/temp.ply"
|
| 159 |
result.save_ply(ply_path)
|
| 160 |
+
# Load and convert to mesh using Open3D
|
| 161 |
+
import open3d as o3d
|
| 162 |
+
pcd = o3d.io.read_point_cloud(ply_path)
|
| 163 |
+
# Estimate normals and create mesh via Poisson reconstruction
|
| 164 |
+
pcd.estimate_normals()
|
| 165 |
+
mesh, _ = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=8)
|
| 166 |
+
o3d.io.write_triangle_mesh(glb_path, mesh)
|
| 167 |
elif 'gaussians' in result:
|
| 168 |
+
ply_path = f"{output_dir}/temp.ply"
|
| 169 |
result['gaussians'].save_ply(ply_path)
|
| 170 |
+
import open3d as o3d
|
| 171 |
+
pcd = o3d.io.read_point_cloud(ply_path)
|
| 172 |
+
pcd.estimate_normals()
|
| 173 |
+
mesh, _ = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=8)
|
| 174 |
+
o3d.io.write_triangle_mesh(glb_path, mesh)
|
| 175 |
else:
|
| 176 |
+
# Try to extract vertices
|
| 177 |
vertices = result.get('xyz', result.get('points', None))
|
| 178 |
if vertices is not None:
|
| 179 |
if torch.is_tensor(vertices):
|
| 180 |
vertices = vertices.cpu().numpy()
|
| 181 |
+
# Create mesh from points
|
| 182 |
+
import open3d as o3d
|
| 183 |
+
pcd = o3d.geometry.PointCloud()
|
| 184 |
+
pcd.points = o3d.utility.Vector3dVector(vertices)
|
| 185 |
+
pcd.estimate_normals()
|
| 186 |
+
mesh, _ = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=8)
|
| 187 |
+
o3d.io.write_triangle_mesh(glb_path, mesh)
|
| 188 |
else:
|
| 189 |
return None, preview, "⚠️ Could not extract 3D data"
|
| 190 |
|
| 191 |
+
return glb_path, preview, f"✓ Detected {len(masks)} objects, reconstructed largest"
|
| 192 |
|
| 193 |
except Exception as e:
|
| 194 |
import traceback
|
requirements.txt
CHANGED
|
@@ -10,6 +10,7 @@ numpy>=1.26.0
|
|
| 10 |
opencv-python>=4.8.0
|
| 11 |
Pillow>=10.0.0
|
| 12 |
trimesh>=4.0.0
|
|
|
|
| 13 |
hydra-core>=1.3.0
|
| 14 |
omegaconf>=2.3.0
|
| 15 |
einops>=0.7.0
|
|
|
|
| 10 |
opencv-python>=4.8.0
|
| 11 |
Pillow>=10.0.0
|
| 12 |
trimesh>=4.0.0
|
| 13 |
+
open3d>=0.18.0
|
| 14 |
hydra-core>=1.3.0
|
| 15 |
omegaconf>=2.3.0
|
| 16 |
einops>=0.7.0
|