Skip to content

A session reset keeps SectionPlane.custom, the most model-relative field it holds #3365

Description

@louistrue

A session reset clears the section plane's cardinal fields because they are model-relative, and keeps custom, which is more model-relative than any of them.

The inconsistency

The reset spreads the live plane and overwrites four fields:

sectionPlane: {
  ...state.sectionPlane,
  axis:     SECTION_PLANE_DEFAULTS.AXIS,
  position: SECTION_PLANE_DEFAULTS.POSITION,
  enabled:  SECTION_PLANE_DEFAULTS.ENABLED,
  flipped:  SECTION_PLANE_DEFAULTS.FLIPPED,
},

The spread is deliberate and correct: showCap, showOutlines and capStyle round-trip to localStorage and are the user's cut-surface appearance, so they must survive. The four overwrites are there because axis and position are meaningless against a different model.

custom is neither. CustomSectionPlane (store/types.ts) is:

normal:    [number, number, number];  // unit world-space normal
distance:  number;                    // signed offset, dot(pointOnPlane, normal)
pickedAt:  [number, number, number];  // world-space hit point at pick time
tangent:   [number, number, number];
bitangent: [number, number, number];

Every one of those is absolute world-space geometry from the outgoing model. position is a normalised value along an axis; distance and pickedAt are raw coordinates. So the reset drops the relative fields and keeps the absolute ones.

Consequence

Face-pick an arbitrary-normal section plane, then load a different file. custom survives with the old model's normal and offset. sectionSlice.ts:348 shows the codebase already treats a cardinal-axis change as invalidating it (custom: undefined), which is the same judgement applied at a smaller scope.

Scope

Pre-existing. Verified against main before the store-teardown refactor (#3358): the same spread, the same four overwrites, custom equally untouched. The refactor preserves it exactly, which is why this is filed rather than changed there.

Marked unproven: read from the source, not reproduced in a running viewer.

Fix

Add custom: undefined to the four overwrites. Note that #3358's teardown-registry.test.ts pins emitted keys per scope in both directions; sectionPlane is already in the pinned list, so the value change needs no pin update, but the arm's test coverage should assert the field specifically.

How this was found

CodeRabbit, reviewing #3358.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions