_

[LISP] Czy napisanie takiego lispa jest trudne?

Forum poświęcone flagowemu produktowi oraz aplikacjom pochodnym Autodesku. To jedyne forum mające w tytule nazwę programu, a to ze względu na jego olbrzymią popularność w Polsce. Można tutaj umieszczać również posty z ogólnie pojętej tematyki "Kreślarskie 2D".

Re: [LISP] Czy napisanie takiego lispa jest trudne?

Postprzez Grappa25 » kwi 12, 2016 17:37

- dla każdego klucza (warstwy) pobierz dane z ini, rozczłonkuj je (zmień na listę), a następnie:
- wykonaj kolejne działania na elementach listy (tutaj:) (kolejno) zmień nazwę warstwy, jej rodzaj linii, kolor, oraz szerokość linii zeń przypisaną.
To wszystko wymagać będzie osobnej funkcji, wykorzystującej CADPL-Pack'a.


-Te dane z pliku INI powinniśmy pobrać (którymś z get...),zmienić na listę przy użyciu (CON_Value2List Val) z cad pack'a?
Dlaczego musimy je zmienić w listę?
Grappa25
 
Posty: 14
Dołączył(a): kwi 06, 2016 17:41

Re: [LISP] Czy napisanie takiego lispa jest trudne?

Postprzez kojacek » kwi 12, 2016 20:49

Grappa25 napisał(a):
- dla każdego klucza (warstwy) pobierz dane z ini, rozczłonkuj je (zmień na listę), a następnie:
- wykonaj kolejne działania na elementach listy (tutaj:) (kolejno) zmień nazwę warstwy, jej rodzaj linii, kolor, oraz szerokość linii zeń przypisaną.
To wszystko wymagać będzie osobnej funkcji, wykorzystującej CADPL-Pack'a.


-Te dane z pliku INI powinniśmy pobrać (którymś z get...),zmienić na listę przy użyciu (CON_Value2List Val) z cad pack'a?
Dlaczego musimy je zmienić w listę?


Pobieranie danych z ini zrobimy tak jak wcześniej wykorzystując acet-ini-get. Tak sprawdzaliśmy wartość klucza Name, tak pobraliśmy wartości kluczy sekcji Layers. Spostrzegawczy czytelnik zauważy różną ilość argumentów w wywołaniu funkcji acet-ini-get. W AutoLISP i VisualLISP jest to możliwe tylko dla funkcji wbudowanych lub zdefiniowanych w arx.
Dane które pobierzemy będą (dla każdego klucza) łańcuchem tekstowym np.
Kod: Zaznacz cały
EBUOA_T_1,Continous,7,0.25

Taki ciąg musimy zamienić na listę elementów (gdzie przecinek będzie separatorem) - to będzie lista łańcuchów tekstowych. W zależności zaś od pozycji elementu na liście, trzeba będzie jeszcze niektóre przekonwertować na liczby. Na każdym etapie, naszego działania, zachować trzeba będzie daleko posuniętą czujność... czyli zagwarantować sprawdzenie poprawności danych w możliwie szerokim (przewidywalnym) zakresie.
Avatar użytkownika
kojacek
 
Posty: 5453
Dołączył(a): paź 03, 2005 20:17

Re: [LISP] Czy napisanie takiego lispa jest trudne?

Postprzez kojacek » kwi 14, 2016 08:57

Zróbmy kolejny krok. Utworzymy funkcję o nazwie _Chlay. Jej zadaniem będzie: odczytanie danych dla klucza, a następnie zmiana cech warstwy na podstawie tych danych. Zawierać ona będzie także podstawowe mechanizmy kontrolne (czyli zaczniemy od róznych if-ów - funkcja będzie cokolwiek robić tylko po spełnieniu określonych warunków). Poniżej cały dotychczasowy kod + nowa funkcja. W tej chwili nic nie robi oprócz:
1. odczytu (acet-ini ...)
2. zmiany danych na listę (cd:STR_Parse ...)
3. sprawdzenia czy warstwa podana jako klucz w ini znajduje się w rysunku (tblobjname ...)

