Plant view: GF / 1F / Roof levels, lamps off the drive areas, pipe bridges land on walls
Deploy test site / deploy (push) Successful in 48s
Deploy test site / deploy (push) Successful in 48s
User feedback on the isometric view (October 2026):
- "a light pole in the middle of the truck apron": a PAVED list of the
drive areas (gate road, aprons, east road, lane, access road, car
park, yard); every lamp now stands on a kerb or verge (the apron lamp
to the south kerb, three more moved off drive areas, one added on the
east road); one LAMPS list feeds poles and light pools.
- "the office building also has 2 levels, can we make a selector for GF
1 2": the Roof / Inside toggle becomes GF | 1F | Roof. 1F shows the
office first floor (+4.0 m: offices, meeting and training, meeting
room, IT and server, toilets, pantry, flexible room, stair and lift)
and the finishing and print block's upper floor (+3.8 m: print room in
reserve, print stock, packaging materials, stair and goods lift), the
rest ghosted. Office ground floor re-split after the floor plans
(site-candidates.md). setMode('inside'/'roof') still works; new
setLevel / getLevel / onLevel; the level survives calculator updates.
- "the pipe bridge to the pump and HX room also stops mid air": both
pipe bridges now drop down the wall faces at the factory and at the
yard building to low-level wall sleeves, with a second support post.
Checks: renderer 720 checks (presets x GF/1F/Roof x 390/1024/1440 x
dark/light) and functional checks pass; calculator regression 0 fails;
level selector works in the page; screenshots reviewed in all rotations.
This commit is contained in:
1 parent
073f20a132
commit
8e4559ee36
1 file changed
+368
-153
+368
-153
@@ -310,7 +310,8 @@ html[data-theme=light] .iso-wrap {
|
||||
.iso-seg { display: inline-flex; }
|
||||
.iso-seg button { border-radius: 0; }
|
||||
.iso-seg button:first-child { border-radius: 5px 0 0 5px; }
|
||||
.iso-seg button:last-child { border-radius: 0 5px 5px 0; border-left: 0; }
|
||||
.iso-seg button:last-child { border-radius: 0 5px 5px 0; }
|
||||
.iso-seg button + button { border-left: 0; }
|
||||
.iso-seg button[aria-pressed=true] { background: var(--iso-btnon); border-color: var(--iso-accent); color: var(--iso-btnfg); font-weight: 600; }
|
||||
.iso-compass { display: inline-flex; align-items: center; gap: 2px; padding: 3px 7px; cursor: default; }
|
||||
.iso-compass svg { width: 20px; height: 20px; }
|
||||
@@ -388,7 +389,8 @@ html[data-theme=light] .iso-wrap {
|
||||
.iso-speaker { --b: #2b2f37; } .iso-shrink { --b: #9aa4b2; } .iso-cass { --b: #333a46; } .iso-cdtower { --b: #c7ccd4; }
|
||||
.iso-forklift { --b: #e3a400; } .iso-pump { --b: #3f78c0; } .iso-motor { --b: #59606b; } .iso-accu { --b: #c9473a; }
|
||||
.iso-comp { --b: #4f8d58; } .iso-oil { --b: #b88a2a; } .iso-belt { --b: #2b313b; } .iso-hx { --b: #8aa0b8; }
|
||||
.iso-lathe { --b: #3c4658; } .iso-stair { --b: #9aa0aa; } .iso-sign { --b: var(--iso-signline); } .iso-fanbox { --b: #6b7585; }
|
||||
.iso-lathe { --b: #3c4658; } .iso-stair { --b: #9aa0aa; } .iso-lift { --b: #737b88; } .iso-rail2 { --b: var(--iso-steel); }
|
||||
.iso-server { --b: #27303f; } .iso-shower { --b: #5f9fd6; } .iso-wc { --b: #8e9aa9; } .iso-sign { --b: var(--iso-signline); } .iso-fanbox { --b: #6b7585; }
|
||||
.iso-bushing { --b: #c9b8a4; } .iso-pipes { --b: #c9473a; } .iso-pipec { --b: #3f78c0; } .iso-pipec2 { --b: #6aa8ff; }
|
||||
.iso-svg .iso-headc { fill: var(--iso-head); }
|
||||
.iso-svg .iso-fence, .iso-svg .iso-fence.iso-t { fill-opacity: var(--iso-fenceo); --b: var(--iso-fence); }
|
||||
@@ -457,6 +459,19 @@ html[data-theme=light] .iso-svg .iso-lamp { fill: #c9ced6; }
|
||||
.iso-z-lobby, .iso-z-canteen { --b: color-mix(in srgb, var(--iso-office) 70%, var(--iso-floor)); }
|
||||
.iso-z-cut, .iso-z-listen { --b: color-mix(in srgb, var(--iso-floor) 72%, #6b4a8e); }
|
||||
.iso-z-arch { --b: color-mix(in srgb, var(--iso-floor) 76%, #6aa8ff); }
|
||||
.iso-z-core { --b: color-mix(in srgb, var(--iso-floor) 88%, #c9ced6); }
|
||||
.iso-z-hall { --b: color-mix(in srgb, var(--iso-office) 55%, var(--iso-floor)); }
|
||||
.iso-z-staff2 { --b: color-mix(in srgb, var(--iso-floor) 80%, #7fa8d8); }
|
||||
.iso-z-kitchen { --b: color-mix(in srgb, var(--iso-floor) 76%, #c89a6a); }
|
||||
.iso-z-wc { --b: color-mix(in srgb, var(--iso-floor) 80%, #8fbfb4); }
|
||||
.iso-z-offices { --b: color-mix(in srgb, var(--iso-floor) 76%, #8fb0e0); }
|
||||
.iso-z-meet, .iso-z-meet2 { --b: color-mix(in srgb, var(--iso-floor) 74%, #7fcf98); }
|
||||
.iso-z-it { --b: color-mix(in srgb, var(--iso-floor) 70%, #4f7fc0); }
|
||||
.iso-z-pantry { --b: color-mix(in srgb, var(--iso-floor) 74%, #e0b070); }
|
||||
.iso-z-flex { --b: color-mix(in srgb, var(--iso-floor) 80%, #b8a8e0); }
|
||||
.iso-z-print { --b: color-mix(in srgb, var(--iso-floor) 74%, #d08ad0); }
|
||||
.iso-z-stock { --b: color-mix(in srgb, var(--iso-floor) 76%, #e0cc90); }
|
||||
.iso-z-packmat { --b: color-mix(in srgb, var(--iso-floor) 78%, #90d0a0); }
|
||||
.iso-svg .iso-part { fill: none; stroke: var(--iso-part); stroke-width: .9; stroke-linecap: square; }
|
||||
.iso-svg .iso-mark { fill: none; stroke: var(--iso-mark); stroke-width: .7; stroke-dasharray: 3 2; }
|
||||
.iso-svg .iso-trench { fill: var(--iso-trench); stroke: none; }
|
||||
@@ -466,6 +481,13 @@ html[data-theme=light] .iso-svg .iso-lamp { fill: #c9ced6; }
|
||||
.iso-svg .iso-slot.iso-empty { stroke-dasharray: 3 2.4; fill: var(--iso-mark); fill-opacity: .06; }
|
||||
.iso-svg .iso-cell { fill: none; stroke: var(--iso-hivis); stroke-width: .45; stroke-dasharray: 1.4 1.4; opacity: .8; }
|
||||
.iso-svg .iso-bay { fill: var(--iso-mark); fill-opacity: .1; stroke: var(--iso-mark); stroke-width: .5; stroke-dasharray: 2 2; }
|
||||
.iso-svg .iso-void { fill: var(--iso-open); stroke: none; }
|
||||
.iso-svg .iso-lining { fill: none; stroke: #8a6fb0; stroke-width: 1.4; opacity: .75; }
|
||||
|
||||
/* 1F level: single-storey buildings stay as ghosted ground-floor context, standing still */
|
||||
.iso-svg .iso-dim { opacity: .4; }
|
||||
html[data-theme=light] .iso-svg .iso-dim { opacity: .5; }
|
||||
.iso-svg .iso-dim .iso-a { animation: none !important; }
|
||||
|
||||
/* tags (counter-scaled by --iso-k so they keep their screen size) */
|
||||
.iso-tag path { fill: var(--iso-tagbg); stroke: var(--iso-tagline); stroke-width: 1; }
|
||||
@@ -552,11 +574,15 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.iso-stage { aspect-ratio: 1 / 1; min-height: 320px; }
|
||||
.iso-bar { gap: 4px; top: 6px; left: 6px; right: 6px; }
|
||||
.iso-bar button { padding: 4px 7px; min-width: 28px; min-height: 30px; }
|
||||
.iso-compass { padding: 3px 4px; min-height: 30px; }
|
||||
.iso-bar { gap: 3px; top: 6px; left: 6px; right: 6px; }
|
||||
.iso-bar button { padding: 4px 6px; min-width: 26px; min-height: 30px; }
|
||||
.iso-compass { padding: 3px; min-height: 30px; }
|
||||
.iso-compass b { display: none; }
|
||||
}
|
||||
/* the level selector, rotation, zoom and fit stay on one line down to ~360 px; the compass gives way first */
|
||||
@media (max-width: 370px) {
|
||||
.iso-compass { display: none; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -596,7 +622,8 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
<p class="note" style="margin-top:0">The current plant configuration (preset or the switches below) as a
|
||||
tile-game view of the site: presses,
|
||||
stamper line, cutting room, utility yard with its boiler and chiller modules, solar and battery.
|
||||
Switch between the roof and the inside, rotate, zoom and tap anything for its figures. Schematic,
|
||||
Switch between the ground floor (GF), the upper floors of the office and the finishing and print
|
||||
block (1F) and the roofs, rotate, zoom and tap anything for its figures. Schematic,
|
||||
not to scale where the vendors publish no footprint.</p>
|
||||
<div id="isoPlant"></div>
|
||||
</section>
|
||||
@@ -884,6 +911,7 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
*
|
||||
* var view = CNXIso.mount(containerEl, cfg, { onPick: function (info) {} });
|
||||
* view.update(cfg); // merges cfg over the current config and redraws
|
||||
* view.setLevel("gf" | "1f" | "roof"); // ground-floor cutaway, upper floors, roofs
|
||||
* view.destroy();
|
||||
*
|
||||
* Layout: the Payap scenario model (docs/site-candidates.md), the detached
|
||||
@@ -896,7 +924,7 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
(function (root) {
|
||||
"use strict";
|
||||
|
||||
var VERSION = "1.0";
|
||||
var VERSION = "1.1";
|
||||
var DEF = {
|
||||
duplex: 1, classic: 1, galvanics: true, cutting: true, metrology: "full",
|
||||
cassette: true, cdr: true, solar: "buy", pvKwp: 300, batteryKwh: 271,
|
||||
@@ -1155,12 +1183,16 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
|
||||
function Scene(rot, uid) {
|
||||
this.P = new Proj(rot); this.uid = uid || 0;
|
||||
this.ground = []; this.sp = []; this.tags = []; this.info = {}; this.flags = [];
|
||||
this.ground = []; this.sp = []; this.tags = []; this.info = {}; this.flags = []; this.dim = false;
|
||||
}
|
||||
Scene.prototype.sprite = function (id, cls) { var s = new Sprite(this, id, cls); this.sp.push(s); return s; };
|
||||
// while sc.dim is set (1F level: single-storey buildings as context) sprites are ghosted and carry no tags
|
||||
Scene.prototype.sprite = function (id, cls) {
|
||||
var s = new Sprite(this, id, this.dim ? (cls ? cls + " " : "") + "iso-dim" : cls); this.sp.push(s); return s;
|
||||
};
|
||||
Scene.prototype.g = function (s) { this.ground.push(s); };
|
||||
Scene.prototype.inf = function (id, name, detail) { this.info[id] = { id: id, name: name, detail: detail || "" }; };
|
||||
Scene.prototype.tag = function (x, y, z, text, prio, id, kind) {
|
||||
if (this.dim) return;
|
||||
this.tags.push({ x: x, y: y, z: z, t: text, p: prio || 1, id: id || "", k: kind || "" });
|
||||
};
|
||||
|
||||
@@ -1261,9 +1293,16 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
lost: hall.lost + p2.lost };
|
||||
}
|
||||
|
||||
// street lamps: site roads, gate and car park; the utility yard gets two on its back fence
|
||||
// (earlier positions at y 99.6 stood in the middle of the yard in front of the boiler hall)
|
||||
var LAMPS = [[116.5, 15], [116.5, 32], [132, 45], [146.6, 62], [101, 62], [56, 15], [13, 34], [45, 113.2], [88, 113.2], [8.5, 97]];
|
||||
// paved areas trucks and cars drive on: [x0, y0, x1, y1]
|
||||
var PAVED = {
|
||||
gateRoad: [118, -6, 130, 37], apron: [100, 37, 148, 69], eastRoad: [136, 69, 148, 100], lane: [4, 94, 148, 100],
|
||||
access: [54, 6, 118, 13], parking: [12, 3, 54, 36], yard: [19, 100, 136, 114]
|
||||
};
|
||||
// street lamps stand on kerbs, fences and walls, never on a paved drive area (one list feeds the poles
|
||||
// and the dusk light pools): gate road west kerb, the apron's west, south and east kerbs, the east road,
|
||||
// the access road, the car park's west kerb, the lane's north kerb at the ramp, behind the utility yard.
|
||||
// (Earlier spots stood in the middle of the truck apron, in the lane and in the yard.)
|
||||
var LAMPS = [[116.5, 15], [116.5, 32], [136, 36.2], [148.8, 62], [99.2, 62], [148.8, 86], [56, 15], [11.2, 34], [50, 114.6], [88, 114.6], [8.5, 100.8]];
|
||||
|
||||
// ------------------------------------------------------------ PV placement
|
||||
var PV_ROWS = [1, 3, 5, 7, 10, 12, 14, 16, 19, 21];
|
||||
@@ -1374,15 +1413,17 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
g.push(flatS(P, rect(-8, -16, 158, -6), 0, "iso-g-asph iso-t", "road"));
|
||||
g.push(linesS(P, [[-8, -11, 158, -11]], 0, "iso-dash"));
|
||||
g.push(linesS(P, [[-8, -6.3, 158, -6.3], [-8, -15.7, 158, -15.7]], 0, "iso-kerb"));
|
||||
g.push(flatS(P, rect(118, -6, 130, 37), 0, "iso-g-asph iso-t", "apron"));
|
||||
g.push(flatS(P, rect(100, 37, 148, 69), 0, "iso-g-conc iso-t", "apron"));
|
||||
g.push(flatS(P, rect(136, 69, 148, 100), 0, "iso-g-asph iso-t", "apron"));
|
||||
g.push(flatS(P, rect(4, 94, 148, 100), 0, "iso-g-asph iso-t", "lane"));
|
||||
g.push(flatS(P, rect(54, 6, 118, 13), 0, "iso-g-asph iso-t", "road"));
|
||||
g.push(flatS(P, rect(12, 3, 54, 36), 0, "iso-g-asph iso-t", "parking"));
|
||||
g.push(flatS(P, rect(28, 36, 30.5, 42), 0, "iso-g-path iso-t", "office"));
|
||||
var pr = function (k) { var r = PAVED[k]; return rect(r[0], r[1], r[2], r[3]); };
|
||||
g.push(flatS(P, pr("gateRoad"), 0, "iso-g-asph iso-t", "apron"));
|
||||
g.push(flatS(P, pr("apron"), 0, "iso-g-conc iso-t", "apron"));
|
||||
g.push(flatS(P, pr("eastRoad"), 0, "iso-g-asph iso-t", "apron"));
|
||||
g.push(flatS(P, pr("lane"), 0, "iso-g-asph iso-t", "lane"));
|
||||
g.push(flatS(P, pr("access"), 0, "iso-g-asph iso-t", "road"));
|
||||
g.push(flatS(P, pr("parking"), 0, "iso-g-asph iso-t", "parking"));
|
||||
// footpath from the car park to the office entrance (lobby at the west end, floor plans)
|
||||
g.push(flatS(P, rect(15.5, 36, 18, 42), 0, "iso-g-path iso-t", "office"));
|
||||
g.push(flatS(P, rect(15.5, 57, 18.5, 69), 0, "iso-g-path iso-t", "link"));
|
||||
g.push(flatS(P, rect(19, 100, 136, 114), 0, "iso-g-conc iso-t", "yard"));
|
||||
g.push(flatS(P, pr("yard"), 0, "iso-g-conc iso-t", "yard"));
|
||||
g.push(flatS(P, rect(91.6, 100.6, 104.9, 112.2), 0.01, "iso-g-pad iso-t", "chillers"));
|
||||
if (al.p2show) g.push(flatS(P, rect(72, 57, 76, 69), 0, "iso-g-path iso-t", "phase2"));
|
||||
else g.push(flatS(P, rect(P2.x0, P2.y0, P2.x1, P2.y1), 0.01, "iso-reserve", "phase2"));
|
||||
@@ -1491,8 +1532,11 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------ factory
|
||||
function zoneList(cfg) {
|
||||
return [
|
||||
// finishing and print block, 14 x 25 m on two levels at fx 92..106 (site-candidates.md, block floor plans):
|
||||
// ground floor trim + optical, QC lab, stair + goods lift along the corridor, packaging behind; upper floor at +3.8 m
|
||||
var BLK = { fx0: 92, fx1: 106, up: 3.8 };
|
||||
function zoneList(cfg, up) {
|
||||
var z = [
|
||||
[0, 0, 8, 10, "iso-z-staff", "staffentry"],
|
||||
[0, 10, 16, 25, "iso-z-shop", "workshop"],
|
||||
[8, 2.6, 16, 10, "iso-z-shop2", "workshop"],
|
||||
@@ -1502,14 +1546,14 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
[30, 2.6, 40, 20.5, "iso-z-colour", "colourstore"],
|
||||
[40, 2.6, 92, 20.5, "iso-z-press", "presshall"],
|
||||
[40, 12.4, 47.8, 20.5, "iso-z-plant", "plantroom"],
|
||||
[16, 20.5, 92, 25, "iso-z-aisle", "aisle"],
|
||||
[92, 2.6, 99, 10, "iso-z-trim", "trim"],
|
||||
[99, 2.6, 106, 10, "iso-z-qc", "qc"],
|
||||
[92, 10, 106, 25, "iso-z-pack", "packaging"],
|
||||
[16, 20.5, up ? 92 : 106, 25, "iso-z-aisle", "aisle"],
|
||||
[106, 0, 120, 25, "iso-z-wh", "warehouse"],
|
||||
[120, 0, 128, 25, "iso-z-disp", "dispatch"],
|
||||
[8, 0, 106, 2.6, cfg.corridor ? "iso-z-corr" : "iso-z-floor", "corridor"]
|
||||
[8, 0, up ? 92 : 106, 2.6, cfg.corridor ? "iso-z-corr" : "iso-z-floor", "corridor"]
|
||||
];
|
||||
if (!up) z.push([92, 2.6, 96, 7.9, "iso-z-trim", "trim"], [96, 2.6, 100, 7.9, "iso-z-qc", "qc"], [100, 2.6, 106, 7.9, "iso-z-core", "block-stair"],
|
||||
[92, 7.9, 106, 20.5, "iso-z-pack", "packaging"]);
|
||||
return z;
|
||||
}
|
||||
function factoryInfo(sc, cfg, al) {
|
||||
sc.inf("factory", "Factory, 128 x 25 m",
|
||||
@@ -1528,7 +1572,15 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
sc.inf("aisle", "Crane and forklift aisle, 4.5 m", "Along the back wall from the machine door to the fire wall: heavy moves need a floor-level path");
|
||||
sc.inf("trim", "Trimming and 100 % optical inspection", "Edge trimmer and the optical station at the end of the record path (quality-automation.md)");
|
||||
sc.inf("qc", "QC and listening", "Sampled audio comparison (about 1 in 50) and the listening point on the tour (quality-automation.md)");
|
||||
sc.inf("packaging", "Finishing and packaging", "Packing tables, shrink wrap and pallet wrapper; the finishing and print block is 14 x 25 m on two levels with the print room reserved upstairs");
|
||||
sc.inf("packaging", "Finishing and packaging", "Packing tables, shrink wrap and pallet wrapper, ~170 m2 on the ground floor of the finishing and print block (14 x 25 m on two levels, print room reserved upstairs)");
|
||||
sc.inf("block-stair", "Stair and goods lift", "Connect the two levels of the finishing and print block. The crane runway ends at the press hall, so loads here move by forklift and goods lift; heavy compound stays on the ground floor (site-candidates.md, crane-workshop-tours.md)");
|
||||
if (cfg.cassette) sc.inf("cassette", "Cassette duplication", "Bench line, ~40 to 80 m2 (project-timeline.md)");
|
||||
if (cfg.cdr) sc.inf("cdr", "CD-R duplication, short run", "Tower duplicator and printer bench, ~20 to 40 m2 (project-timeline.md)");
|
||||
sc.inf("printblock", "Finishing and print block, 14 x 25 m",
|
||||
"Two levels: trim and optical inspection, the QC lab and packaging (~170 m2) on the ground floor; print room (reserve), print stock and packaging materials on the upper floor at +3.8 m (site-candidates.md)");
|
||||
sc.inf("printroom", "Print room (kept in reserve)", "Upper floor at +3.8 m. In-house printing is not decided; jackets come from a print partner today (site-candidates.md, production-timeline.md)");
|
||||
sc.inf("printstock", "Print stock", "Paper and board, upper floor at +3.8 m (site-candidates.md)");
|
||||
sc.inf("packmat", "Packaging materials", "Sleeves, inner bags, mailers and cartons, upper floor at +3.8 m (site-candidates.md)");
|
||||
sc.inf("warehouse", "Warehouse behind the fire wall", "Three racking rows; fire wall EI 60/120; forklift territory, no crane");
|
||||
sc.inf("dispatch", "Dispatch, two dock doors", "Pallets staged for the trucks on the apron");
|
||||
sc.inf("workshop", "Workshop and machine bay, ~200 m2", "Service bay, benches, spares, 3D printers, a lathe and a small CNC mill; machine door 4.5 x 5.0 m with the ramp; the crane parks here (crane-workshop-tours.md)");
|
||||
@@ -1595,11 +1647,11 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
]);
|
||||
// pipe bridges and the covered crossing to water treatment are separate sprites
|
||||
}
|
||||
function factoryInside(sc, cfg, al, pv) {
|
||||
var x0 = X(0), y0 = Y(0), x1 = X(FL), y1 = Y(FW), P = sc.P, z = FFL;
|
||||
function factoryInside(sc, cfg, al, pv, up) {
|
||||
var x0 = X(0), y0 = Y(0), x1 = X(FL), y1 = Y(FW), P = sc.P, z = FFL, xe = up ? X(BLK.fx0) : X(105.8);
|
||||
var fl = sc.sprite("factory");
|
||||
fl.box(x0, y0, x1, y1, 0, FFL, "iso-plinth");
|
||||
var zones = zoneList(cfg);
|
||||
var zones = zoneList(cfg, up);
|
||||
zones.forEach(function (q) { fl.flat(rect(X(q[0]), Y(q[1]), X(q[2]), Y(q[3])), z + 0.005, q[4] + " iso-t", q[5]); });
|
||||
var segs = [];
|
||||
zones.forEach(function (q) {
|
||||
@@ -1608,7 +1660,7 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
segs.push([a, b, c, b], [c, b, c, d], [c, d, a, d], [a, d, a, b]);
|
||||
});
|
||||
fl.lines(segs, z + 0.01, "iso-part");
|
||||
fl.lines([[X(16), Y(20.5), X(92), Y(20.5)], [X(16), Y(24.6), X(92), Y(24.6)]], z + 0.01, "iso-mark");
|
||||
fl.lines([[X(16), Y(20.5), xe, Y(20.5)], [X(16), Y(24.6), xe, Y(24.6)]], z + 0.01, "iso-mark");
|
||||
// service trench along the press rows
|
||||
fl.flat(rect(X(40), Y(11.6), X(92), Y(12.4)), z + 0.01, "iso-trench");
|
||||
var gr = []; for (var gx = 40.5; gx < 92; gx += 1.2) gr.push([X(gx), Y(11.65), X(gx), Y(12.35)]);
|
||||
@@ -1632,7 +1684,7 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
// walls cut: back walls taller than front walls (cutaway)
|
||||
wallsCut(sc, "factory", x0, y0, x1, y1, z, 1.0, 3.0, 0.3, "iso-wall");
|
||||
sc.sprite("factory").box(X(105.85), Y(0.3), X(106.15), Y(FW - 0.3), z, z + 2.2, "iso-firewall", { top: "iso-cut" });
|
||||
if (cfg.corridor) sc.sprite("corridor").box(X(8), Y(2.55), X(106), Y(2.65), z, z + 2.6, "iso-glassw");
|
||||
if (cfg.corridor) sc.sprite("corridor").box(X(8), Y(2.55), up ? X(BLK.fx0) : X(106), Y(2.65), z, z + 2.6, "iso-glassw");
|
||||
// frame columns and crane runway (production compartment, west wall to the end of the press hall)
|
||||
[[0.3, 0.62], [24.38, 24.7]].forEach(function (yy) {
|
||||
var s = sc.sprite("crane", P.vis(0, yy[0] < 12 ? -1 : 1) ? "iso-ghost" : "");
|
||||
@@ -1644,7 +1696,7 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
});
|
||||
if (cfg.crane === "buy") craneM(sc, z, cfg);
|
||||
else sc.tag(X(46), Y(24.5), z + 6.5, "Crane-ready (rented)", 5, "crane");
|
||||
machinesFactory(sc, cfg, al, z);
|
||||
machinesFactory(sc, cfg, al, z, up);
|
||||
// presses in the hall
|
||||
al.hall.forEach(function (sl) {
|
||||
if (sl.e) return;
|
||||
@@ -1653,8 +1705,8 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
else { classicM(sc, sl.n, cx, cy, z, cfg.running); sc.tag(cx, cy, z + 3.2, "Classic " + sl.n, 6, "classic-" + sl.n); }
|
||||
});
|
||||
// record path to finishing (schematic conveyor along the corridor glass)
|
||||
conveyor(sc, z, cfg);
|
||||
if (cfg.corridor) visitors(sc, z, cfg);
|
||||
conveyor(sc, z, cfg, up);
|
||||
if (cfg.corridor && !up) visitors(sc, z, cfg);
|
||||
}
|
||||
function wallsCut(sc, id, x0, y0, x1, y1, z0, lo, hi, t, mat) {
|
||||
var P = sc.P;
|
||||
@@ -1684,8 +1736,8 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
hk.ge();
|
||||
sc.tag(X(30), Y(12), z + 7.6, "Crane 5 t", 6, "crane");
|
||||
}
|
||||
function conveyor(sc, z, cfg) {
|
||||
var P = sc.P, s = sc.sprite("conveyor"), xa = X(40.6), xb = X(95), y0 = Y(2.9), y1 = Y(3.35);
|
||||
function conveyor(sc, z, cfg, up) {
|
||||
var P = sc.P, s = sc.sprite("conveyor"), xa = X(40.6), xb = up ? X(BLK.fx0 - 0.2) : X(93), y0 = Y(2.9), y1 = Y(3.35);
|
||||
s.box(xa, y0, xb, y1, z + 0.72, z + 0.85, "iso-belt");
|
||||
if (!cfg.running) return;
|
||||
var L = xb - xa - 1, v = P.dv(L, 0, 0), n = 8, dur = 16, i, p = P.s(xa + 0.5, (y0 + y1) / 2, z + 0.88), q = P.s(xa + 0.5, (y0 + y1) / 2, z + 0.88);
|
||||
@@ -1721,7 +1773,7 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
Object.keys(groups).forEach(function (k) { var g = groups[k]; s.open(g.A, g.B, g.l, g.cls); });
|
||||
return s;
|
||||
}
|
||||
function machinesFactory(sc, cfg, al, z) {
|
||||
function machinesFactory(sc, cfg, al, z, up) {
|
||||
var P = sc.P, i;
|
||||
// staff entry: lockers
|
||||
sc.sprite("staffentry").box(X(0.6), Y(2), X(1.1), Y(8.5), z, z + 1.9, "iso-locker");
|
||||
@@ -1803,34 +1855,9 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
sc.sprite("plantroom").box(X(45.4), Y(17.3), X(47.3), Y(19.0), z, z + 1.5, "iso-comp");
|
||||
sc.sprite("plantroom").box(X(41), Y(16.0), X(43.6), Y(17.2), z, z + 1.2, "iso-oil");
|
||||
sc.tag(X(44), Y(16.5), z + 3, "Plant room", 4, "plantroom");
|
||||
// finishing block: trimmer + optical station, QC, packaging, cassette, CD-R
|
||||
var tr = sc.sprite("trim"); tr.box(X(95.3), Y(3.0), X(96.4), Y(4.1), z, z + 1.1, "iso-steel"); tr.disc(X(95.85), Y(3.55), z + 1.12, 0.26, "iso-vinylc");
|
||||
var op = sc.sprite("trim"); op.box(X(96.9), Y(2.95), X(98.6), Y(4.3), z, z + 1.5, "iso-optic"); op.cyl(X(97.75), Y(3.6), 0.35, z + 1.5, z + 1.8, "iso-dome"); op.led(X(97.75), Y(3.6), z + 1.82, "iso-ledg");
|
||||
sc.sprite("trim").box(X(96.9), Y(5.0), X(97.8), Y(5.8), z, z + 0.8, "iso-bin");
|
||||
sc.tag(X(97), Y(4), z + 2.6, "Trim + optical", 4, "trim");
|
||||
var qb = sc.sprite("qc"); qb.box(X(99.6), Y(7.6), X(105.6), Y(8.4), z, z + 0.85, "iso-bench");
|
||||
qb.seq([[X(101), Y(8), function (q) { q.box(X(100.4), Y(7.7), X(101.6), Y(8.3), z + 0.85, z + 1.0, "iso-instr"); q.disc(X(101), Y(8), z + 1.02, 0.24, "iso-vinylc"); }],
|
||||
[X(103.5), Y(8), function (q) { q.box(X(103.1), Y(7.75), X(103.9), Y(8.25), z + 0.85, z + 1.45, "iso-instr2"); }],
|
||||
[X(105), Y(8), function (q) { q.box(X(104.7), Y(7.8), X(105.3), Y(8.2), z + 0.85, z + 1.6, "iso-speaker"); }]]);
|
||||
sc.tag(X(102.5), Y(6), z + 2.4, "QC + listening", 4, "qc");
|
||||
sc.sprite("packaging").box(X(93), Y(12), X(97), Y(13.2), z, z + 0.9, "iso-bench");
|
||||
sc.sprite("packaging").box(X(93), Y(15), X(97), Y(16.2), z, z + 0.9, "iso-bench");
|
||||
var sh = sc.sprite("packaging"); sh.box(X(99), Y(12), X(103.4), Y(13.1), z, z + 1.3, "iso-shrink"); sh.open([X(99), Y(12)], [X(103.4), Y(12)], [[1.4, 3.0, z + 0.3, z + 1.1]], "iso-open");
|
||||
var pw = sc.sprite("packaging"); pw.cyl(X(103.4), Y(19), 1.0, z, z + 0.15, "iso-steel"); pw.box(X(103.2), Y(17.8), X(103.6), Y(18.1), z, z + 2.4, "iso-steel");
|
||||
pw.box(X(102.85), Y(18.45), X(103.95), Y(19.55), z + 0.15, z + 1.4, "iso-carton");
|
||||
[[94.5, 19.5], [97, 19.5], [94.5, 17.8]].forEach(function (p) { sc.sprite("packaging").box(X(p[0] - 0.6), Y(p[1] - 0.5), X(p[0] + 0.6), Y(p[1] + 0.5), z, z + 1.2, "iso-carton"); });
|
||||
sc.tag(X(99), Y(16.5), z + 2.6, "Packaging", 5, "packaging");
|
||||
if (cfg.cassette) {
|
||||
var cb = sc.sprite("cassette"); cb.box(X(93), Y(22.2), X(96.6), Y(23.2), z, z + 0.85, "iso-bench");
|
||||
cb.seq([0, 1, 2].map(function (k) { return [X(93.6 + k * 1.1), Y(22.7), function (q) { q.box(X(93.3 + k * 1.1), Y(22.4), X(94.0 + k * 1.1), Y(23.0), z + 0.85, z + 1.15, "iso-cass"); }]; }));
|
||||
sc.inf("cassette", "Cassette duplication", "Bench line, ~40 to 80 m2 (project-timeline.md)");
|
||||
sc.tag(X(94.8), Y(22.7), z + 2.2, "Cassette", 3, "cassette");
|
||||
}
|
||||
if (cfg.cdr) {
|
||||
var cd = sc.sprite("cdr"); cd.box(X(98), Y(22.2), X(100.6), Y(23.2), z, z + 0.85, "iso-bench"); cd.box(X(98.4), Y(22.35), X(99.2), Y(23.05), z + 0.85, z + 1.6, "iso-cdtower"); cd.led(X(98.8), Y(22.7), z + 1.62, "iso-ledg");
|
||||
sc.inf("cdr", "CD-R duplication, short run", "Tower duplicator and printer bench, ~20 to 40 m2 (project-timeline.md)");
|
||||
sc.tag(X(99.3), Y(22.7), z + 2.2, "CD-R", 3, "cdr");
|
||||
}
|
||||
// finishing and print block, ground floor (block floor plans): along the corridor trim + optical, QC lab,
|
||||
// stair + goods lift; packaging behind with the cassette and CD-R benches; the upper floor is drawn at 1F
|
||||
if (!up) finishingGF(sc, cfg, z);
|
||||
// warehouse: three racking rows; dispatch: staged pallets and a forklift
|
||||
[5, 11.5, 18].forEach(function (fy) { rackRow(sc, "warehouse", X(107.2), Y(fy), X(119.2), Y(fy + 1.2), z, 5.6, 4, 0, ["iso-pal-bx", "iso-pal-bx", "iso-pal-w", "", "iso-pal-bx"], "iso-rackf"); });
|
||||
sc.tag(X(113), Y(12), z + 6.4, "Warehouse", 6, "warehouse");
|
||||
@@ -1839,15 +1866,99 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
sc.tag(X(124), Y(10), z + 2.6, "Dispatch", 3, "dispatch");
|
||||
sc.tag(X(66), Y(16), z + 3.8, "Press hall", 7, "presshall");
|
||||
sc.tag(X(19.5), Y(14), z + 3.4, cfg.galvanics ? "Galvanics" : "Galvanics (empty)", 6, "galvanics");
|
||||
sc.tag(X(99), Y(4), z + 3.4, "Finishing", 5, "packaging");
|
||||
}
|
||||
// finishing and print block, ground floor (fx 92..106)
|
||||
function finishingGF(sc, cfg, z) {
|
||||
// trim and optical inspection (fx 92..96): the record path ends at the trimmer
|
||||
var tr = sc.sprite("trim"); tr.box(X(93.0), Y(3.0), X(94.1), Y(4.1), z, z + 1.1, "iso-steel"); tr.disc(X(93.55), Y(3.55), z + 1.12, 0.26, "iso-vinylc");
|
||||
var op = sc.sprite("trim"); op.box(X(94.35), Y(2.95), X(95.75), Y(4.3), z, z + 1.5, "iso-optic"); op.cyl(X(95.05), Y(3.6), 0.35, z + 1.5, z + 1.8, "iso-dome"); op.led(X(95.05), Y(3.6), z + 1.82, "iso-ledg");
|
||||
sc.sprite("trim").box(X(94.6), Y(5.0), X(95.5), Y(5.8), z, z + 0.8, "iso-bin");
|
||||
sc.tag(X(94), Y(5), z + 2.6, "Trim + optical", 4, "trim");
|
||||
// QC lab (fx 96..100): bench on the packaging side
|
||||
var qb = sc.sprite("qc"); qb.box(X(96.3), Y(6.7), X(99.7), Y(7.5), z, z + 0.85, "iso-bench");
|
||||
qb.seq([[X(97), Y(7.1), function (q) { q.box(X(96.5), Y(6.8), X(97.5), Y(7.4), z + 0.85, z + 1.0, "iso-instr"); q.disc(X(97), Y(7.1), z + 1.02, 0.24, "iso-vinylc"); }],
|
||||
[X(98.3), Y(7.1), function (q) { q.box(X(97.95), Y(6.85), X(98.65), Y(7.35), z + 0.85, z + 1.45, "iso-instr2"); }],
|
||||
[X(99.3), Y(7.1), function (q) { q.box(X(99.0), Y(6.9), X(99.55), Y(7.3), z + 0.85, z + 1.6, "iso-speaker"); }]]);
|
||||
sc.tag(X(98), Y(5), z + 2.4, "QC + listening", 4, "qc");
|
||||
// stair and goods lift (fx 100..106), the same footprint on both levels
|
||||
blockCore(sc, z, false);
|
||||
sc.tag(X(103), Y(4.5), z + 3.0, "Stair + goods lift", 2, "block-stair");
|
||||
// packaging (~170 m2): packing tables, shrink wrap, pallet wrapper, cartons
|
||||
[[93, 13.9, 96, 15.1], [93, 10.9, 96, 12.1], [97, 10.9, 100, 12.1]].forEach(function (t) { sc.sprite("packaging").box(X(t[0]), Y(t[1]), X(t[2]), Y(t[3]), z, z + 0.9, "iso-bench"); });
|
||||
var sh = sc.sprite("packaging"); sh.box(X(97), Y(14.8), X(99.8), Y(15.9), z, z + 1.3, "iso-shrink"); sh.open([X(97), Y(14.8)], [X(99.8), Y(14.8)], [[0.6, 2.2, z + 0.3, z + 1.1]], "iso-open");
|
||||
var pw = sc.sprite("packaging"); pw.cyl(X(102.75), Y(15.25), 1.0, z, z + 0.15, "iso-steel"); pw.box(X(102.55), Y(16.45), X(102.95), Y(16.75), z, z + 2.4, "iso-steel");
|
||||
pw.box(X(102.2), Y(14.7), X(103.3), Y(15.8), z + 0.15, z + 1.4, "iso-carton");
|
||||
[[104.9, 12.4], [104.9, 13.8], [103.5, 12.4]].forEach(function (p) { sc.sprite("packaging").box(X(p[0] - 0.6), Y(p[1] - 0.5), X(p[0] + 0.6), Y(p[1] + 0.5), z, z + 1.2, "iso-carton"); });
|
||||
sc.tag(X(98.5), Y(13), z + 2.6, "Packaging", 5, "packaging");
|
||||
sc.tag(X(99), Y(9.5), z + 3.6, "Finishing", 5, "packaging");
|
||||
if (cfg.cassette) {
|
||||
var cb = sc.sprite("cassette"); cb.box(X(93), Y(18.7), X(96.6), Y(19.7), z, z + 0.85, "iso-bench");
|
||||
cb.seq([0, 1, 2].map(function (k) { return [X(93.6 + k * 1.1), Y(19.2), function (q) { q.box(X(93.3 + k * 1.1), Y(18.9), X(94.0 + k * 1.1), Y(19.5), z + 0.85, z + 1.15, "iso-cass"); }]; }));
|
||||
sc.tag(X(94.8), Y(19.2), z + 2.2, "Cassette", 3, "cassette");
|
||||
}
|
||||
if (cfg.cdr) {
|
||||
var cd = sc.sprite("cdr"); cd.box(X(98), Y(18.7), X(100.6), Y(19.7), z, z + 0.85, "iso-bench"); cd.box(X(98.4), Y(18.85), X(99.2), Y(19.55), z + 0.85, z + 1.6, "iso-cdtower"); cd.led(X(98.8), Y(19.2), z + 1.62, "iso-ledg");
|
||||
sc.tag(X(99.3), Y(19.2), z + 2.2, "CD-R", 3, "cdr");
|
||||
}
|
||||
}
|
||||
// stair and goods lift of the block (fx 100..106, fy 2.6..7.9): a stair block on the ground floor, the stair well upstairs
|
||||
function blockCore(sc, z, upper) {
|
||||
var s = sc.sprite("block-stair"), st = [], k, a = X(100.4), b = X(101.5), c = Y(2.95), d = Y(7.5);
|
||||
for (k = 1; k < 8; k++) st.push([a, c + k * 0.57, b, c + k * 0.57]);
|
||||
if (!upper) { s.box(a, c, b, d, z, z + 1.6, "iso-stair"); s.lines(st, z + 1.61, "iso-steps"); }
|
||||
else { s.flat(rect(a, c, b, d), z + 0.01, "iso-void", "block-stair"); s.lines(st, z + 0.02, "iso-steps"); s.box(b, c, b + 0.08, d, z, z + 1.0, "iso-rail2"); }
|
||||
var lf = sc.sprite("block-stair"), L = sides(X(103.4), Y(2.95), X(105.6), Y(5.4));
|
||||
lf.box(X(103.4), Y(2.95), X(105.6), Y(5.4), z, z + 2.4, "iso-lift", { top: "iso-cut" });
|
||||
lf.open(L.N[0], L.N[1], [[0.5, 1.7, z, z + 2.1]], "iso-door").open(L.W[0], L.W[1], [[0.4, 1.6, z, z + 2.1]], "iso-door");
|
||||
}
|
||||
// 1F: the finishing and print block's upper floor at +3.8 m on a closed lower storey
|
||||
function blockUpper(sc, cfg) {
|
||||
var P = sc.P, z = FFL + BLK.up, a = X(BLK.fx0), b = X(105.85), c = Y(0.3), d = Y(FW - 0.3), t = 0.25;
|
||||
var s = sc.sprite("printblock");
|
||||
s.box(a, c, b, d, FFL, z, "iso-wall", { top: "iso-cut" });
|
||||
var rooms = [[92, 0.3, 100, 11.95, "iso-z-print", "printroom"], [92, 11.95, 100, 24.7, "iso-z-stock", "printstock"],
|
||||
[100, 7.9, 105.85, 24.7, "iso-z-packmat", "packmat"], [100, 0.3, 105.85, 7.9, "iso-z-core", "block-stair"]], segs = [];
|
||||
rooms.forEach(function (r) {
|
||||
var p = X(r[0]), q = Y(r[1]), u = X(r[2]), v = Y(r[3]);
|
||||
s.flat(rect(p, q, u, v), z + 0.005, r[4] + " iso-t", r[5]);
|
||||
segs.push([p, q, u, q], [u, q, u, v], [u, v, p, v], [p, v, p, q]);
|
||||
});
|
||||
s.lines(segs, z + 0.01, "iso-part");
|
||||
// walls cut above the slab; the east side is the fire wall
|
||||
[[a, c, b, c + t, 0, -1, "iso-wall"], [a, d - t, b, d, 0, 1, "iso-wall"], [a, c + t, a + t, d - t, -1, 0, "iso-wall"], [b - t, c + t, b, d - t, 1, 0, "iso-firewall"]].forEach(function (w) {
|
||||
sc.sprite("printblock").box(w[0], w[1], w[2], w[3], z, z + (P.vis(w[4], w[5]) ? 1.0 : 2.4), w[6], { top: "iso-cut" });
|
||||
});
|
||||
// print stock: paper and board racking; packaging materials: sleeves, inner bags, mailers, cartons
|
||||
[14.0, 18.0, 22.0].forEach(function (fy) { rackRow(sc, "printstock", X(92.6), Y(fy), X(99.4), Y(fy + 1.0), z, 2.2, 3, 0, ["iso-pal-w", "iso-pal-bx", "iso-pal-w", ""], "iso-shelf"); });
|
||||
[10.0, 14.0, 18.0, 22.0].forEach(function (fy) { rackRow(sc, "packmat", X(100.6), Y(fy), X(105.2), Y(fy + 1.0), z, 2.2, 3, 0, ["iso-pal-bx", "iso-pal-w", "iso-pal-bx", ""], "iso-shelf"); });
|
||||
// print room in reserve: a free position, nothing installed
|
||||
sc.sprite("printroom").flat(rect(X(93), Y(3.9), X(98), Y(6.9)), z + 0.02, "iso-slot iso-empty", "printroom");
|
||||
blockCore(sc, z, true);
|
||||
sc.tag(X(95.5), Y(5.4), z + 1.6, "Print room (reserve)", 7, "printroom");
|
||||
sc.tag(X(96), Y(18), z + 3.0, "Print stock", 6, "printstock");
|
||||
sc.tag(X(103), Y(16), z + 3.0, "Packaging materials", 6, "packmat");
|
||||
sc.tag(X(103), Y(4.5), z + 3.0, "Stair + goods lift", 3, "block-stair");
|
||||
sc.tag(X(99), Y(12.5), z + 5.2, "Upper floor +3.8 m", 9, "printblock");
|
||||
}
|
||||
// Pipe bridge over the 6 m lane: the deck runs between the factory's north wall (y 94) and the
|
||||
// yard building (y 101); at both ends the pipes drop down the wall face to low-level wall sleeves,
|
||||
// so the run never ends in the air (the pump/HX room is lower than the deck, and the GF cutaway
|
||||
// trims the walls below it). User feedback, October 2026.
|
||||
function pipeBridge(sc, x) {
|
||||
var s = sc.sprite("pipebridge");
|
||||
var s = sc.sprite("pipebridge"), Y0 = 94.3, Y1 = 100.7, parts = [];
|
||||
s.box(x - 0.15, 96.85, x + 0.15, 97.15, 0, 5.0, "iso-steel", { noTop: true });
|
||||
s.box(x - 0.9, 94, x + 0.9, 101, 5.0, 5.3, "iso-steel");
|
||||
s.seq([[x - 0.55, 97.5, function (q) { q.box(x - 0.7, 94, x - 0.4, 101, 5.3, 5.62, "iso-pipes"); }],
|
||||
[x - 0.05, 97.5, function (q) { q.box(x - 0.2, 94, x + 0.1, 101, 5.3, 5.62, "iso-pipec"); }],
|
||||
[x + 0.45, 97.5, function (q) { q.box(x + 0.3, 94, x + 0.6, 101, 5.3, 5.62, "iso-pipec2"); }]]);
|
||||
s.box(x - 0.15, 99.35, x + 0.15, 99.65, 0, 5.0, "iso-steel", { noTop: true });
|
||||
s.box(x - 0.9, Y0, x + 0.9, Y1, 5.0, 5.3, "iso-steel");
|
||||
// wall sleeves where the pipes enter
|
||||
s.box(x - 0.85, 93.9, x + 0.85, 94.1, 0.3, 0.9, "iso-steel");
|
||||
s.box(x - 0.85, 100.9, x + 0.85, 101.1, 0.3, 0.9, "iso-steel");
|
||||
[[-0.7, -0.4, "iso-pipes"], [-0.2, 0.1, "iso-pipec"], [0.3, 0.6, "iso-pipec2"]].forEach(function (pp) {
|
||||
var a = x + pp[0], b = x + pp[1], c = pp[2];
|
||||
parts.push([(a + b) / 2, 97.5, function (q) { q.box(a, Y0, b, Y1, 5.3, 5.62, c); }]);
|
||||
parts.push([(a + b) / 2, 94.2, function (q) { q.box(a, 94.0, b, Y0, 0.5, 5.62, c); }]);
|
||||
parts.push([(a + b) / 2, 100.8, function (q) { q.box(a, Y1, b, 101.0, 0.5, 5.62, c); }]);
|
||||
});
|
||||
s.seq(parts);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------ utility yard
|
||||
@@ -2054,34 +2165,71 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------ office building
|
||||
function office(sc, cfg, inside) {
|
||||
var o = OFC, P = sc.P, x0 = o.x0, y0 = o.y0, x1 = o.x1, y1 = o.y1;
|
||||
sc.inf("office", "Office building, 32 x 15 m", "Two storeys (~960 m2): reception, canteen, changing rooms, mastering and cutting, listening, archive; offices, training and IT upstairs. Isolated from the factory floor, joined by a covered link (site-candidates.md).");
|
||||
// Rooms after the floor plans (cnx_vinyl_parametric_payap-office.png): [u0, v0, u1, v1, zone, id] in metres
|
||||
// from the west end (u) and from the south facade (v). Stair and lift sit in the same place on both storeys.
|
||||
var OFC_GF = [
|
||||
[0, 0, 6, 15, "iso-z-lobby", "office"], [6, 7.05, 32, 9.1, "iso-z-hall", "office"],
|
||||
[6, 9.1, 10, 15, "iso-z-core", "office-stair"], [10, 9.1, 14.5, 15, "iso-z-staff", "changing"], [14.5, 9.1, 19, 15, "iso-z-staff2", "changing"],
|
||||
[19, 9.1, 23, 15, "iso-z-arch", "archive"], [23, 9.1, 32, 15, "iso-z-cut", "cutting"],
|
||||
[6, 0, 18, 7.05, "iso-z-canteen", "canteen"], [18, 0, 22, 7.05, "iso-z-kitchen", "canteen"], [22, 0, 26, 7.05, "iso-z-wc", "office-wc"],
|
||||
[26, 0, 32, 7.05, "iso-z-listen", "listening"]
|
||||
];
|
||||
var OFC_1F = [
|
||||
[0, 9.1, 6, 15, "iso-z-meet", "meetingroom"], [6, 9.1, 10, 15, "iso-z-core", "office-stair"], [10, 9.1, 13.5, 15, "iso-z-it", "itroom"],
|
||||
[13.5, 9.1, 16.6, 15, "iso-z-wc", "wc-1f"], [16.6, 9.1, 19, 15, "iso-z-pantry", "pantry"], [19, 9.1, 32, 15, "iso-z-flex", "flexroom"],
|
||||
[0, 7.05, 32, 9.1, "iso-z-hall", "office"], [0, 0, 22, 7.05, "iso-z-offices", "offices"], [22, 0, 32, 7.05, "iso-z-meet2", "training"]
|
||||
];
|
||||
var OFC_UP = 4.0; // storey height: first floor at z0 + 4.0 (8 m to the roof for two storeys)
|
||||
function officeInfo(sc, cfg) {
|
||||
sc.inf("office", "Office building, 32 x 15 m",
|
||||
"Two storeys (~960 m2) with a stair and a lift. Ground floor: reception and lobby, canteen, changing rooms, toilets, mastering and cutting, listening room, archive. " +
|
||||
"First floor: offices, meeting and training, a meeting room, IT and server room, toilets, pantry, a flexible room. Isolated from the factory floor, joined by a covered link (site-candidates.md).");
|
||||
sc.inf("cutting", cfg.cutting ? "Mastering and cutting room" : "Cutting room: cut abroad",
|
||||
cfg.cutting ? "Sillitoe SDMS lathe (USD 125k list) on the ground slab, away from press vibration and outside the crane zone; inner acoustic lining" :
|
||||
"Lacquers are cut by an outside studio (SST Frankfurt cuts Poy Records' lacquers today); the room stays for mastering");
|
||||
sc.inf("lathe", "Sillitoe SDMS cutting lathe", "Integrated Space / Time Control automation, USD 125k published list price (vendor-landscape.md)");
|
||||
sc.inf("archive", "Archive: mobile shelving", "The father and the mother of every side; two fixed runs and four double-sided carriages, ~150 shelf metres, ~50,000 parts (facility-security.md, estimates)");
|
||||
sc.inf("archive", "Archive: mobile shelving", "The father and the mother of every side; two fixed runs and four double-sided carriages, ~150 shelf metres, ~50,000 parts, on the ground slab (facility-security.md, estimates)");
|
||||
sc.inf("listening", "Listening room", "Start of the tour with the cutting-room window");
|
||||
sc.inf("canteen", "Canteen and kitchen", "For about 40");
|
||||
sc.inf("changing", "Changing rooms", "Women and men, four showers each; staff change here before crossing to the factory");
|
||||
sc.inf("link", "Covered link", "Office to the start of the visitor corridor");
|
||||
// covered link (both modes)
|
||||
sc.inf("office-stair", "Stair and lift", "Connect the two storeys of the office building (site-candidates.md)");
|
||||
sc.inf("office-wc", "Toilets", "Ground floor of the office building");
|
||||
sc.inf("offices", "Offices, ~150 m2", "First floor of the office building (site-candidates.md)");
|
||||
sc.inf("training", "Meeting and training room", "For the Payap programmes: mastering and lathe cutting, IT, business administration (payap-partnership.md); first floor");
|
||||
sc.inf("meetingroom", "Meeting room", "First floor of the office building");
|
||||
sc.inf("itroom", "IT and server room", "First floor of the office building");
|
||||
sc.inf("wc-1f", "Toilets", "First floor of the office building");
|
||||
sc.inf("pantry", "Pantry", "First floor of the office building");
|
||||
sc.inf("flexroom", "Flexible room", "A second classroom or more offices; first floor (site-candidates.md)");
|
||||
}
|
||||
// facade openings: ground floor band always, the upper band only on the closed building (roof level)
|
||||
function officeWindows(s, S, o, both) {
|
||||
var gl = [], ul = [], wl = [], u, i;
|
||||
for (u = 8.5, i = 0; u < 31; u += 3, i++) (hash(i + 3) > 0.35 ? gl : wl).push([u, u + 1.8, o.z0 + 0.9, o.z0 + 2.7]);
|
||||
if (both) for (u = 1, i = 0; u < 31; u += 3, i++) (hash(i + 9) > 0.4 ? ul : wl).push([u, u + 1.8, o.z0 + 4.8, o.z0 + 6.8]);
|
||||
s.open(S.S[0], S.S[1], wl, "iso-win").open(S.S[0], S.S[1], gl.concat(ul), "iso-win iso-lit").open(S.S[0], S.S[1], [[0.6, 5.6, o.z0, o.z0 + 3.2]], "iso-glass", "office");
|
||||
["E", "W", "N"].forEach(function (k, j) {
|
||||
var L = k === "N" ? 32 : 15, a = [], b = [];
|
||||
for (u = 1.2, i = 0; u < L - 1.5; u += 3, i++) {
|
||||
(hash(i + j * 17) > 0.45 ? a : b).push([u, u + 1.8, o.z0 + 0.9, o.z0 + 2.7]);
|
||||
if (both) (hash(i + j * 29 + 5) > 0.45 ? a : b).push([u, u + 1.8, o.z0 + 4.8, o.z0 + 6.8]);
|
||||
}
|
||||
s.open(S[k][0], S[k][1], b, "iso-win").open(S[k][0], S[k][1], a, "iso-win iso-lit");
|
||||
});
|
||||
}
|
||||
function office(sc, cfg, level) {
|
||||
var o = OFC, x0 = o.x0, y0 = o.y0, x1 = o.x1, y1 = o.y1, S = sides(x0, y0, x1, y1);
|
||||
officeInfo(sc, cfg);
|
||||
// covered link (all levels)
|
||||
var lk = sc.sprite("link");
|
||||
lk.seq([[15.7, 57.4], [18.3, 57.4], [15.7, 68.6], [18.3, 68.6]].map(function (p) { return [p[0], p[1], function (q) { q.box(p[0] - 0.1, p[1] - 0.1, p[0] + 0.1, p[1] + 0.1, 0, 3.5, "iso-steel", { noTop: true }); }]; }));
|
||||
lk.box(15.5, 57, 18.5, 69, 3.5, 3.75, "iso-roof3");
|
||||
if (!inside) {
|
||||
var s = sc.sprite("office"), S = sides(x0, y0, x1, y1), gl = [], ul = [], wl = [], u, i;
|
||||
if (level === "roof") {
|
||||
var s = sc.sprite("office");
|
||||
s.box(x0, y0, x1, y1, 0, o.z0, "iso-plinth");
|
||||
s.box(x0, y0, x1, y1, o.z0, o.z1, "iso-office", { top: "iso-roof3" });
|
||||
for (u = 8.5, i = 0; u < 31; u += 3, i++) (hash(i + 3) > 0.35 ? gl : wl).push([u, u + 1.8, o.z0 + 0.9, o.z0 + 2.7]);
|
||||
for (u = 1, i = 0; u < 31; u += 3, i++) (hash(i + 9) > 0.4 ? ul : wl).push([u, u + 1.8, o.z0 + 4.8, o.z0 + 6.8]);
|
||||
s.open(S.S[0], S.S[1], wl, "iso-win").open(S.S[0], S.S[1], gl.concat(ul), "iso-win iso-lit").open(S.S[0], S.S[1], [[0.6, 7.2, o.z0, o.z0 + 3.2]], "iso-glass", "office");
|
||||
["E", "W", "N"].forEach(function (k, j) {
|
||||
var L = k === "N" ? 32 : 15, a = [], b = [];
|
||||
for (u = 1.2, i = 0; u < L - 1.5; u += 3, i++) { (hash(i + j * 17) > 0.45 ? a : b).push([u, u + 1.8, o.z0 + 0.9, o.z0 + 2.7]); (hash(i + j * 29 + 5) > 0.45 ? a : b).push([u, u + 1.8, o.z0 + 4.8, o.z0 + 6.8]); }
|
||||
s.open(S[k][0], S[k][1], b, "iso-win").open(S[k][0], S[k][1], a, "iso-win iso-lit");
|
||||
});
|
||||
officeWindows(s, S, o, true);
|
||||
s.flat(rect(x0 + 0.4, y0 + 0.4, x1 - 0.4, y1 - 0.4), o.z1 + 0.01, "iso-roofin");
|
||||
s.seq([[x0 + 20.8, y0 + 5.6], [x0 + 23.4, y0 + 5.6], [x0 + 26, y0 + 9.4]].map(function (p) {
|
||||
return [p[0], p[1], function (q) { q.box(p[0] - 0.8, p[1] - 0.6, p[0] + 0.8, p[1] + 0.6, o.z1, o.z1 + 1.0, "iso-ac"); q.disc(p[0], p[1], o.z1 + 1.01, 0.42, "iso-fanring"); }];
|
||||
@@ -2089,66 +2237,110 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
sc.tag((x0 + x1) / 2, (y0 + y1) / 2, o.z1 + 1.5, "Office", 9, "office");
|
||||
return;
|
||||
}
|
||||
var f = sc.sprite("office"), z = o.z0;
|
||||
f.box(x0, y0, x1, y1, 0, z, "iso-plinth");
|
||||
var rooms = [[0, 0, 7, 15, "iso-z-lobby", "office"], [7, 8, 15, 15, cfg.cutting ? "iso-z-cut" : "iso-z-floor", "cutting"], [15, 8, 20, 15, "iso-z-listen", "listening"],
|
||||
[20, 8, 24, 15, "iso-z-arch", "archive"], [24, 8, 32, 15, "iso-z-staff", "changing"], [7, 0, 25, 8, "iso-z-canteen", "canteen"], [25, 0, 32, 8, "iso-z-staff", "canteen"]];
|
||||
var segs = [];
|
||||
rooms.forEach(function (r) {
|
||||
f.flat(rect(x0 + r[0], y0 + r[1], x0 + r[2], y0 + r[3]), z + 0.005, r[4] + " iso-t", r[5]);
|
||||
var a = x0 + r[0], b = y0 + r[1], c = x0 + r[2], d = y0 + r[3];
|
||||
var up = level === "1f", z = up ? o.z0 + OFC_UP : o.z0, f = sc.sprite("office"), segs = [];
|
||||
f.box(x0, y0, x1, y1, 0, o.z0, "iso-plinth");
|
||||
if (up) { f.box(x0, y0, x1, y1, o.z0, z, "iso-office", { top: "iso-cut" }); officeWindows(f, S, o, false); }
|
||||
(up ? OFC_1F : OFC_GF).forEach(function (r) {
|
||||
var cls = r[5] === "cutting" && !cfg.cutting ? "iso-z-floor" : r[4], a = x0 + r[0], b = y0 + r[1], c = x0 + r[2], d = y0 + r[3];
|
||||
f.flat(rect(a, b, c, d), z + 0.005, cls + " iso-t", r[5]);
|
||||
segs.push([a, b, c, b], [c, b, c, d], [c, d, a, d], [a, d, a, b]);
|
||||
});
|
||||
f.lines(segs, z + 0.01, "iso-part");
|
||||
wallsCut(sc, "office", x0, y0, x1, y1, z, 1.0, 3.0, 0.25, "iso-office");
|
||||
// lobby: reception desk, stair
|
||||
sc.sprite("office").box(x0 + 1, y0 + 3, x0 + 4, y0 + 3.8, z, z + 1.1, "iso-desk");
|
||||
var stair = sc.sprite("office"); stair.box(x0 + 4.4, y0 + 9.6, x0 + 6.6, y0 + 14.4, z, z + 1.6, "iso-stair");
|
||||
var steps = []; for (var si = 1; si < 8; si++) steps.push([x0 + 4.4, y0 + 9.6 + si * 0.6, x0 + 6.6, y0 + 9.6 + si * 0.6]);
|
||||
stair.lines(steps, z + 1.61, "iso-steps");
|
||||
// cutting room
|
||||
officeCore(sc, z, up);
|
||||
if (up) officeUpper(sc, cfg, z); else officeGround(sc, cfg, z);
|
||||
}
|
||||
// stair (u 6.2..7.4) and lift (u 8.0..9.8) on the north side, off the corridor
|
||||
function officeCore(sc, z, up) {
|
||||
var x0 = OFC.x0, y0 = OFC.y0, s = sc.sprite("office-stair"), st = [], k, a = x0 + 6.2, b = x0 + 7.4, c = y0 + 9.3, d = y0 + 14.8;
|
||||
for (k = 1; k < 9; k++) st.push([a, c + k * 0.61, b, c + k * 0.61]);
|
||||
if (!up) { s.box(a, c, b, d, z, z + 1.6, "iso-stair"); s.lines(st, z + 1.61, "iso-steps"); }
|
||||
else { s.flat(rect(a, c, b, d), z + 0.01, "iso-void", "office-stair"); s.lines(st, z + 0.02, "iso-steps"); s.box(b, c, b + 0.08, d, z, z + 1.0, "iso-rail2"); }
|
||||
var lf = sc.sprite("office-stair"), L = sides(x0 + 8.0, y0 + 12.8, x0 + 9.8, y0 + 14.65);
|
||||
lf.box(x0 + 8.0, y0 + 12.8, x0 + 9.8, y0 + 14.65, z, z + 2.4, "iso-lift", { top: "iso-cut" });
|
||||
lf.open(L.S[0], L.S[1], [[0.4, 1.4, z, z + 2.1]], "iso-door");
|
||||
}
|
||||
function officeGround(sc, cfg, z) {
|
||||
var x0 = OFC.x0, y0 = OFC.y0;
|
||||
// lobby: reception desk near the entrance
|
||||
sc.sprite("office").box(x0 + 1, y0 + 2.0, x0 + 3.2, y0 + 2.8, z, z + 1.1, "iso-desk");
|
||||
sc.tag(x0 + 3, y0 + 7, z + 2.6, "Reception", 3, "office");
|
||||
// mastering and cutting (north-east), inner acoustic lining
|
||||
sc.sprite("cutting").flat(rect(x0 + 23.3, y0 + 9.4, x0 + 31.7, y0 + 14.7), z + 0.012, "iso-lining", "cutting");
|
||||
if (cfg.cutting) {
|
||||
var lt = sc.sprite("lathe");
|
||||
lt.box(x0 + 9, y0 + 11, x0 + 11.2, y0 + 12.3, z, z + 1.0, "iso-lathe");
|
||||
lt.seq([[x0 + 9.7, y0 + 11.65, function (q) { q.disc(x0 + 9.7, y0 + 11.65, z + 1.02, 0.42, "iso-platter"); q.disc(x0 + 9.7, y0 + 11.65, z + 1.04, 0.36, "iso-lacquer"); }],
|
||||
[x0 + 10.7, y0 + 11.65, function (q) { q.box(x0 + 10.45, y0 + 11.3, x0 + 10.95, y0 + 12.0, z + 1.0, z + 1.5, "iso-steel"); q.box(x0 + 10.0, y0 + 11.55, x0 + 10.6, y0 + 11.75, z + 1.4, z + 1.55, "iso-steel"); }]]);
|
||||
lt.led(x0 + 11.2, y0 + 11.3, z + 0.8, "iso-ledo");
|
||||
var md = sc.sprite("cutting"); md.box(x0 + 12.4, y0 + 8.8, x0 + 14.6, y0 + 9.7, z, z + 0.75, "iso-desk");
|
||||
md.seq([[x0 + 13, y0 + 9.4, function (q) { q.box(x0 + 12.7, y0 + 9.3, x0 + 13.3, y0 + 9.45, z + 0.75, z + 1.2, "iso-screenm"); }],
|
||||
[x0 + 14, y0 + 9.4, function (q) { q.box(x0 + 13.7, y0 + 9.3, x0 + 14.3, y0 + 9.45, z + 0.75, z + 1.2, "iso-screenm"); }]]);
|
||||
sc.sprite("cutting").box(x0 + 7.6, y0 + 14.2, x0 + 8.2, y0 + 14.7, z, z + 1.1, "iso-speaker");
|
||||
sc.sprite("cutting").box(x0 + 13.8, y0 + 14.2, x0 + 14.4, y0 + 14.7, z, z + 1.1, "iso-speaker");
|
||||
sc.tag(x0 + 10.1, y0 + 11.6, z + 2.6, "Lathe", 7, "lathe");
|
||||
lt.box(x0 + 24.2, y0 + 10.4, x0 + 26.4, y0 + 11.7, z, z + 1.0, "iso-lathe");
|
||||
lt.seq([[x0 + 24.9, y0 + 11.05, function (q) { q.disc(x0 + 24.9, y0 + 11.05, z + 1.02, 0.42, "iso-platter"); q.disc(x0 + 24.9, y0 + 11.05, z + 1.04, 0.36, "iso-lacquer"); }],
|
||||
[x0 + 25.9, y0 + 11.05, function (q) { q.box(x0 + 25.65, y0 + 10.7, x0 + 26.15, y0 + 11.4, z + 1.0, z + 1.5, "iso-steel"); q.box(x0 + 25.2, y0 + 10.95, x0 + 25.8, y0 + 11.15, z + 1.4, z + 1.55, "iso-steel"); }]]);
|
||||
lt.led(x0 + 26.4, y0 + 10.7, z + 0.8, "iso-ledo");
|
||||
var md = sc.sprite("cutting"); md.box(x0 + 27.5, y0 + 12.8, x0 + 29.7, y0 + 13.7, z, z + 0.75, "iso-desk");
|
||||
md.seq([[x0 + 28.1, y0 + 13.5, function (q) { q.box(x0 + 27.8, y0 + 13.45, x0 + 28.4, y0 + 13.6, z + 0.75, z + 1.2, "iso-screenm"); }],
|
||||
[x0 + 29.1, y0 + 13.5, function (q) { q.box(x0 + 28.8, y0 + 13.45, x0 + 29.4, y0 + 13.6, z + 0.75, z + 1.2, "iso-screenm"); }]]);
|
||||
sc.sprite("cutting").box(x0 + 27.0, y0 + 14.0, x0 + 27.6, y0 + 14.5, z, z + 1.1, "iso-speaker");
|
||||
sc.sprite("cutting").box(x0 + 29.6, y0 + 14.0, x0 + 30.2, y0 + 14.5, z, z + 1.1, "iso-speaker");
|
||||
sc.tag(x0 + 25.3, y0 + 11, z + 2.6, "Lathe", 7, "lathe");
|
||||
} else {
|
||||
var sg = sc.sprite("cutting"); sg.box(x0 + 10.9, y0 + 11, x0 + 11.05, y0 + 12.6, z, z + 1.0, "iso-steel"); sg.box(x0 + 10.85, y0 + 10.9, x0 + 11.1, y0 + 12.7, z + 1.0, z + 2.0, "iso-sign");
|
||||
sc.tag(x0 + 11, y0 + 11.8, z + 2.6, "Cut abroad", 100, "cutting", "iso-signtag");
|
||||
var sg = sc.sprite("cutting"); sg.box(x0 + 25.9, y0 + 11, x0 + 26.05, y0 + 12.6, z, z + 1.0, "iso-steel"); sg.box(x0 + 25.85, y0 + 10.9, x0 + 26.1, y0 + 12.7, z + 1.0, z + 2.0, "iso-sign");
|
||||
sc.tag(x0 + 26, y0 + 11.8, z + 2.6, "Cut abroad", 100, "cutting", "iso-signtag");
|
||||
}
|
||||
sc.tag(x0 + 11, y0 + 9.5, z + 3.4, cfg.cutting ? "Cutting room" : "Cutting room (empty)", 6, "cutting");
|
||||
// listening room
|
||||
sc.sprite("listening").box(x0 + 16, y0 + 9, x0 + 19, y0 + 9.9, z, z + 0.6, "iso-sofa");
|
||||
sc.sprite("listening").box(x0 + 15.6, y0 + 14, x0 + 16.2, y0 + 14.6, z, z + 1.2, "iso-speaker");
|
||||
sc.sprite("listening").box(x0 + 18.8, y0 + 14, x0 + 19.4, y0 + 14.6, z, z + 1.2, "iso-speaker");
|
||||
sc.tag(x0 + 28, y0 + 12.5, z + 3.4, cfg.cutting ? "Cutting room" : "Cutting room (empty)", 6, "cutting");
|
||||
// listening room (south-east): seats facing the speakers on the corridor wall
|
||||
sc.sprite("listening").box(x0 + 28.0, y0 + 2.0, x0 + 30.5, y0 + 2.8, z, z + 0.6, "iso-sofa");
|
||||
sc.sprite("listening").box(x0 + 26.6, y0 + 6.2, x0 + 27.2, y0 + 6.7, z, z + 1.2, "iso-speaker");
|
||||
sc.sprite("listening").box(x0 + 30.8, y0 + 6.2, x0 + 31.4, y0 + 6.7, z, z + 1.2, "iso-speaker");
|
||||
sc.tag(x0 + 29, y0 + 3.5, z + 2.6, "Listening", 3, "listening");
|
||||
// archive: two fixed runs, four double-sided carriages and one aisle (rails along the long side)
|
||||
var ar = [[8.3, 8.7], [8.75, 9.55], [9.6, 10.4], [10.45, 11.25], [12.15, 12.95], [13.0, 13.4]];
|
||||
var ar = [[9.55, 9.95], [10.0, 10.8], [10.85, 11.65], [11.7, 12.5], [13.4, 14.2], [14.25, 14.65]];
|
||||
sc.sprite("archive").seq(ar.map(function (r) {
|
||||
return [x0 + 22, y0 + (r[0] + r[1]) / 2, function (q) {
|
||||
var S = sides(x0 + 20.5, y0 + r[0], x0 + 23.5, y0 + r[1]), L = [], lv;
|
||||
q.box(x0 + 20.5, y0 + r[0], x0 + 23.5, y0 + r[1], z, z + 2.2, "iso-archive");
|
||||
return [x0 + 21, y0 + (r[0] + r[1]) / 2, function (q) {
|
||||
var S = sides(x0 + 19.5, y0 + r[0], x0 + 22.5, y0 + r[1]), L = [], lv;
|
||||
q.box(x0 + 19.5, y0 + r[0], x0 + 22.5, y0 + r[1], z, z + 2.2, "iso-archive");
|
||||
for (lv = 0; lv < 5; lv++) L.push([0.1, 2.9, z + 0.15 + lv * 0.42, z + 0.42 + lv * 0.42]);
|
||||
q.open(S.S[0], S.S[1], L, "iso-boxes").open(S.N[0], S.N[1], L, "iso-boxes");
|
||||
}];
|
||||
}));
|
||||
sc.tag(x0 + 22, y0 + 11, z + 3.0, "Archive", 6, "archive");
|
||||
// canteen tables, kitchen counter, lockers
|
||||
var tb = sc.sprite("canteen");
|
||||
var tl = []; for (var tx = 0; tx < 4; tx++) for (var ty = 0; ty < 2; ty++) tl.push([x0 + 9.5 + tx * 3.6, y0 + 2.4 + ty * 3.2]);
|
||||
tb.seq(tl.map(function (p) { return [p[0], p[1], function (q) { q.box(p[0] - 0.9, p[1] - 0.45, p[0] + 0.9, p[1] + 0.45, z, z + 0.75, "iso-table"); }]; }));
|
||||
sc.sprite("canteen").box(x0 + 25.6, y0 + 6.6, x0 + 31.4, y0 + 7.4, z, z + 0.9, "iso-bench");
|
||||
sc.sprite("changing").box(x0 + 24.6, y0 + 14.2, x0 + 31.4, y0 + 14.7, z, z + 1.9, "iso-locker");
|
||||
sc.sprite("changing").box(x0 + 24.6, y0 + 10.6, x0 + 29.4, y0 + 11.1, z, z + 1.9, "iso-locker");
|
||||
sc.tag(x0 + 3.5, y0 + 6, z + 2.6, "Reception", 3, "office");
|
||||
sc.tag(x0 + 16, y0 + 4, z + 2.2, "Canteen", 3, "canteen");
|
||||
sc.tag(x0 + 17.5, y0 + 11.5, z + 2.6, "Listening", 3, "listening");
|
||||
sc.tag(x0 + 21, y0 + 12, z + 3.0, "Archive", 6, "archive");
|
||||
// canteen tables (3 x 2), kitchen servery and line
|
||||
var tl = []; for (var tx = 0; tx < 3; tx++) for (var ty = 0; ty < 2; ty++) tl.push([x0 + 8.2 + tx * 3.5, y0 + 1.7 + ty * 3.2]);
|
||||
sc.sprite("canteen").seq(tl.map(function (p) { return [p[0], p[1], function (q) { q.box(p[0] - 1.2, p[1] - 0.5, p[0] + 1.2, p[1] + 0.5, z, z + 0.75, "iso-table"); }]; }));
|
||||
sc.sprite("canteen").box(x0 + 18.2, y0 + 3.0, x0 + 19.0, y0 + 4.4, z, z + 0.9, "iso-bench");
|
||||
sc.sprite("canteen").box(x0 + 18.4, y0 + 0.5, x0 + 21.6, y0 + 1.3, z, z + 0.9, "iso-steel");
|
||||
sc.tag(x0 + 12, y0 + 3.5, z + 2.2, "Canteen", 3, "canteen");
|
||||
// changing rooms, women and men: showers on the north wall, lockers, a bench
|
||||
[0, 4.5].forEach(function (dx) {
|
||||
var cr = sc.sprite("changing");
|
||||
cr.box(x0 + 10.4 + dx, y0 + 13.7, x0 + 14.1 + dx, y0 + 14.6, z, z + 2.0, "iso-shower");
|
||||
cr.box(x0 + 13.5 + dx, y0 + 9.7, x0 + 14.1 + dx, y0 + 13.3, z, z + 1.9, "iso-locker");
|
||||
cr.box(x0 + 10.6 + dx, y0 + 11.5, x0 + 12.8 + dx, y0 + 11.9, z, z + 0.45, "iso-bench");
|
||||
});
|
||||
sc.tag(x0 + 14.5, y0 + 12, z + 2.8, "Changing", 3, "changing");
|
||||
// toilets
|
||||
sc.sprite("office-wc").box(x0 + 22.4, y0 + 4.4, x0 + 25.6, y0 + 6.6, z, z + 2.0, "iso-wc");
|
||||
}
|
||||
function officeUpper(sc, cfg, z) {
|
||||
var o = OFC, x0 = o.x0, y0 = o.y0, list = [], r, c;
|
||||
// offices (~150 m2): sixteen desks in two rows
|
||||
for (r = 0; r < 2; r++) for (c = 0; c < 8; c++) list.push([x0 + 1.0 + c * 2.6, y0 + (r ? 4.4 : 1.2)]);
|
||||
sc.sprite("offices").seq(list.map(function (p) { return [p[0] + 0.8, p[1] + 0.4, function (q) { q.box(p[0], p[1], p[0] + 1.6, p[1] + 0.8, z, z + 0.75, "iso-desk"); }]; }));
|
||||
// meeting and training room (Payap programmes)
|
||||
sc.sprite("training").seq([2.4, 3.7].map(function (v) { return [x0 + 27, y0 + v + 0.35, function (q) { q.box(x0 + 23.2, y0 + v, x0 + 30.8, y0 + v + 0.7, z, z + 0.75, "iso-table"); }]; }));
|
||||
// meeting room, IT racks, toilets, pantry counter
|
||||
sc.sprite("meetingroom").box(x0 + 1.0, y0 + 11.5, x0 + 5.0, y0 + 12.9, z, z + 0.75, "iso-table");
|
||||
var it = sc.sprite("itroom"), IS = sides(x0 + 10.6, y0 + 12.8, x0 + 12.4, y0 + 13.85);
|
||||
it.box(x0 + 10.6, y0 + 12.8, x0 + 12.4, y0 + 13.85, z, z + 2.0, "iso-server");
|
||||
it.open(IS.S[0], IS.S[1], [[0.1, 0.55, z + 0.2, z + 1.85], [0.65, 1.15, z + 0.2, z + 1.85], [1.25, 1.7, z + 0.2, z + 1.85]], "iso-grille");
|
||||
it.led(x0 + 11.5, y0 + 12.8, z + 1.7, "iso-ledg");
|
||||
sc.sprite("wc-1f").box(x0 + 13.8, y0 + 12.5, x0 + 16.3, y0 + 14.6, z, z + 2.0, "iso-wc");
|
||||
sc.sprite("pantry").box(x0 + 16.8, y0 + 14.05, x0 + 18.7, y0 + 14.65, z, z + 0.9, "iso-bench");
|
||||
sc.tag((o.x0 + o.x1) / 2, y0 + 8, z + 4.4, "Office, first floor", 9, "office");
|
||||
sc.tag(x0 + 11, y0 + 4, z + 2.2, "Offices ~150 m2", 7, "offices");
|
||||
sc.tag(x0 + 27, y0 + 4.5, z + 2.2, "Meeting + training", 6, "training");
|
||||
sc.tag(x0 + 25.5, y0 + 12, z + 2.2, "Flexible room", 5, "flexroom");
|
||||
sc.tag(x0 + 3, y0 + 12, z + 2.2, "Meeting", 4, "meetingroom");
|
||||
sc.tag(x0 + 11.8, y0 + 12, z + 3.0, "IT + server", 4, "itroom");
|
||||
sc.tag(x0 + 17.8, y0 + 12, z + 2.2, "Pantry", 2, "pantry");
|
||||
sc.tag(x0 + 15, y0 + 11, z + 2.6, "WC", 1, "wc-1f");
|
||||
sc.tag(x0 + 8, y0 + 12, z + 3.0, "Stair + lift", 2, "office-stair");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------ phase 2
|
||||
@@ -2242,16 +2434,25 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------ scene
|
||||
function buildScene(cfg, mode, rot, uid) {
|
||||
var sc = new Scene(rot, uid), inside = mode === "inside", al = allocate(cfg), pv = pvPlace(cfg, al), P = sc.P;
|
||||
// level: "roof" (closed buildings, PV), "gf" (ground-floor cutaway), "1f" (upper floors: the office first floor and
|
||||
// the finishing and print block at +3.8 m; single-storey buildings stay in their ground-floor cutaway, ghosted)
|
||||
function levelOf(m, d) {
|
||||
m = String(m === undefined || m === null ? "" : m).toLowerCase();
|
||||
return m === "roof" ? "roof" : (m === "gf" || m === "inside" || m === "ground") ? "gf" : (m === "1f" || m === "upper") ? "1f" : d;
|
||||
}
|
||||
function buildScene(cfg, level, rot, uid) {
|
||||
level = levelOf(level, "roof");
|
||||
var sc = new Scene(rot, uid), inside = level !== "roof", up = level === "1f", al = allocate(cfg), pv = pvPlace(cfg, al), P = sc.P;
|
||||
var ctx = up ? Object.assign({}, cfg, { running: false }) : cfg; // context buildings stand still at 1F
|
||||
siteGround(sc, cfg, al);
|
||||
sitePieces(sc, cfg, al);
|
||||
parking(sc, cfg, pv);
|
||||
factoryInfo(sc, cfg, al);
|
||||
if (inside) factoryInside(sc, cfg, al, pv); else factoryRoof(sc, cfg, pv);
|
||||
office(sc, cfg, inside);
|
||||
if (inside) { sc.dim = up; factoryInside(sc, ctx, al, pv, up); sc.dim = false; if (up) blockUpper(sc, cfg); }
|
||||
else factoryRoof(sc, cfg, pv);
|
||||
office(sc, cfg, level);
|
||||
var y = yard(sc, cfg, inside, pv);
|
||||
if (al.p2show) phase2(sc, cfg, inside, al, pv);
|
||||
if (al.p2show) { sc.dim = up; phase2(sc, ctx, inside, al, pv); sc.dim = false; }
|
||||
else {
|
||||
sc.inf("phase2", "Phase 2 reserve", "Ground kept for a second building: expansion beyond the current program, more pressing or finished goods (scale.md). Switch phase 2 on, or add presses beyond the ~870 m2 hall.");
|
||||
sc.tag((P2.x0 + P2.x1) / 2, (P2.y0 + P2.y1) / 2, 0.5, "Phase 2 reserve", 1, "phase2");
|
||||
@@ -2316,16 +2517,18 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
|
||||
// ------------------------------------------------------------ mount
|
||||
var UID = 0;
|
||||
var NOTE = "Schematic plant view after the Payap scenario model and the utility yard of scale.md; positions and envelopes are estimates. Drag to pan, pinch or Ctrl + wheel to zoom, tap an object for its figures.";
|
||||
var NOTE = "Schematic plant view after the Payap scenario model and the utility yard of scale.md; positions and envelopes are estimates. GF, 1F and Roof switch between the ground floor, the upper floors and the roofs. Drag to pan, pinch or Ctrl + wheel to zoom, tap an object for its figures.";
|
||||
function mount(el, cfg, opts) {
|
||||
if (!el) throw new Error("CNXIso.mount: no container");
|
||||
opts = opts || {};
|
||||
var st = { raw: Object.assign({}, cfg || {}), cfg: norm(cfg), mode: opts.mode === "inside" ? "inside" : "roof", rot: opts.rotation === undefined ? 3 : ((opts.rotation | 0) % 4 + 4) % 4, sel: null, uid: ++UID };
|
||||
var st = { raw: Object.assign({}, cfg || {}), cfg: norm(cfg), level: levelOf(opts.level || opts.mode, "roof"), rot: opts.rotation === undefined ? 3 : ((opts.rotation | 0) % 4 + 4) % 4, sel: null, uid: ++UID };
|
||||
var wrap = document.createElement("div");
|
||||
wrap.className = "iso-wrap";
|
||||
wrap.innerHTML = '<div class="iso-stage"><svg class="iso-svg" xmlns="http://www.w3.org/2000/svg" role="img" tabindex="0" aria-label="Isometric view of the CNX Vinyl plant"></svg>' +
|
||||
'<div class="iso-bar" role="toolbar" aria-label="Plant view">' +
|
||||
'<span class="iso-seg"><button type="button" data-a="roof">Roof</button><button type="button" data-a="inside">Inside</button></span>' +
|
||||
'<span class="iso-seg" role="group" aria-label="Level"><button type="button" data-a="gf" title="Ground floor (cutaway)">GF</button>' +
|
||||
'<button type="button" data-a="1f" title="Upper floors: office first floor, print block at +3.8 m">1F</button>' +
|
||||
'<button type="button" data-a="roof" title="Roofs and PV">Roof</button></span>' +
|
||||
'<button type="button" data-a="rotl" title="Rotate left" aria-label="Rotate the view left">↺</button>' +
|
||||
'<button type="button" data-a="rotr" title="Rotate right" aria-label="Rotate the view right">↻</button>' +
|
||||
'<span class="iso-compass" title="North" aria-hidden="true"><svg viewBox="-10 -10 20 20"><g class="iso-needle"><path d="M0 -8L3 3L0 1.4L-3 3Z"/></g></svg><b>N</b></span>' +
|
||||
@@ -2339,14 +2542,15 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
|
||||
function size() { var r = stage.getBoundingClientRect(); return [Math.max(1, r.width), Math.max(1, r.height)]; }
|
||||
function build() {
|
||||
scn = buildScene(st.cfg, st.mode, st.rot, st.uid);
|
||||
scn = buildScene(st.cfg, st.level, st.rot, st.uid);
|
||||
svg.innerHTML = scn.html;
|
||||
wrap.classList.toggle("iso-still", !st.cfg.running);
|
||||
wrap.classList.toggle("iso-inside", st.mode === "inside");
|
||||
wrap.classList.toggle("iso-inside", st.level !== "roof");
|
||||
wrap.classList.toggle("iso-l1", st.level === "1f");
|
||||
metas = Array.prototype.map.call(svg.querySelectorAll(".iso-tag"), function (g, i) {
|
||||
return { el: g, p: +g.getAttribute("data-p"), w: +g.getAttribute("data-w"), x: +g.getAttribute("data-x"), y: +g.getAttribute("data-y"), i: i, hid: false };
|
||||
}).sort(function (a, b) { return b.p - a.p || a.i - b.i; });
|
||||
Array.prototype.forEach.call(bar.querySelectorAll(".iso-seg button"), function (b) { b.setAttribute("aria-pressed", String(b.getAttribute("data-a") === st.mode)); });
|
||||
Array.prototype.forEach.call(bar.querySelectorAll(".iso-seg button"), function (b) { b.setAttribute("aria-pressed", String(b.getAttribute("data-a") === st.level)); });
|
||||
var n = ROT[st.rot](0, 1), ang = Math.atan2((n[0] + n[1]) / 2, n[0] - n[1]) * 180 / Math.PI + 90;
|
||||
wrap.querySelector(".iso-needle").setAttribute("transform", "rotate(" + ang.toFixed(1) + ")");
|
||||
if (st.sel) select(st.sel, true);
|
||||
@@ -2500,16 +2704,21 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
var b = e.target.closest ? e.target.closest("button") : null;
|
||||
if (!b) return;
|
||||
var a = b.getAttribute("data-a");
|
||||
if (a === "roof" || a === "inside") setMode(a);
|
||||
if (a === "gf" || a === "1f" || a === "roof") setLevel(a);
|
||||
else if (a === "rotl") rotate(-1); else if (a === "rotr") rotate(1);
|
||||
else if (a === "zin") zoomAt(1.5); else if (a === "zout") zoomAt(1 / 1.5); else if (a === "fit") fit();
|
||||
});
|
||||
function setMode(m) {
|
||||
m = m === "inside" ? "inside" : "roof";
|
||||
if (m === st.mode) return;
|
||||
st.mode = m; build(); computeFit(); apply();
|
||||
if (typeof opts.onMode === "function") opts.onMode(m);
|
||||
// levels: "gf" | "1f" | "roof"; the legacy modes map "inside" to GF and "roof" to Roof
|
||||
function legacyMode(l) { return l === "roof" ? "roof" : "inside"; }
|
||||
function setLevel(l) {
|
||||
l = levelOf(l, null);
|
||||
if (!l || l === st.level) return;
|
||||
var om = legacyMode(st.level);
|
||||
st.level = l; build(); computeFit(); apply();
|
||||
if (typeof opts.onLevel === "function") { try { opts.onLevel(l); } catch (e) { if (window.console) console.error(e); } }
|
||||
if (typeof opts.onMode === "function" && legacyMode(l) !== om) { try { opts.onMode(legacyMode(l)); } catch (e) { if (window.console) console.error(e); } }
|
||||
}
|
||||
function setMode(m) { setLevel(levelOf(m, "roof")); }
|
||||
function rotate(d) {
|
||||
var keepZoom = vb ? vb.w / fitW : 1;
|
||||
st.rot = ((st.rot + (d || 1)) % 4 + 4) % 4; build(); hideTip();
|
||||
@@ -2543,7 +2752,9 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
svg: svg,
|
||||
update: function (c) { st.raw = Object.assign({}, st.raw, c || {}); st.cfg = norm(st.raw); build(); var wasFit = atFit; computeFit(); if (wasFit) fit(); else { clampVB(); apply(); } return view; },
|
||||
setMode: function (m) { setMode(m); return view; },
|
||||
getMode: function () { return st.mode; },
|
||||
getMode: function () { return legacyMode(st.level); },
|
||||
setLevel: function (l) { setLevel(l); return view; },
|
||||
getLevel: function () { return st.level; },
|
||||
rotate: function (d) { rotate(d); return view; },
|
||||
setRotation: function (r) { var d = (((r | 0) - st.rot) % 4 + 4) % 4; if (d) rotate(d); return view; },
|
||||
select: function (id) { select(id); return view; },
|
||||
@@ -2569,7 +2780,7 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
fit: function () { fit(); return view; },
|
||||
info: function (id) { return id ? infoOf(id) : Object.keys(scn.info).map(infoOf); },
|
||||
config: function () { return Object.assign({}, st.cfg); },
|
||||
stats: function () { return { nodes: svg.querySelectorAll("*").length, sprites: scn.sprites, presses: scn.alloc, pv: { want: scn.pv.want, placed: scn.pv.placed, left: scn.pv.left } }; },
|
||||
stats: function () { return { nodes: svg.querySelectorAll("*").length, sprites: scn.sprites, level: st.level, presses: scn.alloc, pv: { want: scn.pv.want, placed: scn.pv.placed, left: scn.pv.left } }; },
|
||||
destroy: function () {
|
||||
alive = false;
|
||||
if (ro) ro.disconnect(); else window.removeEventListener("resize", onResize);
|
||||
@@ -2580,7 +2791,11 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
|
||||
return view;
|
||||
}
|
||||
|
||||
function copyRects(o) { var r = {}, k; for (k in o) r[k] = o[k].slice(); return r; }
|
||||
root.CNXIso = { mount: mount, defaults: function () { return Object.assign({}, DEF); }, normalize: norm, version: VERSION,
|
||||
levels: ["gf", "1f", "roof"],
|
||||
// site data for checks: lamp positions and the paved drive areas they must stay off
|
||||
site: function () { return { lamps: LAMPS.map(function (p) { return p.slice(); }), paved: copyRects(PAVED) }; },
|
||||
_build: function (cfg, mode, rot) { return buildScene(norm(cfg), mode, rot || 0, 0); } };
|
||||
})(typeof window !== "undefined" ? window : this);
|
||||
</script>
|
||||
|
||||
Reference in new issue
Block a user