-
Notifications
You must be signed in to change notification settings - Fork 0
Theme Compat Roadmap
Companion to Fractal-Expansion-Roadmap.md. Tracks work to eliminate broken
Slideshow / Video Slideshow renders caused by incompatible
(theme, fractal-type, zoom) combinations, and to expose intelligent
theme filtering / sorting to the user.
Not all IColorMap themes work with every FractalType or zoom depth.
Today the slideshow filter is zoom only — ColorPalette.GetPaletteNamesForZoom
(Engine/Models/ColorPalettes.cs:669).
The fractal type is ignored, which produces the following failure modes:
-
Orbit-trap themes are wired only into
MandelbrotCalculator. On every other fractal the defaultIColorMap.Map(...)fallback runs, collapsing the image to a flat smooth-count gradient (often a uniform black or one-band render at deep zoom). -
Interior themes (CyclePeriod, AtomDomains, Multiplier, Argument,
FakeDE) need Brent cycle detection — only
MandelbrotCalculatorexposes that. Elsewhere they paint the interior with whatever the default 3-paramMapreturns atiter = maxIter, typically solid black. -
Phong3D / Pbr3D / Lambert / Slope need surface normals. IFS,
LSystem, Attractor, DLA, Apollonian, Flame, Plasma do not supply
nx, ny(they call the 3-param overload). 3D themes look flat or monochromatic on these fractals. - Distance-field themes need calculator-supplied DE. Only the DE fractals (Mandelbulb, Kleinian, Mandelbox, Quaternion*, KIFS, Bicomplex, and the holomorphic 2D set) supply it.
| Path | Calculators | Data supplied |
|---|---|---|
| 3-param only | IFS, LSystem, Attractor, DLA, Apollonian, Flame, Plasma | smooth |
| 5-param (DE normals) | Mandelbulb, Kleinian, Mandelbox, QuaternionJulia, QuaternionMandelbrot, KIFS, Bicomplex, UserBulb, Sandbox, UserEquation, TearDrop | smooth + nx,ny |
| 9-param + orbit + interior | MandelbrotCalculator (+ EscapeTimeCalculator family) | smooth + nx,ny + finalZ + dz/dc + orbit accumulator + interior cycle |
Source: grep of ColorMap.Map( call sites in Engine/Calculators/*.cs.
Single source of truth: a FractalCapabilities flags enum (lives next
to FractalType in Abstractions/Models/Enums.cs) plus a static
FractalCapabilityMap.For(FractalType) lookup. A theme's required
capabilities are derived from its ColorMapFeatures flags + the
IOrbitAwareColorMap / IInteriorAwareColorMap marker interfaces.
Compatibility is a single bitmask test: (required & ~supplied) == 0.
[Flags] public enum FractalCapabilities {
None = 0,
SuppliesNormals = 1 << 0,
SuppliesDE = 1 << 1,
SuppliesOrbit = 1 << 2,
SuppliesInterior = 1 << 3,
SuppliesFinalZ = 1 << 4,
SuppliesDerivative= 1 << 5,
SuppliesHistogram = 1 << 6,
}ColorPalette.GetPaletteNamesFor(FractalType, double zoom) combines
the existing zoom cap with the new compatibility predicate. Slideshow
and Video Slideshow call this instead of GetPaletteNamesForZoom. The
predicate falls back to the unfiltered zoom list if the intersection
goes empty (no zero-pool failure mode).
- Add
FractalCapabilitiesflags enum inAbstractions/Models/Enums.cs. - Add
FractalCapabilityMapstatic class withFor(FractalType)switch covering every value inFractalType. - No call sites yet — pure data.
Files touched: Abstractions/Models/Enums.cs (+ new file possible).
Risk: zero. Pure addition.
-
ColorPalette.IsCompatible(IColorMap, FractalType)— derives required caps from features + interface tags, single bitmask test. -
ColorPalette.GetPaletteNamesFor(FractalType ft, double zoom)— combines zoom cap with compat predicate; falls back toGetPaletteNamesForZoom(zoom)if intersection is empty. - Swap Slideshow.cs:299 and VideoZoom.cs:1616 to call the new helper.
Files touched: Engine/Models/ColorPalettes.cs, Slideshow.cs,
VideoZoom.cs.
Risk: low. Fallback path preserves "never empty pool" invariant.
- Replace immediate-repeat
lastThemeIdxint with a boundedQueue<int>of depthmin(8, pool.Count - 1). - Same for region picks (alternative: keep
regionsUsed[]sweep — its exhaustive policy is already non-repeating). - Bounded retry count (
tries < 24) so an exhausted pool never spins. - Optional
SlideshowSeedinSlideshowSettingsfor repeatable demos.
Files touched: Slideshow.cs, VideoZoom.cs,
Engine/Models/SlideshowSettings.cs (optional seed).
Risk: low. O(1) bounded retries, no allocations per pick.
- Add
ByFractalCompatvalue to Views/Controls.cs ColorComboSortMode:190. - Add
FractalType CompatFor { get; set; }onColorComboSortState. - Context menu item "Compatible with current fractal" toggling the
mode; updates
CompatForfrom the active fractal type. - (Optional) Default mode still shows everything but visually demotes (italic / dim suffix) names that are incompatible — non-blocking.
Files touched: Views/Controls.cs plus the Avalonia equivalent
(UI.Avalonia/Views/) once located.
Risk: low. Pure UI; no calculator changes.
- Wire orbit accumulator (
OrbitAccumulator) into the scalar iteration loops ofSandboxCalculator(Engine/Calculators/SandboxCalculator.cs) andUserEquationCalculator(Engine/Calculators/UserEquationCalculator.cs). - Dispatch to
IOrbitAwareColorMap.MapWithOrbitat escape (mirrorMandelbrotCalculator's orbit path). - Bump
FractalCapabilityMap.For(...)entries forSandboxandUserEquationto includeSuppliesOrbit. - UserBulb is out of scope — 3D ray-march doesn't expose a per-iteration z that's meaningful at the surface level.
Files touched: SandboxCalculator.cs, UserEquationCalculator.cs,
Abstractions/Models/Enums.cs (capability map).
Risk: medium. Extra per-iteration call cost — gate on
ColorMap is IOrbitAwareColorMap so non-orbit themes pay nothing.
- Add
List<string>? CuratedThemesfield onFractalRegion(Engine/Models/FractalRegion.cs). - Slideshow uses curated pool first; falls back to compat-filtered; falls back to unfiltered. Three-tier chain, never empty.
- JSON ships with
JsonIgnoreCondition.WhenWritingNullso legacy regions stay clean.
Files touched: FractalRegion.cs, Slideshow.cs, VideoZoom.cs.
Risk: low. Optional field, fully back-compatible.
- Slideshow no longer renders a flat / solid-color frame because the random theme was incompatible with the active fractal type.
- Right-click on the Color Theme combo offers a "Compatible with current fractal" option that hides themes which would render flat.
- Theme repetition window inside a single slideshow session is at least 8 picks deep (configurable via depth constant).
- Sandbox and UserEquation fractals support orbit-trap themes after P5 lands.
- No new dialog / no new delay introduced anywhere in the slideshow hot path.
- Theme metadata: Engine/Interefaces/IColorMap.cs
- Theme registry: Engine/Models/ColorPalettes.cs
- Existing recommender (Sandbox/UserEquation only): Engine/Models/ThemeRecommender.cs
- Combo build: Views/Controls.cs
- Slideshow loop: Slideshow.cs
- Video Slideshow loop: VideoZoom.cs
- Fractal type enum: Abstractions/Models/Enums.cs