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

[Yêu cầu] Nhờ viết lisp tạo nhanh wipeout

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

Lệnh Wipeout gốc chỉ dùng được với pline colsed và không chứa arc. Đây là 1 khiếm khuyết của autodesk chăng? Cái pline của bạn dù kín nhưng vẫn open chứ không closed. Có thể h/c lisp để chuyển từ pline kín mà open sang closed thì dùng được, nhưng hơi vất vả tí.

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

Lệnh Wipeout gốc chỉ dùng được với pline colsed và không chứa arc. Đây là 1 khiếm khuyết của autodesk chăng? Cái pline của bạn dù kín nhưng vẫn open chứ không closed. Có thể h/c lisp để chuyển từ pline kín mà open sang closed thì dùng được, nhưng hơi vất vả tí.

 

Vậy một lần như vậy lại phải chỉnh từ open sang closed à, mất thời gian nhỉ.

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

Vậy một lần như vậy lại phải chỉnh từ open sang closed à, mất thời gian nhỉ.

Để tôi xem có thể sửa lisp được không, chứ sửa thủ công từ Pline open sang closed thì hơi bị khổ. Hãy chờ nhé!

  • 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ôi xem có thể sửa lisp được không, chứ sửa thủ công từ Pline open sang closed thì hơi bị khổ. Hãy chờ nhé!

 

Đợi tin 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

Đã hiệu chỉnh cho bạn, link cũ, lệnh HA1.

 

Quick code

;Doan Van Ha - CADViet.com - Ngay 04/4/2012
;Muc dich: Convert cac Lwpolyline duoc chon thanh cac Wipeout.
(defun C:HA1( / cmd entlst xoa)
(command "undo" "be")
(setq cmd (getvar "cmdecho"))
(setvar "cmdecho" 0)
(setq entlst (vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget '((0 . "LWPOLYLINE")))))))
(initget "X K") (setq xoa (getkword "\n[Xoa/Khong xoa] pline cu <X>: "))
(if (= xoa "K") (setq xoa "N") (setq xoa "Y"))
(foreach ent entlst
 (command "wipeout" "p" (Open->Closed ent) xoa))
(setvar "cmdecho" cmd)
(command "undo" "end")
(princ))
(defun Open->Closed(ent / lst)
(foreach n (acet-geom-vertex-list ent)
 (if (not (member n lst)) (setq lst (cons n lst))))
(setq lst (reverse (cons (last lst) lst)))
(entdel ent)
(entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 (length lst)) (cons 70 1)) (mapcar (function (lambda (p) (cons 10 p))) lst))))

