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])
|
||||
|
||||
elif e.dxftype() == 'CIRCLE':
|
||||
# Kreis durch Punktabtastung (robust bei Transformationen)
|
||||
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)
|
||||
])
|
||||
radius = float(e.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 e.dxftype() == 'ARC':
|
||||
# Vereinfachung: Bounding Box des vollständigen Kreises
|
||||
# Bogen durch Punktabtastung zwischen Start- und Endwinkel
|
||||
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)
|
||||
])
|
||||
radius = 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)
|
||||
# Schritte abhängig vom Sweep
|
||||
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 = []
|
||||
# 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':
|
||||
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)
|
||||
# Nutze virtuelle Entities (Linien/Bögen), inkl. Bulge-Unterstützung
|
||||
for ve in e.virtual_entities():
|
||||
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() == 'POLYLINE':
|
||||
points = []
|
||||
for vertex in e.vertices:
|
||||
pt = Vec3(vertex.dxf.location)
|
||||
# 2D/3D Polylines ebenfalls über virtuelle Entities
|
||||
for ve in e.virtual_entities():
|
||||
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:
|
||||
pt = transform_matrix.transform(pt)
|
||||
points.append(pt)
|
||||
if points:
|
||||
bbox.extend(points)
|
||||
v = transform_matrix.transform(v)
|
||||
sampled.append(v)
|
||||
if sampled:
|
||||
bbox.extend(sampled)
|
||||
|
||||
elif e.dxftype() == 'TEXT':
|
||||
# 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':
|
||||
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)
|
||||
])
|
||||
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':
|
||||
# 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)
|
||||
])
|
||||
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':
|
||||
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)
|
||||
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':
|
||||
points = []
|
||||
for vertex in entity.vertices:
|
||||
pt = Vec3(vertex.dxf.location)
|
||||
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:
|
||||
pt = transform_matrix.transform(pt)
|
||||
points.append(pt)
|
||||
if points:
|
||||
bbox.extend(points)
|
||||
v = transform_matrix.transform(v)
|
||||
sampled.append(v)
|
||||
if sampled:
|
||||
bbox.extend(sampled)
|
||||
|
||||
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)
|
||||
@@ -734,7 +805,7 @@ def calculate_insert_bounding_box(insert_entity, doc,src_doc,filename,parent_tra
|
||||
block_bbox = BoundingBox()
|
||||
|
||||
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)
|
||||
if entity_bbox and entity_bbox.has_data:
|
||||
dst_blk.add_entity(block_entity.copy())
|
||||
|
||||
Reference in New Issue
Block a user