feat: Kettenfoerderer (Schraegfoerderer Stahl) als parametrische 3D-Baugruppe
Neues Modul KettenFoerderer.lsp: baut aus KF_UM_<winkel>, KF_LAENGE und KF_AN_<winkel> (je KS_AUS auf KS_EIN) plus der Draufsicht KF_2D einen Block KF_<n>. Die Bausteine werden aufgerichtet eingebaut (Rz*Rx(90)*Rz), die Hoehe laeuft in Z; KF_2D liegt deckungsgleich mit der Kette. Der Einbauwinkel jedes Folgebausteins wird aus der Richtung des KS_AUS seines Vorgaengers gemessen, KF_LAENGE ueber die Einbauhoehe skaliert. - Dialog (DCL-Vorlage, Typ als Radiobuttons), Hoehe per Zahl oder aus zwei Punkten, Doppelklick auf KF_n oeffnet KF_EDIT mit Neuaufbau - eigenstaendiges Attribut-Schema, Auswahllisten mit Sivas-Optionstexten in data/json/kettenfoerderer.json - Sivas-Export: Merkmale 350, 353-357, 359-361, 391, baugleiche Foerderer werden zu einer Zeile zusammengefasst (Artikelnummer 6120) - ssg_ks_insert.lsp: neue Primitiven ks-xy-winkel, ks-block-messen, insert-block-ks-skaliert und insert-block-ks-matrix (freie 3x3-Rotation); ensure-block-loaded nimmt Bloecke ohne Dimensionssuffix unveraendert - Menueeintrag KettenFoerderer aktiviert, toter Dummy OMNI_KettenFoerderer entfernt; KF_* im Export-Pattern, in der ID-Vergabe und im Dispatcher SSG_BLOCKEDIT (vor dem Omniflo-Zweig) - Unit-Tests tu-tests-kf fuer die reinen Rechenkerne; Modul wird in der MNL vorgeladen, dbg-Schalter kf-zeit zur Laufzeitmessung Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1538,10 +1538,12 @@
|
||||
)
|
||||
|
||||
;; --- Omniflo / KettenFoerderer ---
|
||||
(defun c:OMNI_KettenFoerderer ()
|
||||
(princ "\n[DUMMY] KettenFoerderer")
|
||||
(princ)
|
||||
)
|
||||
;; Der Platzhalter c:OMNI_KettenFoerderer (reiner Dummy, gab nur "[DUMMY]
|
||||
;; KettenFoerderer" aus und war im Menue ausgegraut) wurde entfernt: der
|
||||
;; Kettenfoerderer ist seit 2026-10-22 als eigene Baugruppe umgesetzt, der
|
||||
;; Menueeintrag zeigt jetzt auf (ssg-ensure "KettenFoerderer") KETTENFOERDERER
|
||||
;; (Lisp/KettenFoerderer.lsp). Damit war der Dummy toter Code - auf ihn verwies
|
||||
;; nur noch der Menueeintrag selbst.
|
||||
|
||||
|
||||
;; --- Omniflo / Ladeschleifen ---
|
||||
|
||||
+7
-4
@@ -38,14 +38,13 @@ am Label-Anfang, bei Submenue-Schliessern hinter dem `<-` (`[<-~Label]`).
|
||||
|
||||
| Menuebereich | Eintraege | Definiert in |
|
||||
| --- | --- | --- |
|
||||
| Omniflo ▸ Anbaugruppen | `OMNI_KettenFoerderer` | `OmniModulInsert.lsp` |
|
||||
| Omniflo ▸ Boegen fuer Weichen | alle `OMNI_APBW_*` (14) | `OmniModulInsert.lsp` |
|
||||
| ILS ▸ Zusatzmodule/Kurven | `ILS_ETF_Etagenfoerderer`, `ILS_K{90,60,30}{L,R}{A,I}` (12), `ILS_Gefaellestrecke` | `SSG_LIB_Commands.lsp` |
|
||||
| Geruest | `GERUEST` (Gattertraeger-Platzhalter, derselbe Befehl wie Saeulen/Rohrabhaenger/Wandbefestigung) | `GeruestInsert.lsp` |
|
||||
|
||||
`OMNI_TEF_*` (UmlenkR/L, AntriebL/R, TEF Gerade) sind entgegen frueherem Stand
|
||||
**implementiert** (echtes `omni:insert-dxf`), nur `OMNI_KettenFoerderer` ist
|
||||
weiterhin Dummy.
|
||||
**implementiert** (echtes `omni:insert-dxf`). Der Menueeintrag KettenFoerderer ist
|
||||
ebenfalls aktiv (Modul `KettenFoerderer.lsp`, Beschreibung in `CLAUDE.md`).
|
||||
|
||||
Aktiv (implementiert) sind u.a.: Kreisel, Eckrad, VarioFoerderer (Standard/Etage/
|
||||
Linienzug), Gefaellestrecke, Geruest (Saeulen/Rohrabhaenger/Wandbefestigung/
|
||||
@@ -383,6 +382,10 @@ Gefaellestrecke/`vf_core` geladen sein; Kern-Modul.
|
||||
| `extract-ks-from-block[-raw] name` | KS_EIN/KS_AUS-Punkte eines Blocks ermitteln (Cache `*ks-cache*`) |
|
||||
| `insert-block-by-ks name ks-nr pt` | Block anhand KS-Punkt einfuegen (nur Rz-Rotation) |
|
||||
| `insert-inclined-scaled-block` / `insert-rotated-block-with-ks` | Geneigten/rotierten Block mit KS-Offset einfuegen (Rz*Ry) |
|
||||
| `ks-xy-winkel ks-eintrag` | Richtung der X-Achse eines KS in der XY-Ebene (Grad); `nil` bei senkrechter Achse |
|
||||
| `ks-block-messen name` / `ks-versatz ks-data` | KS eines Blocks messen, ohne bleibende Einfuegung / Versatz KS_AUS-KS_EIN |
|
||||
| `insert-block-ks-skaliert name pt hz skala` | Wie `insert-block-by-ks`, zusaetzlich in X skaliert |
|
||||
| `insert-block-ks-matrix name pt R skala` | Einfuegen mit **freier 3x3-Rotationsmatrix** (`ks-rot-x/-y/-z`), z.B. fuer aufgerichtete Baugruppen |
|
||||
|
||||
---
|
||||
|
||||
@@ -701,7 +704,7 @@ AutoLISP-Implementierung fuer alle Omniflo-Komponenten: Boegen, Weichen, Verbind
|
||||
| Geraden | `OMNI_AP60`, `OMNI_AP110`, `OMNI_APG110` | Omniflo-Geradenstuecke |
|
||||
| Ladeschleifen | `OMNI_LADESCHLEIFE_AP110` | Ladeschleife aus `omniflo_ladeschleifen.json` ueber DCL-Dialog (`dcl/omniflo_ladeschleifen.dcl`) einfuegen; Daten per `ssg-json-laden` (Beschreibungen enthalten Kommas). Blockdatei `<Sivasnr>.dwg` unter `DXFM_OMNIFLO` (`omni:insert-dxf` faellt auf `.dwg` zurueck, wenn keine `.dxf` existiert). Per `OMNI_EDIT` editierbar |
|
||||
| TEF Elemente | `OMNI_TEF_UmlenkR/L`, `OMNI_TEF_AntriebL/R`, `OMNI_TEF_Gerade` | Feste TEF-Bauteile ohne Sivas-Auswahl, direkt per `omni:insert-dxf` an gewaehltem Punkt eingefuegt (Dateien unter `DXFM_OMNIFLO`) |
|
||||
| Anbaugruppen ⚠️ | `OMNI_KettenFoerderer` | **Dummy** (noch nicht implementiert, im Menue ausgegraut); `OMNI_STOPPER`/`OMNI_SCANNER`/`OMNI_BUERSTENBREMSE` sind implementiert |
|
||||
| Anbaugruppen | `OMNI_STOPPER`, `OMNI_SCANNER`, `OMNI_BUERSTENBREMSE` | Implementiert |
|
||||
| Verbinder | `OMNI_TV_*` | Verbinder-DWG aus `data/omniflo/Verbinder` (dimensionsunabhaengig, `omni:insert-verbinder` -> `omni:insert-datei`, Punkt + Drehung interaktiv). Zuordnung Befehl -> DWG nach Dateiname, z.B. `OMNI_TV_W_AP60` -> `TV_W-AP60_oben`, `OMNI_TV_ENDPLATTE` -> `VB_ENDP_AP`, `OMNI_TV_W_AP60_KPL` -> `TV_W-AP60_kpl`, `OMNI_TV_ANSCHLAG` -> `VB_ENDP_AP_Spulenzug`, `OMNI_TV_SW_I_AP110` -> `TV_SW_I_SW-AP110`, `OMNI_TV_MUFFE` -> `VB_Muffe`. Alle 18 Eintraege aktiv |
|
||||
| Bogenweichen ⚠️ | `OMNI_APBW_*` | **Dummy** (noch nicht implementiert, im Menue ausgegraut) |
|
||||
| Bearbeiten | `OMNI_EDIT` | Omniflo-Block selektieren und Attribute bearbeiten |
|
||||
|
||||
@@ -408,6 +408,24 @@
|
||||
(command "_.EATTEDIT")
|
||||
)
|
||||
|
||||
;; Kettenfoerderer (KF_n, KettenFoerderer.lsp) -> KF_EDIT (DCL-Dialog mit
|
||||
;; Neuaufbau an derselben Stelle). MUSS - aus demselben Grund wie GR_* -
|
||||
;; vor dem Omniflo-Zweig stehen: traegt die Baugruppe ein TEILEART-
|
||||
;; Attribut, wuerde dort sonst der Omniflo-Elementdialog aufgehen.
|
||||
((wcmatch bname "KF_*")
|
||||
(princ (ssg-textf "cmd-kettenfoerderer-bearbeiten" (list bname)))
|
||||
(if (and (null *ssg-KettenFoerderer-loaded*) (atoms-family 1 '("SSG-ENSURE")))
|
||||
(ssg-ensure "KettenFoerderer")
|
||||
)
|
||||
(if (atoms-family 1 '("C:KF_EDIT"))
|
||||
(c:KF_EDIT)
|
||||
(progn
|
||||
(princ (ssg-textf "tro-edit-modul-fehlt" (list "KettenFoerderer.lsp")))
|
||||
(command "_.EATTEDIT")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; Omniflo-Bloecke -> OMNI_EDIT
|
||||
;; Erkennung: TEILEART-Attribut vorhanden, AP110-Blockname oder rein numerisch
|
||||
((progn
|
||||
|
||||
@@ -2397,6 +2397,11 @@
|
||||
;; VB_*/TV_* = Omniflo-Verbinder (siehe pattern_verbinder in
|
||||
;; cfg/export.cfg, OMNI_TV_* in OmniModulInsert.lsp). export_sivas.py
|
||||
;; fuehrt sie ueber TEILEART/ARTINR im allgemeinen Omniflo-Zweig.
|
||||
;; KF_* = Kettenfoerderer/Schraegfoerderer Stahl (siehe
|
||||
;; pattern_kettenfoerderer in cfg/export.cfg, KettenFoerderer.lsp). Wie
|
||||
;; GR_* eine selbst zusammengebaute Baugruppe mit eigenen Attributen
|
||||
;; (TEILEART/ARTINR), darum eigenstaendig gesammelt - die drei Bausteine
|
||||
;; darin werden NICHT einzeln gezaehlt.
|
||||
;; Bloecke auf GEFRORENEN Layern (und die Hilfsobjekte gefrorener VF_n/GF_n)
|
||||
;; werden ausgelassen, solange *csv-gefrorene-ausschliessen* an ist (Standard,
|
||||
;; Dialog CSV_EXPORT_KONFIG); ausgeschaltete Layer zaehlen nicht als gefroren.
|
||||
@@ -2449,6 +2454,7 @@
|
||||
(wcmatch bname (export:pattern "pattern_ausgang" "Ausgang*"))
|
||||
(wcmatch bname (export:pattern "pattern_geruest" "GR_*"))
|
||||
(wcmatch bname (export:pattern "pattern_verbinder" "VB_*,TV_*"))
|
||||
(wcmatch bname (export:pattern "pattern_kettenfoerderer" "KF_*"))
|
||||
(wcmatch bname (export:pattern "pattern_unit_marker" "ZZ_UNIT_MARKER*"))
|
||||
;; Rein numerische Namen = Omniflo SivasNr (Boegen/Weichen)
|
||||
;; Rein LISP-intern (Python klassifiziert Omniflo stattdessen
|
||||
|
||||
+5
-1
@@ -86,8 +86,12 @@
|
||||
;; Einheiten-Proxies selbst ab; Separator-/Element-
|
||||
;; Kopien sammeln sich dagegen an - Zeichnung mit
|
||||
;; eingeschaltetem Schalter nicht speichern.
|
||||
;; kf-zeit - Zwischenzeiten beim Aufruf von KETTENFOERDERER
|
||||
;; (Daten lesen / Dialogaufbau), siehe kf-zeit in
|
||||
;; KettenFoerderer.lsp. Standard 0 - nur einschalten,
|
||||
;; wenn der Dialog spuerbar verzoegert erscheint.
|
||||
;; ------------------------------------------------------------
|
||||
(foreach nm '(("vf-sepliste" . 1) ("csv_leave_proxies" . 0))
|
||||
(foreach nm '(("vf-sepliste" . 1) ("csv_leave_proxies" . 0) ("kf-zeit" . 0))
|
||||
(if (not (assoc (car nm) *dbg-schalter*))
|
||||
(setq *dbg-schalter* (cons nm *dbg-schalter*))))
|
||||
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
;; das ID-ATTDEF steht seit *geruest-attrib-defs* zur Verfuegung.
|
||||
;; VB_*/TV_* (Omniflo-Verbinder, siehe pattern_verbinder in
|
||||
;; cfg/export.cfg) ebenso - fest im Code wie GR_*.
|
||||
;; KF_* (Kettenfoerderer, siehe pattern_kettenfoerderer in cfg/export.cfg,
|
||||
;; KettenFoerderer.lsp) ebenso - das ID-ATTDEF kommt aus kf-attrib-defs, das
|
||||
;; auf dem gemeinsamen Strecken-Schema aufsetzt und darum ID bereits fuehrt.
|
||||
;; Gefaellebogen_* (siehe pattern_nested_bogen in cfg/export.cfg): einer der
|
||||
;; Bausteine einer GF-Kette, verpackt in VF_n/GF_n; wird beim Export ebenso
|
||||
;; als temporaere Kopie ausgepackt wie die uebrigen Vario_*/Staustrecke_*-
|
||||
@@ -84,6 +87,7 @@
|
||||
(wcmatch bname "Eingang*,Ausgang*")
|
||||
(wcmatch bname "GR_*")
|
||||
(wcmatch bname "VB_*,TV_*")
|
||||
(wcmatch bname "KF_*")
|
||||
(wcmatch bname "#*")
|
||||
)
|
||||
(ssadd ename ss-out)
|
||||
|
||||
+283
-4
@@ -72,11 +72,31 @@
|
||||
;; Block unter seinem effektiven, dim-suffigierten Namen und GIBT DIESEN ZURUECK,
|
||||
;; damit Aufrufer ihn zum Einfuegen (vla-InsertBlock/tblsearch) verwenden.
|
||||
;; Meldung nur bei Fehlschlag.
|
||||
(defun ensure-block-loaded (blockname / )
|
||||
(if (not (ssg-ils-block-laden blockname))
|
||||
(princ (ssg-textf "vfc-fehler-block-datei-fehlt" (list blockname)))
|
||||
;; Sonderfall Bloecke OHNE Dimensionssuffix (data/omniflo/<Dim>/, z.B. die
|
||||
;; Kettenfoerderer-Bausteine): ssg-ils-blockname wuerde "KF_UM_26" zu
|
||||
;; "KF_UM_26_2D" machen - das ist die Konvention der FLACHEN Ablage data/ils,
|
||||
;; die Omniflo-Ordner arbeiten stattdessen mit getrennten Verzeichnissen und
|
||||
;; unsuffigierten Namen. Liegt die Definition unter dem Rohnamen bereits in
|
||||
;; der Zeichnung und gibt es KEINE suffigierte Variante, wird der Rohname
|
||||
;; unveraendert verwendet. Die Bedingung ist bewusst eng gefasst (BEIDE Teile
|
||||
;; muessen zutreffen), damit die Dim-Aufloesung fuer alle data/ils-Bloecke
|
||||
;; unberuehrt bleibt: dort existiert die suffigierte Variante, sobald der
|
||||
;; Block geladen ist, und der erste Zweig greift nie.
|
||||
;; Realer Fehler, den das behebt: die KS-Messung eines KF-Bausteins lief ins
|
||||
;; Leere und meldete "KS_EIN/KS_AUS fehlt", obwohl beide KS im Block vorhanden
|
||||
;; waren - gesucht wurde nur ein Blockname, den es nicht gibt.
|
||||
(defun ensure-block-loaded (blockname / eff)
|
||||
(setq eff (ssg-ils-blockname blockname))
|
||||
(if (and (not (tblsearch "BLOCK" eff))
|
||||
(tblsearch "BLOCK" blockname))
|
||||
blockname
|
||||
(progn
|
||||
(if (not (ssg-ils-block-laden blockname))
|
||||
(princ (ssg-textf "vfc-fehler-block-datei-fehlt" (list blockname)))
|
||||
)
|
||||
eff
|
||||
)
|
||||
)
|
||||
(ssg-ils-blockname blockname)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
@@ -379,6 +399,265 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; KS-ORIENTIERUNG + SKALIERTE KS-EINFUEGUNG
|
||||
;; ------------------------------------------------------------
|
||||
;; Ergaenzt fuer den Kettenfoerderer (KettenFoerderer.lsp): dort ist die
|
||||
;; Neigung KEIN freier Parameter, sondern steckt fest in der Geometrie der
|
||||
;; Blockvarianten (KF_UM_26 gegen KF_UM_30). Der Einbauwinkel eines
|
||||
;; Folgebausteins ergibt sich darum aus der RICHTUNG des KS_AUS seines
|
||||
;; Vorgaengers. Dafuer reicht der bisher allein ausgewertete KS-URSPRUNG
|
||||
;; nicht - die X-Achse des KS muss mit gelesen werden. extract-ks-from-block
|
||||
;; liefert sie als (origin x-end y-end z-end) bereits mit, sie wurde bislang
|
||||
;; nur von keinem Aufrufer genutzt.
|
||||
|
||||
;; Winkel der X-Achse eines KS-Eintrags in der XY-Ebene, in Grad (-180..180).
|
||||
;; ks-eintrag = (origin x-end y-end z-end), also genau der cadr-Teil eines
|
||||
;; extract-ks-from-block-Ergebnisses. Rueckgabe nil, wenn die X-Achse keine
|
||||
;; XY-Laenge hat (senkrecht stehendes KS) oder der Eintrag unbrauchbar ist.
|
||||
(defun ks-xy-winkel (ks-eintrag / org xend dx dy)
|
||||
(if (and ks-eintrag (listp ks-eintrag) (>= (length ks-eintrag) 2)
|
||||
(listp (car ks-eintrag)) (listp (cadr ks-eintrag)))
|
||||
(progn
|
||||
(setq org (car ks-eintrag) xend (cadr ks-eintrag))
|
||||
(setq dx (- (car xend) (car org))
|
||||
dy (- (cadr xend) (cadr org)))
|
||||
(if (< (+ (* dx dx) (* dy dy)) 1e-12)
|
||||
nil
|
||||
(/ (* 180.0 (atan dy dx)) pi)))
|
||||
nil))
|
||||
|
||||
;; Winkel auf -180..180 Grad normalisieren. Reiner Rechenkern.
|
||||
(defun ks-winkel-normalisieren (w)
|
||||
(if (null w)
|
||||
nil
|
||||
(progn
|
||||
(setq w (float w))
|
||||
(while (> w 180.0) (setq w (- w 360.0)))
|
||||
(while (<= w -180.0) (setq w (+ w 360.0)))
|
||||
w)))
|
||||
|
||||
;; Lokalen KS_AUS-KS_EIN-Versatz eines Blocks als (dx dy dz) liefern.
|
||||
;; ks-data = Ergebnis von extract-ks-from-block/ks-block-messen.
|
||||
;; Rueckgabe nil, wenn eines der beiden KS fehlt.
|
||||
(defun ks-versatz (ks-data / ein aus)
|
||||
(setq ein (cadr (assoc "KS_EIN" ks-data))
|
||||
aus (cadr (assoc "KS_AUS" ks-data)))
|
||||
(if (and ein aus)
|
||||
(list (- (car (car aus)) (car (car ein)))
|
||||
(- (cadr (car aus)) (cadr (car ein)))
|
||||
(- (caddr (car aus)) (caddr (car ein))))
|
||||
nil))
|
||||
|
||||
;; Misst KS_EIN/KS_AUS eines Blocks, ohne eine bleibende Einfuegung zu
|
||||
;; hinterlassen: der Block wird bei Massstab 1 am Ursprung eingefuegt,
|
||||
;; vermessen und wieder geloescht. extract-ks-from-block cached das Ergebnis
|
||||
;; je Blockname, der zweite Aufruf kostet also nichts mehr.
|
||||
;; Rueckgabe wie extract-ks-from-block (Blockkoordinaten), sonst nil.
|
||||
(defun ks-block-messen (blockname / eff temp-obj daten)
|
||||
(setq eff (ensure-block-loaded blockname))
|
||||
(if (tblsearch "BLOCK" eff)
|
||||
(progn
|
||||
(setq temp-obj (vla-InsertBlock modelspace
|
||||
(vlax-3D-point '(0 0 0)) eff 1.0 1.0 1.0 0))
|
||||
(setq daten (extract-ks-from-block temp-obj))
|
||||
(if (not (vlax-erased-p temp-obj)) (vla-Delete temp-obj))
|
||||
daten)
|
||||
nil))
|
||||
|
||||
;; --- Block per KS_EIN/KS_AUS einfuegen, in X SKALIERT (nur Rz-Rotation) ---
|
||||
;; Wie insert-block-by-ks, zusaetzlich mit X-Massstab skala - fuer laengen-
|
||||
;; variable Zwischenstuecke (Kettenfoerderer KF_LAENGE, dieselbe Rolle wie
|
||||
;; die Staustrecke beim VarioFoerderer). Die lokalen KS-Punkte werden VOR der
|
||||
;; Rotation in X mitskaliert; nur so liegt KS_EIN exakt auf einfuegepunkt und
|
||||
;; der zurueckgegebene KS_AUS traegt den skalierten Versatz.
|
||||
;; Rueckgabe: Weltpunkt von KS_AUS (fuer die Verkettung), sonst einfuegepunkt.
|
||||
(defun insert-block-ks-skaliert (blockname einfuegepunkt hz skala /
|
||||
block-obj ks-data ks-ein ks-aus rad-h chv shv
|
||||
ein-x ein-y ein-z aus-x dx-loc dy-loc dz-loc
|
||||
offset ausgang)
|
||||
(if (or (null einfuegepunkt) (not (listp einfuegepunkt)))
|
||||
(progn
|
||||
(princ (ssg-textf "vfc-fehler-ungueltiger-einfuegepunkt" (list blockname)))
|
||||
(exit))
|
||||
)
|
||||
(if (or (null skala) (<= skala 0.0)) (setq skala 1.0))
|
||||
(setq blockname (ensure-block-loaded blockname))
|
||||
(if (not (tblsearch "BLOCK" blockname))
|
||||
(progn
|
||||
(princ (ssg-textf "vfc-fehler-block-nicht-in-bibliothek-abgebrochen" (list blockname)))
|
||||
(exit))
|
||||
)
|
||||
(princ (ssg-textf "vfc-fuege-block-ein-hz" (list blockname (rtos (float hz) 2 1) (chr 176))))
|
||||
(setq rad-h (* (float hz) (/ pi 180.0)))
|
||||
(setq chv (cos rad-h) shv (sin rad-h))
|
||||
;; KS am UNSKALIERTEN Block messen (der Cache arbeitet je Blockname), die
|
||||
;; lokalen Punkte danach selbst in X skalieren.
|
||||
(setq ks-data (ks-block-messen blockname))
|
||||
(setq ks-ein (cadr (assoc "KS_EIN" ks-data)))
|
||||
(setq ks-aus (cadr (assoc "KS_AUS" ks-data)))
|
||||
(setq block-obj (vla-InsertBlock modelspace
|
||||
(vlax-3D-point '(0 0 0))
|
||||
blockname skala 1.0 1.0 0))
|
||||
(ssg-ils-block-auf-ebene block-obj blockname)
|
||||
(if (> (abs hz) 0.0001)
|
||||
(vla-TransformBy block-obj (vlax-tmatrix
|
||||
(list (list chv (- shv) 0 0)
|
||||
(list shv chv 0 0)
|
||||
(list 0 0 1 0)
|
||||
(list 0 0 0 1))))
|
||||
)
|
||||
(if (and ks-ein ks-aus)
|
||||
(progn
|
||||
(setq ein-x (* skala (car (car ks-ein)))
|
||||
ein-y (cadr (car ks-ein))
|
||||
ein-z (caddr (car ks-ein)))
|
||||
(setq aus-x (* skala (car (car ks-aus))))
|
||||
(setq offset (list
|
||||
(- (car einfuegepunkt) (- (* chv ein-x) (* shv ein-y)))
|
||||
(- (cadr einfuegepunkt) (+ (* shv ein-x) (* chv ein-y)))
|
||||
(- (caddr einfuegepunkt) ein-z)))
|
||||
(vla-Move block-obj
|
||||
(vlax-3D-point '(0 0 0))
|
||||
(vlax-3D-point offset))
|
||||
(setq dx-loc (- aus-x ein-x))
|
||||
(setq dy-loc (- (cadr (car ks-aus)) ein-y))
|
||||
(setq dz-loc (- (caddr (car ks-aus)) ein-z))
|
||||
(setq ausgang (list
|
||||
(+ (car einfuegepunkt) (- (* chv dx-loc) (* shv dy-loc)))
|
||||
(+ (cadr einfuegepunkt) (+ (* shv dx-loc) (* chv dy-loc)))
|
||||
(+ (caddr einfuegepunkt) dz-loc)))
|
||||
(ssg-sepliste-dbg
|
||||
(strcat "insert-block-ks-skaliert " blockname
|
||||
" hz=" (rtos (float hz) 2 2) " skala=" (rtos (float skala) 2 4)
|
||||
" einfuegepunkt=" (ssg-sepliste-dbg-pt einfuegepunkt)
|
||||
" offset(=Gruppencode 10)=" (ssg-sepliste-dbg-pt offset)
|
||||
" ausgang=" (ssg-sepliste-dbg-pt ausgang)))
|
||||
(princ (ssg-textf "vfc-ks-aus-xyz"
|
||||
(list (rtos (car ausgang) 2 2) (rtos (cadr ausgang) 2 2) (rtos (caddr ausgang) 2 2))))
|
||||
ausgang
|
||||
)
|
||||
(progn
|
||||
(princ (ssg-text "vfc-warnung-ks-nicht-gefunden"))
|
||||
einfuegepunkt
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; FREI ROTIERTE KS-EINFUEGUNG (beliebige 3x3-Matrix)
|
||||
;; ------------------------------------------------------------
|
||||
;; Verallgemeinerung von insert-block-by-ks/insert-block-ks-skaliert: statt
|
||||
;; einer festen Rz- bzw. Rz*Ry-Drehung nimmt sie eine FERTIGE 3x3-Rotations-
|
||||
;; matrix entgegen. Noetig geworden fuer AUFRECHT eingebaute Baugruppen: der
|
||||
;; Kettenfoerderer ist in der XY-Ebene gezeichnet (X = Fahrtrichtung,
|
||||
;; Y = Hoehe), soll aber im Modell stehen - seine Hoehe muss also nach Z. Das
|
||||
;; ist eine Drehung um X, die weder insert-block-by-ks (nur Rz) noch
|
||||
;; ssg-rot-matrix-zy (Rz*Ry) erzeugen kann.
|
||||
;;
|
||||
;; Bewusst matrixbasiert statt mit einem weiteren Winkelparameter: die
|
||||
;; Aufrichtung ist nur EIN Anwendungsfall, und jeder weitere haette eine
|
||||
;; weitere Spezialfunktion gebraucht. Den Aufrufern bleibt freigestellt,
|
||||
;; welche Drehungen sie kombinieren (beim Kettenfoerderer
|
||||
;; Rz(basis) * Rx(90) * Rz(eigen), siehe kf-matrix-aufrecht).
|
||||
|
||||
;; Elementare Rotationsmatrizen (3x3, Winkel in GRAD).
|
||||
(defun ks-rot-x (grad / r c s)
|
||||
(setq r (* (float grad) (/ pi 180.0)) c (cos r) s (sin r))
|
||||
(list (list 1.0 0.0 0.0)
|
||||
(list 0.0 c (- s))
|
||||
(list 0.0 s c )))
|
||||
|
||||
(defun ks-rot-y (grad / r c s)
|
||||
(setq r (* (float grad) (/ pi 180.0)) c (cos r) s (sin r))
|
||||
(list (list c 0.0 s )
|
||||
(list 0.0 1.0 0.0)
|
||||
(list (- s) 0.0 c )))
|
||||
|
||||
(defun ks-rot-z (grad / r c s)
|
||||
(setq r (* (float grad) (/ pi 180.0)) c (cos r) s (sin r))
|
||||
(list (list c (- s) 0.0)
|
||||
(list s c 0.0)
|
||||
(list 0.0 0.0 1.0)))
|
||||
|
||||
;; 3x3-Rotation in die 4x4-Form bringen, die vla-TransformBy erwartet.
|
||||
(defun ks-mat3->mat4 (R)
|
||||
(list (append (car R) '(0.0))
|
||||
(append (cadr R) '(0.0))
|
||||
(append (caddr R) '(0.0))
|
||||
'(0.0 0.0 0.0 1.0)))
|
||||
|
||||
;; --- Block per KS_EIN/KS_AUS einfuegen, frei rotiert und in X skaliert ---
|
||||
;; blockname Rohname (wird ueber ensure-block-loaded aufgeloest)
|
||||
;; einfuegepunkt Weltpunkt, auf den KS_EIN zu liegen kommt
|
||||
;; R 3x3-Rotationsmatrix (Blockkoordinaten -> Welt)
|
||||
;; skala X-Massstab (1.0 = unskaliert)
|
||||
;; Rueckgabe: Weltpunkt von KS_AUS (fuer die Verkettung), sonst einfuegepunkt.
|
||||
;;
|
||||
;; Reihenfolge wie bei den uebrigen Primitiven: am Ursprung einfuegen,
|
||||
;; skalieren, drehen, dann so verschieben, dass das GEDREHTE KS_EIN exakt auf
|
||||
;; einfuegepunkt liegt. Die lokalen KS-Punkte werden dabei zuerst in X
|
||||
;; mitskaliert - sonst zeigt der zurueckgegebene KS_AUS am skalierten Block
|
||||
;; vorbei.
|
||||
(defun insert-block-ks-matrix (blockname einfuegepunkt R skala /
|
||||
block-obj ks-data ks-ein ks-aus
|
||||
ein-lok aus-lok ein-welt aus-welt offset ausgang)
|
||||
(if (or (null einfuegepunkt) (not (listp einfuegepunkt)))
|
||||
(progn
|
||||
(princ (ssg-textf "vfc-fehler-ungueltiger-einfuegepunkt" (list blockname)))
|
||||
(exit))
|
||||
)
|
||||
(if (or (null skala) (<= skala 0.0)) (setq skala 1.0))
|
||||
(setq blockname (ensure-block-loaded blockname))
|
||||
(if (not (tblsearch "BLOCK" blockname))
|
||||
(progn
|
||||
(princ (ssg-textf "vfc-fehler-block-nicht-in-bibliothek-abgebrochen" (list blockname)))
|
||||
(exit))
|
||||
)
|
||||
(setq ks-data (ks-block-messen blockname))
|
||||
(setq ks-ein (cadr (assoc "KS_EIN" ks-data)))
|
||||
(setq ks-aus (cadr (assoc "KS_AUS" ks-data)))
|
||||
(setq block-obj (vla-InsertBlock modelspace
|
||||
(vlax-3D-point '(0 0 0))
|
||||
blockname skala 1.0 1.0 0))
|
||||
(ssg-ils-block-auf-ebene block-obj blockname)
|
||||
(vla-TransformBy block-obj (vlax-tmatrix (ks-mat3->mat4 R)))
|
||||
(if (and ks-ein ks-aus)
|
||||
(progn
|
||||
;; lokale KS-Punkte, in X mitskaliert
|
||||
(setq ein-lok (list (* skala (car (car ks-ein)))
|
||||
(cadr (car ks-ein))
|
||||
(caddr (car ks-ein))))
|
||||
(setq aus-lok (list (* skala (car (car ks-aus)))
|
||||
(cadr (car ks-aus))
|
||||
(caddr (car ks-aus))))
|
||||
(setq ein-welt (mat3-mul-vec3 R ein-lok))
|
||||
(setq aus-welt (mat3-mul-vec3 R aus-lok))
|
||||
(setq offset (list (- (car einfuegepunkt) (car ein-welt))
|
||||
(- (cadr einfuegepunkt) (cadr ein-welt))
|
||||
(- (caddr einfuegepunkt) (caddr ein-welt))))
|
||||
(vla-Move block-obj
|
||||
(vlax-3D-point '(0 0 0))
|
||||
(vlax-3D-point offset))
|
||||
(setq ausgang (list (+ (car einfuegepunkt) (- (car aus-welt) (car ein-welt)))
|
||||
(+ (cadr einfuegepunkt) (- (cadr aus-welt) (cadr ein-welt)))
|
||||
(+ (caddr einfuegepunkt) (- (caddr aus-welt) (caddr ein-welt)))))
|
||||
(ssg-sepliste-dbg
|
||||
(strcat "insert-block-ks-matrix " blockname
|
||||
" skala=" (rtos (float skala) 2 4)
|
||||
" einfuegepunkt=" (ssg-sepliste-dbg-pt einfuegepunkt)
|
||||
" ks_ein_welt=" (ssg-sepliste-dbg-pt ein-welt)
|
||||
" ks_aus_welt=" (ssg-sepliste-dbg-pt aus-welt)
|
||||
" ausgang=" (ssg-sepliste-dbg-pt ausgang)))
|
||||
ausgang
|
||||
)
|
||||
(progn
|
||||
(princ (ssg-text "vfc-warnung-ks-nicht-gefunden"))
|
||||
einfuegepunkt
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; SEPLISTE: Separator-/AS-/ES-Reihenfolge als XDATA am fertigen Wrapper
|
||||
;; ------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user