P/S (4h22' ngày 05/4/2012): Hiệu chỉnh để wipeout được với cả Lwpolyline kín nhưng open.

Cái này chỉnh luôn cả LWPolyline không kín về close luôn nếu viết như trên

Theo Tue_NV nên kiểm tra POLYline có kín không và kiểm tra luôn điểm cuối và điểm đầu có trùng không?

Nếu điểm đầu và điểm cuối trùng nhau thì nếu Polyline là "Open" thì "Close" Polyline

- Ý nữa là ta có thể xây dựng hàm Open->Closed bằng hàm subst+entmod mã dxf 70 để code gọn hơn

  • 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

Cái này chỉnh luôn cả LWPolyline không kín về close luôn nếu viết như trên

Theo Tue_NV nên kiểm tra POLYline có kín không và kiểm tra luôn điểm cuối và điểm đầu có trùng không?

Nếu điểm đầu và điểm cuối trùng nhau thì nếu Polyline là "Open" thì "Close" Polyline

- Ý nữa là ta có thể xây dựng hàm Open->Closed bằng hàm subst+entmod mã dxf 70 để code gọn hơn

Thanks! Đã sửa ở link cũ.

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

Lệnh Wipeout gốc chỉ dùng được với pline colsed và không chứa arc. Đây là 1 khiếm khuyết của autodesk chăng? Cái pline của bạn dù kín nhưng vẫn open chứ không closed. Có thể h/c lisp để chuyển từ pline kín mà open sang closed thì dùng được, nhưng hơi vất vả tí.

Hiểu biết của bạn bị khiếm khuyết chứ không phải autodesk khiếm khuyết.

Đối tương wipeout bản chất là 1 raster. Nó tương tự như image. người ta không thể tạo được 1 bức ảnh có biên cong hoặc biên không đóng. Wipeout cũng vậy.

  • 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

Hiểu biết của bạn bị khiếm khuyết chứ không phải autodesk khiếm khuyết.

Đối tương wipeout bản chất là 1 raster. Nó tương tự như image. người ta không thể tạo được 1 bức ảnh có biên cong hoặc biên không đóng. Wipeout cũng vậy.

Biên cong thì không nói, nhưng biên thẳng và kín (mà open chứ không closed) thì nên wipeout được chứ nhỉ?

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ới là thứ để bàn,

làm sao lấy dc boundary của Block và Hatch?

còn polyline thì cứ việc chọn xong: (command "wipeout" .........)

Hề hề hề,

Mấy hôm lu bu chưa làm được. Nay làm thử cái củ lisp theo cái luận lý mà mình đã nói bữa trước để các bác tham khảo và góp ý.

Gửi các bác cái củ chuối này để tạo wipeout từ các Lwpolyline kín nằm trong các block. Các bác thử xem nó có quá chát không nhé. Hy vọng rằng nó không đến nỗi là đồ bỏ.


(defun c:wobl (/ bl en plst enw)
(vl-load-com)
(setq oldos (getvar "osmode"))
(setvar "osmode" 0)
(command "undo" "be")
(setq bl (car (entsel "\n Chon block can tao wipeout"))
         en (entlast)
         plst (list)
)
(xbl bl)
(foreach lst plst
	(setq lst (cdr lst))
	(command "pline")
	(foreach p lst
        	(command p)
	)
	(command "c")
	(setq enw (entlast))
	(command "wipeout" "p" enw "y")
)
(command "undo" "e")
(setvar "osmode" oldos)
(princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun xbl ( bl / en elst blp)
(setq  en (entlast)
      	en1 en)
(command "undo" "be" )
(command "explode" bl "" )
(while  (setq en (entnext en))
     (setq  elst (entget en))
     (if (and (= (cdr (assoc 0 elst)) "LWPOLYLINE") (= (cdr (assoc 70 elst)) 1))
      	(setq plst (append plst (list (acet-geom-vertex-list en))))
     )      
     (if (= (cdr (assoc 0 elst)) "INSERT")
         (progn
          	(setq blp (cdr (assoc  -1 elst)))
          	(xbl blp)
         )
  	)
)
(command "undo" "e" )
(command "undo" 1)
plst
)

Chúc các bác vui vẻ.

Chỉnh sửa theo phamthanhbinh
Bổ sung lisp theo góp ý của bác Ketxu và bác ĐoanvanHa
  • Vote tăng 3

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

K ĐƯỢC RỒI BÁC BÌNH..BÁC XEM FILE NHÉ

http://www.cadviet.c...418_bomchim.dwg

Lệnh Wipeout chỉ dùng được cho "Lwpolyline closed và không chứa Arc".

Block của bạn cấu tạo bởi các line, arc... mà không có "Lwpolyline closed và không chứa Arc" nên không thể wipeout bằng lisp này được.

  • 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

Em cảm ơn bác Doan Van Ha nhiều nhé. Mà lúc nãy quên mất, không nhờ viết luôn cả cái thao tác ngược lại phức tạp hơn biến từ wipeout thành poly line với. Bác xem có giúp đc e luôn ko với?

 

Chọn Wipe Out -> Explode

PEdit -> Chọn đoạn bất kì trên cái mớ vừa bẻ -> [ENTER] -> J -> P -> [Enter] -> Done

Có cần phải LISP ko nhỉ

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
VẬY LÀ BÓ TAY HẢ BÁC. CÓ CÁCH NÀO K?

Hề hề hề,

Gửi bạn đoạn code dùng để chuyển LWpolyline có chứ phần đoạn cong về LWpolyline gồm toàn phân đoạn thẳng và từ đó bạn có thể áp dụng vào cái lisp của mình.


(defun c:getppl (/ en par pob pa ppl)
(setq oldos (getvar "osmode"))
(setvar "osmode" 0)
(setq en (car (entsel "\n chon lwpolyline can chuyen ")))
(setq ppl (list)
         par 0
         pob (vlax-ename->vla-object en) )
(while (< par (vlax-curve-getendparam pob))
      	(setq pa (vlax-curve-getpointatparam pob par)
                	ppl (append ppl (list pa))
                	par (+ par 0.1) )
)
(setq ppl (append ppl (list (vlax-curve-getendpoint pob))))
ppl
(command "pline")
(foreach p ppl
   (command p)
)
(command "")
(command "erase" en "")
(setvar "osmode" oldos)
(princ)
)

Hy vọng bạn hài lòng.

Chỉnh sửa theo phamthanhbinh
Chỉnh sửa lại lisp theo góp ý của bác Ketxu và ĐoanVanHa

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

Bác Bình ơi! Các đoạn arc nó biến thành đoạn thẳng nối 2 đầu mút của arc thì không ngon lắm nhỉ. Vi phân arc làm nhiều đoạn thì chính xác cao hơn bác nhỉ.

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

Bác Bình ơi! Các đoạn arc nó biến thành đoạn thẳng nối 2 đầu mút của arc thì không ngon lắm nhỉ. Vi phân arc làm nhiều đoạn thì chính xác cao hơn bác nhỉ.

Hề hề hề,

Bác DoanVanHa à, bác chưa đọc kỹ lisp của mình hay sao ấy. Mình tuy chưa chia nhỏ cung lắm nhưng cũng đã chia nó thành 10 phần rồi mà bác. (cái biến par mỗi lần lặp chỉ tăng lên 0.1 thôi mà). Do vậy nếu muốn chính xác hơn có thể giảm nhỏ cái gia số này. Nhưng mình nghĩ chia như vậy cũng tạm ổn rồi do các cung này thường không quá lớn.(Góc chắn cung có nhẽ là nhỏ hơn 180 độ) nên khi đó mỗi phần chia sẽ nhỏ hơn 18 độ và có thể chấp nhận dây cung trùng với cung được mà.

Nếu mà chia nhỏ quá (tỷ như gia số của biến par là 0.001 ) thì e lisp chạy hơi lâu bác ạ.

Đây chỉ là một bước gợi ý về giải pháp thôi, còn lại thì người dùng có thể tự hiệu chỉnh lisp theo yêu cầu độ chính xác của mình sẽ tốt hơn, đúng không bác. Mình cũng chưa biết cái độ chính xác cần thiết phải bao nhiêu mà.

Hề hề hề, mong bác xem lạ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

Đây bác ơi!

1). File Cad:

http://www.cadviet.c...oi_bac_binh.dwg

2). Hình vẽ:

 

