Skip to content

Uniform spatial-grid neighbor search reimplemented independently 4x — extract a shared utility #395

Description

@mkofler96

Problem

The same uniform-grid (bucket by floor(coord/cell), then scan a 3×3×3 neighborhood of cells) nearest-neighbor search algorithm has been hand-rolled independently at least four times in web/src:

  1. web/src/workers/tie.ts:71nearestCrossBodyNeighbours (added in mkofler96/KoFEM#360, used by the node-merge bonded tie, Node-merge bonded tie for multibody parts that touch without a shared face #359).
  2. web/src/lib/shellize.ts:359 — an inline tie grid.
  3. web/src/lib/shellize.ts:427autoDetectCouplings (used by the RBE3/shell-solid coupling added in mkofler96/KoFEM#392, mkofler96/KoFEM#374).
  4. web/src/lib/shellize.ts:654shellNodeLocator.

Each site independently builds a Map<string, number[]> keyed by cell coordinates, inserts nodes, and walks dx/dy/dz ∈ {-1,0,1} to gather candidates within a search radius — the same ~20-30 lines of spatial-hashing logic, with minor variations (cell size source, key string format, ring count) and no shared helper.

Why this matters

This is exactly the kind of duplication that drifts: a correctness fix or perf improvement to the algorithm (e.g. handling ring counts >1 correctly, as shellNodeLocator's maxRings comment already hints is needed for sparse grids) has to be found and applied in up to four places, and nothing enforces that it is. The multibody tie effort (#359, #357) and the coupled solid-shell effort (mkofler96/KoFEM#374, mkofler96/KoFEM#392) arrived at the same spatial-query need independently and neither reused the other's implementation.

Suggested fix

Extract a single buildSpatialGrid(points, cellSize) / queryNeighbors(grid, point, rings) utility (e.g. web/src/lib/spatialGrid.ts) and have tie.ts and shellize.ts (all four call sites) build on it. Pure refactor — behavior should be unchanged if done carefully, but each of the four sites has slightly different semantics (mutual-nearest-neighbor pairing in tie.ts vs. plain radius query in shellize.ts), so the shared utility should expose the primitive (grid + neighbor query) and let each caller keep its own pairing/selection logic on top.

Related

Adjacent to the multibody tie work (#357, #359) and the shell/solid coupling work (mkofler96/KoFEM#374, mkofler96/KoFEM#392) — this is about the shared primitive underneath both, not a change to either feature's behavior.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions