Inserts richtig in die Bounding box reingetan
This commit is contained in:
+80
-180
@@ -161,6 +161,8 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
||||
max_blockspacing_y = 0
|
||||
|
||||
for filename in os.listdir(input_dir):
|
||||
if filename =='821104043.dxf':
|
||||
test = 2
|
||||
if not filename.lower().endswith(".dxf"):
|
||||
continue
|
||||
|
||||
@@ -213,8 +215,7 @@ 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)
|
||||
boundingbox, ausdehnung, center = calculate_block_bounding_box(filtered_entities, doc,src_doc, filename)
|
||||
if center is None:
|
||||
@@ -238,8 +239,8 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
||||
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)
|
||||
blk.add_entity(cp)
|
||||
add_bounding_box_to_modelspace(blk, boundingbox, centered=True)
|
||||
# Platzierung in Reihen und Spalten
|
||||
# Attribut-Definition (ATTDEF) hinzufügen
|
||||
blk.add_attdef(
|
||||
@@ -518,7 +519,8 @@ def calculate_block_bounding_box(block, doc, src_doc, filename):
|
||||
if entity_bbox and entity_bbox.has_data:
|
||||
bbox.extend(entity_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))
|
||||
|
||||
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,):
|
||||
@@ -527,10 +529,7 @@ def get_entity_bounding_box(e, doc,src_doc,filename, transform_matrix=None,):
|
||||
Berücksichtigt INSERTs mit ihren Block-Inhalten
|
||||
"""
|
||||
|
||||
bbox = BoundingBox()
|
||||
|
||||
|
||||
|
||||
bbox = BoundingBox()
|
||||
try:
|
||||
if e.dxftype() == 'LINE':
|
||||
start = Vec3(e.dxf.start)
|
||||
@@ -538,24 +537,24 @@ def get_entity_bounding_box(e, doc,src_doc,filename, transform_matrix=None,):
|
||||
if transform_matrix:
|
||||
start = transform_matrix.transform(start)
|
||||
end = transform_matrix.transform(end)
|
||||
bbox.extend([start, end])
|
||||
bbox.extend([start])
|
||||
bbox.extend([end])
|
||||
|
||||
elif e.dxftype() == 'CIRCLE':
|
||||
# Kreis durch Punktabtastung (robust bei Transformationen)
|
||||
center = Vec3(e.dxf.center)
|
||||
radius = float(e.dxf.radius)
|
||||
num = 72
|
||||
sampled = []
|
||||
for i in range(num):
|
||||
ang = 2 * math.pi * (i / num)
|
||||
angles = (0.0, math.pi / 2, math.pi, 3 * math.pi / 2)
|
||||
points = []
|
||||
for ang in angles:
|
||||
px = center.x + radius * math.cos(ang)
|
||||
py = center.y + radius * math.sin(ang)
|
||||
p = Vec3(px, py, center.z)
|
||||
if transform_matrix:
|
||||
p = transform_matrix.transform(p)
|
||||
sampled.append(p)
|
||||
if sampled:
|
||||
bbox.extend(sampled)
|
||||
points.append(p)
|
||||
if points:
|
||||
bbox.extend(points)
|
||||
|
||||
elif e.dxftype() == 'ARC':
|
||||
# Bogen durch Punktabtastung zwischen Start- und Endwinkel
|
||||
@@ -565,34 +564,28 @@ def get_entity_bounding_box(e, doc,src_doc,filename, transform_matrix=None,):
|
||||
end_deg = float(e.dxf.end_angle)
|
||||
start = math.radians(start_deg % 360)
|
||||
end = math.radians(end_deg % 360)
|
||||
# Schritte abhängig vom Sweep
|
||||
def sweep_steps(s, e_):
|
||||
|
||||
def in_sweep(a: float, s: float, e_: float) -> bool:
|
||||
# CCW sweep von s nach e_ mit Wrap-Handling
|
||||
if e_ >= s:
|
||||
span = e_ - s
|
||||
else:
|
||||
span = (2 * math.pi - s) + e_
|
||||
return max(12, int(72 * span / (2 * math.pi)))
|
||||
steps = sweep_steps(start, end)
|
||||
sampled = []
|
||||
# CCW Sweeping
|
||||
if end >= start:
|
||||
angles = [start + (end - start) * (i / steps) for i in range(steps + 1)]
|
||||
else:
|
||||
angles = []
|
||||
span1 = 2 * math.pi - start
|
||||
for i in range(int(steps * span1 / (2 * math.pi)) + 1):
|
||||
angles.append(start + span1 * (i / max(1, int(steps * span1 / (2 * math.pi)))))
|
||||
for i in range(1, steps - len(angles) + 2):
|
||||
angles.append(0.0 + end * (i / (steps - len(angles) + 1)))
|
||||
return s <= a <= e_
|
||||
return a >= s or a <= e_
|
||||
|
||||
angles = [start, end]
|
||||
for ang in (0.0, math.pi / 2, math.pi, 3 * math.pi / 2):
|
||||
if in_sweep(ang, start, end):
|
||||
angles.append(ang)
|
||||
|
||||
points = []
|
||||
for ang in angles:
|
||||
px = center.x + radius * math.cos(ang)
|
||||
py = center.y + radius * math.sin(ang)
|
||||
p = Vec3(px, py, center.z)
|
||||
if transform_matrix:
|
||||
p = transform_matrix.transform(p)
|
||||
sampled.append(p)
|
||||
if sampled:
|
||||
bbox.extend(sampled)
|
||||
points.append(p)
|
||||
if points:
|
||||
bbox.extend(points)
|
||||
|
||||
elif e.dxftype() == 'LWPOLYLINE':
|
||||
# Nutze virtuelle Entities (Linien/Bögen), inkl. Bulge-Unterstützung
|
||||
@@ -653,142 +646,30 @@ 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
|
||||
"""
|
||||
|
||||
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 = float(entity.dxf.radius)
|
||||
num = 72
|
||||
sampled = []
|
||||
for i in range(num):
|
||||
ang = 2 * math.pi * (i / num)
|
||||
px = center.x + radius * math.cos(ang)
|
||||
py = center.y + radius * math.sin(ang)
|
||||
p = Vec3(px, py, center.z)
|
||||
if transform_matrix:
|
||||
p = transform_matrix.transform(p)
|
||||
sampled.append(p)
|
||||
if sampled:
|
||||
bbox.extend(sampled)
|
||||
|
||||
elif entity.dxftype() == 'ARC':
|
||||
center = Vec3(entity.dxf.center)
|
||||
radius = float(entity.dxf.radius)
|
||||
start_deg = float(entity.dxf.start_angle)
|
||||
end_deg = float(entity.dxf.end_angle)
|
||||
start = math.radians(start_deg % 360)
|
||||
end = math.radians(end_deg % 360)
|
||||
def sweep_steps(s, e_):
|
||||
if e_ >= s:
|
||||
span = e_ - s
|
||||
else:
|
||||
span = (2 * math.pi - s) + e_
|
||||
return max(12, int(72 * span / (2 * math.pi)))
|
||||
steps = sweep_steps(start, end)
|
||||
sampled = []
|
||||
if end >= start:
|
||||
angles = [start + (end - start) * (i / steps) for i in range(steps + 1)]
|
||||
else:
|
||||
angles = []
|
||||
span1 = 2 * math.pi - start
|
||||
for i in range(int(steps * span1 / (2 * math.pi)) + 1):
|
||||
angles.append(start + span1 * (i / max(1, int(steps * span1 / (2 * math.pi)))))
|
||||
for i in range(1, steps - len(angles) + 2):
|
||||
angles.append(0.0 + end * (i / (steps - len(angles) + 1)))
|
||||
for ang in angles:
|
||||
px = center.x + radius * math.cos(ang)
|
||||
py = center.y + radius * math.sin(ang)
|
||||
p = Vec3(px, py, center.z)
|
||||
if transform_matrix:
|
||||
p = transform_matrix.transform(p)
|
||||
sampled.append(p)
|
||||
if sampled:
|
||||
bbox.extend(sampled)
|
||||
|
||||
elif entity.dxftype() == 'LWPOLYLINE':
|
||||
for ve in entity.virtual_entities():
|
||||
ve_bbox = get_entity_bounding_box_2(ve, doc, src_doc, filename, transform_matrix)[0]
|
||||
if ve_bbox and ve_bbox.has_data:
|
||||
bbox.extend(ve_bbox)
|
||||
|
||||
elif entity.dxftype() == 'POLYLINE':
|
||||
for ve in entity.virtual_entities():
|
||||
ve_bbox = get_entity_bounding_box_2(ve, doc, src_doc, filename, transform_matrix)[0]
|
||||
if ve_bbox and ve_bbox.has_data:
|
||||
bbox.extend(ve_bbox)
|
||||
|
||||
elif entity.dxftype() == 'SPLINE':
|
||||
try:
|
||||
pts = list(entity.approximate(60))
|
||||
except Exception:
|
||||
try:
|
||||
pts = list(entity.flattening(1.0))
|
||||
except Exception:
|
||||
pts = []
|
||||
sampled = []
|
||||
for pt in pts:
|
||||
try:
|
||||
vx, vy = pt.x, pt.y
|
||||
except Exception:
|
||||
vx, vy = pt[0], pt[1]
|
||||
v = Vec3(vx, vy, 0)
|
||||
if transform_matrix:
|
||||
v = transform_matrix.transform(v)
|
||||
sampled.append(v)
|
||||
if sampled:
|
||||
bbox.extend(sampled)
|
||||
|
||||
elif entity.dxftype() == 'TEXT':
|
||||
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_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-Definition finden
|
||||
block_name = insert_entity.dxf.name
|
||||
src_blk = src_doc.blocks[block_name]
|
||||
|
||||
if block_name == "ccLab_2025312125317867_51":
|
||||
print(filename)
|
||||
if block_name in doc.blocks:
|
||||
return BoundingBox()
|
||||
dst_blk = doc.blocks[block_name]
|
||||
|
||||
new_insert = False
|
||||
|
||||
else:
|
||||
dst_blk = doc.blocks.new(name=block_name)
|
||||
|
||||
new_insert = True
|
||||
if block_name not in src_doc.blocks:
|
||||
print(f"Warnung: Block '{block_name}' ")
|
||||
return BoundingBox()
|
||||
|
||||
block_def = src_blk
|
||||
|
||||
|
||||
@@ -806,10 +687,12 @@ 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_2(block_entity, doc,src_doc,filename, combined_transform)
|
||||
entity_bbox= get_entity_bounding_box(block_entity, doc,src_doc,filename, combined_transform)
|
||||
if entity_bbox and entity_bbox.has_data:
|
||||
dst_blk.add_entity(block_entity.copy())
|
||||
if new_insert:
|
||||
dst_blk.add_entity(block_entity.copy())
|
||||
block_bbox.extend(entity_bbox)
|
||||
|
||||
return block_bbox
|
||||
|
||||
except Exception as e:
|
||||
@@ -855,9 +738,11 @@ def copy_entity_to_block(entity, target_block):
|
||||
print(f"Fehler beim Kopieren von {entity.dxftype()}: {e}")
|
||||
|
||||
|
||||
def add_bounding_box_to_modelspace(msp, bbox):
|
||||
def add_bounding_box_to_modelspace(msp, bbox, centered=False):
|
||||
"""
|
||||
Fügt die Bounding Box als Hilfslinien zum Modelspace hinzu
|
||||
Fügt die Bounding Box als Hilfslinien zum Modelspace hinzu.
|
||||
Wenn centered=True, wird das Rechteck um den Ursprung (0,0) zentriert und
|
||||
ein roter Punkt in die Mitte gesetzt.
|
||||
"""
|
||||
if not bbox.has_data:
|
||||
return
|
||||
@@ -865,32 +750,47 @@ def add_bounding_box_to_modelspace(msp, bbox):
|
||||
# Bounding Box Rechteck zeichnen
|
||||
min_pt = bbox.extmin
|
||||
max_pt = bbox.extmax
|
||||
width = max_pt.x - min_pt.x
|
||||
height = max_pt.y - min_pt.y
|
||||
|
||||
# Rechteck als LWPOLYLINE
|
||||
bbox_points = [
|
||||
(min_pt.x, min_pt.y),
|
||||
(max_pt.x, min_pt.y),
|
||||
(max_pt.x, max_pt.y),
|
||||
(min_pt.x, max_pt.y),
|
||||
(min_pt.x, min_pt.y)
|
||||
]
|
||||
if centered:
|
||||
# Rechteck um (0,0) zentriert
|
||||
left = -width / 2.0
|
||||
right = width / 2.0
|
||||
bottom = -height / 2.0
|
||||
top = height / 2.0
|
||||
bbox_points = [
|
||||
(left, bottom),
|
||||
(right, bottom),
|
||||
(right, top),
|
||||
(left, top),
|
||||
(left, bottom)
|
||||
]
|
||||
# Roter Punkt in der Mitte
|
||||
msp.add_circle(center=(0.0, 0.0), radius=max(0.5, min(width, height) * 0.01),
|
||||
dxfattribs={"layer": "BOUNDING_BOX", "color": 1})
|
||||
else:
|
||||
# Ursprüngliche, nicht-zentrierte Bounding Box
|
||||
bbox_points = [
|
||||
(min_pt.x, min_pt.y),
|
||||
(max_pt.x, min_pt.y),
|
||||
(max_pt.x, max_pt.y),
|
||||
(min_pt.x, max_pt.y),
|
||||
(min_pt.x, min_pt.y)
|
||||
]
|
||||
|
||||
bbox_poly = msp.add_lwpolyline(bbox_points)
|
||||
bbox_poly.dxf.layer = "BOUNDING_BOX"
|
||||
bbox_poly.dxf.color = 1 # Rot
|
||||
|
||||
# Bemaßungen hinzufügen
|
||||
width = max_pt.x - min_pt.x
|
||||
height = max_pt.y - min_pt.y
|
||||
|
||||
# Text mit Abmessungen
|
||||
text_pos = Vec3(min_pt.x, max_pt.y + 5, 0)
|
||||
msp.add_text(f"Breite: {width:.2f} mm", height=3,
|
||||
dxfattribs={'insert': text_pos, 'layer': "BOUNDING_BOX", 'color': 1})
|
||||
text_pos = Vec3(bbox_points[0][0], (bbox_points[2][1] if centered else max_pt.y) + 5, 0)
|
||||
msp.add_text(f"Breite: {width:.2f} mm", height=3,
|
||||
dxfattribs={'insert': text_pos, 'layer': "BOUNDING_BOX", 'color': 1})
|
||||
|
||||
text_pos2 = Vec3(min_pt.x, max_pt.y + 10, 0)
|
||||
text_pos2 = Vec3(bbox_points[0][0], (bbox_points[2][1] if centered else max_pt.y) + 10, 0)
|
||||
msp.add_text(f"Höhe: {height:.2f} mm", height=3,
|
||||
dxfattribs={'insert': text_pos2, 'layer': "BOUNDING_BOX", 'color': 1})
|
||||
dxfattribs={'insert': text_pos2, 'layer': "BOUNDING_BOX", 'color': 1})
|
||||
|
||||
|
||||
def format_bounding_box(bbox):
|
||||
|
||||
Reference in New Issue
Block a user