wedzik

Użytkownik forum
  • Postów

    42
  • Dołączył

  • Ostatnia wizyta

  • Wygrane w rankingu

    1

Odpowiedzi opublikowane przez wedzik

  1. Dziękuję.

    Oto kod jaki mam teraz. Wyświetla się też komunikat o ilości znalezionych elementów.

    (defun c:okregi (/)
    	(setq malypromien (getreal "Podaj maly promien: ")) 
    	(setq zbior (ssget "X" (list (cons 0 "CIRCLE") (cons 410 "Model")(cons -4 ">=") (cons 40 malypromien ) ) ))
    	(if zbior (princ (list "Ilosc znalezionych elementow: " (setq ile (sslength zbior)))) (princ "\nBrak elementow"))
        (princ)
    )

    Dziwi mnie że te obiekty nie są wybrane na rysunku.

    Można je ręcznie zaznaczyć z linii poleceń tak

    Polecenie: !ile
    47 
    Polecenie: _SELECT
    Wybierz obiekty: _p
    znaleziono 47
    Wybierz obiekty: 

    i po enterze są zaznaczone z gripami.

    Jak to robię w lispie to nic się nie dzieje:

    (command "_select" "_p" "")

    Jak zaznaczyć z lispa na ekranie te elementy ze zbioru "ile" albo ostatnie zaznaczone?

  2. Chcę napisać lispa który zaznaczy mi okręgi o średnicach znajdujących się w przedziale.

    Zacząłem od napisania takiego programu, który zaznacza wszystkie okręgi w rysunku o promieniu większym lub równym od podanego.

    Ten skrypt działa ale muszę wpisać promień wewnątrz skryptu czyli tak (40 . 10 ) - zaznacza okręgi o promieniu >=10

    Cytuj

    (defun c:okregi (/)
        ;(setq malypromien (getreal "Podaj maly promien: ")) 
        (setq zbior (ssget "X" '( (0 . "CIRCLE") (410 . "Model")(-4 . ">=") (40 . 10 ) ) ))
        (setq ile (sslength zbior))
    )

    Jeśli jednak zapytam o promień i zmodyfikuję program to dostanę błąd

    Cytuj

    (defun c:okregi (/)
        (setq malypromien (getreal "Podaj maly promien: ")) 
        (setq zbior (ssget "X" '( (0 . "CIRCLE") (410 . "Model")(-4 . ">=") (40 . malypromien ) ) ))
        (setq ile (sslength zbior))
    )
     

    Cytuj

    Polecenie: OKREGI
    Podaj maly promien: 10
    błąd: nieprawidłowy typ - nil

    Doszukałem, że trzeba zamienić (40 . malypromien ) na (cons 40 malypromien ) ale błąd jest dalej.

    Jakieś sugestie?

  3. Abs nie wystarczył, trzeba było dorzucić IFa.

    Działa już po lewej i po prawej kierunek zaznaczania bez znaczenia.

    (defun c:krawedzieotworux ()
    	(princ "Zaznacz okregi do rzutownia: \n")
    	(setq okrag (ssget  '((0 . "CIRCLE")) )) 		;prosimy o wskazanie obiektów oknem. Pozwalamy na wybor tylko okregow
    	(setq ile (sslength okrag)) 					;liczymy ile obiektow zaznaczylismy
    	(setq i 0) 										;ustawiamy zmienna i zeby sobie odliczac
    	(setq pt1 (getpoint "Wskaz poczatek linii: ")) 
    	(setq pt2 (getpoint "Wskaz koniec linii: ")) 
    	(setq przedluzenieosi (* (abs (- (car pt2) (car pt1) ))  0.1 ))
    	(setq aktualnawarstwa (getvar "CLAYER"))
    	(command "_-LAYER" "_M" "osie" "_C" "red" "" "_L" "CENTER" "" "") ; Tworze warstwe dla osi
    	(repeat ile	 									; powtarzamy tyle razy ile jest obiektow
    		(setq nazwyobiektow (ssname okrag i))  		; ustalamy nazwe kolejnych obiektow
    		(setq listaobiektu (entget nazwyobiektow))  ;pobieramy wlasciwosci obiektu o nazwie jak w lini wyzej
    		(setq promien (assoc 40 listaobiektu)) 		;odczytujemy promień aktualnego okregu np. (40 . 27.7815)
    		(setq srodek (assoc 10 listaobiektu)) 		;odczytujemy srodek okregu np. (10 310.596 514.272 0.0) 
    		(setq r (cdr promien)) 						;przypisuje do r promien np. 27.7815
    		(setq y (cadr(cdr srodek))) 				;przypisuje do y wspolrzedna Y np. 514.272
    		(setq x (cadr srodek)) 				        ;przypisuje do x wspolrzedna Y np. 310.596
    		(setq grupa (ssadd))
    		(command "_-LAYER" "_S" aktualnawarstwa "")
    		(command "_line" (list (car pt1) (+ y r))  (list (car pt2) (+ y r)) "") ;rysuje linie car pobiera wspolrzedna X z kliknietych punktow
    		(ssadd (entlast) grupa)
    		(command "_line" (list (car pt1) (- y r))  (list (car pt2) (- y r)) "") 
    		(ssadd (entlast) grupa)
    		(command "_-LAYER" "_S" "osie" "")
    		
    		(if (< (car pt1) (car pt2))
    				(command "_line" (list (- (car pt1) przedluzenieosi) y )       (list (+ (car pt2) przedluzenieosi) y) "") ;rysujemy osie symetrii otworów z boku
    				(command "_line" (list (- (car pt2) przedluzenieosi) y )       (list (+ (car pt1) przedluzenieosi) y) "") ;rysujemy osie symetrii otworów z boku
    		)
    		(ssadd (entlast) grupa)
    		;osie na otworach w widoku z góry, na początku os X potem Y
    		(command "_line" (list (- x r przedluzenieosi) y) (list (+ x r przedluzenieosi) y) "" )
    		(ssadd (entlast) grupa)
    		(command "_line" (list x (- y r przedluzenieosi) ) (list x (+ y r przedluzenieosi) ) "" )
    		(ssadd (entlast) grupa)
    		(command "_group" "_c" "*" "opis" grupa "")
    		(setq i (1+ i)) 							;zwiekszamy zmienna i aby odczytac kolejny obiekt
    		)
    	(command "_-LAYER" "_S" aktualnawarstwa "")
    	)
    	

     

  4. Kolejna wersja programu: rysuje osie i grupuje elementy otworu.

    Przed

    1278865376_2020-11-2918_58_16-ZWCAD2021Wersjatestowa(Pozostao20dni)-C__Users_jaros_Desktop_krawedzie.png.8e5825bd4658cd0181ade643c4d5d2cb.png

    Po

    1844186092_2020-11-2918_59_13-ZWCAD2021Wersjatestowa(Pozostao20dni)-C__Users_jaros_Desktop_krawedzie.png.f070b072ea1061324f130546a9844b76.png

    (defun c:krawedzieotworux ()
    	(princ "Zaznacz okregi do rzutownia: \n")
    	(setq okrag (ssget  '((0 . "CIRCLE")) )) 			;prosimy o wskazanie obiektów oknem. Pozwalamy na wybor tylko okregow
    	(setq ile (sslength okrag)) 						;liczymy ile obiektow zaznaczylismy
    	(setq i 0) 											;ustawiamy zmienna i zeby sobie odliczac
    	(setq pt1 (getpoint "Wskaz poczatek linii: ")) 
    	(setq pt2 (getpoint "Wskaz koniec linii: ")) 
    	(setq przedluzenieosi (* (- (car pt2) (car pt1) )  0.1 ))
    	(setq aktualnawarstwa (getvar "CLAYER"))
    	(command "_-LAYER" "_M" "osie" "_C" "red" "" "_L" "CENTER" "" "") ; Tworze warstwe dla osi
    	(repeat ile	 						; powtarzamy tyle razy ile jest obiektow
    		(setq nazwyobiektow (ssname okrag i))  			;ustalamy nazwe kolejnych obiektow
    		(setq listaobiektu (entget nazwyobiektow))  	;pobieramy wlasciwosci obiektu o nazwie jak w lini wyzej
    		(setq promien (assoc 40 listaobiektu)) 			;odczytujemy promień aktualnego okregu np. (40 . 27.7815)
    		(setq srodek (assoc 10 listaobiektu)) 			;odczytujemy srodek okregu np. (10 310.596 514.272 0.0) 
    		(setq r (cdr promien)) 							;przypisuje do r promien np. 27.7815
    		(setq y (cadr(cdr srodek))) 					;przypisuje do y wspolrzedna Y np. 514.272
    		(setq x (cadr srodek)) 				        	;przypisuje do x wspolrzedna Y np. 310.596
    		(setq grupa (ssadd))
    		(command "_-LAYER" "_S" aktualnawarstwa "")
    		(command "_line" (list (car pt1) (+ y r))  (list (car pt2) (+ y r)) "") ;rysuje linie car pobiera wspolrzedna X z kliknietych punktow
    		(ssadd (entlast) grupa)
    		(command "_line" (list (car pt1) (- y r))  (list (car pt2) (- y r)) "") 
    		(ssadd (entlast) grupa)
    		(command "_-LAYER" "_S" "osie" "")
    		(command "_line" (list (- (car pt1) przedluzenieosi) y )       (list (+ (car pt2) przedluzenieosi) y) "") ;rysujemy osie symetrii otworów z boku
    		(ssadd (entlast) grupa)
    		;osie na otworach w widoku z góry, na początku os X potem Y
    		(command "_line" (list (- x r przedluzenieosi) y) (list (+ x r przedluzenieosi) y) "" )
    		(ssadd (entlast) grupa)
    		(command "_line" (list x (- y r przedluzenieosi) ) (list x (+ y r przedluzenieosi) ) "" )
    		(ssadd (entlast) grupa)
    		(command "_group" "_c" "*" "opis" grupa "")
    		(setq i (1+ i)) 								;zwiekszamy zmienna i aby odczytac kolejny obiekt
    		)
    	(command "_-LAYER" "_S" aktualnawarstwa "")
    	)
    	

     

    krawedzieotworux1.lsp

  5. Teraz coś co działa. Program do tworzenia krawędzi otworów na drugim rzucie. Wybieramy wszystkie obiekty, odfiltrują się otwory. Wskazujemy gdzie maja się zaczynać i kończyć otwory.

    Na rysunku po lewej przed rzutowaniem po prawej po rzutowaniu. Jak ktoś jest chętny to plik dwg jest tutaj rzutownie-otworow.dwg

    rzutowanie.png.445e6ecbadf699bd712e34d90ff7c140.png

    Plik lispa z opisem krawedzieotworux.lsp

    Teraz pochwalę się moim kodem:

    (defun c:krawedzieotworux ()
    	(princ "Zaznacz okregi do rzutownia: \n")
    	(setq okrag (ssget  '((0 . "CIRCLE")) )) 		;prosimy o wskazanie obiektów oknem. Pozwalamy na wybor tylko okregow
    	(setq ile (sslength okrag)) 				;liczymy ile obiektow zaznaczylismy
    	(setq i 0) 						;ustawiamy zmienna i zeby sobie odliczac
    	(setq pt1 (getpoint "Wskaz poczatek linii: ")) 
    	(setq pt2 (getpoint "Wskaz koniec linii: ")) 
    	(repeat ile	 					; powtarzamy tyle razy ile jest obiektow
    		(setq nazwyobiektow (ssname okrag i))  		; ustalamy nazwe kolejnych obiektow
    		(setq listaobiektu (entget nazwyobiektow))  	;pobieramy wlasciwosci obiektu o nazwie jak w lini wyzej
    		(setq promien (assoc 40 listaobiektu)) 		;odczytujemy promień aktualnego okregu np. (40 . 27.7815)
    		(setq srodek (assoc 10 listaobiektu)) 		;odczytujemy srodek okregu np. (10 310.596 514.272 0.0) 
    		(setq r (cdr promien)) 				;przypisuje do r promien np. 27.7815
    		(setq y (cadr(cdr srodek))) 			;przypisuje do y wspolrzedna Y np. 514.272
    		(command "_line" (list (car pt1) (+ y r))  (list (car pt2) (+ y r)) "") ;rysuje linie car pobiera wspolrzedna X z kliknietych punktow
    		(command "_line" (list (car pt1) (- y r))  (list (car pt2) (- y r)) "") 
    		(setq i (1+ i)) 				;zwiekszamy zmienna i aby odczytac kolejny obiekt
    		)
    	)
    	

     

  6. Dzięki, przyda się.

    Teraz pracuję nad czymś dużym.

    Zrobiłem początek: zapytanie o zaznaczenie obiektów i wyświetlenie liczby zaznaczonych obiektów i ich właściwości.

    (defun c:krawedzie ()
    	(setq okrag (ssget)) ;prosimy o wskazanie obiektów oknem
    	(setq ile (sslength okrag)) ;liczymy ile obiektow zaznaczylismy
    	(setq i 0) ; ustawiamy zmienna i zeby sobie odliczac
    	(repeat ile	 ; powtarzamy tyle razy ile jest obiektow
    		(setq nazwyobiektow (ssname okrag i))  ; ustalamy nazwe kolejnych obiektow
    		(setq listaobiektu (entget nazwyobiektow))  ;pobieramy wlasciwosci obiektu o nazwie jak w lini wyzej
    		(prompt "Obiekt")	;
    		(princ nazwyobiektow) ;drukujemy nazwe obiektu
    		(princ listaobiektu) ; drukujemy wlasciwosci obiektu
    		(setq i (1+ i)) ;zwiekszamy zmienna i aby odczytac kolejny obiekt
    		)
    	)

    W wyniku działania otrzymujemy np. taką listę 

    Wskaż drugi narożnik: 
    znaleziono 7
    Wybierz obiekty: 
    Obiekt<ENTITY NAME: 9d2fc8a8>((-1 . <ENTITY NAME: 9d2fc8a8>) (0 . LWPOLYLINE) (5 . 240) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbPolyline) (90 . 4) (70 . 1) (43 . 0.0) (38 . 0.0) (39 . 0.0) (10 253.739 563.116) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 541.421 563.116) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 541.421 398.539) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 253.739 398.539) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (210 0.0 0.0 1.0))
    Obiekt<ENTITY NAME: 9d2fc890>((-1 . <ENTITY NAME: 9d2fc890>) (0 . CIRCLE) (5 . 23F) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbCircle) (10 494.711 459.655 0.0) (40 . 28.7788) (210 0.0 0.0 1.0))
    Obiekt<ENTITY NAME: 9d2fc878>((-1 . <ENTITY NAME: 9d2fc878>) (0 . CIRCLE) (5 . 23E) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbCircle) (10 461.97 514.66 0.0) (40 . 29.5208) (210 0.0 0.0 1.0))
    Obiekt<ENTITY NAME: 9d2fc860>((-1 . <ENTITY NAME: 9d2fc860>) (0 . CIRCLE) (5 . 23D) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbCircle) (10 419.625 450.488 0.0) (40 . 24.386) (210 0.0 0.0 1.0))
    Obiekt<ENTITY NAME: 9d2fc848>((-1 . <ENTITY NAME: 9d2fc848>) (0 . CIRCLE) (5 . 23C) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbCircle) (10 337.992 440.884 0.0) (40 . 22.7003) (210 0.0 0.0 1.0))
    Obiekt<ENTITY NAME: 9d2fc830>((-1 . <ENTITY NAME: 9d2fc830>) (0 . CIRCLE) (5 . 23B) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbCircle) (10 380.773 504.183 0.0) (40 . 21.6078) (210 0.0 0.0 1.0))
    Obiekt<ENTITY NAME: 9d2fc818>((-1 . <ENTITY NAME: 9d2fc818>) (0 . CIRCLE) (5 . 23A) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbCircle) (10 302.195 483.665 0.0) (40 . 27.7815) (210 0.0 0.0 1.0))7
    Polecenie: 

    i właśnie w tym momencie trochę zacząłem rozumieć o co chodzi z tym wszystkim.

    Modyfikując np. wartość w kodzie 40 w okręgu zmienimy jego średnice. Kod 10 odpowiada za współrzędne.

     

  7. Dziękuję teraz jest znacznie lepiej.

    (defun c:PETLA (/)
      (setq pnt1 (getpoint "Wskaz srodek polprostych: ")) 
      (initget (+ 1 2 4))
      (setq a (getint "\nPodaj ilosc polprostych: " ))
      (setq k (/ 360.0 a)) ; obliczam kat pomiedzy polprostymi
      (setq i 0) ; zmienna do petli
      (while i
      	(command "_line" pnt1 "D" 100 (* k i) "") ; rysowanie linii, kat pomnozony przez zmienna petli i
    	(setq i (1+ i)) ; zwiekszam o 1 wartosc zmiennej i
    	(if (= i a)  ; jesli mam dosc polprostych to wychodze z petli
    		(setq i nil)
    	)
    	
       )
    )

     

    Zastanawiam się jak zrobić żeby przy pytaniu o ilość program zaproponował coś domyślnie np. <23>:

    Trzeba taką zmienną zadeklarować wcześniej i potem jakoś wyświetlić w getint?

  8. No tak :)

    Mam takie coś:

    (defun c:PETLA (/)
      (setq pnt1 (getpoint "Wskaz srodek polprostych: ")) 
      (setq a (getint "\nPodaj ilosc polprostych: " ))
      (setq k (/ 360 a)) ; obliczam kat pomiedzy polprostymi
      (setq i 0) ; zmienna do petli
      (while i
      	(command "_line" pnt1 "D" 100 (* k i) "") ; rysowanie linii, kat pomnozony przez zmienna petli i
    	(setq i (1+ i)) ; zwiekszam o 1 wartosc zmiennej i
    	(if (= i a)  ; jesli mam dosc polprostych to wychodze z petli
    		(setq i nil)
    	)
    	
       )
    )

    Problem polega na tym, że jak kąt jest liczbą całkowitą np. 36 stopni to rysuje poprawnie. Jeśli to ułamek to nie rysuje wszystkich linii.

     

    2020-11-18 13_42_49-ZWCAD 2021 Wersja testowa (Pozostało 30 dni) - [Rysunek1.dwg].png

  9. Po próbach i poprawkach oraz uzupełnianiu nawiasów doszedłem do takiego skryptu:

    (defun c:WS (/)
      (setq pnt1 (getpoint "Wskaz srodek polprostych: "))
      (command "_line" pnt1 "D" 100 0 "")
      (command "_line" pnt1 "D" 100 30 "")
      (command "_line" pnt1 "D" 100 60 "")
      (command "_line" pnt1 "D" 100 90 "")
      (command "_line" pnt1 "D" 100 120 "")
      (command "_line" pnt1 "D" 100 150 "")
      (command "_line" pnt1 "D" 100 180 "")
    )

    ws.lsp

    Polecenie "WS". Skrypt pyta o wskazanie punktu i rysuje linie co 30 stopni.

    1369540586_2020-11-1712_56_09-ZWCAD2021Wersjatestowa(Pozostao30dni)-Rysunek1_dwg.png.aafa1d94fd19d1fbf879cb5c4811754d.png

     

    Teraz chyba czas na pętle.

     

  10. Zaciekawił mnie bardzo LISP. Niewiele wiem ale znalazłem starą książkę.

    Czytam powoli i w tym wątku chcę napisać co ciekawego udało mi się nauczyć :)

    Nawiasy i inne drobiazgi.

    • Wszystko ma być w nawiasach. 
    • Polecenia w cudzysłowach "".
    • Słowo "command" uruchamia polecenie programu.

    Przykład 

    (command "okrąg")


    powoduje uruchomienie rysowania okręgu.

    Za poleceniem możemy wpisać kolejne parametry np.

    (command "okrąg" "2.5,20" 30)

    Polecenie narysuje okrąg o środku w punkcie 2.5 i 20 o promieniu 30.

     

    Pauza czyli przystanek na żądanie.

    Słowo "pause" czeka na wskazanie czegoś przez użytkownika.

    To polecenie pozwala pokazać środek okręgu i rysuje okrąg o promieniu 5 i środku we wskazanym punkcie.

    (command "okrąg" pause 5)

    To rysuje prostokąt we wskazanym punkcie o szerokości 25, długość sami wprowadzamy.

    (command "prostokąt" pause "W" 25 pause)

     

  11. Potrzebowałbym taką funkcję do kopiowania (a może już jest?):

    1. wybieram funkcje i zaznaczam element
    2. teraz mogę wpisać odległość albo zmierzyć myszą
    3. dopiero teraz wskazuję punkt bazowy i kierunek
    4. po naciśnięciu enter program wykonuje kopię w wybranym kierunku
    5. po kolejnych naciśnięciach entera tworzone są kolejne kopie w takiej samej odległości od ostatniej kopi jak odległość w punkcie 2 i w tym samym kierunku - czyli jak w punkcie 2 wpisze odległość 60, to kopie będą w 60, 120, 180, 240, 300 itp.