AutoLISP

Smart ERaser

Użytkownicy AutoCAD-a (choć nie tylko), są przekonani że jest to doskonałe narzędzie do tworzenia (rysowania i modelowania), a możliwości oprogramowania tych procesów, to już w ogóle bajka… Zgadzając się z tym w ogólności, poświęcę jednak dzisiejszy wpis… wymazywaniu obiektów, ze wskazaniem, że automatyzacja tegoż może być też niezłą zabawą…

Tak jak widać na (ruchomym) obrazie powyżej, chodzi o bardziej kontrolowany proces usuwania obiektów, niż jest to możliwe standardowo. Jest to wybór (wszystkich) obiektów ze wskazanej warstwy (przez wybranie jednego obiektu), z filrowaniem rodzaju obiektu (z możliwością zawężenia wyboru w oknie dialogowym). Normalnie, polecenie AutoCAD-a WYMAŻ (_ERASE), pozwala usunąć tylko wskazane obiekty. Rzecz jasna, utworzenie potrzebnego rozszerzonego zbioru wskazań (dla ERASE) może się odbywać na wiele sposobów (SELECT / QSELECT / SSGET), jednak zawsze wymaga to więcej pracy, niż skorzystanie z przedstawionego tu programu.

Jego działanie ogranicza się tylko do wskazania dowolnego obiektu w rysunku (z niezamkniętej warstwy) przeznaczonego do usunięcia. Program automatycznie tworzy zbiór wskazań wszystkich obiektów (z tej warstwy), dzieląc go na grupy znalezionych obiektów. Następnie (dynamicznie) tworzone jest okno dialogowe, w którym wyświetlana jest warstwa, oraz typy obiektów (z ilością występowania) w wycinkach typu toggle. Domyślnie wszystkie obiekty są wybrane (zaznaczone do usunięcia), wybór można jednak swobodnie ograniczyć.

Dla programujących w LISP-ie, ciekawostką będzie fakt wykorzystania jednej i tej samej funkcji obsługi wycinków toggle, dla nich wszystkich niezależnie od ich ilości (jest różna w zależności od rodzajów wybranych obiektów). Ta sama funkcja wykorzystana jest także do obsługi klawisza akceptującego [OK]. Mechanizm ten pozwala na kontrolowanie jego zachowania (aktywny / nieaktywny) zależnie od stanu wyboru wycinków wybierających. Jest to zilustrowane na grafice powyżej.

Wywołanie programu poleceniem: SER. Kod programu w całości przedstawiam poniżej:


