Rawal Khirodkar commited on
Commit
14f2b6a
·
1 Parent(s): 7fe52e0

Pointmap: radius from KD-tree median nearest-neighbour distance × 0.6 (proper 2D-surface heuristic)

Browse files
Files changed (1) hide show
  1. app.py +11 -5
app.py CHANGED
@@ -267,11 +267,17 @@ def _make_glb(image_pil_texture: Image.Image, pointmap_hwc: np.ndarray,
267
  centroid = pts.mean(axis=0).astype(np.float32) if len(pts) else np.zeros(3, np.float32)
268
  pts = pts - centroid
269
 
270
- # Sphere radius median nearest-neighbour distance in this cloud.
271
- # Quick proxy: use scene extent / cbrt(N) which approximates inter-point
272
- # spacing for a uniformly sampled volume.
273
- extent = float(np.ptp(pts, axis=0).max()) if len(pts) else 1.0
274
- radius = max(extent / max(np.cbrt(len(pts)), 1.0) * 0.7, 1e-4)
 
 
 
 
 
 
275
 
276
  # Icosphere template (subdivisions=1 → 42 verts, 80 faces — smoother balls).
277
  sphere = trimesh.creation.icosphere(subdivisions=1, radius=radius)
 
267
  centroid = pts.mean(axis=0).astype(np.float32) if len(pts) else np.zeros(3, np.float32)
268
  pts = pts - centroid
269
 
270
+ # Sphere radius from MEASURED median nearest-neighbour distance.
271
+ # Why measured (vs. extent / cbrt(N)): our points sit on a ~2D surface
272
+ # (skin), not in a 3D volume — a kd-tree gives the right spacing directly.
273
+ # Factor 0.6 adjacent balls overlap slightly, forming a solid surface
274
+ # without big gaps and without obvious overlap blobs.
275
+ if len(pts) >= 2:
276
+ from scipy.spatial import cKDTree
277
+ nn_dist = cKDTree(pts).query(pts, k=2)[0][:, 1] # k=1 is self
278
+ radius = max(float(np.median(nn_dist)) * 0.6, 1e-4)
279
+ else:
280
+ radius = 0.005 # fallback for empty/tiny clouds
281
 
282
  # Icosphere template (subdivisions=1 → 42 verts, 80 faces — smoother balls).
283
  sphere = trimesh.creation.icosphere(subdivisions=1, radius=radius)