;; KreiselInsert.lsp ;; Kreisel Modul-Einfuegesystem mit Compound-Block ;; Version: 5.0 (Compound Block + 2-Linien-Connect) ;; Setzt ssg_core.lsp voraus. ;; ============================================ ;; ============================================================ ;; TEIL 1: GLOBALE EINSTELLUNGEN ;; ============================================================ (setq block-pfad (getenv "DXFM_BLOCKS")) (if (or (null block-pfad) (= block-pfad "")) (progn (setq block-pfad "C:/Users/y.wang/Documents/dxfmakros/Blocks/") (alert (strcat "Umgebungsvariable DXFM_BLOCKS nicht gefunden.\nNutze Standardpfad: " block-pfad)) ) (setq block-pfad (strcat (vl-string-right-trim "/" (vl-string-translate "\\" "/" block-pfad)) "/")) ) (setq *block-path* block-pfad) (princ (strcat "\nBlock-Pfad aktiv: " block-pfad)) ;; Kreisel-Geometrie-Konstanten (setq *kreisel-durchmesser* 800.0) ;; Kreisdurchmesser AN8/SP8 (setq *kreisel-pin-abstand* 100.0) ;; Einrueckung PIN-Linie vom Kreisrand (setq *kreisel-default-laenge* 2300.0) ;; Standard-Tangentenlaenge ;; Standardwerte (if (null #Kreisel_Typ) (setq #Kreisel_Typ "PIN")) ;; ============================================================ ;; TEIL 2: HILFSFUNKTIONEN ;; ============================================================ ;; PIN-Typ abfragen. Rueckgabe: "PIN" oder "OhnePIN" (defun kreisel-ask-typ ( / typNum typ) (princ "\n[1] Kreisel mit PIN") (princ "\n[2] Kreisel ohne PIN") (princ (strcat "\nBitte waehlen <" (if (= #Kreisel_Typ "PIN") "1" "2") ">: ")) (setq typNum (getstring "")) (cond ((= typNum "2") (setq typ "OhnePIN")) (t (setq typ "PIN")) ) (setq #Kreisel_Typ typ) typ ) ;; Punkt auf Gerade projizieren (Fusspunkt der Senkrechten) ;; pt = beliebiger Punkt; lstart/lend = Geradenendpunkte (jeweils 2D) ;; Rueckgabe: 2D-Punkt auf der Geraden (defun kreisel-project-point (pt lstart lend / dx dy tval) (setq dx (- (car lend) (car lstart)) dy (- (cadr lend) (cadr lstart))) (setq tval (/ (+ (* (- (car pt) (car lstart)) dx) (* (- (cadr pt) (cadr lstart)) dy)) (+ (* dx dx) (* dy dy)))) (list (+ (car lstart) (* tval dx)) (+ (cadr lstart) (* tval dy))) ) ;; Linien-Endpunkte aus LINE-Entity lesen ;; Rueckgabe: ((sx sy) (ex ey)) (defun kreisel-get-line-pts (ent / ed p10 p11) (setq ed (entget ent)) (setq p10 (cdr (assoc 10 ed)) p11 (cdr (assoc 11 ed))) (list (list (car p10) (cadr p10)) (list (car p11) (cadr p11))) ) ;; Pruefen ob zwei Richtungsvektoren parallel sind ;; Normiertes Kreuzprodukt < Toleranz (defun kreisel-parallel-p (d1 d2 / cross len1 len2) (setq cross (abs (- (* (car d1) (cadr d2)) (* (cadr d1) (car d2)))) len1 (sqrt (+ (* (car d1) (car d1)) (* (cadr d1) (cadr d1)))) len2 (sqrt (+ (* (car d2) (car d2)) (* (cadr d2) (cadr d2))))) (< (/ cross (* len1 len2)) 0.01) ) ;; ============================================================ ;; TEIL 3: COMPOUND BLOCK ERZEUGEN UND EINFUEGEN ;; ============================================================ ;; Zeichnet Kreisel-Geometrie bei (0,0), erzeugt Block, fuegt ihn ein. ;; ;; basePoint = Einfuegepunkt (2D-Liste), AN-Seite ;; abstand = Tangentenlaenge zwischen Kreismitten ;; typ = "PIN" oder "OhnePIN" ;; rotation = Einfuegewinkel in Grad (0=rechts, 90=oben, 180=links, 270=unten) ;; ;; Blockgeometrie (bei Rotation 0, horizontal): ;; Basispunkt (0,0) = linke Kreistangente (AN-Seite) ;; AN8 Zentrum bei (radius, 0) ;; SP8 Zentrum bei (radius+abstand, 0) ;; Gesamtbreite = durchmesser + abstand ;; ;; Rueckgabe: Entity-Name des eingefuegten Blocks (defun draw-module (basePoint abstand typ rotation / lastEnt ss e bname radius pin-y) ;; Abgeleitete Masse (setq radius (/ *kreisel-durchmesser* 2.0)) (setq pin-y (- radius *kreisel-pin-abstand*)) ;; Letzte Entity vor dem Zeichnen merken (setq lastEnt (entlast)) ;; --- Geometrie bei Ursprung (0,0) zeichnen --- ;; AN8 Kreis (Antriebsstation) bei (radius, 0) (command "_.INSERT" (strcat block-pfad "AN8.dwg") (list radius 0.0) 1 1 0) ;; SP8 Kreis (Spannstation) bei (radius+abstand, 0) (command "_.INSERT" (strcat block-pfad "SP8.dwg") (list (+ radius abstand) 0.0) 1 1 0) ;; Tangenten auf Layer S_LP (ssg-make-layer "S_LP" "7" T) (if (= typ "PIN") (setvar "CECOLOR" "5") (setvar "CECOLOR" "1") ) ;; Obere Tangente (command "_.LINE" (list radius radius) (list (+ radius abstand) radius) "") ;; Untere Tangente (command "_.LINE" (list radius (- radius)) (list (+ radius abstand) (- radius)) "") ;; PIN-Linien (if (= typ "PIN") (progn (ssg-make-layer "pinbereich" "3" T) (command "_LAYER" "_LT" "2punkt" "pinbereich" "") (setvar "CECOLOR" "3") ;; Obere PIN-Linie (command "_.LINE" (list *kreisel-durchmesser* pin-y) (list (float abstand) pin-y) "") ;; Untere PIN-Linie (command "_.LINE" (list *kreisel-durchmesser* (- pin-y)) (list (float abstand) (- pin-y)) "") ) ) ;; --- Neue Entities einsammeln --- (setq ss (ssadd)) (setq e (entnext lastEnt)) (while e (ssadd e ss) (setq e (entnext e)) ) ;; --- Block erzeugen (Entities werden aus Zeichnung entfernt) --- (setq bname (strcat "KR_" (ssg-make-blockname (list (car basePoint) (cadr basePoint) 0.0)))) (command "_.-BLOCK" bname (list 0.0 0.0 0.0) ss "") ;; --- Block am Zielpunkt mit Rotation einfuegen --- (command "_.INSERT" bname basePoint 1 1 rotation) (entlast) ) ;; ============================================================ ;; TEIL 4: BEFEHLE ;; ============================================================ ;; -------------------------------------------- ;; KreiselInsert: Manuell Position + Parameter ;; -------------------------------------------- (defun c:KreiselInsert ( / pt abstand typ rotation rotStr) (ssg-start "Kreisel Modul einfuegen" '(("OSMODE") ("CECOLOR"))) (setvar "OSMODE" 0) ;; 1. Einfuegepunkt (setq pt (getpoint "\nBasispunkt (AN-Seite): ")) (if (null pt) (exit)) ;; 2. Abstand (zeigen oder tippen) (initget 6) (setq abstand (getdist pt (strcat "\nAbstand (Tangentenlaenge) zeigen oder eingeben <" (rtos *kreisel-default-laenge* 2 0) ">: "))) (if (null abstand) (setq abstand *kreisel-default-laenge*)) ;; 3. Rotation (setq rotStr (getstring "\nRotation in Grad <0>: ")) (if (= rotStr "") (setq rotation 0.0) (setq rotation (atof rotStr)) ) ;; 4. Typ (setq typ (kreisel-ask-typ)) (princ (strcat "\n-> Abstand: " (rtos abstand 2 0) " Rotation: " (rtos rotation 2 1) " Typ: " typ)) ;; 5. Modul einfuegen (draw-module (list (car pt) (cadr pt)) abstand typ rotation) (princ "\nKreisel Modul eingefuegt.") (ssg-end) ) ;; ----------------------------------------------- ;; KreiselConnect: 2 parallele Linien anklicken ;; ;; Ablauf: ;; 1. Erste Linie anklicken -> AN-Position (Antriebsstation) ;; 2. Zweite Linie anklicken -> SP-Seite (Spannstation) ;; 3. Richtung + Abstand werden aus der Geometrie berechnet ;; 4. Nur PIN ja/nein wird abgefragt ;; ;; Beide Linien muessen parallel sein und gleiche Z-Koordinate haben. ;; Horizontale und vertikale Linien werden unterstuetzt. ;; ----------------------------------------------- (defun c:KreiselConnect ( / sel1 ent1 pt1 sel2 ent2 pt2 lpts1 lpts2 s1 e1 s2 e2 dir1 dir2 snap1 foot dx dy dist abstand rotation typ ok msg) (ssg-start "Kreisel Smart Connect" '(("OSMODE") ("CECOLOR"))) (setvar "OSMODE" 0) (setq ok T msg nil) (princ "\n--- Kreisel zwischen zwei parallelen Linien ---") ;; 1. Erste Linie anklicken (AN-Seite) (if ok (progn (setq sel1 (entsel "\nErste Linie anklicken (AN-Seite): ")) (cond ((null sel1) (setq ok nil)) ((/= (cdr (assoc 0 (entget (car sel1)))) "LINE") (setq ok nil msg "Erste Auswahl ist kein LINE-Objekt!")) ) ) ) ;; 2. Zweite Linie anklicken (SP-Seite) (if ok (progn (setq sel2 (entsel "\nZweite Linie anklicken (SP-Seite): ")) (cond ((null sel2) (setq ok nil)) ((/= (cdr (assoc 0 (entget (car sel2)))) "LINE") (setq ok nil msg "Zweite Auswahl ist kein LINE-Objekt!")) ) ) ) ;; 3. Geometrie auswerten (if ok (progn (setq ent1 (car sel1) pt1 (cadr sel1)) (setq ent2 (car sel2) pt2 (cadr sel2)) ;; Linien-Endpunkte lesen (setq lpts1 (kreisel-get-line-pts ent1) s1 (car lpts1) e1 (cadr lpts1)) (setq lpts2 (kreisel-get-line-pts ent2) s2 (car lpts2) e2 (cadr lpts2)) ;; Richtungsvektoren (setq dir1 (list (- (car e1) (car s1)) (- (cadr e1) (cadr s1)))) (setq dir2 (list (- (car e2) (car s2)) (- (cadr e2) (cadr s2)))) ;; Parallelitaet pruefen (if (not (kreisel-parallel-p dir1 dir2)) (setq ok nil msg "Linien sind nicht parallel!") ) ) ) ;; 4. Positionen und Abstand berechnen (if ok (progn ;; Klickpunkt exakt auf Linie 1 projizieren (setq snap1 (kreisel-project-point (list (car pt1) (cadr pt1)) s1 e1)) ;; Von snap1 senkrecht auf Linie 2 projizieren (setq foot (kreisel-project-point snap1 s2 e2)) ;; Richtung und Distanz (setq dx (- (car foot) (car snap1)) dy (- (cadr foot) (cadr snap1))) (setq dist (sqrt (+ (* dx dx) (* dy dy)))) (setq abstand (- dist *kreisel-durchmesser*)) (if (<= abstand 0.0) (setq ok nil msg (strcat "Abstand zwischen Linien zu klein! (" (rtos dist 2 0) " < " (rtos *kreisel-durchmesser* 2 0) ")")) ) ) ) ;; 5. Rotation berechnen und Modul einfuegen (if ok (progn ;; Winkel von AN-Punkt (snap1) zum SP-Fusspunkt (foot) (setq rotation (* (/ 180.0 pi) (atan dy dx))) ;; Typ abfragen (einzige Benutzer-Eingabe) (setq typ (kreisel-ask-typ)) (princ (strcat "\n-> Abstand: " (rtos abstand 2 0) " mm" " Rotation: " (rtos rotation 2 1) " Grad" " Typ: " typ)) ;; Modul als Compound-Block einfuegen (draw-module snap1 abstand typ rotation) (princ "\nKreisel Connect erfolgreich!") ) ;; Fehlerfall (if msg (ssg-emsg msg) (princ "\nAbgebrochen.")) ) (ssg-end) ) ;; -------------------------------------------- ;; KreiselQuick: Schnell mit Defaults (horizontal) ;; -------------------------------------------- (defun c:KreiselQuick ( / pt) (ssg-start "Kreisel Schnell Einfuegen" '(("OSMODE") ("CECOLOR"))) (setvar "OSMODE" 0) (setq pt (getpoint "\nBasispunkt (AN-Seite): ")) (if pt (draw-module (list (car pt) (cadr pt)) *kreisel-default-laenge* #Kreisel_Typ 0.0) ) (princ "\nSchnell Einfuegen fertig.") (ssg-end) ) ;; -------------------------------------------- ;; KreiselParams: Aktuelle Parameter anzeigen ;; -------------------------------------------- (defun c:KreiselParams () (princ "\n=== Aktuelle Kreisel Parameter ===") (princ (strcat "\nTyp: " #Kreisel_Typ)) (princ "\nBasispunkt: AN-Seite (Antriebsstation)") (princ "\nBlock: Compound (AN8 + SP8 + Tangenten + PIN)") (princ "\n===================================\n") (princ) ) (princ "\nKreiselInsert.lsp geladen (Version 5.0 - Compound Block)") (princ "\nBefehle: KreiselInsert, KreiselConnect, KreiselQuick, KreiselParams") (princ)