Skip to content

WaveFrontReader: handle MTL xyz and spectral colors and 'd -halo' - #324

Open
Joel Kiptoo (Kiptoo-Deus) wants to merge 3 commits into
microsoft:mainfrom
Kiptoo-Deus:wavefront-mtl-xyz-colors
Open

Joel Kiptoo (Kiptoo-Deus) wants to merge 3 commits into
microsoft:mainfrom
Kiptoo-Deus:wavefront-mtl-xyz-colors

Conversation

@Kiptoo-Deus

Copy link
Copy Markdown

Fixes #229.

Besides the missing features, the current MTL reader has a failure mode: the color statements read three floats straight from the stream, so Kd xyz 0.5 0.5 0.5, Kd spectral file.rfl or d -halo 0.8 put InFile into a failed state. The main loop's next InFile >> strCommand then fails, so LoadMTL silently stops reading the rest of the file but still returns S_OK. For xyz, the color is also assigned from the uninitialized r, g, b.

Changes in WaveFrontReader.h:

  • A LoadColor helper for Ka, Kd, Ks and Ke parses the rest of the line (read the same way as LoadTexturePath, ignoring an end-of-line comment):
    • r [g b]: g and b default to r, as in the MTL spec
    • xyz x [y z]: y and z default to x; converted from CIE XYZ to linear sRGB (D65), clamping negative, out-of-gamut values to 0
    • spectral file.rfl [factor]: skipped, leaving the color unchanged, with a debug message
  • d -halo factor uses the factor, since view-dependent dissolve isn't supported.
  • Tf gets its own branch with a debug message saying it isn't supported.

For the XYZ conversion I used the standard sRGB/D65 matrix rather than XMColorXYZToRGB, because that function converts to CIE RGB and doesn't map D65 white to (1, 1, 1). Happy to switch if you'd prefer the DirectXMath function.

Testing: on macOS with clang (using the wsl stubs from DirectX-Headers and sal.h), I called LoadMTL on a file using the forms from the issue:

newmtl first
Ka xyz 0.9505 1.0 1.089
Kd 0.5
Ks 0.1 0.2 0.3
d -halo 0.25
Tf 1 1 1

newmtl second
Kd spectral file.rfl 1.5
Ke 1 0 0
d 0.75

newmtl third
Kd 0.2 0.4 0.6 # trailing comment
Ks xyz 0.5

Before (returns S_OK):

first  Ka=(0.000 -21385026171220000768.000 0.000) Kd=(0.800 0.800 0.800) Ks=(1.000 1.000 1.000) Ke=(0.0 0.0 0.0) emissive=0 alpha=1.00
second Ka=(0.200 0.200 0.200) Kd=(0.800 0.800 0.800) Ks=(1.000 1.000 1.000) Ke=(0.0 0.0 0.0) emissive=0 alpha=1.00
third  Ka=(0.200 0.200 0.200) Kd=(0.800 0.800 0.800) Ks=(1.000 1.000 1.000) Ke=(0.0 0.0 0.0) emissive=0 alpha=1.00

After:

first  Ka=(1.000 1.000 1.000) Kd=(0.500 0.500 0.500) Ks=(0.100 0.200 0.300) Ke=(0.0 0.0 0.0) emissive=0 alpha=0.25
second Ka=(0.200 0.200 0.200) Kd=(0.800 0.800 0.800) Ks=(1.000 1.000 1.000) Ke=(1.0 0.0 0.0) emissive=1 alpha=0.75
third  Ka=(0.200 0.200 0.200) Kd=(0.200 0.400 0.600) Ks=(0.602 0.474 0.454) Ke=(0.0 0.0 0.0) emissive=0 alpha=1.00

A typical Blender-exported MTL (RGB colors, Ns, Ni, Tr, illum, map_Kd, tab-separated values) gives identical results before and after.

I couldn't build the full Load path on macOS: std::wifstream(const wchar_t*) is an MSVC extension that libc++ doesn't have, so the test called LoadMTL directly through a small shim. That's unrelated to this change.

The color statements (Ka, Kd, Ks, Ke) read three floats directly from the
stream, so 'Kd xyz x y z', 'Kd spectral file.rfl' or 'd -halo factor' put
the stream into a failed state. LoadMTL then stopped reading the rest of
the file but still returned S_OK, and for 'xyz' the color was set from
uninitialized values.

Each color statement now parses its own line:
- 'r [g b]', where g and b default to r
- 'xyz x [y z]', converted from CIE XYZ to linear sRGB (D65)
- 'spectral file.rfl [factor]' is skipped (debug message)
'd -halo factor' uses the factor, and 'Tf' reports that it is not
supported in debug builds.

Fixes microsoft#229
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

utility Applies to WaveFrontReader, etc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WaveFrontReader MTL support for xyz color-space values

2 participants