Kod: Zaznacz cały
(defun C:LPCON (/ n l)
  (if
    (setq n
      (getfiled "Wybierz plik ini" (getvar "DWGPREFIX") "ini" 16)
    )
    (if
      (= (acet-ini-get n "General" "Name") "LayPropConverter")
      (if
        (setq l (acet-ini-get n "Layers"))
        (foreach % l (_ChLay % n))
        (princ "\nBłąd w pliku ini.")
      )
      (alert "\nNie wskazano poprawnego pliku dla LayPropConverter.lsp")
    )
    (princ "\nNie wskazano pliku ini.")
  )
)
; ------------------------------------------------------------------------ ;
(defun _ChLay (Lay File / d e)
  (if
    (setq d (acet-ini-get File "Layers" Lay))
    (progn
      (setq d (cd:STR_Parse d "," T))
      (if
        (setq e (tblobjname "LAYER" (strcase Lay)))
        (progn
          e
        )
      )
    )
  )
)

Kolejnym krokiem będzie już zmiana pewnych cech warstwy.
Avatar użytkownika
kojacek
 
Posty: 5453
Dołączył(a): paź 03, 2005 20:17

Re: [LISP] Czy napisanie takiego lispa jest trudne?

Postprzez Grappa25 » kwi 19, 2016 21:02

