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

[Yêu cầu] - Chọn nhanh các đối tượng dạng đường (line, curve..) nối tiếp nhau

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

Ketxu vừa vào máy là đọc ngay lisp của bác Hạ. Thấy giải pháp clear ssname nguy hiểm quá ^^

Cái mới thì ngon hơn hẳn, so với FastSelect của Express có phần nhanh hơn nữa.

Tiện thể vì chủ topic làm việc với 3D nên ketxu chia sẻ 1 chút chỗ này, nhỡ may có bác nào chưa để ý

Line (0 0 1) (1 1 1)

 

Line (0 0 0) (1 1 0)

(ssget "c" (0 0 0)) = 2

:)

Trường hợp này do bác H đã kiểm tra lại điều kiện (biết tiếp vòng lặp ở đầu nào) nên k vấn đề gì .... ^^

 

Mà tại sao Lee lại hủy trường hợp gặp Pline kín hem bít nữa ^^

  • 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

Ketxu vừa vào máy là đọc ngay lisp của bác Hạ. Thấy giải pháp clear ssname nguy hiểm quá ^^

Cái mới thì ngon hơn hẳn, so với FastSelect của Express có phần nhanh hơn nữa.

Tiện thể vì chủ topic làm việc với 3D nên ketxu chia sẻ 1 chút chỗ này, nhỡ may có bác nào chưa để ý

Trường hợp này do bác H đã kiểm tra lại điều kiện (biết tiếp vòng lặp ở đầu nào) nên k vấn đề gì .... ^^

Mà tại sao Lee lại hủy trường hợp gặp Pline kín hem bít nữa ^^

1). Chắc tại nếu chọn cả PL closed thì phải sửa code, mà LM thì đang muốn dùng chung 1 kiểu code cho tất cả các kiểu. :lol: . Mặt khác, về mặt ý nghĩa thì PL closed đâu có khái niệm nối tiếp.

2). Sửa lisp này hơi tốn noron, nhưng khoái nhất nằm ở 1 hàm đơn giản (setq ss1 nil), bởi 2 lẽ:

- Gán cục bộ cũng không ổn.

- Đặt sai chỗ cũng không ổn.

  • 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

Đã test cho 1.000 line nối nhau, tốc độ gần như tức thời, nhanh khủng khiếp!

Khi test cho 10.000 line vẫn chạy tốt, thời gian là 31 giây.

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

Tiếp tục sửa. Bỏ hàm ssclear luôn.

(defun C:HA( / sf ss0 ent0 lst)
;Doan Van Ha - CADViet.com - Ngay 25/12/2012. Modify 26/12/2012
;Chuc nang: Chon doi tuong noi tiep nhau (LINE,ARC,LWPOLYLINE,SPLINE,POLYLINE,ELLIPSE).
...

Thanks HA.

Lisp này chạy nhanh hơn của "chính chủ".

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 là lisp mình viết lại. Nó không nhanh hơn lisp của bạn DVH nhưng chắc chắn nhanh hơn của "chính chủ". :)

