Circle und arch logic bishen verbessert (funktieoniert noch nicht ganz), libary zum testen
This commit is contained in:
+71679
-124071
File diff suppressed because it is too large
Load Diff
+152
-81
@@ -541,54 +541,94 @@ def get_entity_bounding_box(e, doc,src_doc,filename, transform_matrix=None,):
|
|||||||
bbox.extend([start, end])
|
bbox.extend([start, end])
|
||||||
|
|
||||||
elif e.dxftype() == 'CIRCLE':
|
elif e.dxftype() == 'CIRCLE':
|
||||||
|
# Kreis durch Punktabtastung (robust bei Transformationen)
|
||||||
center = Vec3(e.dxf.center)
|
center = Vec3(e.dxf.center)
|
||||||
radius = e.dxf.radius
|
radius = float(e.dxf.radius)
|
||||||
if transform_matrix:
|
num = 72
|
||||||
center = transform_matrix.transform(center)
|
sampled = []
|
||||||
# Radius mit durchschnittlicher Skalierung anpassen
|
for i in range(num):
|
||||||
scale_factor = (transform_matrix.scale_x + transform_matrix.scale_y) / 2
|
ang = 2 * math.pi * (i / num)
|
||||||
radius *= abs(scale_factor)
|
px = center.x + radius * math.cos(ang)
|
||||||
|
py = center.y + radius * math.sin(ang)
|
||||||
bbox.extend([
|
p = Vec3(px, py, center.z)
|
||||||
Vec3(center.x - radius, center.y - radius, center.z),
|
if transform_matrix:
|
||||||
Vec3(center.x + radius, center.y + radius, center.z)
|
p = transform_matrix.transform(p)
|
||||||
])
|
sampled.append(p)
|
||||||
|
if sampled:
|
||||||
|
bbox.extend(sampled)
|
||||||
|
|
||||||
elif e.dxftype() == 'ARC':
|
elif e.dxftype() == 'ARC':
|
||||||
# Vereinfachung: Bounding Box des vollständigen Kreises
|
# Bogen durch Punktabtastung zwischen Start- und Endwinkel
|
||||||
center = Vec3(e.dxf.center)
|
center = Vec3(e.dxf.center)
|
||||||
radius = e.dxf.radius
|
radius = float(e.dxf.radius)
|
||||||
if transform_matrix:
|
start_deg = float(e.dxf.start_angle)
|
||||||
center = transform_matrix.transform(center)
|
end_deg = float(e.dxf.end_angle)
|
||||||
x,y =extract_scaling(transform_matrix)
|
start = math.radians(start_deg % 360)
|
||||||
x,y =extract_scaling(transform_matrix)
|
end = math.radians(end_deg % 360)
|
||||||
scale_factor = (x+y)/2
|
# Schritte abhängig vom Sweep
|
||||||
radius *= abs(scale_factor)
|
def sweep_steps(s, e_):
|
||||||
|
if e_ >= s:
|
||||||
bbox.extend([
|
span = e_ - s
|
||||||
Vec3(center.x - radius, center.y - radius, center.z),
|
else:
|
||||||
Vec3(center.x + radius, center.y + radius, center.z)
|
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)))
|
||||||
|
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 e.dxftype() == 'LWPOLYLINE':
|
elif e.dxftype() == 'LWPOLYLINE':
|
||||||
points = []
|
# Nutze virtuelle Entities (Linien/Bögen), inkl. Bulge-Unterstützung
|
||||||
for point in e.get_points():
|
for ve in e.virtual_entities():
|
||||||
pt = Vec3(point[0], point[1], 0)
|
ve_bbox = get_entity_bounding_box(ve, doc, src_doc, filename, transform_matrix)
|
||||||
if transform_matrix:
|
if ve_bbox and ve_bbox.has_data:
|
||||||
pt = transform_matrix.transform(pt)
|
bbox.extend(ve_bbox)
|
||||||
points.append(pt)
|
|
||||||
if points:
|
|
||||||
bbox.extend(points)
|
|
||||||
|
|
||||||
elif e.dxftype() == 'POLYLINE':
|
elif e.dxftype() == 'POLYLINE':
|
||||||
points = []
|
# 2D/3D Polylines ebenfalls über virtuelle Entities
|
||||||
for vertex in e.vertices:
|
for ve in e.virtual_entities():
|
||||||
pt = Vec3(vertex.dxf.location)
|
ve_bbox = get_entity_bounding_box(ve, doc, src_doc, filename, transform_matrix)
|
||||||
|
if ve_bbox and ve_bbox.has_data:
|
||||||
|
bbox.extend(ve_bbox)
|
||||||
|
|
||||||
|
elif e.dxftype() == 'SPLINE':
|
||||||
|
# Approximation der Spline-Kurve
|
||||||
|
try:
|
||||||
|
pts = list(e.approximate(60))
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
pts = list(e.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:
|
if transform_matrix:
|
||||||
pt = transform_matrix.transform(pt)
|
v = transform_matrix.transform(v)
|
||||||
points.append(pt)
|
sampled.append(v)
|
||||||
if points:
|
if sampled:
|
||||||
bbox.extend(points)
|
bbox.extend(sampled)
|
||||||
|
|
||||||
elif e.dxftype() == 'TEXT':
|
elif e.dxftype() == 'TEXT':
|
||||||
# Vereinfachung: Nur Insert-Point berücksichtigen
|
# Vereinfachung: Nur Insert-Point berücksichtigen
|
||||||
@@ -633,63 +673,94 @@ def get_entity_bounding_box_2(entity, doc,src_doc,filename, transform_matrix=Non
|
|||||||
|
|
||||||
elif entity.dxftype() == 'CIRCLE':
|
elif entity.dxftype() == 'CIRCLE':
|
||||||
center = Vec3(entity.dxf.center)
|
center = Vec3(entity.dxf.center)
|
||||||
radius = entity.dxf.radius
|
radius = float(entity.dxf.radius)
|
||||||
if transform_matrix:
|
num = 72
|
||||||
center = transform_matrix.transform(center)
|
sampled = []
|
||||||
# Radius mit durchschnittlicher Skalierung anpassen
|
for i in range(num):
|
||||||
x,y =extract_scaling(transform_matrix)
|
ang = 2 * math.pi * (i / num)
|
||||||
scale_factor = (x+y)/2
|
px = center.x + radius * math.cos(ang)
|
||||||
radius *= abs(scale_factor)
|
py = center.y + radius * math.sin(ang)
|
||||||
|
p = Vec3(px, py, center.z)
|
||||||
bbox.extend([
|
if transform_matrix:
|
||||||
Vec3(center.x - radius, center.y - radius, center.z),
|
p = transform_matrix.transform(p)
|
||||||
Vec3(center.x + radius, center.y + radius, center.z)
|
sampled.append(p)
|
||||||
])
|
if sampled:
|
||||||
|
bbox.extend(sampled)
|
||||||
|
|
||||||
elif entity.dxftype() == 'ARC':
|
elif entity.dxftype() == 'ARC':
|
||||||
# Vereinfachung: Bounding Box des vollständigen Kreises
|
|
||||||
center = Vec3(entity.dxf.center)
|
center = Vec3(entity.dxf.center)
|
||||||
radius = entity.dxf.radius
|
radius = float(entity.dxf.radius)
|
||||||
if transform_matrix:
|
start_deg = float(entity.dxf.start_angle)
|
||||||
center = transform_matrix.transform(center)
|
end_deg = float(entity.dxf.end_angle)
|
||||||
x,y =extract_scaling(transform_matrix)
|
start = math.radians(start_deg % 360)
|
||||||
scale_factor = (x+y)/2
|
end = math.radians(end_deg % 360)
|
||||||
radius *= abs(scale_factor)
|
def sweep_steps(s, e_):
|
||||||
|
if e_ >= s:
|
||||||
bbox.extend([
|
span = e_ - s
|
||||||
Vec3(center.x - radius, center.y - radius, center.z),
|
else:
|
||||||
Vec3(center.x + radius, center.y + radius, center.z)
|
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':
|
elif entity.dxftype() == 'LWPOLYLINE':
|
||||||
points = []
|
for ve in entity.virtual_entities():
|
||||||
for point in entity.get_points():
|
ve_bbox = get_entity_bounding_box_2(ve, doc, src_doc, filename, transform_matrix)[0]
|
||||||
pt = Vec3(point[0], point[1], 0)
|
if ve_bbox and ve_bbox.has_data:
|
||||||
if transform_matrix:
|
bbox.extend(ve_bbox)
|
||||||
pt = transform_matrix.transform(pt)
|
|
||||||
points.append(pt)
|
|
||||||
if points:
|
|
||||||
bbox.extend(points)
|
|
||||||
|
|
||||||
elif entity.dxftype() == 'POLYLINE':
|
elif entity.dxftype() == 'POLYLINE':
|
||||||
points = []
|
for ve in entity.virtual_entities():
|
||||||
for vertex in entity.vertices:
|
ve_bbox = get_entity_bounding_box_2(ve, doc, src_doc, filename, transform_matrix)[0]
|
||||||
pt = Vec3(vertex.dxf.location)
|
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:
|
if transform_matrix:
|
||||||
pt = transform_matrix.transform(pt)
|
v = transform_matrix.transform(v)
|
||||||
points.append(pt)
|
sampled.append(v)
|
||||||
if points:
|
if sampled:
|
||||||
bbox.extend(points)
|
bbox.extend(sampled)
|
||||||
|
|
||||||
elif entity.dxftype() == 'TEXT':
|
elif entity.dxftype() == 'TEXT':
|
||||||
# Vereinfachung: Nur Insert-Point berücksichtigen
|
|
||||||
insert_point = Vec3(entity.dxf.insert)
|
insert_point = Vec3(entity.dxf.insert)
|
||||||
if transform_matrix:
|
if transform_matrix:
|
||||||
insert_point = transform_matrix.transform(insert_point)
|
insert_point = transform_matrix.transform(insert_point)
|
||||||
bbox.extend([insert_point])
|
bbox.extend([insert_point])
|
||||||
|
|
||||||
elif entity.dxftype() == 'INSERT':
|
elif entity.dxftype() == 'INSERT':
|
||||||
# INSERT: Block-Inhalt mit Transformation berücksichtigen
|
|
||||||
insert_bbox = calculate_insert_bounding_box(entity, doc,src_doc,filename, transform_matrix)
|
insert_bbox = calculate_insert_bounding_box(entity, doc,src_doc,filename, transform_matrix)
|
||||||
if insert_bbox and insert_bbox.has_data:
|
if insert_bbox and insert_bbox.has_data:
|
||||||
bbox.extend(insert_bbox)
|
bbox.extend(insert_bbox)
|
||||||
@@ -734,7 +805,7 @@ def calculate_insert_bounding_box(insert_entity, doc,src_doc,filename,parent_tra
|
|||||||
block_bbox = BoundingBox()
|
block_bbox = BoundingBox()
|
||||||
|
|
||||||
for block_entity in block_def:
|
for block_entity in block_def:
|
||||||
if block_entity is not "ATTDEF":
|
|
||||||
entity_bbox,= get_entity_bounding_box_2(block_entity, doc,src_doc,filename, combined_transform)
|
entity_bbox,= get_entity_bounding_box_2(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())
|
dst_blk.add_entity(block_entity.copy())
|
||||||
|
|||||||
Reference in New Issue
Block a user