(defun C:LPCON (/ n l) ;definiujemy polecenie o nazwie LPCON, C: oznacza, że polecenie będzie wywoływane z linii poleceń, (/nl)oznacza zmienną lokalną, jeśli byłyby jakieś parametry funkcji powinny być umieszczone przed znakiem /;
(if
(setq n
(getfiled "Wybierz plik ini" (getvar "DWGPREFIX") "ini" 16) ; setq- to przypisywanie wartości do zmiennej (u mnie do zmiennej n), funkcja getfiled wyświetla okno dialogowe zawierające listę dostępnych plików danego rozszerzenia ( u mnie będzie to ini). Można użyć tego okienka dialogowego do przeszukiwania różnych lokalizacji, getvar- to odczytywanie zmiennej systemowej, 16- założenie, że nie ma domyślnej nazwy pliku, w oknie dialogowym w polu nazwa będzie puste pole;
)
(if
(= (acet-ini-get n "General" "Name") "LayPropConverter") ;acet-ini-get-to funkcja z express tools pobierająca dane z pliku INI i ma postać (acet-ini-get nazwa pliku[sekcja „name” w pliku INI[nazwa klucza w sekcji[domyślna wartość do zwrócenia jeśli nie zostanie znalezione INI]]] –pobieramy wartość klucza Name
Zwracane wartości:
Zależą od podanych wartości. Jeśli dany jest tylko plik ini –funkcja zwróci listę nazw sekcji lub Nil jeśli nie można otworzyć pliku. Jeśli jest dana nazwa sekcji- zwrócona będzie lista kluczy. Jeśli klucz jest dany- zwróci wartość przypisaną do klucza lub domyślną jeśli klucz nie może być zlokalizowany.Zwróci Nil jeśli żadna informacja nie zostanie znaleziona. ;

(if
(setq l (acet-ini-get n "Layers")) pobieramy dane z pliku ini – wartości kluczy z sekcji „Layers”
(foreach % l (_ChLay % n)) dla każdego –wartościowanie pętli-przypisuje do zmiennej l funkcję ChLay????
(princ "\nBłąd w pliku ini.") wyświetl „Bład w pliku ini” z przeskokiem do następnej linii (\n)
)
(alert "\nNie wskazano poprawnego pliku dla LayPropConverter.lsp") wyświetl ostrzeżenie „Nie wskazano…
)
(princ "\nNie wskazano pliku ini.") wyświetl „Nie wskazano pliku ini”
)
)
; ------------------------------------------------------------------------ ;
(defun _ChLay (Lay File / d e) definiujemy funkcję o nazwie ChLay o zmiennych d i e
(if
(setq d (acet-ini-get File "Layers" Lay)) zmienna d-odczyt danych dla klucza „Layers”
(progn grupowanie wyrażeń w jedno
(setq d (cd:STR_Parse d "," T)) zmiana danych na listę (STR- z ang. STRING) –funkcja zwracająca listę (z CAD-pack’a)
(if
(setq e (tblobjname "LAYER" (strcase Lay))) sprawdzenie czy warstwa będąca kluczem w ini znajduje się w rysunku, strcase konwertuje tekst LAYER na Lay???
(progn grupowanie-czyli będzie kolejne „e”
e
)
)
)
)
)

coś tam już kojarzę, ale na razie szału nie ma i nie ma mowy o samodzielnej pracy ;( Części z funkcji nie znalazłam w książce, ale to pewnie te, które pochodzą z CAD pack'a. Proszę o dlasze wskazówki.
Grappa25
 
Posty: 14
Dołączył(a): kwi 06, 2016 17:41

Re: [LISP] Czy napisanie takiego lispa jest trudne?

Postprzez kojacek » kwi 21, 2016 10:59

Grappa25 napisał(a): (...) coś tam już kojarzę, ale na razie szału nie ma i nie ma mowy o samodzielnej pracy ;( Części z funkcji nie znalazłam w książce, ale to pewnie te, które pochodzą z CAD pack'a. Proszę o dlasze wskazówki.


No no... :) może się wkręcisz?
A teraz zrobimy zmianę w idei działania naszego makra. Zmienimy kolejność w:
kojacek napisał(a):1. odczytu (acet-ini ...)
2. zmiany danych na listę (cd:STR_Parse ...)
3. sprawdzenia czy warstwa podana jako klucz w ini znajduje się w rysunku (tblobjname ...)

... albowiem, zmiany winny tyczyć tylko warstw istniejących w rysunku. Możemy sobie wyobrazić że w pliku ini mamy dane dla 80-ciu warstw, a w bieżącym rysunku warstw odpowiadających jest tylko np. 10. Wynika z tego że, działać będziemy na 10 warstwach, czyli tylko te dane musimy odczytać, przetworzyć i użyć do zmiany - prawda?
Kolejność działań będzie taka:
1. sprawdzenia czy warstwa istnieje
2. (jeśli tak) odczytanie danych
3. (jeśli (2)) zamiana na listę
Avatar użytkownika
kojacek
 
Posty: 5453
Dołączył(a): paź 03, 2005 20:17

Re: [LISP] Czy napisanie takiego lispa jest trudne?

Postprzez MS_MS » wrz 27, 2018 23:29

Chetnie bym odswiezyl temat. Taki lisp przydalby mi sie jak zloto. Srobowalem to co znalazlem w postach, ale wyskauje mi blad w pliku *.ini. Czy to dlatego, ze 2 wartwy zamieniam na jedna, czyli wartswa 1 i warstwa 2 zmienia sie na warstwe A?
MS_MS
 
Posty: 17
Dołączył(a): wrz 24, 2017 11:42

Re: [LISP] Czy napisanie takiego lispa jest trudne?

Postprzez MS_MS » wrz 28, 2018 00:07

Znalazlem takie cos:

Kod: Zaznacz cały
;;function to rename a layer.
;;if old layer exists, and new layer doesn't exist, the old layer is simply renamed.
;;if old layer exists, and new layer is already there, it takes everything on old layer and puts them on new layer.
;;if old layer doesn't exist, it does nothing.
(defun renlay (ol nl / ss i ent )
  (cond ((and (tblsearch "layer" ol) (not (tblsearch "layer" nl)))
    (command "._rename" "la" ol nl)
   )
   ((and (tblsearch "layer" ol)(tblsearch "layer" nl))
     (setq ss (ssget "x" (list (cons 8 ol))))
     (setq i -1)
      (repeat (sslength ss)
         (setq ent (entget (ssname ss (setq i (1+ i))))
          ent (subst (cons 8 nl) (cons 8 (cdr (assoc 8 ent))) ent)
         )   
         (entmod ent)
           )
   )
   ((not (tblsearch "layer" ol))
     (prompt (strcat "\nLayer " ol " not found. "))
        )
  )
  (princ)
)

;;example
(defun c:test ()
(Renlay "1" "A")
(Renlay "2" "A")
)


Zalezalo by mi na tym, zeby liste polecen renlay zastapic plikem wsadowym. No i trudniejsze: zeby z dwoch warstw zrobic jedna
MS_MS
 
Posty: 17
Dołączył(a): wrz 24, 2017 11:42

Poprzednia strona

Powrót do AutoCAD

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników