Pawcyk Opublikowano 21 Marca 2017 Zgłoś Opublikowano 21 Marca 2017 (edytowane) Dzień dobry. Mam pewien pomysł na lispa. Niestety nie potrafię go samemu napisać. Otóż: 1- tworzę z punktów 3D siatkę powierzchni 3DFace (http://paulbourke.net/papers/triangulate/Triangulator.LSP) 2- rysuję trasę (np. wodociągu, kanalizacji, drogi...) jako polilinię 2D (z=0) ;tu zaczyna się proponowany lisp 3- tymczasowo tworzę powierzchnie 3DFACE o z=0 (https://forum.cad.info.pl/topic/1873-entmod-na-wielu-obiektach/) 4- znajduję punkty przecięcia z krawędziami powierzchni 3DFACE (punkty 2D) Nie wiem czy to pomoże, ale znalazłem coś takiego: (http://www.cadstudio.cz/freeware Chodzi o plik: INTLINES - draws points in all intersections of selected objects, lines, incl. self-intersections (cdnc5-02.LSP by B.Kramer)) 5- tworzę listę z długością polilinii 2D do tych punktów Np. tak: (vl-load-com) (if (and (progn (prompt "\n Select Polyline :") (setq e (ssget "_:s" '((0 . "*POLYLINE")))) ) (setq p (getpoint "\n Specify point on the previous selected polyline :")) ) (print (vlax-curve-getdistatpoint (ssname e 0) (vlax-curve-getclosestpointto (ssname e 0) p))) ) 6- rzutuję punkty 2D na powierzchnie 3DFACE. Pojawia się kilka pytań: na którą powierzchnię? odp: na powierzchnię, w której po spłaszczeniu (z=0) taki punkt się znajdzie (punkt wewnątrz trojkąta,a dokładnie na krawędzi): (https://4programmers.net/Forum/Newbie/187154-program_sprawdzajacy_czy_punkt_nalezy_do_trojkata_) jak taki punkt zrzutować? odp: (https://forums.autodesk.com/t5/net/getting-the-point-of-intersection-between-plane-and-spline-3d/td-p/5812328) 7 - odczytuję współrzędne Z utworzonych punktów 3D Mając odległości (pkt 5) i rzędne (pkt 7) można narysować profil po terenie istniejącym Pozdrawiam Edytowane 21 Marca 2017 przez Pawcyk Cytuj
dmatusz3 Opublikowano 21 Marca 2017 Zgłoś Opublikowano 21 Marca 2017 Temat wydaje się ciekawy, niestety raczej nie będziemy w stanie opracować "wszystkomającego" lispa za jednym zamachem. Chętnie pomożemy ale proszę się zastanowić nad podzieleniem jednego dużego skryptu na większą liczbę małych funkcji. Tym bardziej, że zagadnienie jest nieco zawiłe i można "pójść w złym kierunku". Cytuj
JasW Opublikowano 21 Marca 2017 Zgłoś Opublikowano 21 Marca 2017 (edytowane) Wydaje mi się że łatwiej coś by można podpowiedzieć jeśli autor umieściłby jakieś szkice. Może DWG z wykonanym krokiem 1 oraz screen lub drugi DWG z tym co ma byc na końcu (krok 7) . J. Edytowane 21 Marca 2017 przez JasW Cytuj
Pawcyk Opublikowano 21 Marca 2017 Autor Zgłoś Opublikowano 21 Marca 2017 (edytowane) Zrobiłem kilka rysunków pokazujących co mi chodzi po głowie. Edytowane 21 Marca 2017 przez Pawcyk Cytuj
Pawcyk Opublikowano 21 Marca 2017 Autor Zgłoś Opublikowano 21 Marca 2017 Wydaje mi się, że pierwszym krokiem byłoby (punkt 4) stworzenie listy punktów utworzonych w miejscach przecięć osi i krawędzi powierzchni o z=0. Poprzednie kroki już są zrobione. Cytuj
kruszynski Opublikowano 22 Marca 2017 Zgłoś Opublikowano 22 Marca 2017 NIe sprawdzałem na żywym przykładzie, ale teoretycznie punkty przecięcia 3DFace z polilinią może się udać uzyskać tak: (vlax-invoke-method powierzchnia 'IntersectWith oś acExtendNone ) Cytuj
JasW Opublikowano 22 Marca 2017 Zgłoś Opublikowano 22 Marca 2017 20 godzin temu, Pawcyk napisał: Dzień dobry. 2- rysuję trasę (np. wodociągu, kanalizacji, drogi...) jako polilinię 2D (z=0) ;tu zaczyna się proponowany lisp Pozdrawiam Spostrzeżenia: 1. Jeśli w pkt 1 mamy już siatkę (np. triangulacyjną) to w pkt 2 zamiast używania polilinii 2d lepiej użyć polilinii 3d (3dPoly) wtedy problem właściwie sam się rozwiązuje gdy zadbamy by snap polilinii łapał także współrzedną 'z' najbliższego 3DFace. Stworzenie rozciągniętej kopii tej polilinii (jako profil) to już banalne zadanie. 2. Duża mapa to setki 3dFace. Jeśli chcesz porządny skrypt zrobić to znacznie bardziej skuteczne będzie uzycie zamiast n*3dFace obiektów PolygonMesh lub PolyfaceMesh lepiej przystosowanychdo pracy jako siatka terenu z elewacją. 3. W Zwcad2017 jest polecenie gein ( import z Google Earth) . Prawdopodobnie importuje płaskie zdjęcia (bez elewacji) ale jako podklad graficzny terenu byłby przydatny w całości takiego projektu do dokumentacji. J. Cytuj
Pawcyk Opublikowano 22 Marca 2017 Autor Zgłoś Opublikowano 22 Marca 2017 (edytowane) 1 godzinę temu, JasW napisał: Spostrzeżenia: 1. Jeśli w pkt 1 mamy już siatkę (np. triangulacyjną) to w pkt 2 zamiast używania polilinii 2d lepiej użyć polilinii 3d (3dPoly) wtedy problem właściwie sam się rozwiązuje gdy zadbamy by snap polilinii łapał także współrzedną 'z' najbliższego 3DFace. Stworzenie rozciągniętej kopii tej polilinii (jako profil) to już banalne zadanie. 2. Duża mapa to setki 3DFace. Jeśli chcesz porządny skrypt zrobić to znacznie bardziej skuteczne będzie uzycie zamiast n*3dFace obiektów PolygonMesh lub PolyfaceMesh lepiej przystosowanychdo pracy jako siatka terenu z elewacją. 3. W Zwcad2017 jest polecenie gein ( import z Google Earth) . Prawdopodobnie importuje płaskie zdjęcia (bez elewacji) ale jako podklad graficzny terenu byłby przydatny w całości takiego projektu do dokumentacji. J. Ad 1. Pojawia się problem z łukami. Po drugie jak narysować polilinię 3d idealnie prostą w płaszczyźnie 2D? Ad 2. Przyznam się że nie zastanawiałem się nad zastosowaniem innych rzeczy niż 3DFace. Można również narysować zwykłe trójkąty z 3DPOLY (program do triangulacji tworzy 3DFACE) 2 godziny temu, kruszynski napisał: NIe sprawdzałem na żywym przykładzie, ale teoretycznie punkty przecięcia 3DFace z polilinią może się udać uzyskać tak: (vlax-invoke-method powierzchnia 'IntersectWith oś acExtendNone ) A co do tworzenia punktów wygrzebałem coś takiego: http://www.lee-mac.com/intersectionfunctions.html co daje taki efekt: ;; Intersections - Lee Mac ;; Returns a list of all points of intersection between two objects ;; for the given intersection mode. ;; ob1,ob2 - [vla] VLA-Objects ;; mod - [int] acextendoption enum of intersectwith method (defun LM:intersections ( ob1 ob2 mod / lst rtn ) (if (and (vlax-method-applicable-p ob1 'intersectwith) (vlax-method-applicable-p ob2 'intersectwith) (setq lst (vlax-invoke ob1 'intersectwith ob2 mod)) ) (repeat (/ (length lst) 3) (setq rtn (cons (list (car lst) (cadr lst) (caddr lst)) rtn) lst (cdddr lst) ) ) ) (reverse rtn) ) ;; Intersections Between Sets - Lee Mac ;; Returns a list of all points of intersection between objects in two selection sets. ;; ss1,ss2 - [sel] Selection sets (defun LM:intersectionsbetweensets ( ss1 ss2 / id1 id2 ob1 ob2 rtn ) (repeat (setq id1 (sslength ss1)) (setq ob1 (vlax-ename->vla-object (ssname ss1 (setq id1 (1- id1))))) (repeat (setq id2 (sslength ss2)) (setq ob2 (vlax-ename->vla-object (ssname ss2 (setq id2 (1- id2)))) rtn (cons (LM:intersections ob1 ob2 acextendnone) rtn) ) ) ) (apply 'append (reverse rtn)) ) (defun c:intersets ( / ss1 ss2 ) (if (and (setq ss1 (ssget)) (setq ss2 (ssget)) ) (foreach pnt (LM:intersectionsbetweensets ss1 ss2) (entmake (list '(0 . "POINT") (cons 10 pnt))) ) ) (princ) ) (vl-load-com) (princ) ...i działa. Chociaż wolałbym jedną linijkę kodu... Edytowane 22 Marca 2017 przez Pawcyk Cytuj
Pawcyk Opublikowano 22 Marca 2017 Autor Zgłoś Opublikowano 22 Marca 2017 Punkt 4 odhaczony. Punkt 5 również da radę zrobić. Czas na 6, czyli z listy wszystkich 3DFace wybrać tę powierzchnię, która spełnia warunek:https://4programmers.net/Forum/Newbie/187154-program_sprawdzajacy_czy_punkt_nalezy_do_trojkata_ Wcześniej pisałem, że trzeba "spłaszczyć" 3DFace, ale wystarczy do sprawdzenia brać tylko współrzędne x i y wierzchołków. Pozdrawiam Cytuj
Pawcyk Opublikowano 23 Marca 2017 Autor Zgłoś Opublikowano 23 Marca 2017 Zdaje się, że wyważamy otwarte drzwi...https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/to-get-intersection-between-a-line-and-a-3dface/td-p/2745633/page/3 ;lisp by Marko_Ribar (defun _ilt ( p1 p2 t1 t2 t3 / v^v unit Coplanar-p ptinsidetriangle-p ptontriangle-p ptonline-p _ilp nor o ) (defun v^v ( u v ) (list (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u))) (- (* (car v) (caddr u)) (* (car u) (caddr v))) (- (* (car u) (cadr v)) (* (car v) (cadr u))) ) ) (defun unit ( v ) (mapcar '(lambda ( x ) (/ x (distance '(0.0 0.0 0.0) v))) v) ) (defun Coplanar-p ( p1 p2 p3 p4 ) ( (lambda ( n1 n2 ) (equal (v^v n1 n2) '(0.0 0.0 0.0) 1e-8) ) (v^v (mapcar '- p1 p2) (mapcar '- p1 p3)) (v^v (mapcar '- p1 p2) (mapcar '- p1 p4)) ) ) (defun ptinsidetriangle-p ( pt p1 p2 p3 ) (if (and (Coplanar-p pt p1 p2 p3) (not (or (inters pt p1 p2 p3) (inters pt p2 p1 p3) (inters pt p3 p1 p2) ) ) (not (or (> (+ (distance pt p1) (distance pt p2)) (+ (distance p3 p1) (distance p3 p2))) (> (+ (distance pt p2) (distance pt p3)) (+ (distance p1 p2) (distance p1 p3))) (> (+ (distance pt p3) (distance pt p1)) (+ (distance p2 p3) (distance p2 p1))) ) ) ) T nil ) ) (defun ptontriangle-p ( pt p1 p2 p3 ) (if (or (equal (distance p1 p2) (+ (distance pt p1) (distance pt p2)) 1e-7) (equal (distance p2 p3) (+ (distance pt p2) (distance pt p3)) 1e-7) (equal (distance p1 p3) (+ (distance pt p1) (distance pt p3)) 1e-7) ) T nil ) ) (defun ptonline-p ( pt p1 p2 ) (equal (distance p1 p2) (+ (distance pt p1) (distance pt p2)) 1e-7) ) (defun _ilp ( p1 p2 o nor / p1p p2p op tp pp p ) (if (not (equal (v^v nor (unit (mapcar '- p2 p1))) '(0.0 0.0 0.0) 1e-7)) (progn (setq p1p (trans p1 0 (v^v nor (unit (mapcar '- p2 p1)))) p2p (trans p2 0 (v^v nor (unit (mapcar '- p2 p1)))) op (trans o 0 (v^v nor (unit (mapcar '- p2 p1)))) op (list (car op) (cadr op) (caddr p1p)) tp (polar op (+ (* 0.5 pi) (angle '(0.0 0.0 0.0) (trans nor 0 (v^v nor (unit (mapcar '- p2 p1)))))) 1.0) ) (if (inters p1p p2p op tp nil) (progn (setq p (trans (inters p1p p2p op tp nil) (v^v nor (unit (mapcar '- p2 p1))) 0)) p ) nil ) ) (progn (setq pp (list (car (trans p1 0 nor)) (cadr (trans p1 0 nor)) (caddr (trans o 0 nor)))) (setq p (trans pp nor 0)) p ) ) ) (setq nor (unit (v^v (mapcar '- t3 t1) (mapcar '- t2 t1)))) (setq o t1) (if (_ilp p1 p2 o nor) (if (and (or (ptinsidetriangle-p (_ilp p1 p2 o nor) t1 t2 t3) (ptontriangle-p (_ilp p1 p2 o nor) t1 t2 t3) ) (ptonline-p (_ilp p1 p2 o nor) p1 p2) ) (_ilp p1 p2 o nor) nil ) nil ) ) (defun c:bum () (setq P100 (getpoint)) (setq P101 (getpoint)) (setq T100 (getpoint)) (setq T101 (getpoint)) (setq T102 (getpoint)) (_ilt P100 P101 T100 T101 T102) );Koniec test Cytuj
Pawcyk Opublikowano 23 Marca 2017 Autor Zgłoś Opublikowano 23 Marca 2017 Jeżeli można to wróciłbym do punktu 3 i 4. Otóż zastanawiam się na koniecznością tworzenia zrzutowanych 3DFace do poziomu zero. Może w kodzie ze str.http://www.lee-mac.com/intersectionfunctions.htm (zaproponowanym kilka postów wyżej) linijkę:(setq rtn (cons (list (car lst) (cadr lst) (caddr lst)) rtn) wystarczy zamienić na: (setq rtn (cons (list (car lst) (cadr lst) 0) rtn) Oczywiście nie wystarczy ..bo nie tworzy w ten sposób "wirtualnych" punktów przecięcia. Idea jest taka aby program brał współrzędne powierzchni x, y, a za "z" podstawiał 0. W ten sposób odpadnie konieczność tworzenia płaskich 3DFACE. Cytuj
Pawcyk Opublikowano 29 Marca 2017 Autor Zgłoś Opublikowano 29 Marca 2017 Próbuję coś tam pisać, ale ze względu na ograniczony wolny czas idzie mi to powoli. Natrafiłem na problem. Poniższy kod raz rzutuje punkt, a raz wyrzuca błąd. ;; ;;PONIEWAŻ 3DFace POSIADA 4 WIERZCHOLKI (2 TAKIE SAME) NALEŻY USUNĄĆ DUPLIKUJĄCE SIĘ ELEMENTY ;; ;; Unique - Lee Mac ;; Returns a list with duplicate elements removed. ;; (defun remove_doubles (lst /) (vl-load-com) (if lst (cons (car lst) (remove_doubles (vl-remove (car lst) lst))))) ;; ;; (defun c:bum () (print "wskaż powierzchnie") (setq ssSelections (ssget)) (print "wskaż punkt") (setq Point (getpoint)) (setq Point2 (list (nth 0 Point) ; Point i Point2 tworzy linię pionową o wys 500 (nth 1 Point) 500)) (repeat (setq intCount (sslength ssSelections)) (setq intCount (1- intCount) entSelection (ssname ssSelections intCount) lstEntity (entget entSelection)) ;Wierzchołki 3DFACE (setq P10 (list (nth 1 (assoc 10 lstEntity)) (nth 2 (assoc 10 lstEntity)) (nth 3 (assoc 10 lstEntity)) ) P11 (list (nth 1 (assoc 11 lstEntity)) (nth 2 (assoc 11 lstEntity)) (nth 3 (assoc 11 lstEntity)) ) P12 (list (nth 1 (assoc 12 lstEntity)) (nth 2 (assoc 12 lstEntity)) (nth 3 (assoc 12 lstEntity)) ) P13 (list (nth 1 (assoc 13 lstEntity)) (nth 2 (assoc 13 lstEntity)) (nth 3 (assoc 13 lstEntity)) )) ;Lista wierzchołków z jednym (zdublowanym) usuniętym (setq ListVtx (remove_doubles (list P10 P11 P12 P13) )) ;Pozostałe 3 wierzchołki trójkąta (setq P100 (nth 0 ListVtx) P101 (nth 1 ListVtx) P102 (nth 2 ListVtx)) ;tworzenie punktu przecięcia linii (point, Point2) i trójkąta (P100 P101 P102) (entmake (list '(0 . "POINT") (cons 10 (_ilt Point Point2 P100 P101 P102)) )) );end repeat );koniec bum UWAGA: kod funkcji _ilt jest zamieszczony wyżej. ...a i jeszcze jeden problem. jeżeli punkt 2D (który rzutujemy) trafia na krawędź 2 trójkątów to program tworzy 2 punkty. Jak to obejść? Pozdrawiam Cytuj
kruszynski Opublikowano 31 Marca 2017 Zgłoś Opublikowano 31 Marca 2017 Dnia 29.03.2017 o 14:14, Pawcyk napisał: Natrafiłem na problem. Poniższy kod raz rzutuje punkt, a raz wyrzuca błąd. może Pan coś więcej powiedzieć na temat tego błędu? np komunikat błędu jaki się pojawia? sprawdzałem na stworzonym przez siebie przykładzie i komunikat jaki otrzymuję jest: Error: incorrect type - nil Jest to spowodowane tym, że _ilt czasem zwraca nil, a w pętli jest (entmake (list '(0 . "POINT") (cons 10 (_ilt Point Point2 P100 P101 P102)) )) Jesli _ilt zwróci nil, to gdzie entmake ma wstawić punkt? Najłatwiej to ogarnąć tak: (setq iltresult (_ilt Point Point2 P100 P101 P102 ) ) (if (not (null iltresult)) (progn (entmake (list '(0 . "POINT") (cons 10 iltresult ) )) ) Dnia 29.03.2017 o 14:14, Pawcyk napisał: ...a i jeszcze jeden problem. jeżeli punkt 2D (który rzutujemy) trafia na krawędź 2 trójkątów to program tworzy 2 punkty. Jak to obejść? Na rozwiązanie tego tematu może być wiele pomysłów, ja proponuję taki, żeby w funkcji tworzyć listę punktów. następnie usunąć z niej duplikaty, a na końcu rysować punkty z przeczyszczonej listy. Samo usuwanie duplikatów może spowodować niespodzianki jeśli użyje Pan do porównania operatora =. do porównywania punktów lepiej jest użyć np (> (distance p1 p2 ) 0.0001) albo: (equal p1 p2 0.0001 ) Cytuj
Pawcyk Opublikowano 12 Kwietnia 2017 Autor Zgłoś Opublikowano 12 Kwietnia 2017 ...z dziennika pokładowego: nie mam już siły do kodu "ilt". Coś z nim jest nie tak, albo ja czegoś nie ogarniam. Raz działa ok, a raz wyrzuca nil. Chyba będę musiał się przyjrzeć propozycji: (vlax-invoke-method powierzchnia 'IntersectWith oś acExtendNone ) Cytuj
montek Opublikowano 21 Maja 2017 Zgłoś Opublikowano 21 Maja 2017 Wczoraj znalazłem taki program, niestety działa na wersji ZW2015+ http://www.glamsen.se/CadTools.htm jest praktycznie za darmo. Generalnie jest pod drogi, ale można utworzyć teren, siatkę, warstwice na podstawie pkt.PL3D przekroje, profil, powierzanie wykopu i nasypu. Ma nawet funkcję konwersji tekstu na rzędną Z . Cytuj
Pawcyk Opublikowano 24 Maja 2017 Autor Zgłoś Opublikowano 24 Maja 2017 Już go kiedyś testowałem i jest problem z nowszymi windowsami. Montek, a u Ciebie działa na jakim windowsie?? Cytuj
montek Opublikowano 24 Maja 2017 Zgłoś Opublikowano 24 Maja 2017 Win 7 Pro 64bit Nie działa na ZW2017 aczkolwiek są pytania do autora czy planuje dostosowanie do nowej wersji http://glamsen.se/smf/index.php?topic=392.msg1093#msg1093 Cytuj
montek Opublikowano 8 Sierpnia 2017 Zgłoś Opublikowano 8 Sierpnia 2017 Dnia 12.04.2017 o 07:50, Pawcyk napisał: ...z dziennika pokładowego Czy o prócz tego lispa udało się Tobie znaleźć coś żeby robić poprzeczki i profil na podstawie terenu. Niestety rzeźbie na podstawie interpolowanych pktów ale jakakolwiek zmiana to robota odnowa :( Dzięki Cytuj
Mayster Opublikowano 11 Sierpnia 2017 Zgłoś Opublikowano 11 Sierpnia 2017 Też mam problem z odpaleniem na win10. Cytuj
montek Opublikowano 11 Sierpnia 2017 Zgłoś Opublikowano 11 Sierpnia 2017 @Mayster sprawdź a forum CadTools http://glamsen.se/smf/index.php?topic=395.msg1068#msg1068 może się uda uruchomić, aha Cadtools działa tylko z ZWCad+ 2014 v 2015 Cytuj
Pawcyk Opublikowano 17 Sierpnia 2017 Autor Zgłoś Opublikowano 17 Sierpnia 2017 Znalazłem to: ale niestety musimy poczekać na uzupełnienie paru funkcji... Cytuj
s1016 Opublikowano 18 Sierpnia 2017 Zgłoś Opublikowano 18 Sierpnia 2017 (edytowane) CadTools można uruchomić na zwcad2017. wg informacji znalezionych na ich forum trzeba: cad version and parameter ustawić na manually i potem podać zwcad.application.2017. Sprawdzałem działa. podobno działa około 85% funkcji Edytowane 18 Sierpnia 2017 przez s1016 Cytuj
montek Opublikowano 19 Sierpnia 2017 Zgłoś Opublikowano 19 Sierpnia 2017 Dzięki @s1016 - działa Cytuj
Mayster Opublikowano 28 Sierpnia 2017 Zgłoś Opublikowano 28 Sierpnia 2017 Też potwierdzam, dzięki! ;) Cytuj
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ą.