From 133152742fe43eabf9965aac6730f61c4d4446fe Mon Sep 17 00:00:00 2001 From: Bendik Lynghaug Date: Mon, 21 Sep 2026 15:48:52 +0200 Subject: [PATCH] =?UTF-8?q?M=C3=A5l=20grunnmuren=20over=20bakken=20fra=20o?= =?UTF-8?q?verkant=20mur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Høyden ble målt fra gulvet i etasjen over, så dekkets egen tykkelse ble regnet som mur over bakken. Nå måles den fra overkant av selve muren, som geometrien gir den. For Nordhusstykket 5 går høyden fra 1,11–1,50 m til 0,76–1,24 m, i snitt 0,98 m. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_015GeH3y8fwTaTudaD88P57o --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/inndata/ifc.rs | 8 ++++++-- src/inndata/ifcgeom.rs | 17 +++++++++++++++++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4d64ea..ce876e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -222,7 +222,7 @@ dependencies = [ [[package]] name = "enok" -version = "0.4.5" +version = "0.4.6" dependencies = [ "anyhow", "approx", diff --git a/Cargo.toml b/Cargo.toml index 34c6af6..a0543a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "enok" -version = "0.4.5" +version = "0.4.6" edition = "2021" description = "Årlig energiberegning og energirapport for boliger etter NS 3031 (timesmetode, ISO 52016-1)" license = "MIT" diff --git a/src/inndata/ifc.rs b/src/inndata/ifc.rs index 2fa3f86..ecd22ed 100644 --- a/src/inndata/ifc.rs +++ b/src/inndata/ifc.rs @@ -186,6 +186,7 @@ pub fn fra_tekst_med(tekst: &str, standardnavn: &str, valg: &Importvalg) -> Resu areal: flate.map(|f| f.areal).unwrap_or(0.0), normal: flate.map(|f| f.normal), z: plass.map(|p| p.2).unwrap_or(0.0) + flate.map(|f| f.hoyde).unwrap_or(0.0), + topp: plass.map(|p| p.2).unwrap_or(0.0) + flate.map(|f| f.topp).unwrap_or(0.0), }); } @@ -363,12 +364,13 @@ pub fn fra_tekst_med(tekst: &str, standardnavn: &str, valg: &Importvalg) -> Resu } // Terrengmodellen sier hvor høyt bakken ligger akkurat der denne veggen står, så en // skrånende tomt gir forskjellig høyde over bakken på hver side av huset. + // Høyden måles fra overkant mur, ikke fra gulvet over: dekket selv står ikke i bakken. let over_bakken = d .plass .and_then(|(x, y, _, _, _)| terreng_ved(&terrengmodell, x, y)) - .map(|z| (etasjekontekst.forste_over_hoyde.unwrap_or(0.0) - z).clamp(0.0, kjellerdybde)) + .map(|z| (d.topp - z).clamp(0.0, kjellerdybde)) .unwrap_or(kjeller_over_terreng); - if i_kjeller && mot == Mot::Grunn { + if i_kjeller && mot == Mot::Grunn && typ == FlateType::Vegg { grunnmurshoyder.push(over_bakken); } let mal = if i_kjeller { @@ -1316,6 +1318,8 @@ struct Del { normal: Option<[f64; 3]>, /// Delens høyde over byggets nullpunkt, av geometrien, m. z: f64, + /// Overkanten av delen over byggets nullpunkt, m. For en kjellervegg er det overkant mur. + topp: f64, } /// Oversetter en fritekstverdi fra modellen til en bygningskategori. diff --git a/src/inndata/ifcgeom.rs b/src/inndata/ifcgeom.rs index 021166f..ba0e118 100644 --- a/src/inndata/ifcgeom.rs +++ b/src/inndata/ifcgeom.rs @@ -30,6 +30,8 @@ pub struct Hovedflate { /// Midlere høyde over delens eget nullpunkt, m. Sier hvilken etasje delen ligger i når /// plasseringen i filen ikke gjør det. pub hoyde: f64, + /// Øverste punkt over delens eget nullpunkt, m. For en kjellervegg er det overkant mur. + pub topp: f64, } impl Nett { @@ -103,11 +105,18 @@ impl Nett { } else { self.punkter.iter().map(|p| p[2]).sum::() / self.punkter.len() as f64 * skala }; + let topp = self + .punkter + .iter() + .map(|p| p[2]) + .fold(f64::NEG_INFINITY, f64::max) + * skala; Some(Hovedflate { areal: sum / 2.0, normal, plan: self.utstrekning(normal, skala), hoyde, + topp: if topp.is_finite() { topp } else { 0.0 }, }) } @@ -189,9 +198,14 @@ pub fn samlet_hovedflate(deler: &[Nett], skala: f64) -> Option { } else { grupper[0].hoyde }; + let topp = grupper + .iter() + .map(|g| g.topp) + .fold(f64::NEG_INFINITY, f64::max); Some(Hovedflate { areal, hoyde, + topp, ..grupper[0] }) } @@ -562,6 +576,9 @@ mod tester { let h = n.hovedflate(1.0).unwrap(); assert!((h.areal - 12.0).abs() < 1e-9, "areal ble {}", h.areal); assert!(h.normal[2].abs() > 0.99, "normal ble {:?}", h.normal); + // Midlere høyde er halve tykkelsen, og overkanten er tykkelsen. + assert!((h.hoyde - z / 2.0).abs() < 1e-9, "høyde ble {}", h.hoyde); + assert!((h.topp - z).abs() < 1e-9, "topp ble {}", h.topp); } /// Et hull i flaten skal trekkes fra, siden hullet mangler trekanter.