Skip to content

ClipEdges.dispose() destroys SHARED style materials when Clipper.localClippingPlanes is false (the default) — one disposed clip breaks all others #785

Description

@stokuewe

Versions

@thatopen/components-front 3.4.4 with @thatopen/components 3.4.8 (verified against the published dists).

What happens

ClipEdges.getStyleMeshes() clones the style materials ONLY in local-clipping mode:

const local = this._components.get(Clipper).localClippingPlanes,
      line  = local && lineMat ? lineMat.clone() : lineMat,
      fill  = local && fillMat ? fillMat.clone() : fillMat;

With the default Clipper.localClippingPlanes = false, the meshes mount the original materials from ClipStyler.styles. ClipEdges.dispose() then runs:

this._components.get(Disposer).destroy(this.three, true, true);

and Disposer.destroy recursively calls .dispose() on every child's material.

Consequence

Disposing ONE ClipEdges instance disposes the line and fill materials that every OTHER ClipEdges sharing the same style still uses — their sections render broken from that moment on. Any app that creates and removes styled section planes at runtime with a shared style hits this on the first removal.

Repro (library only)

  1. const style = clipStyler.styles.create("s", { lineMaterial, fillMaterial }) (shared style).
  2. Create two styled clips from two planes with that style.
  3. Dispose one of them.
  4. The remaining clip's edges/fill render with disposed materials.

Suggested fix

Clone the materials per ClipEdges regardless of clipping mode, or skip material disposal for style-owned materials in dispose().

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