Erzeuge per Programm ein Koordinatensystem in einem Block und benennen ihn nach Wahl. Testfunktion zur Erzeugung und zum wiederauslesen impl.
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
@echo off
|
||||||
|
REM ================================================================
|
||||||
|
REM Setzt Einfuegepunkte fuer Omniflo DXF-Dateien
|
||||||
|
REM ================================================================
|
||||||
|
|
||||||
|
call "%~dp0setenv.bat"
|
||||||
|
|
||||||
|
python "%DXFM_LIB%\set_koords.py" %*
|
||||||
+128
-6
@@ -79,18 +79,140 @@ def insert_ks(msp, name, point, rx=0, ry=0, rz=0):
|
|||||||
return insert
|
return insert
|
||||||
|
|
||||||
|
|
||||||
|
def read_ks(doc, name):
|
||||||
|
"""
|
||||||
|
Liest ein Koordinatensystem aus einer DXF-Datei zurueck.
|
||||||
|
|
||||||
|
Bestimmt Position und Rotationswinkel (rx, ry, rz) aus den
|
||||||
|
tatsaechlichen Linienendpunkten des aufgeloesten INSERT-Blocks.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
doc: ezdxf DXF-Dokument.
|
||||||
|
name: Block-Name (z.B. "K1").
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict mit 'name', 'point', 'rx', 'ry', 'rz' oder None.
|
||||||
|
"""
|
||||||
|
msp = doc.modelspace()
|
||||||
|
for entity in msp:
|
||||||
|
if entity.dxftype() == "INSERT" and entity.dxf.name == name:
|
||||||
|
# Linien aus Block-Referenz aufloesen (virtuelle Entities)
|
||||||
|
lines = [e for e in entity.virtual_entities() if e.dxftype() == "LINE"]
|
||||||
|
if len(lines) != 3:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Gemeinsamer Startpunkt = Einfuegepunkt
|
||||||
|
point = (lines[0].dxf.start[0], lines[0].dxf.start[1], lines[0].dxf.start[2])
|
||||||
|
|
||||||
|
# Richtungsvektoren aus den Endpunkten extrahieren
|
||||||
|
axes = {}
|
||||||
|
for line in lines:
|
||||||
|
end = line.dxf.end
|
||||||
|
dx = end[0] - point[0]
|
||||||
|
dy = end[1] - point[1]
|
||||||
|
dz = end[2] - point[2]
|
||||||
|
length = (dx**2 + dy**2 + dz**2) ** 0.5
|
||||||
|
axes[line.dxf.color] = (dx / length, dy / length, dz / length)
|
||||||
|
|
||||||
|
# X-Achse (color=1), Y-Achse (color=3), Z-Achse (color=5)
|
||||||
|
x_axis = axes.get(1, (1, 0, 0))
|
||||||
|
y_axis = axes.get(3, (0, 1, 0))
|
||||||
|
z_axis = axes.get(5, (0, 0, 1))
|
||||||
|
|
||||||
|
# Rotationswinkel aus Rotationsmatrix R = Rz * Ry * Rx
|
||||||
|
# Spalten von R: x_axis, y_axis, z_axis
|
||||||
|
# R20 = -sin(ry) = x_axis[2]
|
||||||
|
# R21 = cos(ry)*sin(rx) = y_axis[2]
|
||||||
|
# R22 = cos(ry)*cos(rx) = z_axis[2]
|
||||||
|
# R10 = sin(rz)*cos(ry) = x_axis[1]
|
||||||
|
# R00 = cos(rz)*cos(ry) = x_axis[0]
|
||||||
|
ry = math.asin(max(-1, min(1, -x_axis[2])))
|
||||||
|
cos_ry = math.cos(ry)
|
||||||
|
|
||||||
|
if abs(cos_ry) > 1e-6:
|
||||||
|
rx = math.atan2(y_axis[2] / cos_ry, z_axis[2] / cos_ry)
|
||||||
|
rz = math.atan2(x_axis[1] / cos_ry, x_axis[0] / cos_ry)
|
||||||
|
else:
|
||||||
|
# Gimbal Lock: ry = +/-90, rx und rz nicht unabhaengig
|
||||||
|
rz = 0
|
||||||
|
rx = math.atan2(-z_axis[0], y_axis[0])
|
||||||
|
|
||||||
|
return {
|
||||||
|
"name": name,
|
||||||
|
"point": point,
|
||||||
|
"rx": math.degrees(rx),
|
||||||
|
"ry": math.degrees(ry),
|
||||||
|
"rz": math.degrees(rz),
|
||||||
|
}
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def verify_ks(dxf_path, expected):
|
||||||
|
"""
|
||||||
|
Liest KS-Bloecke aus einer DXF-Datei und vergleicht mit Erwartungswerten.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
dxf_path: Pfad zur DXF-Datei.
|
||||||
|
expected: Liste von Dicts mit 'name', 'point', 'rx', 'ry', 'rz'.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True wenn alle Werte uebereinstimmen (Toleranz 0.01).
|
||||||
|
"""
|
||||||
|
doc = ezdxf.readfile(dxf_path)
|
||||||
|
all_ok = True
|
||||||
|
tol = 0.01
|
||||||
|
|
||||||
|
for exp in expected:
|
||||||
|
result = read_ks(doc, exp["name"])
|
||||||
|
if result is None:
|
||||||
|
print(f"FEHLER: Block '{exp['name']}' nicht gefunden")
|
||||||
|
all_ok = False
|
||||||
|
continue
|
||||||
|
|
||||||
|
errors = []
|
||||||
|
for i, axis in enumerate(("x", "y", "z")):
|
||||||
|
if abs(result["point"][i] - exp["point"][i]) > tol:
|
||||||
|
errors.append(f"{axis}={result['point'][i]:.3f} (erwartet {exp['point'][i]:.3f})")
|
||||||
|
|
||||||
|
for angle in ("rx", "ry", "rz"):
|
||||||
|
diff = abs(result[angle] - exp[angle])
|
||||||
|
if diff > 360 - tol:
|
||||||
|
diff = abs(diff - 360)
|
||||||
|
if diff > tol:
|
||||||
|
errors.append(f"{angle}={result[angle]:.2f} (erwartet {exp[angle]:.2f})")
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
print(f"FEHLER {exp['name']}: {', '.join(errors)}")
|
||||||
|
all_ok = False
|
||||||
|
else:
|
||||||
|
print(f"OK {exp['name']}: point=({result['point'][0]:.2f},{result['point'][1]:.2f},{result['point'][2]:.2f}) "
|
||||||
|
f"rx={result['rx']:.2f} ry={result['ry']:.2f} rz={result['rz']:.2f}")
|
||||||
|
|
||||||
|
return all_ok
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
import os
|
||||||
|
|
||||||
doc = ezdxf.new(dxfversion="R2010")
|
doc = ezdxf.new(dxfversion="R2010")
|
||||||
msp = doc.modelspace()
|
msp = doc.modelspace()
|
||||||
|
|
||||||
insert_ks(msp, "K1", (0, 0, 0))
|
test_cases = [
|
||||||
insert_ks(msp, "K2", (10, 0, 0), rz=90)
|
{"name": "K1", "point": (0, 0, 0), "rx": 0, "ry": 0, "rz": 0},
|
||||||
insert_ks(msp, "K3", (20, 0, 0), ry=45)
|
{"name": "K2", "point": (10, 0, 0), "rx": 0, "ry": 0, "rz": 90},
|
||||||
insert_ks(msp, "K4", (30, 0, 0), rx=30, ry=45, rz=60)
|
{"name": "K3", "point": (20, 0, 0), "rx": 0, "ry": 45, "rz": 0},
|
||||||
|
{"name": "K4", "point": (30, 0, 0), "rx": 30, "ry": 45, "rz": 60},
|
||||||
|
]
|
||||||
|
|
||||||
|
for tc in test_cases:
|
||||||
|
insert_ks(msp, tc["name"], tc["point"], tc["rx"], tc["ry"], tc["rz"])
|
||||||
|
|
||||||
import os
|
|
||||||
results_dir = os.environ.get("DXFM_RESULTS", "results")
|
results_dir = os.environ.get("DXFM_RESULTS", "results")
|
||||||
os.makedirs(results_dir, exist_ok=True)
|
os.makedirs(results_dir, exist_ok=True)
|
||||||
out_path = os.path.join(results_dir, "ks_test.dxf")
|
out_path = os.path.join(results_dir, "ks_test.dxf")
|
||||||
doc.saveas(out_path)
|
doc.saveas(out_path)
|
||||||
print(f"Testdatei gespeichert: {out_path}")
|
print(f"Testdatei gespeichert: {out_path}\n")
|
||||||
|
|
||||||
|
print("Verifikation:")
|
||||||
|
ok = verify_ks(out_path, test_cases)
|
||||||
|
print(f"\nErgebnis: {'ALLE OK' if ok else 'FEHLER GEFUNDEN'}")
|
||||||
|
|||||||
Reference in New Issue
Block a user