Đến nội dung


Hình ảnh
- - - - -

[Yêu cầu] Sửa lisp chọn Block trong bản vẽ!


  • Please log in to reply
6 replies to this topic

#1 aliosa

aliosa

    biết vẽ polygon

  • Members
  • PipPip
  • 73 Bài viết
Điểm đánh giá: 4 (bình thường)

Đã gửi 13 August 2012 - 01:21 PM

Chào các bạn trên diễn đàn. Mình đanh tập viết lisp. Mong các bạn giúp đỡ.

Mình viết một đọn code để chọn các block trong bản vẽ có tên là tên của Block mình đã chọn trước.
Do chưa nắm rõ lên chương trình chưa chạy được. Mong các bạn chỉnh sửa lại giúp.



(defun c:Dem ( / ss )
; Lay ten block can dem
(setq pt (cadr (entsel "\nChon Block can dem")))
(setq e1 (ssget pt))
(setq e2 (entget (ssname e1 0)))
(setq tenblock (cdr (assoc 2 e2)))

; Chon tat ca cac block co ten cua block da chon o tren va dem
(setq ss (ssget '((cons 2 tenblock) (0 . "INSERT"))))
(if ss
(princ (strcat "\n So block da chon la: " (rtos (sslength ss))))
)
(princ)
)


Vạn sự khởi đầu nan. Mong các bạn chỉ giùm. Thank !!!
  • 0

#2 duy782006

duy782006

    PHẠM QUỐC DUY

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 2155 Bài viết
Điểm đánh giá: 1359 (rất tốt)

Đã gửi 13 August 2012 - 03:01 PM


(Defun c:dem ( )
(prompt "\nChon BLOCK mau.")
(setq DT (car (entsel)))
(setq DT (entget DT))
(setq STNAME (cdr (assoc 2 DT)))
(Princ "\nHay chon vung :")
(setq SS (ssget (list (cons 0 "insert")
(cons 2 STNAME)
)
)
)
(if (Null ss)
(princ "\nKhong tim thay doi tuong nao")
)
(IF (/= NIL SS) (PROGN
(setq Sl (SSLength SS))
(princ (strcat "\nTim thay: <" (itoa sl) "> doi tuong la BLOCK co ten: <" STNAME ">"))
)
)
(princ)
)

Của mình thì như này bạn đọc coi bạn sai chổ nào, dạo này mình hơi lười.
  • 1

Cứ ngỡ trần gian là cõi thật.Cho nên tất bật đến bây giờ.
Tạo hộp thoại bằng lisp My blog QUY ĐỊNH ĐẶT TÊN TOPIC TRONG CHUYÊN MỤC LISPD http://ktsduy.wordpress.com/
Để cám ơn chỉ cần nhấn rep_up.png
(Là nhấn vào nút đó phía bài viết của người ta í chứ đừng có nhè cái hình này mà nhấn miết đi nha :-D


#3 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6009 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 13 August 2012 - 03:38 PM

Chào các bạn trên diễn đàn. Mình đanh tập viết lisp. Mong các bạn giúp đỡ.

Mình viết một đọn code để chọn các block trong bản vẽ có tên là tên của Block mình đã chọn trước.
Do chưa nắm rõ lên chương trình chưa chạy được. Mong các bạn chỉnh sửa lại giúp.



(defun c:Dem ( / ss )
; Lay ten block can dem
(setq pt (cadr (entsel "\nChon Block can dem")))
(setq e1 (ssget pt))
(setq e2 (entget (ssname e1 0)))
(setq tenblock (cdr (assoc 2 e2)))

; Chon tat ca cac block co ten cua block da chon o tren va dem
(setq ss (ssget '((cons 2 tenblock) (0 . "INSERT"))))
(if ss
(princ (strcat "\n So block da chon la: " (rtos (sslength ss))))
)
(princ)
)


Vạn sự khởi đầu nan. Mong các bạn chỉ giùm. Thank !!!


Hề hề hề,
Có một vài góp ý với bạn như sau:
1/- Để lấy được tên của block mẫu, bạn sử dụng hàm (ssget pt). Như vậy sẽ có khả năng tại điểm chọn này bạn sẽ có thể không có đối tượng nào hoặc có nhiều đối tượng cùng đi qua điểm chọn này. Vì thế rất dễ dàng xảy ra là biến tenblock của bạn bị trả về là nil.
Bạn lưu ý rằng hàm (entsel) cho phép pick chọn đối tượng với độ chính xác không cao lắm. Nhưng khi dùng (ssget ...) thì việc pick chọn lại rất cần chuẩn xác.
Vì thế bạn nên sử dụng code đơn giản hơn để lấy tenblock. Chẳng hạn chỉ cần:
(setq tenblock (cdr (assoc 2 (entget (car (entsel "\n Chọn block mau"))))))
2/- Việc sử dụng list bộ lọc cho hàm (ssget) của bạn chưa chuẩn khi chọn tập chọn các block.
Bạn đã dùng: (setq ss (ssget '((cons 2 tenblock) (0 . "INSERT"))))
Như vậy (cons 2 tenblock) sẽ trả về một list còn (0. "INSERT") chưa phải là list.
Do vậy cái bộ lọc '((cons 2 tenblock) (0 . "INSERT")) bị sai và bạn phải sửa thành '((cons 2 tenblock) (cons 0 "INSERT")) hoặc '((cons 2 tenblock) '(0 . "INSERT")) hoặc (list (cons 2 tenblock) (cons 0 "INSERT")).....

Bạn hãy thử sửa lại xem còn lỗi nữa không nhé.
  • 1
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#4 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

  • Moderator
  • PipPipPipPipPipPipPip
  • 4296 Bài viết
Điểm đánh giá: 3805 (đỉnh cao)

Đã gửi 13 August 2012 - 03:54 PM


Hề hề hề,
Có một vài góp ý với bạn như sau:
1/- Để lấy được tên của block mẫu, bạn sử dụng hàm (ssget pt). Như vậy sẽ có khả năng tại điểm chọn này bạn sẽ có thể không có đối tượng nào hoặc có nhiều đối tượng cùng đi qua điểm chọn này. Vì thế rất dễ dàng xảy ra là biến tenblock của bạn bị trả về là nil.
Bạn lưu ý rằng hàm (entsel) cho phép pick chọn đối tượng với độ chính xác không cao lắm. Nhưng khi dùng (ssget ...) thì việc pick chọn lại rất cần chuẩn xác.
Vì thế bạn nên sử dụng code đơn giản hơn để lấy tenblock. Chẳng hạn chỉ cần:
(setq tenblock (cdr (assoc 2 (entget (car (entsel "\n Chọn block mau"))))))
2/- Việc sử dụng list bộ lọc cho hàm (ssget) của bạn chưa chuẩn khi chọn tập chọn các block.
Bạn đã dùng: (setq ss (ssget '((cons 2 tenblock) (0 . "INSERT"))))
Như vậy (cons 2 tenblock) sẽ trả về một list còn (0. "INSERT") chưa phải là list.
Do vậy cái bộ lọc '((cons 2 tenblock) (0 . "INSERT")) bị sai và bạn phải sửa thành '((cons 2 tenblock) (cons 0 "INSERT")) hoặc '((cons 2 tenblock) '(0 . "INSERT")) hoặc (list (cons 2 tenblock) (cons 0 "INSERT")).....

Bạn hãy thử sửa lại xem còn lỗi nữa không nhé.

Bác Bình sửa thành 2 dòng màu xanh vầy là không đúng rồi
  • 2

#5 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6009 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 13 August 2012 - 04:00 PM

Bác Bình sửa thành 2 dòng màu xanh vầy là không đúng rồi

Hề hề hề,
Mình hiểu lỗ mỗ vậy, nhờ bác giải thíc thêm về cách dùng thằng quote này với.
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#6 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

  • Moderator
  • PipPipPipPipPipPipPip
  • 4296 Bài viết
Điểm đánh giá: 3805 (đỉnh cao)

Đã gửi 13 August 2012 - 04:33 PM

Hề hề hề,
Mình hiểu lỗ mỗ vậy, nhờ bác giải thíc thêm về cách dùng thằng quote này với.

Hàm ' : Không định giá trị của các phần tử trước khi tạo list
List : định giá trị các phần tử trước khi tạo list
(setq tenblock "a")
(quote (cons 2 tenblock)) -> trả về: (CONS 2 TENBLOCK)
-> Bác sẽ thu được 1 list gồm 3 phần tử : 2 phần tử có kiểu SYM là CONS, TENBLOCK và một phần tử 2 có kiểu INT

Cái của mình cần là :
(ssget (list (cons 2 tenblock) (cons 0 "INSERT")) )
Hoặc :
(ssget (list (cons 2 tenblock) '(0 . "INSERT")) )

Vì tenblock là biến thì không thể viết là :
(ssget '((cons 2 tenblock) )) được bác ạ
  • 2

#7 aliosa

aliosa

    biết vẽ polygon

  • Members
  • PipPip
  • 73 Bài viết
Điểm đánh giá: 4 (bình thường)

Đã gửi 13 August 2012 - 06:37 PM

Chân thành cảm ơn các bạn ! Lisp đã chạy tốt.
Đúng là sai một ly đi một dặm quả không sai.
Các bạn giải thích mình lại hiểu thêm một chút:

1. Mình phải đi lòng vòng mới lấy được tên của đối tượng, mà kết quả đôi khi lại không chính xác.
(setq pt (cadr (entsel "\nChon Block can dem")))
(setq e1 (ssget pt))
(setq e2 (entget (ssname e1 0)))

2. Đi như bạn PhamThanhBinh thì nhanh hơn và chính xác hơn.


(setq tenblock (cdr (assoc 2 (entget (car (entsel "\n CChon Block can thong ke:"))))))

Cái này mình sẽ tìm hiểu dần dần. Âu cũng là Lisp toàn đi cóp nhặt mới như vậy.

Chúc các bạn thành công và hạnh phúc.
  • 0