Chuyển đến nội dung
Diễn đàn CADViet
Đăng nhập để thực hiện theo  
LoveLisp

[Hỏi] Làm thế nào để truy xuất thông tin bên trong Block?

Các bài được khuyến nghị

Dùng đệ quy bác HA chú ý khử đệ quy ^^

Test với 2 block, trong mỗi block chứa 1 block khác :

1). Ket gửi giùm file đó để ktra xem sao, tôi đã test trước khi post mà sao vẫn còn lỗi.

2). Tất nhiên đệ quy có nhược điểm của đệ quy, còn khử đệ quy có phải là (defun C:HA( / HA)...?

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Thêm một cách nữa để chọn các block có chứa layer nào đó (có thể mở rộng để chọn theo color,linetype...).

(defun C:HA( / lay dsent)	;Doan Van Ha CADViet.com
(setq lay (getstring "\nNhap ten lop nam trong block: ") ss (ssadd))
(foreach ent (acet-ss-to-list (ssget '((0 . "INSERT"))))
 (foreach ent1 (acet-ss-to-list (acet-explode ent))
  (if (equal lay (cdr (assoc 8 (entget ent1))))
(setq dsent (if (not (member ent dsent)) (cons ent dsent) dsent))))
 (command "u"))
(setq ss (if dsent (acet-list-to-ss dsent) nil))		; ss la tap hop chon cua cac block co chua layer lay (2 dong duoi chi de test).
(princ (strcat "\nSo block co chua doi tuong thuoc layer " lay " la: " (if ss (itoa (sslength ss)) "0")))
(princ))

Hề hề hề,

Bác sử dụng explode rồi sau đó lại undo xem ra hơi vất vả.

Theo thiển ý của mình (đúng hơn là theo cái mình mót đượic của .....thiên hạ) thì có thể duyệt qua các đối tựơng trong block bằng cách sử dụng hàm entnext với vòng lặp while bác ạ. Tỷ như:

(setq ent (cdr (assoc -2 (tblsearch "block" blname))))

(while (/= ent nil)

(do smthing)

(setq ent (entnext ent))

)

và như vậy để duyệt qua tất cả các block có trên bản vẽ bác chỉ cần tạo một list các tên block có trên bản vẽ theo kiểu bác ketxu hay của bác (có dùng sort) rồi foreach là ngon lành.

Vì mình không có nhiều thời gian nên chưa viết cụ thể được, mong bác thông cảm, chỉ là vài suy nghĩ định hướng nếu có trật thì mong bác chớ chê cười, còn nếu đúng bác thử triển khai nhé.

Chúc bác vui.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Hề hề hề,

hổng phải đâu là hổng phải đâu.

bác ketxu đã trả lời bạn ấy rùi bác ạ

Hề hề hề...

Ketxu trả lời đúng theo nguyên lý của hàm getstring, nhưng cách nhập "a b" cũng không sai, có dỡ chăng là phải thêm 2 dấu " mà thôi. Bác kiểm tra lại xem sao hè.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Hề hề hề,

Bác sử dụng explode rồi sau đó lại undo xem ra hơi vất vả.

Theo thiển ý của mình (đúng hơn là theo cái mình mót đượic của .....thiên hạ) thì có thể duyệt qua các đối tựơng trong block bằng cách sử dụng hàm entnext với vòng lặp while bác ạ. Tỷ như:

(setq ent (cdr (assoc -2 (tblsearch "block" blname))))

(while (/= ent nil)

(do smthing)

(setq ent (entnext ent))

)

và như vậy để duyệt qua tất cả các block có trên bản vẽ bác chỉ cần tạo một list các tên block có trên bản vẽ theo kiểu bác ketxu hay của bác (có dùng sort) rồi foreach là ngon lành.

Vì mình không có nhiều thời gian nên chưa viết cụ thể được, mong bác thông cảm, chỉ là vài suy nghĩ định hướng nếu có trật thì mong bác chớ chê cười, còn nếu đúng bác thử triển khai nhé.

Chúc bác vui.

Bác PTB ạ, thấy chán thằng (command "u") nên tôi đã edit lại ở sau bài đó, bác xem lại giùm đi (đúng ý tưởng entnext của bác). Tuy nhiên nếu block lồng block thì đang có lỗi nên tôi đang cố gắng sửa mà chưa được, chứ block không lồng block thì vô tư rồi.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Cuối cùng cũng giải quyết được lỗi, để chọn được các block lồng nhau mà trong block có chứa 1 layer nào đó. Hy vọng ok.

;----- Doan Van Ha CADViet.com
(defun C:HA (/  dsent ename)
(vl-load-com)
(setq ss (ssadd) lay (getstring T "\nNhap ten Layer nam trong Block: "))
(setq dsent (acet-ss-to-list (ssget '((0 . "INSERT")))))
(foreach ent dsent
 (HA (cdr (assoc 2 (entget ent))))))
(defun HA (ename / ename1)
(setq ename1 (tblobjname "block" ename))
(while (setq ename1 (entnext ename1))
 (cond
  ((= (cdr (assoc 0 (entget ename1))) "INSERT")
(HA (cdr (assoc 2 (entget ename1)))))
  ((and (/= "INSERT" (cdr (assoc 0 (entget ename1)))) (/= "SEQEND" (cdr (assoc 0 (entget ename1)))) (= lay (cdr (assoc 8 (entget ename1)))))
(setq ss (ssadd ent ss))))))		;Ten cua tap hop chon la ss [co the dung (command "erase" ss "") de test].

  • Vote tăng 2

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tốt rồi bác ạ. Thêm check Sequend thì mới có đường thoát chứ ^^ Hay là bác nhích lên 1 tí, ssadd cả thằng Block bên trong không chứa đối tượng nào thuộc layer đã định, nhưng nó lại nằm trên layer đó đi ^^

(and (= Insert)(= lay)) => OK

Ngoài ra e nghĩ điều kiện vòng lặp while nên thêm 1 flag T/nil. Nếu tìm thấy 1 đối tượng bất kỳ trong Block thuộc layer chỉ định thì đổi flag và thoát khỏi vòng lặp luôn, giúp giảm số lần kiểm tra ^^

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tốt rồi bác ạ. Thêm check Sequend thì mới có đường thoát chứ ^^ Hay là bác nhích lên 1 tí, ssadd cả thằng Block bên trong không chứa đối tượng nào thuộc layer đã định, nhưng nó lại nằm trên layer đó đi ^^

(and (= Insert)(= lay)) => OK

Ngoài ra e nghĩ điều kiện vòng lặp while nên thêm 1 flag T/nil. Nếu tìm thấy 1 đối tượng bất kỳ trong Block thuộc layer chỉ định thì đổi flag và thoát khỏi vòng lặp luôn, giúp giảm số lần kiểm tra ^^

Lisp dưới đây đã hiệu chỉnh để có thể:

- Chọn các Blocks mà trong Block có chứa 1 Layer nào đó đã chỉ định.

- Các Blocks có thể lồng nhau nhiều tầng.

- Có thêm tuỳ chọn để có thể chọn cả Block con nằm trên Layer đó.

@Ketxu: Hỏi nhỏ tí, viết cho CV "giàu" thế mà không đủ sống sao còn kiếm cơm bằng nghề... phụ?

;----- Doan Van Ha CADViet.com
(defun C:HA (/  dsent ename layblk)
(setq ss (ssadd) lay (getstring T "\nNhap ten Layer nam trong Block: "))
(setq dsent (acet-ss-to-list (ssget '((0 . "INSERT")))))
(foreach ent dsent
 (HA (cdr (assoc 2 (entget ent))))))
(defun HA (ename / ename1 flag)
(setq ename1 (tblobjname "block" ename))
(while (and (not flag) (setq ename1 (entnext ename1)))
 (cond
  ((and (= "INSERT" (cdr (assoc 0 (entget ename1)))) (/= lay (cdr (assoc 8 (entget ename1)))))
(HA (cdr (assoc 2 (entget ename1)))))
  ((and (= "INSERT" (cdr (assoc 0 (entget ename1)))) (= lay (cdr (assoc 8 (entget ename1)))))
(cond
((not layblk)
 	(initget "Y N")
 	(setq layblk (getkword (strcat "\nBan co muon chon luon ca block con chua layer " lay " hay khong? [N/<Y>]: ")))
 	(if (not layblk) (setq layblk "Y"))))
(if (= layblk "N")
(HA (cdr (assoc 2 (entget ename1))))
(setq ss (ssadd ent ss) flag T)))
  ((and (/= "INSERT" (cdr (assoc 0 (entget ename1)))) (/= "SEQEND" (cdr (assoc 0 (entget ename1)))) (= lay (cdr (assoc 8 (entget ename1)))))
(setq ss (ssadd ent ss) flag T)))))		;Ten cua tap hop chon la ss, co the dung (command "erase" ss "") de test.

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Trả lời nhỏ bác : Viết cho CV 100% Free mà bác^^. Học hỏi là chính, còn viết lấy phí thì e cũng nghĩ tới, và chắc là cũng phải áp dụng, mặc dù biết thừa là cái thu về chẳng bằng cái râu của cái đã bỏ ra, nhưng phải có hình thức để sàng lọc những người thực sự cần với những người yêu cầu chơi chơi chứ ^^

SV mới ra trường kiếm miếng cơm cũng khó, mọi người đánh vó hết rồi. Giờ e còn phải trau dồi thêm KT, điện, nước...để kiếm tí thôi.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Các lisp của bạn ketxu và bạn Ha đã tốt dần đến mức hoàn thiện, không cần góp ý gì thêm nữa. Qua các trao đổi trên đây, mình đã có rất nhiều kinh nghiệm trong lập trình. Chân thành cám ơn các bạn!!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tạo một tài khoản hoặc đăng nhập để nhận xét

Bạn cần phải là một thành viên để lại một bình luận

Tạo tài khoản

Đăng ký một tài khoản mới trong cộng đồng của chúng tôi. Điều đó dễ mà.

Đăng ký tài khoản mới

Đăng nhập

Bạn có sẵn sàng để tạo một tài khoản ? Đăng nhập tại đây.

Đăng nhập ngay
Đăng nhập để thực hiện theo  

×