Skip to content

Supporting profiles for lineaments and craters, with Craters/Lineaments export (#833) - #845

Merged
haraldsteinlechner merged 3 commits into
developfrom
features/833_supporting-profiles
Oct 20, 2026
Merged

haraldsteinlechner merged 3 commits into
developfrom
features/833_supporting-profiles

Conversation

@haraldsteinlechner

Copy link
Copy Markdown
Collaborator

Closes #833.

Generates supporting profiles, Sky-projected line annotations, across lineaments (polylines) and through craters (ellipses), and exports them together with their parent. User guide: docs/SupportingProfiles.md. Spec and design notes: docs/dev/SupportingProfiles.md.

What users get

  • Properties → Supporting Profiles: generate for the selected polyline, line or ellipse.
    • Polylines: perpendicular profiles by spacing (every d m) or by count (N equally spaced over the whole line). Profiles at the start and end are optional, and the length is centred on the line.
    • Ellipses: N-S, NE-SW, E-W, NW-SE (compass) or the major/minor axes, through the centre, ending exactly on the drawn outline.
  • Toolbar: Lineament profiles (Polyline) and Crater profiles (ellipses) generate the profiles as soon as the annotation is finished. Both are off by default and share their settings with the panel. Every setting has a tooltip.
  • Behaviour:
    • All or nothing: if one profile fails (e.g. an end hangs off the mesh), none are created and the message says why.
    • Generating again for the same parent replaces its earlier profiles, in a single undo step.
    • Profiles are added without text labels.
    • At most 1000 profiles per generation.
  • Export: two new presets, Craters (ellipses + profiles) and Lineaments (polylines + profiles). Each writes <file>.csv and <file>_profiles.csv, joined by parentKey, with profileIndex, profileDirection, profileAzimuth and profileStation on every profile row.
    • Surface properties in the profiles file are optional.
    • A new annotation-type filter, lines only (no generated profiles).

Compatibility

  • Scenes: each profile stores a ProfileLink under a new key profileOf, so older releases load the scene and see plain lines. The new reader is total: a link from a later version, or a damaged one, is dropped to None instead of failing the load.
  • Import: importing annotations re-keys them; profile links are relinked to the new keys.
  • Profile preset columns: the preset now writes parentKey, profileIndex, profileDirection, profileAzimuth and profileStation after surfaceName, empty for hand-drawn lines. Point columns therefore move five places to the right. Scripts that read columns by name are unaffected; scripts that read by position need updating. Worth a line in the release notes.

Also in here

  • Test harness: drawingScene used the AFC template's 10 m near plane. The annotation depth offset scales with distance/near, so draped lines and ellipse outlines z-fought with the terrain. It now uses PRo3D's default 0.1 m (ai/TESTING.md updated). The z-fighting itself (a depth offset that depends on the near plane) is left for a separate issue.
  • Test helpers: the export helpers moved from annotation-profile-export.spec.ts into tests-ui/src/export.ts for reuse.

Review

An agent review before opening this PR found two real bugs, both fixed with tests:

  1. Import re-keyed annotations without relinking their profiles, so the Craters/Lineaments profiles file came out empty after an import.
  2. Generating twice left two indistinguishable sets of profiles, which the export interleaved.

Also addressed:

  • the 1000-profile cap;
  • no profiles file when the window hides its checkbox (per-point granularity);
  • the total profileOf read;
  • auto mode passing its parent explicitly;
  • tests for a point clicked twice, a NaN azimuth round trip and the import relink.

Testing

  • Expecto: Section22_SupportingProfiles, 37 tests, covering:
    • stations for both modes and every start/end combination;
    • perpendicularity and rim intersection (asymmetric ellipses too);
    • all-or-nothing, replace on regenerate, undo;
    • persistence (including a later-version and a damaged link), import relink;
    • export records, presets, auto-trigger.
  • Full kernel-independent suite: 750 passed, 0 failed.
  • Playwright on the Dimorphos OPC (supporting-profiles.spec.ts, plus annotation-profile-export and ellipse-annotation for the near-plane change):
    • draws a crater and a lineament through the UI;
    • generates their profiles from the panel and from the toolbar (spacing and count);
    • runs both exports and checks the files: join, directions, azimuths, distance from 0, surface layers on every point.
    • The doc's screenshots come from this spec.

🤖 Generated with Claude Code

Generates Sky-projected line annotations ("profiles") from an existing
polyline or ellipse, by hand (Properties -> Supporting Profiles) or
automatically when one is finished (toolbar: Lineament / Crater profiles).

- Polylines: perpendicular profiles by spacing or by count over the whole
  line, with profiles at start/end optional; length centred on the line.
- Ellipses: N-S/NE-SW/E-W/NW-SE or major-axis profiles through the centre,
  ending exactly on the drawn outline.
- All or nothing, one undo step; labels off; profiles keep a ProfileLink
  (parent, index, direction, azimuth, station) under the new "profileOf"
  key, so older releases still load the scene.
- Export: Craters (ellipses + profiles) and Lineaments (polylines +
  profiles) presets write <file>.csv and <file>_profiles.csv joined by
  parentKey; profile columns available in every preset; optional surface
  properties in the profiles file; "lines only" type filter.
- Test harness: drawing scenes use PRo3D's 0.1 m near plane instead of the
  AFC template's 10 m, which made annotation lines z-fight.

Docs: docs/SupportingProfiles.md (user guide), docs/dev/SupportingProfiles.md
(spec), export docs. Tests: Section22_SupportingProfiles (Expecto),
supporting-profiles.spec.ts (Playwright on Dimorphos).
- Import re-keys annotations; profile links now follow their parent's new
  key (ViewerApp.rekeyImported), so Craters/Lineaments exports still find
  the profiles of imported craters and lineaments.
- Generating again for a parent replaces its earlier profiles in the same
  undo step instead of adding a second, indistinguishable set.
- At most 1000 profiles per generation, so a typo in the spacing cannot
  freeze the update loop.
- profileOf is read totally: a link from a later version or a damaged one
  drops to None instead of failing the scene load.
- The profiles file is only written for per-annotation CSV, where the
  window shows its checkbox.
- Auto-generation selects its parent explicitly.
- Compass azimuths are stored exactly (0, not 1e-16) and near-north
  bearings snap to 0.
- Tests for all of the above, plus a point clicked twice and a NaN azimuth
  round trip; docs updated.
…t the undo stack (#833)

finishAndAppend/addPoint/finish return the annotation they added; DrawingApp.updateFinishing
passes it on and update = updateFinishing >> fst. The toolbar auto profiles use it directly
instead of reading the head of the undo stack, so undo/redo can never trigger them, and the
pick and Finish paths no longer diff the annotation map to find the new leaf.
@haraldsteinlechner
haraldsteinlechner merged commit 75bd201 into develop Oct 20, 2026
3 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.

Supporting profiles for polylines and ellipses, Craters export

1 participant