Lag bygning.toml av IFC-modellen og en tilleggsfil

«enok import modell.ifc --tillegg prosjekt.toml» fletter inn det modellen ikke beskriver,
som varmeanlegg og tiltak, og rettelser der den mangler noe. Tilleggsfilen kan holde rom
utenfor oppvarmet BRA, og et navn med «*» treffer alle elementer det passer på, også i
scenarioer.

Importen er nå deterministisk: entitetene leses i fast rekkefølge, helningen arealvektes
når flater slås sammen, og skrå tak får alltid normalen oppover. Vegger får himmelretningen
i navnet, slik at tilleggsfiler kan vise til dem.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015GeH3y8fwTaTudaD88P57o
This commit is contained in:
bl
2026-09-15 20:05:20 +02:00
co-authored by Claude Opus 5
parent d02a3d9666
commit 6d87ef496f
6 changed files with 348 additions and 23 deletions
+36 -4
View File
@@ -62,6 +62,10 @@ struct Beregn {
struct Import {
/// gbXML-, IFC- eller CSV-fil eksportert fra BIM-verktøyet.
fil: PathBuf,
/// Tilleggsfil som flettes inn i den importerte bygningen: det modellen ikke beskriver
/// (drift, varmeanlegg, scenarioer) og rettelser til det den beskriver.
#[arg(short, long, value_name = "FIL")]
tillegg: Option<PathBuf>,
/// Utdatafil. Standard: samme navn med endelsen .toml.
#[arg(short, long, value_name = "FIL")]
ut: Option<PathBuf>,
@@ -217,13 +221,18 @@ fn import(a: Import) -> Result<()> {
.and_then(|e| e.to_str())
.unwrap_or("")
.to_lowercase();
let (bygning, merknader) = match endelse.as_str() {
let tillegg = a.tillegg.as_deref().map(inndata::les_tillegg).transpose()?;
let valg = tillegg
.as_ref()
.map(|t| t.import.clone())
.unwrap_or_default();
let (bygning, mut merknader) = match endelse.as_str() {
"gbxml" | "xml" => {
let r = inndata::gbxml::les(&a.fil)?;
(r.bygning, r.merknader)
}
"ifc" => {
let r = inndata::ifc::les(&a.fil)?;
let r = inndata::ifc::les_med(&a.fil, &valg)?;
(r.bygning, r.merknader)
}
"csv" => {
@@ -234,10 +243,33 @@ fn import(a: Import) -> Result<()> {
"ukjent filtype «{annen}». enok importerer .gbxml, .ifc og .csv (regneark fra Vectorworks)"
),
};
if endelse != "ifc" && !valg.uoppvarmede_rom.is_empty() {
merknader.push("uoppvarmede_rom i tilleggsfilen brukes bare ved import fra IFC.".into());
}
let (bygning, mut innhold) = match (&tillegg, &a.tillegg) {
(Some(t), Some(sti)) => {
let (b, bom) = inndata::flett_tillegg(&bygning, &t.endringer)?;
for m in bom {
merknader.push(format!(
"Navnemønsteret «{m}» i tilleggsfilen traff ingen oppføring i modellen."
));
}
let hode = format!(
"# Generert av enok fra «{}» og tilleggsfilen «{}».\n\
# Rett i modellen eller i tilleggsfilen; denne filen skrives på nytt ved hver import.\n\
# Merknader fra importen:\n",
a.fil.display(),
sti.display()
);
(b, hode)
}
_ => (
bygning,
String::from("# Importert med enok. Fyll ut feltene som er merket nedenfor.\n"),
),
};
let ut = a.ut.unwrap_or_else(|| a.fil.with_extension("toml"));
let tekst = toml::to_string_pretty(&bygning).context("serialiserer bygningen til TOML")?;
let mut innhold =
String::from("# Importert med enok. Fyll ut feltene som er merket nedenfor.\n");
for m in &merknader {
innhold.push_str(&format!("# {m}\n"));
}