Commit Graph
7 Commits
Author SHA1 Message Date
Hakan SevenandClaude Opus 4.8 10e4c18ba7 chore: silence native and wasm build warnings
Gate target-specific code so neither build warns about the other's items:
native-only helpers (view, window icon, file dialogs, file association, plugin
host/guard/registry, self-update) are cfg'd to non-wasm; the wasm-only font
fallback (script_of / cjk_lang / request) is cfg'd to wasm. Drop an unused mut,
allow the few genuinely-conditional dead items (mesh_click_hit, GPU layout
helpers, parity stubs), and gate the embedded PlotSettings-unrelated dead
constants. Both targets now build clean (only the unavoidable nom/quick-xml
future-incompat dependency notice remains).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 02:03:34 +03:00
Hakan SevenandClaude Opus 4.8 7fe7e0230d refactor(scene): group modules into role-based subfolders
Move the 30 flat modules under src/scene/ into six folders by role:
convert (entity→geometry), text (fonts/shaping), model (render models),
pick (hit-test/selection/grips/xclip), view (camera/transform/render),
cache (block + property caches). pipeline/ is unchanged.

Full path migration — all `scene::X` references become
`scene::<group>::X`, no compatibility re-exports. render.rs items that
were `pub(super)` (parent was scene) become `pub(in crate::scene)` to
keep their original scene-wide visibility.

No behavior change; build and tests are green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 11:33:46 +03:00
Hakan SevenandClaude Opus 4.8 09e7e90aae feat(draworder): cross-type draw order + context menu
DRAWORDER now affects rendering immediately (bump geometry epoch so the
sort cache rebuilds) and front/back anchor to the block's full effective
sort range instead of only existing table entries, so bring-to-front
actually lands on top. The render fallback sorts table-absent entities by
their own handle.

Draw order now applies across entity types, not just within a type. A
per-entity draw-order rank (SortEntitiesTable override or own handle,
ranked per block) is encoded as a small signed clip-z bias in the wire,
hatch, image, and 3DFACE pipelines. The shared LessEqual depth buffer then
orders fills, lines, rasters and 2D solids against each other regardless of
pass order — without touching model coordinates. 3D meshes keep real
geometric depth; wipeouts stay always-on-top.

Adds a Draw Order submenu to the viewport context menu (Bring to Front,
Send to Back, Bring Above/Send Under Object). The above/under items run an
interactive reference-object pick, then reorder the captured selection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 21:29:01 +03:00
Hakan SevenandClaude Opus 4.7 798a391207 refactor(pipeline): drop legacy per-hatch path (Phase 4-B, step 5)
The batched hatch pipeline has soaked through visibility + LOD; it's
correct on every file tested (Floor plan.dxf, UTM site plans, the
non-UTM regression case). Time to remove the parallel per-hatch
plumbing that's been sitting empty since step 3:

- `gpu_hatches: Vec<HatchGpu>` — never populated since
  `upload_hatches` switched to the batched builder; dropped.
- `hatch_pixel_scissors`, `hatch_skip_flags` — same story; dropped.
- `compute_hatch_scissors` — no longer has a consumer; dropped, with
  the render-time call removed from `Primitive::prepare`.
- Hatch render pass — the dead `else if` branch over `gpu_hatches`
  is gone; only the single batched `pass.draw(0..vertex_count, 0..1)`
  remains.
- `compute_hatch_lod` — no fallback path; if `gpu_hatch_batched` is
  `None` (empty hatch list) it just returns early.

`HatchGpu` itself stays — the wipeout pipeline still uses it. So do
`hatch_pipeline` / `hatch_bgl1`, kept around for that path.

`#[allow(dead_code)]` on the four storage-buffer fields in
`HatchBatchedGpu` — they exist only to keep the bind group's
referenced resources alive; nothing reads them directly.

