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
|
max_blockspacing_y = 0
|
||||||
|
|
||||||
for filename in os.listdir(input_dir):
|
for filename in os.listdir(input_dir):
|
||||||
|
if filename =='821104043.dxf':
|
||||||
|
test = 2
|
||||||
if not filename.lower().endswith(".dxf"):
|
if not filename.lower().endswith(".dxf"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -213,8 +215,7 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if filename == "0_BG090090_834372101_0_BG090090.dxf":
|
|
||||||
filetest =3
|
|
||||||
# center, ausdehnung = get_bbox(entities)
|
# 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)
|
||||||
if center is None:
|
if center is None:
|
||||||
@@ -238,8 +239,8 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
|||||||
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:
|
||||||
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
|
# Platzierung in Reihen und Spalten
|
||||||
# Attribut-Definition (ATTDEF) hinzufügen
|
# Attribut-Definition (ATTDEF) hinzufügen
|
||||||
blk.add_attdef(
|
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:
|
if entity_bbox and entity_bbox.has_data:
|
||||||
bbox.extend(entity_bbox)
|
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,):
|
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
|
Berücksichtigt INSERTs mit ihren Block-Inhalten
|
||||||
"""
|
"""
|
||||||
|
|
||||||
bbox = BoundingBox()
|
bbox = BoundingBox()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if e.dxftype() == 'LINE':
|
if e.dxftype() == 'LINE':
|
||||||
start = Vec3(e.dxf.start)
|
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:
|
if transform_matrix:
|
||||||
start = transform_matrix.transform(start)
|
start = transform_matrix.transform(start)
|
||||||
end = transform_matrix.transform(end)
|
end = transform_matrix.transform(end)
|
||||||
bbox.extend([start, end])
|
bbox.extend([start])
|
||||||
|
bbox.extend([end])
|
||||||
|
|
||||||
elif e.dxftype() == 'CIRCLE':
|
elif e.dxftype() == 'CIRCLE':
|
||||||
# Kreis durch Punktabtastung (robust bei Transformationen)
|
# Kreis durch Punktabtastung (robust bei Transformationen)
|
||||||
center = Vec3(e.dxf.center)
|
center = Vec3(e.dxf.center)
|
||||||
radius = float(e.dxf.radius)
|
radius = float(e.dxf.radius)
|
||||||
num = 72
|
angles = (0.0, math.pi / 2, math.pi, 3 * math.pi / 2)
|
||||||
sampled = []
|
points = []
|
||||||
for i in range(num):
|
for ang in angles:
|
||||||
ang = 2 * math.pi * (i / num)
|
|
||||||
px = center.x + radius * math.cos(ang)
|
px = center.x + radius * math.cos(ang)
|
||||||
py = center.y + radius * math.sin(ang)
|
py = center.y + radius * math.sin(ang)
|
||||||
p = Vec3(px, py, center.z)
|
p = Vec3(px, py, center.z)
|
||||||
if transform_matrix:
|
if transform_matrix:
|
||||||
p = transform_matrix.transform(p)
|
p = transform_matrix.transform(p)
|
||||||
sampled.append(p)
|
points.append(p)
|
||||||
if sampled:
|
if points:
|
||||||
bbox.extend(sampled)
|
bbox.extend(points)
|
||||||
|
|
||||||
elif e.dxftype() == 'ARC':
|
elif e.dxftype() == 'ARC':
|
||||||
# Bogen durch Punktabtastung zwischen Start- und Endwinkel
|
# 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)
|
end_deg = float(e.dxf.end_angle)
|
||||||
start = math.radians(start_deg % 360)
|
start = math.radians(start_deg % 360)
|
||||||
end = math.radians(end_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:
|
if e_ >= s:
|
||||||
span = e_ - s
|
return s <= a <= e_
|
||||||
else:
|
return a >= s or a <= e_
|
||||||
span = (2 * math.pi - s) + e_
|
|
||||||
return max(12, int(72 * span / (2 * math.pi)))
|
angles = [start, end]
|
||||||
steps = sweep_steps(start, end)
|
for ang in (0.0, math.pi / 2, math.pi, 3 * math.pi / 2):
|
||||||
sampled = []
|
if in_sweep(ang, start, end):
|
||||||
# CCW Sweeping
|
angles.append(ang)
|
||||||
if end >= start:
|
|
||||||
angles = [start + (end - start) * (i / steps) for i in range(steps + 1)]
|
points = []
|
||||||
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:
|
for ang in angles:
|
||||||
px = center.x + radius * math.cos(ang)
|
px = center.x + radius * math.cos(ang)
|
||||||
py = center.y + radius * math.sin(ang)
|
py = center.y + radius * math.sin(ang)
|
||||||
p = Vec3(px, py, center.z)
|
p = Vec3(px, py, center.z)
|
||||||
if transform_matrix:
|
if transform_matrix:
|
||||||
p = transform_matrix.transform(p)
|
p = transform_matrix.transform(p)
|
||||||
sampled.append(p)
|
points.append(p)
|
||||||
if sampled:
|
if points:
|
||||||
bbox.extend(sampled)
|
bbox.extend(points)
|
||||||
|
|
||||||
elif e.dxftype() == 'LWPOLYLINE':
|
elif e.dxftype() == 'LWPOLYLINE':
|
||||||
# Nutze virtuelle Entities (Linien/Bögen), inkl. Bulge-Unterstützung
|
# 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)
|
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)
|
sy = math.sqrt(matrix[1, 0]**2 + matrix[1, 1]**2 + matrix[1, 2]**2)
|
||||||
return sx, sy,
|
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):
|
def calculate_insert_bounding_box(insert_entity, doc,src_doc,filename,parent_transform=None):
|
||||||
"""
|
"""
|
||||||
Berechnet die Bounding Box eines INSERTs inklusive Block-Inhalt
|
Berechnet die Bounding Box eines INSERTs inklusive Block-Inhalt
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if filename == "0_BG071090_834372404.dxf":
|
# Block-Definition finden
|
||||||
filetest = 3
|
|
||||||
# Block-Definition finden
|
|
||||||
block_name = insert_entity.dxf.name
|
block_name = insert_entity.dxf.name
|
||||||
src_blk = src_doc.blocks[block_name]
|
src_blk = src_doc.blocks[block_name]
|
||||||
|
if block_name == "ccLab_2025312125317867_51":
|
||||||
|
print(filename)
|
||||||
if block_name in doc.blocks:
|
if block_name in doc.blocks:
|
||||||
return BoundingBox()
|
dst_blk = doc.blocks[block_name]
|
||||||
|
|
||||||
|
new_insert = False
|
||||||
|
|
||||||
else:
|
else:
|
||||||
dst_blk = doc.blocks.new(name=block_name)
|
dst_blk = doc.blocks.new(name=block_name)
|
||||||
|
new_insert = True
|
||||||
if block_name not in src_doc.blocks:
|
if block_name not in src_doc.blocks:
|
||||||
print(f"Warnung: Block '{block_name}' ")
|
print(f"Warnung: Block '{block_name}' ")
|
||||||
return BoundingBox()
|
return BoundingBox()
|
||||||
|
|
||||||
block_def = src_blk
|
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:
|
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:
|
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)
|
block_bbox.extend(entity_bbox)
|
||||||
|
|
||||||
return block_bbox
|
return block_bbox
|
||||||
|
|
||||||
except Exception as e:
|
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}")
|
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:
|
if not bbox.has_data:
|
||||||
return
|
return
|
||||||
@@ -865,32 +750,47 @@ def add_bounding_box_to_modelspace(msp, bbox):
|
|||||||
# Bounding Box Rechteck zeichnen
|
# Bounding Box Rechteck zeichnen
|
||||||
min_pt = bbox.extmin
|
min_pt = bbox.extmin
|
||||||
max_pt = bbox.extmax
|
max_pt = bbox.extmax
|
||||||
|
width = max_pt.x - min_pt.x
|
||||||
|
height = max_pt.y - min_pt.y
|
||||||
|
|
||||||
# Rechteck als LWPOLYLINE
|
if centered:
|
||||||
bbox_points = [
|
# Rechteck um (0,0) zentriert
|
||||||
(min_pt.x, min_pt.y),
|
left = -width / 2.0
|
||||||
(max_pt.x, min_pt.y),
|
right = width / 2.0
|
||||||
(max_pt.x, max_pt.y),
|
bottom = -height / 2.0
|
||||||
(min_pt.x, max_pt.y),
|
top = height / 2.0
|
||||||
(min_pt.x, min_pt.y)
|
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 = msp.add_lwpolyline(bbox_points)
|
||||||
bbox_poly.dxf.layer = "BOUNDING_BOX"
|
bbox_poly.dxf.layer = "BOUNDING_BOX"
|
||||||
bbox_poly.dxf.color = 1 # Rot
|
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 mit Abmessungen
|
||||||
text_pos = Vec3(min_pt.x, max_pt.y + 5, 0)
|
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,
|
msp.add_text(f"Breite: {width:.2f} mm", height=3,
|
||||||
dxfattribs={'insert': text_pos, 'layer': "BOUNDING_BOX", 'color': 1})
|
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,
|
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):
|
def format_bounding_box(bbox):
|
||||||
|
|||||||
Reference in New Issue
Block a user