; ---------------------------------------------------------------------------------- ;
; SmartERaser.lsp by kojacek 2022                                                    ;
; ---------------------------------------------------------------------------------- ;
(defun C:SER ()(jk:SER_Main)(princ))
; ---------------------------------------------------------------------------------- ;
(defun jk:SER_GetSelectLay (/ s)
  (if
    (setq s
      (car (entsel "\nSelect object:"))
    )
    (cdr (assoc 8 (entget s)))
  )
)
; ---------------------------------------------------------------------------------- ;
(defun jk:SER_isLock (Lay)
  (= :vlax-true
    (vla-get-Lock
      (vla-item
        (cd:ACX_Layers) Lay
      )
    )
  )
)
; ---------------------------------------------------------------------------------- ;
(defun jk:SER_ssGet (Lay LObj / ss l)
  (setq l
    (list
      (cons 8 Lay)
      (cons 410 (getvar "CTAB"))
    )
  )
  (if
    (setq ss
      (ssget "_x"
        (if
          (not LObj)
          l
          (append
            (list
              (cons 0 (cd:STR_ReParse LObj ","))
            )   l
          )
        )
      )
    )
    (cd:SSX_Convert ss 0)
  )
)
; ---------------------------------------------------------------------------------- ;
(defun jk:SER_ObjLays (LObj)
  (mapcar
    '(lambda (%)
       (cdr
         (assoc 0 (entget %))
       )
    ) LObj
  )
)
; ---------------------------------------------------------------------------------- ;
(defun jk:SER_ObjLaysItem (LObj / l :i)
  (defun :i (o l / %1)
    (setq %1 (vl-remove o l))
    (strcat
      o " ("
      (itoa (- (length l)(length %1)))
      ")"
    )
  )
  (setq l (LM:Unique LObj))
  (acad_strlsort
    (mapcar
      '(lambda (%)
         (:i % LObj)
      ) l
    )
  )
)
; ---------------------------------------------------------------------------------- ;
(defun jk:SER_ObjDlgData (Lst / s k e l)
  (setq s ":toggle{label=\""
        k "\";key=\""
        e "\";}"
  )
  (mapcar
   '(lambda (%)
      (strcat
        s
        %
        k
        (car (cd:STR_Parse % " " t))
        e
      )
    ) Lst
  )
)
; ---------------------------------------------------------------------------------- ;
(defun jk:SER_Main (/ o l s i a r)
  (if
    (setq o (jk:SER_GetSelectLay))
    (if
      (jk:SER_isLock o)
      (princ
        (strcat "\nLayer \"" (strcase o) "\" is locked.")
      )
      (progn
        (setq s (jk:SER_ssGet o nil)
              l (jk:SER_ObjLays s)
              i (length l)
        )
        (if
          (= 1 i)
          (jk:SER_Erase (list s) o)
          (if
            (setq r (jk:SER_Dialog l o))
            (progn
              (setq s (jk:SER_ssGet o r))
              (jk:SER_Erase (list s) o)
            )
            (princ "\nCancelled.")
          )
        )
      )
    )
    (princ "\nNothing selected.")
  )
)
; ----------------------------------------------------------------------------------- ;
(defun jk:SER_Erase (Lst Lay / i)
  (setq i (itoa (apply '+ (mapcar 'length Lst))))
  (cd:SYS_UndoBegin)
  (foreach % Lst
    (foreach %1 % (entdel %1))
  )
  (cd:SYS_UndoEnd)
  (princ
    (strcat
      "\n" i
      " objects erased from \""
      (strcase Lay)
      "\" layer."
    )
  )
)
; ----------------------------------------------------------------------------------- ;
(defun jk:SER_Dialog (Lst Lay / a b d f i m r w x :c :o :r)
  (defun :c ()
    (mapcar
      '(lambda (%)
         (cons % (read (get_tile %)))
      ) x
    )
  )
  (defun :o (/ j)
    (setq j (apply '+ (mapcar 'cdr (:c))))
    (mode_tile "accept"
      (cond
        ( (zerop j) 1)
        (t 0)
      )
    )
  )
  (defun :r (n)
    (mapcar 'car
      (vl-remove-if '(lambda (%)(zerop (cdr %))) n)
    )
  )
  (setq l (jk:SER_ObjLaysItem Lst)
        x (LM:Unique Lst)
        a (jk:SER_ObjDlgData l)
        i (itoa (1- (length a)))
        b "Smart ERaser 1.00"
        w "width=12;"
  )
  (cond
    ((not
       (and
         (setq f
           (open
             (setq m (vl-FileName-MkTemp nil nil ".dcl")) "w"
           )
         )    
         (foreach % 
           (list
             (strcat
              "ser:dialog{label=\"" b
              "\";:column{:boxed_row{label=\"Layer:\";:text{label=\""
              (strcase Lay)
              "\";}}:row{:boxed_column{label=\"Objects to erase:\";"
              (apply 'strcat a)              
              "}:column{:spacer{height=" i
              ";}:column{height=2;fixed_height=true;:ok_button{" w
              "}:cancel_button{" w
              "label=\"Cancel\";}}}}}}"
              )
            )
            (write-line % f)
          )
          (not (close f))
          (< 0 (setq d (load_dialog m)))
          (new_dialog "ser" d ""
            (cond
              ( %p )
              ( (quote (-1 -1)) )
            )
          )
        )
      )
    )
    ( T
      (foreach % x
        (set_tile % "1")
        (action_tile % "(:o)")
      )
      (action_tile "accept"
        "(setq r (:c) %p (done_dialog 1))"
      )
      (action_tile "cancel"
        "(setq %p (done_dialog 0))"
      )
      (start_dialog)
    )
  )
  (if r (:r r))
)
; ---------------------------------------------------------------------------------- ;
; http://www.lee-mac.com/uniqueduplicate.html                                        ;
; Unique  -  Lee Mac                                                                 ;
; Returns a list with duplicate elements removed.                                    ;
(defun LM:Unique ( l / x r )
  (while l
    (setq 
      x (car l)
      l (vl-remove x (cdr l))
      r (cons x r)
    )
  )
  (reverse r)
)
; ---------------------------------------------------------------------------------- ;
(princ)

Oczywiście do poprawnego działania, konieczne jest wcześniejsze załadowanie CADPL-Pack’a.

To jest #212 wpis na blogu

( . . . )

AutoCAD, AutoLISP

Obiekty nazwane

O nazwach, czyli co wolno a czego nie wolno używać w nazwach obiektów. Z pewnością nie raz, mogliście spotkać się z takim (nieco smutnym) komunikatem Menedżera warstw, zabijającym wasze mozolne (i niewątpliwie kreatywne) starania w celu utworzenia tej jedynej niepowtarzalnej nazwy warstwy… 😉

O nazwanych (autocad-owych)  obiektach pisałem już TUTAJ, a o pewnych możliwościach ich zmiany także – TUTAJ. Dziś chcę przybliżyć nieco problemy związane z podaniem poprawnej nazwy w LISP-ie. O ile bowiem, ręczne działania użytkownika skutkują wyświetlaniem odpowiednich (jak powyżej) komunikatów, to działania w (dowolnym) API, z niedopuszczalną nazwą, powodują zawsze błąd programu. Ponieważ (zaś) nadrzędnym zadaniem programującego jest zapewnienie poprawnego działania programu w możliwie najszerszym zakresie, ważnym jest przewidywanie potencjalnych błędów i zapobieganie im, już na najniższym poziomie.

Obecnie (od wersji AutoCAD 2000 (1999)) w nazwach symboli nazwanych niedopuszczalne są znaki:

Oczywiście AutoCAD zapewnia pełną zgodność z wcześniejszymi, wprowadzając odpowiednią zmienną systemową:

W AutoLISP istnieje funkcja o nazwie snvalid, która  pozwala sprawdzić czy nazwa określona jako jej argument, jest dopuszczalną nazwą symbolu. W niektórych jednak sytuacjach, okazuje się to niewystarczające. Stąd też zdefiniowałem swoją LISP-ową funkcję którą wywołuję w kodzie, gdy snvalid, zwraca wartość NIL. W tym przypadku, funkcja jk:STR_SNValid, dokonuje „naprawy” nazwy (argument Str) , zastępując wszystkie wystąpienia znaków niedopuszczalnych, znakiem określonym jako argument Nst. Funkcja wygląda tak:


;;; --------------------------------------------------------------- ;;;
;;; jk:STR_SNValid - kojacek 2018                                   ;;;
;;; --------------------------------------------------------------- ;;;
(defun jk:STR_SNValid (Str Nst / p)
  (setq p  (list 34 42 44 47 58 59 60 61 62 63 96 92 124))
  (while p
    (setq Str (vl-string-translate (chr (car p)) Nst Str)
          p (cdr p)
    )
  )
  Str
)
;;; --------------------------------------------------------------- ;;;

Przykładowe wywołanie (i wynik działania) ilustruje obraz:

Potrzeba napisania tej funkcji powstała w wyniku użycia pewnego (doskonałego zresztą) programu zmieniającego wstawienie bloku dynamicznego na odpowiadający mu graficznie blok statyczny. Program ów, jako część nowej nazwy bloku przyjmował opis jego stanu widoczności. W niektórych blokach opis ten zawierał znaki, które są niedopuszczalne, w nazwie bloku, w konsekwencji czego, program generował błąd. Użycie funkcji jk:STR_SNValid, skutecznie wyeliminowało przyczynę powstawania błędu, i odtąd program działa bez zakłóceń.

. . . )

