K2 für die Bögen werden jetzt richtig gesetzt

This commit is contained in:
2026-05-13 12:08:48 +02:00
parent 854b5e3bd5
commit bf8b7756ea
4 changed files with 280 additions and 62 deletions
+1 -10
View File
@@ -4,7 +4,7 @@ REM ================================================================
REM TEST - Umgebungsvariablen Setup
REM ================================================================
echo Setting up environment variables for TEST ...
echo Setting up environment variables for DXFMAKROS ...
REM Basis-Projektpfad (aktueller Ordner)
set "DXFMAKRO=%~dp0.."
@@ -44,16 +44,7 @@ if not exist "%DXFM_RESULTS%" mkdir "%DXFM_RESULTS%"
REM Umgebungsvariablen anzeigen
echo.
echo ================================================================
echo TEST ENVIRONMENT SETUP COMPLETE
echo ================================================================
echo DXFMAKRO = %DXFMAKRO%
echo DXFM_BIN = %DXFM_BIN%
echo DXFM_CFG = %DXFM_CFG%
echo DXFM_LIB = %DXFM_LIB%
echo DXFM_DATA = %DXFM_DATA%
echo DXFM_BLOCKS = %DXFM_BLOCKS%
echo DXFM_LISP = %DXFM_LISP%
echo DXFM_RESULTS = %DXFM_RESULTS%
echo PYTHONPATH = %PYTHONPATH%
echo ================================================================
echo.
+15 -50
View File
@@ -33,6 +33,7 @@ import ezdxf
from utils import (
ROW_GROUPS, TEXT_HEIGHT, TEXT_MARGIN, CROSS_SIZE, ROW_LABEL_WIDTH,
SWITCH_FILTERS,
build_row_layout, import_element_as_block, draw_cross,
)
@@ -225,59 +226,23 @@ def horizontal_midpoint_insertion(doc):
# ---------------------------------------------------------------------------
# Schalter-Definitionen: (Label, JSON-Datei, Filter, Einfuegepunkt-Funktion)
# Filter kommen aus SWITCH_FILTERS in utils.py.
# ---------------------------------------------------------------------------
_INSERTION_FUNCS = {
"boegen": boegen_insertion_point,
"weichen45": weichen_insertion_point,
"weichen90": weichen_insertion_point,
"weichenkoerper": weichenkoerper_insertion_point,
"weichen_parallel": weichenkoerper_insertion_point,
"sternweiche": horizontal_midpoint_insertion,
"delta": horizontal_midpoint_insertion,
"dreifachweiche": horizontal_midpoint_insertion,
}
SWITCH_DEFS = {
"boegen": (
"Boegen",
"omniflo_boegen.json",
lambda item: True,
boegen_insertion_point,
),
"weichen45": (
"Weichen 45 Grad",
"omniflo_weichen.json",
lambda item: item["KurvenWinkel"] == 45
and item["WeichenTyp"] not in ("Dreifachweiche", "Deltaweiche"),
weichen_insertion_point,
),
"weichen90": (
"Weichen 90 Grad",
"omniflo_weichen.json",
lambda item: item["KurvenWinkel"] == 90
and item["WeichenTyp"] not in ("Dreifachweiche", "Deltaweiche"),
weichen_insertion_point,
),
"weichenkoerper": (
"Weichenkoerper",
"omniflo_weichen.json",
lambda item: item["KurvenWinkel"] == 22.5,
weichenkoerper_insertion_point,
),
"weichen_parallel": (
"Weichen Parallel",
"omniflo_weichen.json",
lambda item: item["KurvenWinkel"] == 0 and item["WeichenTyp"] != "Sternweiche",
weichenkoerper_insertion_point,
),
"sternweiche": (
"Sternweiche",
"omniflo_weichen.json",
lambda item: item["WeichenTyp"] == "Sternweiche",
horizontal_midpoint_insertion,
),
"delta": (
"Deltaweichen",
"omniflo_weichen.json",
lambda item: item["WeichenTyp"] == "Deltaweiche",
horizontal_midpoint_insertion,
),
"dreifachweiche": (
"Dreifachweichen",
"omniflo_weichen.json",
lambda item: item["WeichenTyp"] == "Dreifachweiche",
horizontal_midpoint_insertion,
),
key: (*SWITCH_FILTERS[key], _INSERTION_FUNCS[key])
for key in SWITCH_FILTERS
}
+213 -2
View File
@@ -11,7 +11,11 @@ Schalter:
Boegen: Beginn der obersten horizontalen Linie,
x rechts, y oben, z aus Zeichenebene.
Weichen: Beginn der untersten vertikalen Linie,
x oben, y rechts, z aus Zeichenebene.
x oben, y links, z aus Zeichenebene.
--k2set K2 an alle Boegen und Weichen setzen.
Boegen: anderes Kettenende, x tangential,
y senkrecht, z wie K1.
Weichen: noch nicht implementiert (Dummy).
--show-omniflo Uebersichts-DXF mit K-Positionen als farbige Kreuze.
--test Erzeugt Testdatei mit 4 KOS und verifiziert diese.
--number SIVA Nur diese eine 9-stellige Sivasnr verarbeiten.
@@ -28,6 +32,7 @@ from ezdxf.math import Matrix44
from utils import (
ROW_GROUPS, TEXT_HEIGHT, TEXT_MARGIN, CROSS_SIZE, ROW_LABEL_WIDTH,
SWITCH_FILTERS,
load_omniflo_data, build_row_layout, import_element_as_block,
draw_cross, is_bogen,
)
@@ -251,6 +256,150 @@ def k1_point_weiche(doc):
return (x, bottom_y, 0), 0, 0, 90
# ---------------------------------------------------------------------------
# K2-Positionsbestimmung (nur Boegen)
# ---------------------------------------------------------------------------
def k2_point_bogen(doc):
"""K2-Position fuer Boegen: anderes Ende der Kette (Gerade-Bogen-Gerade).
Sucht den Bogen, bestimmt welches Ende zur K1-Seite (oberste H-Linie)
gehoert, findet die laengste Linie am anderen Bogenende und setzt K2
an deren aeusseres Ende.
x-Achse tangential zur Linie (Richtung weg vom Bogen),
y senkrecht dazu, z aus Zeichenebene (wie K1).
Sonderfall 180-Grad-Bogen: x nach rechts (rz=0).
"""
msp = doc.modelspace()
# Bogen finden
arc = None
for e in msp:
if e.dxftype() == "ARC":
arc = e
break
if arc is None:
return None
cx, cy = arc.dxf.center[0], arc.dxf.center[1]
r = arc.dxf.radius
sa, ea = arc.dxf.start_angle, arc.dxf.end_angle
arc_start = (cx + r * math.cos(math.radians(sa)),
cy + r * math.sin(math.radians(sa)))
arc_end = (cx + r * math.cos(math.radians(ea)),
cy + r * math.sin(math.radians(ea)))
# K1-Seite = oberste horizontale Linie
hline = find_topmost_horizontal_line(doc)
if hline is None:
return None
h_y = hline.dxf.start[1]
# Welches Bogenende liegt an der K1-H-Linie?
tol = 1.0
if abs(arc_end[1] - h_y) < tol:
k2_junction = arc_start
else:
k2_junction = arc_end
# Laengste Linie am K2-Bogenende suchen
best_line_len = 0
k2_pos = None
junc_pt = None
for e in msp:
if e.dxftype() != "LINE":
continue
s = (e.dxf.start[0], e.dxf.start[1])
end = (e.dxf.end[0], e.dxf.end[1])
ds = ((s[0] - k2_junction[0])**2 + (s[1] - k2_junction[1])**2) ** 0.5
de = ((end[0] - k2_junction[0])**2 + (end[1] - k2_junction[1])**2) ** 0.5
if ds > tol and de > tol:
continue
ln = ((end[0] - s[0])**2 + (end[1] - s[1])**2) ** 0.5
if ln > best_line_len:
best_line_len = ln
if ds < tol:
k2_pos = end
junc_pt = s
else:
k2_pos = s
junc_pt = end
if k2_pos is None:
return None
# Bogenspanne berechnen
span = (ea - sa) % 360
# Tangenten-Richtung: von K2 zur Junction (zur Bogenmitte)
dx = junc_pt[0] - k2_pos[0]
dy = junc_pt[1] - k2_pos[1]
rz = math.degrees(math.atan2(dy, dx))
# 180-Grad-Sonderfall: x nach rechts, wie K1
if abs(span - 180) < 1:
rz = 0
return (k2_pos[0], k2_pos[1], 0), 0, 0, rz
# ---------------------------------------------------------------------------
# K2-Positionsbestimmung Weichen (Dummy-Funktionen)
# ---------------------------------------------------------------------------
def k2_point_weichen45(doc):
"""K2 fuer Weichen 45 Grad noch nicht implementiert."""
return None
def k2_point_weichen90(doc):
"""K2 fuer Weichen 90 Grad noch nicht implementiert."""
return None
def k2_point_weichenkoerper(doc):
"""K2 fuer Weichenkoerper noch nicht implementiert."""
return None
def k2_point_weichen_parallel(doc):
"""K2 fuer Weichen Parallel noch nicht implementiert."""
return None
def k2_point_sternweiche(doc):
"""K2 fuer Sternweiche noch nicht implementiert."""
return None
def k2_point_delta(doc):
"""K2 fuer Deltaweichen noch nicht implementiert."""
return None
def k2_point_dreifachweiche(doc):
"""K2 fuer Dreifachweichen noch nicht implementiert."""
return None
# ---------------------------------------------------------------------------
# K2 Schalter-Zuordnung: SWITCH_FILTERS-Key -> K2-Funktion
# ---------------------------------------------------------------------------
K2_FUNCS = {
"boegen": k2_point_bogen,
"weichen45": k2_point_weichen45,
"weichen90": k2_point_weichen90,
"weichenkoerper": k2_point_weichenkoerper,
"weichen_parallel": k2_point_weichen_parallel,
"sternweiche": k2_point_sternweiche,
"delta": k2_point_delta,
"dreifachweiche": k2_point_dreifachweiche,
}
# ---------------------------------------------------------------------------
# --k1set
# ---------------------------------------------------------------------------
@@ -310,6 +459,63 @@ def process_k1set(data_dir, results_dir, number=None):
print(f"\nErgebnisse in: {results_dir}")
# ---------------------------------------------------------------------------
# --k2set
# ---------------------------------------------------------------------------
def process_k2set(data_dir, results_dir, number=None):
"""Setzt K2-Block an alle Boegen und Weichen (ueber SWITCH_FILTERS)."""
omniflo_dir = os.path.join(data_dir, "omniflo")
for key, k2_func in K2_FUNCS.items():
label, json_file, filter_func = SWITCH_FILTERS[key]
json_path = os.path.join(data_dir, "json", json_file)
if not os.path.exists(json_path):
continue
with open(json_path, "r", encoding="utf-8") as f:
all_items = json.load(f)
filtered = [item for item in all_items if filter_func(item)]
if number:
filtered = [item for item in filtered if str(item["Sivasnr"]) == str(number)]
if not filtered:
continue
print(f"=== K2 setzen: {label} ===")
for item in filtered:
sivasnr = str(item["Sivasnr"])
dxf_path = os.path.join(results_dir, f"{sivasnr}.dxf")
if not os.path.exists(dxf_path):
dxf_path = os.path.join(omniflo_dir, f"{sivasnr}.dxf")
if not os.path.exists(dxf_path):
continue
doc = ezdxf.readfile(dxf_path)
msp = doc.modelspace()
# Bestehende K2-Referenzen entfernen
for entity in list(msp):
if entity.dxftype() == "INSERT" and entity.dxf.name == "K2":
msp.delete_entity(entity)
result = k2_func(doc)
if result is None:
print(f" {sivasnr}: K2 nicht bestimmbar (Dummy), ueberspringe.")
continue
point, rx, ry, rz = result
insert_ks(msp, "K2", point, rx, ry, rz)
out_path = os.path.join(results_dir, f"{sivasnr}.dxf")
doc.saveas(out_path)
print(f" {sivasnr}: K2 at ({point[0]:.2f},{point[1]:.2f},{point[2]:.2f}) "
f"rx={rx} ry={ry} rz={rz:.1f} [{item['ProfilTyp']}]")
print(f"\nErgebnisse in: {results_dir}")
# ---------------------------------------------------------------------------
# --show-omniflo
# ---------------------------------------------------------------------------
@@ -412,6 +618,8 @@ def main():
)
parser.add_argument("--k1set", action="store_true",
help="K1-Block an alle Boegen und Weichen setzen")
parser.add_argument("--k2set", action="store_true",
help="K2-Block an alle Boegen setzen (anderes Kettenende)")
parser.add_argument("--show-omniflo", action="store_true",
help="Uebersichts-DXF mit K-Positionen erzeugen")
parser.add_argument("--test", action="store_true",
@@ -424,7 +632,7 @@ def main():
print("FEHLER: --number muss eine 9-stellige Ganzzahl sein.")
sys.exit(1)
if not args.k1set and not args.show_omniflo and not args.test:
if not args.k1set and not args.k2set and not args.show_omniflo and not args.test:
parser.print_help()
sys.exit(1)
@@ -448,6 +656,9 @@ def main():
if args.k1set:
process_k1set(data_dir, results_dir, args.number)
if args.k2set:
process_k2set(data_dir, results_dir, args.number)
if args.show_omniflo:
print("=== Koordinaten Uebersicht ===")
show_omniflo(data_dir, results_dir)
+51
View File
@@ -60,6 +60,57 @@ ROW_GROUPS = [
lambda w: w["WeichenTyp"] == "Sternweiche"),
]
# ---------------------------------------------------------------------------
# Schalter-Filter: (Label, JSON-Datei, Filter-Funktion)
# Gemeinsam genutzt von set_einfuegepkt.py und set_koords.py.
# ---------------------------------------------------------------------------
SWITCH_FILTERS = {
"boegen": (
"Boegen",
"omniflo_boegen.json",
lambda item: True,
),
"weichen45": (
"Weichen 45 Grad",
"omniflo_weichen.json",
lambda item: item["KurvenWinkel"] == 45
and item["WeichenTyp"] not in ("Dreifachweiche", "Deltaweiche"),
),
"weichen90": (
"Weichen 90 Grad",
"omniflo_weichen.json",
lambda item: item["KurvenWinkel"] == 90
and item["WeichenTyp"] not in ("Dreifachweiche", "Deltaweiche"),
),
"weichenkoerper": (
"Weichenkoerper",
"omniflo_weichen.json",
lambda item: item["KurvenWinkel"] == 22.5,
),
"weichen_parallel": (
"Weichen Parallel",
"omniflo_weichen.json",
lambda item: item["KurvenWinkel"] == 0 and item["WeichenTyp"] != "Sternweiche",
),
"sternweiche": (
"Sternweiche",
"omniflo_weichen.json",
lambda item: item["WeichenTyp"] == "Sternweiche",
),
"delta": (
"Deltaweichen",
"omniflo_weichen.json",
lambda item: item["WeichenTyp"] == "Deltaweiche",
),
"dreifachweiche": (
"Dreifachweichen",
"omniflo_weichen.json",
lambda item: item["WeichenTyp"] == "Dreifachweiche",
),
}
PADDING_X = 200
PADDING_Y = 400
TEXT_HEIGHT = 30