kojacek

Użytkownik forum
  • Postów

    236
  • Dołączył

  • Ostatnia wizyta

  • Wygrane w rankingu

    26

Treść opublikowana przez kojacek

  1. Tak jak w opisie podałem - są to dwa Fieldy zagnieżdżone. Pierwszy to pobrany kąt obiektu typu linia - to jest _ObjId 2081....864, i to jest odniesienie do obiektu graficznego. Oraz drugi, to jest _FldPtr 2081...760, czyli wartość kąta tej linii, czyli Field jako obiekt niegraficzny. Jeden jest odwołaniem do obiektu, drugi odwołaniem do jego właściwości (tutaj kąta).
  2. W programach z obsługą pól danych (FIELD) można tworzyć dynamiczny opis wartości pochylenia: https://kojacek.wordpress.com/autolisp/inne/teksty-i-opisy/field-pochylenie-dynamiczne/
  3. kojacek

    Bloki (dynamiczne)

    Tutaj szerszy opis: https://kojacek.wordpress.com/autolisp/obiekty-niegraficzne/tablice-symboli/blok-effectivename/
  4. kojacek

    Bloki (dynamiczne)

    Zagadnienie (bo nie problem) w AutoCAD, było (na polskim forum CAD) omawiane już wiele lat temu (gdy tylko pojawiły się bloki dynamiczne). Droga jest stosunkowo prosta: Odniesienie (wstawienie) bloku (mające nazwę anonimową) jest dynamicznym blokiem zależnym od nazwanego bloku dynamicznego, po spełnieniu warunków - (1) jego definicja posiada dane dodatkowe aplikacji o nazwie "AcDbBlockRepBTag", oraz (2) zawiera (w tych danych dodatkowych) odniesienie do uchwytu (handle) obiektu, który jest definicją bloku nazwanego. W zestawie funkcji CADPL-Pack, (http://forum.cad.pl/cadpl-pack-v1-lsp-t78161.html) zdefiniowana jest funkcja o nazwie cd:BLK_GetDynBlockNames. Zwraca ona listę wszystkich nazw odniesień (bloków anonimowych) zależnych.
  5. Obawiam się że się nie da. Dla twoich wywołań (bez ostatniego) sprawdź: (entget (vlax-vla-object->ename (vla-item mldrdict 0))) Wywołanie to zwraca coś podobnego do tego: ((-1 . <Entity name: 94c8760>) (0 . "ACAD_PROXY_OBJECT") (5 . "E1") (102 . "{ACAD_REACTORS") (330 . <Entity name: 94c8870>) (102 . "}") (100 . "AcDbMLeaderStyle") (90 . 499.000) (91 . 0.000000) (95 . 0.000000) (70 . 0) (94 . 0.000000)) W AutoCAD-zie to samo wywołanie zwraca: ((-1 . <Nazwa elementu: 7ff663004ce0>) (0 . "MLEADERSTYLE") (5 . "25E") (102 . "{ACAD_REACTORS") (330 . <Nazwa elementu: 7ff663004150>) (102 . "}") (330 . <Nazwa elementu: 7ff663004150>) (100 . "AcDbMLeaderStyle") (179 . 2) (170 . 2) (171 . 1) (172 . 0) (90 . 2) (40 . 0.0) (41 . 0.0) (173 . 1) (91 . -1073741824) (340 . <Nazwa elementu: 0>) (92 . -2) (290 . 1) (42 . 0.4) (291 . 1) (43 . 2.0) (3 . "") (341 . <Nazwa elementu: 0>) (44 . 0.18) (300 . "") (342 . <Nazwa elementu: 0>) (174 . 7) (178 . 6) (175 . 0) (176 . 0) (93 . -1073741824) (45 . 0.2) (292 . 0) (297 . 0) (46 . 5.0) (343 . <Nazwa elementu: 0>) (94 . -1073741824) (47 . 1.0) (49 . 1.0) (140 . 1.0) (293 . 1) (141 . 0.0) (294 . 1) (177 . 0) (142 . 1.0) (295 . 0) (296 . 0) (143 . 0.125) (271 . 0) (272 . 9) (273 . 9) (298 . 1)) Wynika z tego że w ZwCAD-zie, nie ma obiektu typu "MLEADERSTYLE". Obsługuje go uniwersalny obiekt zastępczy "ACAD_PROXY_OBJECT". Domyślam się zatem że ZwCAD obłuży z LISP-a style wielolinii, za jakiś czas dopiero (wątpię czy będzie to 2017).
  6. Dyskusje na ten temat w przeszłości miały już miejsce: http://forum.cad.pl/przenoszenie-w-a-ciwo-ci-rysunku-drawing-properties-t79709.html? oraz: http://forum.cad.pl/cadpl-pack-v1-lsp-t78158-100.html Niezmiennie polecam zatem CADPL-Pack'a, do tychże zastosowań, z uwzględnieniem funkcji: cd:DWG_AddCustomProp cd:DWG_GetCustomProp cd:DWG_RemoveCustomProp cd:DWG_GetSummaryInfo cd:DWG_SetSummaryInfo oraz innych, do zapisu / odczytu plików tekstowych - tamże
  7. Teza oparta na jakichś przykładach? Pliki lsp w AutoCAD są plikami tekstowymi. Edytor Visual LISP może kompilować pliki lsp do dwóch formatów: fas (fast lsp), oraz do vlx, gdzie oprócz tekstowego lsp, można dołączyć definicje okien dialogowych dcl. Kompilacja jako taka, chroni (ukrywa) kod przed nieautoryzowanym wykorzystaniem, właściwie "przy okazji". Celem kompilacji jest przede wszystkim zoptymalizowanie działania kodu,i w efekcie przyspieszenie działania. Różnice w szybkości między interpretowanym tekstowym lsp a skompilowanym vlx, mogą w skrajnych przypadkach być nawet 10-12 krotne.
  8. Nie mogę na AutoCAD-zie sprawdzić ani jednego rozwiązania... z prostej przyczyny - AutoCAD działa poprawnie i w trybie edycji lokalnej bloku (REFEDIT), po prostu nie jest możliwy wybór innych obiektów niźli tych z zestawu roboczego. Czyli generalnie jest to przypadłość ZwCAD-a, może po prostu mogliby to poprawić? A wtedy żadna protetyka nie będzie potrzebna.
  9. Rozwiązania widzę co najmniej dwa, a właściwie trzy (jako mariaż pierwszego i drugiego): Wspomniana wcześniej funkcja CADPL-Pack,owa, do "ogolenia" ssget'a z elementów nie będących częścią definicji edytowanego bloku. To rozwiązuje sprawę na poziomie elementarnym. Utworzenie zbioru wskazań za pomocą bardziej złożonego wywołania funkcji ssget - np. z wykluczeniem nazw pewnych bloków, obiektów, obiektów na warstwie itp. Np. "kulturalnie" zdefiniowany blok ma obiekty na warstwie "0" (w definicji). Zachowując higieniczność w malowaniu (nic nigdy nie jest na warstwie "0"), podczas edycji bloku, dobieramy się do jego obiektów w definicji, czyli na warstwie "0", właśnie. Oczywiście to mógłby być jeden z warunków, może być ich więcej. Kombinacja tych powyższych: inteligentny ssget, potwierdzony (czy zweryfikowany) listą.
  10. Przyznam że nie rozumiem. Jeśli klikacz siedzi i klika (czyli wybiera) to skąd problem z ssget-em? Niech klika i wybierze w końcu. W AutoCAD jest zmienna REFEDITNAME która zwraca nazwę bloku (ZOdn) edytowanego, lub "". Jeżeli blok jest edytowany w edytorze bloków, to o jego stanie informuje zmienna BLOCKEDITOR (0 lub 1)
  11. W tym przypadku polecam (jak zwykle) CADPL-Pack (https://kojacek.wordpress.com/cadpl-pack/). Tutaj będzie to funkcja o nazwie cd:BLK_GetEntity. Tworzy ona listę obiektów tworzących blok. W wywołaniu repeat (ale dlaczego? - użyłbym foreach), wystarczy wtedy porównać czy obiekt ze zbioru wskazań znajduje się na liście (i wtedy wykonać jakąś operację), czy nie (i wtedy nic z nim nie robić). Na marginesie, dlaczego takie zabawy? - zmian w bloku można dokonać przecież lispem "po cichu", bez użytkownika, czyli bez edycji bloku, bez ssget'ów, itp. i innych problemów.
  12. Dodaj do pliku definicję funkcji DXF, której to właśnie brakuje: (defun DXF (code elist)(cdr (assoc code elist))) Na marginesie. Fajna jest zabawa kodami DXF obiektów, by na końcu użyć... command, A i dopiero teraz zauważyłem. Te reversy to po co są? Kto to pisał?
  13. Rozważmy teraz (na początek) zakończenie typu 1 - parallel to Global XY. Nieco teorii przybliży prosty malunek. Oto mamy wyciągnięty profil z bloku. Wstawienie w punkcie P1, wyciągnięcie w kierunku punktu P2 (niewidocznego na rysunku). Powinniśmy teraz utworzyć kolejne wyciągnięcie profilu, ale w odwrotnym kierunku (o długości odcinka a). Po utworzeniu takiej bryły należy ją przeciąć płaszczyzną równoległą do X0Y przechodzącą przez P1. "Dolną" część usunąć, "górną" zestalić z profilem typu 0. Musimy znać: - wysokość profilu , także jego szerokość - kąt alfa czyli kąt punktów P1 P2 tworzących ścieżkę w przestrzeni - pozostałe boki trójkąta [a] - długość wyciągnięcia zakończenia, oraz [c] czyli długość P1 A. Oczywiście, obliczeń dokona AutoLISP. My wstawimy tylko parę nawiasów... ;)
  14. To kombinowanie z kawałkowaniem i ze sztukowaniem też mi się nie podoba, przyznam. W kontekście tego malunku co wrzuciłeś (Type of ending...), przyjąć można że punkt bazowy naszych bloków powinien być nie w punkcie symetrycznym dolnej krawędzi zarysu, jak jest teraz, a w samym środeczku profilu. Tak jest właśnie na tym rysunku. I wtedy nasz już istniejący B3D, realizowałby zakończenie Type 0-Normal. Z dwóch stron, bo jak rozumiem, docelowym optymalnym rozwiązaniem, powinna być mozliwość aby określać dowolne (z trzech) zakończenie dla każego końca niezależnie, już na etapie wskazywania punktów, wyboru skali i profilu. Z automatu następowałoby wydłużenie w odpowiednich kierunkach linii z punktów definiujących, wyrysowanie bryły (większej z końcami 0-Normal), oraz albo ucięcie płaszczyzną, albo domalowanie jakiejś kosteczki i jej odjęcie.
  15. Osadzenie nawet na łuku dla wytrawnych lispaczy nie będzie problemem... ;) Problemem jest czas, a właściwie jego brak, na takie zabawy... ale spokojnie. Damy radę.
  16. Opcja z dwoma punktami jest najprostsza. Wydaje się że też najbardziej naturalna (mam jakieś przeczucie, że w wymyślny sposób gięte profile, w konstrukcjach występują z mniejszą intensywnością, niźli proste). Wyciąganie po wskazanej ścieżce jest też jak najbardziej możliwe. Problemem z jakim się pewnie zetkniemy, a które będzie trudno rozwiązać (albo rozwiązać w sposób stosunkowo rozbudowany) będą: 1) Bryła będzie jedna dla całej ścieżki. Zwykle oczekiwalibyśmy dopasowanych do siebie ale jednak kilka brył. 2) Zbyt małe kąty, czy promienie zaokrągleń, potrzebne do prawidłowego wyciągnięcia (zbyt dużego) profilu.Tego nie będzie można prawdopodobnie kontrolować przed wykonaniem operacji. 3) Ustawienie orientacji profili w początku ścieżki. O ile dla profilu będącym rurą okrągłą, nie ma to szczególnie znaczenia, dla innych może mieć (np. ścieżka oparta na polilinii 2d jest w istocie dwuwymiarowa. Pytanie - czy określamy każdorazowo w jaki sposób względem płaszczyzny na której leży ścieżka ustawiamy np. dwuteownik? Półka równolegle? prostopadle? Inaczej? Dla polilini 3d jest podobnie. Oczywiście coś tam potestujemy, zobaczymy jak to wygląda.
  17. E no, jak ja coś zrobię, to działa... ;) Nie kopiuj fragmentów, używaj Pack-a tak jak tu opisałem: https://kojacek.wordpress.com/cadpl-pack/ Jeśli patrzyłeś tu obok, na harce z wyciąganiem profili, zauważysz że z 30% (na oko) kodu jest pack-owego, niektóre zadania nawet w 100% (okna dialogowe i ich obsługa).
  18. Tak, metodą ActiveX - GetBoundingBox można otrzymać współrzędne przekątnej prostokąta opisującego obiekt. Tak samo dla wstawienia bloku (AcadBlockReference) jak też dla każdej entycji w definicji bloku.
  19. Próbowałeś: cd:ACX_LoadLineType z: http://forum.cad.pl/cadpl-pack-v1-lsp-t78161.html ?
  20. Wy tu sobie testujcie póki co, dajcie znać jak macie jakieś uwagi, a ja sobie powoli przemyślę innych parę pomysłów, bo coś bym tu jeszcze ewentualnie zmienił...
  21. Kolejne wcielenie do testowania. Zmiany są takie:. 1) Na samym początku można ustawić skalę wstawianego bloku (w konsekwencji profilu). Zakres od 0,001 do 100, ustawiane w oknie. 2) Słowo kluczowe Nazwa do wpisania z ręki nazwy bloku. 3) Poprawki różne Kod: ; =========================================================================================== ; (if (not cd:ACX_ADoc)(load "CADPL-Pack-v1.lsp" -1)) ; =========================================================================================== ; (defun C:B3D ()(b3d:ExtrIns)(princ)) ; =========================================================================================== ; ; ExtrudeProfile.lsp by kojacek 2015 / ; =========================================================================================== ; (defun b3d:ExtrIns (/ l n s e p o x) (if (not (setq l (b3d:BlockProfileList))) (princ "\nW rysunku nie zdefiniowano bloków dla profili. ") (progn (if (not *B3D-Settings*)(setq *B3D-Settings* (list (car l) 1.0))) (if (setq s (vl-catch-all-apply 'b3d:GetPointProfile (list nil))) (if (and (listp s) (setq e (vl-catch-all-apply 'b3d:GetPointProfile (list s))) ) (if (listp e) (if (and (setq n (vl-catch-all-apply 'b3d:GetBlockProfileName (list l))) (= (type n) 'STR) ) (progn (setq x (cadr *B3D-Settings*)) (cd:SYS_UndoBegin) (setq o (cd:BLK_InsertBlock s n (list x x x) 0 T)) (b3d:SetInsertZOrient (b3d:NewVect s e) (setq o (vlax-vla-object->ename o)) ) (setq p (cd:ENT_MakeLine (getvar "CTAB") s e T)) (b3d:ExtrudeProfile (vlax-ename->vla-object o) p) (cd:SYS_UndoEnd) ) ) ) ) ) ) ) ) ; =========================================================================================== ; (defun b3d:GetBlockProfileName (LProf / f k s) (setq f (car *B3D-Settings*) s (car (mapcar '(lambda (%)(cd:STR_ReParse LProf %))(list " "))) ) (initget (strcat "Lista Wybierz Nazwa")) (setq k (vl-catch-all-apply 'getkword (list (strcat "\nProfil [Lista/Wybierz/Nazwa] lub podaj nazwę <" f ">: ")) ) ) (if (not k) f (if (= (type k) 'STR) (cond ( (= k "Lista")(b3d:ProfileDlg LProf)) ( (= k "Wybierz")(b3d:SelectBlock LProf)) ( (= k "Nazwa")(b3d:SelectName LProf)) (t k) ) ) ) ) ; =========================================================================================== ; (defun b3d:SetGlobal (Mode Val) (if (zerop Mode) (setq *B3D-Settings* (list Val (cadr *B3D-Settings*))) (setq *B3D-Settings* (list (car *B3D-Settings*) Val)) ) ) ; =========================================================================================== ; (defun b3d:SelectName (Lst / r) (if (and (setq r (getstring "\nNazwa: ")) (member (strcase r)(mapcar 'strcase Lst)) ) (progn (b3d:SetGlobal 0 r) r) (b3d:GetBlockProfileName Lst) ) ) ; =========================================================================================== ; (defun b3d:ProfileDlg (BlkL / r p) (setq r (cd:DCL_StdListDialog BlkL (vl-position (car *B3D-Settings*) BlkL) "Profile" "Wybierz:" 25 12 2 12 (list "&Ok" "&Anuluj") nil T T nil) ) (if r (progn (setq p (nth r BlkL))(b3d:SetGlobal 0 p))) p ) ; =========================================================================================== ; (defun b3d:SelectBlock (Lst / e d s) (if (and (setq e (entsel "\nWybierz blok: ")) (setq d (entget (car e))) (= "INSERT" (cdr (assoc 0 d))) (member (strcase (setq s (cdr (assoc 2 d)))) (mapcar 'strcase Lst) ) ) (progn (b3d:SetGlobal 0 s) s) (b3d:GetBlockProfileName Lst) ) ) ; =========================================================================================== ; (defun b3d:ExtrudeProfile (Blk Lin / p c r d) (vla-explode Blk) (setq p (entlast)) (vla-delete Blk) (if (cond ( (= "LWPOLYLINE" (cdr (assoc 0 (entget p)))) (setq c (vlax-make-safearray vlax-vbObject '(0 . 0))) (vlax-safearray-put-element c 0 (vlax-ename->vla-object p)) (setq r (vla-AddRegion (cd:ACX_ASpace) c)) ) ( (= "REGION" (cdr (assoc 0 (entget p)))) (setq r (vlax-ename->vla-object p)) ) (t nil) ) (progn (vla-AddExtrudedSolidAlongPath (cd:ACX_ASpace) (if (= (type r)'VLA-OBJECT) r (setq d (vlax-safearray-get-element (vlax-variant-value r) 0)) ) (vlax-ename->vla-object Lin) ) (if d (vla-delete d)) (foreach % (list Lin p)(entdel %)) ) ) ) ; =========================================================================================== ; (defun b3d:NewVect (p1 p2 / d q s m v) (setq d (mapcar '- p2 p1) q (mapcar '* d d) s (apply '+ q) m (sqrt s) v (mapcar '/ d (list m m m)) ) ) ; =========================================================================================== ; (defun b3d:SetInsertZOrient (ExtrVec Ename / e b) (setq e (entget Ename) b (trans (cdr (assoc 10 e)) Ename ExtrVec) e (subst (cons 10 b)(assoc 10 e) e) e (subst (cons 50 0.0)(assoc 50 e) e) e (subst (cons 210 ExtrVec)(assoc 210 e) e) ) (entmod e) ) ; =========================================================================================== ; (defun b3d:BlockProfile-p (Name / l d) (if (= 1 (length (setq l (cd:BLK_GetEntity Name nil)))) (progn (setq d (entget (car l))) (or (and (= (cdr (assoc 0 d)) "LWPOLYLINE") (= 1 (logand 1 (cdr (assoc 70 d)))) ) (= (cdr (assoc 0 d)) "REGION") ) ) ) ) ; =========================================================================================== ; (defun b3d:BlockProfileList (/ l) (if (setq l (cd:SYS_CollList "BLOCK" (+ 1 2 4 8))) (acad_strlsort (vl-remove-if-not '(lambda (%)(b3d:BlockProfile-p %)) l)) ) ) ; =========================================================================================== ; (defun b3d:GetPointProfile (Pt / m r) (setq r (if Pt (progn (initget 1) (getpoint Pt "\nKoniec ścieżki: ") ) (progn (setq m (strcat "\nProfil (" (car *B3D-Settings*) " skala=" (cd:CON_Real2Str (cadr *B3D-Settings*) 2 (getvar "LUPREC")) ") [Skala] lub wskaż pierwszy punkt ścieżki: " ) ) (initget 1 "Skala") (getpoint m) ) ) ) (if (= r "Skala")(b3d:SetProfileScale) r) ) ; =========================================================================================== ; (defun b3d:SetProfileScale ( / f l r) (setq f (cadr *B3D-Settings*) l (getvar "LUPREC") ) (if (setq r (cd:DCL_StdEditBoxDialog (list 3 (list (cons 1 "Wprowadź liczbę rzeczywistą") (cons 2 "Liczba nie może być zerem") (cons 8 "Spacje są niedozwolone") (cons 16 "To nie jest liczba") (cons 32 "Liczba jest za mała") (cons 64 "Liczba jest za duża") ) (cd:CON_Real2Str f 2 l) 0.001 100 2 l ) "Skala" "Wartość: " 25 12 (list "&OK" "&Anuluj") T nil ) ) (b3d:SetGlobal 1 (read r)) ) (b3d:GetPointProfile nil) ) ; =========================================================================================== ; (princ "\nZaładowano polecenie: B3D ") (princ) Testujcie!
  22. To już lepiej nie brać do listy takich bloków, ale... mam mieszane uczucia czy to dobry sposób. Nakładanie zbyt dużo ograniczeń, też nie jest dobrą drogą. Na razie myślę zrobię z tą Nazwą jako słowo kluczowe, i zobaczymy jak to działa.
  23. Nie o LUW, z LUW-em nie ma problemu - tu się wstawi zabezpieczenie że ma być w globalnym i jest po krzyku. Chodzi o nazwy bloków zawierające podkreślnik lub spację. Aby można było wybrać blok z "wolnej ręki", lista bloków przekazywana jest do initget. To zaś powoduje że nazwy są "rozrywane" (podkreślnik służy do lokalizowania nazw, spacej to separatory). Są dwa rozwiązania: 1) Rezygnacja z wpisywania ręcznego (jest wybierz, i wybór z listy, oraz enter jako ostatni) 2) Dodanie słowa kluczowego do wpisu czyli zgłoszenie typu: Profil [Lista/Wybierz/Nazwa]<IPE500>: czyli Lista - wiadomo, Wybierz - wiadomo, i trzeba dodatkowo Nazwa, aby podać nazwę bloku (tu już bez initgeta, tylko zakres listy), enter - wiadomo To jest dodatkowe wydłużenie operacji