samrobertsondev commited on
Commit
4ff935e
·
verified ·
1 Parent(s): d42d85e

Upload 2 files

Browse files
Files changed (1) hide show
  1. app.py +20 -2
app.py CHANGED
@@ -144,6 +144,7 @@ def pointcloud_to_mesh_glb_bytes(points: np.ndarray, colors: np.ndarray) -> byte
144
  export as GLB with vertex colors.
145
  """
146
  print("Building mesh from point cloud for GLB export")
 
147
  # Optional: downsample for speed
148
  max_points = 50000
149
  if points.shape[0] > max_points:
@@ -159,7 +160,23 @@ def pointcloud_to_mesh_glb_bytes(points: np.ndarray, colors: np.ndarray) -> byte
159
  pcd.points = o3d.utility.Vector3dVector(pts_ds.astype(np.float64))
160
  pcd.colors = o3d.utility.Vector3dVector((cols_ds / 255.0).astype(np.float64))
161
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  # Poisson reconstruction
 
163
  mesh, densities = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(
164
  pcd, depth=8
165
  )
@@ -183,11 +200,13 @@ def pointcloud_to_mesh_glb_bytes(points: np.ndarray, colors: np.ndarray) -> byte
183
  raise RuntimeError("Mesh reconstruction failed; got empty mesh")
184
 
185
  # Transfer colors from original (downsampled) cloud to mesh vertices
 
186
  pcd_tree = o3d.geometry.KDTreeFlann(pcd)
187
  vert_colors = []
 
188
  for v in verts:
189
  _, idx, _ = pcd_tree.search_knn_vector_3d(v, 1)
190
- vert_colors.append(np.asarray(pcd.colors)[idx[0]])
191
  vert_colors = np.stack(vert_colors, axis=0) # (V,3) in [0,1]
192
 
193
  # Convert to trimesh for GLB export
@@ -203,7 +222,6 @@ def pointcloud_to_mesh_glb_bytes(points: np.ndarray, colors: np.ndarray) -> byte
203
  glb_bytes = glb_bytes.encode("utf-8")
204
  return glb_bytes
205
 
206
-
207
  def infer_and_export_files(image: np.ndarray):
208
  if image is None:
209
  raise gr.Error("Please upload an image.")
 
144
  export as GLB with vertex colors.
145
  """
146
  print("Building mesh from point cloud for GLB export")
147
+
148
  # Optional: downsample for speed
149
  max_points = 50000
150
  if points.shape[0] > max_points:
 
160
  pcd.points = o3d.utility.Vector3dVector(pts_ds.astype(np.float64))
161
  pcd.colors = o3d.utility.Vector3dVector((cols_ds / 255.0).astype(np.float64))
162
 
163
+ # --- NEW: estimate normals ---
164
+ print("Estimating normals...")
165
+ pcd.estimate_normals(
166
+ search_param=o3d.geometry.KDTreeSearchParamKNN(knn=30)
167
+ )
168
+ # Or radius-based:
169
+ # pcd.estimate_normals(
170
+ # search_param=o3d.geometry.KDTreeSearchParamHybrid(
171
+ # radius=0.05, max_nn=30
172
+ # )
173
+ # )
174
+
175
+ # Optional: orient normals consistently (helps Poisson)
176
+ pcd.orient_normals_consistent_tangent_plane(orientation_k=30)
177
+
178
  # Poisson reconstruction
179
+ print("Running Poisson reconstruction...")
180
  mesh, densities = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(
181
  pcd, depth=8
182
  )
 
200
  raise RuntimeError("Mesh reconstruction failed; got empty mesh")
201
 
202
  # Transfer colors from original (downsampled) cloud to mesh vertices
203
+ print("Transferring vertex colors...")
204
  pcd_tree = o3d.geometry.KDTreeFlann(pcd)
205
  vert_colors = []
206
+ pcd_colors_np = np.asarray(pcd.colors)
207
  for v in verts:
208
  _, idx, _ = pcd_tree.search_knn_vector_3d(v, 1)
209
+ vert_colors.append(pcd_colors_np[idx[0]])
210
  vert_colors = np.stack(vert_colors, axis=0) # (V,3) in [0,1]
211
 
212
  # Convert to trimesh for GLB export
 
222
  glb_bytes = glb_bytes.encode("utf-8")
223
  return glb_bytes
224
 
 
225
  def infer_and_export_files(image: np.ndarray):
226
  if image is None:
227
  raise gr.Error("Please upload an image.")