v0.6.1: standaardmodellen uit één lijst (HouseModel.MODELS) voor Snel nieuw en het venster Nieuw, gedeelde bouwstenen (modelKit) voor Amstel en nieuw model Wetering (10,5 × 4,8 m, twee units zonder naadwand, hoekkeuken, badkamer, slaapkamer met kast); keukenblok met kookplaat (plek instelbaar) en spoelbak aan/uit, kookplaat ook in de kosten van een keukenblok
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ceda0b554d
commit
bd084e4a96
+115
-35
@@ -73,12 +73,17 @@ window.HouseModel = (() => {
|
||||
return { exterior: 'vochtdoek', stone: null, stuc: null, cladding, trasraam, rabatColor: state.settings.facade.rabatColor };
|
||||
}
|
||||
|
||||
function newModelState(naam) {
|
||||
const st = { project: createEmptyProject(), settings: createDefaultSettings(), units: [], interiorWalls: [], rooms: [], fixtures: [] };
|
||||
st.project.naam = naam || '';
|
||||
return st;
|
||||
}
|
||||
|
||||
// TIJDELIJK (testen): nieuwe woning = voorbeeldontwerp (json/premade/vlinderwoning.json); false = één unit.
|
||||
const TEST_DEFAULT = true;
|
||||
|
||||
function createVlinderwoning() {
|
||||
const st = { project: createEmptyProject(), settings: createDefaultSettings(), units: [], interiorWalls: [], rooms: [], fixtures: [] };
|
||||
st.project.naam = 'Vlinderwoning';
|
||||
const st = newModelState('Vlinderwoning');
|
||||
st.settings.trasraam.finish = 'K490';
|
||||
const A = createUnitEntry('A', null, { width: 10000, depth: 4000, windowOn: [] });
|
||||
const B = createUnitEntry('B', { to: 'A', side: 'achter', align: 'start', offset: 0 }, { width: 10000, depth: 3600, windowOn: [] });
|
||||
@@ -112,10 +117,35 @@ window.HouseModel = (() => {
|
||||
return st;
|
||||
}
|
||||
|
||||
// Bouwstenen voor de standaardmodellen. Gevelopeningen: [type, w, h, y, anchor, offset, fill];
|
||||
// binnenwanden: [type, w, h, anchor, offset, fill] vanaf de vloer.
|
||||
function modelKit(st, H, T) {
|
||||
const K = (type, extra) => Object.assign(KozijnModel.defaultFill(type === 'raam' ? 'raam' : 'deur'), { out: 'zwart', in: 'zwart' }, extra || {});
|
||||
const binnen = (extra) => Object.assign(KozijnModel.defaultFill('deur'), { out: 'wit', in: 'wit', glas: false }, extra || {});
|
||||
const ops = (ws, list) => { ws.openings = list.map(([type, w, h, y, anchor, offset, fill], i) => ({ id: i + 1, type, w, h, y, anchor, offset, fill })); };
|
||||
const iw = (x1, z1, x2, z2, openings) => {
|
||||
const wall = interiorWallDefaults(T, H);
|
||||
wall.openings = (openings || []).map(([type, w, h, anchor, offset, fill], i) => ({ id: i + 1, type, w, h, y: 0, anchor, offset, fill }));
|
||||
st.interiorWalls.push({ id: st.interiorWalls.length + 1, x1, z1, x2, z2, wall });
|
||||
};
|
||||
// zaadpunt t.o.v. de noordwesthoek van de unit
|
||||
const room = (unitId, x, z, type, name) =>
|
||||
st.rooms.push(Object.assign(RoomModel.applyType({ id: st.rooms.length + 1, unitId, x, z, name: '' }, type), { name: name || '' }));
|
||||
// Midden voetafdruk t.o.v. de noordwesthoek van de unit; rot = richting van de rug (0 = noord, 90 = oost).
|
||||
// anchor 'oost': x opgeven vanaf de westgevel, het meubel schuift mee met de oostgevel.
|
||||
const fx = (type, unitId, x, z, rot, size, opts) => {
|
||||
const f = FixtureModel.create(st, type, unitId, x, z, rot);
|
||||
if (size && size.anchor === 'oost') f.x = Math.round(st.units.find(u => u.id === unitId).unit.floor.floor.width - x);
|
||||
Object.assign(f, size || {});
|
||||
Object.assign(f.opts, opts || {});
|
||||
st.fixtures.push(f);
|
||||
};
|
||||
return { K, binnen, ops, iw, room, fx };
|
||||
}
|
||||
|
||||
// Model Amstel (examples/ontwerp_amstel.pdf). Alles vanaf de westgevel gemaat, zodat de woning in de lengte kan groeien.
|
||||
function createAmstel() {
|
||||
const st = { project: createEmptyProject(), settings: createDefaultSettings(), units: [], interiorWalls: [], rooms: [], fixtures: [] };
|
||||
st.project.naam = 'Amstel';
|
||||
const st = newModelState('Amstel');
|
||||
const S = st.settings, H = 2800;
|
||||
Object.assign(S.facade, { type: 'stuc', stucColor: 'wit', rabatColor: 'naturel' });
|
||||
S.cladding = 'verticaal';
|
||||
@@ -131,9 +161,7 @@ window.HouseModel = (() => {
|
||||
setHouseRoof(st, true);
|
||||
Object.assign(S.roof.house, { form: { type: 'plat', low: H, high: H }, cover: true });
|
||||
|
||||
const K = (type, extra) => Object.assign(KozijnModel.defaultFill(type === 'raam' ? 'raam' : 'deur'), { out: 'zwart', in: 'zwart' }, extra || {});
|
||||
const binnen = (extra) => Object.assign(KozijnModel.defaultFill('deur'), { out: 'wit', in: 'wit', glas: false }, extra || {});
|
||||
const ops = (ws, list) => { ws.openings = list.map(([type, w, h, y, anchor, offset, fill], i) => ({ id: i + 1, type, w, h, y, anchor, offset, fill })); };
|
||||
const { K, binnen, ops, iw, room, fx } = modelKit(st, H, 90);
|
||||
// Noordgevel: 'right' = vanaf de westhoek.
|
||||
ops(A.unit.walls.voor, [
|
||||
['deur', 1474, 2650, 0, 'right', 150, K('deur', { leaf: 'links', hinge: 'rechts', swing: 'buiten', volglas: true })],
|
||||
@@ -152,13 +180,6 @@ window.HouseModel = (() => {
|
||||
B.facade.walls.rechts = { type: 'rabat' };
|
||||
B.lighting.walls.achter = 'openingen';
|
||||
|
||||
const T = 90;
|
||||
let iwId = 0;
|
||||
const iw = (x1, z1, x2, z2, openings) => {
|
||||
const wall = interiorWallDefaults(T, H);
|
||||
wall.openings = (openings || []).map(([type, w, h, anchor, offset, fill], i) => ({ id: i + 1, type, w, h, y: 0, anchor, offset, fill }));
|
||||
st.interiorWalls.push({ id: ++iwId, x1, z1, x2, z2, wall });
|
||||
};
|
||||
const D = 2115;
|
||||
iw(2555, 3700, 2555, 4800, [['deur', 850, D, 'left', 80, binnen({ hinge: 'links', swing: 'buiten' })]]); // hal | logeerkamer
|
||||
iw(1980, 4845, 3070, 4845); // boven boilerkast en garderobe
|
||||
@@ -180,25 +201,14 @@ window.HouseModel = (() => {
|
||||
fill: Object.assign(KozijnModel.defaultFill('deur'), { type: 'schuifdeur', leaves: 2, mount: 'opbouw', side: 'binnen', glas: true, out: 'zwart', in: 'zwart' }) }];
|
||||
}
|
||||
|
||||
// zaadpunt t.o.v. de noordwesthoek van de unit
|
||||
const room = (id, unitId, x, z, type, name) => st.rooms.push(Object.assign(RoomModel.applyType({ id, unitId, x, z, name: '' }, type), { name }));
|
||||
room(1, 'A', 5600, 1200, 'woonkeuken', 'Woonkamer/keuken');
|
||||
room(2, 'B', 1000, 2000, 'slaapkamer', 'Logeerkamer');
|
||||
room(3, 'B', 3600, 2600, 'hal', 'Entree');
|
||||
room(4, 'B', 2480, 2800, 'toilet', '');
|
||||
room(5, 'B', 5300, 2700, 'badkamer', '');
|
||||
room(6, 'B', 8300, 1800, 'slaapkamer', 'Slaapkamer');
|
||||
room(7, 'B', 2245, 1650, 'techniek', 'Boilerkast');
|
||||
room('A', 5600, 1200, 'woonkeuken', 'Woonkamer/keuken');
|
||||
room('B', 1000, 2000, 'slaapkamer', 'Logeerkamer');
|
||||
room('B', 3600, 2600, 'hal', 'Entree');
|
||||
room('B', 2480, 2800, 'toilet');
|
||||
room('B', 5300, 2700, 'badkamer');
|
||||
room('B', 8300, 1800, 'slaapkamer', 'Slaapkamer');
|
||||
room('B', 2245, 1650, 'techniek', 'Boilerkast');
|
||||
|
||||
// Midden voetafdruk t.o.v. de noordwesthoek van de unit; rot = richting van de rug (0 = noord, 90 = oost).
|
||||
const xA = 11240, xB = 10600;
|
||||
const fx = (type, unitId, x, z, rot, size, opts) => {
|
||||
const f = FixtureModel.create(st, type, unitId, x, z, rot);
|
||||
if (size && size.anchor === 'oost') f.x = Math.round((unitId === 'A' ? xA : xB) - x);
|
||||
Object.assign(f, size || {});
|
||||
Object.assign(f.opts, opts || {});
|
||||
st.fixtures.push(f);
|
||||
};
|
||||
fx('keuken', 'A', 4746, 556, 0, { w: 2660 }, { front: 'antraciet', hogeKast: 'links', spoelbak: 0.49 });
|
||||
fx('kookeiland', 'A', 4746, 2000, 0, { w: 2660, d: 600 }, { front: 'antraciet', kookplaat: true });
|
||||
fx('eettafel', 'A', 1600, 1820, 90, { w: 2000, d: 1100 }, { vorm: 'ovaal', stoelen: 6 });
|
||||
@@ -220,10 +230,80 @@ window.HouseModel = (() => {
|
||||
return st;
|
||||
}
|
||||
|
||||
// Model Wetering (examples/ontwerp_wetering.pdf): 10,5 × 4,8 m, één rechthoek zonder naadwand (open woonkamer
|
||||
// over de volle diepte). 4,8 m is te diep voor één unit, dus twee units (2,6 + 2,2 m). Alles vanaf de westgevel en
|
||||
// de noordgevel gemaat (buitenwerks); de entreegevel met openslaande deuren en voordeur is het zuiden.
|
||||
function createWetering() {
|
||||
const st = newModelState('Wetering');
|
||||
const S = st.settings, H = 2800, W = 10500, DA = 2600, DB = 2200;
|
||||
Object.assign(S.facade, { type: 'rabat', rabatColor: 'grijs' });
|
||||
S.cladding = 'verticaal';
|
||||
S.trasraam.enabled = false;
|
||||
S.roof.fasciaColor = 'zwart';
|
||||
S.lighting.mode = 'gevel';
|
||||
S.lighting.direction = 'both';
|
||||
if (S.elektra && S.elektra.apparaten) Object.assign(S.elektra.apparaten, { koken: true, oven: true, vaatwasser: true });
|
||||
|
||||
const A = createUnitEntry('A', null, { width: W, depth: DA, height: H, windowOn: [] });
|
||||
const B = createUnitEntry('B', { to: 'A', side: 'achter', align: 'start', offset: 0 }, { width: W, depth: DB, height: H, windowOn: [] });
|
||||
st.units.push(A, B);
|
||||
setHouseRoof(st, true);
|
||||
Object.assign(S.roof.house, { form: { type: 'plat', low: H, high: H } });
|
||||
|
||||
const { K, binnen, ops, iw, room, fx } = modelKit(st, H, 90);
|
||||
// Noord 'right' en zuid 'left' = vanaf de westhoek; west 'left' en oost 'right' = vanaf de noordkant van de wand.
|
||||
ops(A.unit.walls.voor, [['raam', 500, 700, 1400, 'right', 5670, K('raam')]]);
|
||||
ops(A.unit.walls.links, [['raam', 700, 2100, 0, 'left', 300, K('raam')], ['raam', 700, 2100, 0, 'left', 1500, K('raam')]]);
|
||||
ops(A.unit.walls.rechts, [['raam', 500, 1400, 700, 'right', 270, K('raam')]]);
|
||||
ops(B.unit.walls.rechts, [['raam', 500, 1400, 700, 'right', 540, K('raam')]]);
|
||||
ops(B.unit.walls.achter, [
|
||||
['deur', 824, 2100, 0, 'left', 1200, K('deur', { hinge: 'links', swing: 'buiten', volglas: true })],
|
||||
['deur', 824, 2100, 0, 'left', 2176, K('deur', { hinge: 'rechts', swing: 'buiten', volglas: true })],
|
||||
['voordeur', 1100, 2100, 0, 'left', 5350, K('deur', { hinge: 'rechts', swing: 'buiten', volglas: true })]]);
|
||||
B.lighting.walls.achter = 'openingen';
|
||||
|
||||
const D = 2115;
|
||||
iw(4675, 190, 4675, 2210); // keuken | badkamer
|
||||
iw(4630, 2255, 7120, 2255, [['deur', 930, D, 'left', 1390, binnen({ hinge: 'rechts', swing: 'buiten' })]]); // badkamer | entree
|
||||
iw(7165, 190, 7165, 4610, [ // slaapkamer
|
||||
['deur', 980, 2130, 'left', 360, Object.assign(binnen(), { type: 'schuifdeur', leaves: 1, mount: 'opbouw', side: 'binnen', dir: 'rechts' })],
|
||||
['deur', 930, D, 'left', 2277, binnen({ hinge: 'links', swing: 'buiten' })]]);
|
||||
iw(6455, 3765, 7120, 3765); // kapstoknis entree
|
||||
|
||||
// Geen naadwand: woonkamer en slaapkamer lopen over beide units door (Unit › Naadwand toevoegen zet hem terug).
|
||||
|
||||
room('A', 2000, 1500, 'woonkeuken', 'Woonkamer/keuken');
|
||||
room('A', 5900, 1500, 'badkamer');
|
||||
room('A', 8700, 1500, 'slaapkamer', 'Slaapkamer');
|
||||
|
||||
const zB = (z) => z - DA;
|
||||
fx('keuken', 'A', 4330, 1245, 90, { w: 2110 }, { front: 'antraciet', hogeKast: 'geen', spoelbak: 0.85, kookplaat: true, kookplaatPlek: 0.2 });
|
||||
fx('keuken', 'A', 4630, 2600, 0, { w: 1200 }, { front: 'antraciet', hogeKast: 'rechts', spoel: false, vaatwasser: false });
|
||||
fx('boiler', 'A', 5515, 2525, 0);
|
||||
fx('eettafel', 'A', 1620, 1160, 0, { w: 1000, d: 1000 }, { vorm: 'ovaal', stoelen: 4 });
|
||||
fx('bank', 'B', 615, zB(3640), 270, { w: 1600, d: 850 }, { chaise: 'geen' });
|
||||
fx('salontafel', 'B', 1770, zB(3510), 0, { w: 600, d: 600 }, { vorm: 'rond' });
|
||||
fx('fauteuil', 'B', 2760, zB(4060), 150);
|
||||
fx('douche', 'A', 5245, 640, 270, { w: 900, d: 1050 }, { glas: 'links', glasLengte: 800 });
|
||||
fx('toilet', 'A', 5065, 1760, 270, { w: 900 });
|
||||
fx('wastafel', 'A', 6150, 420, 0, { w: 600 }, { spiegel: false });
|
||||
fx('bed', 'A', 9260, 2050, 90, { w: 1600, d: 2100, anchor: 'oost' }, { nachtkastjes: false });
|
||||
fx('kledingkast', 'B', 8760, zB(4310), 180, { w: 3100 });
|
||||
|
||||
computeParts(st, { skip3D: true });
|
||||
return st;
|
||||
}
|
||||
|
||||
// Standaardmodellen: Bestand › Snel nieuw en het venster Nieuw. De sleutel is de template.
|
||||
const MODELS = {
|
||||
amstel: { label: 'Woning Amstel', icon: 'house-heart', create: createAmstel },
|
||||
wetering: { label: 'Woning Wetering', icon: 'house-door', create: createWetering }
|
||||
};
|
||||
|
||||
function createDefaultState(template) {
|
||||
if (template === 'amstel') return createAmstel();
|
||||
if (MODELS[template]) return MODELS[template].create();
|
||||
if (TEST_DEFAULT && (!template || template === 'single')) return createVlinderwoning();
|
||||
const state = { project: createEmptyProject(), settings: createDefaultSettings(), units: [], interiorWalls: [], rooms: [], fixtures: [] };
|
||||
const state = newModelState();
|
||||
state.units.push(createUnitEntry('A', null, template === 'L' ? { width: 8000, depth: 3600 } : { width: 6000, depth: 3000 }));
|
||||
if (template === 'L') {
|
||||
state.units.push(createUnitEntry('B', { to: 'A', side: 'achter', align: 'start', offset: 0 }, { width: 4500, depth: 3600, windowOn: [] }));
|
||||
@@ -1371,7 +1451,7 @@ window.HouseModel = (() => {
|
||||
|
||||
return {
|
||||
ALIGN_LABELS, SIDE_LABELS, DEFAULT_INTERIOR_THICKNESS, FACADE_TYPES, facadeFor, facadeMaterials,
|
||||
clone, createEmptyProject, createDefaultSettings, createUnitEntry, applyGlobalSettings, nextUnitId, createDefaultState, unitRects, computeSeams, overlappingPairs,
|
||||
clone, createEmptyProject, createDefaultSettings, createUnitEntry, applyGlobalSettings, nextUnitId, MODELS, createDefaultState, unitRects, computeSeams, overlappingPairs,
|
||||
interiorWallDefaults, setThickness, thicknessOf, interiorLayout, ensureSeamWalls, syncSeamWalls, missingSeamWalls,
|
||||
houseRoofShape, houseRoofFits, setHouseRoof, coverExtensions,
|
||||
computeParts, allWallPieces, computeTotals, computeDimensions, dimensionRows, TRANSPORT, TRANSPORT_CLASSES, computeTransport, validateState, fromUnitDesign, normalize
|
||||
|
||||
Reference in New Issue
Block a user