..., AutoLISP, CADPL-Pack

Jednostki wstawienia bloku

Kilka słów o definiowaniu bloków – a właściwie o jednej z możliwych opcji dostępnej w oknie Definicji bloku, mianowicie o jednostkach bloku. Ta właściwość pojawiła się w wersji AutoCAD 2001, wcześniej bloki nie miały predefiniowanej wartości jednostek.

blockinsunits0

Jest to kod 70 danych DXF obiektu typu BLOCK_RECORD, jego wartości to liczby całkowite od 0 do 24 (w AutoCAD 2017 dodano cztery ostatnie pozycje). W modelu ActiveX jest to odpowiednik właściwości Units, obiektu Block. Ich wartości są następujące:
0 = bez jednostek
1 = cale
2 = stopy
3 = mile
4 = milimetry
5 = centymetry
6 = metry
7 = kilometry
8 = mikrocale
9 = milicale
10 = jardy
11 = angstremy
12 = nanometry
13 = mikrony
14 = decymetry
15 = dekametry
16 = hektometry
17 = gigametry
18 = jednostki astronomiczne
19 = lata świetlne
20 = parseki
21 = Stopy geodezyjne US Survey
22 = cal geodezyjny US Survey
23 = jard geodezyjny US Survey
24 = mila geodezyjna US Survey

Podczas przeciągania bloku na przykład z palety narzędzi do rysunku jest on automatycznie skalowany na podstawie współczynnika będącego stosunkiem jednostek zdefiniowanych w rysunku (zmienna systemowa INSUNITS) do jednostek zdefiniowanych w bloku. Właściwość ta może jednak być czasami uciążliwa, z powodu nieprzewidzianego skalowania bloku, stąd zasada aby jeśli nie jest to konieczne, definiować bloki z nastawą jednostek = 0 (czyli bez jednostek – unitless), wydaje się być dobrym pomysłem.

Dla istniejących, wcześniej już zdefiniowanych bloków (z wartością Units inną niż unitless), napisałem krótkie narzędzie które zmienia właściwość Units na 0 (czyli bez jednostek). Kod programu wygląda tak:


