Skip to content

fix: correct hatch draw order and COLORTHEME-aware fill colors#228

Merged
mlightcad merged 1 commit intomainfrom
fix/hatch-draw-order
Apr 22, 2026
Merged

fix: correct hatch draw order and COLORTHEME-aware fill colors#228
mlightcad merged 1 commit intomainfrom
fix/hatch-draw-order

Conversation

@pauloricardoma
Copy link
Copy Markdown
Collaborator

Summary

Fixes a family of rendering bugs around solid hatches resolved to the foreground pseudo-colour (ACI 7):

  1. Draw order — ACI 7 solid hatches covered BYLAYER outlines because all meshes ended up in the same THREE render queue slot with sorting by material id (effectively random). On a tower DWG, interior floor divisions vanished behind white rectangles in light mode and dark rectangles in dark mode.
  2. Theme tracking — solid ACI 7 hatches kept an absolute RGB regardless of the canvas theme, so toggling light/dark left the fills painted in the previous theme's background colour.
  3. Boot-in-dark — hatches created during batchConvert rendered with the default trait RGB on the first frame even when the theme was already flipped, only correcting themselves after a manual re-toggle.

What changes

  • AcTrBatchedGroup — tag hatch / solid-fill meshes with renderOrder = -1 so they draw below linework and text (matches AutoCAD's default SortentsTable ordering). Text glyph meshes go through the same batch path but keep the default tier via material.userData.isTextFill.
  • AcTrFillMaterialManager — new isTextFill option partitions text glyph fills from hatch fills. Text glyphs follow COLORTHEME inversion (stay legible); hatches follow the canvas background (fuse with the paper). Cache keys gain _text / _bgfill suffixes only when applicable, so the common non-ACI-7 path stays bit-identical.
  • AcTrMaterialManager — new shouldTrackForeground / shouldTrackBackground hooks plus a changeBackground(color) method symmetric to the existing changeForeground. Defaults preserve current behaviour; only the fill manager opts materials in.
  • AcTrStyleManager / AcTrStyleManagerOptions / AcTrRenderer — new currentBackgroundColor tracked field. Setter both stores the bg on the style manager options (so materials created later are born with it) and fires changeBackground (so cached materials are repainted). Closes the boot-in-dark edge case.
  • AcTrView2d — react to the COLORTHEME sysvar as well. Previously only WHITEBKCOLOR was bridged, but the Vue-side theme toggle (useDark) only flips COLORTHEME, so flipping the UI theme left the canvas background stale. Both sysvars remain independently settable.
  • AcTrMTextRenderer — route MText glyph fills through the new AcTrStyleManager.getMTextFillMaterial so they land in the isTextFill partition and never share a material instance with a hatch of the same colour + layer.

Performance

Cache fragmentation is opt-in. The _text and _bgfill suffixes only attach when the relevant conditions match, so drawings without ACI 7 hatches or MText produce the exact same cache keys (and therefore the same batch count and draw calls) as before this PR.

Depends on

mlightcad/realdwg-web#59 — preserves the DWG's truecolor when the entity carries both RGB and ACI index, so ACI 254 with a custom palette doesn't fall through to the ACI 7 path. The fix in this PR is correct on its own but only takes full effect once that upstream PR is released and bumped here.

Test plan

  • Open a DWG whose tower / interior layout uses BYLAYER outlines with ACI 7 solid hatches. Interior floor divisions are visible in both light and dark themes (hatches fuse with the paper).
  • Open any DWG with ACI 7 MText over a hatch. Glyphs remain legible against both theme backgrounds.
  • Toggle COLORTHEME via the theme button in the UI. Hatches flip colour with the paper on the same frame; MText and linework flip the opposite way and stay legible.
  • Start the app in dark theme (persisted via useDark) and open a DWG with ACI 7 hatches. First frame renders correctly — no manual re-toggle required.
  • Open a drawing with only linework / points / no hatches. No visual regression; batch count unchanged.

Fixes a family of rendering bugs around solid hatches resolved to the
foreground pseudo-colour (ACI 7). Before: such hatches covered BYLAYER
outlines in light mode (interior subdivisions of a tower DWG vanished
behind white rectangles) and did not react to theme flips at all.

- AcTrBatchedGroup: tag hatch / solid area fill meshes with
  `renderOrder = -1` so they draw below linework and text (matches
  AutoCAD's default SortentsTable ordering). Text glyph meshes go
  through the same batch path but are detected via
  `material.userData.isTextFill` and keep the default tier so they
  stay above lines.

- AcTrFillMaterialManager: partition text glyph fills from
  hatch / solid area fills via a new `isTextFill` option. Text
  glyphs follow COLORTHEME inversion (`shouldTrackForeground`) so
  ACI 7 text stays legible on both themes; hatches follow the canvas
  background (`shouldTrackBackground`) so ACI 7 fills fuse with the
  paper in both themes. The two flags partition the material cache
  via `_text` and `_bgfill` key suffixes — appended only when
  applicable, so the common non-ACI-7 path keeps its keys
  bit-identical and its batches unchanged.

- AcTrMaterialManager: add the `shouldTrackForeground` /
  `shouldTrackBackground` hooks so each primitive type can opt
  materials into either lifecycle independently. Introduce
  `changeBackground(color)` mirroring the existing `changeForeground`
  API. Defaults preserve current behaviour (foreground-aware, no
  background tracking).

- AcTrStyleManager / AcTrStyleManagerOptions / AcTrRenderer:
  promote the canvas background colour to a tracked field
  (`currentBackgroundColor`). Writing it stores the value on the
  style manager options AND fires `changeBackground`, so materials
  created AFTER the flip are born with the correct colour while
  materials already in the cache are repainted. Closes the
  boot-in-dark edge case where ACI 7 hatches rendered solid white
  on the first frame until the user manually toggled the theme.

- AcTrView2d: react to both WHITEBKCOLOR and COLORTHEME sysvars
  (previously only the former was bridged to the canvas). The
  Vue-side theme toggle (`useDark`) only flips COLORTHEME, so
  without this listener the canvas background stayed stale even as
  `changeForeground` fired for MText/lines. Both sysvars remain
  independently settable.

- AcTrMTextRenderer: route MText glyph fills through the new
  `AcTrStyleManager.getMTextFillMaterial` so they are tagged as
  `isTextFill` and land in a separate cache slot from any hatch
  that happens to share colour + layer.
@pauloricardoma pauloricardoma self-assigned this Apr 21, 2026
@pauloricardoma pauloricardoma added the fix A direct fix for a known issue or regression. label Apr 21, 2026
@mlightcad
Copy link
Copy Markdown
Owner

@pauloricardoma The correct way to control draw order is to use SORTENTSTABLE. For now, realdwg-web doesn't parse this object yet. So it is ok to handel it using your changes. Later, we will use SORTENTSTABLE to handle draw order after support parsing SORTENTSTABLE.

https://help.autodesk.com/view/OARX/2024/ENU/?guid=GUID-462F4378-F850-4E89-90F2-3C1880F55779

@mlightcad
Copy link
Copy Markdown
Owner

@pauloricardoma There is one small issue on this change and you can fix it in next PR.

Steps to reproduce it are as follows.

  • Open one drawing
  • Click "theme" button in status bar. The theme is changed to light from dark. The canvas background is changed to white from black.
  • Then click button "switch background color" button in vertical toolbar at the right side of window.

Result:

  • Nothing happen.
  • Click "switch background color" button again. It works again.

Expected Resut:

  • The background color is changed to black from white.

@mlightcad mlightcad merged commit 720afc6 into main Apr 22, 2026
2 checks passed
@mlightcad mlightcad deleted the fix/hatch-draw-order branch April 22, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix A direct fix for a known issue or regression.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants