Files
plant2dxf/lib/dxf2lib
T

100 lines
3.5 KiB
Plaintext

import os
import ezdxf
from ezdxf.math import Vec2
# Hilfsfunktion für Umgebungsvariablen mit Fallback
def check_environment_var(env_str: str, fallback: str) -> str:
out_path = os.environ.get(env_str)
if out_path:
return out_path
print(f"[WARN] Umgebungsvariable {env_str} ist nicht gesetzt oder leer. Verwende '{fallback}'.")
return fallback
# Verzeichnisse/Dateien über Umgebungsvariablen oder Fallback
INPUT_DIR = os.path.join(check_environment_var("PROJECT_WORK", "."), "converted_dxfs")
OUTPUT_FILE = os.path.join(check_environment_var("PROJECT_WORK", "."), "block_library.dxf")
doc = ezdxf.new()
msp = doc.modelspace()
def get_bbox(entities):
min_x, min_y = float('inf'), float('inf')
max_x, max_y = float('-inf'), float('-inf')
for e in entities:
try:
# Für POLYLINE-Entities: Bounding Box manuell berechnen
if e.dxftype() == "POLYLINE":
if hasattr(e, 'vertices') and len(e.vertices) > 0:
for vertex in e.vertices:
if hasattr(vertex, 'dxf') and hasattr(vertex.dxf, 'location'):
x, y = vertex.dxf.location.x, vertex.dxf.location.y
min_x, min_y = min(min_x, x), min(min_y, y)
max_x, max_y = max(max_x, x), max(max_y, y)
else:
# Für andere Entity-Typen: Standard bbox() verwenden
box = e.bbox()
if box:
(x1, y1), (x2, y2) = box.extmin, box.extmax
min_x, min_y = min(min_x, x1), min(min_y, y1)
max_x, max_y = max(max_x, x2), max(max_y, y2)
except Exception as err:
print(f" BBox Fehler für {e.dxftype()}: {err}")
continue
if min_x == float('inf'):
return None
return Vec2((min_x + max_x) / 2, (min_y + max_y) / 2)
x_offset = 0
y_offset = 0
blocks_in_row = 0
for filename in os.listdir(INPUT_DIR):
if not filename.lower().endswith(".dxf"):
continue
filepath = os.path.join(INPUT_DIR, filename)
name = os.path.splitext(filename)[0]
try:
src_doc = ezdxf.readfile(filepath)
src_msp = src_doc.modelspace()
entities = list(src_msp)
allowed_types = {"LINE", "LWPOLYLINE", "POLYLINE", "SPLINE", "CIRCLE", "ARC"}
filtered_entities = [e for e in entities if e.dxftype() in allowed_types]
entities = filtered_entities
except Exception as e:
print(f"Fehler beim Lesen von {filename}: {e}")
continue
center = get_bbox(entities)
if center is None:
print(f"Keine gültige Geometrie in {filename}")
continue
if name in doc.blocks:
doc.blocks.delete_block(name)
blk = doc.blocks.new(name=name, base_point=center)
for e in entities:
try:
blk.add_entity(e.copy())
except Exception as err:
print(f"Fehler in {filename}: {err}")
# Platzierung in Reihen und Spalten
msp.add_blockref(name, insert=(x_offset, y_offset))
# Text mit Blocknamen über dem Block
text_y = y_offset + 150 # 150 Einheiten über dem Block
msp.add_text(name, dxfattribs={'height': 20, 'insert': (x_offset-150, text_y)})
blocks_in_row += 1
x_offset += 350 # Abstand zwischen Blöcken in einer Reihe
if blocks_in_row == 20:
blocks_in_row = 0
x_offset = 0
y_offset -= 500 # Neue Zeile, nach unten versetzt
print(f"Bibliotheks-DXF gespeichert: {OUTPUT_FILE}")
doc.saveas(OUTPUT_FILE)