Data centres: multi-storey shell, racks and pods, cooling, fire safety, power
Deploy web Studio / deploy (push) Successful in 1m4s
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:
1 parent
c8becc2e59
commit
2810477f1b
22 files changed
+2281
-18
No files matched your search
@@ -59,6 +59,10 @@ pub struct Rendered {
|
||||
pub nodes: usize,
|
||||
/// Depth-sort cycles that had to be broken (0 is ideal).
|
||||
pub cycles: usize,
|
||||
/// Where they were broken: "a before b, c" (sprite ids; a was drawn
|
||||
/// before b and c, which it should have followed).
|
||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||
pub cycle_at: Vec<String>,
|
||||
pub warnings: Vec<String>,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||
pub order: Vec<OrderItem>,
|
||||
@@ -714,6 +718,7 @@ pub fn render(scene: &Scene, rot: u8, opts: &RenderOpts) -> Rendered {
|
||||
let mut frame = [1e9f64, 1e9, -1e9, -1e9];
|
||||
let mut sprites = 0;
|
||||
let mut cycles = 0;
|
||||
let mut cycle_at = vec![];
|
||||
let mut order = vec![];
|
||||
let mut warnings = scene.warnings.clone();
|
||||
|
||||
@@ -748,6 +753,10 @@ pub fn render(scene: &Scene, rot: u8, opts: &RenderOpts) -> Rendered {
|
||||
.collect();
|
||||
let o = sort::sort_hulls(&pairs, &hulls, layer.opts.zfirst);
|
||||
cycles += o.cycles;
|
||||
for (b, before) in &o.broken {
|
||||
let ids: Vec<&str> = before.iter().map(|&i| live[i].id.as_str()).collect();
|
||||
cycle_at.push(format!("{} before {}", live[*b].id, ids.join(", ")));
|
||||
}
|
||||
o.order
|
||||
} else {
|
||||
(0..live.len()).collect()
|
||||
@@ -876,6 +885,7 @@ pub fn render(scene: &Scene, rot: u8, opts: &RenderOpts) -> Rendered {
|
||||
sprites,
|
||||
nodes,
|
||||
cycles,
|
||||
cycle_at,
|
||||
warnings,
|
||||
order,
|
||||
html,
|
||||
|
||||
@@ -153,6 +153,9 @@ fn rect_of(b: &Bb) -> Hull {
|
||||
pub struct Order {
|
||||
pub order: Vec<usize>,
|
||||
pub cycles: usize,
|
||||
/// Each broken cycle: the sprite drawn early to break it and the sprites
|
||||
/// not drawn yet that should have come before it.
|
||||
pub broken: Vec<(usize, Vec<usize>)>,
|
||||
}
|
||||
|
||||
pub fn sort(boxes: &[(Bb, Sb)], zf: bool) -> Order {
|
||||
@@ -203,6 +206,7 @@ pub fn sort_hulls(boxes: &[(Bb, Sb)], hulls: &[Option<Hull>], zf: bool) -> Order
|
||||
let mut out = Order {
|
||||
order: Vec::with_capacity(n),
|
||||
cycles: 0,
|
||||
broken: vec![],
|
||||
};
|
||||
for _ in 0..n {
|
||||
let mut best: Option<usize> = None;
|
||||
@@ -227,6 +231,12 @@ pub fn sort_hulls(boxes: &[(Bb, Sb)], hulls: &[Option<Hull>], zf: bool) -> Order
|
||||
}
|
||||
}
|
||||
let b = best.expect("n > 0");
|
||||
if indeg[b] > 0 {
|
||||
let before: Vec<usize> = (0..n)
|
||||
.filter(|&i| !done[i] && adj[i].contains(&b))
|
||||
.collect();
|
||||
out.broken.push((b, before));
|
||||
}
|
||||
done[b] = true;
|
||||
out.order.push(b);
|
||||
for &j in &adj[b] {
|
||||
@@ -245,6 +255,24 @@ mod tests {
|
||||
([x0, y0, x1, y1, z0, z1], [0.0, 0.0, 10.0, 10.0])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn broken_cycles_name_the_sprites() {
|
||||
// a before b (x), b before c (y), c before a (z): no order fits all three
|
||||
let o = sort(
|
||||
&[
|
||||
bx(0.0, 0.0, 1.0, 10.0, 5.0, 6.0),
|
||||
bx(2.0, 0.0, 3.0, 1.0, 0.0, 5.0),
|
||||
bx(0.0, 2.0, 3.0, 3.0, 0.0, 1.0),
|
||||
],
|
||||
false,
|
||||
);
|
||||
assert_eq!(o.cycles, 1);
|
||||
assert_eq!(o.broken.len(), 1);
|
||||
let (b, before) = &o.broken[0];
|
||||
assert_eq!(before.len(), 1);
|
||||
assert_ne!(*b, before[0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn separated_on_x_draws_far_first() {
|
||||
let o = sort(
|
||||
|
||||
Reference in new issue
Block a user