Skip to content

feat: add LOD selection UI to PLATEAU building picker sidebar#202

Open
Soynyuu wants to merge 2 commits intofeature/199-lod-selection-apifrom
feature/201-lod-selection-ui
Open

feat: add LOD selection UI to PLATEAU building picker sidebar#202
Soynyuu wants to merge 2 commits intofeature/199-lod-selection-apifrom
feature/201-lod-selection-ui

Conversation

@Soynyuu
Copy link
Owner

@Soynyuu Soynyuu commented Mar 5, 2026

Summary

  • Add a segmented button control (自動/かんたん/標準/詳細) to the PLATEAU building picker Sidebar that lets users choose the conversion LOD for papercraft models
  • Wire the selected LOD through the full frontend stack: UI state → picker result → service layer → API request body
  • Revert unnecessary AGENTS.md reformatting from PR feat: Add LOD selection parameter to CityGML/PLATEAU API endpoints #200

Background

Lower LOD = simpler geometry = easier papercraft assembly. This UI completes the feature started in PR #200, which added backend target_lod parameter support.

Button LOD Description
自動 null (auto) Backend uses LOD3→LOD2→LOD1 fallback (default, backward-compatible)
かんたん LOD1 Simplest geometry, easiest papercraft
標準 LOD2 Standard detail
詳細 LOD3 Full detail, most complex papercraft

Changes

New files

  • LodSelector.tsx — Segmented button component with LodLevel type
  • LodSelector.module.css — Styled with CSS variables and color-mix() to match Paper-CAD design system

Modified files

  • Sidebar.tsx — Integrate LodSelector in footer (conditionally shown when buildings are selected)
  • PlateauCesiumPickerReact.tsx — Manage selectedLod state, pass to Sidebar, include targetLod in import/unfold callbacks
  • plateauCesiumPickerDialog.ts — Add targetLod to PlateauCesiumPickerResult interface
  • citygmlService.ts — Add lod parameter to API request bodies
  • importPlateauBuilding.ts — Extract and pass targetLod to service calls
  • AGENTS.md — Reverted to pre-PR#200 state

Test results

  • TypeScript: npx tsc --noEmit0 errors
  • Jest: 26 suites, 115 tests all passing
  • Pre-commit hooks (Prettier): clean

Stacking

This PR is stacked on PR #200 (feature/199-lod-selection-api). Merge #200 first; this PR will auto-retarget to main.

Closes #201

Add a segmented button control (自動/かんたん/標準/詳細) to the Sidebar
footer that lets users choose the conversion LOD (assembly difficulty)
for papercraft models. Lower LOD = simpler geometry = easier papercraft.

New components:
- LodSelector.tsx: segmented button with 4 LOD options
- LodSelector.module.css: styled to match Paper-CAD design system

Modified:
- Sidebar.tsx: integrate LodSelector, new props for LOD state
- PlateauCesiumPickerReact.tsx: manage selectedLod state, pass to Sidebar
  and include targetLod in import/unfold callbacks
- plateauCesiumPickerDialog.ts: add targetLod to PlateauCesiumPickerResult
- citygmlService.ts: add lod parameter to API request bodies
- importPlateauBuilding.ts: extract and pass targetLod to service calls

Also reverts unnecessary AGENTS.md reformatting from PR #200.

Closes #201
Copilot AI review requested due to automatic review settings March 5, 2026 14:06
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Level of Detail (LOD) segmented selector to the PLATEAU building picker sidebar and threads the chosen LOD through the picker result and frontend service calls so the backend can generate simpler/more detailed papercraft geometry.

