From 3c4a149aa6c434c2419f047755ed1fe7d4d6bba7 Mon Sep 17 00:00:00 2001 From: Paul Wolok Date: Tue, 9 Sep 2025 15:04:51 +0200 Subject: [PATCH] inserts funktionieren jetzt muss noch mittelpunkt richtig setzten --- lib/dxf2lib.py | 303 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 206 insertions(+), 97 deletions(-) diff --git a/lib/dxf2lib.py b/lib/dxf2lib.py index e0de2e5..f9c9467 100644 --- a/lib/dxf2lib.py +++ b/lib/dxf2lib.py @@ -213,9 +213,10 @@ def create_block_library(input_dir, output_file, config, logger=None): except Exception: pass - + if filename == "0_BG090090_834372101_0_BG090090.dxf": + filetest =3 # center, ausdehnung = get_bbox(entities) - center, ausdehnung = get_entity_bounding_box(entities, doc, transform_matrix=None) + boundingbox, ausdehnung, center = calculate_block_bounding_box(filtered_entities, doc,src_doc, filename) if center is None: error_msg = f"Keine gültige Geometrie in {filename}" if logger: @@ -229,16 +230,18 @@ 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) - cp = copy_entity(logger, error_files, filename, e, center) - if cp: - blk.add_entity(cp) - # Platzierung in Reihen und Spalten - # Attribut-Definition (ATTDEF) hinzufügen + for e in entities: + cp = copy_entity(logger, error_files, filename, e, center) + if cp: + copy_entity_to_block(cp,blk) + # blk.add_entity(cp) + # Platzierung in Reihen und Spalten + # Attribut-Definition (ATTDEF) hinzufügen blk.add_attdef( tag="NAME", insert=(0.2, 0.2), # Position relativ zum Blockursprung @@ -347,7 +350,7 @@ def copy_entity(logger, error_files, filename, e, center): try: cp = e.copy() # Geometrie verschieben! - cp.translate(-center.x, -center.y, 0) + cp.translate(-center.x, -center.y,0) # Ursprungs-Layer übernehmen if hasattr(e.dxf, "layer"): cp.dxf.layer = e.dxf.layer @@ -503,115 +506,220 @@ def copy_block_definitions(source_doc, target_doc): return copied_blocks -def calculate_block_bounding_box(block, doc): +def calculate_block_bounding_box(block, doc, src_doc, filename): """ Berechnet die Bounding Box eines Blocks inklusive aller INSERTs """ + bbox = BoundingBox() for entity in block: - entity_bbox = get_entity_bounding_box(entity, doc) + entity_bbox = get_entity_bounding_box(entity, doc,src_doc,filename) if entity_bbox and entity_bbox.has_data: bbox.extend(entity_bbox) - return bbox + return bbox, (bbox.extmax.x -bbox.extmin.x, bbox.extmax.y -bbox.extmin.y),Vec2(((bbox.extmax.x + bbox.extmin.x) / 2, (bbox.extmax.y + bbox.extmin.y) /2)) -def get_entity_bounding_box(entity, doc, transform_matrix=None): +def get_entity_bounding_box(e, doc,src_doc,filename, transform_matrix=None,): """ Berechnet die Bounding Box einer einzelnen Entity Berücksichtigt INSERTs mit ihren Block-Inhalten """ + bbox = BoundingBox() - for e in entity: - try: - if e.dxftype() == 'LINE': - start = Vec3(e.dxf.start) - end = Vec3(e.dxf.end) - if transform_matrix: - start = transform_matrix.transform(start) - end = transform_matrix.transform(end) - bbox.extend([start, end]) - - elif e.dxftype() == 'CIRCLE': - center = Vec3(e.dxf.center) - radius = e.dxf.radius - if transform_matrix: - center = transform_matrix.transform(center) - # Radius mit durchschnittlicher Skalierung anpassen - scale_factor = (transform_matrix.scale_x + transform_matrix.scale_y) / 2 - radius *= abs(scale_factor) - - bbox.extend([ - Vec3(center.x - radius, center.y - radius, center.z), - Vec3(center.x + radius, center.y + radius, center.z) - ]) - - elif e.dxftype() == 'ARC': - # Vereinfachung: Bounding Box des vollständigen Kreises - center = Vec3(e.dxf.center) - radius = e.dxf.radius - if transform_matrix: - center = transform_matrix.transform(center) - scale_factor = (transform_matrix.scale_x + transform_matrix.scale_y) / 2 - radius *= abs(scale_factor) - - bbox.extend([ - Vec3(center.x - radius, center.y - radius, center.z), - Vec3(center.x + radius, center.y + radius, center.z) - ]) - - elif e.dxftype() == 'LWPOLYLINE': - points = [] - for point in e.get_points(): - pt = Vec3(point[0], point[1], 0) - if transform_matrix: - pt = transform_matrix.transform(pt) - points.append(pt) - if points: - bbox.extend(points) - - elif e.dxftype() == 'POLYLINE': - points = [] - for vertex in e.vertices: - pt = Vec3(vertex.dxf.location) - if transform_matrix: - pt = transform_matrix.transform(pt) - points.append(pt) - if points: - bbox.extend(points) - - elif e.dxftype() == 'TEXT': - # Vereinfachung: Nur Insert-Point berücksichtigen - insert_point = Vec3(e.dxf.insert) - if transform_matrix: - insert_point = transform_matrix.transform(insert_point) - bbox.extend([insert_point]) - - 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) - - except Exception as e: - print(f"Fehler bei Bounding Box Berechnung für {entity.dxftype()}: {e}") + - return bbox,( bbox.extmax.x - bbox.extmin.x,bbox.extmax.y -bbox.extmin.y) + + try: + if e.dxftype() == 'LINE': + start = Vec3(e.dxf.start) + end = Vec3(e.dxf.end) + if transform_matrix: + start = transform_matrix.transform(start) + end = transform_matrix.transform(end) + bbox.extend([start, end]) + + elif e.dxftype() == 'CIRCLE': + center = Vec3(e.dxf.center) + radius = e.dxf.radius + if transform_matrix: + center = transform_matrix.transform(center) + # Radius mit durchschnittlicher Skalierung anpassen + scale_factor = (transform_matrix.scale_x + transform_matrix.scale_y) / 2 + radius *= abs(scale_factor) + + bbox.extend([ + Vec3(center.x - radius, center.y - radius, center.z), + Vec3(center.x + radius, center.y + radius, center.z) + ]) + + elif e.dxftype() == 'ARC': + # Vereinfachung: Bounding Box des vollständigen Kreises + center = Vec3(e.dxf.center) + radius = e.dxf.radius + if transform_matrix: + center = transform_matrix.transform(center) + x,y =extract_scaling(transform_matrix) + x,y =extract_scaling(transform_matrix) + scale_factor = (x+y)/2 + radius *= abs(scale_factor) + + bbox.extend([ + Vec3(center.x - radius, center.y - radius, center.z), + Vec3(center.x + radius, center.y + radius, center.z) + ]) + + elif e.dxftype() == 'LWPOLYLINE': + points = [] + for point in e.get_points(): + pt = Vec3(point[0], point[1], 0) + if transform_matrix: + pt = transform_matrix.transform(pt) + points.append(pt) + if points: + bbox.extend(points) + + elif e.dxftype() == 'POLYLINE': + points = [] + for vertex in e.vertices: + pt = Vec3(vertex.dxf.location) + if transform_matrix: + pt = transform_matrix.transform(pt) + points.append(pt) + if points: + bbox.extend(points) + + elif e.dxftype() == 'TEXT': + # Vereinfachung: Nur Insert-Point berücksichtigen + insert_point = Vec3(e.dxf.insert) + if transform_matrix: + insert_point = transform_matrix.transform(insert_point) + bbox.extend([insert_point]) + + 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: + bbox.extend(insert_bbox) + + except Exception as e: + print(f"Fehler bei Bounding Box Berechnung für {e.dxftype()}: {e}") + + + return bbox +def extract_scaling(matrix): + sx = math.sqrt(matrix[0, 0]**2 + matrix[0, 1]**2 + matrix[0, 2]**2) + sy = math.sqrt(matrix[1, 0]**2 + matrix[1, 1]**2 + matrix[1, 2]**2) + return sx, sy, +def get_entity_bounding_box_2(entity, doc,src_doc,filename, transform_matrix=None): + """ + Berechnet die Bounding Box einer einzelnen Entity + Berücksichtigt INSERTs mit ihren Block-Inhalten + """ -def calculate_insert_bounding_box(insert_entity, doc, parent_transform=None): + bbox = BoundingBox() + + + try: + if entity.dxftype() == 'LINE': + start = Vec3(entity.dxf.start) + end = Vec3(entity.dxf.end) + if transform_matrix: + start = transform_matrix.transform(start) + end = transform_matrix.transform(end) + bbox.extend([start, end]) + + elif entity.dxftype() == 'CIRCLE': + center = Vec3(entity.dxf.center) + radius = entity.dxf.radius + if transform_matrix: + center = transform_matrix.transform(center) + # Radius mit durchschnittlicher Skalierung anpassen + x,y =extract_scaling(transform_matrix) + scale_factor = (x+y)/2 + radius *= abs(scale_factor) + + bbox.extend([ + Vec3(center.x - radius, center.y - radius, center.z), + Vec3(center.x + radius, center.y + radius, center.z) + ]) + + elif entity.dxftype() == 'ARC': + # Vereinfachung: Bounding Box des vollständigen Kreises + center = Vec3(entity.dxf.center) + radius = entity.dxf.radius + if transform_matrix: + center = transform_matrix.transform(center) + x,y =extract_scaling(transform_matrix) + scale_factor = (x+y)/2 + radius *= abs(scale_factor) + + bbox.extend([ + Vec3(center.x - radius, center.y - radius, center.z), + Vec3(center.x + radius, center.y + radius, center.z) + ]) + + elif entity.dxftype() == 'LWPOLYLINE': + points = [] + for point in entity.get_points(): + pt = Vec3(point[0], point[1], 0) + if transform_matrix: + pt = transform_matrix.transform(pt) + points.append(pt) + if points: + bbox.extend(points) + + elif entity.dxftype() == 'POLYLINE': + points = [] + for vertex in entity.vertices: + pt = Vec3(vertex.dxf.location) + if transform_matrix: + pt = transform_matrix.transform(pt) + points.append(pt) + if points: + bbox.extend(points) + + elif entity.dxftype() == 'TEXT': + # Vereinfachung: Nur Insert-Point berücksichtigen + insert_point = Vec3(entity.dxf.insert) + if transform_matrix: + insert_point = transform_matrix.transform(insert_point) + bbox.extend([insert_point]) + + elif entity.dxftype() == 'INSERT': + # INSERT: Block-Inhalt mit Transformation berücksichtigen + insert_bbox = calculate_insert_bounding_box(entity, doc,src_doc,filename, transform_matrix) + if insert_bbox and insert_bbox.has_data: + bbox.extend(insert_bbox) + + except Exception as e: + print(f"Fehler bei Bounding Box Berechnung für {entity.dxftype()}: {e},{filename}") + + return bbox, +def calculate_insert_bounding_box(insert_entity, doc,src_doc,filename,parent_transform=None): """ Berechnet die Bounding Box eines INSERTs inklusive Block-Inhalt """ + try: + if filename == "0_BG071090_834372404.dxf": + filetest = 3 # Block-Definition finden block_name = insert_entity.dxf.name - if block_name not in doc.blocks: - print(f"Warnung: Block '{block_name}' nicht gefunden") + src_blk = src_doc.blocks[block_name] + + if block_name in doc.blocks: return BoundingBox() - - block_def = doc.blocks[block_name] + else: + dst_blk = doc.blocks.new(name=block_name) + + if block_name not in src_doc.blocks: + print(f"Warnung: Block '{block_name}' ") + return BoundingBox() + block_def = src_blk + # Transformation der INSERT-Entity berechnen insert_transform = get_insert_transform_matrix(insert_entity) @@ -626,14 +734,15 @@ def calculate_insert_bounding_box(insert_entity, doc, parent_transform=None): block_bbox = BoundingBox() for block_entity in block_def: - entity_bbox = get_entity_bounding_box(block_entity, doc, combined_transform) - if entity_bbox and entity_bbox.has_data: - block_bbox.extend(entity_bbox) - + if block_entity is not "ATTDEF": + entity_bbox,= get_entity_bounding_box_2(block_entity, doc,src_doc,filename, combined_transform) + if entity_bbox and entity_bbox.has_data: + dst_blk.add_entity(block_entity.copy()) + block_bbox.extend(entity_bbox) return block_bbox except Exception as e: - print(f"Fehler bei INSERT Bounding Box: {e}") + print(f"Fehler bei INSERT Bounding Box: {e},{filename}") return BoundingBox()