Wandstile: Schichtfuge pro Fuge als LineStyle waehlbar + ResourceManager-Abteilung
Mehrschichtige Waende zeichnen die Trennlinie an jeder Materialfuge jetzt mit einem pro Fuge waehlbaren LineStyle statt einer festen Haarlinie. - Layer.jointLineStyleId (optional): LineStyle der Fuge an der Innenkante dieser Schicht; fehlt er, gilt die Default-Haarlinie (0.02) in Wandfarbe. - generatePlan: Schicht-Baender tragen nur noch Fuellung + Schraffur (kein Band-Umriss); jede innere Fuge wird als eigene Linie mit ihrem LineStyle (Gewicht/Farbe/Dash, x Detailfaktor) gezeichnet. Wand-Umriss (0.35) und grob-Pfad unveraendert. - ResourceManager: neue Abteilung "Wandstile" - je Wandtyp die Schichten mit Fugen-LineStyle-Dropdown. - Sample: LineStyle "Schichtfuge 0.13"; der Daemmung-Backstein-Fuge (massiv/ massiv) zugewiesen, Putzfugen bleiben Haarlinie. - 2 Joint-Tests ergaenzt.
This commit is contained in:
@@ -114,3 +114,31 @@ describe("generatePlan — Wandecken-Gehrung", () => {
|
||||
for (const p of wallPolys) expect(p.noStrokeEdges).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("generatePlan — Schichtfugen als stilisierbare Linien", () => {
|
||||
const jointLines = (proj: Project) =>
|
||||
generatePlan(proj, "eg", visible, undefined, "mittel").primitives.filter(
|
||||
(p): p is Extract<typeof p, { kind: "line" }> =>
|
||||
p.kind === "line" && p.cls === "layer-joint",
|
||||
);
|
||||
|
||||
it("zieht die innere Fuge als eigene Linie und übernimmt Gewicht/Farbe des LineStyle", () => {
|
||||
const proj = cornerProject();
|
||||
proj.walls = [proj.walls[0]]; // nur W1, zwei Schichten → genau eine innere Fuge
|
||||
proj.wallTypes[0].layers[0].jointLineStyleId = "thin"; // weight 0.13, color #111
|
||||
const joints = jointLines(proj);
|
||||
expect(joints.length).toBe(1);
|
||||
// LAYER_DETAIL_FACTOR["mittel"] == 1 → das LineStyle-Gewicht wirkt direkt.
|
||||
expect(joints[0].weightMm).toBeCloseTo(0.13, 6);
|
||||
expect(joints[0].color).toBe("#111");
|
||||
expect(joints[0].dash ?? null).toBeNull();
|
||||
});
|
||||
|
||||
it("fällt ohne Zuweisung auf die Haarlinie (0.02 mm) in Wandfarbe zurück", () => {
|
||||
const proj = cornerProject();
|
||||
proj.walls = [proj.walls[0]];
|
||||
const joints = jointLines(proj);
|
||||
expect(joints.length).toBe(1);
|
||||
expect(joints[0].weightMm).toBeCloseTo(0.02, 6);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -80,7 +80,9 @@ const MONO_INK = "#111111";
|
||||
// dpi = 96·devicePixelRatio in konstante Bildschirm-Pixel um (non-scaling-stroke),
|
||||
// damit Linien beim Zoomen ihre Papiergröße behalten und der Massstab stimmt.
|
||||
|
||||
/** Haarlinie zwischen den Schichten (Schichtfugen) in mm — gleiche Stärke wie die Schraffur-Tinte. */
|
||||
/** Default-Schichtfuge zwischen den Materialschichten in mm — Haarlinie (0.02),
|
||||
* gleiche Stärke wie die Schraffur-Tinte. Pro Fuge im Wandstil überschreibbar
|
||||
* (z. B. 0.13, wenn zwei massive Materialien aufeinandertreffen). */
|
||||
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;
|
||||
@@ -905,10 +907,12 @@ function addWallPoche(
|
||||
|
||||
// mittel/fein: Schichten von außen (-T/2) nach innen (+T/2) stapeln. Jede
|
||||
// Schicht löst Bauteil (Füllfarbe) + Schraffur (Muster/Maßstab/Winkel/Farbe)
|
||||
// auf; die Schichtfugen werden dünn gestrichen.
|
||||
// auf. Die Bänder tragen NUR Füllung + Schraffur (kein eigener Umriss); jede
|
||||
// innere Schichtfuge wird als EIGENSTÄNDIGE, stilisierbare Linie gezeichnet.
|
||||
const bandJoinEdges = joinEdges(startCut, endCut);
|
||||
let off = refOff - total / 2;
|
||||
for (const layer of wt.layers) {
|
||||
for (let li = 0; li < wt.layers.length; li++) {
|
||||
const layer = wt.layers[li];
|
||||
const comp = getComponent(project, layer.componentId);
|
||||
const layerHatch = resolveHatch(project, comp.hatchId, wallAngleDeg);
|
||||
// SIA-Poché: neutraler Hintergrund (weiß) statt Bauteil-Albedo, die
|
||||
@@ -918,16 +922,42 @@ function addWallPoche(
|
||||
kind: "polygon",
|
||||
pts: clippedBand(p1, p2, off, off + layer.thickness, startCut, endCut),
|
||||
fill: layerSolid ? POCHE_FILL_BLACK : POCHE_FILL_WHITE,
|
||||
stroke,
|
||||
strokeWidthMm: layerLineMm,
|
||||
// Band ohne Umriss: keine Schichtfuge über die Bandkante, keine 45°-Naht
|
||||
// am Knoten. Die Fugen kommen als separate `line`-Primitive (siehe unten).
|
||||
stroke: "none",
|
||||
strokeWidthMm: 0,
|
||||
hatch: layerSolid ? { ...layerHatch, color: POCHE_FILL_BLACK } : layerHatch,
|
||||
greyed,
|
||||
// Die Diagonale am Knoten NICHT stricheln → keine 45°-Naht zwischen
|
||||
// gleichfarbigen Schichten der beiden Wände.
|
||||
// Für die Ecktests/Konsistenz beibehalten (bei stroke:"none" wirkungslos).
|
||||
noStrokeEdges: bandJoinEdges,
|
||||
wallId,
|
||||
});
|
||||
off += layer.thickness;
|
||||
// Innere Schichtfuge (zwischen dieser und der nächst-inneren Schicht) als
|
||||
// eigene Linie am kumulierten Offset `off`, mit dem Cut der Bänder geclippt.
|
||||
// Stil aus layer.jointLineStyleId (Gewicht/Farbe/Strich); Rückfall = Haar-
|
||||
// linie (LAYER_LINE_MM) in Wandfarbe. Das Gewicht folgt demselben Detail-
|
||||
// Faktor wie die frühere Schichtfuge (`layerLineMm`), damit die Detailgrade
|
||||
// sich unverändert verhalten. Die innerste Schicht hat keine innere Fuge.
|
||||
if (li < wt.layers.length - 1) {
|
||||
// clippedBand(p1, p2, off, off, …) liefert [edgeStart, edgeEnd, edgeEnd,
|
||||
// edgeStart] → die zwei distinkten Endpunkte sind Index 0 (Start) und 1
|
||||
// (Ende), beide am Cut abgeschnitten wie die Bandlängskante.
|
||||
const jq = clippedBand(p1, p2, off, off, startCut, endCut);
|
||||
const jls = layer.jointLineStyleId
|
||||
? project.lineStyles.find((l) => l.id === layer.jointLineStyleId)
|
||||
: undefined;
|
||||
out.push({
|
||||
kind: "line",
|
||||
a: jq[0],
|
||||
b: jq[1],
|
||||
cls: "layer-joint",
|
||||
weightMm: jls ? jls.weight * LAYER_DETAIL_FACTOR[detail] : layerLineMm,
|
||||
color: jls ? jls.color : stroke,
|
||||
dash: jls ? jls.dash : null,
|
||||
greyed,
|
||||
});
|
||||
}
|
||||
}
|
||||
// Kräftige Wand-Umrisslinie über die volle Dicke (nur Kontur, keine Füllung),
|
||||
// damit die Wand sich klar von den dünnen Schichtfugen abhebt. Die Gehrungs-
|
||||
|
||||
Reference in New Issue
Block a user