Changes:

  • Add LodSelector UI (自動/かんたん/標準/詳細) and integrate it into the Sidebar when buildings are selected
  • Propagate selected LOD through PlateauCesiumPickerReact → dialog result → ImportPlateauBuildingCityGMLService request bodies (lod)
  • Update AGENTS.md formatting/content (per PR description: revert prior reformatting)

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
frontend/packages/chili/src/commands/importPlateauBuilding.ts Pass lod option through import/unfold flows based on picker result
frontend/packages/chili-ui/src/react/components/Sidebar.tsx Add LodSelector to sidebar footer and new props for LOD state
frontend/packages/chili-ui/src/react/components/PlateauSearchLoading.tsx Minor formatting-only change
frontend/packages/chili-ui/src/react/components/LodSelector.tsx New segmented button component and LodLevel type
frontend/packages/chili-ui/src/react/components/LodSelector.module.css Styling for segmented LOD control
frontend/packages/chili-ui/src/react/PlateauCesiumPickerReact.tsx Manage selectedLod state and include it in dialog close payload
frontend/packages/chili-ui/src/plateauCesiumPickerDialog.ts Extend picker result to include targetLod
frontend/packages/chili-core/src/services/citygmlService.ts Add lod option and include it in PLATEAU request bodies
AGENTS.md Update repository guidelines formatting/content

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 25 to +28
export interface PlateauCesiumPickerResult {
selectedBuildings: PickedBuilding[];
action?: "import" | "unfoldBeta";
targetLod?: string | null; // "LOD1" | "LOD2" | "LOD3" | null (auto fallback)
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

targetLod is typed as string | null, which allows arbitrary strings to flow into ImportPlateauBuildingCityGMLService and reach the backend. Since the backend only accepts LOD1/LOD2/LOD3 (or omitted for auto), please narrow this to a union type (e.g. "LOD1" | "LOD2" | "LOD3" | null) or a shared LodLevel type alias to preserve end-to-end type safety.

Suggested change
export interface PlateauCesiumPickerResult {
selectedBuildings: PickedBuilding[];
action?: "import" | "unfoldBeta";
targetLod?: string | null; // "LOD1" | "LOD2" | "LOD3" | null (auto fallback)
export type LodLevel = "LOD1" | "LOD2" | "LOD3";
export interface PlateauCesiumPickerResult {
selectedBuildings: PickedBuilding[];
action?: "import" | "unfoldBeta";
targetLod?: LodLevel | null; // "LOD1" | "LOD2" | "LOD3" | null (auto fallback)

Copilot uses AI. Check for mistakes.
export interface PlateauBuildingIdWithMeshSearchOptions {
debug?: boolean;
mergeBuildingParts?: boolean;
lod?: string | null; // "LOD1" | "LOD2" | "LOD3" | null (auto fallback)
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lod is currently typed as string | null, which is broader than what the API supports and makes it easy to accidentally send an invalid value (e.g. typos) in the request body. Please constrain this to the supported values (e.g. "LOD1" | "LOD2" | "LOD3") and represent “auto” by omitting the field (or use null only at the UI layer and normalize before calling the service).

Suggested change
lod?: string | null; // "LOD1" | "LOD2" | "LOD3" | null (auto fallback)
lod?: "LOD1" | "LOD2" | "LOD3"; // "LOD1" | "LOD2" | "LOD3"; omit for auto fallback

Copilot uses AI. Check for mistakes.

## Project Overview
Paper-CAD is a CAD application for unfolding 3D models into 2D SVG/PDF patterns. The frontend is a TypeScript monorepo (Rspack + npm workspaces), the backend is a FastAPI Python server with OpenCASCADE for geometry processing. A C++ kernel (OpenCASCADE) compiles to WebAssembly.
Paper-CAD is a CAD application for unfolding 3D models into 2D SVG/PDF patterns. The frontend is a TypeScript monorepo (Rspack), the backend is a FastAPI Python server with OpenCASCADE for geometry processing. A C++ kernel (OpenCASCADE) compiles to WebAssembly.
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Project Overview says the frontend is a monorepo “(Rspack)”, but the Project Structure section immediately below describes it as “(Rspack + npm workspaces)”. Please make these consistent to avoid confusion about the build system/workspace setup.

Suggested change
Paper-CAD is a CAD application for unfolding 3D models into 2D SVG/PDF patterns. The frontend is a TypeScript monorepo (Rspack), the backend is a FastAPI Python server with OpenCASCADE for geometry processing. A C++ kernel (OpenCASCADE) compiles to WebAssembly.
Paper-CAD is a CAD application for unfolding 3D models into 2D SVG/PDF patterns. The frontend is a TypeScript monorepo (Rspack + npm workspaces), the backend is a FastAPI Python server with OpenCASCADE for geometry processing. A C++ kernel (OpenCASCADE) compiles to WebAssembly.

Copilot uses AI. Check for mistakes.
The ShapeCache was keyed by (building_id, precision_mode, shape_fix_level)
without including target_lod. This caused a bug where importing a building
with auto/LOD2 would cache the LOD2 shape, and a subsequent LOD1 request
for the same building would return the cached LOD2 result instead of
re-extracting with LOD1 geometry.

Fix: Extend cache key to (building_id, precision_mode, shape_fix_level,
target_lod) in both sequential and parallel processing paths.

Fixes #201
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 6, 2026

Deploying paper-cad with  Cloudflare Pages  Cloudflare Pages

Latest commit: 5246c4e
Status: ✅  Deploy successful!
Preview URL: https://06516320.paper-cad.pages.dev
Branch Preview URL: https://feature-201-lod-selection-ui.paper-cad.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link

Deploying newlppaper-cad with  Cloudflare Pages  Cloudflare Pages

Latest commit: 5246c4e
Status: ✅  Deploy successful!
Preview URL: https://0974edf8.newlppaper-cad.pages.dev
Branch Preview URL: https://feature-201-lod-selection-ui.newlppaper-cad.pages.dev

View logs

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants