VF-Linienzug Modus 2 auf SEGS umstellen (behebt Doppelklick-Desync)

Modus 2 journalisiert die Segment-Essenz (SEGS) statt der Objekt-Handles
(OBJS) - identische Umstellung wie Modus 3. Damit ist der Block selbst-
enthalten und der Doppelklick-Neubau unabhaengig von den Original-LINE/ARC.
Behebt den beobachteten Modus-2-Desync (Winkel wurde beim Neuaufbau interaktiv
nachgefragt + Abweichung, weil der OBJS-Replay an den - ggf. verschobenen -
Pfad-Objekten hing).

- vfl-in-selection + obj-liste im Modus-2-Ablauf durch vfl-in-segmente ersetzt
  (Live: ssget -> gf-sortiere-objekte -> gf-analysiere-kette -> Eck-Vorpruefung
  -> SEGS; Replay: fertige Essenz aus dem Journal). Objektauswahl steht jetzt
  NACH der Startpunkt-Praeambel (vfl-in-segmente braucht den startpunkt).
- segmente9 (9-Feld-Essenz) eingefuehrt, 5-Feld-segmente daraus abgeleitet;
  seg-ent -> nil (kein Live-Highlight mehr, wie Modus 3).
- Marker bleibt "linienzug2".

HARTER SCHNITT fuer Altbestand: alte OBJS-"linienzug2"-Bloecke (ohne SEGS)
werden beim Doppelklick klar abgewiesen (neuer Text vfl-edit-m2-obsolet, de/en)
statt mit falschen Daten in den Bau zu laufen; der Batch-Konverter ueberspringt
sie. Erkennung: vfl-journal-hat-segs-p.

