Skip to content

REL: Version 3.1.0#51

Merged
imikejackson merged 21 commits into
BlueQuartzSoftware:developfrom
imikejackson:release/3.1
Jun 30, 2026
Merged

REL: Version 3.1.0#51
imikejackson merged 21 commits into
BlueQuartzSoftware:developfrom
imikejackson:release/3.1

Conversation

@imikejackson

Copy link
Copy Markdown
Collaborator

Release Notes — EbsdLib 3.1.0

EbsdLib 3.1 is the "discrete pole figures + TSL-by-default" release. It builds
on the 3.0 MTEX-correctness work with a new vector-marker pole-figure renderer
and a switch of the public default hexagonal/trigonal basis back to X‖a
(TSL/EDAX). The two themes:

  1. Discrete (vector-marker) pole figures. A new renderer draws each pole as
    a crisp, decimated vector marker instead of rasterizing it as pixels —
    sharper figures, controllable marker size, and a hard cap on overdraw for
    million-pole datasets.
  2. X‖a (TSL) is the default convention again. 3.0 shipped X‖a* (MTEX) as
    the public default; 3.1 returns the default to X‖a to match legacy DREAM3D
    and the rest of EbsdLib. The internal canonical tables are unchanged
    (X‖a*); only the default the public APIs/structs select changed.

Detailed API reference: v3_api_reference.md.

Breaking changes

Default hexagonal/trigonal convention is now X‖a (TSL)

The default value of HexConvention flipped from XParallelAStar (3.0) to
XParallelA (3.1) in every public surface that selects it:

  • LaueOps::generateIPFTriangleLegend(...) — the conv parameter, which was
    required in 3.0, now defaults to ebsdlib::HexConvention::XParallelA.
  • PoleFigureConfiguration_t::hexConvention — now defaults to XParallelA.
  • CompositePoleFigureConfiguration_t::hexConvention — now defaults to XParallelA.

Effect: hexagonal/trigonal pole-figure positions and legend/family labels
render in the TSL basis by default. IPF colors are unaffected (convention-
invariant). Callers that want the 3.0 behavior must now pass
HexConvention::XParallelAStar explicitly (e.g. to compare side-by-side with
MTEX). Cubic / tetragonal / orthorhombic / monoclinic / triclinic are unaffected.

Pole-figure family labels: brace notation, convention-independent

getDefaultPoleFigureNames() now returns plane-family brace notation
{0001}, {10-10}, {11-20}, {001}, {011}, {111}, etc. — for every
Laue class, and the labels are identical under both conventions. The 3.0
behavior of switching the hexagonal a-family label (<10-10><2-1-10>) with
the convention is removed; both conventions now report {11-20} for that family
(the family identity is convention-independent; only the on-figure dot positions
rotate by 30°). Downstream code that parsed the old angle-bracket strings, or
that relied on the per-convention label switch, must update.

Rendered-figure differences

Pole figures now render +Y-up by default (flipFinalImage), and discrete
figures use the vector-marker renderer rather than per-pixel stamping. Output is
not byte-identical to 3.0. Any pixel-level exemplars pinned against 3.0 pole
figures must be regenerated.

New features

Discrete vector-marker pole figure renderer

  • DiscretePoleFigureCompositor renders discrete pole figures by stamping
    opaque marker sprites, with a MarkerOccupancyGrid that decimates
    overlapping markers (bounded overdraw for >1M-pole inputs).
  • ebsdlib::GeneratePoleFigureComposite(config) is the dispatch entry point:
    it routes discrete && !discreteHeatMap figures to the vector-marker
    renderer and everything else to the raster PoleFigureCompositor. Prefer
    this over calling a compositor directly.
  • CompositePoleFigureConfiguration_t gained a DiscreteMarkerStyle
    (markerStyle.radiusFraction) to control marker size.
  • StereographicProjectUpperHemisphere(...) projection helper.
  • Shared title / axis / info-block chrome extracted into a reusable
    PoleFigureChrome module.

IPF legends annotate their convention

Hexagonal and trigonal IPF triangle legends now print a small
Convention: X||a (TSL) (or X||a* (MTEX/Oxford)) sub-line under the title,
so a legend is self-documenting. Non-hex/trig classes are unchanged.

Apps that changed

App Status
generate_ipf_legends defaults to X‖a; prints the absolute output directory at start/finish; regenerates the per-class legend + pole-figure matrix as PNG
render_ebsd --convention now defaults to x_a (TSL)

