diff --git a/Lisp/export.lsp b/Lisp/export.lsp index 9af5963..7ccfa53 100644 --- a/Lisp/export.lsp +++ b/Lisp/export.lsp @@ -381,6 +381,50 @@ ) ) +;; --- KS-Position eines VF/GF-Wrappers ueber das RICHTIGE Element --- +;; bname = Blockname des VF_n/GF_n-Wrappers. +;; elem-pat = Muster des KS-tragenden Teilbloecks ("AS_ELEMENT*" bzw. +;; "ES_ELEMENT*", Grossschreibung - wcmatch ist unempfindlich). +;; ks-pat = Muster des gesuchten Koordinatensystems ("KS_EIN,KSYS_EIN" +;; bzw. "KS_AUS,KSYS_AUS"). +;; Warum zwei Ebenen: das AS_Element UND das ES_Element eines VF_n fuehren +;; JEWEILS ein KS_EIN UND ein KS_AUS (siehe check_hoehen.lsp ch-measure-vfgf). +;; Ein flaches (ssg-collect-nested-inserts bname "KS_AUS") ueber den GANZEN +;; Wrapper lieferte darum zwei Treffer und (car ...) griff den falschen (den +;; des AS_Elements) - K2/ES landete auf der falschen (Anfangs-)Seite. Darum +;; ERST das passende Element (AS/ES) suchen und NUR IN DESSEN Blockdefinition +;; das KS. Die KS-Position wird durch die Weltlage des Elements (world-pt/ +;; R-world/Skalierung aus dem Element-Record) in das Koordinatensystem der +;; Wrapper-Blockdefinition transformiert - dieselbe Verkettung wie in +;; ssg-collect-nested-inserts-rel (OCS ist in den Records bereits aufgeloest). +;; Rueckgabe: (x y z) im Wrapper-Definitionsframe, oder nil wenn nicht gefunden. +(defun csv:vfgf-ks-loc (bname elem-pat ks-pat / elem-hits elem-rec elem-bname + elem-pt elem-R elem-sx elem-sy elem-sz ks-hits ks-loc + scaled) + (setq elem-hits (ssg-collect-nested-inserts bname elem-pat)) + (if elem-hits + (progn + (setq elem-rec (car elem-hits)) + (setq elem-bname (strcase (cdr (assoc 2 (entget (car elem-rec)))))) + ;; Nur das KS INNERHALB dieser Element-Blockdefinition (nicht im Wrapper). + (setq ks-hits (ssg-collect-nested-inserts elem-bname ks-pat)) + (if ks-hits + (progn + (setq elem-pt (cadr elem-rec)) + (setq elem-R (caddr elem-rec)) + (setq elem-sx (nth 3 elem-rec) elem-sy (nth 4 elem-rec) elem-sz (nth 5 elem-rec)) + (setq ks-loc (cadr (car ks-hits))) ;; KS-Pos im Element-Frame + (setq scaled (list (* elem-sx (car ks-loc)) + (* elem-sy (cadr ks-loc)) + (* elem-sz (caddr ks-loc)))) + ;; Element-Weltlage (im Wrapper-Frame) + rotierte KS-Position. + (mapcar '+ elem-pt (mat3-mul-vec3 elem-R scaled)) + ) + ) + ) + ) +) + ;; --- K1 (AS/KS_EIN) / K2 (ES/KS_AUS) eines VF_n/GF_n-Wrappers ableiten --- ;; ename = Entity-Name des platzierten VF_n/GF_n-INSERT. ;; pt/rot-rad = Welt-Einfuegepunkt/-Rotation (radiant) des Wrappers (siehe @@ -388,43 +432,42 @@ ;; VF/GF-Wrapper fuehren - anders als Omniflo-Boegen - KEINE direkten K1-K4- ;; oder KS-Sub-INSERTs; ihre Streckenenden stecken je EINE Ebene tiefer: ;; KS_EIN im AS_Element*, KS_AUS im ES_Element* (siehe check_hoehen.lsp, -;; extract-ks-from-block-raw). ssg-collect-nested-inserts findet diese -;; verschachtelten INSERTs mit ihrer Platzierung RELATIV zur Wrapper- -;; Blockdefinition (ename/(x y z)/... - der zweite Eintrag ist der Ursprung -;; des KS-INSERTs, also die AS-/ES-Position). Der lokale Punkt wird ueber die -;; Wrapper-Weltlage (reine Z-Drehung) in Weltkoordinaten gedreht und wie K1-K4 -;; als reiner Positions-String (csv:trans-encode) exportiert. Damit hat auch -;; eine Strecke K1 (AS) und K2 (ES) fuer die Python-Kollisionspruefung -;; (export_neighbors.py: Schleuselemente + Kreisel-Kollision ueber die AS/ES- -;; Position mit fester BBox statt der ganzen Wrapper-Box). +;; extract-ks-from-block-raw). csv:vfgf-ks-loc holt die KS-Position aus dem +;; JEWEILS zugehoerigen Element (nicht flach aus dem ganzen Wrapper - beide +;; Elemente tragen beide KS-Typen). Der so ermittelte Punkt (Wrapper-Frame) +;; wird ueber die Wrapper-Weltlage (reine Z-Drehung) in Weltkoordinaten +;; gedreht und wie K1-K4 als reiner Positions-String (csv:trans-encode) +;; exportiert. Damit hat auch eine Strecke K1 (AS) und K2 (ES) fuer die +;; Python-Kollisionspruefung (export_neighbors.py: Schleuselemente + +;; Kreisel-Kollision ueber die AS/ES-Position mit fester BBox statt der +;; ganzen Wrapper-Box). ;; Rueckgabe wie csv:get-k-kos-strings: (("K1" . str) ("K2" . str)) - nur die ;; tatsaechlich gefundenen Enden. -(defun csv:vfgf-k-kos-strings (ename pt rot-rad / ed bname as-hits es-hits result - loc world) +(defun csv:vfgf-k-kos-strings (ename pt rot-rad / ed bname loc world result) (setq ed (entget ename)) (setq bname (cdr (assoc 2 ed))) (setq result nil) - ;; KS-INSERTs (KS_EIN/KS_AUS bzw. KSYS_-Varianten) direkt im AS_Element/ - ;; ES_Element suchen. wcmatch ist Gross/Klein-unempfindlich fuer Blocknamen. - (setq as-hits (ssg-collect-nested-inserts bname "KS_EIN,KSYS_EIN")) - (setq es-hits (ssg-collect-nested-inserts bname "KS_AUS,KSYS_AUS")) - (if as-hits + ;; K1 = KS_EIN aus dem AS_Element, K2 = KS_AUS aus dem ES_Element. Die + ;; Element-Zuordnung ist zwingend (jedes Element traegt beide KS-Typen, + ;; siehe csv:vfgf-ks-loc). Ergebnis-Frame -> Weltlage ueber die reine + ;; Z-Drehung des Wrappers (csv:local-to-world). + (setq loc (csv:vfgf-ks-loc bname "AS_ELEMENT*" "KS_EIN,KSYS_EIN")) + (if loc (progn - (setq loc (cadr (car as-hits))) (setq world (csv:local-to-world pt rot-rad loc)) (setq result (cons (cons "K1" (csv:trans-encode (car world) (cadr world) (caddr world))) result)) ) ) - (if es-hits + (setq loc (csv:vfgf-ks-loc bname "ES_ELEMENT*" "KS_AUS,KSYS_AUS")) + (if loc (progn - (setq loc (cadr (car es-hits))) (setq world (csv:local-to-world pt rot-rad loc)) (setq result (cons (cons "K2" (csv:trans-encode (car world) (cadr world) (caddr world))) result)) ) ) - result + (reverse result) )