diff --git a/Lisp/Gefaellestrecke.lsp b/Lisp/Gefaellestrecke.lsp index 955c84d..641a91b 100644 --- a/Lisp/Gefaellestrecke.lsp +++ b/Lisp/Gefaellestrecke.lsp @@ -993,7 +993,7 @@ aktuell-frame nach-aus-pt gf-nummer last-ent L-gf-str delta-l-gf laengen-liste first-l l-item - bL90 bL60 bL30 bR90 bR60 bR30 n-bogen-gf + bL90 bL60 bL30 bR90 bR60 bR30 ein-hz-as rad-h-as rad-v-as xu-entry sep-endpunkt rad-h-es rad-v-es xu-exit sep-frame es-aus-frame @@ -1312,8 +1312,6 @@ ) ) ) - (setq n-bogen-gf (+ bL90 bL60 bL30 bR90 bR60 bR30)) - ;; delta-l-gf bereits vor der Zusammenfassung berechnet ;; Block mit allen Attributen erstellen. Geruest fuer Einzelmodul/ @@ -1327,7 +1325,9 @@ delta-l-gf L-gf-str grade - (1+ n-bogen-gf) + ;; n-separator/n-scanner = 0: interne Ketten-Separatoren zaehlen nicht; + ;; die echte Anzahl setzt der Export aus platzierten Symbolen. + 0 0 bL90 bL60 bL30 bR90 bR60 bR30 @@ -1386,7 +1386,7 @@ ;; L-first-seg: Laenge der ersten geraden Staustrecke in mm. ;; Beschriftung: Mitte der ersten Geraden, 400mm senkrecht rechts versetzt. (defun gf-make-label (gf-nummer hoehe-von hoehe-bis deltaH deltaL - L-gf-str winkel n-separator nach-aus-pt entry-hz L-first-seg / + L-gf-str winkel nach-aus-pt entry-hz L-first-seg / label-txt label-pt chz-l shz-l halb basis-winkel) (setq chz-l (cos (* entry-hz (/ pi 180.0)))) (setq shz-l (sin (* entry-hz (/ pi 180.0)))) @@ -1401,8 +1401,7 @@ " " delta-sym "H=" (itoa (fix (abs deltaH))) "mm" " " delta-sym "L=" (itoa (fix deltaL)) "mm" " L=[" L-gf-str "]m" - " W=" (rtos (float winkel) 2 2) grad-zeichen - " Sep=" (itoa n-separator))) + " W=" (rtos (float winkel) 2 2) grad-zeichen)) ;; Basiswinkel: Text immer lesbar auf 0 Grad (X-Achse, links->rechts) oder ;; 90 Grad (Y-Achse) einrasten - unabhaengig von der tatsaechlichen ;; Fahrtrichtung (nie 180/270, damit der Text nie auf dem Kopf steht). @@ -1439,7 +1438,7 @@ (if (null geruest-typ) (setq geruest-typ (ssg-geruest-idx-to-typ (ssg-geruest-typ-to-idx nil)))) ;; Beschriftung: Mitte der ersten Geraden, 400mm senkrecht versetzt (gf-make-label gf-nummer hoehe-von hoehe-bis deltaH deltaL - L-gf-str winkel n-separator nach-aus-pt entry-hz L-first-seg) + L-gf-str winkel nach-aus-pt entry-hz L-first-seg) ;; TYP: mit Bogen -> "Streckengruppe"; ohne Bogen (einsegmentig) -> ;; "Gefaellestrecke" (reduzierter Attributsatz, siehe ssg-strecke-attrib-defs). (setq typ-str @@ -1518,6 +1517,12 @@ (cons "GF_Bogen_R_90" (itoa bogen-R90)) (cons "GF_Bogen_R_60" (itoa bogen-R60)) (cons "GF_Bogen_R_30" (itoa bogen-R30)) + ;; ANZAHL_SEPARATOR/ANZAHL_SCANNER werden beim Bau mit 0 vorbelegt + ;; (n-separator/n-scanner werden von den Aufrufern als 0 uebergeben): + ;; der intern gezeichnete Ketten-Separator Staustrecke_Separator_SP zaehlt + ;; NICHT als Separator. Die tatsaechliche Anzahl ermittelt der Export aus + ;; den platzierten Separator_SP/S-LP-/Scanner-Symbolen und schreibt sie + ;; hier hinein (cs-zuordnung-lauf in count_sep_scan.lsp). (cons "ANZAHL_SEPARATOR" (itoa n-separator)) (cons "ANZAHL_SCANNER" (itoa n-scanner)) (cons "GERUEST_EINZELMODUL" geruest-einzelmodul) @@ -1637,7 +1642,9 @@ (float deltaL-total) L-gf-str winkel - 1 0 + ;; n-separator/n-scanner = 0: der interne Ketten-Separator zaehlt nicht; + ;; die echte Anzahl setzt der Export aus platzierten Symbolen (s.o.). + 0 0 0 0 0 0 0 0 startpunkt last-ent nach-aus-pt (float hz) (float L_stau) es-seite geruest-einzelmodul geruest-typ)) diff --git a/Lisp/count_sep_scan.lsp b/Lisp/count_sep_scan.lsp index 160fa51..b61cd7e 100644 --- a/Lisp/count_sep_scan.lsp +++ b/Lisp/count_sep_scan.lsp @@ -10,6 +10,13 @@ ;;; Attribute ANZAHL_SCANNER/ANZAHL_SEPARATOR des jeweiligen ;;; Carrier-Blocks. ;;; +;;; WICHTIG: Gezaehlt werden ausschliesslich die eigenstaendig +;;; platzierten Sensor-Symbole. Der intern in der GF/VF-Kette +;;; gezeichnete 300-mm-Block Staustrecke_Separator_SP ist nur ein +;;; Ketten-/Uebergabestueck (kein eigenstaendiger Separator) und wird +;;; NICHT mitgezaehlt - wer einen Separator gezaehlt haben will, setzt +;;; ein Separator_SP/S-LP-Symbol. +;;; ;;; Zuordnung eines Sensors zu einem Carrier (Z wird ignoriert): ;;; 0. Traegt der Sensor bereits ein ZUORDNUNG-Attribut, wird das ;;; respektiert (nicht ueberschrieben) - er zaehlt mit, wenn die @@ -77,14 +84,6 @@ ;; zugeordneten Carriers geschrieben wird. (setq *zuordnung-tag* "ZUORDNUNG") -;; Blockname-Muster fuer die INTERN im Carrier-Block (in der Kette) -;; gezeichneten Separatoren. Diese bilden einen Teil von -;; ANZAHL_SEPARATOR und werden bei jedem Lauf frisch aus der -;; Blockdefinition gezaehlt (siehe cs-count-nested) - rein LISP- -;; intern, daher (anders als pattern_separator/pattern_scanner) nicht -;; in cfg/export.cfg. -(setq *intern-separator-pattern* "STAUSTRECKE_SEPARATOR_SP*") - ;; Markierung von Sensoren ohne jeglichen Carrier: Kreis auf eigenem Layer. (setq *mark-layer* "S_SENSOR_UNZUGEORDNET") (setq *mark-color* 2) ;; 2 = Gelb @@ -400,35 +399,6 @@ ok ) -;;; ------------------------------------------------------------ -;;; Zaehlt rekursiv, wie oft ein Block (Muster pat) in der -;;; Definition des Blocks bname verwendet wird - inklusive -;;; verschachtelter Unterbloecke. Damit wird die interne Anzahl -;;; der Kette-Separatoren aus der Geometrie ermittelt. -;;; ------------------------------------------------------------ -(defun cs-count-nested (bname pat / e ed nm n stop) - (setq n 0 stop nil) - (setq e (tblobjname "BLOCK" bname)) - (if e - (progn - (setq e (entnext e)) - (while (and e (not stop)) - (setq ed (entget e)) - (cond - ((= (cdr (assoc 0 ed)) "ENDBLK") (setq stop t)) - ((= (cdr (assoc 0 ed)) "INSERT") - (setq nm (cdr (assoc 2 ed))) - (if (wcmatch (strcase nm) pat) - (setq n (1+ n)) - (setq n (+ n (cs-count-nested nm pat))))) - ) - (if (not stop) (setq e (entnext e))) - ) - ) - ) - n -) - ;;; ------------------------------------------------------------ ;;; Attributwert (String) an einem INSERT lesen. "" wenn nicht ;;; vorhanden. Tag ohne Gross/Klein-Unterscheidung. @@ -517,60 +487,82 @@ ;;; Schnelltest: Ist ein vollstaendiger cs-zuordnung-lauf ueberhaupt ;;; noetig? Der eigentliche Lauf ist teuer (vla-getboundingbox + Regen ;;; je Carrier UND je Sensor). Diese Vorpruefung kommt ohne jede -;;; Bounding-Box aus - sie liest nur Attribute (entget) und zaehlt die -;;; internen Ketten-Separatoren aus der Blockdefinition (cs-count-nested, -;;; reine Tabellen-Traversierung, kein Regen). +;;; Bounding-Box aus - sie liest nur Attribute (entget). ;;; ;;; Rueckgabe T (Lauf noetig), wenn EINE der Bedingungen zutrifft: ;;; a) Ein Scanner-/Separator-Symbol hat ein leeres ZUORDNUNG-Attribut -;;; (noch nicht zugeordnet). -;;; b) Die Summe der ANZAHL_SCANNER ueber alle Carrier weicht von der -;;; Anzahl der Scanner-Symbole in der Zeichnung ab. -;;; c) Die Summe der ANZAHL_SEPARATOR ueber alle Carrier weicht von -;;; (Anzahl Separator-Symbole + interne Ketten-Separatoren) ab. -;;; Sonst nil - die vorhandenen Attribute sind konsistent, der teure +;;; (noch nicht zugeordnet) oder ein ZUORDNUNG, das auf keinen +;;; (mehr) existierenden Carrier zeigt. +;;; b) An einem Carrier passt ANZAHL_SCANNER nicht zur Anzahl der ihm +;;; per ZUORDNUNG zugeschriebenen Scanner-Symbole. +;;; c) An einem Carrier passt ANZAHL_SEPARATOR nicht zur Anzahl der ihm +;;; per ZUORDNUNG zugeschriebenen Separator-Symbole (nur platzierte +;;; Symbole zaehlen - dieselbe Regel wie newP im eigentlichen Lauf; +;;; der interne Staustrecke_Separator_SP zaehlt nicht mit). +;;; Sonst nil - die gespeicherten Attribute sind konsistent, der teure ;;; Lauf wird uebersprungen. ;;; -;;; Grenze (bewusst in Kauf genommen): Wird ein Sensor von einem Carrier -;;; zu einem anderen verschoben, OHNE dass sich die GESAMTzahlen aendern -;;; (z.B. ein Scanner von Kreisel A nach Kreisel B), faellt das hier -;;; nicht auf - ZUORDNUNG bleibt ja gesetzt und die Summen stimmen -;;; weiter. In so einem Fall ZAEHLE_SEP_SCAN manuell aufrufen, um die -;;; Zuordnung komplett neu zu berechnen. +;;; Die Zuordnung Symbol->Carrier wird hier billig ueber das bereits +;;; gesetzte ZUORDNUNG-Attribut rekonstruiert (Carrier-ID), OHNE die +;;; teure Boundingbox-/Distanz-Rechnung des eigentlichen Laufs. Dadurch +;;; erkennt der Test - anders als eine reine Gesamtsummen-Pruefung - auch +;;; das Verschieben eines Sensors von einem Carrier zu einem anderen +;;; (die Per-Carrier-Zahl kippt, ZUORDNUNG zeigt aber noch auf den alten). ;;; ------------------------------------------------------------ -(defun cs-zuordnung-noetig-p ( / ss i ent ed nm sk zuord - sumScan sumSep sumIntern nScanSym nSepSym noetig) - (setq sumScan 0 sumSep 0 sumIntern 0 nScanSym 0 nSepSym 0 noetig nil) +(defun cs-zuordnung-noetig-p ( / ss i ent ed nm sk zuord id + carriers carrier-ids sensors s + sepByCarrier scanByCarrier + noetig expScan expSep rec) + (setq noetig nil carriers nil carrier-ids nil sensors nil + sepByCarrier nil scanByCarrier nil) (setq ss (ssget "_X" '((0 . "INSERT")))) (if (null ss) nil ;; keine Bloecke -> nichts zu tun (progn + ;; Pass 1: Carrier (ename . id) und Sensor-Symbole (kind . ZUORDNUNG) + ;; sammeln - die ssget-Reihenfolge ist beliebig, daher erst sammeln, + ;; dann auswerten. (setq i 0) (while (< i (sslength ss)) - (setq ent (ssname ss i)) - (setq ed (entget ent)) - (setq nm (cdr (assoc 2 ed))) + (setq ent (ssname ss i) ed (entget ent) nm (cdr (assoc 2 ed))) (cond ((cs-carrier-p nm) - (setq sumScan (+ sumScan (atoi (cs-get-att-str ent "ANZAHL_SCANNER")))) - (setq sumSep (+ sumSep (atoi (cs-get-att-str ent "ANZAHL_SEPARATOR")))) - (setq sumIntern (+ sumIntern (cs-count-nested nm *intern-separator-pattern*)))) + (setq id (cs-get-att-str ent "ID")) + (setq carriers (cons (cons ent id) carriers)) + (setq carrier-ids (cons id carrier-ids))) (t (setq sk (cs-sensor-kind nm)) (if sk - (progn - (setq zuord (cs-get-att-str ent *zuordnung-tag*)) - (if (or (null zuord) (= zuord "")) (setq noetig T)) - (if (eq sk 'scanner) - (setq nScanSym (1+ nScanSym)) - (setq nSepSym (1+ nSepSym))))) - ) + (setq sensors + (cons (cons sk (cs-get-att-str ent *zuordnung-tag*)) sensors)))) ) (setq i (1+ i)) ) - (or noetig - (/= sumScan nScanSym) - (/= sumSep (+ sumIntern nSepSym))) + ;; Pass 2: Symbole ueber ZUORDNUNG je Carrier-ID zaehlen. Leeres + ;; ZUORDNUNG oder ZUORDNUNG auf einen nicht (mehr) existierenden + ;; Carrier -> Lauf noetig. + (foreach s sensors + (setq sk (car s) zuord (cdr s)) + (cond + ((or (null zuord) (= zuord "")) (setq noetig T)) + ((not (member zuord carrier-ids)) (setq noetig T)) + ((eq sk 'scanner) (setq scanByCarrier (cs-bump scanByCarrier zuord))) + (t (setq sepByCarrier (cs-bump sepByCarrier zuord))) + ) + ) + ;; Pass 3: je Carrier Soll (= zugeschriebene Symbole) gegen die + ;; gespeicherten Attribute pruefen. + (if (not noetig) + (foreach rec carriers + (setq id (cdr rec)) ;; rec = (ename . carrier-id) + (setq expScan (cond ((assoc id scanByCarrier) (cdr (assoc id scanByCarrier))) (t 0))) + (setq expSep (cond ((assoc id sepByCarrier) (cdr (assoc id sepByCarrier))) (t 0))) + (if (or (/= (atoi (cs-get-att-str (car rec) "ANZAHL_SCANNER")) expScan) + (/= (atoi (cs-get-att-str (car rec) "ANZAHL_SEPARATOR")) expSep)) + (setq noetig T)) + ) + ) + noetig ) ) ) @@ -603,7 +595,7 @@ n-strittig n-zuordnung-fehlt s sent spt res mode rec best-d second-rec second-d scanner-id contested handle - en nm2 ns nsep internSep newS newP okS okP eintrag) + en nm2 ns nsep newS newP okS okP eintrag) (setq carriers nil scanlist nil seplist nil n-zuordnung-fehlt 0 n-scan-unassigned 0 n-sep-unassigned 0 n-strittig 0) (setq *cs-scanner-ergaenzt* nil) @@ -734,16 +726,19 @@ (setq nm2 (cdr (assoc 2 (entget en)))) (setq ns (cond ((assoc en scanCounts) (cdr (assoc en scanCounts))) (t 0))) (setq nsep (cond ((assoc en sepCounts) (cdr (assoc en sepCounts))) (t 0))) - ;; interne Kette-Separatoren frisch aus der Blockdefinition zaehlen - (setq internSep (cs-count-nested nm2 *intern-separator-pattern*)) (setq newS ns) - (setq newP (+ internSep nsep)) + ;; ANZAHL_SEPARATOR = nur die tatsaechlich platzierten Separator- + ;; Symbole (Separator_SP/S-LP), die diesem Carrier zugeordnet sind. + ;; Der intern in der GF/VF-Kette gezeichnete 300-mm-Block + ;; Staustrecke_Separator_SP ist nur ein Kettenglied (Foerder-/ + ;; Uebergabestueck), KEIN eigenstaendiger Separator - er wird bewusst + ;; NICHT mitgezaehlt (Entscheidung: nur platzierte Symbole zaehlen). + (setq newP nsep) (setq okS (cs-set-att en (nth 1 rec) (itoa newS))) (setq okP (cs-set-att en (nth 2 rec) (itoa newP))) (if verbose (princ (ssg-textf "sens-carrier-zeile" - (list nm2 (nth 9 rec) (itoa ns) (itoa internSep) (itoa nsep) - (itoa newS) (itoa newP))))) + (list nm2 (nth 9 rec) (itoa newS) (itoa newP))))) (if (not (and okS okP)) (princ (ssg-textf "sens-carrier-fehler" (list nm2)))) ) diff --git a/lang/de_DE.json b/lang/de_DE.json index 9746c61..241b304 100644 --- a/lang/de_DE.json +++ b/lang/de_DE.json @@ -516,7 +516,7 @@ "sens-start": "\n[%1] Pruefe Separator-/Scanner-Zuordnung (ANZAHL_SEPARATOR/ANZAHL_SCANNER)...", "sens-no-inserts": "\n[%1] Keine Bloecke in der Zeichnung gefunden - Sensor-Zuordnung uebersprungen.", "sens-bbox-fehler": "\n ! Bounding-Box fehlgeschlagen fuer ILS-Block '%1'", - "sens-carrier-zeile": "\n %1 [%2]: Scanner(neu)=%3, Separator intern=%4 + manuell=%5 -> ANZAHL_SCANNER=%6, ANZAHL_SEPARATOR=%7", + "sens-carrier-zeile": "\n %1 [%2]: ANZAHL_SCANNER=%3, ANZAHL_SEPARATOR=%4 (nur platzierte Symbole)", "sens-carrier-fehler": "\n FEHLER beim Schreiben der Anzahl-Attribute an %1", "sens-summary": "\n[%1] %2 Kreisel/Streckengruppen/Gefaellestrecken aktualisiert, %3 Scanner gesamt (%4 nicht zuordenbar), %5 Separator gesamt (%6 nicht zuordenbar).", "sens-ergaenzt-header": "\n[%1] %2 Scanner ausserhalb jeder Kreisel-/Strecken-Boundingbox per Abstand automatisch zugeordnet:", diff --git a/lang/en_GB.json b/lang/en_GB.json index 9098337..57d9607 100644 --- a/lang/en_GB.json +++ b/lang/en_GB.json @@ -516,7 +516,7 @@ "sens-start": "\n[%1] Checking separator/scanner assignment (ANZAHL_SEPARATOR/ANZAHL_SCANNER)...", "sens-no-inserts": "\n[%1] No blocks found in the drawing - sensor assignment skipped.", "sens-bbox-fehler": "\n ! Bounding box failed for ILS block '%1'", - "sens-carrier-zeile": "\n %1 [%2]: Scanner(new)=%3, Separator internal=%4 + manual=%5 -> ANZAHL_SCANNER=%6, ANZAHL_SEPARATOR=%7", + "sens-carrier-zeile": "\n %1 [%2]: ANZAHL_SCANNER=%3, ANZAHL_SEPARATOR=%4 (placed symbols only)", "sens-carrier-fehler": "\n ERROR writing the count attributes on %1", "sens-summary": "\n[%1] %2 Kreisel/Streckengruppen/Gefaellestrecken updated, %3 scanners total (%4 unassignable), %5 separators total (%6 unassignable).", "sens-ergaenzt-header": "\n[%1] %2 scanners outside every Kreisel/track bounding box auto-assigned by distance:",