Hề hề hề,

Mình chưa hiểu vì sao lại bị vậy bác ạ. Cũng cái bản vẽ bác gửi, mình test lại thì nó ra cái ni:5194_thanhminh.jpg

 

Vậy phải chăng có biến hệ thống nào đó của bác khác với của mình???

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

Sao có command mà k có "osmode" hay "non" đâu bác nhỉ ^^

Hề hề hề,

Đúng là cái biến này mình hay bị quên do Cad của mình đặt biến Osmode thường trực là 0.

Việc dùng thằng "non" của bác mình có đọc được trong một topic nào đó nhưng thấy nó hơi lôi thôi do nó chỉ có tác dụng phát một và thực sự là mình cũng chưa quen dùng nó nên hơi ..... sợ bác ạ.

Tỷ như khi dùng trong vòng lặp (foreach p ppl ....... ) thì phải dùng là (command "non" p) hử bác???

Mình đã sửa lại lisp ở bài post trước (cho nó đỡ tốn đất ý mà), bác thử check lại xem còn sai sót gì không nhé.

À tiện đây mình hỏi luôn là vì sao khi mình dùng (while (<= par (vlax-curve-getendparam pob)) thì với par (+ par 0.1) nó lại bị sót thằng end point của đối tượng bác nhỉ??? Tức là khi biến par có giá trị bằng với (vlax-curve-getenparam pob) thì hàm điều kiện lặp trên đây trả về nil.

Mình cũng đã thử sửa là (while (<= par (+ (vlax-curve-getendparam pob) 0.001)) thì cái điểm end point lại trả về là nil. Tức là thằng (vlax-curve-getpointatparam pob par) này trả về nil khi biến par bằng với giá trị của (vlax-curve-getendparam pob) bác ạ.

Vì thế mình chơi kiểu chuối là bỏ béng thằng này đi và chỉ lặp (while (< par (vlax-curve-getendparam pob)) rồi nhét nó vào cuối của ppl bằng:

(setq ppl (append ppl (list (vlax-curve-getendpoint pob))))

Bác có thể giải thích cho mình lý do rõ hơn được không???

Cám ơn bác nhiều,

Hề hề 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

1). Việc dùng thằng "non"...

2). À tiện đây mình hỏi luôn là vì sao khi mình dùng (while (<= par (vlax-curve-getendparam pob)) thì với par (+ par 0.1) nó lại bị sót thằng end point của đối tượng bác nhỉ??? Tức là khi biến par có giá trị bằng với (vlax-curve-getenparam pob) thì hàm điều kiện lặp trên đây trả về nil.

Mình cũng đã thử sửa là (while (<= par (+ (vlax-curve-getendparam pob) 0.001)) thì cái điểm end point lại trả về là nil. Tức là thằng (vlax-curve-getpointatparam pob par) này trả về nil khi biến par bằng với giá trị của (vlax-curve-getendparam pob) bác ạ.

Vì thế mình chơi kiểu chuối là bỏ béng thằng này đi và chỉ lặp (while (< par (vlax-curve-getendparam pob)) rồi nhét nó vào cuối của ppl bằng:

(setq ppl (append ppl (list (vlax-curve-getendpoint pob))))

Bác có thể giải thích cho mình lý do rõ hơn được không???

Cám ơn bác nhiều,

Hề hề hế,

1). Khi dùng command, ở đâu có point thì trước nó phải có "non". VD: (command "move" (entlast) "" "non" p1 "non" p2)

Trong lisp của bác chỉ cần (command "non" p) là đủ. Tuy nhiên trường hợp này không nên dùng "non" vì nó lặp nhiều lần, làm chậm lisp, trong khi osnap bên ngoài thì chỉ xử 1 lần.

2). Việc chia curve này là 1 phép tính gần đúng nên điểm cuối cùng của phép chia có khi không trùng điểm cuối cùng của curve bác ạ. Tôi đã gặp sự cố này 1 lần rồi, và bác Gia bách đã phân tích như thế tôi thấy cũng hợp lý (trong mục "các lỗi thường gặp trong lập trình" í). Vì vậy, biện pháp củ chuối của bác là rất khoa học chứ không chuối chút nào cả, và tôi cũng đã dùng củ chuối này rồi đó).

  • 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ạ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

×