Chuyển đến nội dung
Diễn đàn CADViet

Thaistreetz

Nhà quảng cáo
  • Số lượng nội dung

    905
  • Đã tham gia

  • Lần ghé thăm cuối

  • Ngày trúng

    30

Bài đăng được đăng bởi Thaistreetz


  1. Sửa code của Ketxu 2 tí cho giống cách dùng của lệnh offset

    - lựa offset sang 1 bên hoặc 2 bên

    - đổi tên lệnh về số 0 bàn phím số, ví dụ: muốn offset 1 đơn vị bản vẽ gõ 01; offset 0.5 đvbv gõ 0.5; offset 1.5 đvbv gõ 01.5...

    (if (null ostd) (setq ostd (vlr-command-reactor nil '((:vlr-unknownCommand . offsettudong)))))
    ;;*********************************************************************
    (defun offsettudong (calling-reactor endcommandInfo / Layer_Key ss ang1 ang2 dist en pt0 pt1 vobj)
    (setq Layer_Key (strcase (car endcommandInfo)))
    (if (wcmatch Layer_Key "0*")
    (if (setq dist (atof (vl-string-left-trim "0" Layer_Key)))
    (while (setq en (car (entsel "Chon doi tuong offset\n")))
    (setq vobj (vlax-ename->vla-object En))
    (if (setq pt1 (getpoint "Chon phia offset,[enter] de offset sang 2 ben\n"))
    (progn
    (setq ang1 (angle (Vlax-curve-getfirstderiv en (vlax-curve-getParamAtPoint en (setq Pt0 (vlax-curve-getClosestPointTo en pt1)))) '(0 0)) ang2 (angle pt0 pt1))
    (setq dist (if(or(equal(/(- ang1 ang2)(/ pi 2))1 0.001)(equal(/(- ang1 ang2)(/ pi 2))-3 0.001)) (- dist) dist))
    (if (vlax-method-applicable-p vobj 'Offset) (vla-offset vObj dist)))
    (and (vlax-method-applicable-p vobj 'Offset) (vla-offset vObj dist) (vla-offset vObj (- dist))))
    (setq dist (abs dist)))))
    (princ))

     

    Các bác có cánh nào để sau khi sử dụng lệnh này xong, muốn tiếp tục sử dụng lại thì chỉ việc gõ enter hoặc space như các lệnh thông thường khác không. nhược điểm của thằng này là phải gõ lại lệnh, không tự động nhận lệnh cũ


  2. @Bác Tue_NV: Nghe bác lăn tăn nhiều về vấn đề có nên viết hay không viết lại các hàm acet (Vì chắc chắn là không thể viết lại được toàn bộ) nên em sẽ nói luôn về trường hợp của em để thấy rằng Mod Ketxu khởi động dự án này là cần thiết và nhiều người cần nó:

    Vì muốn đạt được sự linh hoạt tối đa khi sử dụng, chỉ cần load và chạy trên bất kỳ máy nào nên toàn bộ lisp của em được đóng gói vào 1 project fas duy nhất (trong đó có tất cả các thứ fục vụ cho quá trình chay: thư viện hàm, block, dimstyle, texsty, layer,linetype...). lẽ dĩ nhiên việc đó đòi hỏi tất cả các thư viện em sử dụng fải được đóng gói luôn vào trong file fas đó. Rồi 1 lần sang máy lạ không cài express mới fát hiện ra gần như toàn bộ các lệnh của em đểu không chạy được do em hay sử dụng acet. Vấn đề là có 1 số lệnh tương đối đơn giản cũng không chạy được dù không sử dụng các hàm đặc biệt, khi đó em nhận ra là mình đã quá lệ thuộc vào acet, nếu em tự viết các hàm có cùng chức năng acet thì chương trình của em đã không bị lệ thuộc quá nhiều như vậy.

    thực tế thì các hàm đặc biệt chỉ đôi khi chúng ta mới dùng, và nếu không có express thì em cũng chỉ mất 1 vài lệnh ít dùng là không thể chạy được. Em vẫn dùng acet và em vẫn ủng hộ topic này vì điều đó.

    • Vote tăng 1

  3. Đối tượng có dữ liệu mở rộng mình muốn truy cập thì nhất thiết phải biết Application Name khi người tạo ra đã đăng ký phải không nhỉ? Nghĩa là nếu mình không biết cái tên này (tức với Nova không biết “TDNW”) thì mình bó tay không vào nhà lấy trộm đồ được hả các bác?

    Tra tất cả dữ liệu mở rộng của đối tượng (nếu có), nếu muốn tra dữ liệu mở rộng của nova thôi thì thay "*" bằng "TDNW"

    (defun c:xd (/ en)

    (and (setq en (car (entsel "Chon doi tuong can tra")))

    (setq en (assoc -3 (entget en '("*"))))

    (princ (cdr en))) (princ))

    • Vote tăng 1

  4. Theo như những gì bạn nêu ở trên thì mình đoán là bạn chưa nắm chắc hiểu biết về xdata của đối tượng -> chưa nắm được cách thức nova tổ chức và xây dựng cơ sở dữ liệu cho đối tượng -> chương trình này bạn viết chỉ thao tác với các đối tượng thông qua các thông tin nhìn thấy như : loại đói tượng, layer, góc quay, textstyle... Nếu vậy thì quả thực chương trình bạn viết rất công phu đấy.

     

    - Về ý kiến thứ nhất của bạn. Nếu là Nova thì bạn có thể yên tâm và chắc chắn rằng người dùng chỉ có thể vẽ ra được đối tượng thông thường bằng layer của nova, nhưng ko thể vẽ được ra đối tượng chứa thông tin của nova. Cụ thể với đối tượng là đầu trắc ngang. bạn thử vẽ 1 line bằng layer "ENTTNTUNHIEN" bên cạnh đối tượng của nova. sau đó dùng code dưới để chọn sẽ thấy chỉ có đối tượng của nova mới chọn được:

    (ssget (list (list -3(list"TDNW"))'(0 . "LINE")'(8 . "ENTTNTUNHIEN")))

     

    - Mã -3 là mã lưu dữ liệu mở rộng của đối tượng (gọi là xdata, diễn đàn đã có nhiều topic bàn về vấn đề này rồi). bạn hoàn toàn có thể tạo ra đối tượng có chứa xdata, hoặc có thể chỉnh sửa, thậm chí là xóa hẳn toàn bộ xdata của đối tượng. rất nhiều đối tượng của cad cũng chứa loại dữ liệu này.

     

    - thông tin thêm có thể hữu ích với bạn: các đối tượng nova có cách thức tổ chức dữ liệu mở rộng dạng: ("TDNW" (1070 . -XXXX) (1070 . Y)....))

    trong đó:

    "TDNW" là chuỗi nhận dạng dữ liệu mở rộng của nova (trong 1 đối tượng có thể chứa nhiều loại dữ liệu mở rộng)

    -XXXX là số quy định đối tượng thuộc bình đồ (-2000), trắc dọc(-3000) hay trắc ngang(-4000);

    Y: số thứ tự của tuyến; tiếp theo là các mã quy định về loại đối tượng (cọc, số thứ tự cọc, lý trình, tên cọc, đường dóng, đường line bảng, text tự nhiên, text thiết kế...) và các thông tin khác. Mình chẳng có bí mật nào hết, nó nằm toàn bộ trong đó, bạn chỉ việc lôi cổ nó ra là dùng được liền

    • Vote tăng 1

  5. - Yêu cầu nhập vào chiều cao bảng trắc ngang là thừa. bạn hoàn toàn có thể để chương trình làm việc này tự động

    - Lựa chọn tỷ lệ in cũng thừa vì cũng có thể làm việc này tự động. trong cơ sở dữ liệu của trắc ngang đã có rồi.

    tặng bạn cái này (áp dụng với trắc ngang của nova):

    (defun tyle-tn (EN-gTN / X NV) ;EN-gTN la doi tuong pline goc trac ngang
    (if (setq NV (assoc -3 (entget EN-gTN '("TDNW"))))
    (list (setq X (cdr(nth 5(cadr NV))))
    (/ X (cdr(nth 6(cadr NV))))))).

    nhìn qua cách thức làm việc thì mình góp ý được thế thôi. Về quan điểm cá nhân thì mình thấy cách thức giải quyết in ấn trắc ngang bằng viewport như chương trình của bạn tạo ra những khó khăn không chỉ với người lập trình mà cả với người dùng. bản thân bạn cũng đã nhận ra được điều này. vậy sao không làm nó luôn bên model nhỉ? Tất nhiên trừ khi bên bạn yêu cầu quản lý tất cả bản vẽ bằng layout thì chương trình của bạn là rất ổn rồi.

    • Vote tăng 1

  6. 1) sao tôi undo thì nó đâu in ra màn hình như bác nói nhỉ? Chắc bác cũng đã set cmdecho 0, command undo begin, command undo end rồi chứ nhỉ? Hay còn lý do gì nữa chăng?

    Bác thử cái này

    (defun c:vl (/ p1 p2)

    (setvar "cmdecho" 0)

    (command "undo" "begin")

    (setq p1 (getpoint (setq p2(getpoint)))) (repeat 200 (command "line" p1 p2 ""))

    (command "undo" "end")(princ))

    Chạy lệnh VL xong thì bác undo 1 phát. mình lặp 200 lần nên nếu bác rảnh rỗi để đếm thì sẽ thấy đủ 200 lần thông báo "(Lisp Expression)"

    PS: riêng (command "undo"...) thì không bị trả về thông báo này.


  7. Hề hề hề,

    1/- Theo mình không nên bỏ vì có nó tốc độ không chậm đi bao nhiêu cả mà trong một số trường hợp khi không có nó cái lst1 dễ bị kéo theo các thằng ngoại lai khác do các hàm phía trước để lại. Việc này mình đã từng dính đòn khi viết và test các lisp.

    Không bác Bình ạ. vì ta đã xét biến lst1 là biến cục bộ rồi nên trong quá trình chạy, hàm sẽ xét giá trị tạm thời cho biến lst1 thôi. xong đâu đấy nó sẽ trả lại giá trị cũ cho lst1.

    bác có thể dán cái này vào command để kiểm chứng:

    (setq lst1 "Pham Thanh Binh") (defun c:test (/ lst1) (setq lst1 "Thaistreetz")).

    Sau khi chạy lệnh test bác kiểm tra lại giá trị của lst1 xem

    Về vấn đề tốc độ giữa các hàm vl,vla,vlax so với command thì cũng còn tùy, nhưng fần lớn là command chậm hơn. em ghét command ở thao tác undo, chậm khủng khiếp.Có lần em dùng command để viết 1 lệnh rải taluy. lệnh đó vẽ ra khoảng hơn 5.000 đối tượng. Undo phát là bản vẽ treo luôn gần 10p. sử dụng phương pháp khác thì undo gần như là tức thời. ngoài ra thì nếu ta sử dụng command bao nhiêu lần, khi undo lại nó sẽ print ra màn hình bấy nhiêu dòng thông báo gì gì đó em quên roài. rất là khó chịu.

    • Vote tăng 2

  8. đúng là ngớ ngẩn khi cẩn thận (setq lst1 nil). ketxu thử kiểm tra xem hàm này và hàm của bạn thằng nào chạy nhanh hơn thì lấy. Mình hơi ác cảm với 3 thằng vl-remove vì nó gây chậm chương trình của mình tương đối nhiều nên hạn chế dùng nó để viết hàm con.

    Tiện đây bạn cho mình hỏi lợi ích của vl-position so với member là gì? nó hơn về tính tổng quát hay về tốc độ?


  9. ACET-LIST-REMOVE-DUPLICATES. nguyên bản thì cú pháp của nó được viết như sau: (ACET-LIST-REMOVE-DUPLICATES list flag)

    trong đó thì tham số flag của nó là nil hoặc 0 hoặc 1 (nil và 0 là giống nhau)

    - flag = 0 hoặc nil: hàmchâp nhận mọi định dạng của các phần tử trong list kiêm tra : real, integer, list, string, variable...

    - flag = 1: nó chỉ chấp nhận list kiểm tra chứa các phần tử là real và integer. tuy nhiên khi kiểm tra với real nó trả về kết quả lung tung beng. không thể chấp nhận được.

    vì thế mình bỏ cái tham số flag vô nghĩa kia đi.

     

    (defun CV:list-remove-duplicates (lst / lst1)

    (foreach x lst (if (not (member x lst1)) (setq lst1 (append lst1 (list x))))) lst1)

     

    ps: à quên, hàm này loại bỏ sự trùng (bằng hoặc giống) nhau của các phần tử trong list

    • Vote tăng 1

  10. Cảm ơn bác, nhưng hàm của bác nó chỉ trả về list danh sách các textstyle và font tương ứng. không rõ font nào là unicode.

    Mình vừa làm được rồi, tuy hơi củ chuối tý vìchỉ nhận biết các font hay dùng: arial. tahoma và times new roman. cũng tạm chấp nhận được.

    (wcmatch (cdr (assoc 3 (entget (tblobjname "style" (cdr (assoc 7 (entget (car (entsel "chon text"))))))))) "ARIAL*,TAHOMA*,TIMES*")

    Bác nào có cao kiến gì hay hơn thì cứ post nhé. mình hơi khó tính, hề hề


  11. Các bác cho mình hỏi. có cách nào để biết 1 textstyle đang sử dụng font của bảng mã Unicode không?

    hoặc đơn giản hơn, kiểm tra 1 chuỗi xem chuỗi đó có được viết bằng mã unicode hay không. (mình làm bằng cách củ chuối (wcmatch string "*\U+*") nhưng cũng không được. chưa biết vì sao nó cứ trả về nil.


  12. Mình bổ sung thêm hai tí nhau nữa là thông báo ra màn hình cho người dùng nhòm thấy và chuyển layer bị khóa này về hiện hành để người dùng biết mà xử trảm nó. Còn nếu không bị khóa thì nó hàm sẽ trả về nil y như thằng acet. các bác cứ xem nếu thấy chưa ưng tí nhau nào thì trảm tí nhau đó đi là Ok hỉ.

    Cái dở của bác chính là chỗ này bác ạ. bởi nếu đưa hàm này vào 1 chương trình, khi gặp layer bị khóa quá trình chạy sẽ bị gián đoạn. người dùng bắt buộc phải nhấn ok để chương trình chạy tiếp. Nhỡ mà nó chạy trong vòng lặp gặp vài layer bị khóa như vậy là mệt rồi. VD: bác sử dụng hàm này để viết 1 lệnh đếm số layer bị khóa của bản vẽ. chương trình đếm được bao nhiêu layer bị khóa là bấy nhiêu lần ta phải nhấn OK.

    Theo quan điểm của em, bất kì hàm kiểm tra điều kiện nào, chỉ cần trả về T hoặc nil. còn ứng xử sau đó thế nào tùy thuộc vào mục đích ta dùng nó bác ạ.

     

    @DVH: Bác diễn đạt sai rồi. trong cái hàm của bác thì P1 và P2 liên quan gì đến thằng Curve mà bác nhắc đến.

    Mình hiểu ý bác là viết 1 hàm lấy tọa độ 1 điểm nằm trên đường thẳng nối 2 điểm sao cho khoảng cách từ điểm đó đến 2 điểm kia có tỷ lệ a/b

    • Vote tăng 1

  13. Cái vụ cãi nhau này cuối cùng cũng dứt được rồi ah. :rolleyes:

    Mình góp đây:

    acet-pixel-unit : lấy ra tỷ lệ số đơn vị bản vẽ chứa trong 1 pixel màn hình (rất hữu dụng với bác nào hay dùng vector)

    (defun CV:pixel-unit nil (/ (getvar "viewsize")(cadr (getvar"screensize"))))

    acet-sys-sleep: tạm dừng mọi tính toán trong thời gian ms (đôi khi chúng ta muốn làm chậm chương trình của mình lại 1 chút)

    (defun CV:sys-sleep  (ms / x) (setq x (+ (getvar "cdate")(* ms 1E-8)))(while (> x (getvar "cdate"))))

    Còn vài cái nữa, cứ từ từ kiếm thank, hê hê

    @ketxu: Sếp nên test rồi cập nhật các hàm đã được viết lên post #1 cho anh em dễ theo dõi. lưu ý cho anh em cách đặt tên nữa đi, lung tung cả rồi kìa

    • Vote tăng 1

  14. @ketxu: nếu lấy gốc tọa độ theo topleft của editor thì mình làm được roài. cái mình cần lấy là tọa độ theo hệ tọa độ của màn hình.

    Bởi vì mỗi người thiết lập giao diện cad khác nhau nên việc lấy theo tọa độ màn hình mục đích cũng chính là để tránh sự ảnh hưởng của các thanh menu, toolbar... như bạn nêu hay việc của sổ cad đang ở chế độ maximize hay minimize.


  15. Nhân tiện cho mình hỏi. các bác có cách nào lấy được tọa độ của con trỏ theo hệ tọa độ của màn hình không? gốc tọa độ là 1 trong các góc của màn hình. (thường là topLeft) đơn vị là pixel.

    vấn đề này trước đây mình từng hỏi, nhưng chưa có giải đáp, giờ lại vấp fải nó nên bức xúc quá hỏi lại.

×