v0.6.2: dakaansluiting L/T (vleugel met nokdak loopt het hoofddak in met kilkepers, of de kop wordt een schild met hoekkeper; eigen dakdeel en PDF-blad per unit, ook in de kosten), model IJssel (L-vorm met zadeldaken in riet), unit max 4,7 m breed; mansarde vervallen (oude ontwerpen worden een zadeldak met dezelfde nok); gevelbekleding volgt voorbij het wandeinde de daklijn (geen blok meer boven een steil dakvlak) en bij een bolle daklijn per punt de bovenkant van het dak; gevellampen standaard min. 500 mm h.o.h. (geen samengevoegde lamp meer boven een smal raam)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
bd084e4a96
commit
b137a458d4
+6
-26
@@ -1228,7 +1228,7 @@ function mountHouseEditor(container, callbacks) {
|
||||
toggle('hs-roof-house', 'Over hele woning', hr.enabled, { hint: 'Eén dakvorm over alle units (bijv. een grote wolfskap); uit = dak per unit. De daken per unit blijven bewaard.' }) +
|
||||
|
||||
(houseRoofUi ? sel('hs-roof-cover', 'Bedekking', covOpts, RoofModel.coveringFor(state.units[0].roof.covering, shapeType), { hint: 'Voor alle units (per unit aan te passen)' }) : '') +
|
||||
toggle('hs-steel-ridge', 'Stalen nokbalk', state.units.some(u => u.roof.steelRidge !== false), { hint: 'IPE onder de nok van zadel-, mansarde- en wolfsdaken (alle units); uit = verwijderen' }) }
|
||||
toggle('hs-steel-ridge', 'Stalen nokbalk', state.units.some(u => u.roof.steelRidge !== false), { hint: 'IPE onder de nok van zadel- en wolfsdaken (alle units); uit = verwijderen' }) }
|
||||
];
|
||||
if (houseRoofUi) groups.push(...houseRoofUi.groups());
|
||||
else groups.push({ label: 'Dakvorm', html: note('Vorm, hoogtes, helling en bedekking zijn per unit: selecteer een unit.') });
|
||||
@@ -1256,7 +1256,8 @@ function mountHouseEditor(container, callbacks) {
|
||||
const el = body.querySelector('[data-live="roof-list"]');
|
||||
if (!el || !parts) return;
|
||||
el.innerHTML = parts.units.map(u => {
|
||||
const pl = u.roof.planes[0], deg = Math.abs(pl ? pl.theta : 0) * 180 / Math.PI;
|
||||
const pl = u.roof.planes[0], cap = u.roof.unitRoof.cap;
|
||||
const deg = (pl ? Math.abs(pl.theta) : cap ? Math.atan(cap.slope) : 0) * 180 / Math.PI;
|
||||
const cov = (RoofModel.COVERINGS[u.roof.covering] || {}).label || '';
|
||||
return kv(`Unit ${u.id}`, `${(UnitModel.ROOF_TYPES[u.roof.shape.type] || u.roof.shape.type).toLowerCase()}${deg > 0.05 ? ' ' + fmtDeg(deg) + '°' : ''} · ${cov.toLowerCase()}`);
|
||||
}).join('');
|
||||
@@ -1754,10 +1755,6 @@ function mountHouseEditor(container, callbacks) {
|
||||
const LIM = UnitModel.LIMITS;
|
||||
const runOf = () => UnitModel.hasRidge(form.type) ? o.span() / 2 : o.span();
|
||||
const degOf = () => sloped() ? Math.atan(Math.max(0, form.high - form.low) / runOf()) * 180 / Math.PI : 0;
|
||||
const mansardeDeg = () => {
|
||||
const kIn = Math.max(1, form.kneeIn || 1), rest = Math.max(1, runOf() - kIn);
|
||||
return [Math.atan(Math.max(0, form.kneeH - form.low) / kIn), Math.atan(Math.max(0, form.high - form.kneeH) / rest)].map(r => r * 180 / Math.PI);
|
||||
};
|
||||
const f = (k) => `${id}-roof-${k}`;
|
||||
const groups = () => {
|
||||
const g = [
|
||||
@@ -1768,12 +1765,8 @@ function mountHouseEditor(container, callbacks) {
|
||||
];
|
||||
if (sloped()) g.push({ label: 'Helling', html:
|
||||
UI.range(f('high'), UnitModel.hasRidge(form.type) ? 'Nok' : 'Hoog', form.high, { min: 2100, max: LIM.ridge, step: 10, hint: `Max ${LIM.ridge} mm` }) +
|
||||
(form.type === 'mansarde' ? '' : UI.range(f('deg'), 'Helling', Math.round(degOf() * 10) / 10, { min: 1, max: 60, step: 0.5, unit: '°', hint: 'Zet de hoge zijde/nok bij de huidige goothoogte' })) +
|
||||
UI.range(f('deg'), 'Helling', Math.round(degOf() * 10) / 10, { min: 1, max: 60, step: 0.5, unit: '°', hint: 'Zet de hoge zijde/nok bij de huidige goothoogte' }) +
|
||||
(o.gable ? `<div data-live="roof-gable">${kv('Kopgevel', `wand ${SIDE_SHORT[UnitModel.gableOf(form)].toLowerCase()} + overstaande`)}</div>` : '') });
|
||||
if (form.type === 'mansarde') g.push({ label: 'Mansarde', html:
|
||||
UI.range(f('knee-h'), 'Knik', form.kneeH, { min: 2100, max: LIM.ridge, step: 10, hint: 'Hoogte van de knik tussen het steile en het flauwe dakvlak' }) +
|
||||
UI.range(f('knee-in'), 'Knik in', form.kneeIn, { min: 100, max: 3000, step: 10, hint: 'Horizontale afstand van de gevel tot de knik' }) +
|
||||
`<div data-live="roof-mansarde">${kv('Hellingen', mansardeDeg().map(d => fmtDeg(d) + '°').join(' / '))}</div>` });
|
||||
if (form.type === 'wolf') g.push({ label: 'Wolfsdak', html:
|
||||
UI.range(f('cut'), 'Wolfseind', form.cut, { min: 2100, max: LIM.ridge, step: 10, hint: 'Hoogte waarop de kopgevels stoppen; daarboven driehoekige wolfseinden met de dakhelling tot de nok' }) });
|
||||
return g;
|
||||
@@ -1789,13 +1782,6 @@ function mountHouseEditor(container, callbacks) {
|
||||
if (v !== 'plat' && !(form.high > form.low)) form.high = form.low + 700;
|
||||
if (v === 'lessenaar' && !form.dir) form.dir = 'voor';
|
||||
if (UnitModel.hasRidge(v) && !form.ridge) form.ridge = 'z';
|
||||
if (v === 'mansarde') {
|
||||
const run = runOf();
|
||||
form.kneeIn = Math.round(run * 0.35);
|
||||
form.kneeH = Math.round(form.low + form.kneeIn * 2.1);
|
||||
form.high = Math.min(LIM.ridge, Math.max(form.high, Math.round(form.kneeH + (run - form.kneeIn) * 0.5)));
|
||||
form.kneeRatio = Math.min(0.9, (form.kneeH - form.low) / (form.high - form.low));
|
||||
}
|
||||
if (v === 'wolf') {
|
||||
if (form.high - form.low < 1000) form.high = form.low + 1500;
|
||||
form.cutRatio = 0.6;
|
||||
@@ -1806,13 +1792,9 @@ function mountHouseEditor(container, callbacks) {
|
||||
UI.onSel(f('ridge'), v => { form.ridge = v; apply(); }, rerender);
|
||||
const syncDeg = () => {
|
||||
const now = o.readBack();
|
||||
if (now && now.type === form.type) ['kneeH', 'kneeIn', 'cut'].forEach(k => { if (now[k] !== undefined) form[k] = now[k]; });
|
||||
if (now && now.type === form.type) ['cut'].forEach(k => { if (now[k] !== undefined) form[k] = now[k]; });
|
||||
UI.setRange(f('deg'), Math.round(degOf() * 10) / 10);
|
||||
UI.setRange(f('knee-h'), form.kneeH);
|
||||
UI.setRange(f('knee-in'), form.kneeIn);
|
||||
UI.setRange(f('cut'), form.cut);
|
||||
const md = body.querySelector('[data-live="roof-mansarde"]');
|
||||
if (md && form.type === 'mansarde') md.innerHTML = kv('Hellingen', mansardeDeg().map(d => fmtDeg(d) + '°').join(' / '));
|
||||
};
|
||||
UI.onRange(f('low'), v => {
|
||||
if (!(v >= 500)) return;
|
||||
@@ -1832,8 +1814,6 @@ function mountHouseEditor(container, callbacks) {
|
||||
apply(); syncDeg();
|
||||
}, after);
|
||||
const ratioOf = (v) => Math.max(0.05, Math.min(0.95, (v - form.low) / Math.max(1, form.high - form.low)));
|
||||
UI.onRange(f('knee-h'), v => { if (v >= 500) { form.kneeRatio = ratioOf(v); apply(); syncDeg(); } }, after);
|
||||
UI.onRange(f('knee-in'), v => { if (v >= 50) { form.kneeIn = v; apply(); syncDeg(); } }, after);
|
||||
UI.onRange(f('cut'), v => { if (v >= 500) { form.cutRatio = ratioOf(v); apply(); syncDeg(); } }, after);
|
||||
};
|
||||
return { groups, wire };
|
||||
@@ -1877,7 +1857,7 @@ function mountHouseEditor(container, callbacks) {
|
||||
pair(sel('hp-roof-cover', 'Bedekking', covOpts, covNow, { hint: shapeNow === 'plat' ? 'Riet en felsplaten alleen bij een hellend dak' : `${c.thickMM} mm, ${String(c.kgM2).replace('.', ',')} kg/m²` }),
|
||||
thumb(RoofModel.coveringThumbUrl(covNow, 64), c.label)) +
|
||||
toggle('hp-fascia', 'Boeidelen', u.roof.fascia !== false, { hint: 'Uit = daktrim' }) +
|
||||
(pu && pu.roof.unitRoof.ridgeBeam || u.roof.steelRidge === false && ['zadel', 'mansarde', 'wolf'].includes(shapeNow)
|
||||
(pu && pu.roof.unitRoof.ridgeBeam || u.roof.steelRidge === false && ['zadel', 'wolf'].includes(shapeNow)
|
||||
? toggle('hp-steel-ridge', 'Stalen nokbalk', u.roof.steelRidge !== false, { hint: pu && pu.roof.unitRoof.ridgeBeam ? `${pu.roof.unitRoof.ridgeBeam.profile.name}, ${Math.round(pu.roof.unitRoof.ridgeBeam.steelKg)} kg; uit = verwijderen` : 'Uit = verwijderd' }) : '') +
|
||||
toggle('hp-roof-follow', 'Maat volgt vloer', u.roof.followFloor) });
|
||||
if (!u.roof.followFloor) groups.push({ label: 'Dakmaat', html:
|
||||
|
||||
Reference in New Issue
Block a user