v0.4.15: gevelbekleding per woning (rabat/steen, override per wand), stenen trasraam (110 mm, 181 texturen), riet per unit, vloerafwerking, verfkleur binnen, boeideelkleur, gevel tot onder dakrand, binnenhoek-fixes; testontwerp als standaard
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7d91416004
commit
12c2579471
+129
-19
@@ -60,12 +60,23 @@ window.HouseModel = (() => {
|
||||
function createDefaultSettings() {
|
||||
return {
|
||||
spacing: { exterior: { min: 240, max: 480 }, interior: { min: 300, max: 600 } },
|
||||
cladding: 'horizontaal', // richting gevelbekleding, voorlopig voor alle buitenwanden
|
||||
// Gevelbekleding van alle buitenwanden (override per wand: unit.facade):
|
||||
// rabat = vochtdoek + kruislat + rabat (richting: cladding);
|
||||
// steen = cement-gebonden plaat + steenblok (stone = steencode, WallModel.STONE).
|
||||
// Het trasraam (eigen afwerking/steen) komt onder beide.
|
||||
facade: { type: 'rabat', stone: 'K490' },
|
||||
cladding: 'horizontaal', // richting rabat, voorlopig voor alle buitenwanden
|
||||
// Trasraam: cement-gebonden plaat onderaan alle vochtdoek-gevels, hoogte
|
||||
// vanaf het beloopbare vloervlak (WallModel.trasraamFor).
|
||||
trasraam: { enabled: true, height: WallModel.TRASRAAM_DEFAULT_MM },
|
||||
// finish: 'cementplaat' of een steencode (WallModel.TRASRAAM_STONES).
|
||||
trasraam: { enabled: true, height: WallModel.TRASRAAM_DEFAULT_MM, finish: 'cementplaat' },
|
||||
// Binnenzijde van alle wanden (voorlopig globaal): geschilderd in
|
||||
// interiorColor (egaal, zonder plaatnaden) of kale spaanplaat.
|
||||
interiorPaint: true,
|
||||
interiorColor: '#f2efe9',
|
||||
sandwich: true, // sandwichpanelen rondom (SandwichModel), vanaf loopvlak 600 mm de grond in
|
||||
groundLevel: 350, // maaiveld: zoveel mm onder het loopvlak (bovenkant vloer); voor de 3D-omgeving
|
||||
groundLevel: 0, // maaiveld: zoveel mm onder het loopvlak (bovenkant vloer); voor de 3D-omgeving
|
||||
floorFinish: 'visgraat_001', // vloerafwerking (FloorModel.FINISHES), voorlopig globaal
|
||||
roof: Object.assign({}, RoofModel.DEFAULT_SETTINGS),
|
||||
lighting: Object.assign({}, LightingModel.DEFAULT_SETTINGS)
|
||||
};
|
||||
@@ -73,10 +84,35 @@ window.HouseModel = (() => {
|
||||
|
||||
function createUnitEntry(id, attach, unitOpts) {
|
||||
const unit = UnitModel.createDefaultState(unitOpts);
|
||||
return { id, attach, unit, roof: RoofModel.createDefaultRoof(unit.floor), lighting: LightingModel.createDefaultUnitLighting() };
|
||||
return { id, attach, unit, roof: RoofModel.createDefaultRoof(unit.floor), lighting: LightingModel.createDefaultUnitLighting(), facade: { walls: {} } };
|
||||
}
|
||||
|
||||
// Gevelbekleding: keuze voor de woning, override per wand.
|
||||
const FACADE_TYPES = { rabat: 'Rabat', steen: 'Steen' };
|
||||
// { type, stone } voor één wand van een unit (u = entry uit state.units).
|
||||
function facadeFor(state, u, side) {
|
||||
const f = state.settings.facade;
|
||||
const o = (u.facade && u.facade.walls && u.facade.walls[side]) || null;
|
||||
const type = o && FACADE_TYPES[o.type] ? o.type : f.type;
|
||||
const stone = o && o.type === 'steen' && WallModel.isStoneFinish(o.stone) ? o.stone : f.stone;
|
||||
return { type, stone, override: !!o };
|
||||
}
|
||||
|
||||
// TIJDELIJK (testen): een nieuwe woning is standaard het testontwerp:
|
||||
// L-vorm, unit A lessenaar (noord 2600, zuid 3200) met riet. Op false
|
||||
// zetten om terug te gaan naar de gewone standaard (één unit).
|
||||
const TEST_DEFAULT = true;
|
||||
|
||||
function createDefaultState(template) {
|
||||
if (TEST_DEFAULT && (!template || template === 'single')) {
|
||||
const st = createDefaultState('L');
|
||||
const A = st.units[0], W = A.unit.walls;
|
||||
const h = (k, l, r) => Object.assign(W[k].wall, { heightAll: Math.min(l, r), heightLeft: l, heightRight: r, heightMid: null });
|
||||
h('achter', 3200, 3200); h('links', 2600, 3200); h('rechts', 3200, 2600);
|
||||
A.roof.covering = 'riet_001';
|
||||
computeParts(st, { skip3D: true });
|
||||
return st;
|
||||
}
|
||||
const state = { project: createEmptyProject(), settings: createDefaultSettings(), units: [], interiorWalls: [] };
|
||||
state.units.push(createUnitEntry('A', null, { width: 6000, depth: 3000 }));
|
||||
if (template === 'L') {
|
||||
@@ -282,11 +318,14 @@ window.HouseModel = (() => {
|
||||
const sp = state.settings.spacing;
|
||||
const tr = state.settings.trasraam;
|
||||
state.units.forEach(u => {
|
||||
const trasraam = tr.enabled ? WallModel.trasraamFor(tr.height) : null;
|
||||
Object.values(u.unit.walls).forEach(ws => {
|
||||
const trasraam = tr.enabled ? WallModel.trasraamFor(tr.height, tr.finish) : null;
|
||||
Object.entries(u.unit.walls).forEach(([side, ws]) => {
|
||||
ws.wall.minSpacing = sp.exterior.min;
|
||||
ws.wall.maxSpacing = sp.exterior.max;
|
||||
ws.materials = Object.assign({}, ws.materials, { cladding: state.settings.cladding, trasraam });
|
||||
const fc = facadeFor(state, u, side);
|
||||
ws.materials = Object.assign({}, ws.materials, fc.type === 'steen'
|
||||
? { exterior: 'cementplaat', stone: fc.stone, cladding: state.settings.cladding, trasraam }
|
||||
: { exterior: 'vochtdoek', stone: null, cladding: state.settings.cladding, trasraam });
|
||||
});
|
||||
if (u.roof.followFloor) {
|
||||
u.roof.deck.floor.width = u.unit.floor.floor.width;
|
||||
@@ -310,14 +349,22 @@ window.HouseModel = (() => {
|
||||
const W = p.place.width, T = p.place.thickness;
|
||||
const normal = { x: p.place.normal.x, z: p.place.normal.y };
|
||||
const axis = Math.abs(normal.z) > 0.5 ? 'x' : 'z', perp = axis === 'x' ? 'z' : 'x';
|
||||
const q0 = UnitModel.localToWorld(p.place, -W / 2, T / 2), q1 = UnitModel.localToWorld(p.place, W / 2, T / 2);
|
||||
segs.push({ piece: p, axis, normal, line: q0[perp], sAt0: q0[axis], sAtW: q1[axis], s0: Math.min(q0[axis], q1[axis]), s1: Math.max(q0[axis], q1[axis]) });
|
||||
// Binnenhoek-doorloop (negatieve skinExt, zie trimTop): zit dat stuk
|
||||
// over de hele hoogte in de buur-unit, dan begint de gevel pas daarna.
|
||||
// Loopt de gevel erboven door (lager dak van de buur), dan telt het
|
||||
// hele stuk mee, zodat de gevel één geheel blijft met de rest.
|
||||
const e = p.skinExt || {}, tt = p.trimTop || {};
|
||||
const maxY = WallModel.topLine(p.config).maxY + (p.skinAbove || 0);
|
||||
const trim = (k) => e[k] < 0 && !(tt[k] > 0 && tt[k] < maxY - 1) ? -e[k] : 0;
|
||||
const tL = trim('left'), tR = trim('right');
|
||||
const q0 = UnitModel.localToWorld(p.place, -W / 2 + tL, T / 2), q1 = UnitModel.localToWorld(p.place, W / 2 - tR, T / 2);
|
||||
segs.push({ piece: p, trimL: tL, axis, normal, line: q0[perp], sAt0: q0[axis], sAtW: q1[axis], s0: Math.min(q0[axis], q1[axis]), s1: Math.max(q0[axis], q1[axis]) });
|
||||
});
|
||||
groupFacadeRuns(segs).forEach(run => {
|
||||
const dir = Math.sign(run.segs[0].sAtW - run.segs[0].sAt0) || 1;
|
||||
const sLeft = dir > 0 ? run.s0 : run.s1, sRight = dir > 0 ? run.s1 : run.s0;
|
||||
const first = run.segs.reduce((best, sg) => Math.abs(sg.sAt0 - sLeft) < Math.abs(best.sAt0 - sLeft) ? sg : best);
|
||||
const extLeft = (first.piece.skinExt && first.piece.skinExt.left) || 0;
|
||||
const extLeft = Math.max(0, (first.piece.skinExt && first.piece.skinExt.left) || 0);
|
||||
// Horizontaal latten-raster: vanaf het trasraam van een gewoon stuk
|
||||
// (absolute hoogte), zodat opbouw/naadwand-stukken erop aansluiten.
|
||||
const ref = run.segs.find(sg => !sg.piece.place.baseY && sg.piece.skinFrom === undefined);
|
||||
@@ -326,7 +373,7 @@ window.HouseModel = (() => {
|
||||
run.segs.forEach(sg => {
|
||||
const p = sg.piece;
|
||||
sg.piece.facade = {
|
||||
u0: Math.abs(sg.sAt0 - sLeft) + extLeft, extStart: extLeft > 0, isEnd: Math.abs(sg.sAtW - sRight) < 5,
|
||||
u0: Math.abs(sg.sAt0 - sLeft) + extLeft - sg.trimL, extStart: extLeft > 0, isEnd: Math.abs(sg.sAtW - sRight) < 5,
|
||||
gridY0: gridAbs === undefined ? undefined : gridAbs - p.place.floorTop,
|
||||
yOff: floorAbs === undefined ? 0 : p.place.floorTop - floorAbs
|
||||
};
|
||||
@@ -344,10 +391,11 @@ window.HouseModel = (() => {
|
||||
const wallThickness = (id, side) => WallModel.thicknessOf(WallModel.configFromState(state.units.find(u => u.id === id).unit.walls[side]));
|
||||
const { cuts, seams } = computeSeams(rects, wallThickness);
|
||||
|
||||
function buildWall(config, frame, buitenMateriaal, cladding, trasraam, skinExt, facade, skinFrom, spaanplaatBelow) {
|
||||
function buildWall(config, frame, buitenMateriaal, cladding, trasraam, skinExt, facade, skinFrom, spaanplaatBelow, stone, skinAbove, trimTop) {
|
||||
if (!build) return { group: null, stats: null, specs: null };
|
||||
const built = WallModel.build3D(config, frame, {
|
||||
materials: o.wallMaterials, buitenMateriaal, cladding, trasraam, skinExt, facade, skinFrom, spaanplaatBelow,
|
||||
materials: o.wallMaterials, buitenMateriaal, cladding, trasraam, skinExt, facade, skinFrom, spaanplaatBelow, stone, skinAbove, trimTop,
|
||||
painted: state.settings.interiorPaint,
|
||||
spaanplaatVisible: o.beplatingVisible !== false, buitenVisible: o.beplatingVisible !== false
|
||||
});
|
||||
return { group: built.group, stats: built.stats, specs: WallModel.computeSpecs(config, built.stats, buitenMateriaal) };
|
||||
@@ -360,7 +408,8 @@ window.HouseModel = (() => {
|
||||
const ws = u.unit.walls[wl.side];
|
||||
const buitenMateriaal = (ws.materials || {}).exterior || 'vochtdoek';
|
||||
const cladding = (ws.materials || {}).cladding || 'horizontaal';
|
||||
const trasraam = buitenMateriaal === 'vochtdoek' ? ((ws.materials || {}).trasraam || null) : null;
|
||||
const stone = buitenMateriaal === 'cementplaat' ? ((ws.materials || {}).stone || null) : null;
|
||||
const trasraam = buitenMateriaal === 'vochtdoek' || stone ? ((ws.materials || {}).trasraam || null) : null;
|
||||
const wp = UnitModel.wallPieces(wl, ws, raised);
|
||||
const pieces = wp.pieces.map(p => {
|
||||
const c = UnitModel.localToWorld(wl, p.lxCenter, 0);
|
||||
@@ -368,7 +417,7 @@ window.HouseModel = (() => {
|
||||
return Object.assign(p, {
|
||||
element: `${u.id}-W${wl.nr}${p.suffix}`,
|
||||
label: `Unit ${u.id} ${wl.label.toLowerCase()}` + (base ? ` opbouw (vanaf ${base} mm)` : p.suffix ? ` (${p.suffix})` : ''),
|
||||
buitenMateriaal, cladding, trasraam: base ? null : trasraam,
|
||||
buitenMateriaal, cladding, trasraam: base ? null : trasraam, stone,
|
||||
place: { cx: rect.cx + c.x, cz: rect.cz + c.z, rotY: wl.rotY, width: p.config.wallWidth, thickness: wl.thickness, normal: wl.normal, floorTop: layout.floorTop + base, baseY: base }
|
||||
}); // 3D volgt na assignFacades (latwerk/doek per gevel)
|
||||
});
|
||||
@@ -394,7 +443,8 @@ window.HouseModel = (() => {
|
||||
const floorData = FloorModel.computeFromState(u.unit.floor, rims);
|
||||
const floorSpecs = FloorModel.computeSpecs(floorData.calcData, floorData.resolvedOpenings);
|
||||
const floorGroup = build ? FloorModel.build3D(floorData.calcData, floorData.resolvedOpenings, floorData.chassisData, {
|
||||
materials: o.floorMaterials, osbVisible: o.beplatingVisible !== false
|
||||
materials: o.floorMaterials, osbVisible: o.beplatingVisible !== false,
|
||||
finish: { key: state.settings.floorFinish, originX: rect.cx * 0.001, originZ: rect.cz * 0.001 }
|
||||
}) : null;
|
||||
|
||||
const walls = layout.walls.map(wl => wallOf(u, rect, layout, wl));
|
||||
@@ -643,9 +693,35 @@ window.HouseModel = (() => {
|
||||
// over het blootliggende deel van een naadwand. Daarna pas bouwen.
|
||||
const extPieces = [];
|
||||
units.forEach(u => u.walls.forEach(w => w.pieces.forEach(p => extPieces.push(p))));
|
||||
// Gevel tot onder de dakrand: tussen wandbovenkant en onderkant boeideel
|
||||
// resp. daktrim zit het dakpakket (dek + bedekking, verschilt per dak).
|
||||
// De buitenlagen van de wand lopen daar door (skinAbove, mm), zodat er
|
||||
// geen dakrand bloot ligt, bij elke daksoort.
|
||||
const roofSt = RoofModel.normalizeSettings(state.settings.roof);
|
||||
const flatTopsPre = units.filter(u => u.roof.shape.type === 'plat').map(u => u.roof.top);
|
||||
const flatTopPre = flatTopsPre.length ? Math.max(...flatTopsPre) : 0;
|
||||
units.forEach(u => {
|
||||
const su = state.units.find(x => x.id === u.id);
|
||||
const below = su.roof.fascia !== false ? roofSt.fasciaHeight - RoofModel.EDGE_ABOVE_MM : roofSt.trimHeight;
|
||||
u.walls.forEach(w => w.pieces.forEach(p => {
|
||||
const m = UnitModel.localToWorld(p.place, 0, p.place.thickness / 2);
|
||||
const top = u.roof.shape.type === 'plat' ? flatTopPre : u.roof.topAt(m.x, m.z);
|
||||
p.skinAbove = Math.max(0, Math.round(top - u.roof.ceilingAt(m.x, m.z) - below));
|
||||
// Binnenhoek-doorloop (negatieve skinExt): tot de bovenkant van het
|
||||
// dak van de buur-unit die daar staat geen buitenlagen (trimTop).
|
||||
const e = p.skinExt || {}, W = p.place.width;
|
||||
p.trimTop = {};
|
||||
[['left', -1], ['right', 1]].forEach(([k, d]) => {
|
||||
if (!(e[k] < 0)) return;
|
||||
const q = UnitModel.localToWorld(p.place, d * (W / 2 + e[k] / 2), p.place.thickness / 2 + 20);
|
||||
const nb = units.find(o => o.id !== u.id && q.x > o.rect.x0 && q.x < o.rect.x1 && q.z > o.rect.z0 && q.z < o.rect.z1);
|
||||
p.trimTop[k] = nb ? Math.round(nb.roof.topAt(q.x, q.z) - p.place.floorTop) : 0;
|
||||
});
|
||||
}));
|
||||
});
|
||||
assignFacades(extPieces.concat(interior.filter(p => p.skinFrom !== undefined)));
|
||||
extPieces.concat(interior).forEach(p => {
|
||||
const built = buildWall(p.config, p.frame, p.buitenMateriaal, p.cladding, p.trasraam, p.skinExt, p.facade, p.skinFrom, p.spaanplaatBelow);
|
||||
const built = buildWall(p.config, p.frame, p.buitenMateriaal, p.cladding, p.trasraam, p.skinExt, p.facade, p.skinFrom, p.spaanplaatBelow, p.stone, p.skinAbove, p.trimTop);
|
||||
if (built.group && p.shiftZ) {
|
||||
const outer = new THREE.Group();
|
||||
built.group.position.z = p.shiftZ * 0.001;
|
||||
@@ -725,6 +801,9 @@ window.HouseModel = (() => {
|
||||
const purchase = WallModel.planPurchase(wallBom);
|
||||
|
||||
const sumP = (fn) => pieces.reduce((acc, p) => acc + fn(p), 0);
|
||||
const stonePiece = pieces.find(p => p.trasraam && WallModel.isStoneFinish(p.trasraam.finish));
|
||||
const stoneCode = stonePiece ? stonePiece.trasraam.finish : null;
|
||||
const stoneCodes = [...new Set(pieces.filter(p => p.stone).map(p => p.stone))].join(', ');
|
||||
const sumU = (fn) => parts.units.reduce((acc, u) => acc + fn(u), 0);
|
||||
const byMat = (mat) => pieces.filter(p => p.buitenMateriaal === mat);
|
||||
|
||||
@@ -762,10 +841,24 @@ window.HouseModel = (() => {
|
||||
},
|
||||
{ naam: 'OSB-plaat (vloeren + plafonds dak)', m2: sumU(u => u.floorSpecs.osbAreaM2 + u.roof.specs.osbAreaM2), m3: sumU(u => u.floorSpecs.osbVolM3 + u.roof.specs.osbVolM3), kg: sumU(u => u.floorSpecs.osbKg + u.roof.specs.osbKg) },
|
||||
{ naam: 'Dakleer (EPDM)', m2: sumU(u => u.roof.specs.dakleerM2), m3: null, kg: sumU(u => u.roof.specs.dakleerKg) },
|
||||
{ naam: `Riet (${RoofModel.RIET.thickMM} mm)`, m2: sumU(u => u.roof.specs.rietM2 || 0), m3: null, kg: sumU(u => u.roof.specs.rietKg || 0) },
|
||||
{
|
||||
naam: 'Cementplaat (buitenzijde)', m2: byMat('cementplaat').reduce((a, p) => a + p.stats.cementplaatAreaM2, 0),
|
||||
m3: byMat('cementplaat').reduce((a, p) => a + p.stats.cementplaatVolumeM3, 0), kg: byMat('cementplaat').reduce((a, p) => a + p.specs.buitenKg, 0)
|
||||
},
|
||||
{
|
||||
naam: `Steenstrips gevel${stoneCodes ? ' (' + stoneCodes + ')' : ''}`,
|
||||
m2: sumP(p => p.stats.stoneAreaM2 || 0), m3: null, kg: 0 // gewicht volgt
|
||||
},
|
||||
{
|
||||
naam: `Steenstrips trasraam${stoneCode ? ' (' + stoneCode + ')' : ''}`,
|
||||
m2: sumP(p => p.stats.trasraamStoneAreaM2 || 0), m3: null, kg: 0 // gewicht volgt
|
||||
},
|
||||
{
|
||||
naam: `Isolatieblok steen (${WallModel.STONE.THICK_MM - WallModel.STONE.STRIP_MM} mm)`,
|
||||
m2: sumP(p => (p.stats.trasraamIsolatieM3 || 0) + (p.stats.stoneIsolatieM3 || 0)) / ((WallModel.STONE.THICK_MM - WallModel.STONE.STRIP_MM) / 1000),
|
||||
m3: sumP(p => (p.stats.trasraamIsolatieM3 || 0) + (p.stats.stoneIsolatieM3 || 0)), kg: 0
|
||||
},
|
||||
{
|
||||
naam: 'Cementplaat (trasraam)', m2: sumP(p => p.stats.trasraamAreaM2 || 0),
|
||||
m3: sumP(p => p.stats.trasraamVolumeM3 || 0), kg: sumP(p => p.specs.trasraamKg || 0)
|
||||
@@ -784,6 +877,7 @@ window.HouseModel = (() => {
|
||||
roofEdge: parts.roofEdge ? {
|
||||
fasciaLengthM: parts.roofEdge.fasciaLengthMM / 1000,
|
||||
fasciaHeight: parts.roofEdge.fasciaHeight,
|
||||
fasciaColor: (RoofModel.FASCIA_COLORS[parts.roofEdge.fasciaColor] || {}).label || '',
|
||||
overhang: parts.roofEdge.overhang,
|
||||
soffitM2: parts.roofEdge.soffitM2,
|
||||
trimLengthM: parts.roofEdge.trimLengthMM / 1000,
|
||||
@@ -837,11 +931,22 @@ window.HouseModel = (() => {
|
||||
state.settings = state.settings || {};
|
||||
state.settings.spacing = Object.assign(def.spacing, state.settings.spacing || {});
|
||||
if (!WallModel.CLADDING_DIRECTIONS[state.settings.cladding]) state.settings.cladding = def.cladding;
|
||||
// v0.4.15: gevelbekleding per woning; een wand met cementplaat wordt een
|
||||
// steen-override (de rest volgt de woning, standaard rabat).
|
||||
const hadFacade = !!state.settings.facade;
|
||||
state.settings.facade = Object.assign(def.facade, state.settings.facade || {});
|
||||
if (!FACADE_TYPES[state.settings.facade.type]) state.settings.facade.type = 'rabat';
|
||||
if (!WallModel.isStoneFinish(state.settings.facade.stone)) state.settings.facade.stone = def.facade.stone;
|
||||
state.settings.trasraam = Object.assign(def.trasraam, state.settings.trasraam || {});
|
||||
state.settings.trasraam.enabled = state.settings.trasraam.enabled !== false;
|
||||
if (!(state.settings.trasraam.height > 0)) state.settings.trasraam.height = WallModel.TRASRAAM_DEFAULT_MM;
|
||||
if (!WallModel.isStoneFinish(state.settings.trasraam.finish)) state.settings.trasraam.finish = 'cementplaat';
|
||||
state.settings.sandwich = state.settings.sandwich !== false;
|
||||
if (!(state.settings.groundLevel >= 0)) state.settings.groundLevel = def.groundLevel;
|
||||
if (!/^#[0-9a-f]{6}$/i.test(state.settings.interiorColor || '')) state.settings.interiorColor = def.interiorColor;
|
||||
state.settings.interiorPaint = state.settings.interiorPaint !== false;
|
||||
// v0.4.15: maaiveld standaard gelijk met de bovenkant vloer (was 350 mm eronder).
|
||||
if (!(state.settings.groundLevel >= 0) || (!state.settings.floorFinish && state.settings.groundLevel === 350)) state.settings.groundLevel = def.groundLevel;
|
||||
if (!FloorModel.FINISHES[state.settings.floorFinish]) state.settings.floorFinish = def.floorFinish;
|
||||
const oldRoof = state.settings.roof || {}; // v0.3.0: edge/spots waren woning-breed
|
||||
state.settings.roof = RoofModel.normalizeSettings(oldRoof);
|
||||
// v0.3.1: type/richting van de verlichting stonden per unit; nu woning-breed.
|
||||
@@ -854,13 +959,18 @@ window.HouseModel = (() => {
|
||||
if (!u.unit.layout) u.unit.layout = { corners: 'voor-achter' };
|
||||
if (!u.roof) { u.roof = RoofModel.createDefaultRoof(u.unit.floor); delete u.roof.fascia; }
|
||||
if (u.roof.fascia === undefined) u.roof.fascia = oldRoof.edge !== 'daktrim';
|
||||
if (!RoofModel.COVERINGS[u.roof.covering]) u.roof.covering = 'dakleer';
|
||||
u.lighting = { walls: (u.lighting && u.lighting.walls) || {} };
|
||||
u.facade = { walls: (u.facade && u.facade.walls) || {} };
|
||||
if (!hadFacade) Object.entries(u.unit.walls).forEach(([side, ws]) => {
|
||||
if ((ws.materials || {}).exterior === 'cementplaat' && !u.facade.walls[side]) u.facade.walls[side] = { type: 'steen' };
|
||||
});
|
||||
});
|
||||
return state;
|
||||
}
|
||||
|
||||
return {
|
||||
ALIGN_LABELS, SIDE_LABELS, DEFAULT_INTERIOR_THICKNESS,
|
||||
ALIGN_LABELS, SIDE_LABELS, DEFAULT_INTERIOR_THICKNESS, FACADE_TYPES, facadeFor,
|
||||
clone, createEmptyProject, createDefaultSettings, createUnitEntry, applyGlobalSettings, nextUnitId, createDefaultState, unitRects, computeSeams, overlappingPairs,
|
||||
interiorWallDefaults, setThickness, thicknessOf, interiorLayout, ensureSeamWalls,
|
||||
computeParts, allWallPieces, computeTotals, validateState, fromUnitDesign, normalize
|
||||
|
||||
Reference in New Issue
Block a user