v0.4.17: openingen met schuine bovenzijde (hoogte links/rechts, volg dakhelling), 9 sleeppunten in het vooraanzicht; regelwerk, beplating, doek, steen en latwerk volgen de schuinte (columnMinusRects met schuine uitsparingen)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
23bfe153a2
commit
8cdfa21f46
@@ -681,8 +681,10 @@ window.HouseModel = (() => {
|
||||
const ops = firstConfig.openings.map(op => {
|
||||
const wa = UnitModel.localToWorld(first.place, -first.place.width / 2 + op.x, 0);
|
||||
const wb = UnitModel.localToWorld(first.place, -first.place.width / 2 + op.x + op.w, 0);
|
||||
const u = Math.min(toLocalU(lf.place, wa), toLocalU(lf.place, wb));
|
||||
return { id: op.id, type: op.type, w: op.w, h: op.h, y: op.y, anchor: 'left', offset: Math.round(u) };
|
||||
const ua = toLocalU(lf.place, wa), ub = toLocalU(lf.place, wb);
|
||||
// Gespiegeld (andere kijkrichting): schuine bovenzijde klapt om.
|
||||
const flip = ua > ub;
|
||||
return { id: op.id, type: op.type, w: op.w, h: flip ? op.hR : op.h, hR: flip ? op.h : op.hR, y: op.y, anchor: 'left', offset: Math.round(Math.min(ua, ub)) };
|
||||
});
|
||||
config = WallModel.buildConfig(paramsOf(lf), ops);
|
||||
}
|
||||
@@ -827,11 +829,11 @@ window.HouseModel = (() => {
|
||||
const poly = [{ x: -W / 2, y: y0 }, { x: W / 2, y: y0 }, ...tl.pts.slice().reverse()];
|
||||
return Math.max(0, polygonArea(poly)) + (p.skinAbove || 0) * W;
|
||||
};
|
||||
const openingsMM2 = (p) => (p.config.openings || []).reduce((a, op) => a + op.w * op.h, 0);
|
||||
const openingsMM2 = (p) => (p.config.openings || []).reduce((a, op) => a + WallModel.openingArea(op), 0);
|
||||
const facadePieces = ext.concat(parts.interior.filter(p => p.skinFrom !== undefined));
|
||||
const gevelBruto = facadePieces.reduce((a, p) => a + wallArea(p, p.skinFrom || 0), 0);
|
||||
const gevelOpen = ext.reduce((a, p) => a + openingsMM2(p), 0);
|
||||
const glas = ext.reduce((a, p) => a + (p.config.openings || []).filter(op => op.type === 'raam').reduce((b, op) => b + op.w * op.h, 0), 0);
|
||||
const glas = ext.reduce((a, p) => a + (p.config.openings || []).filter(op => op.type === 'raam').reduce((b, op) => b + WallModel.openingArea(op), 0), 0);
|
||||
const binnen = all.reduce((a, p) => a + ((p.stats && p.stats.spaanplaatAreaM2) || 0) + ((p.stats && p.stats.spaanplaatBuitenAreaM2) || 0), 0);
|
||||
const dakM2 = parts.units.reduce((a, u) => a + (u.roof.specs.dakleerM2 || 0) + (u.roof.specs.rietM2 || 0), 0);
|
||||
const dakPlanMM2 = parts.units.reduce((a, u) => a + u.roof.rect.W * u.roof.rect.D, 0);
|
||||
|
||||
@@ -229,10 +229,12 @@ window.HousePdf = (() => {
|
||||
}
|
||||
// Openingen (glas / deur), vóór de gevel
|
||||
(p.config.openings || []).forEach(op => {
|
||||
if (op.y + op.h <= y0) return;
|
||||
const x0 = -p.place.width / 2 + op.x, x1 = x0 + op.w, ya = Math.max(y0, op.y), yb = op.y + op.h;
|
||||
if (WallModel.openingTopMax(op) <= y0) return;
|
||||
// Schuine bovenzijde: bovenkant links/rechts.
|
||||
const x0 = -p.place.width / 2 + op.x, x1 = x0 + op.w, ya = Math.max(y0, op.y);
|
||||
const ybL = Math.max(ya, op.y + op.h), ybR = Math.max(ya, op.y + op.hR);
|
||||
const color = op.type === 'raam' ? VIEW_COLORS.glas : VIEW_COLORS.deur;
|
||||
faces.push({ pts: [[x0, ya], [x1, ya], [x1, yb], [x0, yb]].map(([lx, ly]) => toWorld(p, lx, ly, zOut)), n, color, bias: 2, window: true });
|
||||
faces.push({ pts: [[x0, ya], [x1, ya], [x1, ybR], [x0, ybL]].map(([lx, ly]) => toWorld(p, lx, ly, zOut)), n, color, bias: 2, window: true });
|
||||
});
|
||||
};
|
||||
parts.units.forEach(u => u.walls.forEach(w => w.pieces.forEach(p => addWall(p, 0))));
|
||||
|
||||
+3
-3
@@ -350,8 +350,8 @@ function mountHouseEditor(container, callbacks) {
|
||||
}
|
||||
const e = p.skinExt || {};
|
||||
const xL = -W / 2 - (e.left > 0 ? e.left + out : 0), xR = W / 2 + (e.right > 0 ? e.right + out : 0);
|
||||
const gaps = p.config.openings.filter(op => op.y < y && op.y + op.h > y)
|
||||
.map(op => [-W / 2 + op.x, -W / 2 + op.x + op.w]).sort((a, b) => a[0] - b[0]);
|
||||
const gaps = p.config.openings.map(op => WallModel.openingSpanAtY(op, y)).filter(Boolean)
|
||||
.map(([a, b]) => [-W / 2 + a, -W / 2 + b]).sort((a, b) => a[0] - b[0]);
|
||||
const spans = [];
|
||||
let cur = xL;
|
||||
gaps.forEach(([a, b]) => { if (a > cur) spans.push([cur, Math.min(a, xR)]); cur = Math.max(cur, b); });
|
||||
@@ -1118,7 +1118,7 @@ function mountHouseEditor(container, callbacks) {
|
||||
const out = p.place.normal ? WallModel.claddingOffset(p.buitenMateriaal, p.stone) : 0;
|
||||
if (lz < -T / 2 - WALK_RADIUS || lz > T / 2 + out + WALK_RADIUS || Math.abs(lx) > W / 2 + WALK_RADIUS) return false;
|
||||
// Door een deur(opening) mag je lopen.
|
||||
return !(p.config.openings || []).some(op => op.y < 100 && op.y + op.h > 1800 &&
|
||||
return !(p.config.openings || []).some(op => op.y < 100 && op.y + Math.min(op.h, op.hR) > 1800 &&
|
||||
lx > -W / 2 + op.x + WALK_RADIUS * 0.6 && lx < -W / 2 + op.x + op.w - WALK_RADIUS * 0.6);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user