Tests: 3 file-freie Unit-Tests fuer vfl-journal-hat-segs-p (SEGS erkannt,
OBJS/leer nicht). 243/243 LISP-Unit-Tests gruen in BricsCAD; test-neutral gegen
HEAD (11=11 Python-Failures); lang-Paritaet geprueft. End-to-end (Neubau +
deckungsgleicher Doppelklick) wie bei Modus 3 interaktiv zu bestaetigen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Michael Stangl
2026-09-18 16:44:10 +02:00
co-authored by Claude Opus 4.8
parent 008f497b5d
commit 8ccec9dea7
4 changed files with 68 additions and 23 deletions
+50 -23
View File
@@ -8285,7 +8285,12 @@
(setq marker (car xd) journal (cdr xd))
(if (and (wcmatch bname "VF_*")
(member marker '("linienzug" "linienzug2" "linienzug3"))
journal)
journal
;; Alte OBJS-"linienzug2"-Bloecke (ohne SEGS) NICHT konvertieren -
;; ihr Replay ist mit dem SEGS-Umbau nicht mehr fahrbar (harter
;; Schnitt, wie im Doppelklick-Pfad vfl-edit-ent). Sie ueberspringen
;; (nil zurueck), damit die Batch-Schleife sauber weiterlaeuft.
(or (/= marker "linienzug2") (vfl-journal-hat-segs-p journal)))
(progn
(setq *ssg-ils-dim* ziel-dim) ; Zieldim erzwingen
(entdel ent) ; alten Block weg
@@ -8320,7 +8325,14 @@
;; gelesen; der Override greift beim anschliessenden Replay/Weiterbau.
(setq dim (ssg-dim-xdata-lesen ent))
(cond
((= marker "linienzug2") (vfl-edit-ent2 ent journal))
((= marker "linienzug2")
;; Harter Schnitt: nur SEGS-Bloecke (neue Fassung) sind per Doppelklick
;; neu aufbaubar. Alte OBJS-Bloecke (Objekt-Handles statt Segment-Essenz)
;; wuerden im Replay falsche Daten in den Bau geben - klar abweisen statt
;; zu crashen.
(if (vfl-journal-hat-segs-p journal)
(vfl-edit-ent2 ent journal)
(alert (ssg-text "vfl-edit-m2-obsolet"))))
((= marker "linienzug3") (vfl-edit-ent3 ent journal))
(t
(progn
@@ -8381,6 +8393,13 @@
(setq *ssg-ils-dim* nil))))))
(princ))
;; T, wenn das Journal einen SEGS-Eintrag traegt (Modus 2 NEU / Modus 3 - die
;; Kette ist per Segment-Essenz selbst-enthalten). Alte Modus-2-Bloecke tragen
;; hier stattdessen einen OBJS-Eintrag (Objekt-Handles) - fuer die ist der
;; SEGS-Replay nicht mehr fahrbar (harter Schnitt, siehe vfl-edit-ent).
(defun vfl-journal-hat-segs-p (journal)
(and (vl-some (function (lambda (e) (equal (car e) "SEGS"))) journal) t))
;; Modus-2/3-Block per Doppelklick zuruecksetzen: voller Reset - die komplette
;; gespeicherte Eingabe wird 1:1 stumm abgespielt, identischer Neuaufbau. Kein
;; Sektions-Dialog; der Nutzer kann den neu entstandenen Block danach ganz
@@ -9384,7 +9403,7 @@
100.0))))
(defun vf-linienzug-modus2 ( / ss k obj-liste startpunkt start-hoehe as-seite
endpunkt end-hoehe es-seite kette segmente n i seg
endpunkt end-hoehe es-seite kette segmente segmente9 n i seg
seg-ent
typ hz laenge bwinkel bseite antwort winkel klass
plan e ecke-bad vf-start vf-ende dz z-front
@@ -9448,11 +9467,14 @@
(vfl-gf-abhaengigkeit-sicherstellen "vfl-m3-alert-gf-modul")
;; --- 1. Pfad-Objekte waehlen ---
(princ (ssg-text "vfl-m3-pfad-waehlen"))
(setq ss (vfl-in-selection '((0 . "LINE,ARC"))))
(if (null ss) (progn (princ (ssg-text "vfl-m3-keine-objekte")) (exit)))
(setq obj-liste (mapcar 'vlax-ename->vla-object ss))
;; --- 1./4. Pfad-Objekte + Segment-Essenz: siehe Schritt 4 unten. ---
;; Auswahl UND Ableitung laufen zusammen in vfl-in-segmente (Live: ssget ->
;; gf-sortiere-objekte -> gf-analysiere-kette -> Eck-Vorpruefung -> SEGS;
;; Replay: fertige Essenz aus dem Journal). Persistiert die Segment-Essenz
;; statt der Objekt-Handles - der Block ist damit selbst-enthalten und der
;; Doppelklick-Neubau unabhaengig von den Original-LINE/ARC (behebt den
;; frueheren OBJS-Replay-Drift). Da vfl-in-segmente den startpunkt fuer die
;; Sortierung braucht, steht die Auswahl NACH der Startpunkt-Praeambel.
;; --- 2. Startpunkt + Z + AS-Seite ---
(if (vfl-wizard-aktiv)
@@ -9502,16 +9524,16 @@
(setq es-seite (vfl-frage-es-winkel-seite "gf-seite-ein-header"))
)
;; --- 4. Sortieren + Analysieren + Eck-Vorpruefung ---
(setq kette (gf-sortiere-objekte obj-liste startpunkt))
(if (null kette)
(progn (princ (ssg-text "vfl-m3-fehler-nicht-sortierbar")) (exit)))
(setq segmente (gf-analysiere-kette kette))
(setq ecke-bad (vfl2-pruefe-eckwinkel kette *vfk-eckwinkel-toleranz*))
(if ecke-bad
(progn
(vfl-meldung (ssg-textf "vfl-m3-alert-eckwinkel" (list (rtos ecke-bad 2 1))))
(exit)))
;; --- 4. Pfad waehlen + Sortieren + Analysieren + Eck-Vorpruefung ---
;; vfl-in-segmente kapselt Live + Replay und persistiert die Segment-Essenz
;; (SEGS) statt der Objekt-Handles - siehe Schritt 1 oben und Modus 3.
(princ (ssg-text "vfl-m3-pfad-waehlen"))
(setq segmente9 (vfl-in-segmente '((0 . "LINE,ARC")) startpunkt *vfk-eckwinkel-toleranz*))
(if (null segmente9) (progn (princ (ssg-text "vfl-m3-keine-objekte")) (exit)))
;; segmente = 5-Feld-Bausicht (typ hz laenge bwinkel bseite) aus der 9-Feld-
;; Essenz - die Klassifizierungs-Schleife unten arbeitet unveraendert damit.
(setq segmente (mapcar (function (lambda (s) (list (nth 0 s) (nth 1 s) (nth 2 s) (nth 3 s) (nth 4 s))))
segmente9))
;; --- 5. Klassifizierung (Phase A: nur speichern, nichts bauen) ---
;; Plan-Eintrag Gerade: ("Linie" hz laenge klass winkel) klass=GF/VF
@@ -9519,13 +9541,18 @@
(setq n (length segmente) i 0 plan '())
(while (< i n)
(setq seg (nth i segmente) typ (car seg) hz (cadr seg) laenge (caddr seg))
(setq seg-ent (car (nth i kette))) ; echte LINE/ARC-Entity dieses Segments
;; seg-ent: KEINE Live-Entity mehr - Modus 2 baut jetzt aus der Segment-
;; Essenz (SEGS), nicht aus durchgereichten LINE/ARC (siehe Modus 3). Damit
;; entfaellt das kosmetische Pfad-Segment-Highlight (vfl-seg-highlight ist
;; nil-sicher). Bewusst: die Essenz macht Bau/Replay unabhaengig von den
;; Original-Objekten, ein Highlight haette beim Doppelklick-Neubau ohnehin
;; keine Entity mehr.
(setq seg-ent nil)
;; Wizard: alle Fragen dieses Segments in EINEM Dialog erfassen (die
;; unveraenderten vfl-menu/vfl-in-*-Aufrufe unten konsumieren die Antworten
;; aus *vflw-pending*). Segment vorher in der Zeichnung hervorheben. Der
;; nach-kurve-Fall stellt keine Frage (auto-VF) -> kein Dialog. Ebenso
;; nach-vf bei einem Bogen: Vario-Kurve ist dann erzwungen (eine VF-
;; Einheit kann nicht in einen GF-Bogen auslaufen), auch kein Dialog.
;; aus *vflw-pending*). Der nach-kurve-Fall stellt keine Frage (auto-VF) ->
;; kein Dialog. Ebenso nach-vf bei einem Bogen: Vario-Kurve ist dann
;; erzwungen (eine VF-Einheit kann nicht in einen GF-Bogen auslaufen).
(if (and (vfl-wizard-aktiv)
(not (and (= typ "Linie") nach-kurve))
(not (and (= typ "Bogen") nach-vf)))
+1
View File
@@ -111,6 +111,7 @@
"vfl-glied-vario": "Vario-Kurve (horizontale Kurve im VF)",
"vfl-glied-offen": "(offen)",
"vfl-edit-kein-journal": "Dieser Linienzug-Block traegt kein Eingabe-Journal (Altbestand) und kann nicht schrittweise editiert werden.",
"vfl-edit-m2-obsolet": "Dieser Modus-2-Block wurde mit dem alten Objekt-Referenz-Journal gebaut und kann nicht mehr per Doppelklick neu aufgebaut werden. Bitte die Kette mit Modus 2 neu erzeugen (die neue Fassung speichert die Segment-Daten direkt am Block).",
"vfl-edit-kette-header": "\n\nLinienzug mit %1 Glied(ern):",
"vfl-edit-abgespielt": "\n>>> %1 Glied(er) werden abgespielt, %2 zurueckgenommen - danach interaktiv weiter.",
"vfl-edit2-reset-info": "\n>>> Linienzug (Modus 2) wird mit den gespeicherten Angaben identisch neu aufgebaut...",
+1
View File
@@ -111,6 +111,7 @@
"vfl-glied-vario": "Vario curve (horizontal curve in VF)",
"vfl-glied-offen": "(open)",
"vfl-edit-kein-journal": "This chain block carries no input journal (legacy) and cannot be edited step by step.",
"vfl-edit-m2-obsolet": "This mode-2 block was built with the old object-reference journal and can no longer be rebuilt by double-click. Please recreate the chain with mode 2 (the new version stores the segment data directly on the block).",
"vfl-edit-kette-header": "\n\nChain with %1 segment(s):",
"vfl-edit-abgespielt": "\n>>> %1 segment(s) replayed, %2 undone - then continue interactively.",
"vfl-edit2-reset-info": "\n>>> Rebuilding this Modus-2 chain identically from the saved inputs...",
+16
View File
@@ -900,6 +900,22 @@
;; erwarteten Trenner und KEIN Newline (sonst zerrisse der Record-Trenner)
(tu-nil "vfl-segs/kein-newline"
(vl-string-search "\n" (vfl-segs->string _segs)))
;; vfl-journal-hat-segs-p: unterscheidet neue SEGS-Ketten von alten
;; OBJS-"linienzug2"-Bloecken (harter Schnitt beim Doppelklick).
(if (atoms-family 1 '("VFL-JOURNAL-HAT-SEGS-P"))
(progn
;; SEGS-Journal (Modus 2 neu / Modus 3): erkannt
(tu-true "vfl-hat-segs/mit-segs"
(vfl-journal-hat-segs-p
(list (cons "PT" '(0.0 0.0 0.0)) (cons "SEGS" _segs))))
;; Altes OBJS-Journal (Objekt-Handles): NICHT als SEGS erkannt
(tu-nil "vfl-hat-segs/nur-objs"
(vfl-journal-hat-segs-p
(list (cons "PT" '(0.0 0.0 0.0)) (cons "OBJS" '("A1" "A2")))))
;; Leeres Journal: nil
(tu-nil "vfl-hat-segs/leer" (vfl-journal-hat-segs-p '())))
(tu-record nil "vfl-hat-segs/modul" "VFL-JOURNAL-HAT-SEGS-P fehlt"))
)
)
)