kojacek

Użytkownik forum
  • Postów

    268
  • Dołączył

  • Ostatnia wizyta

  • Wygrane w rankingu

    43

Treść opublikowana przez kojacek

  1. 😉 takie coś można wydziobać albo wydrapać... blok dynamiczny sterowany dynamicznie z okna dialogowego:
  2. Przedstawiony kod dotyczy tak zwanej "lekkiej polilinii" czyli obiektu typu LWPOLYLINE, a makro oczywiście (i rzeczywiście) "omija" segmenty łukowe. Polilinia której segmenty są splajnami, jest automatycznie konwertowana na ("stary") obiekt i jest typu POLYLINE, więc na tych obiektach kod nie działa. Krótko (ale mam nadzieję) w jasny sposób parę słów o polilinich znajdziesz (reklama) tu: https://kojacek.wordpress.com/2015/09/18/polilinie-2d/ Jeśli chodzi o rozwój przedstawionego rozwiązania. Sugerowałbym aby blok grota, był blokiem dynamicznym (z kilkoma trybami widoczności), co uprościłoby wszelkie zabawy z tymże - zamiast przebierać w setkach (możliwych przecież) bloków w rysunku, brać jeden i wybierać potrzebny stan widoczności. Idea bloków dynamicznych właśnie (choć nie tylko) sprawdza się doskonale w takich sytuacjach. PS. w avatarze jest wrona, nie wilk... 😉
  3. Zadanie z tych banalnych raczej... Można rozwiązać tak: ; ---------------------------------------------------------------------------- ; (defun c:testuj ()(InsBlkInPolySeg (car (entsel)) "arrow1" 20.0 15.0)(princ)) ; ---------------------------------------------------------------------------- ; ; funkcja zwraca liste segmentow LWPOLY typu: ((p1 bulge1 p2)(p2 bulge2 p3)...); ; ---------------------------------------------------------------------------- ; (defun jk:LWP_GetSegments (e / p d r) (setq d (entget e) p (if (= 1 (logand (cdr (assoc 70 d)) 1)) (cdr (assoc 10 d)) ) d (mapcar 'cdr (vl-remove-if-not '(lambda (%)(member (car %) '(10 42))) d ) ) ) (if p (setq d (append d (list p))) ) (while (> (length d) 2) (setq r (cons (list (car d) (cadr d) (caddr d) ) r ) d (cddr d) ) ) (reverse r) ) ; ---------------------------------------------------------------------------- ; (defun InsBlkInPolySeg (Poly Block Scale MinLength / d b n a p) (if (not (tblobjname "BLOCK" Block)) (princ (strcat "\nBłąd: w rysunku nie ma bloku " (strcase Block) "." ) ) (if (not (setq d (jk:LWP_GetSegments Poly)) ) (princ "\nBłąd - niepoprawna polilinia.") (if (not (setq d (vl-remove-if-not '(lambda (%)(zerop (cadr %))) d) ) ) (princ "\nBłąd - polilinia składa sie z samych łuków.") (if (not (setq d (vl-remove-if '(lambda (%) (< (distance (car %)(caddr %)) MinLength) ) d ) ) ) (princ "\nBłąd - segmenty polilinii są za krótkie.") (progn (cd:SYS_UndoBegin) (foreach % d (setq a (angle (car %)(caddr %)) p (polar (car %) a (/ (distance (car %)(caddr %)) 2.0)) ) (cd:BLK_InsertBlock p Block (list Scale Scale Scale) a nil) ) (cd:SYS_UndoEnd) ) ) ) ) ) ) ; ---------------------------------------------------------------------------- ; Polecenie TESTUJ, wywołuje funkcję InsBlkInPolySeg, dla której jednak kluczem jest funkcja jk:LWP_GetSegments. Dla całości trzeba CADPL-Pack-a który opisywałem kiedyś tutaj: https://kojacek.wordpress.com/2015/11/04/cadpl-pack/ . W uproszczeniu - groty strzałek w postaci bloku (argument Block) wstawiane są na liniowych segmentach wskazanej polilinii (argument Block - tutaj trzeba wstawić jeszcze jakieś testowanie wyboru), których długość jest większa niż argument MinLength.
  4. LISP-em można sterować parametrami bloku dynamicznego podczas aktywności okna dialogowego. Pozwala to kontrolować wizualnie dokonane zmiany. Tutaj na szybko tylko jeden parametr:
  5. Ustalenie koloru (choć nie tylko) na JakWarstwa dla elementów bloków uważam (nie tylko ja zresztą) raczej za wadę a nie zaletę. Sposób tworzenia bloków (warstwa "0" / kolor / rodzaj linii / szerokość linii ByBlock itd.) to osobny duży temat. O kolorach (i nie tylko) ByLayer i ByBlock pisałem TUTAJ. Zaś z przemianami cech wszelkich elementów bloków, w sposób masowy (czy też jednostkowy) można zapoznać się TU.
  6. Mam dwie uwagi. 1) AutoCAD-we SETBYLAYER zmienia więcej właściwości niźli tylko kolor: 2) Jeżeli zaś chodzi o kolor tylko, mam wrażenie że to można załatwić używając amunicji mniejszego kalibru, Wystarczy wiedzieć że w danych DXF obiektu kod 62 odpowiada za jego kolor. I tak jeśli kod 62 ma wartość 256 (lub w danych nie ma tego kodu) to obiekt ma kolor logiczny jakwarstwa. Wynika z tego że wystarczy manipulować wartością kodu 62 danych DXF obiektu. Klasycznie entmodem, bez żdnych com... vla-... etc. Tak samo można w inteligentny sposób wybierać obiekty do zmiany (po co wybierać te które już są JakWarstwa?). Poniższy kod wystarczy aby wybrać obiekty z niezamknietych warstw i które nie mają koloru JakWarstwa i takimi je uczynić: (if (setq ss (ssget "_:L" '((-4 . "/=")(62 . 256))) ) (foreach % (cd:SSX_Convert ss 0) (cd:ENT_SetDXF % 62 256) ) ) Wykorzystuję tu dwie funcje biblioteczne CADPL-Pack-a, który krótko przedstawiam tutaj.
  7. kojacek

    Start

    Zapraszam do czytania mojego bloga na: https://kojacek.wordpress.com
  8. LISP-em, najprościej użyć funkcji startapp. Zobacz tutaj: https://kojacek.wordpress.com/2016/07/31/pliki-szybki-dostep/
  9. Może tak (czując się wywołanym linkiem): Uproszczony kod: ; -------------------------------------------------------------------------------------- ; ; 2021 by kojacek (defun C:LPOLY (/ GetObjectID getObj l b v i) (defun GetObjectID (obj doc) ;; Lee Mac (if (eq "64" (strcase (getenv "PROCESSOR_ARCHITECTURE"))) (vlax-invoke-method (vla-get-Utility doc) 'GetObjectIdString obj :vlax-false) (itoa (vla-get-Objectid obj)) ) ) (defun getObj (/ e) (if (setq e (car (entsel "\nWybierz obiekt do zmierzenia: "))) (if (member (cdr (assoc 0 (entget e))) (list "LINE" "ARC" "LWPOLYLINE") ) e ) ) ) (defun GetBlk (BlkList Att / e d a) (if (setq e (car (entsel "\nWybierz blok opisuący: "))) (if (and (setq d (entget e)) (setq a (mapcar '(lambda (%)(cdr (assoc 2 (entget %)))) (cd:BLK_GetAttEntity e) ) ) (= "INSERT" (cdr (assoc 0 d))) (member (cdr (assoc 2 d)) BlkList ) (member Att a) ) e ) ) ) (if (and (setq l (getObj)) (setq b (GetBlk (list "KABEL" "OBIEKT_OCHRONNY") "MEASURED_LENGTH" ) ) ) (progn (setq v (GetObjectID (vlax-ename->vla-object l) (cd:ACX_ADoc) ) i (strcat "%<\\AcObjProp Object(%<\\_ObjId " v ">%).Length \\f \"%lu2%pr2\">%" ) ) (cd:SYS_UndoBegin) (cd:BLK_SetAttValueVLA b "MEASURED_LENGTH" i ) (vla-Regen (cd:ACX_ADoc) acActiveViewport) (cd:SYS_UndoEnd) ) (princ "\nZły wybór") ) (princ) ) ; -------------------------------------------------------------------------------------------- ; Wymagane jest załadowanie CADPL-Pack'a: https://kojacek.wordpress.com/2015/11/04/cadpl-pack/ Nazwy bloków, tagi atrybutów i format Field-a, trezba sobie "podkręcić" po swojemu.
  10. Najprostszym rozwiązaniem byłoby wstawianie bloku (w formie owego prostokata) w modelu, który byłby na podstawie jego punktu wstawienia, obrotu (+ informacji o skali) reprezentowany (rzutnią) w osobnym Layoucie. To bylo juz klepane na cad.pl parę lat temu.
  11. Tak nieco inaczej podchodząc do tematu: https://kojacek.wordpress.com/2021/01/30/lisp-a-klawisze/
  12. Przyznam że nie rozumiem idei tegoż, jak też i zamysłu całości. Po co tak obrac bloki? Ale się nie znam pewnie.
  13. Po paru nawiasach? Nie zniechęcaj się... jeszcze za wcześnie... ;) Są gorsze języki programowania... :)
  14. Byłoby dziwne gdyby wpółpracował. Lista z tblsearch nie jest poprawną listą dla entmod. Użyj tu formy entget + tblobjname. Zobacz: (setq e (tblobjname "layer" "zbrojenie_linie" )) (setq d (entget e)) (entmod (subst (cons 62 -8)(assoc 62 d) d)) a to prowadzić może do bardziej ogólnej funkcji: (defun LayOnOff (Lay / e d) (if (setq e (tblobjname "LAYER" Lay)) (progn (setq d (entget e)) (setq d (subst (cons 62 (* -1 (cdr (assoc 62 d))) ) (assoc 62 d) d) ) (entmod d) ) ) ) Funkcja steruje widocznością warstwy podanej jako jej argument tak jak przełącznik, wywołaj kolejno: (LayOnOff "zbrojenie_linie")
  15. 1) Sugerowałbym próbę wpisywania tekstu ze spacjami.
  16. W AutoCAD jest zmienna o nazwie MIRRHATCH
  17. Link jest już poprawiony
  18. Ładowanie ustawień zmiennych z pliku na żądanie: https://kojacek.wordpress.com/2015/11/24/setvar-z-pliku/
  19. Witam, parę uwag: 1) Wskazanie punktu. To standardowa funkcja LISP-a, getpoint - trzeba wskazać punkt, może być podany jako odległość, ale w formie "przyrostowej" @dist<angle. Pomyślę (w przyszłości) o dodaniu opcji (słowa kluczowego) do odległości. Wtedy dodatnia wartość przesunie linie "na zewnątrz" (od punktów zaczepienia) a ujemna "do wewnątrz". Obecnie (proszę zwrócić uwagę) wskazanie punktu nie wymaga trybu ortogonalnego, punkt można wskazać w dowolnym miejscu, a linie zostaną ustawione w miejsciu przechodzenia przez ten punkt. 2) Poprawię obsługę błędów, 3) Program z założenia "przesuwając" linie wymiarowe, w rzeczywistości modyfikuje wymiary w taki sposób że punkty zaczepienia pozostają w niezmienionym miejscu, czyli tak jakby (wymiary) były rozciągane. Uważam to za zaletę, a nie wadę. Idea przesuwania wymiarów, kłóci się w mojej opinii, z zasadami poprawnego wymiarowania, które powinno być (w miarę możliwości) maksymalnie zespolone z wymiarowanymi obiektami. Przesuwanie wymiaru niszczy to połączenie. Na marginesie: na Pańskim obrazku te "wymiary BIK" mogły by mieć zdefiniowane krótkie linie pomocnicze i (nadal) posiadać zespolenie, czyli gripy w pierwotnych punktach, bez względu na położenie linii wymiarowch. Podsumowując - do przesuwania wymiarów proszę je po prostu przesuwać, bez korzystania z DIM-MO. Raczej tego nie zamierzam zmieniać.
  20. Tutaj: https://kojacek.wordpress.com/2020/04/16/dim-mo/ już jest.
  21. https://kojacek.wordpress.com/2017/09/22/edycja-multilinii/
  22. Jakieś osiem (!) lat temu na innym forum podobne zagadnienie było omawiane: http://forum.cad.pl/prostowanie-polilinii-t77940.html Kody też tam chyba były. Bezpłatnie. No i jawne... 😉