AutoLISP

Warstwy… bloki… purge…

Prawdopodobnie każdy użytkownik AutoCAD-a, stanął w przeszłości (lub stanie w przyszłości) przed (irytującym) problemem niemożliwości usunięcia z rysunku nieużywanej warstwy. Widoczne poniżej pojawiające się okno komunikatu, niewiele pomaga, a wielokrotne „purgowanie” rysunku nie przynosi efektu.

W normalnym trybie edycji rysunku na nieusuwalnej warstwie nie znajdują się żadne obiekty, a jednak warstwy nie da się usunąć. Przyczyną takiego stanu rzeczy, są zwykle źle zdefiniowane bloki, których elementy znajdują na innych niż „zerowa” warstwa. Praca polegająca na żmudnym przeglądaniu każdej definicji bloku w celu znalezienia „winnych” nie wchodzi w grę, ze względu na potrzebny czas dla takich operacji. Pewnym sposobem usunięcia warstwy jest polecenie WARUSUŃ (_LAYDEL), jednak, jest to w moim przekonaniu „działanie siłowe” – polecenie usuwa warstwę wraz z obiektami, na nie się znajdującymi (nawet w definicji bloku). Taki sposób zmiany bloków, może być z wielu względów nie do przyjęcia (utrata ważnej części grafiki). Nie pozostaje zatem  nic innego jak wykorzystać możliwości dowolnego API AutoCAD-a. W moim przekonaniu (oczywiście) – LISP-a…

