Skip to content

The annotation overlay channel can carry only grid geometry, and then it reframes the camera #3359

Description

@louistrue

CHANNEL_EXPANDS_MODEL_BOUNDS in packages/renderer/src/renderer-overlays.ts decides whether a 3D line overlay grows the scene AABB, keyed by channel. But the content reaching a channel does not follow the channel name: the annotation channel can receive a buffer holding only IfcGrid geometry, and then it reframes the camera on grid axes, which is exactly what grid: false exists to prevent.

The failing case

apps/viewer/src/components/viewer/Viewport.tsx calls:

useSymbolicAnnotations({ enabled: ifcAnnotationsVisible, gridEnabled: ifcGridVisible, ... })

and apps/viewer/src/hooks/useSymbolicAnnotations.ts appends the grid buckets into the same verts array it returns for the annotation channel.

So with "Show IFC Annotations" off and the IfcGrid toggle on, the array delivered to setLineOverlay('annotation', ...) contains only grid lines. CHANNEL_EXPANDS_MODEL_BOUNDS.annotation is true, so expandModelBoundsWithFlatVertices and syncCameraSceneBounds run, and the camera reframes on the grid.

Grid axes routinely extend well past the model envelope. That is the documented reason grid: false exists (#967), and the same reason applies to the DXF reference layer (#2043).

Why the table cannot see it

The policy is keyed by channel; the real rule is about content — does this geometry define the model's extent, such that a file containing only it must still be framable. Those coincide for three of the four channels and diverge for annotation, because one hook multiplexes two content kinds into it.

Marked unproven: this is read off the source, not observed in a running viewer. Reproducing it means loading a file with IfcGrid axes extending past the products, turning annotations off and the grid on, and watching Home / fit-to-view.

Two possible fixes

  1. Route the symbolic grid lift into the grid channel, so a channel name means one content kind. That changes which section-clip and visibility semantics apply to those lines, so it is not a rename.
  2. Key the policy by content contribution rather than by channel, so a buffer declares whether it defines extent.

The second is the deeper fix and the more expensive one.

Also worth recording

The boolean is expand-only. Clearing an expanding channel never shrinks the bounds back, so toggling annotations on grows them for the rest of the session. A Record<channel, boolean> cannot express that; per-channel extent contributions recomputed on set and clear could.

How this was found

During review of the line-overlay channel collapse. The code comment in renderer-overlays.ts names this gap and defers it; filing so it does not stay deferred by default. No code change has been made for it.

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