Plandarstellung schwarz: Tür/Fenster-Symbole als Haarlinie, Decke weiss hinterlegt

Plandarstellung ist schwarz/grau; Farbe bleibt spaeteren Schemaelementen
vorbehalten.

- Tuerblatt, Schwenkbogen, Fensterscheibe und Anschlagstriche: einheitlich
  #1a1a1a statt blau (#2b3039/#4a86c7/#6b7280), im render2d/PDF-Pfad
  (CLS_STROKE) und im SVG-CSS.
- Schwenkbogen als Volllinie (Strichelung entfernt).
- Tuer-/Fenstersymbol-Linien auf Haarlinie 0.02 mm (SYMBOL_HAIRLINE_MM).
- Decken-Poche: Schraffur auf weissem Grund wie mehrschichtige Waende
  (pocheFill), solid schwarz - nicht mehr die Bauteil-Fuellfarbe.
This commit is contained in:
2026-07-03 20:28:03 +02:00
parent ec2568276d
commit f9a5e763fd
3 changed files with 26 additions and 22 deletions
+17 -13
View File
@@ -82,6 +82,8 @@ const MONO_INK = "#111111";
/** Haarlinie zwischen den Schichten (Schichtfugen) in mm — gleiche Stärke wie die Schraffur-Tinte. */ /** Haarlinie zwischen den Schichten (Schichtfugen) in mm — gleiche Stärke wie die Schraffur-Tinte. */
const LAYER_LINE_MM = 0.02; const LAYER_LINE_MM = 0.02;
/** Haarlinie für Tür-/Fenstersymbole (Flügel, Bogen, Rahmen, Glas) in mm. */
const SYMBOL_HAIRLINE_MM = 0.02;
/** Stärke der Wand-Umrisslinie je Detailgrad, als Faktor auf die Ebenen-lw. */ /** Stärke der Wand-Umrisslinie je Detailgrad, als Faktor auf die Ebenen-lw. */
const OUTLINE_DETAIL_FACTOR: Record<DetailLevel, number> = { const OUTLINE_DETAIL_FACTOR: Record<DetailLevel, number> = {
grob: 1.6, // dickere Sammellinie grob: 1.6, // dickere Sammellinie
@@ -974,7 +976,7 @@ function addDoorSymbol(
door: Project["doors"][number], door: Project["doors"][number],
greyed: boolean, greyed: boolean,
detail: DetailLevel, detail: DetailLevel,
doorLwMm: number, _doorLwMm: number,
): void { ): void {
const u = normalize(sub(wall.end, wall.start)); const u = normalize(sub(wall.end, wall.start));
const n = leftNormal(u); // linke Seite der Wandachse const n = leftNormal(u); // linke Seite der Wandachse
@@ -994,7 +996,7 @@ function addDoorSymbol(
a: hinge, a: hinge,
b: openEnd, b: openEnd,
cls: "door-leaf", cls: "door-leaf",
weightMm: doorLwMm, weightMm: SYMBOL_HAIRLINE_MM,
greyed, greyed,
}); });
@@ -1007,8 +1009,7 @@ function addDoorSymbol(
to: openEnd, to: openEnd,
r: door.width, r: door.width,
cls: "door-swing", cls: "door-swing",
weightMm: doorLwMm * 0.6, weightMm: SYMBOL_HAIRLINE_MM,
dash: [0.06, 0.04], // gestrichelt in mm Papier
greyed, greyed,
}); });
} }
@@ -1023,7 +1024,7 @@ function addDoorSymbol(
a: add(jamb, scale(n, reveal)), a: add(jamb, scale(n, reveal)),
b: add(jamb, scale(n, -reveal)), b: add(jamb, scale(n, -reveal)),
cls: "door-frame", cls: "door-frame",
weightMm: doorLwMm, weightMm: SYMBOL_HAIRLINE_MM,
greyed, greyed,
}); });
} }
@@ -1062,7 +1063,7 @@ function addOpeningSymbol(
a: sym.hinge, a: sym.hinge,
b: sym.openEnd, b: sym.openEnd,
cls: "door-leaf", cls: "door-leaf",
weightMm: lwMm, weightMm: SYMBOL_HAIRLINE_MM,
greyed, greyed,
openingId: o.id, openingId: o.id,
}); });
@@ -1075,8 +1076,7 @@ function addOpeningSymbol(
to: sym.openEnd, to: sym.openEnd,
r: sym.radius, r: sym.radius,
cls: "door-swing", cls: "door-swing",
weightMm: lwMm * 0.6, weightMm: SYMBOL_HAIRLINE_MM,
dash: [0.06, 0.04],
greyed, greyed,
openingId: o.id, openingId: o.id,
}); });
@@ -1090,7 +1090,7 @@ function addOpeningSymbol(
a: add(jamb, scale(sym.normal, reveal)), a: add(jamb, scale(sym.normal, reveal)),
b: add(jamb, scale(sym.normal, -reveal)), b: add(jamb, scale(sym.normal, -reveal)),
cls: "door-frame", cls: "door-frame",
weightMm: lwMm, weightMm: SYMBOL_HAIRLINE_MM,
greyed, greyed,
openingId: o.id, openingId: o.id,
}); });
@@ -1122,7 +1122,7 @@ function addOpeningSymbol(
a, a,
b, b,
cls: "window-glass", cls: "window-glass",
weightMm: lwMm * 0.7, weightMm: SYMBOL_HAIRLINE_MM,
greyed, greyed,
openingId: o.id, openingId: o.id,
}); });
@@ -1183,14 +1183,18 @@ function addCeilingPoche(
const ceilingId = ceiling.id; const ceilingId = ceiling.id;
// Gefüllte + schraffierte Fläche (Component-Poché). Im Detailgrad „grob" ohne // Gefüllte + schraffierte Fläche (Component-Poché). Im Detailgrad „grob" ohne
// Schraffur (reine Füllung), sonst die Bauteil-Schraffur. // Schraffur (reine Füllung), sonst die Bauteil-Schraffur. SIA-Poché wie bei
// der mehrschichtigen Wand: neutraler Hintergrund (weiß) statt Bauteil-Albedo,
// Vollmuster ("solid") = schwarze Poché.
const hatch = comp && detail !== "grob" ? resolveHatch(project, comp.hatchId) : NO_HATCH;
const solid = hatch.pattern === "solid";
out.push({ out.push({
kind: "polygon", kind: "polygon",
pts, pts,
fill: comp ? comp.color : "none", fill: comp ? pocheFill(hatch.pattern) : "none",
stroke, stroke,
strokeWidthMm: LAYER_LINE_MM * LAYER_DETAIL_FACTOR[detail], strokeWidthMm: LAYER_LINE_MM * LAYER_DETAIL_FACTOR[detail],
hatch: comp && detail !== "grob" ? resolveHatch(project, comp.hatchId) : NO_HATCH, hatch: solid ? { ...hatch, color: POCHE_FILL_BLACK } : hatch,
greyed, greyed,
ceilingId, ceilingId,
}); });
+5 -5
View File
@@ -128,10 +128,10 @@ const DEFAULT_LINE = "#1a1a1a";
* `opacity: 0.7`, wall-axis `opacity: 0.85`. * `opacity: 0.7`, wall-axis `opacity: 0.85`.
*/ */
const CLS_STROKE: Record<string, string> = { const CLS_STROKE: Record<string, string> = {
"door-leaf": "#2b3039", "door-leaf": "#1a1a1a",
"door-swing": "#6b7280", "door-swing": "#1a1a1a",
"door-frame": "#2b3039", "door-frame": "#1a1a1a",
"window-glass": "#4a86c7", "window-glass": "#1a1a1a",
"wall-axis": "#2f5d54", // var(--accent) des hellen Standard-Themes "wall-axis": "#2f5d54", // var(--accent) des hellen Standard-Themes
}; };
const CLS_OPACITY: Record<string, number> = { const CLS_OPACITY: Record<string, number> = {
@@ -433,7 +433,7 @@ export function planToRenderScene(plan: Plan, paperScaleN: number = STAMP_DEFAUL
} }
} else if (p.kind === "arc") { } else if (p.kind === "arc") {
flushRun(); flushRun();
// Farbe wie im SVG: CSS-Klassen-Regel (z. B. .door-swing → #6b7280). // Farbe wie im SVG: CSS-Klassen-Regel (z. B. .door-swing → #1a1a1a).
const col = withOpacity(strokeColorFor(p.cls, undefined), p.cls, p.greyed); const col = withOpacity(strokeColorFor(p.cls, undefined), p.cls, p.greyed);
// Bogen unvortessellliert an Rust übergeben (`RArc`) — die exakte runde // Bogen unvortessellliert an Rust übergeben (`RArc`) — die exakte runde
// Darstellung (analytischer SDF-Shader, `ARC_WGSL`) und ein evtl. Strich- // Darstellung (analytischer SDF-Shader, `ARC_WGSL`) und ein evtl. Strich-
+4 -4
View File
@@ -1527,24 +1527,24 @@ body {
Das Zeichenblatt ist IMMER hell (--sheet) Plan-Tinte bleibt fix dunkel, Das Zeichenblatt ist IMMER hell (--sheet) Plan-Tinte bleibt fix dunkel,
unabhängig vom UI-Theme (sonst unsichtbar auf Weiß im Dark-Mode). */ unabhängig vom UI-Theme (sonst unsichtbar auf Weiß im Dark-Mode). */
.plan-svg .door-leaf { .plan-svg .door-leaf {
stroke: #2b3039; stroke: #1a1a1a;
fill: none; fill: none;
} }
.plan-svg .door-swing { .plan-svg .door-swing {
stroke: #6b7280; stroke: #1a1a1a;
fill: none; fill: none;
} }
/* Anschlag-/Rahmenstriche der Tür (nur im Detailgrad „fein"). */ /* Anschlag-/Rahmenstriche der Tür (nur im Detailgrad „fein"). */
.plan-svg .door-frame { .plan-svg .door-frame {
stroke: #2b3039; stroke: #1a1a1a;
fill: none; fill: none;
} }
/* Glaslinien des Fensters (dünn, gedämpft — die Verglasung im Grundriss). */ /* Glaslinien des Fensters (dünn, gedämpft — die Verglasung im Grundriss). */
.plan-svg .window-glass { .plan-svg .window-glass {
stroke: #4a86c7; stroke: #1a1a1a;
fill: none; fill: none;
} }