""" Teilt ils_library.dxf in einzelne DXF-Dateien pro Block auf. Jede Ausgabedatei enthaelt den Block + alle seine Unterblock-Abhaengigkeiten. Aufruf: python split_block_library.py """ import os import sys import ezdxf from ezdxf.document import Drawing # Pfade SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) PROJECT_ROOT = os.path.dirname(SCRIPT_DIR) LIB_PATH = os.path.join(PROJECT_ROOT, "data", "block_libraries", "ils_library.dxf") OUT_DIR = os.path.join(PROJECT_ROOT, "data", "ils") # Nur diese Bloecke exportieren (alle fuer den Vario-Foerderer relevanten) EXPORT_PREFIXES = ( "Vario_", "Staustrecke_", "_3D_AS_", "_3D_ES_", ) # Abhaengigkeiten: KS_EIN und KS_AUS muessen immer mitgeliefert werden ALWAYS_INCLUDE = {"KS_EIN", "KS_AUS"} def collect_dependencies(src_doc: Drawing, blockname: str, visited: set) -> set: """Gibt alle Unterblock-Namen zurueck, die 'blockname' direkt oder transitiv benoetigt.""" if blockname in visited: return visited visited.add(blockname) if blockname not in src_doc.blocks: return visited blk = src_doc.blocks[blockname] for entity in blk: if entity.dxftype() == "INSERT": ref = entity.dxf.name collect_dependencies(src_doc, ref, visited) return visited def copy_block(src_doc: Drawing, dst_doc: Drawing, blockname: str): """Kopiert einen Block und seine Abhaengigkeiten von src nach dst.""" deps = collect_dependencies(src_doc, blockname, set()) for name in deps: if name not in src_doc.blocks: continue if name in dst_doc.blocks: continue src_blk = src_doc.blocks[name] # Neuen Block im Zieldokument anlegen dst_blk = dst_doc.blocks.new( name=name, base_point=src_blk.block.dxf.base_point if hasattr(src_blk.block.dxf, "base_point") else (0, 0, 0), ) # Alle Entities kopieren (ausser BLOCK/ENDBLK - die werden automatisch erstellt) for entity in src_blk: try: dst_blk.add_entity(entity.copy()) except Exception: pass def export_block(src_doc: Drawing, blockname: str, out_dir: str): """Exportiert einen einzelnen Block als eigene DXF-Datei.""" safe_name = blockname.replace("/", "_").replace("\\", "_") out_path = os.path.join(out_dir, safe_name + ".dxf") dst_doc = ezdxf.new(dxfversion="R2010") dst_doc.units = src_doc.units # Layer aus Quelldatei uebernehmen (nur die benutzten) for layer in src_doc.layers: if layer.dxf.name not in dst_doc.layers: try: dst_doc.layers.new( name=layer.dxf.name, dxfattribs={"color": layer.dxf.get("color", 7)}, ) except Exception: pass # Block + Abhaengigkeiten kopieren copy_block(src_doc, dst_doc, blockname) dst_doc.saveas(out_path) return out_path def main(): print(f"Lese Bibliothek: {LIB_PATH}") if not os.path.exists(LIB_PATH): print(f"FEHLER: Datei nicht gefunden: {LIB_PATH}") sys.exit(1) src_doc = ezdxf.readfile(LIB_PATH) print(f" Geladen. Bloecke gesamt: {len(list(src_doc.blocks))}") os.makedirs(OUT_DIR, exist_ok=True) # Relevante Bloecke filtern to_export = [] for blk in src_doc.blocks: name = blk.name if name.startswith("*"): continue if any(name.startswith(p) for p in EXPORT_PREFIXES) or name in ALWAYS_INCLUDE: to_export.append(name) print(f" Zu exportierende Bloecke: {len(to_export)}") ok = 0 fail = 0 for name in sorted(to_export): try: out = export_block(src_doc, name, OUT_DIR) # KS_EIN/KS_AUS pruefen check_doc = ezdxf.readfile(out) has_ks_ein = "KS_EIN" in check_doc.blocks has_ks_aus = "KS_AUS" in check_doc.blocks ks_status = "" if name not in ALWAYS_INCLUDE: blk = check_doc.blocks[name] inserts = [e.dxf.name for e in blk if e.dxftype() == "INSERT"] has_ks_ein_ref = "KS_EIN" in inserts has_ks_aus_ref = "KS_AUS" in inserts ks_status = f" KS_EIN={'ja' if has_ks_ein_ref else 'NEIN'} KS_AUS={'ja' if has_ks_aus_ref else 'NEIN'}" print(f" OK {name}{ks_status}") ok += 1 except Exception as e: print(f" FEHLER {name}: {e}") fail += 1 print(f"\nErgebnis: {ok} exportiert, {fail} Fehler") print(f"Ausgabeverzeichnis: {OUT_DIR}") if __name__ == "__main__": main()