bug: 3D Gamut Visualization Fails to Render Mesh and Profcheck Metric Cards Display 0.00 (#179) #179

Closed
opened 2026-09-02 01:06:37 +01:00 by gronod · 1 comment
Owner

Detailed Analysis of Generated Pipeline Files (c:\temp\argyllfiles)

Review of the complete workflow output files in c:\temp\argyllfiles (xp_55_koala_satin.gam, xp_55_koala_satin.icm, xp_55_koala_satin.ti1, xp_55_koala_satin.ti2, xp_55_koala_satin.ti3, xp_55_koala_satin.tif) confirms the exact structure generated by the ArgyllCMS pipeline and reveals the precise mechanisms failing in Stage 5:


Key Technical Findings from xp_55_koala_satin.gam

  1. Exact .gam File Specification:
    xp_55_koala_satin.gam (43.6 KB) contains two structured data sets created by iccgamut -v -d 10:

    • Gamut Header Metadata:
      • COLOR_REP "LAB"
      • GAMUT_CENTER "50.0 0.0 0.0"
      • CSPACE_WHITE "93.59 1.94 -7.63", CSPACE_BLACK "3.82 1.29 -4.22"
      • Primary Cusp Coordinates: CUSP_RED, CUSP_YELLOW, CUSP_GREEN, CUSP_CYAN, CUSP_BLUE, CUSP_MAGENTA
    • Vertex Table (NUMBER_OF_SETS 739):
      NUMBER_OF_FIELDS 4
      BEGIN_DATA_FORMAT
      VERTEX_NO LAB_L LAB_A LAB_B 
      END_DATA_FORMAT
      BEGIN_DATA
      0 88.37509 -1.934604 107.3089
      ...
      738 15.95737 -6.058368 -9.006460
      END_DATA
      
    • Triangle Face Table (NUMBER_OF_SETS 1474):
      NUMBER_OF_FIELDS 3
      BEGIN_DATA_FORMAT
      VERTEX_0 VERTEX_1 VERTEX_2 
      END_DATA_FORMAT
      BEGIN_DATA
      36 22 38
      36 38 45
      ...
      END_DATA
      
  2. Why 3D Gamut Visualization Shows Empty Scene:

    • src/js/gamut_viewer.js currently uses parseCGATS(text) which:
      1. Only parses the first BEGIN_DATA block up to END_DATA.
      2. Discards the second BEGIN_DATA block (the 1,474 triangle surface faces).
      3. Produces objects shaped as { L, a, b }.
      4. Passes { L, a, b } into computeQuickHull(points).
    • src/js/vendor/quickhull.js strictly indexes p.x, p.y, p.z. Because p.x is undefined, computeQuickHull evaluates minX === maxX (0 === 0) as true and returns [] (empty array).
    • As a result, no geometry is built for either the generated profile gamut (xp_55_koala_satin.gam) or the standard reference gamut (assets/sRGB.gam).
  3. Why Profcheck Quality Report Shows 0.00:

    • The actual stdout from profcheck on xp_55_koala_satin is:
      Profile check complete, errors(CIEDE2000): max. = 1.284622, avg. = 0.223759, RMS = 0.277903
    • src/js/profcheck.js:136-138 regex expects avg.\s*dE\s*= (requiring the literal "dE" string), which fails to match and leaves metrics at 0.00.

Detailed Actionable Targets

Target 1: Full Native Argyll .gam Surface Mesh Parser (src/js/gamut_viewer.js)

  • Implement parseGamutFile(gamText) to parse both tables from .gam files:
    1. Vertices: Extract [id, L, a, b], mapping to 3D Three.js coordinate space:
      • x = a* (Green <-> Red axis, range ~ -128..+127)
      • y = L* (Lightness axis, range 0..100)
      • z = b* (Blue <-> Yellow axis, range ~ -128..+127)
    2. Face Indices: Extract [v0, v1, v2] triangle indices from the second BEGIN_DATA block.
  • Construct a THREE.BufferGeometry using:
    • geometry.setAttribute('position', new THREE.BufferAttribute(vertexFloat32Array, 3))
    • geometry.setIndex(new THREE.BufferAttribute(indicesUint32Array, 1))
    • geometry.computeVertexNormals()
  • Render the generated profile gamut with semi-transparent Lambertian shading (opacity: 0.75, color: 0x3b82f6) alongside the wireframe reference assets/sRGB.gam.

Target 2: Fix computeQuickHull Fallback for Raw Point Clouds

  • For point cloud inputs (such as .ti3 measurement files without precomputed .gam), ensure points are transformed to { x: a, y: L, z: b } prior to invoking computeQuickHull.

Target 3: Profcheck Stdout Regex Normalization (src/js/profcheck.js)

  • Update regex matching to support both standard Argyll output and fallback formats:
    • avgDe: stdout.match(/(?:avg\.|average)\s*(?:dE\s*)?[:=]\s*([\d\.]+)/i)
    • maxDe: stdout.match(/(?:max\.|peak)\s*(?:dE\s*)?[:=]\s*([\d\.]+)/i)
    • rmsDe: stdout.match(/(?:rms\.|rms)\s*(?:dE\s*)?[:=]\s*([\d\.]+)/i)
  • Verify metric cards render: Average ΔE₀₀: 0.22, Peak ΔE₀₀: 1.28, RMS ΔE₀₀: 0.28.
### Detailed Analysis of Generated Pipeline Files (`c:\temp\argyllfiles`) Review of the complete workflow output files in `c:\temp\argyllfiles` (`xp_55_koala_satin.gam`, `xp_55_koala_satin.icm`, `xp_55_koala_satin.ti1`, `xp_55_koala_satin.ti2`, `xp_55_koala_satin.ti3`, `xp_55_koala_satin.tif`) confirms the exact structure generated by the ArgyllCMS pipeline and reveals the precise mechanisms failing in Stage 5: --- ### Key Technical Findings from `xp_55_koala_satin.gam` 1. **Exact `.gam` File Specification**: `xp_55_koala_satin.gam` (43.6 KB) contains two structured data sets created by `iccgamut -v -d 10`: * **Gamut Header Metadata**: - `COLOR_REP "LAB"` - `GAMUT_CENTER "50.0 0.0 0.0"` - `CSPACE_WHITE "93.59 1.94 -7.63"`, `CSPACE_BLACK "3.82 1.29 -4.22"` - Primary Cusp Coordinates: `CUSP_RED`, `CUSP_YELLOW`, `CUSP_GREEN`, `CUSP_CYAN`, `CUSP_BLUE`, `CUSP_MAGENTA` * **Vertex Table (`NUMBER_OF_SETS 739`)**: ``` NUMBER_OF_FIELDS 4 BEGIN_DATA_FORMAT VERTEX_NO LAB_L LAB_A LAB_B END_DATA_FORMAT BEGIN_DATA 0 88.37509 -1.934604 107.3089 ... 738 15.95737 -6.058368 -9.006460 END_DATA ``` * **Triangle Face Table (`NUMBER_OF_SETS 1474`)**: ``` NUMBER_OF_FIELDS 3 BEGIN_DATA_FORMAT VERTEX_0 VERTEX_1 VERTEX_2 END_DATA_FORMAT BEGIN_DATA 36 22 38 36 38 45 ... END_DATA ``` 2. **Why 3D Gamut Visualization Shows Empty Scene**: * [`src/js/gamut_viewer.js`](file:///z:/ICCery/src/js/gamut_viewer.js) currently uses `parseCGATS(text)` which: 1. Only parses the first `BEGIN_DATA` block up to `END_DATA`. 2. Discards the second `BEGIN_DATA` block (the 1,474 triangle surface faces). 3. Produces objects shaped as `{ L, a, b }`. 4. Passes `{ L, a, b }` into `computeQuickHull(points)`. * [`src/js/vendor/quickhull.js`](file:///z:/ICCery/src/js/vendor/quickhull.js) strictly indexes `p.x`, `p.y`, `p.z`. Because `p.x` is `undefined`, `computeQuickHull` evaluates `minX === maxX (0 === 0)` as `true` and returns `[]` (empty array). * As a result, **no geometry is built** for either the generated profile gamut (`xp_55_koala_satin.gam`) or the standard reference gamut (`assets/sRGB.gam`). 3. **Why Profcheck Quality Report Shows `0.00`**: * The actual stdout from `profcheck` on `xp_55_koala_satin` is: `Profile check complete, errors(CIEDE2000): max. = 1.284622, avg. = 0.223759, RMS = 0.277903` * [`src/js/profcheck.js:136-138`](file:///z:/ICCery/src/js/profcheck.js#L136-L138) regex expects `avg.\s*dE\s*=` (requiring the literal `"dE"` string), which fails to match and leaves metrics at `0.00`. --- ### Detailed Actionable Targets #### Target 1: Full Native Argyll `.gam` Surface Mesh Parser (`src/js/gamut_viewer.js`) * [ ] Implement `parseGamutFile(gamText)` to parse both tables from `.gam` files: 1. **Vertices**: Extract `[id, L, a, b]`, mapping to 3D Three.js coordinate space: - `x = a*` (Green <-> Red axis, range ~ -128..+127) - `y = L*` (Lightness axis, range 0..100) - `z = b*` (Blue <-> Yellow axis, range ~ -128..+127) 2. **Face Indices**: Extract `[v0, v1, v2]` triangle indices from the second `BEGIN_DATA` block. * [ ] Construct a `THREE.BufferGeometry` using: - `geometry.setAttribute('position', new THREE.BufferAttribute(vertexFloat32Array, 3))` - `geometry.setIndex(new THREE.BufferAttribute(indicesUint32Array, 1))` - `geometry.computeVertexNormals()` * [ ] Render the generated profile gamut with semi-transparent Lambertian shading (`opacity: 0.75, color: 0x3b82f6`) alongside the wireframe reference `assets/sRGB.gam`. #### Target 2: Fix `computeQuickHull` Fallback for Raw Point Clouds * [ ] For point cloud inputs (such as `.ti3` measurement files without precomputed `.gam`), ensure points are transformed to `{ x: a, y: L, z: b }` prior to invoking `computeQuickHull`. #### Target 3: Profcheck Stdout Regex Normalization (`src/js/profcheck.js`) * [ ] Update regex matching to support both standard Argyll output and fallback formats: - `avgDe`: `stdout.match(/(?:avg\.|average)\s*(?:dE\s*)?[:=]\s*([\d\.]+)/i)` - `maxDe`: `stdout.match(/(?:max\.|peak)\s*(?:dE\s*)?[:=]\s*([\d\.]+)/i)` - `rmsDe`: `stdout.match(/(?:rms\.|rms)\s*(?:dE\s*)?[:=]\s*([\d\.]+)/i)` * [ ] Verify metric cards render: **Average ΔE₀₀: 0.22**, **Peak ΔE₀₀: 1.28**, **RMS ΔE₀₀: 0.28**.
gronod changed title from bug : 3d gamut visualisation does not show the actual gamut to bug: 3D Gamut Visualization Fails to Render Mesh and Profcheck Metric Cards Display 0.00 (#179) 2026-09-02 01:08:18 +01:00
gronod added the Kind/Bug
Priority
High
2
Reviewed
Confirmed
1
labels 2026-09-02 01:08:20 +01:00
gronod added this to the Milestone 13 : Polish milestone 2026-09-03 22:55:49 +01:00
Author
Owner

Fixed in fix/179-gamut-profcheck (stacked on enh/185-gamut-viewer):

  • Hardened parseGamutFile to support multiple BEGIN_DATA blocks, inline # comments, out-of-bounds vertex warnings, and user-visible parser warnings.
  • Hardened profcheck.js report parsing to prefer the last valid JSON summary and fall back to an expanded set of regex patterns for legacy plain-text output.
  • Added parser warnings to the process log when metrics cannot be detected.
  • Fixed loadGamutMesh call signature and wrapped the gamut load in try/catch.

Closes #179.

Fixed in `fix/179-gamut-profcheck` (stacked on `enh/185-gamut-viewer`): - Hardened `parseGamutFile` to support multiple `BEGIN_DATA` blocks, inline `#` comments, out-of-bounds vertex warnings, and user-visible parser warnings. - Hardened `profcheck.js` report parsing to prefer the last valid JSON summary and fall back to an expanded set of regex patterns for legacy plain-text output. - Added parser warnings to the process log when metrics cannot be detected. - Fixed `loadGamutMesh` call signature and wrapped the gamut load in `try/catch`. Closes #179.
Sign in to join this conversation.