;;; ThuyLinh313 - TriTueViet.jsc
(defun c:sf (/ A101 A102 A103 A104 A111 A112 E EN FUZ I LST LST-POINT P P1 P2 S1 SS)
(setq fuz 0.001)
; (1) get root_object
(if (setq en (ssget "_:E:S" (list '(-4 . "<OR")
                              	'(0 . "LINE,ARC")
                              	'(-4 . "<AND") '(0 . "LWPOLYLINE,SPLINE") '(-4 . "<NOT") '(-4 . "&=") '(70 . 1) '(-4 . "NOT>") '(-4 . "AND>")
                              	'(-4 . "<AND") '(0 . "POLYLINE") '(-4 . "<NOT") '(-4 . "&") '(70 . 89) '(-4 . "NOT>") '(-4 . "AND>")
                              	'(-4 . "<AND") '(0 . "ELLIPSE") '(-4 . "<OR") '(-4 . "<>") '(41 . 0.0) '(-4 . "<>") (cons 42 (+ pi pi)) '(-4 . "OR>") '(-4 . "AND>")
                              	'(-4 . "OR>")
                              	(if (= 1 (getvar "cvport")) (cons 410 (getvar "ctab")) '(410 . "Model")))))
 (progn
  (setq en (ssname en 0))
  (if (setq ss (ssget "X" (list '(-4 . "<OR")
                            	'(0 . "ARC")
                            	'(-4 . "<AND") '(0 . "ELLIPSE") '(-4 . "<OR") '(-4 . "<>") '(41 . 0.0) '(-4 . "<>") (cons 42 (+ pi pi)) '(-4 . "OR>") '(-4 . "AND>")
                            	'(-4 . "OR>")
                            	(if (= 1 (getvar "cvport")) (cons 410 (getvar "ctab")) '(410 . "Model")))))
(progn
	(ssdel en ss)    
	(repeat (setq i (sslength ss))
 	(setq e  (ssname ss (setq i (1- i)))
      	lst (cons (list (setq p1 (vlax-curve-getstartpoint e)) (setq p2 (vlax-curve-getendpoint e)) e) lst)
      	lst (cons (list p2 p1 e) lst))))) ;_(1)

  (setq lst-point (list (vlax-curve-getstartpoint en) (vlax-curve-getendpoint en))
    	ss (ssadd en))
  (while (setq p (car lst-point))
(setq lst-point (cdr lst-point))
; (2) add arc, elip
(if lst
	(setq lst (vl-remove-if '(lambda (a) (and (equal (car a) p fuz)
                                          	(ssadd (caddr a) ss)
                                          	(setq lst-point (cons (cadr a) lst-point)))) lst))) ;_(2)
; (3) add *Line
(setq A101 (cons 10 (setq p1 (polar p 0.7854 fuz)))
     	A102 (cons 10 (setq p2 (polar p 0.7854 (* -1 fuz))))
     	A103 (cons 10 (polar p -0.7854 fuz))
     	A104 (cons 10 (polar p -0.7854 (* -1 fuz)))
     	A111 (cons 11 p1)
     	A112 (cons 11 p2))
(if
(setq s1 (ssget "X" (list '(-4 . "<OR")
                         	'(-4 . "<AND") '(0 . "LINE") '(-4 . "<,<,*") A101 '(-4 . ">,>,*") A102 '(-4 . "AND>")
                         	'(-4 . "<AND") '(0 . "LINE") '(-4 . "<,<,*") A111 '(-4 . ">,>,*") A112 '(-4 . "AND>")
                         	'(-4 . "<AND") '(0 . "LWPOLYLINE,SPLINE") '(-4 . "<,<,*") A101 '(-4 . ">,>,*") A102 '(-4 . "<,>,*") A103 '(-4 . ">,<,*") A104
                         	'(-4 . "<NOT") '(-4 . "&=") '(70 . 1) '(-4 . "NOT>")'(-4 . "AND>")
                         	'(-4 . "OR>"))))
(progn
	(ssdel en s1)
	(repeat (setq i (sslength s1))
 	(setq e (ssname s1 (setq i (1- i))))
 	(if (not (ssmemb e ss))
  	(progn
   	(ssadd e ss)
   	(if (not (equal (setq p1 (vlax-curve-getstartpoint e)) p fuz))
    	(setq lst-point (cons p1 lst-point))
    	(setq lst-point (cons (vlax-curve-getendpoint e) lst-point)))))))))
  (sssetfirst nil ss)))
(princ))

  • 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

Lisp chạy ổn, tốc độ tương đối tốt. Có 1 góp ý nhỏ thôi:

Lisp của bạn có fuzz, và bạn đặt ngay đầu lisp. Vì vậy, bạn cần tránh trường hợp user sửa fuzz thì lisp chạy sai. Đó là: sửa cái 0.7854 thành (/ pi 4), đề phòng user dùng fuzz quá 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

Lisp của ThuyLinh vẫn giống bản gốc ở chỗ nó chọn toàn bộ bản vẽ để dò tìm. Đây là điểm hạn chế khi làm việc với bản vẽ có rất nhiều đối tượng.

Điểm hạn chế này đã được bác HA khắc phục và lisp của bác HA vẫn làm việc tốt trên bản vẽ có rất nhiều đối tượng.

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

Lisp của ThuyLinh vẫn giống bản gốc ở chỗ nó chọn toàn bộ bản vẽ để dò tìm. Đây là điểm hạn chế khi làm việc với bản vẽ có rất nhiều đối tượng.

Điểm hạn chế này đã được bác HA khắc phục và lisp của bác HA vẫn làm việc tốt trên bản vẽ có rất nhiều đối tượng.

1). Chọn "X" nhưng có lọc nên sẽ duyệt ít phần tử hơn (điều kiện 2), cũng tốt.

2). Nếu xui xẻo gặp bản vẽ toàn arc và ellipse hở (điều kiện 1) thì hơi bị... đen :lol: .

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

@DVH: Con số đó (0.7854 = 0.25pi) không quá quan trọng trong trường hợp này bạn ạ. (khoảng cách từ tâm hình vuông đến các đỉnh của nó tất nhiên luôn lớn hơn khoảng cách đến các cạnh. Bởi vậy nếu nó có chính xác bằng 0.25pi thì cũng không phản ánh được chính xác tuyệt đối hệ số fuzz mà người dùng nhập vào, sẽ có những đối tượng thỏa mãn fuzz nhưng không được chọn)

@LoveLisp: Chỗ này cũng khiến mình hơi thất vọng 1 chút, bởi ban đầu mình cứ nghĩ dữ liệu DXF của Arc và elisp có chứa tọa độ các điểm cuối (nên có phần mạnh miệng). Xét về hiệu quả sử dụng thì nên sử dụng lisp của bạn DVH, lisp này của mình chỉ có mục đích chứng minh Lee sử thuật toán chưa tối ưu 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

DVH xem xét lại code trên của bạn, nên thêm 1 hàm kiểm tra số lượng đối tượng của (ssget "c" p p sf). Nếu số lượng đối tương quá lớn thì thông báo yêu cầu kiểm tra lại các đối tượng nằm trên biên màn hình sau khi zoom extend.

Mình vừa dính phải trường hợp này khi sử dụng lisp của bạn. bản vẽ có 1 số đối tượng nằm quá xa khiến màn hình bị zoom đủ nhỏ để tập hợp (ssget "c" p p sf) gần như chọn hết toàn bộ đối tượng trên bản vẽ. Trong trường hợp này thì lisp của bạn thậm chí còn chậm hơn lisp của chính chủ rất nhiều.

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

OK. Đây là một kiểu "sai số" khi chọn "c", vì nó thường "ăn gian" ra bên ngoài point.

Tôi sẽ sửa, đồng thời nhờ bạn post bản vẽ ấy lên để tôi test luôn cho dễ 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

Nó "ăn gian" bằng chích kích thước Pickbox của bạn. bản vẽ của mình hơi nặng, khó upload. bạn cứ lấy 1 bản vẽ nhiều đối tượng 1 chút rồi copy vài đối tượng ra thật xa là sẽ test được ngay.

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  

×