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

[Yêu cầu] Lisp offset nhiều đường tròn

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

Bác ơi, lisp này chỉ hoạt động khi tồn tại Circle đáp ứng điều kiện R <=15, còn nếu ko tồn tại thì sẽ gặp lỗi ko chạy đc. Có cách nào cho nó kiểm tra, xem có tồn tại đường tròn R<=15, nếu tồn tại thì mới thực hiện lệnh scale circle vậy bác?

(defun C:scc ( / ss)
(prompt "\nSelect circles to change... ")
(cond
 ((not (setq ss (ssget  '((0 . "CIRCLE") (-4 . "<=") (40 . 15.0)))))(princ "Nothing or no Circle selected."))
 (T (vl-load-com)
  (vlax-for circle (setq ss (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object))))
 (vla-put-Radius circle 10)
)
))
(princ)
)

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

(defun C:scc ( / ss)
(prompt "\nSelect circles to change... ")
(cond
 ((not (setq ss (ssget  '((0 . "CIRCLE") (-4 . "<=") (40 . 15.0)))))(princ "Nothing or no Circle selected."))
 (T (vl-load-com)
  (vlax-for circle (setq ss (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object))))
 (vla-put-Radius circle 10)
)
))
(princ)
)

Đã dùng ActiveSelectionSet thì không cần (setq ss ...)

(defun C:scc ()
 (prompt "\nSelect circles to change... ")
 (cond
((not (ssget  '((0 . "CIRCLE") (-4 . "<=") (40 . 15.0))))(princ "Nothing or no Circle selected."))
(T (vl-load-com)
	(vlax-for circle (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object)))
  	(vla-put-Radius circle 10) )))
(princ))

  • 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

Bác cho mình hỏi cú pháp lệnh filber trong lisp với :D

Một vài ví dụ về Filter trong lisp.

;chon d/tron co b/kinh = 500
(setq ss (ssget  '((0 . "CIRCLE")  (40 . 500))))
;chon d/tron co b/kinh > 500
(setq ss (ssget  '((0 . "CIRCLE") (-4 . ">") (40 . 500))))
;chon d/tron co b/kinh < 500
(setq ss (ssget  '((0 . "CIRCLE") (-4 . "<") (40 . 500))))
;chon d/tron co b/kinh /= 500
(setq ss (ssget  '((0 . "CIRCLE")
	(-4 . "<NOT")
 	(40 . 500)
	(-4 . "NOT>") ))) 
;chon d/tron co b/kinh = 400 va b/kinh = 600
(setq ss (ssget  '((0 . "CIRCLE")
	(-4 . "<OR")
 	(40 . 400)
 	(40 . 600)
	(-4 . "OR>") )))    
;chon d/tron co b/kinh /= 400 va b/kinh /= 600
(setq ss (ssget  '((0 . "CIRCLE")
	(-4 . "<NOT")
 	(-4 . "<OR")
  	(40 . 400)
  	(40 . 600)
 	(-4 . "OR>")
	(-4 . "NOT>") )))
;chon d/tron co b/kinh  400 <= R <= 600
(setq ss (ssget '((0 . "CIRCLE") (-4 . "<=") (40 . 600) (-4 . ">=") (40 . 400))))
;chon d/tron co b/kinh R < 400 va R > 600
(setq ss (ssget  '((0 . "CIRCLE")
 	(-4 . "<OR")
  	(-4 . ">") (40 . 600)
  	(-4 . "<") (40 . 400)
 	(-4 . "OR>") )))

  • 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

vậy muốn lọc Arc theo lengh hay total angle, thì dxf code của nó là gì vậy các bác?

Không có dxf quy định Length của arc

Còn total angle của arc thì dựa vào mã dxf 50 và dxf 51 để tính total angle (A)

Mã dxf40 quy định bán kính arc ®

-> Có ® và (A) -> Length của arc

 

Muốn lọc các điều kiện về Length hay Total Angle của Arc thì phải lọc qua Arc -> xét điều kiện -> Nếu thỏa mãn thì cho vào tập chọn selection set

Hình như mình đã đi lạc chủ đề rồi thì phải......

  • 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

Một vài ví dụ về Filter trong lisp.

;chon d/tron co b/kinh = 500
(setq ss (ssget  '((0 . "CIRCLE")  (40 . 500))))
;chon d/tron co b/kinh > 500
(setq ss (ssget  '((0 . "CIRCLE") (-4 . ">") (40 . 500))))
;chon d/tron co b/kinh < 500
(setq ss (ssget  '((0 . "CIRCLE") (-4 . "<") (40 . 500))))
;chon d/tron co b/kinh /= 500
(setq ss (ssget  '((0 . "CIRCLE")
(-4 . "<NOT")
 	(40 . 500)
(-4 . "NOT>") )))
;chon d/tron co b/kinh = 400 va b/kinh = 600
(setq ss (ssget  '((0 . "CIRCLE")
(-4 . "<OR")
 	(40 . 400)
 	(40 . 600)
(-4 . "OR>") )))    
;chon d/tron co b/kinh /= 400 va b/kinh /= 600
(setq ss (ssget  '((0 . "CIRCLE")
(-4 . "<NOT")
 	(-4 . "<OR")
  	(40 . 400)
  	(40 . 600)
 	(-4 . "OR>")
(-4 . "NOT>") )))
;chon d/tron co b/kinh  400 <= R <= 600
(setq ss (ssget '((0 . "CIRCLE") (-4 . "<=") (40 . 600) (-4 . ">=") (40 . 400))))
;chon d/tron co b/kinh R < 400 va R > 600
(setq ss (ssget  '((0 . "CIRCLE")
 	(-4 . "<OR")
  	(-4 . ">") (40 . 600)
  	(-4 . "<") (40 . 400)
 	(-4 . "OR>") )))

Em viết Chọn đường tròn có bán kính /=400 và đường tròn có bán kính /=600 khác anh giabach 1 chút xíu

;chon d/tron co b/kinh /= 400 va b/kinh /= 600

(setq ss (ssget  '((0 . "CIRCLE")
 (-4 . "!=")
   (40 . 400)
 (-4 . "!=")
   (40 . 600)
)))

  • 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

Không có dxf quy định Length của arc

Còn total angle của arc thì dựa vào mã dxf 50 và dxf 51 để tính total angle (A)

Mã dxf40 quy định bán kính arc ®

-> Có ® và (A) -> Length của arc

 

Muốn lọc các điều kiện về Length hay Total Angle của Arc thì phải lọc qua Arc -> xét điều kiện -> Nếu thỏa mãn thì cho vào tập chọn selection set

Hình như mình đã đi lạc chủ đề rồi thì phải......

Thanks bác hì hì.

Vậy mình muốn lọc các cung tròn, có R<15, có total angle <85 thì làm thế nào vậy bác :D

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

Thanks bác hì hì.

Vậy mình muốn lọc các cung tròn, có R<15, có total angle <85 thì làm thế nào vậy bác :D

Bạn tham khảo


(defun c:artt(/ ss ssa dxf i en)
 (defun dxf (code e) (cdr(assoc code (entget e))))
 (if (setq ss (ssget '((0 . "ARC") (-4 . "<") (40 . 15))) )
   (progn
     (setq ssa (ssadd) i -1)
     (while (setq en (ssname ss (setq i (1+ i))))
(if (< (setq ang (abs (- (dxf 50 en) (dxf 51 en))))
     (/ (* 85 pi) 180.0)
  )
(setq ssa (ssadd en ssa))
)
     )
     (sssetfirst ssa ssa)
   )
 )
(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

Bạn tham khảo


(defun c:artt(/ ss ssa dxf i en)
 (defun dxf (code e) (cdr(assoc code (entget e))))
 (if (setq ss (ssget '((0 . "ARC") (-4 . "<") (40 . 15))) )
   (progn
     (setq ssa (ssadd) i -1)
     (while (setq en (ssname ss (setq i (1+ i))))
(if (< (setq ang (abs (- (dxf 50 en) (dxf 51 en))))
     (/ (* 85 pi) 180.0)
  )
(setq ssa (ssadd en ssa))
)
     )
     (sssetfirst ssa ssa)
   )
 )
(princ)
)

Bác siêu quá hixhix. Đúng là chuyên gia có khác ^^. Bác giúp em luôn cái scale R =10 với, em mò hoài ko đ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

Bác siêu quá hixhix. Đúng là chuyên gia có khác ^^. Bác giúp em luôn cái scale R =10 với, em mò hoài ko đc :(

(defun c:artt(/ ss ssa dxf i en)
(defun dxf (code e)
(cdr (assoc code (entget e))))
(if (setq ss (ssget '((0 . "ARC") (-4 . "<") (40 . 15))))
 (progn
  (setq ssa (ssadd) i -1)
  (while (setq en (ssname ss (setq i (1+ i))))
(if (< (setq ang (abs (- (dxf 50 en) (dxf 51 en)))) (/ (* 85 pi) 180.0))
	(setq ssa (ssadd en ssa))))
  (if ssa
(progn
	(vl-load-com)
	(setq entlst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ssa))))
	(foreach ent entlst
 	(vla-put-Radius (vlax-ename->vla-object ent) 10.0))))))
(princ))

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

(defun c:artt(/ ss ssa dxf i en)
(defun dxf (code e)
(cdr (assoc code (entget e))))
(if (setq ss (ssget '((0 . "ARC") (-4 . "<") (40 . 15))))
 (progn
  (setq ssa (ssadd) i -1)
  (while (setq en (ssname ss (setq i (1+ i))))
(if (< (setq ang (abs (- (dxf 50 en) (dxf 51 en)))) (/ (* 85 pi) 180.0))
(setq ssa (ssadd en ssa))))
  (if ssa
(progn
(vl-load-com)
(setq entlst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ssa))))
(foreach ent entlst
 	(vla-put-Radius (vlax-ename->vla-object ent) 10.0))))))
(princ))

Nếu đã duyệt qua từng ARC rồi thì không nên dùng thêm vòng lặp Foreach đâu bạn, chỉ mỗi vòng While là đủ rồi, biến ssa cũng không cần luôn

- Khi đã (setq ssa (ssadd)) thì (type ssa) -> PICKSET rồi nên dòng (if ssa (progn là thừa , không cần phải kiểm tra ssa đâu bạn, biến ssa đã khai báo trên rồi.

(setq entlst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ssa)))) -> sẽ trở về NIL nếu không có en nào nằm trong ssa cả. Cái này mình biết bạn hay mắc lỗi nên cái bệnh nghề nghiệp thì nó thế hề hề

Hơn nữa, mình đã kiểm tra ss rồi nên việc kiểm tra ssa nữa thì việc đó không cần thiết

 

(vl-load-com)
(defun c:artt(/ ss dxf i en)
(defun dxf (code e) (cdr (assoc code (entget e))))
(if (setq ss (ssget '((0 . "ARC") (-4 . "<") (40 . 15))))
 (progn
  (setq i -1)
  (while (setq en (ssname ss (setq i (1+ i))))
(if (< (abs (- (dxf 50 en) (dxf 51 en))) (/ (* 85 pi) 180.0))
(vla-put-Radius (vlax-ename->vla-object en) 10.0)))))
(princ))

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ệnh ở đây là viết nhanh theo kiểu nối đuôi vào cái có sẵn của bác.

Ồ! Có thể sửa lại code của Tue_NV mà. Tue_NV không ngại khi bạn sửa code của mình mà giúp cho người khác đâu. Giúp được ai là quý hóa lắm rồi.

Cái mình đang nói tới là biến ssa mà bạn đang dùng làm điều kiện logic cho hàm If ấy có thể bỏ đi ấy mà.

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ếu đã dùng vla-put-radius thì dùng thuần vl nhanh hơn 2 bác ạ :

(defun c:artt()
(cond
((ssget '((0 . "ARC") (-4 . "<") (40 . 15)))
 (vlax-for obj (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object)))
  (if (< (vla-get-TotalAngle obj) (/ (* 85 pi) 180.0))
(vla-put-Radius obj 10.0)
  )
 )
)
)
(princ))

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

Gởi chung các bác: Tue_NV, Gia Bach, Ketxu, Pham Thanh Binh, Thaistreetz... và nhiều bác khác không thể liệt kê hết!

Ngay mỗi topic này các bác đã cho thấy tài năng code lisp của mình: nhanh, hay, gọn...

Tôi thì đôi lúc code nó lúa không chịu nổi, nên luôn nhận được những góp ý của các bác.

Và tôi mượn topic này để nói lời cám ơn vậy. Hy vọng các bác vẫn còn giúp đỡ, và giúp "nhè nhẹ" cho nó dễ tiếp thu tí nghe.

Thân thương!

Srr, vì đã làm loãng topic.

  • 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

Nếu đã dùng vla-put-radius thì dùng thuần vl nhanh hơn 2 bác ạ :

(defun c:artt()
(cond
((ssget '((0 . "ARC") (-4 . "<") (40 . 15)))
 (vlax-for obj (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object)))
  (if (< (vla-get-TotalAngle obj) (/ (* 85 pi) 180.0))
(vla-put-Radius obj 10.0)
  )
 )
)
)
(princ))

Hì hì, ssget là thuần Lisp, chứ đâu phải thuần vl đâu nè.

Muốn thuần Vl phải viết ssget thay bằng hàm vl khác và nó sẽ dài hơ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

Ý em nói trong vòng lặp ý mà. Check entity data bằng dxf code rồi xong lại chuyển nó sang vla để thay đổi thì khổ thân nó ^^. Còn ssget thì L hay VL cũng phải có cho nhanh chứ :D

@bác ĐVH : Mỗi lời mình nói, mỗi câu mình viết đều có những lời phản hồi. Và phản hồi đó là hay hay dở là do mình. Nghe hay không cũng là do mình ^^ k tự nhiên mà một người lại hoàn thiện hơn (trong 1 lĩnh vực nào đó).

Chúc bác ngày 1 phờ rồ ^^

  • 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

@bác ĐVH : Mỗi lời mình nói, mỗi câu mình viết đều có những lời phản hồi. Và phản hồi đó là hay hay dở là do mình. Nghe hay không cũng là do mình ^^ k tự nhiên mà một người lại hoàn thiện hơn (trong 1 lĩnh vực nào đó).

Chúc bác ngày 1 phờ rồ ^^

Đỏ:đúng.

Tím: Dĩ hoà vi quý.

Xanh: Văn hoá ứng xử quan trọng hơn lisp.

Nâu: cám ơn lời động viê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  

×