Known gap left as a follow-up: per-hatch viewport scissor for paper-
space MSPACE viewports isn't ported to the batched path yet. Hatches
inside a paper-space viewport can render past the viewport border
until that's added. Hasn't surfaced as a visible regression in the
test files so far.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 20:18:06 +03:00
Hakan SevenandClaude Opus 4.7 398eee551d feat(pipeline): per-instance visibility for batched hatches (Phase 4-B, step 4)
Adds a dedicated `visibility: array<u32>` storage buffer (binding 4)
alongside the existing batched hatch buffers. Vertex shader reads
`visibility[v.instance_index]` — 0 → emit an out-of-NDC clip
position so the GPU rasterizer clips the primitive before the
fragment stage runs.

`compute_hatch_lod` now drives this buffer instead of (or alongside,
for the per-hatch fallback) `hatch_skip_flags`. Walks a per-instance
CPU AABB mirror that the builder fills at upload time (`instance_aabbs`),
applies the same `aabb_below_pixel` (sub-pixel LOD) OR `aabb_offscreen`
(frustum cull) rule the legacy path used, and pushes the resulting
0/1 flags via `queue.write_buffer` on a separate 4 B-per-hatch buffer
— ~40 KB per pan tick for 10 k hatches, far cheaper than re-writing
the 112 B-per-instance data.

Step 5 will remove the legacy `gpu_hatches` Vec, the per-hatch draw
loop, and `hatch_skip_flags` once the batched path has soaked.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 20:11:28 +03:00
Hakan SevenandClaude Opus 4.7 cfe53bd789 fix(pipeline): batched-hatch pattern math + invisible-instance clip
Two issues in the step-3 batched path surfaced during testing:

1. WGSL rejects compile-time NaN literals (`0.0 / 0.0`), so the
   visibility-skip path that emitted a NaN clip position failed
   `Device::create_shader_module` validation. Replaced with an
   out-of-frustum clip position `(2, 2, 2, 1)` — the GPU rasterizer
   clips the primitive and the fragment shader never runs.

2. Pattern hatches rendered with the wrong spacing / direction. The
   batched builder was rotating `perp_step` / `along_step` into the
   global frame, but the per-hatch shader (`hatch.wgsl`) expects them
   in QCAD PAT local-frame convention: `perp_step = family.dy`,
   `along_step = family.dx`, with the cos_off/sin_off rotation applied
   inside the shader. Now matches `build_family_batch` from
   `hatch_gpu.rs` line-for-line. `line_width` also reset to 0 (the
   shader picks 1 px from a screen-space derivative; the stored field
   is unused).

3. Padding's `max_spacing` likewise dropped its bogus rotation and
   now uses `|dy|` per family, matching the new perp_step convention.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 20:04:16 +03:00
Hakan SevenandClaude Opus 4.7 fe202f5f8e feat(pipeline): batched-hatch GPU resources + builder (Phase 4-B, step 1)
Stand-alone module — no consumers yet. Packs an entire `&[HatchModel]`
into four storage buffers + a per-vertex (corner, instance_index)
stream:

- `InstanceBuffer`  — `HatchInstance[]` (112 B each): color, mode,
  gradient params, world_origin, local-space aabb, boundary range,
  family range, visibility flag.
- `BoundaryBuffer`  — flat `vec4<f32>[]` (NaN markers preserved as
  per-path separators, just like the per-hatch shader expects).
- `FamilyBuffer`    — flat `LineFamilyGpu[]` (matches the per-hatch
  family layout one-for-one apart from `dash_offset` indexing into a
  separate dash buffer).
- `DashBuffer`      — flat `f32[]`.

The per-vertex buffer holds `6 × instance_count` records of
`(corner: u32, instance_index: u32)`. Step 2 will add the matching
WGSL shader that uses these to project a per-instance AABB quad and
run the in-polygon test against `BoundaryBuffer[offset..offset+count]`.

iced reports 8 storage buffers per stage, 128 MB binding cap, 256 MB
buffer cap — plenty for ~10 k hatches × 112 B + ~32 MB boundaries.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 19:45:26 +03:00