[ADD] Geruest: Teile-DWGs (data/geruest/<artnr>.dwg) als Geometrie im GR_-Block; TEILEFARBE als Liste parallel zu ARTINR (Flag farbig in geruest.json), Sivas-Merkmal 108 aus cfg [Sivas]; Menue-Befehle GERUEST_SAEULEN/_ROHRABHAENGER/_WANDBEFESTIGUNG

[FIX] Sivas-Export las nicht existierendes Attribut FARBE
This commit is contained in:
Simon Hensch
2026-09-29 12:07:00 +02:00
parent 66c4336b9e
commit 4e39c64ec1
21 changed files with 637 additions and 383 deletions
+62 -22
View File
@@ -54,12 +54,18 @@ import json
import sys
import os
from export_blockpatterns import load_patterns, matches_any, csv_quote, safe_float, safe_int
from export_blockpatterns import (load_patterns, load_export_cfg, cfg_path_from_env,
matches_any, csv_quote, safe_float, safe_int)
from merkmalstamm import lade_merkmalstamm, bezeichnung_fuer
import sivas_mapping
BLOCKPATTERNS = load_patterns()
# Merkmalnummer fuer die Teilefarbe der Geruest-Baugruppen ([Sivas] in
# cfg/export.cfg; 108 = "Farbe" im Merkmalstamm).
MERKMAL_TEILEFARBE = load_export_cfg(cfg_path_from_env()).get(
"Sivas", "merkmal_teilefarbe", fallback="108").strip()
def load_json(path):
"""Laedt JSON, tolerant gegenueber BricsCAD-Ausgaben.
@@ -310,17 +316,51 @@ def build_eckrad_details(block):
return sivas_mapping.anwenden(SIVAS_MAPPING_ECKRAD, attribs, TRANSFORMS)
def build_geruest_details(block):
"""Merkmale-Dict fuer eine GR_-Geruest-Baugruppe (siehe pattern_geruest in
cfg/export.cfg, GeruestInsert.lsp *geruest-attrib-defs*). ARTINR/
BEZEICHNUNG/TEILEART/LAENGE wandern in feste Sivas-Spalten (sivasnr/
bezeichnung/teileart/laenge_mm), FARBE bleibt als Rest-Attribut hier
(cfg/sivas.cfg [geruest]). LAYER ist reine BricsCAD-Zeichnungsinformation
ohne Sivas-Bedeutung und wird bewusst NICHT mit exportiert (anders als im
CSV-Export export_csv.py, wo sie fuer die Zuordnung in der Zeichnung
nuetzlich bleibt)."""
attribs = block.get("attribs", {})
return sivas_mapping.anwenden(SIVAS_MAPPING_GERUEST, attribs, TRANSFORMS)
# def build_geruest_details(block):
#"""Merkmale-Dict fuer eine GR_-Geruest-Baugruppe (siehe pattern_geruest in
#cfg/export.cfg, GeruestInsert.lsp *geruest-attrib-defs*). ARTINR/
#BEZEICHNUNG/TEILEART/LAENGE wandern in feste Sivas-Spalten (sivasnr/
#bezeichnung/teileart/laenge_mm), FARBE bleibt als Rest-Attribut hier
#(cfg/sivas.cfg [geruest]). LAYER ist reine BricsCAD-Zeichnungsinformation
#ohne Sivas-Bedeutung und wird bewusst NICHT mit exportiert (anders als im
#CSV-Export export_csv.py, wo sie fuer die Zuordnung in der Zeichnung
#nuetzlich bleibt)."""
#attribs = block.get("attribs", {})
#return sivas_mapping.anwenden(SIVAS_MAPPING_GERUEST, attribs, TRANSFORMS)
def build_geruest_details(farbe):
"""Merkmale-Dict fuer EINE Artikelnummer einer GR_-Geruest-Baugruppe
(siehe pattern_geruest in cfg/export.cfg, GeruestInsert.lsp
*geruest-attrib-defs*). ARTINR/BEZEICHNUNG/TEILEART/LAENGE wandern in
feste Sivas-Spalten (sivasnr/bezeichnung/teileart/laenge_mm); hier bleibt
nur die Teilefarbe dieser Artikelnummer als Merkmal MERKMAL_TEILEFARBE -
ohne Farbe (Teil darf keine tragen) ein leeres Dict. LAYER ist reine
BricsCAD-Zeichnungsinformation ohne Sivas-Bedeutung und wird bewusst
NICHT mit exportiert (anders als im CSV-Export export_csv.py, wo sie fuer
die Zuordnung in der Zeichnung nuetzlich bleibt)."""
return {MERKMAL_TEILEFARBE: farbe} if farbe else {}
def geruest_artinr_farben(attribs):
"""(artinr, farbe)-Paare eines GR_-Blocks. TEILEFARBE ist eine
kommagetrennte Liste parallel zu ARTINR (GeruestInsert.lsp,
geruest-farbliste): je Artikelnummer die Baugruppenfarbe oder "".
Passt die Laenge nicht (Altbestand mit einem Einzelwert oder von Hand
geaendertes Attribut), wird gewarnt und ohne Farbe exportiert - eine
geratene Zuordnung waere schlimmer als keine. Leere Artikelnummern
werden verworfen."""
artinr_roh = attribs.get("ARTINR", "").split(",")
farben_roh = attribs.get("TEILEFARBE", "")
farben = [f.strip() for f in farben_roh.split(",")]
if farben_roh.strip() == "":
farben = [""] * len(artinr_roh)
elif len(farben) != len(artinr_roh):
print(f"WARNUNG: Geruest-Block ID {attribs.get('ID', '?')}: TEILEFARBE "
f"({len(farben)} Eintraege) passt nicht zu ARTINR "
f"({len(artinr_roh)} Eintraege) - ohne Farbe exportiert.",
file=sys.stderr)
farben = [""] * len(artinr_roh)
return [(a.strip(), f) for a, f in zip(artinr_roh, farben) if a.strip()]
# --- Bekannte Bloecke ignorieren ---
@@ -706,14 +746,15 @@ def process_blocks(blocks):
# zusammengefasst (wie omniflo_groups oben). Die volle
# LAENGE der Baugruppe steht auf JEDER so entstandenen Zeile - Sivas hat
# kein Konzept einer "gemeinsamen" Laenge ueber mehrere Zeilen hinweg.
# Die Teilefarbe steht je Artikelnummer in TEILEFARBE (parallele Liste),
# gruppiert wird darum ueber (Artikelnummer, Farbe).
for block in geruest_list:
attribs = block.get("attribs", {})
artinr_list = [a.strip() for a in attribs.get("ARTINR", "").split(",") if a.strip()]
artinr_groups = {}
for artinr in artinr_list:
artinr_groups.setdefault(artinr, 0)
artinr_groups[artinr] += 1
for artinr, anzahl in artinr_groups.items():
for paar in geruest_artinr_farben(attribs):
artinr_groups.setdefault(paar, 0)
artinr_groups[paar] += 1
for (artinr, farbe), anzahl in artinr_groups.items():
items.append({
"nr": nr,
"teileart": attribs.get("TEILEART", "Geruest"),
@@ -724,7 +765,7 @@ def process_blocks(blocks):
"anzahl": anzahl,
"laenge_mm": attribs.get("LAENGE", ""),
"ids": [get_id(block)],
"details": build_geruest_details(block),
"details": build_geruest_details(farbe),
})
nr += 1
@@ -861,10 +902,9 @@ def format_csv_line(item, details=None):
def details_mit_bezeichnung(details, merkmalstamm):
"""Kopie von details, bei der jeder Merkmalnummer-Key durch seine
Klartext-Bezeichnung aus dem Merkmalstamm ersetzt wird (Wert bleibt
unveraendert). Keys, die keine reine Zahl sind (aktuell nur bei
Eckrad/Geruest, siehe build_eckrad_details/build_geruest_details - dort
noch beschreibende Klartext-Keys statt Merkmalnummern), bleiben
unveraendert."""
unveraendert). Keys, die keine reine Zahl sind (aktuell nur beim
Eckrad, siehe build_eckrad_details - dort noch beschreibende
Klartext-Keys statt Merkmalnummern), bleiben unveraendert."""
neu = {}
for key, value in details.items():
if key.isdigit():