Validation evidence

  • Strict IPF-color corners. LaueOpsTest::IPFColor_SSTCorners asserts the
    standard-stereographic-triangle corners render as pure primaries for every
    Laue class: apex ([0001]/[001]) = red, η-min edge = green, η-max edge =
    blue (exact primaries for cubic and hex 6/mmm; dominant-channel just inside the
    edge for the wider-wedge classes, which sit on a fold boundary).
  • Discrete-render performance guard. A hidden test renders a >1M-pole
    discrete figure to bound decimation cost.
  • MTEX positions still validated. PoleFigurePositionTest continues to pass
    against the MTEX golden (X‖a*). PoleFigureLaueComparisonTest now routes
    through GeneratePoleFigureComposite (vector markers) and pins X‖a* locally
    to stay aligned with its MTEX comparison script.

imikejackson and others added 21 commits June 23, 2026 18:30
Now use A1, A2, A3 for axis labels and get away from the arbitrary RD, TD, ND
…cimation

Wires together LaueOps crystallography, StereographicProjectUpperHemisphere,
RenderDiscreteMarkerSprite, MarkerOccupancyGrid, and shared chrome free
functions into DiscretePoleFigureCompositor::generateCompositeImage. Adds
smoke (ProducesImage) and determinism (IsDeterministic) tests; all 3
DiscretePoleFigureCompositorTest cases pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…FigureComposite

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The v3 archive reflects the new discrete vector rendering plus current axis
label positions. NOTE: Pole_Figure_Images_v3.tar.gz must be uploaded to the
EbsdLib test-data archive before CI / fresh clones can download it; the data
is already present locally for verification.
* The marker Y mapping in DiscretePoleFigureCompositor hardcoded +Y-up
  regardless of config.flipFinalImage, while DrawPoleFigureFrame places
  the A2 label based on that flag — causing label/marker mismatch when
  flipFinalImage=false.
* Gate the cy formula on flipFinalImage: true keeps the existing +Y-up
  (subtracted dy), false uses +Y-down (added dy), matching the raster
  path's conditional vertical flip.
* Add HonorsFlipFinalImage test that compares the figure-1 pixel box
  between flip=true and flip=false, requiring boxDiffs > 0 to confirm
  markers are vertically mirrored by the flag.

Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
  * getDefaultPoleFigureNames now returns plane-family brace notation
    ({001}, {10-10}, {11-20}, ...) for every Laue class. Hexagonal high/low
    no longer switch the a-family label by convention: the family identity
    is convention-independent, so both X||a and X||a* report {11-20}.
  * Default HexConvention is now XParallelA (TSL/EDAX) across the library:
    the generateIPFTriangleLegend API, PoleFigureConfiguration_t, and
    CompositePoleFigureConfiguration_t. IPF colors are convention-invariant;
    only the corner/pole labels and hex/trig pole positions follow the basis.
  * Annotate hex/trig IPF legends with a small "Convention: X||a (TSL)"
    sub-line under the title (centralized in annotateIPFImage); cubic and the
    other non-hex classes are unaffected.
  * PoleFigureChrome renders {hkil} family labels as parenthesized titles.
  * generate_ipf_legends and render_ebsd default to X||a and print their
    output directory; regenerate the shipped IPF legends as PNG (replacing
    the legacy TIFF assets).
  * Route PoleFigureLaueComparisonTest through GeneratePoleFigureComposite so
    discrete figures use the vector-marker renderer; it pins X||a* locally to
    stay aligned with the MTEX comparison script.
  * Add LaueOpsTest::IPFColor_SSTCorners asserting SST-corner primaries
    (red apex, green eta-min edge, blue eta-max edge) for all Laue classes,
    and update the family-label assertions.
  * Sync the MTEX pole-figure golden CSV and generator script family labels
    to brace notation.

  Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
  * Update v3_api_reference.md to v3.1.0: document the discrete vector-marker
    renderer (GeneratePoleFigureComposite dispatch, DiscretePoleFigureCompositor,
    DiscreteMarkerStyle, StereographicProjectUpperHemisphere, PoleFigureChrome)
    and correct the now-stale v3.0 statements (conv base-virtual default,
    convention-independent brace labels, struct-default flip to X||a).
  * Default InversePoleFigureConfiguration_t::hexConvention to X||a for
    consistency with the pole-figure config structs; IPF colors are
    convention-invariant so this affects only the SST label annotation.
  * Pin compare_pole_figures_all_laue.m to X||a* explicitly so the MTEX
    side-by-side stays apples-to-apples with PoleFigureLaueComparisonTest.
  * Note InversePoleFigureConfiguration_t in the Index.md migration list.

  Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
@imikejackson imikejackson merged commit 21adef1 into BlueQuartzSoftware:develop Jun 30, 2026
6 checks passed
@imikejackson imikejackson deleted the release/3.1 branch June 30, 2026 21:19
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.

1 participant