Merge origin/master: i18n-System (de/en) + 30-Grad-AS/ES-Elemente zusammenfuehren

Lokaler Stand (Modus-3 Randwert-Solver, 30/90-AS/ES, Kreisel-Attribute)
mit dem Remote-Stand (Internationalisierung ssg-text, neue Bloecke,
Sivas-Export) vereint.

Konfliktaufloesung:
- vf_linienzug.lsp: Nicht-interaktive -block-Kerne (fuer Pfad-Modi) behalten,
  interaktive Abfragen (GF-Bogen, Vario-Kurve, ES-Seite) auf ssg-text
  umgestellt. Kein doppelter defun mehr.
- Gefaellestrecke.lsp: 30/90-Winkelabfrage mit den i18n-Seiten-Prompts
  kombiniert; gefaellestrecke-einfuegen-Aufruf mit as-/es-winkel.
- vf_core.lsp: vf-frage-element-winkel nimmt jetzt einen i18n-Header-Key
  (vf-winkel-aus-header / vf-winkel-ein-header) statt festem Text.
- lang/de_DE.json + en_GB.json: neue Keys vf-winkel-aus/ein-header,
  vf-winkel-90/30; gf-seite-Header ohne irrefuehrendes "_90_".
- export_sivas.py: ANZAHL_SEPARATOR/ANZAHL_SCANNER mit N_*-Fallback plus
  Remote-Umsortierung; doppelte "Kreiselart"-Zeile entfernt.
- AS_Element_30_links/rechts.dwg + Separator_SP.dwg (3D): Remote-Version
  (Attribut-Stand) uebernommen. Die KS_AUS-Geometrie-Korrektur der 30-Grad-
  AS-Elemente wird danach in BricsCAD nachgezogen.

Offen (Folge-Commit): die Modus-Treiber in vf_linienzug.lsp
(vf-linienzug-modus / -modus2 / -modus3) sind noch nicht i18n
(ca. 110 Strings).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-20 14:08:13 +02:00
311 changed files with 67986 additions and 49100 deletions
+13 -4
View File
@@ -52,6 +52,15 @@ def build_lookup(boegen, weichen):
return lookup
def format_sivasnr(sivasnr):
"""
Wandelt einen "+"-separierten Sivasnr-Wert (Rohformat aus den JSON-Katalogen,
dort weiterhin benoetigt fuer Dateinamen-Referenzen) in eine reine
kommaseparierte Liste fuer die Ausgabe (CSV/Block-Attribut) um.
"""
return ", ".join(p.strip() for p in str(sivasnr).split("+") if p.strip())
# ---------------------------------------------------------------------------
# Merkmale-Builder
# ---------------------------------------------------------------------------
@@ -80,7 +89,7 @@ def build_bogen_merkmale(block, eintrag):
"Radius": float(eintrag.get("Radius", 0)),
"Höhe": get_hoehe(block),
"Drehung": get_drehung(block),
"SivasNummer": str(eintrag.get("Sivasnr", ""))
"SivasNummer": format_sivasnr(eintrag.get("Sivasnr", ""))
}
@@ -93,7 +102,7 @@ def build_weiche_merkmale(block, eintrag):
"Höhe": get_hoehe(block),
"Drehung": get_drehung(block),
"Antrieb Kurve": eintrag.get("SivasnrTEF") is not None,
"SivasNummer": str(eintrag.get("Sivasnr", ""))
"SivasNummer": format_sivasnr(eintrag.get("Sivasnr", ""))
}
@@ -305,7 +314,7 @@ def process_blocks(blocks, lookup):
vf_count += 1
items.append({
"nr": elem_nr,
"teileart": "VarioFoerderer",
"teileart": "ILS 2.0 Strecke",
"teileid": block.get("attribs", {}).get("ID", "0000"),
"bezeichnung": f"VarioFoerderer :{vf_count}",
"merkmale": build_variofoerderer_merkmale(block),
@@ -318,7 +327,7 @@ def process_blocks(blocks, lookup):
gf_count += 1
items.append({
"nr": elem_nr,
"teileart": "Gefaellestrecke",
"teileart": "ILS 2.0 Gefaellestrecke",
"teileid": block.get("attribs", {}).get("ID", "0000"),
"bezeichnung": f"Gefaellestrecke :{gf_count}",
"merkmale": build_variofoerderer_merkmale(block),
+195 -18
View File
@@ -4,7 +4,7 @@
export_sivas.py - Erzeugt Sivas-Export-CSV mit gruppierten Zeilen und Summierungszeilen.
Neues CSV-Format:
Nr;TeileArt;SivasNummer;Dispgruppe;Anzahl;Laenge[mm];Hoehe[m];details
Nr;TeileArt;SivasNummer;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details
- Omniflo Bogen/Weiche: gruppiert nach SivasNummer, Anzahl summiert
- Omniflo Gerade: gruppiert nach ARTINR-Attribut, Laenge[mm] summiert
@@ -83,6 +83,15 @@ def get_id(block):
return block.get("attribs", {}).get("ID", "")
def format_sivasnr(sivasnr):
"""
Wandelt einen "+"-separierten Sivasnr-Wert (Rohformat aus den JSON-Katalogen,
dort weiterhin benoetigt fuer Dateinamen-Referenzen) in eine reine
kommaseparierte Liste fuer die Ausgabe (CSV/Block-Attribut) um.
"""
return ", ".join(p.strip() for p in str(sivasnr).split("+") if p.strip())
def format_hoehe_m(hoehe_mm_str):
"""Konvertiert mm-String nach m mit deutschem Dezimaltrennzeichen."""
try:
@@ -94,6 +103,113 @@ def format_hoehe_m(hoehe_mm_str):
return ""
def build_gefaellestrecke_details(block):
"""Merkmale-Dict fuer eine einzelne ILS Gefaellestrecke (GF_N-Block)."""
attribs = block.get("attribs", {})
def mm_to_m(key):
try:
return str(round(float(attribs.get(key, "0")) / 1000.0, 2))
except (ValueError, TypeError):
return "0"
return {
"IDs": [get_id(block)],
"Bezeichnung": attribs.get("Bezeichnung", block.get("block_name", "")),
"Hoehe oben": mm_to_m("HOEHE_VON_mm"),
"Hoehe unten": mm_to_m("HOEHE_BIS_mm"),
"Laenge in Meter": attribs.get("L_GF_m", ""),
"Winkel": attribs.get("GF_WINKEL", ""),
"Anzahl der Separatoren": attribs.get("ANZAHL_SEPARATOR", "0"),
"Anzahl der Scanner": attribs.get("ANZAHL_SCANNER", "0"),
"Typ": attribs.get("TYP", "Gefaellestrecke"),
}
def gefaellestrecke_signature(block):
"""
Schluessel zur Gruppierung gleichartiger Gefaellestrecken: Bloecke mit
identischen Massen (Hoehe, Laenge, Winkel, Separatoren, Scanner, Typ)
landen in derselben Sivas-Zeile - nur IDs/Bezeichnung unterscheiden sich.
"""
attribs = block.get("attribs", {})
return (
attribs.get("HOEHE_VON_mm", "0"),
attribs.get("HOEHE_BIS_mm", "0"),
attribs.get("L_GF_m", ""),
attribs.get("GF_WINKEL", ""),
attribs.get("ANZAHL_SEPARATOR", "0"),
attribs.get("ANZAHL_SCANNER", "0"),
attribs.get("TYP", "Gefaellestrecke"),
)
def parse_float_list(csv_str):
"""Kommagetrennten Attribut-String (z.B. L_GF_m) in Liste von floats."""
out = []
for part in str(csv_str or "").split(","):
part = part.strip()
if not part:
continue
try:
out.append(float(part))
except ValueError:
pass
return out
def parse_str_list(csv_str):
"""Kommagetrennten Attribut-String (z.B. MOTORSEITE) in Liste von Strings."""
return [p.strip() for p in str(csv_str or "").split(",") if p.strip()]
def build_variofoerderer_details(block):
"""
Merkmale-Dict fuer eine VF_N-Streckengruppe (VarioFoerderer, ggf.
mehrsegmentig aus Gefaelle- und angetriebenen Foerderer-Teilen).
"""
attribs = block.get("attribs", {})
def to_int(key):
try:
return int(attribs.get(key, "0") or "0")
except (ValueError, TypeError):
return 0
return {
"IDs": [get_id(block)],
"Anzahl Foerdergruppen": to_int("ANZAHL_VF"),
"Anzahl Gefaellegruppen": to_int("ANZAHL_GF"),
"Hoehe in m": attribs.get("MONTAGEHOEHE_m", "0"),
"GruppenteileGefaelle": {
"AnzahlGeraden": to_int("ANZAHL_GF"),
"Laenge in Meter": parse_float_list(attribs.get("L_GF_m", "")),
"Winkel": parse_float_list(attribs.get("GF_WINKEL", "")),
"AnzahlKurvenLinks90": to_int("GF_Bogen_L_90"),
"AnzahlKurvenLinks60": to_int("GF_Bogen_L_60"),
"AnzahlKurvenLinks30": to_int("GF_Bogen_L_30"),
"AnzahlKurvenRechts90": to_int("GF_Bogen_R_90"),
"AnzahlKurvenRechts60": to_int("GF_Bogen_R_60"),
"AnzahlKurvenRechts30": to_int("GF_Bogen_R_30"),
},
"GruppenteileAngetrieben": {
"MotorSeite": parse_str_list(attribs.get("MOTORSEITE", "")),
"AnzahlGeraden": to_int("ANZAHL_VF"),
"Laenge in Meter": parse_float_list(attribs.get("L_VF_m", "")),
"Winkel": parse_float_list(attribs.get("VF_WINKEL", "")),
"Foerderrichtung": parse_str_list(attribs.get("ANTRIEBFAHRTRICHTUNG", "")),
"AnzahlKurvenAussen90": to_int("VF_Bogen_A_90"),
"AnzahlKurvenAussen60": to_int("VF_Bogen_A_60"),
"AnzahlKurvenAussen30": to_int("VF_Bogen_A_30"),
"AnzahlKurvenInnen90": to_int("VF_Bogen_I_90"),
"AnzahlKurvenInnen60": to_int("VF_Bogen_I_60"),
"AnzahlKurvenInnen30": to_int("VF_Bogen_I_30"),
},
"Anzahl der Separatoren": to_int("ANZAHL_SEPARATOR"),
"Anzahl der Scanner": to_int("ANZAHL_SCANNER"),
}
def build_kreisel_details(block):
"""Merkmale-Dict fuer einen ILS Kreisel."""
attribs = block.get("attribs", {})
@@ -108,12 +224,12 @@ def build_kreisel_details(block):
except (ValueError, TypeError):
hoehe_m = "0"
return {
"Hoehe in m": hoehe_m,
"Kreiselart": attribs.get("KREISELART", "STANDARD"),
"Abstand (Kreiselachse A - Kreiselachse) in Meter": abstand_m,
"Anzahl der Separatoren": attribs.get("ANZAHL_SEPARATOR", attribs.get("N_SEPARATOREN", "2")),
"Kreiselart": attribs.get("KREISELART", "STANDARD"),
"Anzahl der Scanner": attribs.get("ANZAHL_SCANNER", attribs.get("N_SCANNER", "0")),
"Anzahl der Rampen": attribs.get("N_RAMPEN", "0"),
"Hoehe in m": hoehe_m,
"Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"),
"Drehung": block.get("rotation", 0.0),
}
@@ -123,13 +239,20 @@ def build_kreisel_details(block):
SKIP_BLOCKS = set(BLOCKPATTERNS.get("pattern_ks_subblocks", ["K1", "K2", "K3", "K4", "KS_EIN", "KS_AUS"]))
# Sivas-Nummern und Bezeichnungen je ILS-Elementtyp
# Hinweis: "ils_kurve", "bt_beladung" und "bg_entladung" sind aktuell nur
# Typnamen-Platzhalter - die zugehoerigen Menuebefehle sind noch Dummies
# (siehe Lisp/README.md), es gibt noch keine Block-Erkennung dafuer.
ILS_SIVASNR = {
"kreisel": ("6200", "ILS 2.0 Kreisel"),
"eckrad": ("6210", "ILS 2.0 Eckrad"),
"zusatzmodul":("6215", "ILS 2.0 Zusatzmodul"),
"ils_weiche": ("6216", "ILS 2.0 Weichen"),
"strecke": ("6220", "ILS 2.0 Strecke - Module"),
"automation": ("6269", "ILS 2.0 Automation und Pneumatik - Gesamtanlage"),
"kreisel": ("6200", "ILS 2.0 Kreisel"),
"eckrad": ("6210", "ILS 2.0 Eckrad"),
"zusatzmodul": ("6215", "ILS 2.0 Zusatzmodul"),
"ils_weiche": ("6216", "ILS 2.0 Weiche"),
"ils_kurve": ("", "ILS 2.0 Kurve"),
"strecke": ("6220", "ILS 2.0 Strecke"),
"gefaellestrecke": ("6220", "ILS 2.0 Gefaellestrecke"),
"bt_beladung": ("", "BT - Beladung"),
"bg_entladung": ("", "BG - Entladung"),
"automation": ("6269", "ILS 2.0 Automation und Pneumatik - Gesamtanlage"),
}
@@ -148,7 +271,9 @@ def process_blocks(blocks, lookup):
gerade_groups = {}
kreisel_list = [] # Liste von blocks
eckrad_ids = [] # IDs aller Eckrad-Bloecke
strecke_ids = [] # IDs aller Strecke-Module (VF_*, GF_*, Vario/Staustrecke)
strecke_ids = [] # IDs loser Strecke-Elemente (Vario/Staustrecke ausserhalb VF_N)
vario_list = [] # Liste von VarioFoerderer-Compound-Bloecken (VF_N), je einer Zeile
gefaelle_list = [] # Liste von Gefaellestrecke-Bloecken (GF_*), je einer Zeile
counters = {
"anzahl_boegen": 0,
@@ -190,7 +315,7 @@ def process_blocks(blocks, lookup):
# --- Omniflo Bogen oder Weiche (erkannt via Katalog) ---
if bname in lookup:
typ, eintrag = lookup[bname]
sivasnr = str(eintrag.get("Sivasnr", bname))
sivasnr = format_sivasnr(eintrag.get("Sivasnr", bname))
hoehe = get_hoehe_mm(block)
if typ == "bogen":
@@ -270,10 +395,12 @@ def process_blocks(blocks, lookup):
continue
# --- VarioFoerderer Compound-Block (VF_N) ---
# Bekommt immer eine eigene Detail-Zeile (vario_list) statt der
# generischen IDs-Gruppierung - siehe build_variofoerderer_details.
if matches_any(bname, BLOCKPATTERNS.get("pattern_variofoerderer", [])):
attribs = block.get("attribs", {})
counters["anzahl_variofoerderer"] += 1
strecke_ids.append(get_id(block))
vario_list.append(block)
try:
counters["laengen_variofoerderer"] += float(attribs.get("L_VF_m", "0") or "0")
except (ValueError, TypeError):
@@ -291,11 +418,11 @@ def process_blocks(blocks, lookup):
continue
# --- Gefaellestrecke Compound-Block (GF_N) ---
# Eigener Typ "ILS 2.0 Gefaellestrecke" - NICHT als Variofoerderer zaehlen.
if matches_any(bname, BLOCKPATTERNS.get("pattern_gefaellestrecke", [])):
attribs = block.get("attribs", {})
counters["anzahl_variofoerderer"] += 1
counters["anzahl_gefaellestrecken"] += 1
strecke_ids.append(get_id(block))
gefaelle_list.append(block)
try:
counters["laengen_gefaellestrecken"] += float(attribs.get("L_GF_m", "0") or "0")
except (ValueError, TypeError):
@@ -395,7 +522,10 @@ def process_blocks(blocks, lookup):
})
nr += 1
if counters["anzahl_variofoerderer"] > 0:
# Lose Strecke-Elemente (Vario/Staustrecke ausserhalb eines VF_N-Blocks)
# als eine gruppierte Zeile; VF_N-Compound-Bloecke bekommen unten je eine
# eigene Detail-Zeile.
if strecke_ids:
sivasnr, teileart = ILS_SIVASNR["strecke"]
items.append({
"nr": nr,
@@ -403,17 +533,64 @@ def process_blocks(blocks, lookup):
"sivasnr": sivasnr,
"sivasnr_quoted": True,
"dispgruppe": 20,
"anzahl": counters["anzahl_variofoerderer"],
"anzahl": len(strecke_ids),
"laenge_mm": "",
"hoehe_m": "",
"details": {"IDs": strecke_ids},
})
nr += 1
# VarioFoerderer-Compound-Bloecke (VF_N) - je Block eine eigene Zeile mit
# vollstaendigen Gefaelle-/Angetrieben-Teilgruppen (immer TYP "Streckengruppe").
for block in vario_list:
sivasnr, teileart = ILS_SIVASNR["strecke"]
items.append({
"nr": nr,
"teileart": teileart,
"sivasnr": sivasnr,
"sivasnr_quoted": True,
"dispgruppe": 20,
"anzahl": 1,
"laenge_mm": "",
"hoehe_m": "",
"details": build_variofoerderer_details(block),
})
nr += 1
# Gleichartige Gefaellestrecken (identische Masse) zu einer Zeile
# zusammenfassen - nur IDs/Bezeichnung bleiben je Block unterschiedlich.
gefaelle_groups = {}
for block in gefaelle_list:
sig = gefaellestrecke_signature(block)
if sig not in gefaelle_groups:
gefaelle_groups[sig] = {"ids": [], "bezeichnungen": [], "block": block}
gefaelle_groups[sig]["ids"].append(get_id(block))
gefaelle_groups[sig]["bezeichnungen"].append(
block.get("attribs", {}).get("Bezeichnung", block.get("block_name", "")))
for group in gefaelle_groups.values():
sivasnr, teileart = ILS_SIVASNR["gefaellestrecke"]
details = build_gefaellestrecke_details(group["block"])
details["IDs"] = group["ids"]
details["Bezeichnung"] = group["bezeichnungen"]
items.append({
"nr": nr,
"teileart": teileart,
"sivasnr": sivasnr,
"sivasnr_quoted": True,
"dispgruppe": 20,
"anzahl": len(group["ids"]),
"laenge_mm": "",
"hoehe_m": "",
"details": details,
})
nr += 1
# ILS Automation Summierungszeile (nur wenn ILS-Elemente vorhanden)
has_ils = (counters["anzahl_kreisel"] > 0
or counters["anzahl_eckraeder"] > 0
or counters["anzahl_variofoerderer"] > 0)
or counters["anzahl_variofoerderer"] > 0
or counters["anzahl_gefaellestrecken"] > 0)
if has_ils:
automation_details = {
"Anzahl Kreisel": counters["anzahl_kreisel"],
@@ -492,7 +669,7 @@ def main():
items, _ = process_blocks(blocks, lookup)
header = "Nr;TeileArt;SivasNummer;Dispgruppe;Anzahl;Laenge[mm];Hoehe[m];details"
header = "Nr;TeileArt;SivasNummer;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details"
with open(output_csv, "w", encoding="utf-8") as f:
f.write(header + "\n")
for item in items:
+67 -8
View File
@@ -39,13 +39,14 @@ Umgebungsvariablen:
DXFM_RESULTS - Pfad zum results/-Verzeichnis
Aufruf:
python lib/set_attributs.py [--number SIVASNR] [--dry-run]
python lib/set_attributs.py [--number SIVASNR] [--dry-run] [--type 2D|3D]
"""
import argparse
import configparser
import json
import os
import re
import sys
import ezdxf
@@ -64,6 +65,7 @@ def load_config(cfg_path):
"bogen": [("BESCHR", "ProfilTyp"), ("ARTINR", "Sivasnr"), ...],
"weiche": [("BESCHR", "ProfilTyp"), ...],
"layer": {"bogen": "OF Boegen A-2", "weiche_90": "Weiche 90 Grad A-2", ...},
"container": {"0_BG071090": "0_B10071, 0_B10090, 0_B10090", ...},
}
"""
config = configparser.ConfigParser()
@@ -81,6 +83,13 @@ def load_config(cfg_path):
val = val[1:-1]
layer_map[key] = val
result["layer"] = layer_map
elif section == "container":
# Container-Sektion: 0_BGxxxxxx -> bereinigte, kommaseparierte Liste
container_map = {}
for key, val in config.items(section):
parts = [p.strip() for p in val.split(",") if p.strip()]
container_map[key] = ", ".join(parts)
result["container"] = container_map
else:
attrs = []
for tag, source in config.items(section):
@@ -131,12 +140,41 @@ def get_layer_for_entry(typ, json_entry, layer_map):
return ""
def resolve_value(source, json_entry, sivasnr):
CONTAINER_PATTERN = re.compile(r"0_BG\d+")
def resolve_container_refs(text, container_map):
"""
Ersetzt jedes Vorkommen von 0_BGxxxxxx in text durch die zugehoerige
kommaseparierte Liste aus [container]. Kommt das Muster mehrfach vor,
wird jedes Vorkommen einzeln ersetzt. Unbekannte 0_BG-Werte bleiben
unveraendert stehen.
Anschliessend werden verbleibende "+"-Trenner (z.B. zwischen Artikelnr.
und 0_BG-Referenz) durch ", " ersetzt, damit SivasNummer ausschliesslich
eine kommaseparierte Liste ist.
"""
if container_map and "0_BG" in text:
text = CONTAINER_PATTERN.sub(
lambda m: container_map.get(m.group(0), m.group(0)), text
)
if "+" in text:
parts = [p.strip() for p in text.split("+") if p.strip()]
text = ", ".join(parts)
return text
def resolve_value(source, json_entry, sivasnr, container_map=None):
"""
Loest einen Quell-Ausdruck aus der Config auf:
- "fester Text" -> fester Text
- {sivasnr} -> SivasNr-Wert
- Feldname -> Wert aus json_entry
Wird das Feld "Sivasnr" aufgeloest, werden enthaltene 0_BGxxxxxx-Muster
anhand von [container] durch die dort hinterlegte kommaseparierte Liste
ersetzt und verbleibende "+"-Trenner durch ", " ersetzt, sodass das
Ergebnis ausschliesslich eine kommaseparierte Liste ist (keine "+" mehr).
"""
source = source.strip()
@@ -152,7 +190,10 @@ def resolve_value(source, json_entry, sivasnr):
val = json_entry.get(source)
if val is None:
return ""
return str(val)
val = str(val)
if source == "Sivasnr":
val = resolve_container_refs(val, container_map)
return val
# ---------------------------------------------------------------------------
@@ -225,7 +266,7 @@ def wrap_entities_in_block(doc, block_name):
def add_attdefs_to_dxf(dxf_path, output_path, attr_defs, json_entry, sivasnr,
layer_value=""):
layer_value="", container_map=None):
"""
Oeffnet eine DXF-Datei, fuegt ATTDEF-Entities in den Modelspace ein
und speichert das Ergebnis.
@@ -233,6 +274,7 @@ def add_attdefs_to_dxf(dxf_path, output_path, attr_defs, json_entry, sivasnr,
attr_defs: Liste von (TAG, source_expression) aus der Config
json_entry: Dict mit den JSON-Daten fuer dieses Element
layer_value: Layer-Name aus [layer]-Sektion (wird als LAYER-ATTDEF gesetzt)
container_map: Dict aus [container]-Sektion fuer 0_BG-Aufloesung in Sivasnr
"""
doc = ezdxf.readfile(dxf_path)
msp = doc.modelspace()
@@ -265,7 +307,7 @@ def add_attdefs_to_dxf(dxf_path, output_path, attr_defs, json_entry, sivasnr,
y_pos = y_start
count = 0
for tag, source in all_defs:
default_value = resolve_value(source, json_entry, sivasnr)
default_value = resolve_value(source, json_entry, sivasnr, container_map)
prompt = tag
msp.add_attdef(
@@ -296,6 +338,7 @@ def process_all(data_dir, cfg_path, results_dir, single_nr=None, dry_run=False):
# Config laden
attr_config = load_config(cfg_path)
layer_map = attr_config.pop("layer", {})
container_map = attr_config.pop("container", {})
print(f"[set_attributs] Config geladen: {list(attr_config.keys())}")
if layer_map:
print(f" [layer] {len(layer_map)} Zuordnungen: "
@@ -319,7 +362,18 @@ def process_all(data_dir, cfg_path, results_dir, single_nr=None, dry_run=False):
out_dir = os.path.join(results_dir, "omniflo")
os.makedirs(out_dir, exist_ok=True)
omniflo_dir = os.environ.get("DXFM_OMNIFLO") or os.path.join(data_dir, "omniflo")
dxfm_dim = os.environ.get("DXFM_DIM")
if dxfm_dim:
omniflo_dir = os.path.join(data_dir, "omniflo", dxfm_dim)
else:
omniflo_dir = os.environ.get("DXFM_OMNIFLO") or os.path.join(data_dir, "omniflo")
if not os.path.isdir(omniflo_dir) or not any(
f.lower().endswith(".dxf") for f in os.listdir(omniflo_dir)
):
print(f"[set_attributs] FEHLER: Im Quellverzeichnis '{omniflo_dir}' "
f"wurden keine DXF-Dateien gefunden. eventuell DXFM_DIM=2D in Umgebung setzen")
sys.exit(1)
processed = 0
skipped = 0
errors = 0
@@ -348,7 +402,7 @@ def process_all(data_dir, cfg_path, results_dir, single_nr=None, dry_run=False):
output_path = os.path.join(out_dir, dxf_name)
if dry_run:
values = {tag: resolve_value(src, entry, sivasnr)
values = {tag: resolve_value(src, entry, sivasnr, container_map)
for tag, src in attr_defs}
if layer_value:
values["LAYER"] = layer_value
@@ -359,7 +413,8 @@ def process_all(data_dir, cfg_path, results_dir, single_nr=None, dry_run=False):
try:
count = add_attdefs_to_dxf(dxf_path, output_path, attr_defs,
entry, sivasnr,
layer_value=layer_value)
layer_value=layer_value,
container_map=container_map)
processed += 1
print(f" OK: {sivasnr} ({typ}) -> {count} Attribute -> {output_path}")
except Exception as e:
@@ -379,9 +434,13 @@ def main():
help="Nur diese SivasNr verarbeiten")
parser.add_argument("--dry-run", "-d", action="store_true",
help="Nur anzeigen, nicht schreiben")
parser.add_argument("--type", "-t", choices=["2D", "3D"], default="2D",
help="Ueberschreibt DXFM_DIM und damit das "
"Quellverzeichnis data/omniflo/<type> (Default: 2D)")
args = parser.parse_args()
# Umgebungsvariablen
os.environ["DXFM_DIM"] = args.type
data_dir = os.environ.get("DXFM_DATA")
cfg_dir = os.environ.get("DXFM_CFG")
results_dir = os.environ.get("DXFM_RESULTS")