Man kann jetzt bestimmte dxf.layer durch den cofig aus der boundingbox berechnung für die Mitte auschließen
This commit is contained in:
@@ -31,3 +31,5 @@ block_spacing_x = 350
|
|||||||
blocks_per_row = 20
|
blocks_per_row = 20
|
||||||
# Vertikaler Abstand zwischen Zeilen im Raster (in DXF-Einheiten)
|
# Vertikaler Abstand zwischen Zeilen im Raster (in DXF-Einheiten)
|
||||||
block_spacing_y = 500
|
block_spacing_y = 500
|
||||||
|
# Nicht in die MittelPunkt Berechnung erlaubt
|
||||||
|
not_allowed_in_center = ("A-GRUPPE","B-GRUPPE")
|
||||||
+9
-151
@@ -10,123 +10,6 @@ from utils import check_environment_var, setup_logger
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import logging
|
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):
|
def create_block_library(input_dir, output_file, config, logger=None):
|
||||||
"""
|
"""
|
||||||
Erstellt eine DXF-Block-Bibliothek aus einzelnen DXF-Dateien.
|
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:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
boundingbox, ausdehnung, center = calculate_block_bounding_box(filtered_entities, doc,src_doc, filename,config)
|
||||||
# center, ausdehnung = get_bbox(entities)
|
|
||||||
boundingbox, ausdehnung, center = calculate_block_bounding_box(filtered_entities, doc,src_doc, filename)
|
|
||||||
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:
|
||||||
@@ -231,11 +112,7 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
|||||||
doc.blocks.delete_block(name)
|
doc.blocks.delete_block(name)
|
||||||
|
|
||||||
blk = doc.blocks.new(name=name, base_point=(0,0))
|
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:
|
for e in entities:
|
||||||
cp = copy_entity(logger, error_files, filename, e, center)
|
cp = copy_entity(logger, error_files, filename, e, center)
|
||||||
if cp:
|
if cp:
|
||||||
@@ -368,25 +245,6 @@ def copy_entity(logger, error_files, filename, e, center):
|
|||||||
error_files.append((filename, error_msg))
|
error_files.append((filename, error_msg))
|
||||||
return None
|
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)
|
|
||||||
# Basispunkt ü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)
|
# Standardwerte (falls nicht in der Config)
|
||||||
@@ -507,7 +365,7 @@ def copy_block_definitions(source_doc, target_doc):
|
|||||||
return copied_blocks
|
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
|
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()
|
bbox = BoundingBox()
|
||||||
|
|
||||||
for entity in block:
|
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:
|
if entity_bbox and entity_bbox.has_data:
|
||||||
bbox.extend(entity_bbox)
|
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
|
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
|
Berechnet die Bounding Box einer einzelnen Entity
|
||||||
Berücksichtigt INSERTs mit ihren Block-Inhalten
|
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':
|
elif e.dxftype() == 'INSERT':
|
||||||
# INSERT: Block-Inhalt mit Transformation berücksichtigen
|
# INSERT: Block-Inhalt mit Transformation berücksichtigen
|
||||||
insert_bbox = calculate_insert_bounding_box(e, doc,src_doc,filename, transform_matrix)
|
insert_bbox = calculate_insert_bounding_box(e, doc,src_doc,filename,config, transform_matrix)
|
||||||
if insert_bbox and insert_bbox.has_data:
|
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)
|
bbox.extend(insert_bbox)
|
||||||
|
|
||||||
except Exception as e:
|
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)
|
sy = math.sqrt(matrix[1, 0]**2 + matrix[1, 1]**2 + matrix[1, 2]**2)
|
||||||
return sx, sy,
|
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
|
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:
|
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 entity_bbox and entity_bbox.has_data:
|
||||||
if new_insert:
|
if new_insert:
|
||||||
dst_blk.add_entity(block_entity.copy())
|
dst_blk.add_entity(block_entity.copy())
|
||||||
|
|||||||
Reference in New Issue
Block a user