Tür: Teilverglasung (glazingRatio) im 3D wirksam
DoorType.glazingRatio wurde bisher von keinem Renderer gelesen (Designdoc). Bei Glasblatt (leafStyle 'glas') füllt das Glas jetzt nur den oberen glazingRatio-Anteil des Hauptfelds; darunter bleibt ein blindes Blattfeld (z. B. Tür mit Oberglas). Fenster unberührt (glazedFraction = 1). +1 Test (Halbglas: Unterkante angehoben, Oberkante am Sturz). 673/673 grün.
This commit is contained in:
@@ -604,6 +604,52 @@ describe("Rahmen-/Sprossen-Riegel typisierter Öffnungen (emitOpeningFrames)", (
|
|||||||
expect(operableCount).toBe(8); // + 4 Flügelrahmen-Riegel
|
expect(operableCount).toBe(8); // + 4 Flügelrahmen-Riegel
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Glastür mit glazingRatio < 1: Glas nur im oberen Blattanteil (Teilverglasung)", () => {
|
||||||
|
const glassDoor = (glazingRatio?: number): Project => ({
|
||||||
|
...sampleProject,
|
||||||
|
doorTypes: [
|
||||||
|
{
|
||||||
|
id: "dt-glass",
|
||||||
|
name: "Glastür Test",
|
||||||
|
kind: "dreh",
|
||||||
|
leafCount: 1,
|
||||||
|
leafStyle: "glas",
|
||||||
|
glazingRatio,
|
||||||
|
frameThickness: 0.06,
|
||||||
|
frameWidth: 0.06,
|
||||||
|
defaultWidth: 0.9,
|
||||||
|
defaultHeight: 2.0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
openings: [
|
||||||
|
{
|
||||||
|
id: "DG",
|
||||||
|
type: "opening",
|
||||||
|
hostWallId: "W1",
|
||||||
|
categoryCode: "21",
|
||||||
|
kind: "door",
|
||||||
|
typeId: "dt-glass",
|
||||||
|
position: 3.0,
|
||||||
|
width: 0.9,
|
||||||
|
height: 2.0,
|
||||||
|
sillHeight: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
doors: [],
|
||||||
|
context: [],
|
||||||
|
});
|
||||||
|
// Vollglas (ratio 1 / fehlt): Glas über (fast) die ganze Blatthöhe.
|
||||||
|
const full = projectToModel3d(glassDoor(1)).meshes.filter(isGlass);
|
||||||
|
expect(full.length).toBe(1);
|
||||||
|
const fullR = zRange(full[0]);
|
||||||
|
// Halbglas (ratio 0.5): Glas nur in der oberen Hälfte -> Unterkante deutlich höher.
|
||||||
|
const half = projectToModel3d(glassDoor(0.5)).meshes.filter(isGlass);
|
||||||
|
expect(half.length).toBe(1);
|
||||||
|
const halfR = zRange(half[0]);
|
||||||
|
expect(halfR.max).toBeCloseTo(fullR.max, 6); // Oberkante gleich (an OK/Sturz)
|
||||||
|
expect(halfR.min).toBeGreaterThan(fullR.min + 0.5); // Unterkante klar angehoben
|
||||||
|
});
|
||||||
|
|
||||||
it("insetFromFace verschiebt Rahmen-Position entlang der Wand-Normalen gegenüber bündig (kein Einzug)", () => {
|
it("insetFromFace verschiebt Rahmen-Position entlang der Wand-Normalen gegenüber bündig (kein Einzug)", () => {
|
||||||
// W1-Achse (0,0)->(5,0): u=(1,0) -> Normale n=(0,-1); der Quer-Versatz
|
// W1-Achse (0,0)->(5,0): u=(1,0) -> Normale n=(0,-1); der Quer-Versatz
|
||||||
// bildet sich rein in der Y-Koordinate ab (y = -t). insetFromFace 0.1 muss
|
// bildet sich rein in der Y-Koordinate ab (y = -t). insetFromFace 0.1 muss
|
||||||
|
|||||||
+20
-3
@@ -1942,6 +1942,13 @@ interface OpeningFrameParams {
|
|||||||
* {@link glassPanesForOpening}.
|
* {@link glassPanesForOpening}.
|
||||||
*/
|
*/
|
||||||
glazingPanes: 1 | 2 | 3;
|
glazingPanes: 1 | 2 | 3;
|
||||||
|
/**
|
||||||
|
* Verglasungs-Anteil des HAUPTFELDS (0..1, von OBEN gemessen): 1 = voll
|
||||||
|
* verglast (Fenster, Ganzglastür), < 1 = nur der obere Anteil ist Glas, unten
|
||||||
|
* bleibt ein blindes Feld (z. B. Tür mit Oberglas, `DoorType.glazingRatio`).
|
||||||
|
* Fenster: immer 1.
|
||||||
|
*/
|
||||||
|
glazedFraction: number;
|
||||||
/**
|
/**
|
||||||
* Flügeleinteilung ({@link sashesOfWindowType}) — je ÖFFENBAREM Flügel wird im
|
* Flügeleinteilung ({@link sashesOfWindowType}) — je ÖFFENBAREM Flügel wird im
|
||||||
* 3D ein Flügelrahmen (Rahmen-Riegel innerhalb des Blendrahmens) erzeugt
|
* 3D ein Flügelrahmen (Rahmen-Riegel innerhalb des Blendrahmens) erzeugt
|
||||||
@@ -1975,6 +1982,8 @@ function resolveOpeningFrame(project: Project, wall: Wall, op: Opening): Opening
|
|||||||
mullionRows: 1,
|
mullionRows: 1,
|
||||||
glazed: dt.leafStyle === "glas",
|
glazed: dt.leafStyle === "glas",
|
||||||
glazingPanes: 1,
|
glazingPanes: 1,
|
||||||
|
// Teilverglasung: glazingRatio (Glasanteil oben) bei Glasblatt; sonst voll.
|
||||||
|
glazedFraction: Math.max(0.05, Math.min(1, dt.glazingRatio ?? 1)),
|
||||||
sashes: [],
|
sashes: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -2014,6 +2023,7 @@ function resolveOpeningFrame(project: Project, wall: Wall, op: Opening): Opening
|
|||||||
mullionRows: Math.max(1, Math.round(wt.mullionRows ?? 1)),
|
mullionRows: Math.max(1, Math.round(wt.mullionRows ?? 1)),
|
||||||
glazed: true,
|
glazed: true,
|
||||||
glazingPanes: glazingPanesOf(wt),
|
glazingPanes: glazingPanesOf(wt),
|
||||||
|
glazedFraction: 1,
|
||||||
sashes,
|
sashes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -2184,12 +2194,19 @@ function glassPanesForOpening(
|
|||||||
if (n1 <= params.nMin) break;
|
if (n1 <= params.nMin) break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// Teilverglasung (Türen mit glazingRatio < 1): das HAUPTFELD ist nur im oberen
|
||||||
|
// `glazedFraction`-Anteil Glas; darunter bleibt ein blindes Blattfeld. Von der
|
||||||
|
// OBERKANTE des Hauptbands gemessen. Fenster: glazedFraction = 1 (voll).
|
||||||
|
const frac = Math.max(0.05, Math.min(1, params.glazedFraction));
|
||||||
|
const glazedBottom = (bBottom: number, bTop: number) =>
|
||||||
|
bTop - frac * (bTop - bBottom);
|
||||||
if (params.transomHeight > EPS) {
|
if (params.transomHeight > EPS) {
|
||||||
const splitZ = clampRange(vert.zTop - params.transomHeight, sashBottom, sashTopFull);
|
const splitZ = clampRange(vert.zTop - params.transomHeight, sashBottom, sashTopFull);
|
||||||
push(sashBottom, splitZ - fw / 2); // Hauptscheibe/-blatt unterhalb des Kämpfers.
|
const mainTop = splitZ - fw / 2;
|
||||||
push(splitZ + fw / 2, sashTopFull); // Oberlicht-Scheibe oberhalb des Kämpfers.
|
push(glazedBottom(sashBottom, mainTop), mainTop); // Hauptglas (ggf. nur oben).
|
||||||
|
push(splitZ + fw / 2, sashTopFull); // Oberlicht-Scheibe (immer voll).
|
||||||
} else {
|
} else {
|
||||||
push(sashBottom, sashTopFull);
|
push(glazedBottom(sashBottom, sashTopFull), sashTopFull);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user