;; ============================================================ ;; TEFInsert.lsp - TEF-Geradenstuecke entlang einer Linie ;; ;; Zeichnet eine Linie zwischen zwei vom Benutzer gewaehlten Punkten ;; und reiht darauf 1000 mm lange TEF-Geradenelemente ;; (data/omniflo//0_B10030.dxf, $INSBASE=Ursprung=Anfang des ;; Elements, Ende bei lokal X=1000) aneinander. ;; ;; Ist die Linienlaenge kein exaktes Vielfaches von 1000 mm, wird fuer ;; das letzte Stueck ein zusaetzliches Element eingefuegt, das auf der ;; Linie zurueckverschoben platziert wird (ueberlappt das vorletzte ;; Element), sodass der Foerderer exakt am Linienende endet - statt ;; einer Luecke oder eines abgeschnittenen Elements. ;; ;; Die Linie darf geneigt sein (3D): Start-/Endpunkt koennen ;; unterschiedliche Z-Werte haben, die Elemente werden dann analog zu ;; vf_core.lsp (Rz(hz)*Ry(winkel)-Rotation, winkel positiv=abwaerts) ;; gekippt eingefuegt. ;; ;; Befehl: TEF_FOERDERER_LINIE ;; ============================================================ (vl-load-com) (if (null doc) (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))) (if (null modelspace) (setq modelspace (vla-get-ModelSpace doc))) ;; Elementlaenge (mm) von 0_B10030.dxf (siehe Header-Kommentar oben) (if (null *tefl-elementlaenge*) (setq *tefl-elementlaenge* 1000.0)) ;; Toleranz (mm): Restlaenge unterhalb dieses Werts gilt als "exaktes ;; Vielfaches der Elementlaenge" -> kein Zusatzelement noetig. (if (null *tefl-toleranz*) (setq *tefl-toleranz* 0.5)) ;; Dateiname (ohne .dxf) des TEF-Geradenelements in DXFM_OMNIFLO (if (null *tefl-blockname*) (setq *tefl-blockname* "0_B10030")) ;; ------------------------------------------------------------ ;; Pfad zur Element-DXF ermitteln (DXFM_OMNIFLO, wie omni:insert-dxf ;; in OmniModulInsert.lsp). ;; ------------------------------------------------------------ (defun tefl-dxf-pfad ( / omniflo-pfad) (setq omniflo-pfad (getenv "DXFM_OMNIFLO")) (if omniflo-pfad (strcat (vl-string-translate "\\" "/" omniflo-pfad) "/" *tefl-blockname* ".dxf") ) ) ;; ------------------------------------------------------------ ;; Element-DXF einmalig als Block registrieren (Analog zu ;; ensure-block-loaded in vf_core.lsp, aber fuer eine externe .dxf statt ;; .dwg): einmal am Ursprung einfuegen und wieder loeschen, damit die ;; Datei als Block-Tabelleneintrag *tefl-blockname* existiert. Danach ;; kann jede weitere Einfuegung ueber vla-InsertBlock + vla-TransformBy ;; mit voller 3D-Rotation erfolgen (das kann die reine command-Zeilen- ;; INSERT nicht leisten - die dreht nur um die Z-Achse). ;; ------------------------------------------------------------ (defun tefl-ensure-block-loaded (dxf-pfad / tmpEnt) (if (not (tblsearch "BLOCK" *tefl-blockname*)) (progn (command "_.INSERT" dxf-pfad (list 0.0 0.0 0.0) 1 1 0) (while (> (getvar "CMDACTIVE") 0) (command "")) (setq tmpEnt (entlast)) (if (and tmpEnt (= (cdr (assoc 0 (entget tmpEnt))) "INSERT")) (command "_.ERASE" tmpEnt "") ) ) ) (tblsearch "BLOCK" *tefl-blockname*) ) ;; ------------------------------------------------------------ ;; Ein Element an Position 's' (mm ab Startpunkt) entlang der ;; Fahrtrichtung einfuegen. ;; start : Startpunkt der Linie (3D) ;; richtung-einheit : Einheitsvektor der Fahrtrichtung (3D) ;; hz / winkel : Fahrtrichtung in Grad (Rz(hz)*Ry(winkel)-Konvention ;; wie hz-winkel->xu/frame->hz-winkel in vf_core.lsp) ;; ;; Attribute: vla-InsertBlock legt fuer ein Block mit ATTDEFs automatisch ;; ATTRIB-Entities mit den Vorgabewerten aus der Quell-DXF an (wie beim ;; command-Zeilen-INSERT mit ATTREQ=0). Analog zu omni:insert-dxf in ;; OmniModulInsert.lsp wird danach nur das LAYER-Attribut ausgelesen und ;; der Block auf diesen Layer verschoben - alle anderen Attribute ;; (ARTINR, BESCHR, MENGE, POSITION, DETAILS, ...) behalten den aus der ;; Quell-DXF uebernommenen Vorgabewert. ;; ------------------------------------------------------------ (defun tefl-insert-element (start richtung-einheit s hz winkel / rad-h rad-v chv shv cvv svv matrix block-obj blockEnt pt attribs layer-name) (setq pt (list (+ (car start) (* s (car richtung-einheit))) (+ (cadr start) (* s (cadr richtung-einheit))) (+ (caddr start) (* s (caddr richtung-einheit))))) (setq rad-h (* (float hz) (/ pi 180.0))) (setq rad-v (* (float winkel) (/ pi 180.0))) (setq chv (cos rad-h) shv (sin rad-h) cvv (cos rad-v) svv (sin rad-v)) (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point '(0.0 0.0 0.0)) *tefl-blockname* 1.0 1.0 1.0 0)) (setq matrix (list (list (* chv cvv) (- shv) (* chv svv) 0) (list (* shv cvv) chv (* shv svv) 0) (list (- svv) 0 cvv 0) (list 0 0 0 1))) (vla-TransformBy block-obj (vlax-tmatrix matrix)) (vla-Move block-obj (vlax-3D-point '(0.0 0.0 0.0)) (vlax-3D-point pt)) ;; LAYER-Attribut auslesen und Block auf diesen Layer verschieben (setq blockEnt (vlax-vla-object->ename block-obj)) (setq attribs (ssg-attrib-read blockEnt)) (setq layer-name (cdr (assoc "LAYER" attribs))) (if (and layer-name (> (strlen layer-name) 0)) (progn (ssg-make-layer layer-name 7 nil) (entmod (subst (cons 8 layer-name) (assoc 8 (entget blockEnt)) (entget blockEnt))) (entupd blockEnt) ) ) ;; Eindeutige ID zuweisen, falls das Block-Schema ein ID-Attribut fuehrt ;; (bei 0_B10030 aktuell nicht der Fall - dann folgenlos, wie in ;; omni:insert-dxf). (if (atoms-family 1 '("ssg-id-generate")) (ssg-id-generate blockEnt) ) block-obj ) ;; ------------------------------------------------------------ ;; Hauptbefehl: Start-/Endpunkt abfragen, Linie zeichnen, TEF-Geraden- ;; elemente entlang der Linie aneinanderreihen. ;; ------------------------------------------------------------ (defun c:TEF_FOERDERER_LINIE ( / dxf-pfad p1 p2 dx dy dz laenge horiz hz winkel richtung-einheit anzahl-voll rest i s) (setq dxf-pfad (tefl-dxf-pfad)) (cond ((null dxf-pfad) (princ (ssg-text "tefl-fehler-dxfm-omniflo"))) ((not (findfile dxf-pfad)) (princ (ssg-textf "tefl-fehler-dxf-nicht-gefunden" (list dxf-pfad)))) (t (setq p1 (getpoint (ssg-text "tefl-prompt-startpunkt"))) (if (null p1) (princ (ssg-text "tefl-abgebrochen")) (progn (setq p2 (getpoint p1 (ssg-text "tefl-prompt-endpunkt"))) (if (null p2) (princ (ssg-text "tefl-abgebrochen")) (progn (setq dx (- (car p2) (car p1)) dy (- (cadr p2) (cadr p1)) dz (- (caddr p2) (caddr p1))) (setq laenge (sqrt (+ (* dx dx) (* dy dy) (* dz dz)))) (if (< laenge *tefl-toleranz*) (princ (ssg-text "tefl-fehler-laenge-null")) (progn (ssg-start "TEF Foerderer Linie" '(("OSMODE") ("ATTREQ") ("ATTDIA"))) (setvar "ATTREQ" 0) (setvar "ATTDIA" 0) (if (not (tefl-ensure-block-loaded dxf-pfad)) (progn (princ (ssg-textf "tefl-fehler-dxf-nicht-gefunden" (list dxf-pfad))) (ssg-end) ) (progn ;; Fahrtrichtung als Einheitsvektor + hz/winkel (setq richtung-einheit (list (/ dx laenge) (/ dy laenge) (/ dz laenge))) (setq horiz (sqrt (+ (* dx dx) (* dy dy)))) (setq hz (* (atan dy dx) (/ 180.0 pi))) (setq winkel (* (atan (- dz) horiz) (/ 180.0 pi))) ;; Linie zwischen den beiden Punkten zeichnen (entmake (list '(0 . "LINE") (cons 8 (getvar "CLAYER")) (cons 10 p1) (cons 11 p2))) ;; Volle Elemente ab dem Startpunkt aneinanderreihen (setq anzahl-voll (fix (/ (+ laenge *tefl-toleranz*) *tefl-elementlaenge*))) (setq i 0) (repeat anzahl-voll (tefl-insert-element p1 richtung-einheit (* i *tefl-elementlaenge*) hz winkel) (setq i (1+ i)) ) ;; Restlaenge: Zusatzelement zurueckverschoben einfuegen, ;; damit der Foerderer exakt am Linienende (p2) endet. (setq rest (- laenge (* anzahl-voll *tefl-elementlaenge*))) (if (> rest *tefl-toleranz*) (progn (setq s (- laenge *tefl-elementlaenge*)) (tefl-insert-element p1 richtung-einheit s hz winkel) (setq anzahl-voll (1+ anzahl-voll)) ) ) (princ (ssg-textf "tefl-fertig" (list (itoa anzahl-voll) (rtos laenge 2 0)))) (ssg-end) ) ) ) ) ) ) ) ) ) ) (princ) ) (princ "\nTEFInsert.lsp geladen. Befehl: TEF_FOERDERER_LINIE") (princ)