Skip to content

Refactor solver and UI code, add tests, improve configuration - #7

Merged
petergstfsn merged 3 commits into
mainfrom
claude/sleepy-heisenberg-2kau9o
Jun 12, 2026
Merged

Refactor solver and UI code, add tests, improve configuration#7
petergstfsn merged 3 commits into
mainfrom
claude/sleepy-heisenberg-2kau9o

Conversation

@petergstfsn

Copy link
Copy Markdown
Contributor

Summary

This PR consolidates duplicated code across the solver and UI layers, adds comprehensive test coverage, improves configuration handling, and fixes several bugs in mask morphology operations and region ID generation.

Key Changes

Solver & Geometry Refactoring

  • Removed duplicate connector segment building logic from mesh.ts and solverWorker.ts, consolidating into a single buildConnectorSegments() function in solverWorker.ts
  • Removed unused functions from voxel.ts: nearestDomainPoint(), paintTubeSample(), paintTubeSegment(), and rasterizeConnectionGraph() (dead code)
  • Removed unused functions from mesh.ts: buildOrganicTrussGeometry(), makeNodeSphere(), makeEdgeCylinder(), and related helpers
  • Removed unused geometry utilities from geometry.ts: toNonIndexedGeometryFromPositions() and gatherPositionsByFaces()
  • Moved estimateSolverMemoryBytes() from solverWorker.ts to geometry.ts for better organization
  • Exported retainConnectedToAnchors() from optimize.ts for use in tests

Mask Morphology Bug Fixes

  • Fixed critical bug in dilateMask() and erodeMask(): These functions now properly avoid mutating the caller's input mask when iterations >= 2 by using a ping-pong buffer strategy that never writes back to the original mask
  • Added clarifying comments explaining the buffer management approach

UI & State Management

  • Refactored region ID generation in studyState.ts:
    • Introduced faceIndicesMatching() helper to reduce code duplication in face filtering functions
    • Added nextSequentialId() function that generates IDs based on the maximum existing ID number rather than array length, preventing ID collisions when regions are deleted
    • Updated buildConstraintGroups() to use the new ID generation strategy
  • Fixed load case ID generation in App.tsx to use the new nextSequentialId() function
  • Improved event listener management in ViewerCanvas.tsx with better capture-phase handling for right-click selection clearing

Configuration & Quality Profile

  • Refactored resolveQualityProfile() in config.ts:
    • Changed signature to accept outcomeCount instead of pre-calculated estimatedBytes
    • Now calculates memory estimates internally using the moved estimateSolverMemoryBytes() function
    • Simplified logic and improved clarity
  • Enhanced Settings class in config.py:
    • Added environment variable support (OPENTOS_DATA_DIR, OPENTOS_MAX_WORKERS)
    • Added helper function _int_env() for safe integer environment variable parsing
    • Improved documentation with docstring explaining configuration options

Database & API Improvements

  • Improved database connection handling in database.py:
    • Extracted _connect() function with WAL mode and busy timeout configuration
    • Enables concurrent reader/writer access needed for worker thread progress updates
  • Refactored outcome parsing in repository.py:
    • Extracted _parse_outcome_row() helper to reduce duplication in get_outcomes_by_job_v2() and get_outcomes_by_study_v2()
  • Improved API lifecycle management in main.py:
    • Added _lifespan() context manager for proper initialization and shutdown of JobManager
    • Ensures database is initialized on startup
  • Vectorized world-to-voxel conversion in fusion_solver.py:
    • Renamed _world_to_index() to _world_to_indices() and refactored to process multiple points at once using NumPy operations
    • Improves performance for batch coordinate transformations

Test Coverage

  • Added comprehensive voxel morphology tests (voxel.test.ts):
    • Tests dilation/eros

https://claude.ai/code/session_01EjrufiVyciihwDSSqtjxfd

claude added 3 commits June 12, 2026 20:05
- dilateMask/erodeMask no longer mutate their input mask when run for
  multiple iterations (previously corrupted surfaceMask in the open-mesh
  voxelization fallback and any multi-voxel thickness enforcement)
- force and load-case ids derive from the max existing id instead of
  array length, so deleting an entry can no longer mint a duplicate id
- constraint region ids are keyed by the group's smallest face index so
  load-case fixed-region references stay attached to the same physical
  region when painting adds/removes groups earlier in face order
- browser quality profile resolution estimates memory from the requested
  profile's voxel target instead of a hardcoded high-fidelity count
- connector segments and connector mask are computed once per solve
  instead of once per variant; truss boost reuses the same segments
- worker message omits the encoded model base64 (worker solves from the
  transferred position buffer only)
- right-click clear listeners scoped to the canvas instead of window
- BFS in minSurfaceHops uses an index cursor instead of Array.shift
- remove dead code: unused truss/connection-graph builders, unused
  exports (lerp, volumeOfOccupancy, gatherPositionsByFaces, etc.),
  duplicate vite.config.js that shadowed vite.config.ts, orphaned
  tsconfig.node.json
- tests: voxel morphology non-mutation, quality resolution, stable
  region ids, sequential id minting

https://claude.ai/code/session_01EjrufiVyciihwDSSqtjxfd
- replace deprecated on_event startup with a lifespan handler and shut
  down the JobManager thread pool on app shutdown
- disable CORS allow_credentials: the API is unauthenticated and
  cookie-free, and wildcard origins with credentials is an insecure
  combination
- open SQLite in WAL mode with a busy timeout (worker threads update job
  progress while request handlers poll) and roll back on errors
- POST /studies/{id}/run accepts an absent body, matching the documented
  'optional run options' contract (previously 422)
- replace deprecated trimesh Scene.dump(concatenate=True) with
  Scene.to_geometry()
- vectorize world->voxel index mapping (was inverting the 4x4 transform
  once per preserved/fixed face center)
- allow OPENTOS_DATA_DIR / OPENTOS_MAX_WORKERS env overrides with
  unchanged defaults; gitignore runtime SQLite files
- log job failures via logging instead of traceback.print_exc; remove
  never-written baseline/ and reports/ study directories
- remove dead validate_solve_payload shim; deduplicate outcome row
  parsing in the repository
- tests: repository job/outcome round-trips, bodyless run request

https://claude.ai/code/session_01EjrufiVyciihwDSSqtjxfd
- GitHub Actions: web typecheck/test/build on Node 22, API pytest on
  Python 3.11
- document OPENTOS_DATA_DIR / OPENTOS_MAX_WORKERS overrides in the API
  README and link them from the root README
- fix stale /api/solve reference in the web .env.example

https://claude.ai/code/session_01EjrufiVyciihwDSSqtjxfd
@petergstfsn
petergstfsn merged commit ec24619 into main Jun 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants