Đến nội dung


Hình ảnh
- - - - -

[Yêu cầu] Nhờ viết lisp copy nhóm đối tượng lên points


  • Please log in to reply
35 replies to this topic

#21 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5448 Bài viết
Điểm đánh giá: 2624 (tuyệt vời)

Đã gửi 18 May 2012 - 02:50 PM

Hề hề hề,
Cái này là do biến osmode. Mình quen dùng truy bắt điểm bằng thanh osnap nên không để ý tới sự phức tạp của bạn. Đã sủa tại lisp cũ bạn down lại nhé.
@ bác Đoàn van ha: Bác thử dùng "_non" xem sao.
Hỏi thêm bác về sự khác biệt giữa :
(setq lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget (list '(0 . "TEXT") (cons 1 txt)))))))
và :
(setq lst (acet-ss-to-list (ssget (list '(0 . "TEXT") (cons 1 txt)))))

1). Cái chuyện "NON": tôi nghĩ rất có thể bạn ấy nhầm lẫn gì chăng. Chứ tham khảo nhiều lisp của các cao thủ foreign thì nó vẫn dùng bình thường mà không kèm bất cứ điều kiện nào.
2). Về câu hỏi của bác: kết quả trả về đều là list các ename.
- Hàm (setq lst (acet-ss-to-list (ssget)))
Bản chất bên trong như thế nào thì tôi chịu, chỉ có thằng viết ra nó mới hiểu.
- Hàm (setq lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget)))))
Không biết bác théc méc hàm nào trong những hàm con của hàm trên. Vì vậy, tôi đưa ra ví dụ (chọn 3 text) cách dùng từng hàm để bác rõ vậy:
Hàm ssnamex:
Trả về 1 list chứa thông tin đối tượngphương pháp chọn đối tượng.
Trong đó, thành phần thứ 2 (tương ứng hàm cadr) trong mỗi list con của list mẹ chính là tên đối tượng. Ta đang quan tâm tới nó.
(ssnamex (ssget)) =>
((2 <Entity name: 7efaf2d8> 0 -1) (2 <Entity name: 7efaf2d0> 0 -1) (2 <Entity name: 7efaf2c8> 0 -1) (-1 (0 (42.7551 41.859 0.0)) (0 (53.315 41.859 0.0)) (0 (53.315 32.4024 0.0)) (0 (42.7551 32.4024 0.0))))
Hàm mapcar:
(mapcar 'car '((1 2 3 4 5))) => (1)
(mapcar 'cadr '((1 2 3 4 5))) => (2)
(mapcar 'caddr '((1 2 3 4 5))) => (3)
(mapcar 'cadr (ssnamex (ssget))) => (<Entity name: 7efaf2d8> <Entity name: 7efaf2d0> <Entity name: 7efaf2c8> (0 (47.2158 39.5858 0.0)))
Hàm vl-remove-if:
Loại bỏ những phần tử khỏi list nếu nó không thoả hàm ‘func (VD: 'zerop ; 'listp ; 'vl-symbolp...)
(vl-remove-if 'zerop (list pi 5 0 12)) => (3.14159 5 12)
(vl-remove-if 'listp (list pi 5 0 '(1 2) 12)) => (3.14159 5 0 12)
(vl-remove-if 'vl-symbolp (list pi t 0 "abc")) => (3.14159 0 "abc")
(vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget)))) => (<Entity name: 7efaf2d8> <Entity name: 7efaf2d0> <Entity name: 7efaf2c8>)
  • 1

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#22 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5448 Bài viết
Điểm đánh giá: 2624 (tuyệt vời)

Đã gửi 18 May 2012 - 03:01 PM

Mình đã down lại lisp của bác phamthanhbinh. Có lẽ dùng cái lisp của bác là lành mạnh nhất. hì.

Hồi giờ mới nghe "lisp lành mạnh"? Chắc 2 cái còn lại thuộc "lisp buông thả"?
  • 1

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#23 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 18 May 2012 - 04:33 PM

1). Cái chuyện "NON": tôi nghĩ rất có thể bạn ấy nhầm lẫn gì chăng. Chứ tham khảo nhiều lisp của các cao thủ foreign thì nó vẫn dùng bình thường mà không kèm bất cứ điều kiện nào.
2). Về câu hỏi của bác: kết quả trả về đều là list các ename.
- Hàm (setq lst (acet-ss-to-list (ssget)))
Bản chất bên trong như thế nào thì tôi chịu, chỉ có thằng viết ra nó mới hiểu.
- Hàm (setq lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget)))))
Không biết bác théc méc hàm nào trong những hàm con của hàm trên. Vì vậy, tôi đưa ra ví dụ (chọn 3 text) cách dùng từng hàm để bác rõ vậy:
Hàm ssnamex:
Trả về 1 list chứa thông tin đối tượngphương pháp chọn đối tượng.
Trong đó, thành phần thứ 2 (tương ứng hàm cadr) trong mỗi list con của list mẹ chính là tên đối tượng. Ta đang quan tâm tới nó.
(ssnamex (ssget)) =>
((2 <Entity name: 7efaf2d8> 0 -1) (2 <Entity name: 7efaf2d0> 0 -1) (2 <Entity name: 7efaf2c8> 0 -1) (-1 (0 (42.7551 41.859 0.0)) (0 (53.315 41.859 0.0)) (0 (53.315 32.4024 0.0)) (0 (42.7551 32.4024 0.0))))
Hàm mapcar:
(mapcar 'car '((1 2 3 4 5))) => (1)
(mapcar 'cadr '((1 2 3 4 5))) => (2)
(mapcar 'caddr '((1 2 3 4 5))) => (3)
(mapcar 'cadr (ssnamex (ssget))) => (<Entity name: 7efaf2d8> <Entity name: 7efaf2d0> <Entity name: 7efaf2c8> (0 (47.2158 39.5858 0.0)))
Hàm vl-remove-if:
Loại bỏ những phần tử khỏi list nếu nó không thoả hàm ‘func (VD: 'zerop ; 'listp ; 'vl-symbolp...)
(vl-remove-if 'zerop (list pi 5 0 12)) => (3.14159 5 12)
(vl-remove-if 'listp (list pi 5 0 '(1 2) 12)) => (3.14159 5 0 12)
(vl-remove-if 'vl-symbolp (list pi t 0 "abc")) => (3.14159 0 "abc")
(vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget)))) => (<Entity name: 7efaf2d8> <Entity name: 7efaf2d0> <Entity name: 7efaf2c8>)

Hề hề hề,
Thiệt tình mà nói thì các hàm trên bác sử dụng đều có trong help developer của CAd nên mình cũng đã mày mò đọc nó rồi. Tuy nhiên cái sự hiểu thì nó vẫn rất lỗ mỗ.bởi cái tiếng tây nó hơi lủng củng.
Việc mình théc méc là do khi sử dụng như vầy, không biết nó có cho kết quả gì chuẩn xác hơn dùng acet ..... không ??? Bởi vì cứ theo thiển ý của mình thì mèo trắng hay mèo đen, miễn là bắt được chuột sẽ là mèo tốt. Bởi vậy khi dùng như bác, những người mới học sẽ phải lọ mọ khá lâu mới có thể thủng hết cái chức năng của hàm cho dù trông nó thấy có vẻ bác học hơn.
Còn nếu dùng acet.... thì xem ra có vẻ trực quan và dễ hiểu hơn đối với người mới học, nhất là học mót như mình bác ạ. Nội dung bên trong của thằng acet mình cũng chả biết gì đâu nhưng biết rằng cứ dùng nó thì được cái mình cần thôi. Vậy là mần chớ chửa tìm hiểu được gì thêm.
Rất mong bác thông cảm cho cái sự thec méc của mình.
Hề hề hề,..
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#24 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5448 Bài viết
Điểm đánh giá: 2624 (tuyệt vời)

Đã gửi 18 May 2012 - 04:46 PM

Thiệt tình là như cái hàm đã nói thì bần tui cũng đi mót thôi. Sau đó lấy búa gõ ra từng miếng rồi ngâm... rượu. Có cái ngâm nó ngọt, có cái ngâm nó đắng lè.
Nhưng chắc chắn 100% kết quả của hàm trên là đúng. Biết đâu thằng acet nó cũng viết kiểu đó bác ạ.
  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#25 duy267

duy267

    biết vẽ point

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

Đã gửi 18 May 2012 - 07:55 PM

Hàm vl-remove-if:
Loại bỏ những phần tử khỏi list nếu nó không thoả hàm ‘func (VD: 'zerop ; 'listp ; 'vl-symbolp...)

Câu này hình như bác nói bị ngược?
  • 0

#26 Thaistreetz

Thaistreetz

    biết lệnh adcenter

  • Advance Member
  • PipPipPipPipPipPipPip
  • 903 Bài viết
Điểm đánh giá: 505 (tốt)

Đã gửi 18 May 2012 - 09:08 PM

Thiệt tình là như cái hàm đã nói thì bần tui cũng đi mót thôi. Sau đó lấy búa gõ ra từng miếng rồi ngâm... rượu. Có cái ngâm nó ngọt, có cái ngâm nó đắng lè.
Nhưng chắc chắn 100% kết quả của hàm trên là đúng. Biết đâu thằng acet nó cũng viết kiểu đó bác ạ.

Có thể trả lời chắc chắn cho bác Hà biết là Acet nó không viết hàm trên như thế. Có thể nó không dùng lisp để viết mà dùng ngôn ngữ khác cho tốc độ nhanh hơn. Mình đã tốn tương đối nhiều công sức để viết 1 hàm chuyển đổi selection set về list. Cách viết như trên chỉ là 1 trong số các cách mà mình từng viết. Khi viết mình ưu tiên tốc độ vì hầu hết chương trình của mình đều thường xuyên fải xử lý con số hàng nghìn đối tượng. (hình như bác cũng chuyên ngành cầu đường nên chắc sẽ hiểu vì sao lại nhiều như vậy)

Kết luận: Cách trên là cách triển khai code ngắn gọn nhất, nhưng nó cũng là cách viết tệ nhất vì nó cực chậm. Chậm hơn acet có khi đến cả 1000 lần. Nguyên nhân gây chậm chính là ở hàm ssnamex. Các cách viết khác sử dụng hàm ssname cho tốc độ gần bằng acet. Tuy nhiên mình chưa viết được 1 hàm nào nhanh bằng hoặc hơn acet-ss-to-list cả. Đây là lựa chọn cuối cùng của mình để thay thế cho acet:
(defun ss->list (ss / i lst) (if ss (repeat (setq i (sslength ss)) (setq lst (cons (ssname ss (setq i (1- i))) lst)))))
Đúng ra fải reverse kết quả mới đúng thứ tự. tuy nhiên do ít khi có nhu cầu nên mình cũng bỏ hàm này luôn. khi nào cần list kết quả đúng thứ tự thì viết thế này (reverse (ss->list ss))
  • 3

Hình đã gửi
IN HIM, I TRUST. THE TRUST IN MY GOD


#27 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 18 May 2012 - 10:13 PM

Theo e thì dùng while nhanh hơn bác ạ. Mà bác chạy từ sslength chạy ngược về thì cons sẽ thành list chuẩn, sao lại rev mần chi ^^
ACET thì ta biết rồi, dính vào thằng ARX ^^
  • 1

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#28 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5448 Bài viết
Điểm đánh giá: 2624 (tuyệt vời)

Đã gửi 18 May 2012 - 10:17 PM

Có thể trả lời chắc chắn cho bác Hà biết là Acet nó không viết hàm trên như thế. Có thể nó không dùng lisp để viết mà dùng ngôn ngữ khác cho tốc độ nhanh hơn. Mình đã tốn tương đối nhiều công sức để viết 1 hàm chuyển đổi selection set về list. Cách viết như trên chỉ là 1 trong số các cách mà mình từng viết. Khi viết mình ưu tiên tốc độ vì hầu hết chương trình của mình đều thường xuyên fải xử lý con số hàng nghìn đối tượng. (hình như bác cũng chuyên ngành cầu đường nên chắc sẽ hiểu vì sao lại nhiều như vậy)
Kết luận: Cách trên là cách triển khai code ngắn gọn nhất, nhưng nó cũng là cách viết tệ nhất vì nó cực chậm. Chậm hơn acet có khi đến cả 1000 lần. Nguyên nhân gây chậm chính là ở hàm ssnamex. Các cách viết khác sử dụng hàm ssname cho tốc độ gần bằng acet. Tuy nhiên mình chưa viết được 1 hàm nào nhanh bằng hoặc hơn acet-ss-to-list cả. Đây là lựa chọn cuối cùng của mình để thay thế cho acet:
(defun ss->list (ss / i lst) (if ss (repeat (setq i (sslength ss)) (setq lst (cons (ssname ss (setq i (1- i))) lst)))))
Đúng ra fải reverse kết quả mới đúng thứ tự. tuy nhiên do ít khi có nhu cầu nên mình cũng bỏ hàm này luôn. khi nào cần list kết quả đúng thứ tự thì viết thế này (reverse (ss->list ss))

1). Tôi biết về bản chất các hàm acet rất mơ hồ. Một số hàm nằm trong thư mục Exprees thì còn lấy búa đập nó ra được. Còn đa số nằm trong arx thì bó tay nên chỉ nói là "có thể". Vậy là "có thể" của tôi đã trở thành "không thể". OK.
2). Tôi mê "tốc độ" bởi vì nhiều chương trình dài hơi của tôi đã khốn đốn vì tốc độ, nên tôi ủng hộ.
3). Tôi cực chán cái hàm reserve, bởi nó làm chậm rất đáng kể. Do đó, không thể không quan tâm tới nó.
4). Cuối cùng: tôi rất mê các hàm Acet, Cal. Nhưng hình như chúng là loại "tầm gởi" của cad nên tôi hơi thiếu thiện chí với chúng. Lý do đó khiến tôi viết lisp thì rất hạn chế dùng, trừ trường hợp làm biếng hoặc không thể viết tốt hơn. À, thêm thằng command nữa.
Tóm lại: từ topic này mà mà mở mang được vài kiến thức.
Nhưng còn 1 vấn đề: tại sao chủ topic dùng "NON" bị lỗi (xem các phản hồi ở trên)? Ai biết xin chỉ giùm.
  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#29 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 18 May 2012 - 10:45 PM

Bác đã bỏ lisp đó đi nên k bắt lỗi được ^^ Lỗi báo nhập vào giá trị nil chứ k phải lỗi của thằng non ạ. Ngoài ra cũng có thể lưu ý cả yếu tố về đời CAD (bạn victor chắc dùng 12 với lệnh copy có array)
  • 1

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#30 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5448 Bài viết
Điểm đánh giá: 2624 (tuyệt vời)

Đã gửi 18 May 2012 - 10:50 PM

Bác đã bỏ lisp đó đi nên k bắt lỗi được ^^ Lỗi báo nhập vào giá trị nil chứ k phải lỗi của thằng non ạ. Ngoài ra cũng có thể lưu ý cả yếu tố về đời CAD (bạn victor chắc dùng 12 với lệnh copy có array)

Lisp cũ chỉ khác là không set osmode. Thay vào đó, trong lệnh copy thì trước điểm nguồn và điểm đích đều có "non" thôi.
Tiếc là không có 12 để test.
  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#31 Thaistreetz

Thaistreetz

    biết lệnh adcenter

  • Advance Member
  • PipPipPipPipPipPipPip
  • 903 Bài viết
Điểm đánh giá: 505 (tốt)

Đã gửi 18 May 2012 - 11:19 PM

Theo e thì dùng while nhanh hơn bác ạ. Mà bác chạy từ sslength chạy ngược về thì cons sẽ thành list chuẩn, sao lại rev mần chi ^^
ACET thì ta biết rồi, dính vào thằng ARX ^^

