Data centres: multi-storey shell, racks and pods, cooling, fire safety, power
Deploy web Studio / deploy (push) Successful in 1m4s

datacentre.rhai (palette groups Data centre, Cooling, Fire safety, Power):

- dc_building: multi-storey shell (storeys of storey_h), walls in pieces,
  slabs, roof with parapet, louvres, front door and loading dock; levels
  cut it open storey by storey
- raised_floor; rack_row and dc_pod (cabinets by U, width, depth,
  equipment, fill, doors, LEDs; in-row coolers; cold / hot aisle
  containment with vent tiles, roof, end doors, ceiling duct, airflow);
  dc_cage for colocation
- crah, chiller (air-cooled, dry, adiabatic), cooling_tower, pipe_run
- smoke_detectors (grid + coverage), fire_pipe (VESDA, sprinkler, gas),
  gas_bank (Novec 1230, FM-200, Inergen sized for its halls), fire_device
  (panels, call points, abort switches, beacons, extinguishers)
- power_cab (UPS, battery, PDU, switchgear, RPP), busway, cable_tray,
  transformer
- tooltips sum IT load, kW/m2, cooling redundancy per storey, UPS load,
  battery runtime, plant cooling and agent quantity (warning when short)

Engine and stdlib:

- part_hidden(o) in house.rhai: parts on closed storeys inside a
  dc_building are not drawn (they only made sort cycles under the slab
  above); house parts, furniture and people use it. Existing examples
  render byte-identical.
- overhead services sort in their own "ceiling" layer with tight boxes
- sort records which sprites each broken cycle involved; isokit check
  names them (Rendered.cycle_at)

examples/datacentre (three storeys and a roof plant), Data centre demo in
the web Studio, tests, SCRIPTING/README/ROADMAP, MCP instructions.
This commit is contained in:
grabowski committed 2026-10-27 17:08:39 +07:00
1 parent c8becc2e59
commit 2810477f1b
22 files changed
+2281 -18

No files matched your search

+39
View File
@@ -94,6 +94,45 @@ fn country_demo_renders_every_view_cleanly() {
example_renders_every_view_cleanly("country");
}
#[test]
fn datacentre_demo_renders_every_view_cleanly() {
let p = Project::load(Path::new(env!("CARGO_MANIFEST_DIR")).join("../../examples/datacentre"))
.unwrap();
assert!(p.runtime.is_ok(), "{:?}", p.runtime.as_ref().err());
// storeys of 5 m; the building covers |x| <= 21, |y| <= 13 and has three
// storeys, the plant on its roof (storey 3)
let storey = |z: f64| ((z + 0.5) / 5.0).floor() as i64;
for l in p.manifest.levels() {
let k: i64 = match l.id.as_str() {
"gf" => 0,
"1f" => 1,
"2f" => 2,
_ => -1,
};
for rot in 0..4 {
let v = p.render(&l.id, rot, None, false).unwrap();
assert!(v.warnings.is_empty(), "{}/{rot}: {:?}", l.id, v.warnings);
assert_eq!(v.cycles, 0, "{}/{rot}: {:?}", l.id, v.cycle_at);
assert!(!v.html.contains("NaN"));
for o in p.doc.objects.iter().filter(|o| o.kind != "group") {
let s = storey(o.z);
let ground = o.kind == "site" || o.kind == "area";
let inside = !ground && o.x.abs() < 21.0 && o.y.abs() < 13.0;
// the cut storey shows, closed storeys inside the shell and storeys above do not
let shown = o.kind == "dc_building" || !inside || s == k || (k < 0 && s >= 3);
assert_eq!(
v.boxes.contains_key(&o.id),
shown,
"{} on {}/{rot}",
o.id,
l.id
);
}
}
}
assert!(check::check(&p).is_empty(), "{:?}", check::check(&p));
}
fn example_renders_every_view_cleanly(name: &str) {
let p = Project::load(
Path::new(env!("CARGO_MANIFEST_DIR"))