From ad48e9ef76e1bb029893bf13cf563b29f1220427 Mon Sep 17 00:00:00 2001 From: Paul Wolok Date: Mon, 15 Sep 2025 15:10:22 +0200 Subject: [PATCH] =?UTF-8?q?Man=20kann=20jetzt=20bestimmte=20dxf.layer=20du?= =?UTF-8?q?rch=20den=20cofig=20aus=20der=20boundingbox=20berechnung=20f?= =?UTF-8?q?=C3=BCr=20die=20Mitte=20auschlie=C3=9Fen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cfg/allgemein.cfg | 2 + lib/dxf2lib.py | 160 +++------------------------------------------- 2 files changed, 11 insertions(+), 151 deletions(-) diff --git a/cfg/allgemein.cfg b/cfg/allgemein.cfg index 08b3f33..57a18fc 100644 --- a/cfg/allgemein.cfg +++ b/cfg/allgemein.cfg @@ -31,3 +31,5 @@ block_spacing_x = 350 blocks_per_row = 20 # Vertikaler Abstand zwischen Zeilen im Raster (in DXF-Einheiten) block_spacing_y = 500 +# Nicht in die MittelPunkt Berechnung erlaubt +not_allowed_in_center = ("A-GRUPPE","B-GRUPPE") \ No newline at end of file diff --git a/lib/dxf2lib.py b/lib/dxf2lib.py index 54bdcc9..51c9199 100644 --- a/lib/dxf2lib.py +++ b/lib/dxf2lib.py @@ -10,123 +10,6 @@ from utils import check_environment_var, setup_logger from pathlib import Path import logging - -# def get_bbox(entities, transform_matrix=None): -# """ -# Berechnet die Bounding Box für eine Liste von DXF-Entities. - -# Args: -# entities: Liste von DXF-Entities (ezdxf entities) - -# Returns: -# Vec2 or None: Zentrum der Bounding Box als Vec2-Objekt oder None, -# falls keine gültige Geometrie gefunden wurde - -# Note: -# Unterstützt POLYLINE, LWPOLYLINE und andere Entity-Typen. -# Fehlerhafte Entities werden übersprungen und protokolliert. -# """ -# min_x, min_y = float('inf'), float('inf') -# max_x, max_y = float('-inf'), float('-inf') -# for e in entities: -# try: -# if e.dxftype() == "POLYLINE": -# for vertex in e.vertices: -# if 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) -# elif e.dxftype() == "LWPOLYLINE": -# for x, y, *_ in e.get_points("xy"): -# min_x, min_y = min(min_x, x), min(min_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() == "CIRCLE": -# # Handle CIRCLE entities via center and radius -# try: -# cx, cy = e.dsf.center.x, e.dsf.center.y -# except Exception: -# cx, cy = e.dxf.center -# r = float(e.dxf.radius) -# min_x, min_y = min(min_x, cx - r), min(min_y, cy - r) -# max_x, max_y = max(max_x, cx + r), max(max_y, cy + r) -# elif e.dxftype() == "LINE" or 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, ex ), min(min_y, sy, ey) -# max_x, max_y = max(max_x, sx, ex), max(max_y, sy, ey) -# elif e.dxftype() == "SPLINE": -# # Approximate spline to compute bounding box -# points = [] -# try: -# points = e.approximate(60) -# except Exception: -# try: -# points = list(e.flattening(1.0)) -# except Exception: -# points = [] -# if points: -# for pt in points: -# try: -# px, py = pt.x, pt.y -# except Exception: -# px, py = pt[0], pt[1] -# 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() == 'INSERT': -# # INSERT: Block-Inhalt mit Transformation berücksichtigen -# insert_bbox = calculate_insert_bounding_box(e, doc, transform_matrix) -# if insert_bbox and insert_bbox.has_data: -# bbox.extend(insert_bbox) -# else: -# 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, (0,0) - -# 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): """ Erstellt eine DXF-Block-Bibliothek aus einzelnen DXF-Dateien. @@ -215,9 +98,7 @@ def create_block_library(input_dir, output_file, config, logger=None): except Exception: pass - - # center, ausdehnung = get_bbox(entities) - boundingbox, ausdehnung, center = calculate_block_bounding_box(filtered_entities, doc,src_doc, filename) + boundingbox, ausdehnung, center = calculate_block_bounding_box(filtered_entities, doc,src_doc, filename,config) if center is None: error_msg = f"Keine gültige Geometrie in {filename}" if logger: @@ -231,11 +112,7 @@ def create_block_library(input_dir, output_file, config, logger=None): doc.blocks.delete_block(name) blk = doc.blocks.new(name=name, base_point=(0,0)) - - # for e in entities: - # # Sicherstellen, dass referenzierte Blöcke für INSERT verfügbar sind - # if e.dxftype() == "INSERT": - # handle_insert_entities(doc, src_doc, e) + for e in entities: cp = copy_entity(logger, error_files, filename, e, center) if cp: @@ -368,25 +245,6 @@ def copy_entity(logger, error_files, filename, e, center): error_files.append((filename, error_msg)) return None -def handle_insert_entities(doc, src_doc, e): - - try: - ref_name = e.dxf.name - if ref_name not in doc.blocks and ref_name in src_doc.blocks: - src_blk = src_doc.blocks[ref_name] - dst_blk = doc.blocks.new(name=ref_name) - # Basis­punkt übernehmen, falls vorhanden - try: - dst_blk.block.dxf.base_point = src_blk.block.dxf.base_point - - except Exception: - pass - for ent in src_blk: - dst_blk.add_entity(ent.copy()) - - - except Exception: - pass # Standardwerte (falls nicht in der Config) @@ -507,7 +365,7 @@ def copy_block_definitions(source_doc, target_doc): return copied_blocks -def calculate_block_bounding_box(block, doc, src_doc, filename): +def calculate_block_bounding_box(block, doc, src_doc, filename,config): """ Berechnet die Bounding Box eines Blocks inklusive aller INSERTs """ @@ -515,7 +373,7 @@ def calculate_block_bounding_box(block, doc, src_doc, filename): bbox = BoundingBox() for entity in block: - entity_bbox = get_entity_bounding_box(entity, doc,src_doc,filename) + entity_bbox = get_entity_bounding_box(entity, doc,src_doc,filename,config) if entity_bbox and entity_bbox.has_data: bbox.extend(entity_bbox) @@ -523,7 +381,7 @@ def calculate_block_bounding_box(block, doc, src_doc, filename): return bbox, (bbox.extmax.x -bbox.extmin.x, bbox.extmax.y -bbox.extmin.y),bbox.center -def get_entity_bounding_box(e, doc,src_doc,filename, transform_matrix=None,): +def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=None): """ Berechnet die Bounding Box einer einzelnen Entity Berücksichtigt INSERTs mit ihren Block-Inhalten @@ -632,8 +490,8 @@ def get_entity_bounding_box(e, doc,src_doc,filename, transform_matrix=None,): elif e.dxftype() == 'INSERT': # INSERT: Block-Inhalt mit Transformation berücksichtigen - insert_bbox = calculate_insert_bounding_box(e, doc,src_doc,filename, transform_matrix) - if insert_bbox and insert_bbox.has_data: + insert_bbox = calculate_insert_bounding_box(e, doc,src_doc,filename,config, transform_matrix) + if insert_bbox and insert_bbox.has_data and e.dxf.layer not in config.get("dxf2lib","not_allowed_in_center"): bbox.extend(insert_bbox) except Exception as e: @@ -647,7 +505,7 @@ def extract_scaling(matrix): sy = math.sqrt(matrix[1, 0]**2 + matrix[1, 1]**2 + matrix[1, 2]**2) return sx, sy, -def calculate_insert_bounding_box(insert_entity, doc,src_doc,filename,parent_transform=None): +def calculate_insert_bounding_box(insert_entity, doc,src_doc,filename,config,parent_transform=None): """ Berechnet die Bounding Box eines INSERTs inklusive Block-Inhalt """ @@ -686,7 +544,7 @@ def calculate_insert_bounding_box(insert_entity, doc,src_doc,filename,parent_tra for block_entity in block_def: - entity_bbox= get_entity_bounding_box(block_entity, doc,src_doc,filename, combined_transform) + entity_bbox= get_entity_bounding_box(block_entity, doc,src_doc,filename, config,combined_transform) if entity_bbox and entity_bbox.has_data: if new_insert: dst_blk.add_entity(block_entity.copy())