Poniżej definicje dwóch krótkich funkcji LISP-a, które napisałem w celu „namierzenia” obiektów wchodzących w skład bloku, znajdujących się na innej warstwie niż warstwa „0”. Pierwsza z nich dla argumentu którym jest nazwa bloku zwraca listę takich obiektów (ename). Druga funkcja pozwala „przeglądać” większą ilość bloków.


; ---------------------------------------------------------------- ;
; by kojacek 2018                                                  ;
; ---------------------------------------------------------------- ;
; Funkcja sprawdza wszystkie elementy bloku <BName>. Zwraca liste  ;
; obiektow <ename> ktore znajduja sie na innej warstwie niz "0"    ;
; lub nil                                                          ;
; ---------------------------------------------------------------- ;
(defun jk:BLK_Find-NoStandardLay (BName)
  (vl-remove-if
    '(lambda (%)
       (= "0" (cdr (assoc 8 (entget %))))
    )
    (cd:BLK_GetEntity BName nil)
  )
)
; ---------------------------------------------------------------- ;
; Funkcja dla listy nazw blokow <Blist>, sprawdza kazdy blok, czy  ;
; znajduja sie w nim elementy na innych warstwach niz "0". Zwraca  ;
; liste typu (("BName-1 <ename...> ... )) lub nil                  ;
; ---------------------------------------------------------------- ;
(defun jk:BLK_InspectBlock (BList / r)
  (if
    (setq r
      (mapcar
       '(lambda (% / %1)
          (if
            (setq %1 (jk:BLK_Find-NoStandardLay %))
            (append (list %) %1)
          )
        ) BList
      )
    )
    (vl-remove 'nil r)
  )
)
; ---------------------------------------------------------------- ;

Przykładowe wywołanie (i zapisanie wyniku jako zmienna a) wygląda tak:


(setq a (jk:BLK_InspectBlock (cd:SYS_CollList "BLOCK" (+ 1 2 4))))

i może zwrócić listę podobną do pokazanej poniżej. Jak widać w przeglądzie wartości listy w konsoli VLIDE, zostały znalezione dwa bloki, w których zdefiniowano obiekty na warstwach innych niż warstwa „0”:

Oczywiście lista może być o wiele dłuższa. Czas teraz „naprawić złe” bloki, czyli przenieść wszystkie znalezione w nich elementy na warstwę „0”. Wydawać się może, że będzie to skomplikowana operacja – normalnie trzeba każdy blok otworzyć do edycji, zmienić odpowiednim obiektom cechy, ponownie zapisać  zmienioną definicję bloku. Nic bardziej mylnego – wykorzystując LISP-a, można to zrobić w bardzo prosty, krótki i wręcz „niewidzialny” sposób. Mając już wcześniej zapisaną zmienną o nazwie a, wystarczy wywołać (nawet w linii poleceń) poniższe wyrażenie:


(foreach % a (foreach %1 (cdr %)(cd:ENT_SetDXF %1 8 "0")))

… i w ułamku sekundy wszystkie bloki znajdujące się na liście zostają przedefiniowane. Po tym zabiegu, można wywołać polecenie USUŃ (_PURGE). Z pewnością jeżeli przyczyną wcześniejszej niemożliwości usunięcia warstw, były źle zdefiniowane bloki, teraz po ich redefinicji, przeszkoda ta została usunięta.

Kilka ważnych uwag:

  • argumentem funkcji jk:BLK_InspectBlock, jest lista nazw bloków. Może to być dowolna ich lista, niemniej należy uważać z blokami anonimowymi. Szczególnie z blokami tworzącymi grafikę dla wymiarów i tabel (bloki o nazwach *Dnnn i *Tnnn). Mogą one zawierać w sobie obiekty na innych warstwach niż „0”, i nie jest to w tym przypadku wadą. Programujący powinien mieć świadomość z konsekwencji zmiany definicji pewnych bloków – z założenia należy używać funkcji do naprawy bloków użytkownika.
  • Alternatywnym sposobem masowej zmiany definicji bloków jest omawiany już tutaj wcześniej program (ze stajni CADPL-Pack): RedefineBlockProperties.lsp znany wcześniej jako bl-redef.vlx. Pozwala on jednocześnie zmienić więcej cech obiektów wchodzących w skład bloku. Niemniej działa „w ciemno”, nie wiemy który blok powinien być zmieniany – w dzisiejszym wpisie, omawiam sytuację, w której znajdowane są właściwe bloki.
  • Może zaistnieć sytuacja, że nie uda się poprawnie zmienić definicji bloku. Może to mieć miejsce w przypadku bloków w których znajdują się obiekty którym nie można zmienić warstwy – zwykle są to tzw. grafiki zastępcze (obiekty typu PROXY).
  • Do poprawnego działania przedstawionych powyżej narzędzi wymagane jest załadowanie biblioteki CADPL-Pack.

( . . . )

AutoLISP

LAYER – nieudokumentowana własność – isHidden

O warstwach i ich cechach już parę razy wspominałem w tych wpisach. Teraz parę słów o pewnej nieudokumentowanej własności obiektu LAYER. To cecha o nazwie isHidden. Właściwość isHidden odpowiada za widoczność nazwy warstwy w oknach, listach rozwijalnych itp. Przyjmuje dwie wartości 0 lub 1. Poniżej przykład ilustrujący praktyczne działanie zmiany właściwości. Narysujmy dwa obiekty – nich to będzie linia i okrąg:

Niechże czerwony okrąg (z kolorem jakwarstwa) będzie na warstwie o nazwie B…

… zaś żółta linia (także jakwarstwa), niech leży na warstwie A:

Jak widać w rysunku istnieją tylko trzy warstwy: 0, A oraz B. Za pomocą LISP-a zdefiniowałem polecenie HL, które nieco zmienia ten obraz:

Polecenie wymaga wskazania dowolnego obiektu – tutaj wybieramy okrąg:

… i właściwie nic się nie dzieje dopóty, dopóki nie rozwiniemy listy warstw. Na liście widoczne są dwie warstwy: 0 i A. Pamiętamy że okrąg (nadal istniejący) znajduje się na warstwie B.

Zaznaczenie obiektu na „nieistniejącej warstwie” powoduje „wyczyszczenie” pola listy warstw:

Poniżej przedstawiam krótkie makro – definicję polecenia HL, które dla wskazanego obiektu, ukrywa jego warstwę, zmieniając cechę isHidden. Dla poprawności działania, wykluczyłem możliwość ukrywania warstw 0 i DefPoints, jak również warstwy aktualnej. Polecenie działa jak przełącznik sekwencyjny – ukrywa / odkrywa warstwę, w zależności od jej stanu w chwili wskazania obiektu. Cały kod poniżej:


; =============================================================== ;
; hiddenlay.lsp - kojacek - 2017 -                                ;
; =============================================================== ;
(defun C:HL (/ e d l f)
  (if
    (and
      (setq e (car (entsel "\nWybierz obiekt: ")))
      (not
        (member
          (setq l
          (cdr (assoc 8 (setq d (entget e)))))
         '("0" "DEFPOINTS")
        )
      )
    )
    (if
      (/= (getvar "CLAYER") l)
      (progn
        (setq f (if (= (substr l 1 1) "*") 0 1))
        (setpropertyvalue (tblobjname "LAYER" l) "IsHidden" f)
        (princ
          (strcat
            "\nWarstwa "
            (if (zerop f)(substr l 2 (strlen l)) l)
            " jest " (nth f '("od" "u")) "kryta. "
          )
        )
      )
      (princ "\nObiekt na warstwie aktualnej. ")
    )
  )
  (princ)
)
; =============================================================== ;
(princ)

Warto zwrócić uwagę że właściwość isHidden nie ma bezpośredniego odzwierciedlenia w kodach DXF danych obiektu. Jedyna różnica to nazwa warstwy poprzedzona znakiem gwiazdki. I jest to jedyny sposób aby z poziomu AutoLISP-a, odczytać czy warstwa jest „ukryta”:

Tak samo jest dla danych odczytanych dla VLA-OBJECT. Tylko gwiazdka w nazwie warstwy świadczy o różnych wartościach własności isHidden:

Fakt możliwości zamiany nazwy warstwy, poprzez zmianę właściwości isHidden, nie jest nigdzie udokumentowany, ani w DXF Reference, ani podręcznikach programisty traktujących o AutoLISP / VisualLISP czy ActiveX dla AutoCAD-a.  IsHidden widoczne jest tylko dla danych uzyskanych za pomocą funkcji dumpallproperties, i tylko przy pomocy funkcji getpropertyvalue i setpropertyvalue , możliwy jest jej odczyt i zmiana. Poniższe okno odczytu danych opisałem w Visual dumpallproperties.

(  . . . )

AutoCAD, AutoLISP

Warstwa używana…

Warstwa jest nierozerwalnym elementem mechanizmów zarządzania strukturą rysunku AutoCAD-a. Każdy obiekt graficzny musi znajdować się na jakiejkolwiek warstwie – po prostu nie da się utworzyć żadnej entycji bez przypisania jej do warstwy. W drugą stronę – mogą istnieć warstwy bez jakichkolwiek elementów graficznych. Warstwy używanej nie można usunąć. Właściwość warstwy o nazwie Used, informuje o stanie używania warstwy. Jest to właściwość r-o (read-only), ma zatem charakter jedynie informacyjny.

Stan „używalności” warstwy można sprawdzić (LISP-em) na dwa sposoby: wykorzystując mechanizm ActiveX. Warstwa (VLA-OBJECT). Wartość zwracana to :vlax-false, lub :vlax-true:

showlayerusagealub sprawdzając właściwość IsUsed obiektu warstwy: (EntityName). Wartość zwracana: 0 lub 1:

showlayerusageb

Niestety nie ma możliwości sprawdzenia tego stanu za pomocą odczytu kodów DXF obiektu warstwy.

Stan warstw można również kontrolować w oknie Menedżera warstw. Zmienna systemowa o nazwie SHOWLAYERUSAGE, odpowiada za to czy w Menadżerze warstw pokazywane są ikony stanu używania warstw.

showlayerusage0Wartością domyślną jest 0 – nie można wtedy rozpoznać czy warstwa jest używana (obraz powyżej). Wartość 1 zmiennej wyświetla w oknie ikony wskazujące czy warstwy są używane:

showlayerusage1

Wartością zmiennej można sterować również za pomocą okna Ustawienia palety menadżera właściwości warstw:

showlayerusage2

 

AutoCAD

Zarządzanie warstwami

Jednym z narzędzi do zarządzania warstwami jest Menedżer właściwości warstw. Obecnie i domyślnie jest to (zgodnie z obecnie panującymi trendami), niemodalna paleta narzędzi umożliwiająca dokonywanie podstawowych operacji na warstwach (tworzenie, zmiany właściwości, widoczności itd.): laymen

Paleta wywoływana jest poleceniem WARSTWA (_LAYER), jeśli nie jest aktualnie wyświetlana, a w trybie wyświetlania może być automatycznie ukrywana (zwijana w pionie), ponadto może mieć regulowaną przezroczystość (aktywowanie pełnej widoczności po najechaniu kursorem).

Dla zachowania zgodności, i dla wygody użytkowników, pozostawiono możliwość korzystania ze starego modalnego menedżera w postaci okna dialogowego: laydlg

Informacja o trybie wyświetlania menedżera (stary / nowy) ustalana jest przez zmienną systemową o nazwie LAYERDLGMODE (przechowywanej w rejestrze Windows). Może ona mieć dwie wartości: 0 – tryb starego okna, oraz 1 (domyślnie) – tryb palety. Wystarczy zatem zmienić ustawienie zmiennej LAYERDLGMODE, aby móc korzystać z innego trybu.

Niezależnie od ustawień zmiennej można zamiennie użyć poleceń: CLASSICLAYER (_CLASSICLAYER), dla wywołania okna dialogowego, oraz polecenia WARSTWAPALETA (_LAYERPALETTE), dla korzystania z palety menedżera warstw.

 

 

AutoCAD, AutoLISP

Opis warstwy

Od wersji 2004 AutoCAD-a, użytkownicy mają możliwość dodawania opisu do warstwy. Cecha ta umożliwia dodawanie rozszerzeń tekstowych dla każdej warstwy, w sytuacji kiedy nazwa warstwy może być niezrozumiała, lub niewystarczająca. Pomysłów na wykorzystywanie opisów warstw może być więcej. Dodawanie opisów warstw może być realizowane na wiele sposobów:

  1. W linii poleceń, jako opcja polecenia _-LAYER (-WARSTWA)laydesc01
  2.  W oknie dialogowym warstw (_CLASSICLAYER) lub palecie managera warstw _LAYER (WARSTWAlaydesc02
  3. Programowo, wykorzystując mechanizmy ActiveX. Opis warstwy jest bowiem właściwością o nazwie Description dla obiektu IAcadLayer. Przykładowo wywołanie:laydesc03tworzy opis „ABC” dla warstwy o nazwie Defpoints. Można to sprawdzić przeglądając obiekt warstwy:  laydesc04
    albo sprawdzić właściowość Description obiektu: laydesc05Usunięcie opisu warstwy polega na przypisaniu właściwości Description, wartości będącej pustym łańcuchem.
  4. Programowo – manipulując danymi dodatkowymi. Opis bowiem nie jest jakąś nową cechą – wykorzystuje się tutaj możliwość dodawania danych dodatkowych (XDATA) do dowolnego obiektu (tutaj warstwy). Możliwość ta istnieje w AutoCAD-zie już od wersji 10. Opisy związane są z aplikacją o nazwie „AcAecLayerStandard„, oraz „zajmują” dwa kody 1000, jeden to ciąg pusty, drugi wartość opisu warstwy. Jeżeli obiekt (warstwa) ma tak zdefiniowane dane dodatkowe, opis warstwy widoczny jest w oknie dialogowym menadżera warstw.
    Za pomocą trzech funkcji zdefiniowanych w CADPL-Pack‚u dotyczących danych dodatkowych (XDATA), można utworzyć opis warstwy:laydesc06sprawdzić wartość opisu:laydesc07lub go usunąć:laydesc08

Poniżej struktura danych DXF obiektu warstwy z danymi dodatkowymi tworzącymi opis warstwy:
laydesc09