Pawcyk Opublikowano 6 Marca 2017 Zgłoś Udostępnij Opublikowano 6 Marca 2017 Dzień dobry. Próbuję wykonać pewną operację na wielu powierzchniach 3DFace. Dla przykładu pomnożyć współrzędną "Z" wierzchołków razy 10. Korzystając z kilku podpowiedzi:https://www.zwcad.pl/help/lisp-help/246-subst.htmlhttp://forums.augi.com/showthread.php?120834-How-to-know-name-of-Entity-by-ssget Stworzyłem coś takiego: (defun c:zz () (if (setq ssSelections (ssget (list (cons 0 "3DFACE")))) (repeat (setq intCount (sslength ssSelections)) (setq intCount (1- intCount) entSelection (ssname ssSelections intCount) lstEntity (entget entSelection) ) ;współrzędne wierzchołka 1 (setq wierzcholek1 (assoc 10 lstEntity)) (setq x1 (nth 1 wierzcholek1)) (setq y1 (nth 2 wierzcholek1)) (setq z1 (nth 3 wierzcholek1)) ;współrzędne wierzchołka 2 (setq wierzcholek2 (assoc 11 lstEntity)) (setq x2 (nth 1 wierzcholek2)) (setq y2 (nth 2 wierzcholek2)) (setq z2 (nth 3 wierzcholek2)) ;podmiana punktu 1 (setq lstEntity (subst (cons 10 (list x1 y1 (* z1 10)) (assoc '10 lstEntity ) lstEntity ) )) (entmod lstEntity) ;podmiana punktu 2 (setq lstEntity (subst (cons 11 (list x2 y2 (* z2 10)) (assoc '11 lstEntity ) lstEntity ) )) (entmod lstEntity) );koniec repeat );koniec if (print) );Koniec W powyższym kodzie pominąłem dwa ostatnie punkty. Chciałem pokazać tylko ideę. Co robię źle, że to nie działa? Pozdrawiam Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kojacek Opublikowano 7 Marca 2017 Zgłoś Udostępnij Opublikowano 7 Marca 2017 (edytowane) Prawie wszystko. Począwszy od: 1) braku zmiennych lokalnych (zobacz: https://kojacek.wordpress.com/2015/12/20/symbole-zmienne/). 2) Potem pomysł z mnożeniem wartości współrzędnej z. Operacje dodawania/odejmowania wydają się być chyba bardziej naturalne (sprawdź mnożenie 1 i 0 przez dowolną wartość). Na marginesie: zmiana składowej Z wszystkich punktów obiektu, o tę samą wartość, to w rzeczywistości przesunięcie go w przestrzeni - to można też robić prościej (command MOVE, lub vla-Move dla ActiveX) 3) Ponadto ja bym nie użył (ze względu na wydajność) repeat, tylko raczej foreach dla listy otrzymanej ze zbioru wskazań. 4) Tak samo zmieniłbym całą listę, i tylko raz wywołał entmod. Oczywiście dwa ostatnie punkty nie są szczególnymi błędami. Poczytaj też o: https://kojacek.wordpress.com/2015/11/04/cadpl-pack/ Jest tam parę dość użytecznych rzeczy. Edytowane 7 Marca 2017 przez kojacek Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Pawcyk Opublikowano 7 Marca 2017 Autor Zgłoś Udostępnij Opublikowano 7 Marca 2017 Oczywiście zajrzę na Pańską stronę. Każda dodatkowa wiedza jest cenna. Do tej pory myślałem, że deklarowanie zmiennych to pomoc przy dużych kodach, a nie konieczność. Czy to może być powodem nie działania programu? Program działa do linijki: podmiana punktu 1 Natomiast mnożenie zmiennej "Z" to tylko przykład. Pozdrawiam Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kojacek Opublikowano 7 Marca 2017 Zgłoś Udostępnij Opublikowano 7 Marca 2017 Zobacz to: (setq NowyZ 152) (defun C:ZZ (/ ss :chFaceZ) (defun :chFaceZ (En Val / l d n p) (setq l '(10 11 12 13) d (entget En) n (vl-remove-if '(lambda (%)(member (car %) l)) d) p (vl-remove-if-not '(lambda (%)(member (car %) l)) d) p (mapcar '(lambda (%) (list (car %)(cadr %)(caddr %)(+ Val (cadddr %)))) p) ) (entmod (append n p)) ) (if (setq ss (ssget '((0 . "3DFACE")))) (foreach % (cd:SSX_Convert ss 0) (:chFaceZ % NowyZ) ) ) (princ) ) Dodaje wartość zmiennej globalnej NowyZ do składowej z każdego wierzchołka wybranych 3DFace. Wykorzystuje cd:SSX_Convert ze wspomnianego CADPL-Pack'a Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Pawcyk Opublikowano 7 Marca 2017 Autor Zgłoś Udostępnij Opublikowano 7 Marca 2017 Mój poziom wiedzy o lispie jest o kilka poziomów za niski, żeby w 100% zrozumieć powyższy kod... a może strach ma wielkie oczy. Żeby ruszyć dalej z nauką muszę wiedzieć gdzie robię błędy na obecnym etapie. Tak czy siak dziękuję za pomoc PS docelowy kod ma zmieniać wsp wierzchołków z takich: W1: x1=5.12345678 y1=3.23456789 z1=7.42345678 na takie: W1: x1=5.12000000 y1=3.23000000 z1=7.42000000 Czyli niewielkie przesunięcie. Uważałem, że nie ma potrzeby pisać całego kodu, dlatego posłużyłem się przykładem (* z 10) Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kruszynski Opublikowano 8 Marca 2017 Zgłoś Udostępnij Opublikowano 8 Marca 2017 Problemem w kodzie z pierwszego przykładu jest: LISP czyli Lost In Stupid Parentheses Po uruchomieniu kodu w pasku poleceń pojawia się : Error: too many arguments czyli któraś funkcja została wywołana ze zbyt dużą ilością argumentów. Pozostaje nam znaleźć która. Tak na pierwszy rzut oka wyglądało OK, więc spróbowałem wykonać kod "po linijce" Okazało się, że komunikat wyświetla linijka (setq lstEntity (subst (cons 10 (list x1 y1 (* z1 10)) (assoc '10 lstEntity ) lstEntity ) )) Notepad++ ma kolorowanie składni i podświetlanie nawiasów. Więc łatwo widać, że to cons, ma nawias zbyt daleko. Czyli cały poprawiony kod: (defun c:zz () (if (setq ssSelections (ssget (list (cons 0 "3DFace")))) (repeat (setq intCount (sslength ssSelections)) (setq intCount (1- intCount) entSelection (ssname ssSelections intCount) lstEntity (entget entSelection) ) ;współrzędne wierzchołka 1 (setq wierzcholek1 (assoc 10 lstEntity)) (setq x1 (nth 1 wierzcholek1)) (setq y1 (nth 2 wierzcholek1)) (setq z1 (nth 3 wierzcholek1)) ;współrzędne wierzchołka 2 (setq wierzcholek2 (assoc 11 lstEntity)) (setq x2 (nth 1 wierzcholek2)) (setq y2 (nth 2 wierzcholek2)) (setq z2 (nth 3 wierzcholek2)) ;podmiana punktu 1 (setq lstEntity (subst (cons 10 (list x1 y1 (* z1 10) )) (assoc '10 lstEntity ) lstEntity ) ) (entmod lstEntity) ;podmiana punktu 2 (setq lstEntity (subst (cons 11 (list x2 y2 (* z2 10) ) ) (assoc '11 lstEntity ) lstEntity ) ) (entmod lstEntity) );koniec repeat );koniec if (print) );Koniec Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Pawcyk Opublikowano 8 Marca 2017 Autor Zgłoś Udostępnij Opublikowano 8 Marca 2017 Lost In Stupid Parentheses - to moje nowe motto;) Nie mogę uwierzyć,że to o to chodziło. Co do powyższego kodu jest jeszcze jeden bug. Zmienia tylko jeden wierzchołek. Prawdopodobnie dlatego, że przy drugim punkcie odwołuję się do lstEntity (przed zmianą 1 punktu). Rozwiązałem to tak: (defun ChangeVx ( NrVx / ) (repeat (setq intCount (sslength ssSelections)) (setq intCount (1- intCount) entSelection (ssname ssSelections intCount) lstEntity (entget entSelection) ) ;Vertex (setq wierzcholek (assoc NrVx lstEntity)) (setq x1 (nth 1 wierzcholek)) (setq y1 (nth 2 wierzcholek)) (setq z1 (nth 3 wierzcholek)) ;podmiana punktu (setq nowaDef (subst (cons NrVx (list (atof (rtos x1 2 2)) (atof (rtos y1 2 2)) (atof (rtos z1 2 2)) )) (assoc 'NrVx lstEntity ) lstEntity )) (setq nowaDef (append lstEntity (list (cons NrVx (list (atof (rtos x1 2 2)) (atof (rtos y1 2 2)) (atof (rtos z1 2 2)))) ) ) ) (entmod nowaDef) );koniec repeat (print) ); (defun c:zz () (setq ssSelections (ssget (list (cons 0 "3DFACE")))) (setq NrVx 10) (repeat 4 (ChangeVx NrVx ) (setq NrVx (1+ NrVx)) );end repeat );KONIEC A zamiast: (atof (rtos x 2 2)) można tak: (/ (fix (* x 100.)) 100.0) Dziękuję za wszystkie podpowiedzi Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
Dołącz do dyskusji
Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.