; =============================================================== ;
; C:BUN by kojacek 2017
; Dla wszystkich blokow ustawia jednoski wstawienia jako Unitless
; (bez jednostek). Wymaga CADPL-Pack-v1.lsp
; =============================================================== ;
(defun C:BUN (/ l i -GetBlockInsUnits)
  (defun -GetBlockInsUnits ()
    (mapcar
      '(lambda (%)
         (cons (vla-get-Units (vla-item (cd:ACX_Blocks) %)) %)
      )
      (cd:SYS_CollList "BLOCK" (+ 1 2 4))
    )
  )
  (if
    (setq l (-GetBlockInsUnits))
    (if
      (setq l (vl-remove-if '(lambda (%)(zerop (car %))) l))
      (progn
        (setq i (length l))
        (cd:SYS_UndoBegin)
        (foreach % (setq l (mapcar 'cdr l))
          (vla-put-Units (vla-item (cd:ACX_Blocks) %) 0)
        )
        (cd:SYS_UndoEnd)
        (princ
          (strcat "\nDla " (itoa i)
            " bloków usunięto jednostki wstawienia. "
          )
        )
      )
      (princ "\nNie ma bloków z ustaloną jednostką wstawienia. ")
    )
    (princ "\nW rysunku nie ma bloków. ")
  )
  (princ)
)
; =============================================================== ;
(princ)

Do prawidłowego działania wymaga wczytanej biblioteki CADPL-Pack. Wywołanie makra poleceniem BUN.

AutoCAD, AutoLISP

Kalkulator…

Już wiele lat temu chciałem napisać parę słów o autocadowskim kalkulatorze geometrycznym… Zwłoka w tym poskutkowała tym, że przez ten czas z prostego działającego tylko w linii poleceń kalkulatora geometrycznego, ów przemienił się w pełnowartościowy graficzny kalkulator:

calc01

Na szczęście, przy okazji nie stracił swoich mechanizmów do obliczeń geometrycznych w przestrzeni rysunkowej AutoCAD-a, z których to przez wiele lat korzystałem. Oczywiście nie ze wszystkich, ale jest kilka z nich które z pamięci wklepuję podczas rysowania „z ręki”… I właśnie o nich będzie dzisiejszy wpis.

  1.  Znajdowanie punktu przecięcia dwóch linii, czyli użycie zmiennej o nazwie ille (funkcji kalkulatora – ill). Poniższy obraz jasno ilustruje działanie: cal_ille Wywołanie w trybie nakładkowym (z apostrofem) w trakcie działania polecenia LINIA, kalkulatora i następnie wyrażenia ille. Wymaga ona wskazania par końców linii (właściwe lokalizacji END) – tutaj są to punkty o numerach 1 – 2 i 3 – 4. Kalkulator wyliczył punkt 5 i przekazał je do polecenia LINIA. Oczywiście działa to w przestrzeni 3D – wskazywanie nie muszą być na jednej płaszczyźnie.
  2. Znajdowanie w szybki sposób wartości promienia narysowanych łuków, okręgów, czy łukowych segmentów polilinii, czyli funkcja radcal_rad Nic nie trzeba mierzyć, wymiarować tylko wywołać kalkulator, funkcję rad, i wskazać interesujący nas element. Bardzo ważna i cenna cecha – element może być częścią bloku – kalkulator nie ma z tym problemu.
  3. Szybkie obliczenia w linii poleceń (jak też jako wywołania AutoLISP). Kalkulator dokonuje obliczeń podanych w linii poleceń zgodnie z zasadami – nie musimy się tutaj martwić o kolejność działań. Chyba że chcemy inaczej, wtedy możemy użyć nawiasów. cal_calc
  4. Ponownie obliczenie punktów przecięcia. Tym razem przecięcia linii wyznaczonej punktami 1 – 2 z płaszczyzną określoną przez punkty 3 – 4 – 5. Przydatne do precyzyjnego rysowania modeli 3D. Służy do tego funkcja ilp. Na poniższym obrazie przykład rysowania okręgu na płaszczyźnie w miejscu teoretycznego przecięcia z linią w przestrzeni 3D: cal_ilp Oczywiście jak wszędzie w wywołaniach kalkulatora można wywoływać inne (niż end w przykładach) tryby lokalizacji.

Bardzo cennymi cechami kalkulatora geometrycznego AutoCAD-a, to możliwość wykorzystania jego wyrażeń w języku AutoLISP, jak też w drugim kierunku, możliwość korzystania przez kalkulator ze zmiennych (punkty, wartości liczbowe) AutoLISP.  Ze względu na dość obszerną materię, przydałby się tutaj osobny wpis na ten temat (pomyślę o tym w przyszłości).

Na koniec, zestawienie wszystkich (mam nadzieję) funkcji kalkulatora geometrycznego, z krótkim opisem:

Funkcje numeryczne:
sin(ang) – Sinus kąta
cos(ang) – Cosinus kąta
tang(ang) – Tangens kąta
asin(real) – Arcus sinus liczby – liczba z przedziału od -1 do 1
acos(real) – Arcus cosinus liczby – liczba z przedziału od -1 do 1
atan(real) – Arcus tangens liczby
ln(real) – Logarytm naturalny liczby
log(real) – Logarytm dziesiętny liczby
exp(real) – Potęga liczby e
exp10(real) – Potęga liczby 10
sqr(real) – Kwadrat liczby
sqrt(real) – Pierwiastek kwadratowy z liczby nieujemnej
abs(real) – Wartość bezwzględna liczby
round(real) – Zaokrąglenie liczby do najbliższej liczby całkowitej
trunc(real) – Część całkowita liczby
r2d(ang) – Zamiana kąta w radianach na stopnie
d2r(ang) – Zamiana kąta w stopniach na radiany
pi – Stała pi

Funkcje geometryczne wektorów:
vec(p1,p2) – Wektor od punktu p1 do punktu p2
vec1(p1,p2) – Wektor jednostkowy od punktu p1 do punktu p2.
abs(v) – Oblicza długość wektora v, jako nieujemną liczbę rzeczywistą.
nor – Określa jednostkowy normalny wektor 3D wybranego okręgu, łuku lub łukowego segmentu polilinii.
nor(v) – Określa wektor jednostkowy 2D normalny do wektora v. Obydwa wektory są traktowane jako rzut 2D na płaszczyznę XY aktualnego lokalnego układu współrzędnych.
nor(p1,p2) – Określa wektor jednostkowy 2D normalny do linii p1,p2 – linia jest skierowana od punktu p1 do p2.
nor(p1,p2,p3) – Określa wektor jednostkowy 3D normalny do płaszczyzny zdefiniowanej przez trzy punkty p1, p2, oraz p3.

Konwersja punktów między UCS a UCS (lokalnym a globalnym układem współrzędnych):
w2u(p1) – Przekształca punkt p1 wyrażony w GUW do aktualnego LUW.
u2w(p1) – Przekształca punkt p1 wyrażony w aktualnym LUW do GUW.

Wyznaczanie punktu na linii:
pld(p1,p2,dist) – Wyznacza punkt na linii przechodzącej przez punkty p1 oraz p2. Parametr dist definiuje odległość tego punktu od punktu p1.
plt(p1,p2,t) – Wyznacza punkt na linii przechodzącej przez punkty p1 oraz p2. Parametr t definiuje pozycję punktu na linii.

Obliczanie obrotu punktu:
rot(p1,origin,ang) – Obraca punkt p1 o kąt ang dookoła osi Z przechodzącej przez punkt origin
rot(p1,AxP1,AxP2,ang) – Obraca punkt p1 o kąt ang dookoła osi przechodzącej przez punkty AxP1 oraz AxP2

Punkty przecięcia obiektów:
ill(p1,p2,p3,p4) – Określa punkt przecięcia między dwoma liniami (p1,p2) oraz (p3,p4).
ilp(p1,p2,p3,p4,p5) – Określa punkt przecięcia między linią (p1,p2) i płaszczyzną przechodzącą przez trzy punkty (p3,p4,p5).

Obliczanie odległości:
dist(p1,p2) – Określa odległość pomiędzy dwoma punktami, p1 i p2. Taką samą wartość zwraca wyrażenie wektorowe abs(p1-p2).
dpl(p,p1,p2) – Określa najkrótszą odległość między punktem p oraz linią przechodzącą przez punkty p1 oraz p2.
rad – Funkcja rad określa promień wybranego obiektu.

Obliczenia kątów:
ang(v) – Określa kąt pomiędzy osią X i wektorem v. Wektor v jest traktowany jako rzut 2D na płaszczyznę XY aktualnego układu współrzędnych.
ang(p1,p2) – Kąt pomiędzy osią X i linią (p1,p2). Punkty traktowane są jako rzut 2D na płaszczyznę XY aktualnego UCS
ang(apex,p1,p2) – Określa kąt pomiędzy liniami (apex,p1) i (apex,p2). Punkty traktowane są jako rzut 2D na płaszczyznę XY aktualnego UCS
ang(apex,p1,p2,p) – Określa kąt pomiędzy liniami (apex,p1) i (apex,p2). Tym razem proste są traktowane jako trójwymiarowe. Ostatni parametr, punkt p, jest używany do zdefiniowania orientacji kąta.

 

AutoLISP, CADPL-Pack

NOD – zestawienie

NOD czyli Named Objects Dictionary, jest miejscem przechowywania wszystkich danych niegraficznych, rysunku AutoCAD-a, typu słownik, xrecord, lub innych danych o podobnej strukturze. Temat NOD podejmowałem już TUTAJ. Tym razem przedstawiam krótki program, „dokumentujący” nazwy spotykanych nazw obiektów w rysunkach AutoCAD-a. Wiadomo że, oprócz typowych i standardowych słowników tworzonych przez AutoCAD-a, inne aplikacje (Autodesk-u jak też niezależne), mogą tworzyć, swoje własne wpisy w Named Objects Dictionary. Stąd pomysł aby zapisywać unikane nazwy w pliku tekstowym, który w ten sposób zbiera w jednym miejscu wszystkie spotykane wpisy w NOD. O ile w standardowym takich wpisów jest około trzydziestu, to po sprawdzeniu kilku różnych rysunków, zdołałem utworzyć listę składającą się z 72  obiektów:

dictlist1Działanie programu jest stosunkowo proste.  Po wywołaniu polecenia DICTLIST, tworzona jest lista słowników w aktywnym rysunku. Dodawana jest do listy odczytanej z pliku tekstowego. Po połączeniu i usunięciu duplikatów, plik tekstowy jest aktualizowany.  W ten sposób plik z nazwami powiększa się tylko o unikalne wpisy. Zawartość pliku tekstowego DictList.txt wygląda tak:

dictlist2Definicja polecenia DICTLIST przedstawiona jest poniżej.


; ===================================================================== ;
;; DictList.lsp by kojacek 2017                                         ;
; ===================================================================== ;
; Polecenie DICTLIST tworzy i uzupelnia w pliku tekstowym DictList.txt  ;
; liste unikalnych nazw obiektow w Named Object Dictionary.             ;
; Wymaga: CADPL-Pack-v1.lsp                                             ;
; --------------------------------------------------------------------- ;

(defun C:DICTLIST (/ p n f d :dialog :deldup)
  (defun :deldup (Lst)
    (foreach % Lst (setq Lst (cons % (vl-remove % Lst))))
  )
  (defun :dialog (File / d i)
    (setq d (cd:SYS_ReadFile nil File)
          i (itoa (length d))
    )
    (cd:DCL_StdListDialog d 0
      (strcat "DictList (" i " obiektów)")
      "Szczegóły: " 55 25 0 13 (list "&OK" "&Zamknij")
      nil T T nil
    )
  )
  (setq p (vl-filename-directory (findfile "DictList.lsp"))
        f (findfile (setq n (strcat p "\\" "DictList.txt")))
  )
  (if
    (not f)
    (progn
      (setq d
        (acad_strlsort (cd:DCT_GetDictList (namedobjdict) nil))
      )
      (cd:SYS_WriteFile n d nil)
      (:dialog n)
    )
    (progn
      (setq d
        (acad_strlsort
          (:deldup
            (append
              (cd:DCT_GetDictList (namedobjdict) nil)
              (cd:SYS_ReadFile nil n)
            )
          )
        )
      )
      (cd:SYS_WriteFile n d nil)
      (:dialog n)
    )
  )
  (princ)
)
; --------------------------------------------------------------------- ;
(princ)

Oczywiście (tradycyjnie już) wykorzystałem w programie kilku funkcji dostępnych w CADPL-Pack‚u, którego wcześniejsze załadowanie zapewnia poprawne działanie. Plik programu musi znajdować w bibliotecznej ścieżce poszukiwań AutoCAD-a.

AutoLISP, CADPL-Pack

Dopełnienie łuku PLUS

W jednym z wrześniowych wpisów ubiegłego roku przedstawiłem krótki program służący do rysowania „dopełnienia łuku”. Dziś pewne rozszerzenie tego makra, polegające na dodaniu dwóch nowych opcji, do polecenia ARCC.

arcc-plus0

Pierwsza opcja – automatyczne rysowanie dla wskazanych łuków i łuków eliptycznych linii łączących końce ze środkiem. Opcja, jako słowo kluczowe polecenia (ze względu na łuk) nazywa się pRomień:

arcc-plus1

Druga opcja łączy linią końce wskazanych łuków. Słowo kluczowe polecenia to Cięciwa:

arcc-plus2

Nowe obiekty rysowane są z cechami (warstwa, kolor, rodzaj linii itd.) wskazywanych łuków i łuków eliptycznych. Poniżej kod programu w całości:


; =================================================================== ;
; Polecenie ARCC tworzy dopelnienie luku i luku eliptycznego.         ;
; Wymaga CADPL-Pack-v1.lsp                                            ;
; 2016, 2017 kojacek                                                  ;
; ------------------------------------------------------------------- ;
(defun C:ARCC (/ ss an lo _arcc)
  (defun _arcc (Mode SS / l s e o d r v c a b)
    (setq l (cd:SSX_Convert ss 0))
    (foreach % l
      (setq d (entget %) o (cdr (assoc 0 d))
            c (cdr (assoc 10 d))
            v (list (cons 0 "LINE"))
      )
      (cond
        ( (= "ARC" o)
          (setq s (cdr (assoc 50 d)) e (cdr (assoc 51 d))
                r (cdr (assoc 40 d))
                d (cd:DXF_RemoveDXF d (list 50 51))
                d (append d (list (cons 50 e)(cons 51 s)))
          )
          (cond
            ( (zerop Mode)(entmod d))
            ( (= 1 Mode)
              (setq d (cd:DXF_RemoveDXF d (list -1 0 5 50 51 100))
                    d (append (list (cons 0 "CIRCLE")) d)
              )
              (entmakex d)(entdel %)
            )
            ( (= 2 Mode)(entmakex d))
            ( (= 3 Mode)
              (setq d
                (cd:DXF_RemoveDXF d (list -1 0 5 40 50 51 100 330))
              )
              (foreach % (list s e)
                (entmakex
                  (append v (list (cons 11 (polar c % r))) d)
                )
              )
            )
            ( (= 4 Mode)
              (setq d
                (cd:DXF_RemoveDXF d (list -1 0 5 10 40 50 51 100 330))
              )
              (entmakex
                (append v
                  (list
                    (cons 10 (polar c e r))
                    (cons 11 (polar c s r))
                  ) d
                )
              )
            )
            (t nil)
          )
        )
        ( (= "ELLIPSE")
          (setq s (cdr (assoc 41 d)) e (cdr (assoc 42 d))
                d (cd:DXF_RemoveDXF d (list 41 42))
                a (getpropertyvalue % "StartPoint")
                b (getpropertyvalue % "EndPoint")
                d (if
                    (= 1 Mode)
                    (append d (list (cons 41 0.0)(cons 42 (* 2 pi))))
                    (append d (list (cons 41 e)(cons 42 s)))
                  )
          )
          (cond
            ( (zerop Mode)(entmod d))
            ( (= 1 Mode)(entmakex d)(entdel %))
            ( (= 2 Mode)(entmakex d))
            ( (= 3 Mode)
              (setq d
                (cd:DXF_RemoveDXF d
                  (list -1 0 5 11 40 41 42 100 330)
                )
              )
              (foreach % (list a b)
                (entmakex
                  (append v (list (cons 11 %)) d)
                )
              )
            )
            ( (= 4 Mode)
              (setq d
                (cd:DXF_RemoveDXF d
                  (list -1 0 5 10 11 40 41 42 100 330)
                )
              )
              (entmakex
                (append v
                  (list
                    (cons 10 a)
                    (cons 11 b)
                  ) d
                )
              )
            )
            (t nil)
          )
        )
        (t nil)
      )
    )
  )
  (setq lo '("Usuń" "Zintegruj" "zAchowaj" "pRomień" "Cięciwa"))
  (princ "\nDopełnienie łuku i łuku eliptycznego ")
  (if
    (setq ss
      (ssget "_:L"
        (list
          (cons 410 (getvar "CTAB"))
          (cons -4 "<OR")
            (cons 0 "ARC")
            (cons -4 "<AND")
              (cons 0 "ELLIPSE")
              (cons -4 "/=")
              (cons 41 0.0)
            (cons -4 "AND>")
          (cons -4 "OR>")
        )
      )
    )
    (progn
      (if (not *cd-ArcC*)(setq *cd-ArcC* (nth 2 lo)))
      (setq an
        (cd:USR_GetKeyWord "\nDopełnienie łuku" lo *cd-ArcC*)
      )
      (if
        (member an lo)
        (progn
          (cd:SYS_UndoBegin)
          (_arcc (vl-position an lo) ss)
          (setq *cd-ArcC* an)
          (cd:SYS_UndoEnd)
        )
        (princ "\nPrzerwano polecenie.")
      )
    )
    (princ "\Nie wybrano łuków. ")
  )
  (princ)
)

Program wymaga oczywiście, załadowanego CADPL-Pack‚a.

AutoCAD

Nowa nazwa (1)

Parę słów o obiektach nazwanych. To przede wszystkim tablice symboli (o których wspominałem TUTAJ), czyli bloki, warstwy, rodzaje linii etc. Pomijając teraz powody dla których istnieje potrzeba zmiany nazwy takiego obiektu, omówię ich możliwości. Na początek oczywiście polecenie NNAZWA (_RENAME). Uruchamia okno dialogowe w którym można zmienić nazwy bloków, stylów szczegółu, stylów wymiarowania, warstw, rodzajów linii, materiałów, stylów wielolinii odniesienia, stylów przekroju, stylów wydruku, stylów tekstu, stylów tabel, lokalnych układów współrzędnych (UCS), widoków i rzutni. Polecenie choć znane – ma pewną cechę o której nie wszyscy wiedzą. Chodzi o wybór wielokrotny na liście elementów, oraz dodatkowo możliwość stosowania znaków zastępczych w wyborze:

rename0

Tak samo można stosować znaki zastępcze dla samej zmiany nazwy:

rename1

W efekcie zmianie podlega część nazwy, dla wielokrotnego wyboru:

rename2

Taki sposób znacznie poprawia efektywność procesu zmiany nazw, dla większej ilości elementów. Co ciekawe, forma polecenia w linii poleceń (-NNAZAWA / _-RENAME):

rename3

nie ma takich możliwości. Zarówno starą jak i nową nazwę trzeba podać w całości i tylko dla jednego elementu. Większości obiektów nazwanych (dostępnych w oknie polecenia NNAZWA), można zmienić nazwę w oknach lub paletach związanych z obiektem (np. menedżer warstw, okno stylów tekstu, wielolinii odniesienia itd.) przez dwuklik na liście, lub wybór opcji prawego klawisza myszy.

Inne nazwane obiekty mają możliwość zmiany nazwy w swoich oknach. Na przykład grupy – poleceniem GRUPAKLASYCZNA (_CLASSICGROUP):

rename4

Stany warstw w oknie polecenia WARSTAN (_LAYERSTATE):

rename5

Style multilinii – polecenie MLSTYL (_MLSTYLE)

rename6

Kolejnym nazwanym elementem, któremu można zmienić nazwę, niewyświetlanym w oknie NNAZWA, jest obiekt typu SCALE – edycja możliwa w oknie polecenia EDLISTYSKAL (_SCALELISTEDIT):

rename7

Zmiany nazw obiektów jak widać to stosunkowo szeroki temat. Ze względu na objętość tytuł dzisiejszego wpisu brzmi: Nowa nazwa (1), co sugeruje ciąg dalszy. Tak też planuję – w kolejnym wpisie omówię możliwości zmian nazw obiektów, przy pomocy LISP-a…

AutoCAD, AutoLISP

TEXT + BigFont

Czy możliwe jest napisanie poniżej prezentowanego wzoru w AutoCAD-zie? Oczywiście – wykorzystując tekst wielowierszowy (MTEXT), bez najmniejszego problemu. A zwykłym (jednowierszowym) tekstem, czyli obiektem typu TEXT?

bfont0

Też można, po spełnieniu dwóch warunków. Po pierwsze styl tekstu musi w definicji używać autocadowskiej czcionki SHX, oraz po drugie, styl powinien używać tak zwanej wielkiej czcionki czyli BigFont.

bfont1

Co to jest BigFont? To rozszerzenie typowego stylu tekstu (opartego na czcionce SHX), poprzez dołączenie dodatkowego pliku SHX, zawierającego definicje znaków języków azjatyckich. Alfabety azjatyckie zawierają bowiem tysiące znaków spoza zestawu znaków ASCII. Stosowanie standardowych BigFont, dołączanych do AutoCAD-a, umożliwia ich stosowanie w rysunku, do tworzenia tekstów chińskich, koreańskich czy japońskich. Ale nie tylko, bo także pozwala korzystać z alfabetu greckiego czy różnych innych znaków specjalnych.

bfont2

Okno polecenia STYL (_STYLE), widoczne powyżej ilustruje mechanizm utworzenia stylu tekstu wykorzystującego BigFont. Podstawowa czcionka simplex.shx, rozszerzona o wielką czcionkę special.shx.

Do tworzenia stylu tekstu z BigFont, można użyć poniższej funkcji lisp-owej:


;;; ================================================================ ;;;
;;; by kojacek 2016
;;; ================================================================ ;;;
(defun jk:TXT_MakeBFStyle (Name Font BFont Width / o b f s)
  (if
    (and
      (not (tblobjname "STYLE" Name))
      (setq f (findfile  Font))
      (setq b (findfile  BFont))
    )
    (if
      (setq s (cd:ENT_MakeTextStyle Name))
      (progn
        (setq o (vlax-ename->vla-object s))
        (vla-put-Fontfile o f)
        (vla-put-BigFontFile o b)
        (vla-put-Width o Width)
      )
    )
  )               
  (or (tblobjname "STYLE" Name))
)

Wymaga ona wprowadzenia czterech argumentów: nazwy stylu, nazwy czcionki podstawowej, czcionki BigFont (obie z rozszerzeniem shx), oraz współczynnika szerokości. Wywołanie:


(jk:TXT_MakeBFStyle "Simplex075BF" "simplex.shx" "special.shx" 0.75)

tworzy styl tekstu z takimi samymi parametrami jak w oknie dialogowym. Funkcja zwraca T po utworzeniu stylu, lub gdy taki styl już jest zdefiniowany.

Jak korzystać z BigFont? Mechanizm jest prosty – rzadko używane znaki (zwykle tylda [~] i/lub kreska pionowa [ | ]), pełnią rolę kodu sterującego, w połączeniu ze znakiem po nim występującym, określają znak specjalny z zestawu dostępnych BigFont. Przedstawiona tutaj kombinacja (simplex.shp + special.shp) wykorzystują znak tyldy. Poniżej możliwe kombinacje znaków. Jak widać można tutaj tworzyć wszystkie indeksy (0 – 9), kilka znaków anglosaskiego rysunku technicznego (CenterLine, Plate, Left itp.), oraz zestaw znaków ułamków.

bfont3

Widoczny tu tekst „ABC” pozwala na lokalizowanie znaków specjalnych względem tekstu podstawowego.

bfont4

Warto wiedzieć, że użytkownik AutoCAD-a, może sam tworzyć własne pliki czcionek, w tym definicje BigFont. Jest to szczegółowo opisane w Podręczniku Adaptacyjnym AutoCAD-a. Trzeba jednak pamiętać aby taki plik dołączyć do rysunku. Korzystanie ze standardowych czcionek (podobnie jak w tutaj opisanym przykładzie), gwarantuje bezbłędne odwzorowanie wszystkich tekstów. Zastosowane typowe czcionki są bowiem zawsze dostępne w każdym AutoCAD-zie.

AutoLISP, CADPL-Pack, Excel

TEXTOUT & TEXTIN

Kolejne narzędzie do eksportu i importu wartości obiektów tekstowych (obok omawianego również tutaj standardowego ATTOUT i ATTIN), tym razem dotyczące właśnie tekstów. Do eksportu służy zdefiniowane LISP-owe polecenie TEXTOUT. Pozwala wybrać obiekty tekstowe, a następnie zapisać ich wartości we wskazanym pliku tekstowym.

textio0

Tak samo jak ma to miejsce z eksportowaniem wartości atrybutów, wynikowy plik tekstowy, składa się z pierwszej linii będącej nagłówkiem danych, oraz kolejnych wierszy tworzących rekordy. Kolumny rozdzielane są znakiem tabulatora. W przedstawionej wersji istnieje możliwość zastąpienia tego znaku na inny – w przedstawionym poniżej kodzie odpowiada za to wartość zmiennej globalnej *jk-TextIO-Sep*. W pierwszej kolumnie znajdują się uchwyty (HANDLE) każdego tekstu, służące do identyfikacji obiektu.

textio1

Plik tekstowy może zostać wczytany na przykład do Excel’a, i tam też edytowany. Działanie takie zostało omówione w ATTOUT i ATTIN. Innym rozwiązaniem może być też po prostu edycja pliku tekstowego w Notatniku, lub innym edytorze:

textio2

Wczytanie pliku za pomocą polecenia TEXTIN do AutoCAD-a, wykorzystuje skojarzenie handle obiektów w pliku tekstowym i rysunku.

textio4

W ten sposób w ułamku sekundy zamieniane są wartości dla wszystkich obiektów tekstowych, dla których zostały one zmienione w pliku tekstowym.

textio5

Przedstawiony program umożliwia pominięcie w wyborze tekstów, tych których wartością jest wyrażenie pola danych (FIELD). Odpowiada za to wartość 0 , zmiennej globalnej *jk-TextIO-SelectField*.  Wartość 1 pozwala wybrać teksty / fieldy. Poniżej kod programu:


;;; ==============================================================
;;; TextIO.lsp 2016 kojacek
;;; Export + import wartosci obiektow TEXT do/z pliku TXT
;;; ==============================================================
(setq *jk-TextIO-Sep* "\t")         ; separator
(setq *jk-TextIO-SelectField* 0)    ; 0 = bez FILED-ow
;;; ==============================================================
(defun C:TEXTOUT (/ ss l f)
  (if
    (setq ss
      (ssget "_:L"
        (if
          (zerop *jk-TextIO-SelectField*)
          '((0 . "TEXT")(-4 . "<NOT")(1 . "*<\\Ac*")(-4 . "NOT>"))
          '((0 . "TEXT"))
        )
      )
    )
    (progn
      (setq l (cd:SSX_Convert ss 0)
            n (vl-string-subst ".txt" ".dwg" (getvar "DWGNAME"))
            l (mapcar
                '(lambda (% / %1)
                   (setq %1 (entget %))
                   (strcat "'" (cdr (assoc 5 %1))
                           *jk-TextIO-Sep* (cdr (assoc 1 %1)))
                ) l)
      )
      (if
        (setq f (getfiled "Zapisz plik TXT" n "txt" 1))
        (cd:SYS_WriteFile f
          (append (list
            (strcat "HANDLE" *jk-TextIO-Sep* "TEXT")) l) nil)
        (princ "\nNie wskazano pliku. ")
      )
    )
    (princ "\nNie wybrano tekstów. ")
  )
  (princ)
)
;;; ==============================================================
(defun C:TEXTIN (/ f n l h v e i d)
  (if
    (setq f (getfiled "Otwórz plik TXT" "" "txt" 8))
    (if
      (and
        (setq n (cd:SYS_ReadFile 0 f))
        (eq n (strcat "HANDLE" *jk-TextIO-Sep* "TEXT"))
      )
      (if
        (setq l (cd:SYS_ReadFile nil f))
        (progn
          (setq i 0
                l (cdr l)
                l (mapcar
                    '(lambda (%)
                       (cd:STR_Parse % *jk-TextIO-Sep* nil)
                    ) l
                  )
          )
          (cd:SYS_UndoBegin)
          (foreach % l
            (setq h (vl-string-left-trim "'" (car %))
                  v (cadr %)
            )
            (if
              (and
                (setq e (handent h))
                (= "TEXT" (cdr (assoc 0 (setq d (entget e)))))
              )
              (if
                (/= v (cdr (assoc 1 d)))
                (progn
                  (setq i (1+ i))
                  (cd:ENT_SetDXF e 1 v)
                )
              )
            )
          )
          (if
            (not (zerop i))
            (princ (strcat "\nZmieniono " (itoa i) " obiektów."))
          )
          (cd:SYS_UndoEnd)
        )
        (princ "\nBłędne dane w pliku tekstowym.")
      )
      (princ "\nBłędny plik tekstowy.")
    )
    (princ "\nNie wskazano pliku. ")
  )
  (princ)
)
;;; ==============================================================
(princ "\n [TextIO.lsp]: (TEXTOUT TEXTIN) ")
(princ)

Do prawidłowego działania konieczne jest załadowania biblioteki CADPL-Pack.