diff --git a/Lisp/EtageVarioFoerderer.lsp b/Lisp/EtageVarioFoerderer.lsp new file mode 100644 index 0000000..fc45b00 --- /dev/null +++ b/Lisp/EtageVarioFoerderer.lsp @@ -0,0 +1,1113 @@ +;; ============================================================ +;; ETAGE VARIO FOERDERER GENERATOR fuer BricsCAD Pro +;; Version: 1.0 +;; Befehl: ETAGEVARIOFOERDERER +;; Abhaengigkeit: VarioFoerderer.lsp muss zuerst geladen sein +;; (stellt bereit: ensure-block-loaded, insert-block-by-ks, +;; insert-inclined-scaled-block, insert-rotated-block-with-ks, +;; extract-ks-from-block, get-bogen-mass, bogen-auf, bogen-ab, +;; block-pfad, grad-zeichen, doc, modelspace, *ks-cache*) +;; +;; Block-Reihenfolge (15 Schritte): +;; 1. _3D_AS_30_rechts/links (Antriebsstation 30°) +;; 2. Staustrecke_SP_700_mm (700mm horizontal, skaliert aus 1000mm-Block) +;; 3. Separator_300 (Staustrecke_Separator_SP_300_mm, horizontal) +;; 4. Gefaellebogen_links_60°_R500 (fester Kurvenblock) +;; 5. L_GF1 (variable Gerade bei 3°) +;; 6. Vario_Umlenkstation_500mm (3° geneigt) +;; 7. 1. Vertikalbogen (3° rotiert) +;; 8. L_VF (variable Steigung/Gefaelle) +;; 9. 2. Vertikalbogen +;; 10. Vario_Motorstation_500mm (3° geneigt) +;; 11. L_GF2 (variable Gerade bei 3°) +;; 12. Gefaellebogen_links_60°_R500 (fester Kurvenblock) +;; 13. Separator_300 +;; 14. Staustrecke_SP_700_mm +;; 15. _3D_ES_30_rechts/links (Endstation 30°) +;; ============================================================ + +;; ============================================================ +;; TEIL 1: ABHAENGIGKEITS-PRUEFUNG +;; ============================================================ +;; VarioFoerderer.lsp sicherstellen (fuer direktes Laden ohne Menu-System). +;; Stellt bereit: ensure-block-loaded (laedt aus ils_library.dxf), +;; insert-block-by-ks, insert-inclined-scaled-block, +;; insert-rotated-block-with-ks, extract-ks-from-block, +;; get-bogen-mass, bogen-auf, bogen-ab, grad-zeichen, doc, modelspace +(if (not (car (atoms-family 1 '("ENSURE-BLOCK-LOADED")))) + (if (getenv "DXFM_LISP") + (load (strcat (getenv "DXFM_LISP") "/VarioFoerderer.lsp")) + (progn + (alert "DXFM_LISP nicht gesetzt! Bitte zuerst bin\\setenv.bat ausfuehren.") + (exit) + ) + ) +) + +;; ============================================================ +;; TEIL 2: ETAGE-SPEZIFISCHE GLOBALE VARIABLEN +;; ============================================================ +(setq etage-aus-dx nil etage-aus-dz nil) ;; AS_30 Masse (rechts als Referenz) +(setq etage-ein-dx nil etage-ein-dz nil) ;; ES_30 Masse (rechts als Referenz) +(setq etage-gef-dx nil etage-gef-dy nil etage-gef-dz nil) ;; Gefaellebogen aktive Seite +(setq etage-gef-dx-rechts nil etage-gef-dz-rechts nil) ;; Gefaellebogen rechts +(setq etage-gef-dx-links nil etage-gef-dz-links nil) ;; Gefaellebogen links +(setq *etage-lib-initialized* nil) + +;; Feste Laengen +(setq FESTE_ETAGE_MITTE 1000) ;; Umlenkstation(500) + Motorstation(500) bei 3° +(setq ETAGE_SCHRAEG_LAENGE 700) ;; Staustrecke_400 + Separator_300 = 700mm je Seite +(setq ETAGE_HZ_WINKEL 60) ;; Horizontalwinkel Schraegteile (Grad, um Z-Achse) + +;; Zeichen-Konstanten (falls VarioFoerderer.lsp noch nicht geladen) +(if (null grad-zeichen) (setq grad-zeichen (chr 176))) + +;; ============================================================ +;; TEIL 3: BIBLIOTHEK INITIALISIEREN (ETAGE-SPEZIFISCH) +;; ============================================================ +(defun init-bibliothek-etage ( / temp-obj ks-data ks-ein-pos ks-aus-pos + gefaelle-blockname) + ;; Sentinel: Flag zuruecksetzen wenn 3D-Bloecke in der Zeichnung fehlen + (if (and *etage-lib-initialized* (not (tblsearch "BLOCK" "_3D_AS_30_rechts"))) + (setq *etage-lib-initialized* nil)) + (if *etage-lib-initialized* + (progn (princ "\n Etage-Bibliothek bereits initialisiert.") t) + (progn + (princ "\n Initialisiere Etage-Bibliothek...") + + ;; VarioFoerderer-Bibliothek initialisieren (laedt Bogen-Daten bogen-auf/bogen-ab) + (if (not *lib-initialized*) + (init-bibliothek) + ) + + ;; === AS_30_rechts Masse extrahieren === + (princ "\n Extrahiere AS_30_rechts Masse...") + (ensure-block-loaded "_3D_AS_30_rechts") + (if (tblsearch "BLOCK" "_3D_AS_30_rechts") + (progn + (setq temp-obj (vla-InsertBlock modelspace + (vlax-3D-point '(0 0 0)) + "_3D_AS_30_rechts" 1.0 1.0 1.0 0)) + (setq ks-data (extract-ks-from-block temp-obj)) + (vla-Delete temp-obj) + (setq ks-ein-pos nil ks-aus-pos nil) + (foreach item ks-data + (if (= (car item) "KS_EIN") (setq ks-ein-pos (cadr item))) + (if (= (car item) "KS_AUS") (setq ks-aus-pos (cadr item))) + ) + (if (and ks-ein-pos ks-aus-pos) + (progn + (setq etage-aus-dx (- (caar ks-aus-pos) (caar ks-ein-pos))) + (setq etage-aus-dz (- (caddr (car ks-aus-pos)) (caddr (car ks-ein-pos)))) + (princ (strcat "\n AS_30_rechts: dx=" (rtos etage-aus-dx 2 1) + " mm, dz=" (rtos etage-aus-dz 2 1) " mm")) + ) + (progn + (princ "\n WARNUNG: KS_EIN/KS_AUS fehlt - verwende Standardwerte") + (setq etage-aus-dx 525.8 etage-aus-dz -72.9) + ) + ) + ) + (progn + (princ "\n WARNUNG: Block _3D_AS_30_rechts nicht in Bibliothek - verwende Standardwerte") + (setq etage-aus-dx 525.8 etage-aus-dz -72.9) + ) + ) + + ;; === ES_30_rechts Masse extrahieren === + (princ "\n Extrahiere ES_30_rechts Masse...") + (ensure-block-loaded "_3D_ES_30_rechts") + (if (tblsearch "BLOCK" "_3D_ES_30_rechts") + (progn + (setq temp-obj (vla-InsertBlock modelspace + (vlax-3D-point '(0 0 0)) + "_3D_ES_30_rechts" 1.0 1.0 1.0 0)) + (setq ks-data (extract-ks-from-block temp-obj)) + (vla-Delete temp-obj) + (setq ks-ein-pos nil ks-aus-pos nil) + (foreach item ks-data + (if (= (car item) "KS_EIN") (setq ks-ein-pos (cadr item))) + (if (= (car item) "KS_AUS") (setq ks-aus-pos (cadr item))) + ) + (if (and ks-ein-pos ks-aus-pos) + (progn + (setq etage-ein-dx (- (caar ks-aus-pos) (caar ks-ein-pos))) + (setq etage-ein-dz (- (caddr (car ks-aus-pos)) (caddr (car ks-ein-pos)))) + (princ (strcat "\n ES_30_rechts: dx=" (rtos etage-ein-dx 2 1) + " mm, dz=" (rtos etage-ein-dz 2 1) " mm")) + ) + (progn + (princ "\n WARNUNG: KS_EIN/KS_AUS fehlt - verwende Standardwerte") + (setq etage-ein-dx 576.2 etage-ein-dz -54.6) + ) + ) + ) + (progn + (princ "\n WARNUNG: Block _3D_ES_30_rechts nicht in Bibliothek - verwende Standardwerte") + (setq etage-ein-dx 576.2 etage-ein-dz -54.6) + ) + ) + + ;; === Gefaellebogen_links_60deg Masse extrahieren (dx, dz) === + (setq gefaelle-blockname + (strcat "Gefaellebogen_links_60" grad-zeichen "_R500")) + (princ (strcat "\n Extrahiere " gefaelle-blockname " Masse...")) + (ensure-block-loaded gefaelle-blockname) + (if (tblsearch "BLOCK" gefaelle-blockname) + (progn + (setq temp-obj (vla-InsertBlock modelspace + (vlax-3D-point '(0 0 0)) gefaelle-blockname 1.0 1.0 1.0 0)) + (setq ks-data (extract-ks-from-block temp-obj)) + (vla-Delete temp-obj) + (setq ks-ein-pos nil ks-aus-pos nil) + (foreach item ks-data + (if (= (car item) "KS_EIN") (setq ks-ein-pos (cadr item))) + (if (= (car item) "KS_AUS") (setq ks-aus-pos (cadr item))) + ) + (if (and ks-ein-pos ks-aus-pos) + (progn + (setq etage-gef-dx-links (- (caar ks-aus-pos) (caar ks-ein-pos))) + (setq etage-gef-dz-links (- (caddr (car ks-aus-pos)) (caddr (car ks-ein-pos)))) + ) + (progn + (princ "\n WARNUNG: kein KS - Standardwerte (links)") + (setq etage-gef-dx-links 0.0 etage-gef-dz-links -10.0) + ) + ) + ) + (progn + (princ "\n WARNUNG: Block nicht gefunden - Standardwerte (links)") + (setq etage-gef-dx-links 0.0 etage-gef-dz-links -10.0) + ) + ) + (princ (strcat "\n Gefaellebogen links: dx=" (rtos etage-gef-dx-links 2 2) + " dz=" (rtos etage-gef-dz-links 2 2) " mm")) + + ;; === Gefaellebogen_rechts_60deg Masse extrahieren (dx, dz) === + (setq gefaelle-blockname + (strcat "Gefaellebogen_rechts_60" grad-zeichen "_R500")) + (princ (strcat "\n Extrahiere " gefaelle-blockname " Masse...")) + (ensure-block-loaded gefaelle-blockname) + (if (tblsearch "BLOCK" gefaelle-blockname) + (progn + (setq temp-obj (vla-InsertBlock modelspace + (vlax-3D-point '(0 0 0)) gefaelle-blockname 1.0 1.0 1.0 0)) + (setq ks-data (extract-ks-from-block temp-obj)) + (vla-Delete temp-obj) + (setq ks-ein-pos nil ks-aus-pos nil) + (foreach item ks-data + (if (= (car item) "KS_EIN") (setq ks-ein-pos (cadr item))) + (if (= (car item) "KS_AUS") (setq ks-aus-pos (cadr item))) + ) + (if (and ks-ein-pos ks-aus-pos) + (progn + (setq etage-gef-dx-rechts (- (caar ks-aus-pos) (caar ks-ein-pos))) + (setq etage-gef-dz-rechts (- (caddr (car ks-aus-pos)) (caddr (car ks-ein-pos)))) + ) + (progn + (princ "\n WARNUNG: kein KS - Standardwerte (rechts)") + (setq etage-gef-dx-rechts 0.0 etage-gef-dz-rechts -10.0) + ) + ) + ) + (progn + (princ "\n WARNUNG: Block nicht gefunden - Standardwerte (rechts)") + (setq etage-gef-dx-rechts 0.0 etage-gef-dz-rechts -10.0) + ) + ) + (princ (strcat "\n Gefaellebogen rechts: dx=" (rtos etage-gef-dx-rechts 2 2) + " dz=" (rtos etage-gef-dz-rechts 2 2) " mm")) + + ;; Etage-spezifische Bloecke vorladen + (ensure-block-loaded "_3D_AS_30_links") + (ensure-block-loaded "_3D_ES_30_links") + + (setq *etage-lib-initialized* t) + (princ "\n Etage-Bibliothek erfolgreich initialisiert.") + t + ) + ) +) + +;; ============================================================ +;; TEIL 3b: EINFUEGEFUNKTIONEN MIT KOMBINIERTER HZ+VERT ROTATION +;; ============================================================ +;; +;; Kombinierte Transformationsmatrix: Rz(hz) * Ry(vert) +;; [ cos(hz)*cos(vert) -sin(hz) cos(hz)*sin(vert) ] +;; [ sin(hz)*cos(vert) cos(hz) sin(hz)*sin(vert) ] +;; [ -sin(vert) 0 cos(vert) ] +;; +;; hz = Horizontalwinkel (Grad, Rotation um Z-Achse, Richtung in XY-Ebene) +;; vert = Vertikalwinkel (Grad, Rotation um Y-Achse, Neigung) + +;; Skalierter Block (z.B. Staustrecke_SP_1000_mm skaliert auf laenge mm) +(defun insert-hz-incl-scaled-block (blockname startpunkt laenge hz-winkel vert-winkel / + rad-hz rad-vert chz shz cv sv scale + matrix block-obj endpunkt) + (setq scale (/ (float laenge) 1000.0)) + (setq rad-hz (* (float hz-winkel) (/ pi 180.0))) + (setq rad-vert (* (float vert-winkel) (/ pi 180.0))) + (setq chz (cos rad-hz) shz (sin rad-hz)) + (setq cv (cos rad-vert) sv (sin rad-vert)) + + (ensure-block-loaded blockname) + (if (not (tblsearch "BLOCK" blockname)) + (progn + (princ (strcat "\n FEHLER: Block '" blockname "' nicht in Bibliothek - Einfuegen abgebrochen")) + (exit) + ) + ) + (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname scale 1.0 1.0 0)) + + (setq matrix (list + (list (* chz cv) (- shz) (* chz sv) 0) + (list (* shz cv) chz (* shz sv) 0) + (list (- sv) 0 cv 0) + (list 0 0 0 1) + )) + (vla-TransformBy block-obj (vlax-tmatrix matrix)) + (vla-Move block-obj (vlax-3D-point '(0 0 0)) (vlax-3D-point startpunkt)) + + ;; Endpunkt: (laenge,0,0) transformiert -> (laenge*chz*cv, laenge*shz*cv, -laenge*sv) + (setq endpunkt (list + (+ (car startpunkt) (* laenge chz cv)) + (+ (cadr startpunkt) (* laenge shz cv)) + (+ (caddr startpunkt) (* (- sv) laenge)))) + + (princ (strcat "\n HzIncl " blockname " L=" (rtos laenge 2 0) + " hz=" (rtos hz-winkel 2 0) (chr 176) + " v=" (rtos vert-winkel 2 0) (chr 176) + " -> X=" (rtos (car endpunkt) 2 1) + " Y=" (rtos (cadr endpunkt) 2 1) + " Z=" (rtos (caddr endpunkt) 2 1))) + endpunkt +) + +;; Fester Block (z.B. Separator) mit bekanntem block-dx, block-dz +(defun insert-hz-rotated-block-with-ks (blockname startpunkt hz-winkel vert-winkel block-dx block-dz / + rad-hz rad-vert chz shz cv sv + matrix block-obj endpunkt) + (setq rad-hz (* (float hz-winkel) (/ pi 180.0))) + (setq rad-vert (* (float vert-winkel) (/ pi 180.0))) + (setq chz (cos rad-hz) shz (sin rad-hz)) + (setq cv (cos rad-vert) sv (sin rad-vert)) + + (ensure-block-loaded blockname) + (if (not (tblsearch "BLOCK" blockname)) + (progn + (princ (strcat "\n FEHLER: Block '" blockname "' nicht in Bibliothek - Einfuegen abgebrochen")) + (exit) + ) + ) + (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname 1.0 1.0 1.0 0)) + + (setq matrix (list + (list (* chz cv) (- shz) (* chz sv) 0) + (list (* shz cv) chz (* shz sv) 0) + (list (- sv) 0 cv 0) + (list 0 0 0 1) + )) + (vla-TransformBy block-obj (vlax-tmatrix matrix)) + (vla-Move block-obj (vlax-3D-point '(0 0 0)) (vlax-3D-point startpunkt)) + + ;; Endpunkt: Richtungsvektor (block-dx, 0, block-dz) transformiert + (setq endpunkt (list + (+ (car startpunkt) (+ (* block-dx chz cv) (* block-dz chz sv))) + (+ (cadr startpunkt) (+ (* block-dx shz cv) (* block-dz shz sv))) + (+ (caddr startpunkt) (+ (* (- sv) block-dx) (* cv block-dz))))) + + (princ (strcat "\n HzRot " blockname + " hz=" (rtos hz-winkel 2 0) (chr 176) + " v=" (rtos vert-winkel 2 0) (chr 176) + " -> X=" (rtos (car endpunkt) 2 1) + " Y=" (rtos (cadr endpunkt) 2 1) + " Z=" (rtos (caddr endpunkt) 2 1))) + endpunkt +) + +;; Block mit kombinierter hz+vert Rotation einfuegen, ausgerichtet an KS_EIN +;; (statt am Block-Einfuegepunkt), damit der Block exakt an das Vorgaengerteil anschliesst. +;; +;; Algorithmus: +;; 1. Lokale KS-Positionen (unreotiert) aus Cache holen +;; 2. Block am Ursprung einfuegen, Rotationsmatrix anwenden +;; 3. Rotierte KS_EIN-Position berechnen (Matrixmultiplikation) +;; 4. Block verschieben: rotiertes KS_EIN -> startpunkt +;; 5. Rotiertes KS_AUS als naechsten aktueller-punkt zurueckgeben +(defun insert-hz-rotated-block-by-ks (blockname startpunkt hz-winkel vert-winkel / + rad-hz rad-vert chz shz cv sv + temp-obj block-obj ks-data ks-ein ks-aus + p-ein p-aus p-ein-rot p-aus-rot + offset ausgang) + (ensure-block-loaded blockname) + (if (not (tblsearch "BLOCK" blockname)) + (progn + (princ (strcat "\n FEHLER: Block '" blockname "' nicht in Bibliothek - abgebrochen")) + (exit) + ) + ) + + ;; Rotationsparameter + (setq rad-hz (* (float hz-winkel) (/ pi 180.0))) + (setq rad-vert (* (float vert-winkel) (/ pi 180.0))) + (setq chz (cos rad-hz) shz (sin rad-hz)) + (setq cv (cos rad-vert) sv (sin rad-vert)) + + ;; Schritt 1: KS-Positionen im lokalen Koordinatensystem holen (Block bei 0° am Ursprung) + ;; Nutzt den Cache aus init-bibliothek-etage -> kein Explode noetig + (setq temp-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname 1.0 1.0 1.0 0)) + (setq ks-data (extract-ks-from-block temp-obj)) + (if (not (vlax-erased-p temp-obj)) (vla-Delete temp-obj)) + + (setq ks-ein (cadr (assoc "KS_EIN" ks-data))) + (setq ks-aus (cadr (assoc "KS_AUS" ks-data))) + + ;; Schritt 2: Eigentlichen Block einfuegen und rotieren (Rz(hz) * Ry(vert)) + (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname 1.0 1.0 1.0 0)) + (vla-TransformBy block-obj (vlax-tmatrix + (list (list (* chz cv) (- shz) (* chz sv) 0) + (list (* shz cv) chz (* shz sv) 0) + (list (- sv) 0 cv 0) + (list 0 0 0 1)))) + + (if (and ks-ein ks-aus) + (progn + ;; Lokale Ursprungspunkte der KS-Marker + (setq p-ein (car ks-ein)) + (setq p-aus (car ks-aus)) + + ;; Rotation anwenden: p' = Rz(hz)*Ry(vert) * p + ;; x' = chz*cv*x - shz*y + chz*sv*z + ;; y' = shz*cv*x + chz*y + shz*sv*z + ;; z' = -sv*x + cv*z + (setq p-ein-rot + (list (+ (* chz cv (car p-ein)) (- (* shz (cadr p-ein))) (* chz sv (caddr p-ein))) + (+ (* shz cv (car p-ein)) (* chz (cadr p-ein)) (* shz sv (caddr p-ein))) + (+ (* (- sv) (car p-ein)) (* cv (caddr p-ein))))) + (setq p-aus-rot + (list (+ (* chz cv (car p-aus)) (- (* shz (cadr p-aus))) (* chz sv (caddr p-aus))) + (+ (* shz cv (car p-aus)) (* chz (cadr p-aus)) (* shz sv (caddr p-aus))) + (+ (* (- sv) (car p-aus)) (* cv (caddr p-aus))))) + + ;; Schritt 3: Block verschieben -> rotiertes KS_EIN auf startpunkt + (vla-Move block-obj + (vlax-3D-point p-ein-rot) + (vlax-3D-point startpunkt)) + + ;; Schritt 4: Ausgang = rotiertes KS_AUS verschoben um denselben Offset + (setq offset (list (- (car startpunkt) (car p-ein-rot)) + (- (cadr startpunkt) (cadr p-ein-rot)) + (- (caddr startpunkt) (caddr p-ein-rot)))) + (setq ausgang (list (+ (car p-aus-rot) (car offset)) + (+ (cadr p-aus-rot) (cadr offset)) + (+ (caddr p-aus-rot) (caddr offset)))) + + (princ (strcat "\n HzRotKS " blockname + " hz=" (rtos hz-winkel 2 0) (chr 176) + " v=" (rtos vert-winkel 2 0) (chr 176) + " -> X=" (rtos (car ausgang) 2 1) + " Y=" (rtos (cadr ausgang) 2 1) + " Z=" (rtos (caddr ausgang) 2 1))) + ausgang + ) + (progn + (princ (strcat "\n WARNUNG: KS_EIN/KS_AUS fehlt in '" blockname "' - verwende Startpunkt")) + startpunkt + ) + ) +) + +;; Block mit kombinierter hz+vert Rotation UND X-Skalierung einfuegen, +;; ausgerichtet an KS_EIN (statt am Block-Einfuegepunkt). +;; laenge: Ziellaenge mm; Basisblock ist 1000mm lang (XScale = laenge/1000). +(defun insert-hz-scaled-block-by-ks (blockname startpunkt laenge hz-winkel vert-winkel / + rad-hz rad-vert chz shz cv sv scale + temp-obj block-obj ks-data ks-ein ks-aus + p-ein p-aus p-ein-s p-aus-s + p-ein-rot p-aus-rot offset ausgang) + (ensure-block-loaded blockname) + (if (not (tblsearch "BLOCK" blockname)) + (progn + (princ (strcat "\n FEHLER: Block '" blockname "' nicht in Bibliothek - abgebrochen")) + (exit) + ) + ) + + ;; XScale = laenge / Basislaenge (1000mm) + (setq scale (/ (float laenge) 1000.0)) + + (setq rad-hz (* (float hz-winkel) (/ pi 180.0))) + (setq rad-vert (* (float vert-winkel) (/ pi 180.0))) + (setq chz (cos rad-hz) shz (sin rad-hz)) + (setq cv (cos rad-vert) sv (sin rad-vert)) + + ;; Schritt 1: KS-Positionen bei Massstab 1 aus Cache + (setq temp-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname 1.0 1.0 1.0 0)) + (setq ks-data (extract-ks-from-block temp-obj)) + (if (not (vlax-erased-p temp-obj)) (vla-Delete temp-obj)) + + (setq ks-ein (cadr (assoc "KS_EIN" ks-data))) + (setq ks-aus (cadr (assoc "KS_AUS" ks-data))) + + ;; Schritt 2: Block mit XScale einfuegen und rotieren (Rz(hz) * Ry(vert)) + (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname scale 1.0 1.0 0)) + (vla-TransformBy block-obj (vlax-tmatrix + (list (list (* chz cv) (- shz) (* chz sv) 0) + (list (* shz cv) chz (* shz sv) 0) + (list (- sv) 0 cv 0) + (list 0 0 0 1)))) + + (if (and ks-ein ks-aus) + (progn + ;; X-Skalierung auf lokale KS-Punkte anwenden (vla-InsertBlock skaliert nur X) + (setq p-ein (car ks-ein)) + (setq p-aus (car ks-aus)) + (setq p-ein-s (list (* scale (car p-ein)) (cadr p-ein) (caddr p-ein))) + (setq p-aus-s (list (* scale (car p-aus)) (cadr p-aus) (caddr p-aus))) + + ;; Rotation: p' = Rz(hz)*Ry(vert) * p + ;; x' = chz*cv*x - shz*y + chz*sv*z + ;; y' = shz*cv*x + chz*y + shz*sv*z + ;; z' = -sv*x + cv*z + (setq p-ein-rot + (list (+ (* chz cv (car p-ein-s)) (- (* shz (cadr p-ein-s))) (* chz sv (caddr p-ein-s))) + (+ (* shz cv (car p-ein-s)) (* chz (cadr p-ein-s)) (* shz sv (caddr p-ein-s))) + (+ (* (- sv) (car p-ein-s)) (* cv (caddr p-ein-s))))) + (setq p-aus-rot + (list (+ (* chz cv (car p-aus-s)) (- (* shz (cadr p-aus-s))) (* chz sv (caddr p-aus-s))) + (+ (* shz cv (car p-aus-s)) (* chz (cadr p-aus-s)) (* shz sv (caddr p-aus-s))) + (+ (* (- sv) (car p-aus-s)) (* cv (caddr p-aus-s))))) + + ;; Block verschieben: rotiertes+skaliertes KS_EIN -> startpunkt + (vla-Move block-obj + (vlax-3D-point p-ein-rot) + (vlax-3D-point startpunkt)) + + (setq offset (list (- (car startpunkt) (car p-ein-rot)) + (- (cadr startpunkt) (cadr p-ein-rot)) + (- (caddr startpunkt) (caddr p-ein-rot)))) + (setq ausgang (list (+ (car p-aus-rot) (car offset)) + (+ (cadr p-aus-rot) (cadr offset)) + (+ (caddr p-aus-rot) (caddr offset)))) + + (princ (strcat "\n HzScaleKS " blockname + " " (rtos laenge 2 0) "mm" + " hz=" (rtos hz-winkel 2 0) (chr 176) + " v=" (rtos vert-winkel 2 0) (chr 176) + " -> X=" (rtos (car ausgang) 2 1) + " Y=" (rtos (cadr ausgang) 2 1) + " Z=" (rtos (caddr ausgang) 2 1))) + ausgang + ) + (progn + (princ (strcat "\n WARNUNG: KS_EIN/KS_AUS fehlt in '" blockname "' - verwende Startpunkt")) + startpunkt + ) + ) +) + +;; ============================================================ +;; TEIL 4: WINKELBERECHNUNG +;; ============================================================ +;; +;; Geometrie (gleich wie VarioFoerderer, andere feste Teile): +;; +;; Schraegteile (Staustrecke_500 + Separator_300 = 800mm je Seite): +;; 60deg horizontal (XY-Ebene) + 3deg vertikal +;; X-Beitrag: 800 * cos(60deg) * cos(3deg) = 800 * schraeg-cos +;; Z-Beitrag: 800 * sin(3deg) = 800 * sin3 +;; +;; X-Bilanz: +;; aus_dx + 700*schraeg-cos + gef_dx + L_GF*cos3 + FESTE_MITTE*cos3 +;; + b1x + L_VF*cosEff + b2x +;; + FESTE_MITTE*cos3 + L_GF*cos3 + gef_dx + 700*schraeg-cos + ein_dx = deltaL +;; +;; Vereinfacht: +;; A = deltaL - aus_dx - ein_dx - 2*700*schraeg-cos - 2*gef_dx +;; - 2*FESTE_MITTE*cos3 - b1x - b2x +;; L_GF*cos3 + L_VF*cosEff = A +;; +;; Z-Bilanz ("Auf"): +;; B = deltaH + |aus_dz| + |ein_dz| + 2*700*sin3 + 2*|gef_dz| +;; + 2*FESTE_MITTE*sin3 - b1z - b2z +;; L_GF*sin3 + L_VF*sinEff = B +;; +;; HINWEIS: FESTE_ETAGE_MITTE (Umlenkstation + Motorstation = 1000mm) +;; erscheint auf BEIDEN Seiten der Bogen (vor L_GF1 und nach L_GF2). +;; In der Formel wird es daher mit Faktor 2 berechnet: +;; FESTE_ETAGE_MITTE_GESAMT = 2 * 1000 = 2000mm bei 3° +;; Aber L_GF liegt ZWISCHEN Bogen und FESTE_MITTE, deshalb: +;; -> Nur EIN FESTE_ETAGE_MITTE tritt in die Gleichung ein (analog VarioFoerderer). +;; -> Der zweite L_GF absorbiert die restliche Laenge. +;; +;; Vereinfachung: L_GF = L_GF1 + L_GF2 (Gesamt, wie in VarioFoerderer) +;; +(defun berechne-winkel-etage (deltaL deltaH richtung / + winkel-list ergebnis-liste A B cos3 sin3 + bogen-x1 bogen-z1 bogen-x2 bogen-z2 + abs-dz-AUS abs-dz-EIN abs-dz-GEF + L_GF L_VF cosα sinα + winkel-eff cosEff sinEff rad5 rad7 + winkel mass1 mass2 gueltig + best-winkel best-L_GF best-L_VF + feste-gesamt-cos feste-gesamt-sin + schraeg-hz-rad schraeg-cos schraeg-z) + + (if (not *etage-lib-initialized*) + (progn + (alert "Etage-Bibliothek nicht initialisiert!") + (exit) + ) + ) + + (setq abs-dz-AUS (abs etage-aus-dz) + abs-dz-EIN (abs etage-ein-dz) + abs-dz-GEF (abs etage-gef-dz)) + + ;; FESTE_ETAGE_MITTE erscheint auf beiden Seiten der Vertikalbogen + ;; (Umlenkstation vor 1. Bogen, Motorstation nach 2. Bogen) + (setq winkel-list '(3 6 9 12 15 18 21 27 33 39 45 51)) + (setq ergebnis-liste '()) + (setq cos3 (cos (* 3.0 (/ pi 180.0))) + sin3 (sin (* 3.0 (/ pi 180.0)))) + + ;; FESTE_ETAGE_MITTE erscheint auf beiden Seiten der Vertikalbogen + (setq feste-gesamt-cos (* FESTE_ETAGE_MITTE cos3)) + (setq feste-gesamt-sin (* FESTE_ETAGE_MITTE sin3)) + ;; Schraegteile: 60° horizontal (XY-Ebene) + 3° vertikal + ;; X-Beitrag je Seite: L * cos(60deg) * cos(3deg) + ;; Z-Beitrag je Seite: L * sin(3deg) (nur vertikale Neigung!) + (setq schraeg-hz-rad (* (float ETAGE_HZ_WINKEL) (/ pi 180.0))) + (setq schraeg-cos (* (cos schraeg-hz-rad) cos3)) + + (princ "\n\n=========================================") + (princ "\n ETAGE-BERECHNUNG FUER ALLE WINKEL") + (princ "\n=========================================") + (princ (strcat "\ndeltaL = " (rtos deltaL 2 2) " mm")) + (princ (strcat "\ndeltaH = " (rtos deltaH 2 2) " mm")) + (princ (strcat "\nRichtung: " richtung)) + (princ (strcat "\nFeste Teile: AS_dx=" (rtos etage-aus-dx 2 1) + " ES_dx=" (rtos etage-ein-dx 2 1) + " 2x(800*cos60*cos3)=" (rtos (* 2.0 ETAGE_SCHRAEG_LAENGE schraeg-cos) 2 1) + " 2xGef_dx=" (rtos (* 2.0 etage-gef-dx) 2 2) + " 2xFESTE_MITTE*cos3=" (rtos (* 2.0 feste-gesamt-cos) 2 1))) + + (foreach winkel winkel-list + (if (= richtung "Auf") + (progn + (setq mass1 (get-bogen-mass bogen-auf winkel)) + (setq mass2 (get-bogen-mass bogen-ab winkel)) + ) + (progn + (setq mass1 (get-bogen-mass bogen-ab winkel)) + (setq mass2 (get-bogen-mass bogen-auf winkel)) + ) + ) + + (if (or (null mass1) (null mass2)) + (progn + (princ (strcat "\n " (itoa winkel) "° -> Bogen nicht vorhanden")) + (setq ergebnis-liste (cons (list winkel nil nil nil) ergebnis-liste)) + ) + (progn + ;; Rotierte Bogen-Vorschuebe (identisch zu VarioFoerderer) + (setq rad5 (* 3.0 (/ pi 180.0))) + (setq rad7 (* (float (if (= richtung "Auf") (- 3 winkel) (+ winkel 3))) + (/ pi 180.0))) + + (setq bogen-x1 (+ (* (car mass1) (cos rad5)) (* (caddr mass1) (sin rad5)))) + (setq bogen-z1 (+ (* (- (car mass1)) (sin rad5)) (* (caddr mass1) (cos rad5)))) + (setq bogen-x2 (+ (* (car mass2) (cos rad7)) (* (caddr mass2) (sin rad7)))) + (setq bogen-z2 (+ (* (- (car mass2)) (sin rad7)) (* (caddr mass2) (cos rad7)))) + + (setq cosα (cos (* winkel (/ pi 180.0))) + sinα (sin (* winkel (/ pi 180.0)))) + (setq winkel-eff (if (= richtung "Auf") (- winkel 3) (+ winkel 3))) + (setq cosEff (cos (* winkel-eff (/ pi 180.0))) + sinEff (sin (* winkel-eff (/ pi 180.0)))) + + ;; A: horizontaler Rest nach Abzug aller fester Teile + ;; Feste X-Beitraege: + ;; - AS_30 Block (etage-aus-dx) + ;; - 2 x (Staustrecke_500 + Separator_300) * cos60° = 2 x 800 * cos60 + ;; - 2 x Gefaellebogen dx (etage-gef-dx) + ;; - 2 x FESTE_ETAGE_MITTE * cos3 (Umlenkstation + Motorstation bei 3°) + ;; - Bogen-Vorschuebe bogen-x1, bogen-x2 + ;; - ES_30 Block (etage-ein-dx) + (setq A (- deltaL + etage-aus-dx + etage-ein-dx + (* 2.0 ETAGE_SCHRAEG_LAENGE schraeg-cos) + (* 2.0 etage-gef-dx) + bogen-x1 + bogen-x2 + (* 2.0 feste-gesamt-cos))) + + ;; B: vertikaler Rest + ;; Vorzeichen-Logik analog VarioFoerderer + ;; Z-Beitrag der Schraegteile (800mm, 3deg vertikal): 800*sin3 Absenkung je Seite + (setq schraeg-z (* ETAGE_SCHRAEG_LAENGE sin3)) + (if (= richtung "Auf") + (setq B (+ deltaH + abs-dz-AUS + abs-dz-EIN + (* 2.0 schraeg-z) + (* 2.0 abs-dz-GEF) + (- bogen-z1) + (- bogen-z2) + (* 2.0 feste-gesamt-sin))) + (setq B (+ (- deltaH + abs-dz-AUS + abs-dz-EIN + (* 2.0 schraeg-z) + (* 2.0 abs-dz-GEF) + (* 2.0 feste-gesamt-sin)) + bogen-z1 + bogen-z2)) + ) + + ;; Gleichungssystem loesen + (if (> (abs sinα) 0.0001) + (progn + (setq L_GF (/ (- (* A sinEff) (* B cosEff)) sinα)) + (if (= richtung "Auf") + (setq L_VF (/ (+ (* A sin3) (* B cos3)) sinα)) + (setq L_VF (/ (- (* B cos3) (* A sin3)) sinα)) + ) + (if (and (numberp L_GF) (numberp L_VF)) + (progn + (setq gueltig (and (>= L_GF 0) (>= L_VF 0))) + (setq ergebnis-liste + (cons (list winkel L_GF L_VF gueltig) ergebnis-liste)) + ) + (setq ergebnis-liste (cons (list winkel nil nil nil) ergebnis-liste)) + ) + ) + (setq ergebnis-liste (cons (list winkel nil nil nil) ergebnis-liste)) + ) + ) + ) + ) + + (setq ergebnis-liste (reverse ergebnis-liste)) + + ;; Ergebnistabelle ausgeben + (princ "\n\n=================================================================================") + (princ "\n ERGEBNISTABELLE (L_GF = gesamt beider GF-Strecken)") + (princ "\n=================================================================================") + (princ "\n Winkel L_GF (mm) L_VF (mm) Status") + (princ "\n=================================================================================") + + (setq best-winkel nil best-L_GF nil best-L_VF nil) + (foreach item ergebnis-liste + (setq winkel (car item) + L_GF (cadr item) + L_VF (caddr item) + gueltig (cadddr item)) + (if (and (numberp L_GF) (numberp L_VF)) + (progn + (princ (strcat "\n " (itoa winkel) (chr 176) + " " (if (numberp L_GF) (rtos L_GF 2 1) "---") " mm" + " " (if (numberp L_VF) (rtos L_VF 2 1) "---") " mm ")) + (if gueltig + (progn + (princ "GUELTIG") + (if (or (null best-winkel) (< winkel best-winkel)) + (setq best-winkel winkel best-L_GF L_GF best-L_VF L_VF) + ) + ) + (princ "UNGUELTIG (negative Laenge)") + ) + ) + (princ (strcat "\n " (itoa winkel) (chr 176) + " --- --- FEHLER")) + ) + ) + (princ "\n=================================================================================") + + (if best-winkel + (princ (strcat "\n>>> Empfohlener Winkel: " (itoa best-winkel) (chr 176))) + (princ "\n>>> KEIN passender Winkel gefunden!") + ) + + (list best-winkel best-L_GF best-L_VF ergebnis-liste) +) + +;; ============================================================ +;; TEIL 5: VarioFoerderer EINFUEGEN (15 SCHRITTE) +;; ============================================================ +(defun etage-foerderanlage-einfuegen (deltaL deltaH richtung + best-winkel L_GF1 L_GF2 L_VF + startpunkt seite + / aktueller-punkt bogen-name endpunkt + bogen-mass bogen-dx bogen-dz + as-block es-block gefaelle-blockname + hz-vorzeichen hz-anfang hz-ende) + + (setq aktueller-punkt startpunkt) + ;; Vorzeichen des Horizontalwinkels je nach Seite: + ;; rechts: Anfang +60deg (links), Ende -60deg (rechts) + ;; links: Anfang -60deg (rechts), Ende +60deg (links) + (setq hz-vorzeichen (if (= seite "rechts") 1 -1)) + (setq hz-anfang (* hz-vorzeichen ETAGE_HZ_WINKEL)) + (setq hz-ende (* (- hz-vorzeichen) ETAGE_HZ_WINKEL)) + (setq as-block (strcat "_3D_AS_30_" seite)) + (setq es-block (strcat "_3D_ES_30_" seite)) + (setq gefaelle-blockname + (if (= seite "rechts") + (strcat "Gefaellebogen_rechts_60" grad-zeichen "_R500") + (strcat "Gefaellebogen_links_60" grad-zeichen "_R500") + )) + ;; Sentinel: *etage-lib-initialized* zuruecksetzen wenn 3D-Bloecke fehlen + ;; (Zeichnung gewechselt oder Bibliothek wurde nicht mit 3D-Bloecken geladen) + (if (and *etage-lib-initialized* (not (tblsearch "BLOCK" "_3D_AS_30_rechts"))) + (setq *etage-lib-initialized* nil)) + (if (not *etage-lib-initialized*) (init-bibliothek-etage)) + + ;; 1. Antriebsstation AS_30 + (princ (strcat "\n\n1/15: " as-block " (0°)")) + (setq aktueller-punkt (insert-block-by-ks as-block aktueller-punkt)) + + ;; 2. Staustrecke_SP_400mm (hz-anfang horizontal, 3° vertikal, Ausrichtung per KS_EIN) + (princ (strcat "\n\n2/15: Staustrecke_SP_400_mm (" (itoa hz-anfang) "deg hz, 3deg vert, KS_EIN)")) + (setq aktueller-punkt + (insert-hz-scaled-block-by-ks "Staustrecke_SP_1000_mm" aktueller-punkt 400 hz-anfang 3)) + + ;; 3. Separator (hz-anfang horizontal, 3° vertikal) + (princ (strcat "\n\n3/15: Separator (300mm, " (itoa hz-anfang) "deg hz, 3deg vert)")) + (setq aktueller-punkt + (insert-hz-rotated-block-with-ks "Staustrecke_Separator_SP_300_mm" aktueller-punkt hz-anfang 3 300 0)) + + ;; 4. Gefaellebogen (Anfang, hz-anfang horizontal, 0° vertikal, Ausrichtung per KS_EIN) + (princ (strcat "\n\n4/15: " gefaelle-blockname " (Anfang, " (itoa hz-anfang) "deg hz, 0deg vert, KS_EIN)")) + (setq aktueller-punkt + (insert-hz-rotated-block-by-ks gefaelle-blockname aktueller-punkt + hz-anfang 0)) + + ;; 5. L_GF1 (variable Gerade bei 3°) + (if (> L_GF1 0.1) + (progn + (princ (strcat "\n\n5/15: Gefaellestrecke (3°, Laenge=" (rtos L_GF1 2 2) " mm)")) + (setq aktueller-punkt + (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt L_GF1 3)) + ) + (princ "\n\n5/15: L_GF1 (uebersprungen, Laenge <= 0)") + ) + + ;; 6. Umlenkstation (3° geneigt) + (princ "\n\n6/15: Umlenkstation (500mm, 3° geneigt)") + (setq aktueller-punkt + (insert-rotated-block-with-ks "Vario_Umlenkstation_500mm" aktueller-punkt 3 500 0)) + + ;; 7. 1. Vertikalbogen (bei 3° rotiert) + (if (= richtung "Auf") + (progn + (setq bogen-name (strcat "Vario_Bogen_auf_" (itoa best-winkel) grad-zeichen)) + (setq bogen-mass (get-bogen-mass bogen-auf best-winkel)) + ) + (progn + (setq bogen-name (strcat "Vario_Bogen_ab_" (itoa best-winkel) grad-zeichen)) + (setq bogen-mass (get-bogen-mass bogen-ab best-winkel)) + ) + ) + (setq bogen-dx (car bogen-mass) bogen-dz (caddr bogen-mass)) + (princ (strcat "\n\n7/15: " bogen-name " (3° geneigt)")) + (setq aktueller-punkt + (insert-rotated-block-with-ks bogen-name aktueller-punkt 3 bogen-dx bogen-dz)) + + ;; 8. Variable Strecke L_VF + (if (> L_VF 0.1) + (progn + (if (= richtung "Auf") + (progn + (princ (strcat "\n\n8/15: Steigungsstrecke (" + (itoa (- (- best-winkel 3))) "°, Laenge=" (rtos L_VF 2 2) " mm)")) + (setq aktueller-punkt + (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt + L_VF (- (- best-winkel 3)))) + ) + (progn + (princ (strcat "\n\n8/15: Gefaellestrecke (" + (itoa (+ best-winkel 3)) "°, Laenge=" (rtos L_VF 2 2) " mm)")) + (setq aktueller-punkt + (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt + L_VF (+ best-winkel 3))) + ) + ) + ) + (princ "\n\n8/15: L_VF (uebersprungen, Laenge <= 0)") + ) + + ;; 9. 2. Vertikalbogen + (if (= richtung "Auf") + (progn + (setq bogen-name (strcat "Vario_Bogen_ab_" (itoa best-winkel) grad-zeichen)) + (setq bogen-mass (get-bogen-mass bogen-ab best-winkel)) + ) + (progn + (setq bogen-name (strcat "Vario_Bogen_auf_" (itoa best-winkel) grad-zeichen)) + (setq bogen-mass (get-bogen-mass bogen-auf best-winkel)) + ) + ) + (setq bogen-dx (car bogen-mass) bogen-dz (caddr bogen-mass)) + (if (= richtung "Auf") + (progn + (princ (strcat "\n\n9/15: " bogen-name " (" (itoa (- 3 best-winkel)) "° geneigt)")) + (setq aktueller-punkt + (insert-rotated-block-with-ks bogen-name aktueller-punkt (- 3 best-winkel) bogen-dx bogen-dz)) + ) + (progn + (princ (strcat "\n\n9/15: " bogen-name " (" (itoa (+ best-winkel 3)) "° geneigt)")) + (setq aktueller-punkt + (insert-rotated-block-with-ks bogen-name aktueller-punkt (+ best-winkel 3) bogen-dx bogen-dz)) + ) + ) + + ;; 10. Motorstation (3° geneigt) + (princ "\n\n10/15: Motorstation (500mm, 3° geneigt)") + (setq aktueller-punkt + (insert-rotated-block-with-ks "Vario_Motorstation_500mm" aktueller-punkt 3 500 0)) + + ;; 11. L_GF2 (variable Gerade bei 3°) + (if (> L_GF2 0.1) + (progn + (princ (strcat "\n\n11/15: Gefaellestrecke (3°, Laenge=" (rtos L_GF2 2 2) " mm)")) + (setq aktueller-punkt + (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt L_GF2 3)) + ) + (princ "\n\n11/15: L_GF2 (uebersprungen, Laenge <= 0)") + ) + + ;; 12. Gefaellebogen (Ende) + (princ (strcat "\n\n12/15: " gefaelle-blockname " (Ende)")) + (setq aktueller-punkt (insert-block-by-ks gefaelle-blockname aktueller-punkt)) + + ;; 13. Separator (Ende, hz-ende horizontal, 3° vertikal) + (princ (strcat "\n\n13/15: Separator (300mm, " (itoa hz-ende) "deg hz, 3deg vert)")) + (setq aktueller-punkt + (insert-hz-rotated-block-with-ks "Staustrecke_Separator_SP_300_mm" aktueller-punkt hz-ende 3 300 0)) + + ;; 14. Staustrecke_SP_400mm (Ende, hz-ende horizontal, 3° vertikal, Ausrichtung per KS_EIN) + (princ (strcat "\n\n14/15: Staustrecke_SP_400_mm (" (itoa hz-ende) "deg hz, 3deg vert, KS_EIN)")) + (setq aktueller-punkt + (insert-hz-scaled-block-by-ks "Staustrecke_SP_1000_mm" aktueller-punkt 400 hz-ende 3)) + + ;; 15. Endstation ES_30 (Ende, hz-ende horizontal, 0° vertikal) + (princ (strcat "\n\n15/15: " es-block " (Ende, " (itoa hz-ende) "deg hz, 0deg vert)")) + (setq endpunkt + (insert-hz-rotated-block-with-ks es-block aktueller-punkt + hz-ende 0 + etage-ein-dx etage-ein-dz)) + + (princ "\n\n=========================================") + (princ "\n>>> Etage-VarioFoerderer erfolgreich eingefuegt! <<<") + (princ "\n=========================================") + + endpunkt +) + +;; ============================================================ +;; TEIL 6: HAUPTFUNKTION +;; ============================================================ +(defun c:ETAGEVARIOFOERDERER ( / eingabe-modus line-points startpunkt endpunkt + differenz deltaL deltaH deltaX deltaY + richtung ergebnis ergebnis-liste + best-winkel L_GF L_GF1 L_GF2 L_VF + gueltige-winkel idx eintrag wahl antwort + seite verteilung-modus + startpunkt-fuer-einfuegen) + + (princ "\n=========================================") + (princ "\n ETAGE VARIO FOERDERER GENERATOR v1.0") + (princ "\n=========================================") + + ;; Bibliothek initialisieren + (if (not (init-bibliothek-etage)) + (progn + (alert "Fehler beim Initialisieren der Etage-Bibliothek!") + (exit) + ) + ) + + ;; Eingabemodus + (princ "\n\nEingabemodus waehlen:") + (princ "\n 1 - 3D-Linie auswaehlen (Start- und Endpunkt mit Hoehe)") + (princ "\n 2 - Werte manuell eingeben") + (setq antwort (getstring "\nIhre Wahl (1/2): ")) + + (cond + ((= antwort "1") (setq eingabe-modus "Linie")) + ((= antwort "2") (setq eingabe-modus "Wert")) + (t (setq eingabe-modus "Linie")) + ) + + (if (= eingabe-modus "Linie") + (progn + (princ "\n\n>>> MODUS: 3D-Linie auswaehlen <<<") + (command "BKS" "W") + (setq line-points + (get-line-start-end-points + "\nBitte 3D-Linie fuer die Etage-Foerderstrecke auswaehlen:")) + (if (null line-points) + (progn (alert "Keine gueltige Linie ausgewaehlt!") (exit)) + ) + (setq startpunkt (car line-points) + endpunkt (cadr line-points)) + (setq differenz (punkt-differenz startpunkt endpunkt)) + (setq deltaX (abs (car differenz)) + deltaY (abs (cadr differenz)) + deltaH (caddr differenz)) + (setq deltaL (max deltaX deltaY)) + (princ (strcat "\n deltaL = " (rtos deltaL 2 2) " mm (max aus deltaX=" (rtos deltaX 2 2) + ", deltaY=" (rtos deltaY 2 2) ")")) + (if (>= deltaH 0) + (progn (setq richtung "Auf") (princ "\n Foerderrichtung: AUF")) + (progn (setq richtung "Ab") (setq deltaH (abs deltaH)) (princ "\n Foerderrichtung: AB")) + ) + (setq startpunkt-fuer-einfuegen startpunkt) + ) + (progn + (princ "\n\n>>> MODUS: Manuelle Werteingabe <<<") + (setq deltaL (getreal "\nHorizontale Distanz deltaL (mm): ")) + (if (null deltaL) (setq deltaL 12000)) + (setq deltaH (getreal "\nHoehenunterschied |deltaH| (mm): ")) + (if (null deltaH) (setq deltaH 3000)) + (princ "\nFoerderrichtung:\n 1 - AUF (nach oben)\n 2 - AB (nach unten)") + (setq antwort (getstring "\nIhre Wahl (1/2): ")) + (if (= antwort "2") (setq richtung "Ab") (setq richtung "Auf")) + (setq startpunkt-fuer-einfuegen (getpoint "\nStartpunkt waehlen: ")) + (if (null startpunkt-fuer-einfuegen) + (setq startpunkt-fuer-einfuegen '(0 0 0))) + ) + ) + + ;; Seite vorab waehlen (benoetigt fuer Gefaellebogen-dx in der Berechnung) + (princ "\n\nSeite waehlen:") + (princ "\n 1 - Rechts (_3D_AS_30_rechts / _3D_ES_30_rechts)") + (princ "\n 2 - Links (_3D_AS_30_links / _3D_ES_30_links)") + (setq antwort (getstring "\nIhre Wahl (1/2) [1]: ")) + (if (= antwort "2") + (setq seite "links") + (setq seite "rechts") + ) + (princ (strcat "\n>>> Seite: " seite)) + ;; Gefaellebogen-Masse fuer die gewaehlte Seite aktivieren + (if (= seite "rechts") + (progn + (setq etage-gef-dx etage-gef-dx-rechts etage-gef-dz etage-gef-dz-rechts)) + (progn + (setq etage-gef-dx etage-gef-dx-links etage-gef-dz etage-gef-dz-links)) + ) + (princ (strcat "\n Gefaellebogen dx=" (rtos etage-gef-dx 2 2) " mm")) + + ;; Berechnung + (setq ergebnis (berechne-winkel-etage deltaL deltaH richtung)) + (setq ergebnis-liste (cadddr ergebnis)) + + ;; Gueltige Winkel ermitteln + (setq gueltige-winkel + (mapcar 'car + (vl-remove-if-not + (function (lambda (e) (and (nth 3 e) + (numberp (nth 1 e)) (numberp (nth 2 e)) + (>= (nth 1 e) 0) (>= (nth 2 e) 0)))) + ergebnis-liste))) + + (if (null gueltige-winkel) + (progn + (alert (strcat "Kein passender Winkel gefunden!\n\n" + "deltaL=" (rtos deltaL 2 0) " mm, deltaH=" (rtos deltaH 2 0) + " mm, Richtung=" richtung + "\n\nHinweis: Etage-Foerderer benoetigt groessere horizontale" + " Distanz als Standard-Variofoerderer.\nBitte andere Werte versuchen.")) + (exit) + ) + ) + + ;; Winkelauswahl + (if (= (length gueltige-winkel) 1) + (progn + (setq best-winkel (car gueltige-winkel)) + (setq eintrag (assoc best-winkel ergebnis-liste)) + (setq L_GF (nth 1 eintrag) L_VF (nth 2 eintrag)) + ) + (progn + (princ "\n\nMehrere gueltige Winkel verfuegbar. Bitte waehlen:") + (setq idx 1) + (foreach w gueltige-winkel + (setq eintrag (assoc w ergebnis-liste)) + (princ (strcat "\n " (itoa idx) " - " (itoa w) (chr 176) + " (L_GF=" (rtos (nth 1 eintrag) 2 1) + " mm, L_VF=" (rtos (nth 2 eintrag) 2 1) " mm)")) + (setq idx (1+ idx)) + ) + (setq wahl (getint (strcat "Winkel waehlen (1-" + (itoa (length gueltige-winkel)) ") [1]: "))) + (if (or (null wahl) (< wahl 1) (> wahl (length gueltige-winkel))) + (setq wahl 1)) + (setq best-winkel (nth (1- wahl) gueltige-winkel)) + (setq eintrag (assoc best-winkel ergebnis-liste)) + (setq L_GF (nth 1 eintrag) L_VF (nth 2 eintrag)) + ) + ) + + (princ "\n\n=========================================") + (princ (strcat "\n>>> Gewaehlter Winkel: " (itoa best-winkel) (chr 176))) + (princ (strcat "\n>>> L_GF (gesamt): " (rtos L_GF 2 2) " mm")) + (princ (strcat "\n>>> L_VF: " (rtos L_VF 2 2) " mm")) + (princ "\n=========================================") + + ;; Verteilung L_GF1 / L_GF2 + (princ "\n\nVerteilung der Gefaellestrecken (L_GF1 vorne / L_GF2 hinten):") + (princ "\n 1 - Gleichmaessig (L_GF1 = L_GF2 = L_GF/2)") + (princ "\n 2 - Vorne Minimum (L_GF1=1000, L_GF2=Rest)") + (princ "\n 3 - Hinten Minimum (L_GF2=1000, L_GF1=Rest)") + (princ "\n 4 - Eigene Werte") + (setq verteilung-modus (getstring "\nIhre Wahl (1/2/3/4) [1]: ")) + (if (= verteilung-modus "") (setq verteilung-modus "1")) + + (cond + ((= verteilung-modus "1") + (setq L_GF1 (/ L_GF 2.0) L_GF2 (/ L_GF 2.0))) + ((= verteilung-modus "2") + (setq L_GF1 1000.0) + (setq L_GF2 (max 0 (- L_GF 1000.0)))) + ((= verteilung-modus "3") + (setq L_GF2 1000.0) + (setq L_GF1 (max 0 (- L_GF 1000.0)))) + ((= verteilung-modus "4") + (setq L_GF1 (getreal (strcat "\nL_GF1 vorne (mm) [" (rtos (/ L_GF 2.0) 2 2) "]: "))) + (if (null L_GF1) (setq L_GF1 (/ L_GF 2.0))) + (setq L_GF2 (max 0 (- L_GF L_GF1))) + (princ (strcat "\n L_GF2 = " (rtos L_GF2 2 2) " mm"))) + (t + (setq L_GF1 (/ L_GF 2.0) L_GF2 (/ L_GF 2.0))) + ) + + (princ (strcat "\n>>> L_GF1 (vorne): " (rtos L_GF1 2 2) " mm")) + (princ (strcat "\n>>> L_GF2 (hinten): " (rtos L_GF2 2 2) " mm")) + + ;; Einfuegen + (princ "\n\nMoechten Sie die Anlage einfuegen?") + (princ "\n 1 - Ja 2 - Nein") + (setq antwort (getstring "\nIhre Wahl (1/2): ")) + + (if (= antwort "1") + (etage-foerderanlage-einfuegen deltaL deltaH richtung best-winkel + L_GF1 L_GF2 L_VF + startpunkt-fuer-einfuegen seite) + (princ "\nVorgang abgebrochen.") + ) + + nil +) + +;; ============================================================ +;; START +;; ============================================================ +(princ "\n=========================================") +(princ "\n>>> ETAGE VARIO FOERDERER v1.0 geladen <<<") +(princ "\n>>> Befehl: ETAGEVARIOFOERDERER <<<") +(princ "\n=========================================") +(princ) diff --git a/Lisp/VarioFoerderer.lsp b/Lisp/VarioFoerderer.lsp index 921c4c4..a888a68 100644 --- a/Lisp/VarioFoerderer.lsp +++ b/Lisp/VarioFoerderer.lsp @@ -134,12 +134,19 @@ (defun ensure-block-loaded (blockname / lib-datei block-datei temp-obj) (if (not (tblsearch "BLOCK" blockname)) (progn - ;; Erste fehlender Block: gesamte Bibliothek laden (enthaelt alle 3D-Bloecke) + ;; Bibliothek laden (enthaelt alle Bloecke). + ;; *library-loaded* immer zuruecksetzen wenn ein Block fehlt: + ;; - nach Zeichnungswechsel fehlen alle Bloecke + ;; - oder die Bibliothek wurde von einem anderen Befehl geladen + ;; aber der angeforderte Block war nicht enthalten + (if *library-loaded* + (setq *library-loaded* nil) + ) (if (not *library-loaded*) (progn (setq lib-datei (strcat (vl-string-translate "\\" "/" (getenv "DXFM_DATA")) - "/block_libraries/ils_library.dwg")) + "/block_libraries/ils_library.dxf")) (if (findfile lib-datei) (progn (princ "\n Lade ils_library.dxf ...") @@ -413,8 +420,7 @@ ) (progn (setq *ks-cache* nil) - (princ "\n Lade Blockdefinitionen aus Einzeldateien...") - (princ (strcat "\n Block-Pfad: " block-pfad)) + (princ "\n Initialisiere Bibliothek...") ;; === AUS_ELEMENT / EIN_ELEMENT – beide Seiten vorladen === (ensure-block-loaded "_3D_AS_90_rechts") @@ -579,6 +585,13 @@ (if (not *lib-initialized*) (init-bibliothek)) (ensure-block-loaded blockname) + (if (not (tblsearch "BLOCK" blockname)) + (progn + (princ (strcat "\n FEHLER: Block '" blockname "' nicht in Bibliothek - Einfuegen abgebrochen")) + (exit) + ) + ) + (princ (strcat "\n Fuege Block '" blockname "' ein...")) (setq block-obj (vla-InsertBlock modelspace @@ -625,6 +638,12 @@ ) (progn (ensure-block-loaded blockname) + (if (not (tblsearch "BLOCK" blockname)) + (progn + (princ (strcat "\n FEHLER: Block '" blockname "' nicht in Bibliothek - Einfuegen abgebrochen")) + (exit) + ) + ) (princ (strcat "\n Fuege '" blockname "' ein (Laenge=" (rtos laenge 2 2) " mm, Winkel=" (itoa winkel) "°)")) (setq scale (/ laenge (ssg-cfg-or "vario" "skalierung_basis" 1000.0))) @@ -671,6 +690,12 @@ ) (progn (ensure-block-loaded blockname) + (if (not (tblsearch "BLOCK" blockname)) + (progn + (princ (strcat "\n FEHLER: Block '" blockname "' nicht in Bibliothek - Einfuegen abgebrochen")) + (exit) + ) + ) (princ (strcat "\n Fuege Block '" blockname "' ein (Rotation " (itoa winkel) "°)")) (setq rad (* winkel (/ pi 180.0))) diff --git a/data/block_libraries/ils_library.dxf b/data/block_libraries/ils_library.dxf index b5fbd77..bb5a1c7 100644 Binary files a/data/block_libraries/ils_library.dxf and b/data/block_libraries/ils_library.dxf differ diff --git a/menu/SSG_LIB.mnl b/menu/SSG_LIB.mnl index 8da4ade..6f4ccee 100644 --- a/menu/SSG_LIB.mnl +++ b/menu/SSG_LIB.mnl @@ -116,6 +116,7 @@ (ssg-ensure "ssg_id") (ssg-ensure "KreiselInsert") (ssg-ensure "VarioFoerderer") + (ssg-ensure "EtageVarioFoerderer") (ssg-ensure "Gefaellestrecke") (ssg-ensure "export") (ssg-ensure "tests") diff --git a/menu/SSG_LIB.mnu b/menu/SSG_LIB.mnu index 5669122..05d0a8b 100644 --- a/menu/SSG_LIB.mnu +++ b/menu/SSG_LIB.mnu @@ -15,6 +15,7 @@ [ETF Etagenfoerderer]^C^CILS_ETF_Etagenfoerderer [Durch TEF angetriebene Strecke]^C^CILS_TEF_Strecke [VarioFoerderer]^C^CVarioFoerderer +[EtageVarioFoerderer]^C^CETAGEVARIOFOERDERER [--] [90 Kurve links angetrieben Aussen]^C^CILS_K90LA [90 Kurve rechts angetrieben Aussen]^C^CILS_K90RA