Files
DOSSIER-STANDALONE/src/plan/generatePlan.stairArrow.test.ts
T
karim b9e330ecb7 Schnittebenen 2D↔3D Phase 1+2, native Fenster, Hell/Dunkel-Theme, SWISSIMAGE-Import
- Schnittebenen: 3D-Live-Schnitt folgt der gewählten Grundriss-Schnittlinie
  (section3dCutId/sectionPlaneFromLevel), Schalter "Im 3D schneiden" im
  Objekt-Info, Doppelklick auf Schnittlinie springt in 2D-Schnittansicht,
  unsichtbare Ebenen blenden ihre Führungslinie aus
- Eigene native Tauri-Fenster für Kontext-Import/Zeichnungsebenen/
  Ebenen-Einstellungen/Ressourcen/Einstellungen + klassische Menüleiste
  (AppMenuBar) neben der Wortmarke
- Hell/Dunkel-Umschalter (Einstellungen → Darstellung), persistiert,
  flackerfrei vor erstem Render gesetzt
- SWISSIMAGE-Luftbild-Import (swisstopo WMS) als Kontext-Hintergrundebene
- UI-Politur: Werkzeug-Panel Symbole/Liste umschaltbar, Topbar-Quick-Access-
  Icons entfernt, Zahnrad→Einstellungen in Panel-Köpfen, Footerbar/
  Snap-Marker/Maß-HUD auf helle Pillen-Sprache umgestellt
- Neues Dachziegel-Material (RoofingTiles013A)
2026-07-20 10:51:37 +02:00

86 lines
2.5 KiB
TypeScript

/**
* Treppen-Pfeil-Darstellung (generatePlan → addStairSymbol): Default "line"
* zeichnet den Auf-/Abpfeil als zwei offene Linien (cls "stair-arrow");
* `arrowStyle:"filled"` ersetzt sie durch EIN gefülltes Dreieck-Polygon
* (SIA-Vollpfeil).
*/
import { describe, it, expect } from "vitest";
import { generatePlan } from "./generatePlan";
import type { DrawingLevel, Project, Stair } from "../model/types";
const visible = new Set(["40"]);
const floor: DrawingLevel = {
id: "eg",
name: "EG",
kind: "floor",
visible: true,
locked: false,
floorHeight: 2.6,
cutHeight: 1.0,
baseElevation: 0,
};
function baseStair(extra: Partial<Stair> = {}): Stair {
return {
id: "st-1",
type: "stair",
floorId: "eg",
categoryCode: "40",
shape: "gerade",
start: { x: 0, y: 0 },
dir: { x: 1, y: 0 },
runLength: 4,
width: 1.2,
stepCount: 16,
totalRise: 2.6,
...extra,
} as Stair;
}
function project(stair: Stair): Project {
return {
id: "t",
name: "T",
lineStyles: [],
hatches: [],
components: [],
wallTypes: [],
drawingLevels: [floor],
layers: [{ code: "40", name: "Treppen", color: "#333", lw: 0.18, visible: true, locked: false }],
walls: [],
doors: [],
openings: [],
ceilings: [],
stairs: [stair],
rooms: [],
drawings2d: [],
context: [],
} as unknown as Project;
}
describe("generatePlan — Treppen-Pfeil", () => {
it("Default: offener Winkelpfeil = zwei stair-arrow-Linien, kein gefülltes Polygon", () => {
const prims = generatePlan(project(baseStair()), "eg", visible).primitives;
const arrowLines = prims.filter((p) => p.kind === "line" && p.cls === "stair-arrow");
expect(arrowLines.length).toBe(2);
// Keine gefüllte Pfeil-Fläche (Tritt-Polygone tragen fill:"none").
const filled = prims.filter(
(p) => p.kind === "polygon" && p.stairId === "st-1" && p.fill !== "none",
);
expect(filled.length).toBe(0);
});
it("filled: ein gefülltes Dreieck-Polygon, keine stair-arrow-Linien", () => {
const prims = generatePlan(project(baseStair({ arrowStyle: "filled" })), "eg", visible)
.primitives;
expect(prims.some((p) => p.kind === "line" && p.cls === "stair-arrow")).toBe(false);
const filled = prims.filter(
(p) => p.kind === "polygon" && p.stairId === "st-1" && p.fill !== "none",
);
expect(filled.length).toBe(1);
expect(filled[0].kind === "polygon" && filled[0].pts.length).toBe(3);
});
});