ENH: Add new color palettes for IPF Colors based on the Nolze & Hielscher color mapping#44
Open
imikejackson wants to merge 16 commits intoBlueQuartzSoftware:developfrom
Open
Conversation
Header-only utility in ebsdlib::color namespace providing hslToRgb, hslToHsv, and rgbToBytes functions, with Catch2 unit tests covering primary colors, achromatic cases, and round-trip value bounds. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…gies Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… for all 11 Laue groups Implements sector geometry definitions (boundary normals, vertices, barycenter) and normalized polar coordinate computation (radius, azimuth) for all 11 Laue groups. Each sector is defined by half-space boundary normals with factory methods for cubicHigh (m-3m), cubicLow (m-3), hexagonalHigh (6/mmm), hexagonalLow (6/m), tetragonalHigh (4/mmm), tetragonalLow (4/m), trigonalHigh (-3m), trigonalLow (-3), orthorhombic (mmm), monoclinic (2/m), and triclinic (-1). Includes 8 Catch2 unit tests covering vertex geometry, polar coordinates, isInside checks, barycenter validity, and azimuthal correction. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduces TSLColorKey implementing IColorKey with the traditional TSL/HKL IPF color algorithm refactored from LaueOps::computeIPFColor(). Adds unit tests covering corner colors, grid validity, regression values, polymorphic usage, and the default angle limits override. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds NolzeHielscherColorKey that maps crystal directions to RGB colors via the perceptually improved scheme from Nolze & Hielscher (2016). Uses polar coordinates from FundamentalSectorGeometry, maps azimuthal angle to hue, radial distance to lightness via nonlinear function (center=white, boundary=saturated), and derives saturation from lightness. Includes static helpers for hue speed, lightness, and saturation functions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add setColorKey/getColorKey methods to LaueOps and delegate IPF color computation to the configured IColorKey strategy in computeIPFColor(). The default color key is TSLColorKey, preserving full backward compatibility. Integration tests verify default TSL behavior, switching to NolzeHielscher, and backward-compatible IPF color output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…scher color key Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…/m, 4/m, 2/m) Add dual white/black center coloring for "extended" mode Laue groups per Nolze-Hielscher paper Section 2.6. Directions in the supergroup sector get white-center mapping (L: 1.0->0.5), directions outside get black-center mapping (L: 0.0->0.5), meeting continuously at fully saturated boundaries. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds TEST_CASE blocks for ImpossibleMode_Triclinic and ImpossibleMode_TrigonalLow verifying that direction2Color produces valid [0,1] RGB output for the impossible coloring path and that the sector barycenter maps to near-white, consistent with the paper's compromise (a) for -1 and -3 Laue groups. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…legends Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The radius-to-lightness mapping was inverted: center (r=0) was mapping to the equator of the color sphere (fully saturated) instead of the pole (white/gray). Fixed to map center->1.0 (white) and boundary->0.5 (saturated), matching the Nolze-Hielscher paper's intent. Also replaced the paper's simple lightness formula with a gray gradient blending approach that produces a compact white center with rich, saturated colors covering most of the sector area. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two fixes to match the MTEX reference output: 1. Added Gaussian CDF-based hue correction that expands compressed yellow, cyan, and magenta hue regions. Uses three Gaussian bumps at R(0), G(1/3), B(2/3) positions with width parameter 200, precomputed as a CDF lookup table in the constructor. 2. Applied power curve (r^0.35) to the radius before lightness mapping to compress the white center and expand the saturated color region. This brings mean saturation from 0.218 to 0.513 (MTEX reference: 0.521). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements the azimuthal angle correction from the paper (Appendix A.1) that was previously left as an identity mapping. The correction: 1. Samples the boundary distance d(rho) at 1000 angles around the barycenter using the same great-circle intersection algorithm 2. Weights the angular distribution by d(rho) so that directions where the boundary is farther away get more hue space 3. Normalizes within each vertex sector so each vertex gets an equal share of the hue circle (2*pi / nVertices) 4. Builds a cumulative lookup table for fast interpolation This smooths the visible seam lines that appeared where the "nearest boundary" switches between different boundary normals, producing continuous color gradients matching the MTEX reference. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The sharp color transition lines ("gray bands") radiating from the center
were caused by the radius computation producing non-monotonic values
along radial paths. When the "closest boundary" switched between
different boundary normals, the radius would dip, creating visible seams.
Fixed by adopting the orix/MTEX polar coordinate algorithm:
- Uses angle(-v, bp) / angle(-center, bp) instead of
angle(center, h) / angle(center, bp)
- Cross product order: v.cross(center) then gcN.cross(normal)
- Convention: radius=1 at center (white), radius=0 at boundary (saturated)
- This produces monotonically varying radius along any radial path,
eliminating the gray band artifacts
Updated NolzeHielscherColorKey to use the new convention:
- White center: r = 0.5 + radius/2 maps [1,0] -> [1.0, 0.5]
- No power curve needed since the orix formula already distributes
colors well
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements the Decorator pattern: GriddedColorKey wraps any IColorKey with grid-based flat shading. Colors are precomputed at regular angular intervals (default 1 degree, matching MTEX) and looked up via nearest- grid-point snapping. This produces flat-colored patches that hide C1 discontinuities in the underlying color function. Adds LegendRenderMode enum and setLegendRenderMode() convenience method to LaueOps for switching between PerPixel (EbsdLib default) and GridInterpolated (MTEX-style) rendering. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.