Đúng rồi, Ketxu rất tinh ý. Mình nhớ nhầm, ban đầu mình sử dụng 1+ thấy rườm rà hơn nên đổi về 1-
Về mấy vòng lặp, mình chưa từng kiểm tra sự chênh lệch tốc độ giữa while, foreach và repeat. Mình suy nghĩ chủ quan rằng với những fép lặp có thể xác định trước số lần lặp thì repeat là nhanh nhất bởi while có thêm yêu cầu kiểm tra điều kiện lặp. có lẽ fải test lại mới được.
  • 0

Hình đã gửi
IN HIM, I TRUST. THE TRUST IN MY GOD


#32 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5448 Bài viết
Điểm đánh giá: 2624 (tuyệt vời)

Đã gửi 18 May 2012 - 11:50 PM

Theo e thì dùng while nhanh hơn bác ạ. Mà bác chạy từ sslength chạy ngược về thì cons sẽ thành list chuẩn, sao lại rev mần chi ^^
ACET thì ta biết rồi, dính vào thằng ARX ^^

Liệu với hàm đó thì dùng foreach có chậm hơn while không, vì while thì có thể giảm số phần tử sau mỗi vòng lặp nhưng lại phải thêm hàm làm giảm, trong khi foreach thì không giảm số lần lặp nhưng chả cần thêm gì. Tôi đang nghi ngờ giữa chúng.
  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#33 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 19 May 2012 - 06:18 AM

Lisp cũ chỉ khác là không set osmode. Thay vào đó, trong lệnh copy thì trước điểm nguồn và điểm đích đều có "non" thôi.
Tiếc là không có 12 để test.

Tue_NV chạy lisp có dòng : (command "copy" ss "" "non" pg "non" (cdr (assoc 10 (entget n))) )) ở CAD2012
chạy tốt -> không có vấn đề gì cả
  • 1

#34 victor85

victor85

    biết lệnh stretch

  • Members
  • PipPipPip
  • 169 Bài viết
Điểm đánh giá: 10 (tàm tạm)

Đã gửi 12 June 2012 - 05:22 PM

Mình thấy được voi mà đòi Hai Bà Trưng thì cũng xấu lắm.
Tuy nhiên trong quá trình sử dụng cad nó cứ phát sinh ra. Mong các bác mở rộng viết dùm mình copy nhóm đối tượng cũng với điểm gốc chèn lên các block ( Thay đầu vào là các point là các điểm chèn của các block)
Mình thấy trong bản vẽ các block xuất hiện với tần xuất rất nhiều lần. Vì vậy việc cần copy nhóm đối tượng theo block cũng khá hay gặp (Không kể đến trường hợp refedit block để thêm các đối tượng vì một số lý do quản lý nên ta không muốn nhóm đối tương kia nằm trong block - VD: nhóm đối tượng là text). Các bác xuống tay viết dùm em với nhé :)
  • 0

#35 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 12 June 2012 - 06:17 PM

Trong lisp của ai đó thì thay "POINT" bằng "INSERT", code lấy điểm chèn vẫn là 10 nên không có gì thay đổi
  • 1

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#36 victor85

victor85

    biết lệnh stretch

  • Members
  • PipPipPip
  • 169 Bài viết
Điểm đánh giá: 10 (tàm tạm)

Đã gửi 13 June 2012 - 09:36 AM

he he, đã làm được rùi. Cảm ơn ket xu nhé.
  • 0