Dach 2D: Ansichts-Poché der Dachaufsicht aus der Eindeckungs-Schicht
Das Dach liegt über der Schnittebene und wird von oben gesehen → das Pick- Polygon der Traufe-Fläche trägt jetzt die Ansichts-Schraffur (viewHatchId) der ÄUSSERSTEN Dachtyp-Schicht (Eindeckung), analog dem Decken-Poché in der Aufsicht. Ohne Dachtyp/viewHatchId weiterhin weiss. +1 Test. 685/685 grün.
This commit is contained in:
@@ -129,6 +129,33 @@ describe("generatePlan — Dächer (Dachaufsicht)", () => {
|
|||||||
expect(linesOf(withoutColor.primitives, "roof-eaves")[0].color).toBe("#8a4b32");
|
expect(linesOf(withoutColor.primitives, "roof-eaves")[0].color).toBe("#8a4b32");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Dachaufsicht-Poché: viewHatchId der äussersten Dachtyp-Schicht schraffiert das Pick-Polygon", () => {
|
||||||
|
const p: Project = {
|
||||||
|
...baseProject([roof("R9", "sattel", { roofTypeId: "rt1" })]),
|
||||||
|
hatches: [
|
||||||
|
{ id: "diag", name: "Diagonal", pattern: "diagonal", scale: 1, angle: 45, color: "#1a1a1a" },
|
||||||
|
],
|
||||||
|
components: [
|
||||||
|
{ id: "tile", name: "Ziegel", color: "#a03a2a", hatchId: "", viewHatchId: "diag", joinPriority: 1 },
|
||||||
|
],
|
||||||
|
roofTypes: [{ id: "rt1", name: "Dach", layers: [{ componentId: "tile", thickness: 0.05 }] }],
|
||||||
|
};
|
||||||
|
const polys = generatePlan(p, "eg", visible).primitives.filter(
|
||||||
|
(pr): pr is Extract<typeof pr, { kind: "polygon" }> =>
|
||||||
|
pr.kind === "polygon" && (pr as { roofId?: string }).roofId === "R9",
|
||||||
|
);
|
||||||
|
expect(polys.length).toBe(1);
|
||||||
|
expect(polys[0].hatch.pattern).toBe("diagonal");
|
||||||
|
|
||||||
|
// Ohne Dachtyp: keine Schraffur (Pattern "none"), Pick-Polygon bleibt.
|
||||||
|
const plain = generatePlan(baseProject([roof("R10", "sattel")]), "eg", visible).primitives.filter(
|
||||||
|
(pr): pr is Extract<typeof pr, { kind: "polygon" }> =>
|
||||||
|
pr.kind === "polygon" && (pr as { roofId?: string }).roofId === "R10",
|
||||||
|
);
|
||||||
|
expect(plain.length).toBe(1);
|
||||||
|
expect(plain[0].hatch.pattern).toBe("none");
|
||||||
|
});
|
||||||
|
|
||||||
it("Rückwärtskompatibilität: ohne Dächer (bzw. Dach auf anderem Geschoss) bleiben die Primitive unverändert", () => {
|
it("Rückwärtskompatibilität: ohne Dächer (bzw. Dach auf anderem Geschoss) bleiben die Primitive unverändert", () => {
|
||||||
const planNoField = generatePlan(baseProject(undefined), "eg", visible);
|
const planNoField = generatePlan(baseProject(undefined), "eg", visible);
|
||||||
const planEmpty = generatePlan(baseProject([]), "eg", visible);
|
const planEmpty = generatePlan(baseProject([]), "eg", visible);
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import {
|
|||||||
glazingPanesOf,
|
glazingPanesOf,
|
||||||
openingLabel,
|
openingLabel,
|
||||||
openingsOfWall,
|
openingsOfWall,
|
||||||
|
roofLayers,
|
||||||
roomsOfFloor,
|
roomsOfFloor,
|
||||||
sashesOfWindowType,
|
sashesOfWindowType,
|
||||||
stairLabel,
|
stairLabel,
|
||||||
@@ -763,7 +764,7 @@ export function generatePlan(
|
|||||||
for (const roof of roofs) {
|
for (const roof of roofs) {
|
||||||
const greyed = categoryDisplay(roof.categoryCode).greyed;
|
const greyed = categoryDisplay(roof.categoryCode).greyed;
|
||||||
const category = catByCode.get(roof.categoryCode);
|
const category = catByCode.get(roof.categoryCode);
|
||||||
addRoof(primitives, roof, greyed, category);
|
addRoof(primitives, project, roof, greyed, category);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Räume (SIA-416-Flächen) dieses Geschosses: transluzente Farbfüllung + Stempel
|
// Räume (SIA-416-Flächen) dieses Geschosses: transluzente Farbfüllung + Stempel
|
||||||
@@ -2567,6 +2568,7 @@ function addCeilingPoche(
|
|||||||
*/
|
*/
|
||||||
function addRoof(
|
function addRoof(
|
||||||
out: Primitive[],
|
out: Primitive[],
|
||||||
|
project: Project,
|
||||||
roof: Roof,
|
roof: Roof,
|
||||||
greyed: boolean,
|
greyed: boolean,
|
||||||
category: LayerCategory | undefined,
|
category: LayerCategory | undefined,
|
||||||
@@ -2574,10 +2576,26 @@ function addRoof(
|
|||||||
const stroke = roof.color ?? category?.color ?? POCHE_STROKE;
|
const stroke = roof.color ?? category?.color ?? POCHE_STROKE;
|
||||||
const geo = roofGeometry(roof, 0);
|
const geo = roofGeometry(roof, 0);
|
||||||
|
|
||||||
// Unsichtbares Pick-Polygon über der Traufe-Fläche — macht das Dach über die
|
// Ansichts-Poché der Dachaufsicht: das Dach liegt ÜBER der Schnittebene und
|
||||||
// ganze Fläche per Links-Klick selektierbar (die Dachlinien allein wären
|
// wird von oben gesehen (nicht geschnitten) → Ansichts-Schraffur
|
||||||
// schwer exakt zu treffen). fill/stroke "none" ⇒ zeichnet nichts; PlanView
|
// (viewHatchId) der ÄUSSERSTEN Schicht (Eindeckung) des Dachtyps, analog dem
|
||||||
// testet nur die `pts` (Punkt-in-Polygon), analog Öffnung/Decke.
|
// Decken-Poché (Aufsicht = erste Lage). Ohne Dachtyp/viewHatchId keine
|
||||||
|
// Schraffur (weiss) — die Fläche bleibt trotzdem das Pick-Polygon.
|
||||||
|
let viewHatch = NO_HATCH;
|
||||||
|
const firstLayer = roofLayers(project, roof)[0];
|
||||||
|
if (firstLayer?.componentId) {
|
||||||
|
try {
|
||||||
|
const comp = getComponent(project, firstLayer.componentId);
|
||||||
|
if (comp.viewHatchId) viewHatch = resolveHatch(project, comp.viewHatchId);
|
||||||
|
} catch {
|
||||||
|
viewHatch = NO_HATCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pick-Polygon über der Traufe-Fläche (macht das Dach über die ganze Fläche
|
||||||
|
// per Links-Klick selektierbar) — trägt jetzt zusätzlich die Ansichts-
|
||||||
|
// Schraffur der Eindeckung (fill bleibt "none": keine Volltonfüllung, nur
|
||||||
|
// Musterlinien). PlanView testet die `pts` (Punkt-in-Polygon).
|
||||||
if (geo.eaves.length >= 3) {
|
if (geo.eaves.length >= 3) {
|
||||||
out.push({
|
out.push({
|
||||||
kind: "polygon",
|
kind: "polygon",
|
||||||
@@ -2585,7 +2603,7 @@ function addRoof(
|
|||||||
fill: "none",
|
fill: "none",
|
||||||
stroke: "none",
|
stroke: "none",
|
||||||
strokeWidthMm: 0,
|
strokeWidthMm: 0,
|
||||||
hatch: NO_HATCH,
|
hatch: viewHatch,
|
||||||
greyed,
|
greyed,
|
||||||
roofId: roof.id,
|
roofId: roof.id,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user