[FIX] VF-Linienzug: Abbruch beim Editieren brach den VF-Block auf
Die interaktiven Editier-Pfade riefen den Neuaufbau ueber vl-catch-all-apply auf. Der alte Block ist dort per entdel schon entfernt, und der Catch faengt einen Abbruch (ESC -> (exit)) VOR *error* ab - der Abbruch-Wickler vfl-modus-abbruch-sichern kam damit nie zum Zug. Ergebnis: die komplette Kette blieb als lose Einzelteile ohne VF_n-Block liegen und war nicht mehr per Doppelklick editierbar. - vfl-edit-ent (Sektions-Zweig) und vfl-edit-ent2 rufen vf-linienzug-modus/-modus2 jetzt DIREKT auf. Nur der nicht-interaktive Batch-Konverter vfl-konvertiere-ent behaelt den Catch (die Batch-Schleife muss weiterlaufen) und meldet den betroffenen Block statt still zu scheitern. - Beide Abbruch-Handler setzen *ssg-ils-dim* zurueck. Das tat bisher nur der Aufrufer, der nach einem Abbruch nicht mehr erreicht wird - der Dim-Override blieb fuer die restliche Sitzung stehen. Wiederherstellung aus der Zeichnung (Sektions-XDATA): - vfl-segment-xdata-sichern schrieb nur die Slice des LETZTEN Glieds einer Schleifen-Iteration. Eine VF-Einheit mit eingebetteten Vario-Kurven verlor dadurch ihre eigenen Eingaben. Jetzt wird der komplette Journal-Abschnitt der Iteration geschrieben, indiziert mit dem ersten Glied-Index darin (neu: vfl-journal-ab-glied, vfl-steps-zaehlen). Ein Glied ohne Geometrie verbraucht seinen Abschnitt nicht mehr - er wandert in den naechsten Record, der Entities bekommt. - Neue XDATA-App SSG_VF_EDIT_PRE haelt die Praeambel (Startpunkt, Starthoehe, AS ja/nein + Winkel/Seite) auf den Entities der ersten Iteration. Ohne sie fehlte der Kopf des Journals in jeder Sektion. - Neuer Befehl VF_SEKTION_RESTORE: Auswahl der losen Geometrie -> Sektionen lueckenlos ab Glied 1 zusammensetzen -> stummer Replay -> interaktiv weiterbauen. Die alte Geometrie wird erst NACH erfolgreichem Neuaufbau geloescht, ein Abbruch laesst sie samt XDATA stehen (Versuch wiederholbar). Altbestand ohne Praeambel-XDATA wird danach gefragt. Die .dbg-Dateien bleiben reine Ausgabe und werden von keinem Befehl gelesen - Wiederherstellungs-Daten gehoeren in die XDATA der Zeichnung. tests/testdata/vfl_journal_hm05_abbruch.json: Journal der Session vom 2026-08-31 (9 Glieder), gegen das die Slice-/Join-Logik geprueft wurde. Reine Daten, wird von keinem Befehl gelesen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+302
-16
@@ -143,8 +143,15 @@
|
||||
;; "NIL" Abbruch/Default (value nil) "STEP" Glied-Checkpoint (value = Label)
|
||||
;; *vfl-journal* wird in UMGEKEHRTER Reihenfolge gehalten (neuestes zuerst, cons).
|
||||
|
||||
;; *vfl-seg-glied-letzte* = Glied-Stand nach der vorherigen Iteration der
|
||||
;; Bau-Hauptschleife (fuer die Segment-XDATA, siehe vfl-segment-xdata-sichern).
|
||||
;; MUSS bei jedem Journal-Start auf 0 stehen, sonst bekaeme das erste Glied
|
||||
;; eines neuen Baus einen zu hohen Index und die Praeambel wuerde nicht
|
||||
;; geschrieben.
|
||||
(if (not (boundp '*vfl-seg-glied-letzte*)) (setq *vfl-seg-glied-letzte* 0))
|
||||
|
||||
(defun vfl-journal-reset ()
|
||||
(setq *vfl-journal* '() *vfl-replay-queue* nil)
|
||||
(setq *vfl-journal* '() *vfl-replay-queue* nil *vfl-seg-glied-letzte* 0)
|
||||
(if (boundp '*vflw-pending*) (setq *vflw-pending* nil)))
|
||||
|
||||
;; Eintrag anhaengen (vorn, da Reverse-Reihenfolge).
|
||||
@@ -1287,6 +1294,7 @@
|
||||
;; forward-journal (Bau-Reihenfolge) als kompakter JSON-Array-String.
|
||||
(defun vfl-journal->json (forward-journal)
|
||||
(strcat "[" (vfl-strjoin (mapcar 'vfl-entry->json forward-journal) ",") "]"))
|
||||
|
||||
(defun vfl-string->journal (s / out)
|
||||
(setq out '())
|
||||
(foreach ln (vfl-strsplit s "\n")
|
||||
@@ -1365,6 +1373,46 @@
|
||||
nil))
|
||||
nil))
|
||||
|
||||
;; --- Praeambel-XDATA (eigene App "SSG_VF_EDIT_PRE") -----------------------
|
||||
;; Die Segment-XDATA (SSG_VF_EDIT_SEG) deckt nur die GLIEDER ab - alles vor
|
||||
;; dem ersten STEP (Startpunkt, Starthoehe, AS ja/nein + AS-Winkel/-Seite)
|
||||
;; steht in keiner Slice. Fuer eine vollstaendige Wiederherstellung aus der
|
||||
;; Zeichnung allein (c:VF_SEKTION_RESTORE) fehlt damit genau der Kopf des
|
||||
;; Journals. Deshalb wird die Praeambel zusaetzlich als eigene XDATA-App auf
|
||||
;; die Entities des ERSTEN Gliedes geschrieben - eigene App, weil pro Entity
|
||||
;; nur ein SSG_VF_EDIT_SEG-Record Platz hat (der gehoert dem Glied).
|
||||
;; Layout: [0]="linienzug-pre" (Marker), [1..]=Journal-String in 250-Byte-Chunks.
|
||||
;;
|
||||
;; Praeambel = alle Journal-Eintraege VOR dem ersten STEP.
|
||||
(defun vfl-journal-praeambel (forward-journal / out fertig)
|
||||
(setq out '() fertig nil)
|
||||
(foreach e forward-journal
|
||||
(if (and (not fertig) (= (car e) "STEP")) (setq fertig t))
|
||||
(if (not fertig) (setq out (cons e out))))
|
||||
(reverse out))
|
||||
|
||||
(defun vfl-journal-xdata-schreiben-pre (ent pre-journal / chunks appentry)
|
||||
(regapp "SSG_VF_EDIT_PRE")
|
||||
(setq chunks (vfl-chunk-string (vfl-journal-list->string pre-journal) 250))
|
||||
(setq appentry
|
||||
(cons "SSG_VF_EDIT_PRE"
|
||||
(cons (cons 1000 "linienzug-pre")
|
||||
(mapcar (function (lambda (c) (cons 1000 c))) chunks))))
|
||||
(entmod (append (entget ent) (list (list -3 appentry))))
|
||||
ent)
|
||||
|
||||
;; Rueckgabe: Praeambel-Journal oder nil (keine/unbekannte Praeambel-XDATA).
|
||||
(defun vfl-journal-xdata-lesen-pre (ent / xd app-data werte)
|
||||
(setq xd (entget ent '("SSG_VF_EDIT_PRE")))
|
||||
(setq app-data (cdr (assoc -3 xd)))
|
||||
(if app-data
|
||||
(progn
|
||||
(setq werte (mapcar 'cdr (cdr (car app-data))))
|
||||
(if (and werte (= (car werte) "linienzug-pre"))
|
||||
(vfl-string->journal (apply 'strcat (cdr werte)))
|
||||
nil))
|
||||
nil))
|
||||
|
||||
;; Wird direkt nach dem Segment-Dispatch-cond in vf-linienzug-modus aufgerufen
|
||||
;; (per vl-catch-all-apply abgesichert - ein Fehler hier darf den Hauptbau nie
|
||||
;; abbrechen, rein additive Zusatz-XDATA). seg-lastEnt = Schnappschuss VOR
|
||||
@@ -1377,13 +1425,31 @@
|
||||
;; ergaenzt) und schreibt sie auf JEDES seit seg-lastEnt neu erzeugte Entity
|
||||
;; (entnext-Wanderung, gleiches Muster wie vfl-block-erstellen/
|
||||
;; vfl-modus-abbruch-sichern).
|
||||
(defun vfl-segment-xdata-sichern (seg-lastEnt wahl / forward-journal seg-idx seg-journal e cnt slice-label)
|
||||
(defun vfl-segment-xdata-sichern (seg-lastEnt wahl / forward-journal seg-idx seg-von
|
||||
seg-journal log-slice e cnt slice-label pre-journal)
|
||||
(setq forward-journal (reverse *vfl-journal*))
|
||||
(setq seg-idx (length (vfl-journal-glieder forward-journal)))
|
||||
;; Erstes Glied DIESER Iteration: eine Iteration kann mehrere Glieder
|
||||
;; erzeugen (VF-Einheit + eingebettete Vario-Kurven). *vfl-seg-glied-letzte*
|
||||
;; haelt den Glied-Stand der vorherigen Iteration.
|
||||
(if (null *vfl-seg-glied-letzte*) (setq *vfl-seg-glied-letzte* 0))
|
||||
(setq seg-von (1+ *vfl-seg-glied-letzte*))
|
||||
(setq cnt 0)
|
||||
(if (> seg-idx 0)
|
||||
(if (and (> seg-idx 0) (>= seg-idx seg-von))
|
||||
(progn
|
||||
(setq seg-journal (vfl-journal-slice forward-journal seg-idx))
|
||||
;; XDATA: der KOMPLETTE in dieser Iteration entstandene Journal-Abschnitt
|
||||
;; (Glieder seg-von .. seg-idx), indiziert mit dem ERSTEN Glied-Index.
|
||||
;; Nur so ist die Kette spaeter luecken- und desync-frei aus der
|
||||
;; Zeichnung rekonstruierbar (c:VF_SEKTION_RESTORE).
|
||||
(setq seg-journal (vfl-journal-ab-glied forward-journal seg-von))
|
||||
;; Fuers Log/die Schema-Validierung weiterhin die Slice des LETZTEN
|
||||
;; Glieds (unveraendertes Verhalten, siehe Kommentar unten).
|
||||
(setq log-slice (vfl-journal-slice forward-journal seg-idx))
|
||||
;; Praeambel (Startpunkt/Starthoehe/AS) bei der ERSTEN Iteration
|
||||
;; mitschreiben - ohne sie waere die Kette aus der Zeichnung nicht
|
||||
;; vollstaendig rekonstruierbar (vfl-journal-xdata-schreiben-pre).
|
||||
;; Danach aendert sich die Praeambel nicht mehr.
|
||||
(setq pre-journal (if (= seg-von 1) (vfl-journal-praeambel forward-journal) nil))
|
||||
;; Tatsaechliches Label der geschnittenen Slice (der STEP-Wert am Anfang).
|
||||
;; Kann von wahl (dem Hauptschleifen-Label) ABWEICHEN: enthaelt die
|
||||
;; VF-Einheit eine Vario-Kurve, ist DEREN STEP das letzte Glied, seg-idx
|
||||
@@ -1391,30 +1457,42 @@
|
||||
;; noch "Horizontal-VF"/"Linie-VF" ist. Fuers Log/die Validierung zaehlt
|
||||
;; das echte Slice-Label, nicht wahl (sonst falsch etikettiert).
|
||||
(setq slice-label
|
||||
(if (and seg-journal (= (car (car seg-journal)) "STEP"))
|
||||
(cdr (car seg-journal)) wahl))
|
||||
(if (and log-slice (= (car (car log-slice)) "STEP"))
|
||||
(cdr (car log-slice)) wahl))
|
||||
(setq e (if seg-lastEnt (entnext seg-lastEnt) (entnext)))
|
||||
(while e
|
||||
(vfl-journal-xdata-schreiben-seg e seg-idx seg-journal)
|
||||
(vfl-journal-xdata-schreiben-seg e seg-von seg-journal)
|
||||
(if pre-journal (vfl-journal-xdata-schreiben-pre e pre-journal))
|
||||
(setq cnt (1+ cnt))
|
||||
(setq e (entnext e))
|
||||
)
|
||||
;; Glied-Stand NUR fortschreiben, wenn wirklich Entities beschrieben
|
||||
;; wurden. Ein Glied ohne Geometrie (z.B. "VF-Einheit nicht baubar" -
|
||||
;; Menue-Antwort und Laenge sind journalisiert, gebaut wurde nichts) hat
|
||||
;; keinen Traeger fuer seine XDATA. Bliebe der Stand trotzdem stehen,
|
||||
;; waere sein Journal-Abschnitt unauffindbar und die Kette waere ab dort
|
||||
;; nur noch mit Luecke wiederherstellbar. So wandert der Abschnitt
|
||||
;; stattdessen in den naechsten Record, der Entities bekommt.
|
||||
(if (> cnt 0) (setq *vfl-seg-glied-letzte* seg-idx))
|
||||
;; Diagnose: den tatsaechlichen Segment-Journal-Inhalt als JSON loggen
|
||||
;; (analog zum Ketten-XDATA-JOURNAL-JSON in vfl-journal-xdata-schreiben)
|
||||
;; plus die Anzahl der beschriebenen Entities. No-Op ohne offene .dbg.
|
||||
(dbgmsg (strcat "SEGMENT-XDATA-JSON Glied " (itoa seg-idx) " ("
|
||||
(if slice-label slice-label "?") ") auf " (itoa cnt) " Entity(s): "
|
||||
(vfl-journal->json seg-journal)))
|
||||
(dbgmsg (strcat "SEGMENT-XDATA-JSON Glied " (itoa seg-von)
|
||||
(if (> seg-idx seg-von) (strcat ".." (itoa seg-idx)) "")
|
||||
" (" (if slice-label slice-label "?") ") auf " (itoa cnt)
|
||||
" Entity(s): " (vfl-journal->json seg-journal)))
|
||||
;; Zusaetzlich benannt loggen (statt roher [INT]/[STR]-Zeilen). Feste
|
||||
;; Glieder (AS/ES/GF-Bogen/Vario-Kurve) ueber ihr Feld-Schema
|
||||
;; (GF-Bogen.winkel = 90), die VF-Einheit (Linie-VF/Horizontal-VF, variable
|
||||
;; Laenge) ueber den Sub-Step-Logger (VF.menue = 4, VF.laenge = ...). Beide
|
||||
;; validieren, was validierbar ist, und markieren Abweichungen (<!! ...>).
|
||||
;; Ueber slice-label (echtes Glied), nicht wahl.
|
||||
;; Bewusst log-slice (genau EIN Glied) - die Schema-Logger erwarten die
|
||||
;; Slice eines einzelnen Glieds, nicht den Iterations-Abschnitt.
|
||||
(if (vfl-schema-felder slice-label)
|
||||
(vfl-schema-log-slice slice-label seg-journal)
|
||||
(vfl-schema-log-slice slice-label log-slice)
|
||||
(if (member slice-label '("Linie-VF" "Horizontal-VF"))
|
||||
(vfl-schema-log-vf slice-label seg-journal)))
|
||||
(vfl-schema-log-vf slice-label log-slice)))
|
||||
)
|
||||
(dbgmsg (strcat "SEGMENT-XDATA: kein Glied vorhanden (" (if wahl wahl "?") ")"))
|
||||
)
|
||||
@@ -1465,7 +1543,8 @@
|
||||
;; zur Lesequelle, *vfl-journal* startet leer und wird bei der erneuten
|
||||
;; Ausfuehrung neu aufgebaut. Genutzt von vfl-edit-ent und der Wiederaufnahme.
|
||||
(defun vfl-journal-replay-start (forward-journal)
|
||||
(setq *vfl-replay-queue* forward-journal *vfl-journal* '())
|
||||
(setq *vfl-replay-queue* forward-journal *vfl-journal* '()
|
||||
*vfl-seg-glied-letzte* 0)
|
||||
(if (boundp '*vflw-pending*) (setq *vflw-pending* nil)))
|
||||
|
||||
;; --- Glied-Zerlegung fuer den Editier-Dialog ---
|
||||
@@ -1507,6 +1586,34 @@
|
||||
(started (setq out (cons e out))))))
|
||||
(reverse out))
|
||||
|
||||
;; Journal-Eintraege AB dem (from-step-idx)-ten Glied bis zum ENDE des
|
||||
;; Journals (alle folgenden STEPs inklusive). Gegenstueck zu
|
||||
;; vfl-journal-slice, das bei genau einem Glied stoppt.
|
||||
;; Gebraucht fuer die Segment-XDATA: eine Iteration der Bau-Hauptschleife kann
|
||||
;; MEHRERE Glieder erzeugen (eine VF-Einheit mit eingebetteten Vario-Kurven
|
||||
;; legt Horizontal-VF/Linie-VF + je Kurve ein eigenes STEP ab). Auf die
|
||||
;; Entities dieser Iteration muss deshalb der GESAMTE in ihr entstandene
|
||||
;; Journal-Abschnitt, nicht nur die Slice des letzten Glieds - sonst fehlen
|
||||
;; die Eingaben der Einheit selbst und die Kette ist aus der Zeichnung nicht
|
||||
;; mehr vollstaendig rekonstruierbar (c:VF_SEKTION_RESTORE).
|
||||
(defun vfl-journal-ab-glied (forward-journal from-step-idx / seen out started)
|
||||
(setq seen 0 out '() started nil)
|
||||
(foreach e forward-journal
|
||||
(if started
|
||||
(setq out (cons e out))
|
||||
(if (= (car e) "STEP")
|
||||
(progn
|
||||
(setq seen (1+ seen))
|
||||
(if (= seen from-step-idx)
|
||||
(progn (setq started t) (setq out (cons e out))))))))
|
||||
(reverse out))
|
||||
|
||||
;; Anzahl der Glieder (STEP-Eintraege) in einem Journal-Abschnitt.
|
||||
(defun vfl-steps-zaehlen (journal / n)
|
||||
(setq n 0)
|
||||
(foreach e journal (if (= (car e) "STEP") (setq n (1+ n))))
|
||||
n)
|
||||
|
||||
;; Journal-Eintraege des Glieds (seg-idx) durch (new-seg-journal) ersetzen -
|
||||
;; alle anderen Glieder (davor UND danach) sowie die Praeambel bleiben
|
||||
;; unveraendert. Gegenstueck zu vfl-journal-slice (welches genau dieses Glied
|
||||
@@ -3167,9 +3274,16 @@
|
||||
;; geschlossen (Undo-Gruppe, gesicherte Systemvariablen, *error* aus dem
|
||||
;; Sitzungs-Frame) - sonst bliebe die von ssg-start geoeffnete Undo-Gruppe
|
||||
;; offen.
|
||||
;; *ssg-ils-dim*: der Editier-/Konverter-Pfad setzt vor dem Replay einen
|
||||
;; Dimensions-Override und raeumt ihn NACH der Rueckkehr wieder ab. Bei einem
|
||||
;; Abbruch kehrt der Aufruf nie dorthin zurueck (der Handler beendet den
|
||||
;; Befehl), daher MUSS der Override hier zurueckgesetzt werden - sonst bliebe
|
||||
;; er fuer den Rest der Sitzung stehen und alle folgenden Einfuegungen liefen
|
||||
;; in der falschen Dimension.
|
||||
(setq *error*
|
||||
(function (lambda (msg)
|
||||
(setq *error* old-error)
|
||||
(setq *ssg-ils-dim* nil)
|
||||
(vfl-modus-abbruch-sichern lastEnt vfl-nummer anzahl-gf anzahl-vf
|
||||
startpunkt frame as-seite es-seite "linienzug")
|
||||
(if dbg-an
|
||||
@@ -4191,7 +4305,18 @@
|
||||
'vf-linienzug-modus2
|
||||
'vf-linienzug-modus)))
|
||||
(setq *ssg-ils-dim* nil) ; Override zuruecksetzen
|
||||
(if (vl-catch-all-error-p ok) nil T))
|
||||
;; Fehlgeschlagene Konvertierung NICHT stumm verschlucken: der alte Block
|
||||
;; ist per entdel schon weg, die Teil-Geometrie liegt frei in der
|
||||
;; Zeichnung (der *error*-Handler in vf-linienzug-modus kann hier nicht
|
||||
;; greifen, weil vl-catch-all-apply den Abbruch vorher abfaengt - das ist
|
||||
;; hier gewollt, damit die Batch-Schleife weiterlaeuft). Meldung mit
|
||||
;; Blockname, damit der betroffene Block auffindbar bleibt.
|
||||
(if (vl-catch-all-error-p ok)
|
||||
(progn
|
||||
(princ (ssg-textf "vfl-konvert-fehler"
|
||||
(list bname (vl-catch-all-error-message ok))))
|
||||
nil)
|
||||
T))
|
||||
nil))
|
||||
|
||||
(defun vfl-edit-ent (ent / xd marker journal glieder glieder-alle has-as n i pos trunc edit-modus dim)
|
||||
@@ -4247,7 +4372,20 @@
|
||||
;; Override auf die Dimension des Bestandsblocks, danach zuruecksetzen.
|
||||
(if dim (setq *ssg-ils-dim* dim))
|
||||
(vfl-journal-replay-start trunc)
|
||||
(vl-catch-all-apply 'vf-linienzug-modus)
|
||||
;; WICHTIG: DIREKTER Aufruf, KEIN vl-catch-all-apply!
|
||||
;; Der Neuaufbau ist interaktiv - bricht der Nutzer ihn ab (ESC ->
|
||||
;; (exit) im Bau-Ablauf), MUSS der *error*-Handler in
|
||||
;; vf-linienzug-modus laufen und die bis dahin gebaute Teil-Geometrie
|
||||
;; zu einem VF_n-Block wickeln. Ein vl-catch-all-apply faengt den
|
||||
;; Abbruch VOR *error* ab: der Handler kaeme nie zum Zug, der alte
|
||||
;; Block ist durch das entdel oben aber schon weg - die ganze Kette
|
||||
;; bliebe als loses Einzelteil-Haufen ohne Block in der Zeichnung
|
||||
;; liegen (nicht mehr per Doppelklick editierbar). Genau das war der
|
||||
;; Fehler "VF-Block aufgebrochen".
|
||||
;; Das Abraeumen des Dim-Overrides uebernimmt im Abbruchfall der
|
||||
;; Handler selbst (dort ebenfalls (setq *ssg-ils-dim* nil)), denn
|
||||
;; die naechste Zeile wird dann nicht mehr erreicht.
|
||||
(vf-linienzug-modus)
|
||||
(setq *ssg-ils-dim* nil)))))
|
||||
(princ))
|
||||
|
||||
@@ -4265,10 +4403,154 @@
|
||||
(princ (ssg-text "vfl-edit2-reset-info"))
|
||||
(if dim (setq *ssg-ils-dim* dim))
|
||||
(vfl-journal-replay-start journal)
|
||||
(vl-catch-all-apply 'vf-linienzug-modus2)
|
||||
;; DIREKTER Aufruf, KEIN vl-catch-all-apply - identische Begruendung wie im
|
||||
;; Sektions-Zweig von vfl-edit-ent (siehe dortiger Kommentar): der alte Block
|
||||
;; ist per entdel schon weg, bei einem Abbruch muss der *error*-Handler von
|
||||
;; vf-linienzug-modus2 die Teil-Geometrie wickeln. Den Dim-Override raeumt im
|
||||
;; Abbruchfall der Handler ab.
|
||||
(vf-linienzug-modus2)
|
||||
(setq *ssg-ils-dim* nil)
|
||||
(princ))
|
||||
|
||||
;; ============================================================
|
||||
;; RECOVERY: Kette aus der Sektions-XDATA der Zeichnung neu aufbauen
|
||||
;; ============================================================
|
||||
;; Wofuer: bleibt eine Linienzug-Kette als LOSE Geometrie ohne VF_n-Block in
|
||||
;; der Zeichnung liegen (der Block war schon per entdel weg, der Neuaufbau
|
||||
;; wurde abgebrochen und konnte nicht gewickelt werden), ist sie nicht mehr per
|
||||
;; Doppelklick editierbar. Die Eingaben sind aber nicht verloren: jedes Entity
|
||||
;; traegt den Journal-Abschnitt der Iteration, in der es entstand
|
||||
;; (SSG_VF_EDIT_SEG, indiziert mit dem ERSTEN Glied-Index darin - siehe
|
||||
;; vfl-segment-xdata-sichern), und die Entities der ersten Iteration
|
||||
;; zusaetzlich die Praeambel (SSG_VF_EDIT_PRE). Daraus laesst sich das
|
||||
;; Ketten-Journal zusammensetzen und die Kette identisch neu bauen - diesmal
|
||||
;; sauber als VF_n-Block mit Ketten-XDATA.
|
||||
;;
|
||||
;; Quelle ist AUSSCHLIESSLICH die Zeichnung selbst. Die .dbg-Dateien sind
|
||||
;; reine Ausgabe und werden hier bewusst NICHT gelesen (sie werden bei jedem
|
||||
;; Lauf neu angelegt, siehe dbgopen).
|
||||
;;
|
||||
;; Ablauf: Geometrie waehlen -> Sektionen sammeln und nach Glied-Index sortieren
|
||||
;; -> Journal (Praeambel + Glieder 1..k) stumm abspielen -> danach normal
|
||||
;; weiterbauen. Die alte Geometrie wird erst NACH einem erfolgreichen Neuaufbau
|
||||
;; geloescht (bricht der Neuaufbau ab, bleibt sie samt ihrer XDATA stehen und
|
||||
;; der Versuch ist wiederholbar).
|
||||
|
||||
;; Praeambel interaktiv erfragen - nur fuer Altbestand ohne SSG_VF_EDIT_PRE
|
||||
;; (Ketten, die vor der Einfuehrung der Praeambel-XDATA gebaut wurden).
|
||||
;; Reihenfolge/Arten MUESSEN dem Kopf von vf-linienzug-modus entsprechen:
|
||||
;; PT (Startpunkt), REAL (Starthoehe), STR (AS ja="1"/nein="2") und bei AS
|
||||
;; zusaetzlich STR (Winkel "30"/"90") + STR (Seite links="1"/rechts="2").
|
||||
;; Rueckgabe: Praeambel-Journal oder nil (Abbruch).
|
||||
(defun vfl-praeambel-erfragen ( / p h as w s out)
|
||||
(princ (ssg-text "vfl-restore-keine-praeambel"))
|
||||
(setq p (getpoint (ssg-text "vfl-prompt-startpunkt-kette")))
|
||||
(if (null p)
|
||||
nil
|
||||
(progn
|
||||
(setq h (getreal (ssg-textf "vfl-prompt-hoehe-startpunkt-kette"
|
||||
(list (rtos (caddr p) 2 1)))))
|
||||
(if (null h) (setq h (caddr p)))
|
||||
(initget "Ja Nein")
|
||||
(setq as (getkword (ssg-text "vfl-restore-frage-as")))
|
||||
(if (null as) (setq as "Ja"))
|
||||
(setq out (list (cons "PT" p) (cons "REAL" h)
|
||||
(cons "STR" (if (= as "Nein") "2" "1"))))
|
||||
(if (/= as "Nein")
|
||||
(progn
|
||||
;; gleiche Frage wie im Bau-Ablauf (liefert "30"/"90")
|
||||
(setq w (vf-frage-element-winkel "vf-winkel-aus-header"))
|
||||
(initget "Links Rechts")
|
||||
(setq s (getkword (ssg-text "vfl-restore-frage-as-seite")))
|
||||
(if (null s) (setq s "Links"))
|
||||
(setq out (append out (list (cons "STR" w)
|
||||
(cons "STR" (if (= s "Rechts") "2" "1")))))))
|
||||
out)))
|
||||
|
||||
;; Sektionen aus einer Auswahl sammeln. Rueckgabe: Liste (idx . slice),
|
||||
;; aufsteigend nach idx, jeder Index nur EINMAL (alle Entities eines Gliedes
|
||||
;; tragen dieselbe Slice).
|
||||
(defun vfl-sektionen-sammeln (ss / i n ent seg idx out)
|
||||
(setq out '() i 0 n (sslength ss))
|
||||
(while (< i n)
|
||||
(setq ent (ssname ss i))
|
||||
(setq seg (vfl-journal-xdata-lesen-seg ent))
|
||||
(if seg
|
||||
(progn
|
||||
(setq idx (car seg))
|
||||
(if (not (assoc idx out)) (setq out (cons (cons idx (cdr seg)) out)))))
|
||||
(setq i (1+ i)))
|
||||
(vl-sort out (function (lambda (a b) (< (car a) (car b))))))
|
||||
|
||||
;; Praeambel aus der Auswahl lesen (erstes Entity, das eine traegt).
|
||||
(defun vfl-praeambel-sammeln (ss / i n pre)
|
||||
(setq i 0 n (sslength ss) pre nil)
|
||||
(while (and (< i n) (null pre))
|
||||
(setq pre (vfl-journal-xdata-lesen-pre (ssname ss i)))
|
||||
(setq i (1+ i)))
|
||||
pre)
|
||||
|
||||
(defun c:VF_SEKTION_RESTORE ( / ss sektionen pre journal teile k erwartet luecke
|
||||
i n sek e alt-liste)
|
||||
(princ (ssg-text "vfl-restore-prompt-auswahl"))
|
||||
(setq ss (ssget))
|
||||
(cond
|
||||
((null ss) (princ (ssg-text "vfl-abgebrochen")))
|
||||
((null (setq sektionen (vfl-sektionen-sammeln ss)))
|
||||
(princ (ssg-text "vfl-restore-keine-sektionen")))
|
||||
(t
|
||||
;; Sektionen aneinanderhaengen, solange sie LUECKENLOS ab Glied 1
|
||||
;; anschliessen. Ein Sektions-Record ist mit dem Index seines ERSTEN
|
||||
;; Gliedes abgelegt und kann mehrere Glieder enthalten (VF-Einheit mit
|
||||
;; Vario-Kurven) - der naechste erwartete Index ist daher
|
||||
;; erster-Index + Anzahl der Glieder darin, nicht einfach +1.
|
||||
;; Bei einer Luecke wird nur der Anfang wiederhergestellt: ein fehlendes
|
||||
;; Glied in der Mitte wuerde alle folgenden an die falsche Position setzen.
|
||||
(setq teile '() k 0 erwartet 1 luecke nil)
|
||||
(foreach sek sektionen
|
||||
(if (and (not luecke) (= (car sek) erwartet))
|
||||
(progn
|
||||
(setq teile (cons (cdr sek) teile))
|
||||
(setq k (+ k (vfl-steps-zaehlen (cdr sek))))
|
||||
(setq erwartet (1+ k)))
|
||||
(setq luecke t)))
|
||||
(if luecke
|
||||
(princ (ssg-textf "vfl-restore-luecke" (list (itoa erwartet) (itoa k)))))
|
||||
(if (= k 0)
|
||||
(princ (ssg-text "vfl-restore-keine-sektionen"))
|
||||
(progn
|
||||
;; Praeambel: aus der Zeichnung, sonst erfragen (Altbestand ohne
|
||||
;; SSG_VF_EDIT_PRE).
|
||||
(setq pre (vfl-praeambel-sammeln ss))
|
||||
(if (null pre) (setq pre (vfl-praeambel-erfragen)))
|
||||
(if (null pre)
|
||||
(princ (ssg-text "vfl-abgebrochen"))
|
||||
(progn
|
||||
(setq journal (apply 'append (cons pre (reverse teile))))
|
||||
(princ (ssg-textf "vfl-restore-gefunden"
|
||||
(list (itoa k) (itoa (length journal)))))
|
||||
;; Enames der alten Geometrie merken - geloescht wird ERST nach
|
||||
;; einem erfolgreichen Neuaufbau (siehe unten).
|
||||
(setq alt-liste '() i 0 n (sslength ss))
|
||||
(while (< i n)
|
||||
(setq alt-liste (cons (ssname ss i) alt-liste))
|
||||
(setq i (1+ i)))
|
||||
;; Neu bauen. DIREKTER Aufruf: bricht der Bau ab, wickelt der
|
||||
;; *error*-Handler in vf-linienzug-modus den Zwischenstand zu
|
||||
;; einem Block - und die Zeilen danach (Loeschen) laufen NICHT
|
||||
;; mehr. Die alte Geometrie samt ihrer Sektions-XDATA bleibt also
|
||||
;; erhalten und der Versuch ist wiederholbar.
|
||||
(vfl-journal-replay-start journal)
|
||||
(vf-linienzug-modus)
|
||||
;; Erfolg: alte lose Geometrie entfernen. Sie liegt VOR lastEnt und
|
||||
;; ist deshalb nicht im neuen Block gelandet (vgl.
|
||||
;; vfl-block-erstellen), wuerde aber deckungsgleich darunter
|
||||
;; liegenbleiben.
|
||||
(foreach e alt-liste (if e (entdel e)))
|
||||
(princ (ssg-textf "vfl-restore-geloescht"
|
||||
(list (itoa (length alt-liste)))))))))))
|
||||
(princ))
|
||||
|
||||
;; DCL-Dialog nach Doppelklick: Editier-Modus waehlen.
|
||||
;; n = Anzahl Glieder (nur fuer die Kopfzeile). Vorbelegung "rueck" (das
|
||||
;; bisherige Verhalten, geringste Ueberraschung). Rueckgabe: "rueck", "glied"
|
||||
@@ -5310,9 +5592,13 @@
|
||||
;; dbg-Hook selbst) und uebernehmen das dbgclose gleich mit, sonst wuerde
|
||||
;; bei einem Abbruch ab hier doppelt geschlossen.
|
||||
(setq old-error dbg-old-error)
|
||||
;; *ssg-ils-dim* hier zuruecksetzen - Begruendung siehe gleichlautende Stelle
|
||||
;; im Handler von vf-linienzug-modus (Abbruch kehrt nie zum Aufrufer zurueck,
|
||||
;; der den Override abraeumen wuerde).
|
||||
(setq *error*
|
||||
(function (lambda (msg)
|
||||
(setq *error* old-error)
|
||||
(setq *ssg-ils-dim* nil)
|
||||
(vfl-modus-abbruch-sichern lastEnt vfl-nummer anzahl-gf anzahl-vf
|
||||
startpunkt frame as-seite es-seite "linienzug2")
|
||||
(if dbg-an
|
||||
|
||||
Reference in New Issue
Block a user