Hinzufügen von Linen und arc für getboundingbox
This commit is contained in:
+54
-19
@@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import ezdxf
|
import ezdxf
|
||||||
from ezdxf.math import Vec2
|
from ezdxf.math import Vec2
|
||||||
|
import math
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import shutil
|
import shutil
|
||||||
@@ -38,7 +39,47 @@ def get_bbox(entities):
|
|||||||
for x, y, *_ in e.get_points("xy"):
|
for x, y, *_ in e.get_points("xy"):
|
||||||
min_x, min_y = min(min_x, x), min(min_y, 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)
|
max_x, max_y = max(max_x, x), max(max_y, y)
|
||||||
|
elif e.dxftype() == "ARC":
|
||||||
|
# Handle ARC entities: consider endpoints and cardinal extrema
|
||||||
|
try:
|
||||||
|
cx, cy = e.dxf.center.x, e.dxf.center.y
|
||||||
|
except Exception:
|
||||||
|
cx, cy = e.dxf.center
|
||||||
|
r = float(e.dxf.radius)
|
||||||
|
start_deg = float(e.dxf.start_angle)
|
||||||
|
end_deg = float(e.dxf.end_angle)
|
||||||
|
start = math.radians(start_deg % 360)
|
||||||
|
end = math.radians(end_deg % 360)
|
||||||
|
|
||||||
|
def in_sweep(a: float, s: float, e_: float) -> bool:
|
||||||
|
# CCW sweep from s to e_ with wrap handling
|
||||||
|
if e_ >= s:
|
||||||
|
return s <= a <= e_
|
||||||
|
return a >= s or a <= e_
|
||||||
|
|
||||||
|
candidates = []
|
||||||
|
# Endpoints
|
||||||
|
candidates.append((cx + r * math.cos(start), cy + r * math.sin(start)))
|
||||||
|
candidates.append((cx + r * math.cos(end), cy + r * math.sin(end)))
|
||||||
|
# Cardinal angles 0, 90, 180, 270 deg
|
||||||
|
for ang in (0.0, math.pi/2, math.pi, 3*math.pi/2):
|
||||||
|
if in_sweep(ang, start, end):
|
||||||
|
candidates.append((cx + r * math.cos(ang), cy + r * math.sin(ang)))
|
||||||
|
for px, py in candidates:
|
||||||
|
min_x, min_y = min(min_x, px), min(min_y, py)
|
||||||
|
max_x, max_y = max(max_x, px), max(max_y, py)
|
||||||
|
elif e.dxftype() == "LINE":
|
||||||
|
# Handle simple line entities by their start/end points
|
||||||
|
try:
|
||||||
|
sx, sy = e.dxf.start.x, e.dxf.start.y
|
||||||
|
ex, ey = e.dxf.end.x, e.dxf.end.y
|
||||||
|
except Exception:
|
||||||
|
# Some ezdxf versions provide tuples
|
||||||
|
(sx, sy), (ex, ey) = e.dxf.start, e.dxf.end
|
||||||
|
min_x, min_y = min(min_x, sx), min(min_y, sy)
|
||||||
|
max_x, max_y = max(max_x, ex), max(max_y, ey)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
# Für andere Entity-Typen: Standard bbox() verwenden
|
# Für andere Entity-Typen: Standard bbox() verwenden
|
||||||
box = e.bbox()
|
box = e.bbox()
|
||||||
if box:
|
if box:
|
||||||
@@ -50,9 +91,9 @@ def get_bbox(entities):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if min_x == float('inf'):
|
if min_x == float('inf'):
|
||||||
return None
|
return None, None
|
||||||
|
|
||||||
return Vec2((min_x + max_x) / 2, (min_y + max_y) / 2)
|
return Vec2((min_x + max_x) / 2, (min_y + max_y) / 2), (max_x -min_x, max_y -min_y)
|
||||||
|
|
||||||
|
|
||||||
def create_block_library(input_dir, output_file, config, logger=None):
|
def create_block_library(input_dir, output_file, config, logger=None):
|
||||||
@@ -109,7 +150,7 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
|||||||
error_files.append((filename, error_msg))
|
error_files.append((filename, error_msg))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
center = get_bbox(entities)
|
center, ausdehnung = get_bbox(entities)
|
||||||
if center is None:
|
if center is None:
|
||||||
error_msg = f"Keine gültige Geometrie in {filename}"
|
error_msg = f"Keine gültige Geometrie in {filename}"
|
||||||
if logger:
|
if logger:
|
||||||
@@ -148,9 +189,13 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
|||||||
max_len = get_cfg_value(section, "max_len", DEFAULTS["max_len"])
|
max_len = get_cfg_value(section, "max_len", DEFAULTS["max_len"])
|
||||||
text_height = get_cfg_value(section, "text_height", DEFAULTS["text_height"])
|
text_height = get_cfg_value(section, "text_height", DEFAULTS["text_height"])
|
||||||
line_spacing = get_cfg_value(section, "line_spacing", DEFAULTS["line_spacing"])
|
line_spacing = get_cfg_value(section, "line_spacing", DEFAULTS["line_spacing"])
|
||||||
block_spacing_x = get_cfg_value(section, "block_spacing_x", DEFAULTS["block_spacing_x"])
|
# block_spacing_x = get_cfg_value(section, "block_spacing_x", DEFAULTS["block_spacing_x"])
|
||||||
|
extra_block_space_x = get_cfg_value(section, "extra_block_space_x", DEFAULTS["extra_block_space_x"])
|
||||||
|
block_spacing_x = ausdehnung[0] + extra_block_space_x
|
||||||
blocks_per_row = get_cfg_value(section, "blocks_per_row", DEFAULTS["blocks_per_row"])
|
blocks_per_row = get_cfg_value(section, "blocks_per_row", DEFAULTS["blocks_per_row"])
|
||||||
block_spacing_y = get_cfg_value(section, "block_spacing_y", DEFAULTS["block_spacing_y"])
|
# block_spacing_y = get_cfg_value(section, "block_spacing_y", DEFAULTS["block_spacing_y"])
|
||||||
|
block_spacing_y = ausdehnung[1]
|
||||||
|
|
||||||
|
|
||||||
if len(name) > max_len:
|
if len(name) > max_len:
|
||||||
first_line = name[:max_len]
|
first_line = name[:max_len]
|
||||||
@@ -203,10 +248,9 @@ DEFAULTS = {
|
|||||||
"max_len": 9, # Maximale Zeichenlänge pro Textzeile (bei Überschreitung wird umgebrochen)
|
"max_len": 9, # Maximale Zeichenlänge pro Textzeile (bei Überschreitung wird umgebrochen)
|
||||||
"text_height": 20, # Schriftgröße des Texts (in DXF-Einheiten)
|
"text_height": 20, # Schriftgröße des Texts (in DXF-Einheiten)
|
||||||
"line_spacing": 22, # Abstand zwischen zwei Textzeilen bei Umbrüchen (in DXF-Einheiten)
|
"line_spacing": 22, # Abstand zwischen zwei Textzeilen bei Umbrüchen (in DXF-Einheiten)
|
||||||
"block_spacing_x": 350, # Horizontaler Abstand zwischen Blöcken in einer Reihe (in DXF-Einheiten)
|
|
||||||
"blocks_per_row": 20, # Anzahl Blöcke pro Zeile im Raster
|
"blocks_per_row": 20, # Anzahl Blöcke pro Zeile im Raster
|
||||||
"block_spacing_y": 500, # Vertikaler Abstand zwischen Zeilen im Raster (in DXF-Einheiten)
|
"extra_block_space_x" : 50 # Extra Platz damit sich Blöcke nicht überlappen
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_cfg_value(section, key, fallback):
|
def get_cfg_value(section, key, fallback):
|
||||||
try:
|
try:
|
||||||
@@ -219,8 +263,7 @@ if __name__ == "__main__":
|
|||||||
parser = argparse.ArgumentParser(description="SVG/XML zu DXF Konverter")
|
parser = argparse.ArgumentParser(description="SVG/XML zu DXF Konverter")
|
||||||
parser.add_argument('-i', '--input', type=str, help='Input-Verzeichnis mit SVG/XML-Dateien')
|
parser.add_argument('-i', '--input', type=str, help='Input-Verzeichnis mit SVG/XML-Dateien')
|
||||||
parser.add_argument('-n', '--name', required=False, type=str, help='Name der zu erzeugenden Bibliothek (optional, wird sonst abgefragt)')
|
parser.add_argument('-n', '--name', required=False, type=str, help='Name der zu erzeugenden Bibliothek (optional, wird sonst abgefragt)')
|
||||||
parser.add_argument('-k', '--keep', action="store_true", help='Behalte converted_dxf Ordner. Sonst Löschen nach erfolgreicher Bibliothekserstellung')
|
|
||||||
|
|
||||||
if len(sys.argv) == 2 and sys.argv[1] in ("-h", "--help"):
|
if len(sys.argv) == 2 and sys.argv[1] in ("-h", "--help"):
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
@@ -238,7 +281,7 @@ if __name__ == "__main__":
|
|||||||
INPUT_DIR = Path(args.input)
|
INPUT_DIR = Path(args.input)
|
||||||
print(f"Verwende Input-Verzeichnis: {INPUT_DIR} \n")
|
print(f"Verwende Input-Verzeichnis: {INPUT_DIR} \n")
|
||||||
else:
|
else:
|
||||||
INPUT_DIR = check_environment_var("PROJECT_WORK") / "converted_dxfs"
|
INPUT_DIR = check_environment_var("PROJECT_DATA") / "dxf"
|
||||||
print(f"Kein Input-Verzeichnis angegeben, verwende Standard: {INPUT_DIR} \n")
|
print(f"Kein Input-Verzeichnis angegeben, verwende Standard: {INPUT_DIR} \n")
|
||||||
|
|
||||||
OUTPUT_FILE = check_environment_var("PROJECT_DATA") / "block_libaries" / f"{args.name}.dxf"
|
OUTPUT_FILE = check_environment_var("PROJECT_DATA") / "block_libaries" / f"{args.name}.dxf"
|
||||||
@@ -265,13 +308,5 @@ if __name__ == "__main__":
|
|||||||
logger.info(f"Erstelle Block-Bibliothek aus {INPUT_DIR}...")
|
logger.info(f"Erstelle Block-Bibliothek aus {INPUT_DIR}...")
|
||||||
create_block_library(INPUT_DIR, OUTPUT_FILE, config, logger)
|
create_block_library(INPUT_DIR, OUTPUT_FILE, config, logger)
|
||||||
|
|
||||||
if not args.keep:
|
|
||||||
logger.info(f"Keep-Argument nicht gesetzt, lösche Input-Verzeichnis: {INPUT_DIR}")
|
|
||||||
try:
|
|
||||||
if INPUT_DIR.exists():
|
|
||||||
shutil.rmtree(INPUT_DIR)
|
|
||||||
logger.info(f"Verzeichnis '{INPUT_DIR}' wurde gelöscht.")
|
|
||||||
except Exception as err:
|
|
||||||
logger.warning(f"Konnte '{INPUT_DIR}' nicht löschen: {err}")
|
|
||||||
|
|
||||||
logger.info("=== DXF2LIB Verarbeitung abgeschlossen ===")
|
logger.info("=== DXF2LIB Verarbeitung abgeschlossen ===")
|
||||||
|
|||||||
Reference in New Issue
Block a user