Đến nội dung


Hình ảnh
- - - - -

Hỏi lisp về Region


  • Please log in to reply
13 replies to this topic

#1 elleHCSC

elleHCSC

    biết lệnh copy

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

Đã gửi 10 August 2009 - 10:41 AM

Tôi có hình vẽ như hình 1:
Hình đã gửi

Sau khi dùng lệnh Region của cad và chọn "All" các line vẽ CAD nó sẽ tạo ra 3 region là A, B và 1 cái region bao ngoài của A, B (đường bao màu xanh đc đánh dấu)
Hình đã gửi

- Cái mình cần là trợ giúp cho mình bằng lisp để sao cho có thể xoá được cái Region bao ngoài kia và chỉ giữ lại Region A và B. Đừng bảo mình ngồi xoá tay từ cái region nha...vì các hình trên chỉ là vd chứ bản vẽ của mình có nhiều cái region kiểu đó lắm !

Tks !
  • 0
Share for all, all will share !

--------------------
HTTP://WWW.HCSC.VN
HTTP://WWW.HCSC.COM.VN

#2 tranlaogia

tranlaogia

    biết lệnh scale

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

Đã gửi 10 August 2009 - 11:35 AM

Tôi có hình vẽ như hình 1:
Hình đã gửi

Sau khi dùng lệnh Region của cad và chọn "All" các line vẽ CAD nó sẽ tạo ra 3 region là A, B và 1 cái region bao ngoài của A, B (đường bao màu xanh đc đánh dấu)
Hình đã gửi

- Cái mình cần là trợ giúp cho mình bằng lisp để sao cho có thể xoá được cái Region bao ngoài kia và chỉ giữ lại Region A và B. Đừng bảo mình ngồi xoá tay từ cái region nha...vì các hình trên chỉ là vd chứ bản vẽ của mình có nhiều cái region kiểu đó lắm !

Tks !

bạn tìm trên diễn đàn bằng từ khoá ewb. đây là lisp xoá vùng giới hạn. cũng đã nói nhiều rồi
  • 0

#3 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 10 August 2009 - 11:53 AM

Tôi có hình vẽ như hình 1:
Hình đã gửi

Sau khi dùng lệnh Region của cad và chọn "All" các line vẽ CAD nó sẽ tạo ra 3 region là A, B và 1 cái region bao ngoài của A, B (đường bao màu xanh đc đánh dấu)
Hình đã gửi

- Cái mình cần là trợ giúp cho mình bằng lisp để sao cho có thể xoá được cái Region bao ngoài kia và chỉ giữ lại Region A và B. Đừng bảo mình ngồi xoá tay từ cái region nha...vì các hình trên chỉ là vd chứ bản vẽ của mình có nhiều cái region kiểu đó lắm !

Tks !

Chào elleHCSC
Trước tiên Tue_NV xin cảm ơn bác Nguyễn Hoành. Từ đoạn Code của bác mà Tue_NV đã viết xong đoạn Code này để trợ giúp cho elleHCSC.
elleHCSC sử dụng đoạn Code này xem sao nhé :

(defun c:gb( / ss from to cur i tap lcanh lcanh1 ent ent1 ss1)
(vl-load-com)
(prompt "\n Chon cac doi tuong can tao thanh region")
(setq ss1 (ssget))
(setq frome (entlast)) ;;

(command "region" ss1 "") ;;
(setq toe (entlast)) ;;

(setq cur frome ;
ss (ssadd)
)
(while (not (eq cur toe)) ;;
(setq
cur (entnext cur)
ss (ssadd cur ss)
)
)

(setq i 0 tap nil)
(while (< i (- (sslength ss) 1))
(setq ent (ssname ss i))
(setq ent1 (ssname ss (+ i 1)))
(setq lcanh (vla-get-area (vlax-ename->vla-object ent)))
(setq lcanh1 (vla-get-area (vlax-ename->vla-object ent1)))
(if (> lcanh1 lcanh)
(setq tap (append tap (list ent1)))
(setq tap (append tap (list ent)))
)
(setq i (1+ i))
)
(entdel (nth (- (vl-list-length tap) 1) tap))
(princ)
)


@tranlaogia : Lisp ewb không thể làm được cái điều mà elleCHSC muốn lão gia ạ

Bài viết đã được chỉnh sửa nội dung bởi Tue_NV: 10 August 2009 - 12:04 PM

  • 2

#4 elleHCSC

elleHCSC

    biết lệnh copy

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

Đã gửi 10 August 2009 - 01:07 PM

Cảm ơn TUE_NV đã trợ giúp. Đoạn code trên chạy ok roài nhưng sorry bạn 1 chút có thể mình đưa cái hình VD minh hoạ chưa đủ và chính xác nên nó chạy còn xót trong TH sau:
Hình đã gửi

Nghĩa là nếu tập hợp các Region nó nằm rời rạc thì đoạn CODE trên chỉ xoá được region bao ngoài của 1 tập các region, còn các tập hợp khác nó chưa xoá.
Tks !
  • 0
Share for all, all will share !

--------------------
HTTP://WWW.HCSC.VN
HTTP://WWW.HCSC.COM.VN

#5 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 10 August 2009 - 04:33 PM

Cảm ơn TUE_NV đã trợ giúp. Đoạn code trên chạy ok roài nhưng sorry bạn 1 chút có thể mình đưa cái hình VD minh hoạ chưa đủ và chính xác nên nó chạy còn xót trong TH sau:
Hình đã gửi

Nghĩa là nếu tập hợp các Region nó nằm rời rạc thì đoạn CODE trên chỉ xoá được region bao ngoài của 1 tập các region, còn các tập hợp khác nó chưa xoá.
Tks !

Trong trường hợp của elleHCSC thì Tue_Nv chưa nghĩ ra thuật toán để chọn hàng loạt được.
Nhưng bạn elleHCSC có thể kết hợp lệnh multiple của CAD với Code trên thử xem. Tuy không nhanh lắm nhưng vẫn giải quyết được vấn đề trước mắt.

Chọn 1 tập các region

Command: multiple
Enter command name to repeat: gb
Chon cac doi tuong can tao thanh region
Select objects: Specify opposite corner: 14 found : Chọn 1 tập các region

Select objects: Enter
region
Select objects: 14 found : Chọn 1 tập các region

Select objects: Enter
7 loops extracted.


7 Regions created.

Nhấn ESC để thoát lệnh
  • 0

#6 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 11 August 2009 - 12:34 AM

Cảm ơn TUE_NV đã trợ giúp. Đoạn code trên chạy ok roài nhưng sorry bạn 1 chút có thể mình đưa cái hình VD minh hoạ chưa đủ và chính xác nên nó chạy còn xót trong TH sau:
Hình đã gửi

Nghĩa là nếu tập hợp các Region nó nằm rời rạc thì đoạn CODE trên chỉ xoá được region bao ngoài của 1 tập các region, còn các tập hợp khác nó chưa xoá.
Tks !

Hôm nào đọc trên diễn đàn thấy bạn đã dùng cadmap để tạo vùng in HSKT rồi sao hôm nay lại quay lại tạo cái region này nhỉ. Theo mình nghĩ muốn làm đc cái này phải chịu khó một tý.
- Thứ nhất phải có hàm tìm điểm bên trong của một đa giác (ở đây là region)
- Thứ hai là hàm xác định điểm bên trong hay ngoài đa giác
- Thứ ba chọn tất cả các region. Lập vòng lặp kiểm tra tuần tự các region với nhau. Để ý rằng các region kg cắt nhau nên nếu region nào có tâm bên trong region kia thì loại bỏ nó ra khỏi tập hợp. Kiểm tra cho đến khi nào kg còn trg hợp này xảy ra nữa thì các region còn lại chính là các region bao ngoài. Lúc đó xóa chúng đi. Trg hợp này chỉ có thể sai nếu có nhiều region bao ngoài lồng nhau
Mình đg rất bận nên kg viết thành lisp đc. Mình nghĩ "elleHCSC" thừa sức viết cái này
  • 1

#7 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 11 August 2009 - 08:39 AM

Hôm nào đọc trên diễn đàn thấy bạn đã dùng cadmap để tạo vùng in HSKT rồi sao hôm nay lại quay lại tạo cái region này nhỉ. Theo mình nghĩ muốn làm đc cái này phải chịu khó một tý.
- Thứ nhất phải có hàm tìm điểm bên trong của một đa giác (ở đây là region)
- Thứ hai là hàm xác định điểm bên trong hay ngoài đa giác
- Thứ ba chọn tất cả các region. Lập vòng lặp kiểm tra tuần tự các region với nhau. Để ý rằng các region kg cắt nhau nên nếu region nào có tâm bên trong region kia thì loại bỏ nó ra khỏi tập hợp. Kiểm tra cho đến khi nào kg còn trg hợp này xảy ra nữa thì các region còn lại chính là các region bao ngoài. Lúc đó xóa chúng đi. Trg hợp này chỉ có thể sai nếu có nhiều region bao ngoài lồng nhau
Mình đg rất bận nên kg viết thành lisp đc. Mình nghĩ "elleHCSC" thừa sức viết cái này

Với những điều mà bạn TRUNGNGAMY nêu trên thì Tue_NV không thể giúp cho bạn elleHCSC được rồi vì khả năng của mình chưa có nhiều. Xin lỗi bạn elleHCSC vì Tue_NV không giúp gì cho elleHCSC được.
Nếu bạn TRUNGNGAMY rãnh thì bạn trợ giúp cho elleHCSC 1 tay nhé.
Cảm ơn.
  • 0

#8 elleHCSC

elleHCSC

    biết lệnh copy

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

Đã gửi 11 August 2009 - 09:07 AM

Với những điều mà bạn TRUNGNGAMY nêu trên thì Tue_NV không thể giúp cho bạn elleHCSC được rồi vì khả năng của mình chưa có nhiều. Xin lỗi bạn elleHCSC vì Tue_NV không giúp gì cho elleHCSC được.
Nếu bạn TRUNGNGAMY rãnh thì bạn trợ giúp cho elleHCSC 1 tay nhé.
Cảm ơn.

Hì hì, chào TRUNGNGAMY. Thực tế dùng CadMAP chạy topology xong thì việc tạo mấy cái vùng này là hoàn toàn tự động và dễ dàng việc này mình đủ khả năng và đã làm rồi chỉ vài dòng lisp thôi. Tuy nhiên mục tiêu của elle là làm 1 cái lisp để nó cũng tạo dc vùng thông qua lệnh Region của cad (chứ không dùng cadmap) vì một số người ko dùng CadaMap. Mình đang viết dở, nó cũng đã chạy OK chỉ có điều mắc mớ là tạo vùng xong thì nó lại thừa ra mấy cái vùng bao kia. Chỉ còn tìm cách xoá nó đi là bài toán đc giải quyết.

OK từ gợi ý của bạn mình đã nghĩ đc 1 phương án rất đơn giản, để thử xem nó có ổn không.

Tks all !
  • 0
Share for all, all will share !

--------------------
HTTP://WWW.HCSC.VN
HTTP://WWW.HCSC.COM.VN

#9 gia_bach

gia_bach

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 1432 Bài viết
Điểm đánh giá: 1425 (rất tốt)

Đã gửi 11 August 2009 - 10:10 AM

..............
Mình đang viết dở, nó cũng đã chạy OK chỉ có điều mắc mớ là tạo vùng xong thì nó lại thừa ra mấy cái vùng bao kia. Chỉ còn tìm cách xoá nó đi là bài toán đc giải quyết.
..............

Bạn chạy thử Lisp Highlight đối tuợng Region bao ngoài (nếu có) trong tập hợp các đối tuợng Region.
Sau đó việc erase, move, copy ... bạn tùy nghi xử lý.
Chú ý : Lisp này không tạo ra Region mà chỉ chọn ra Region bao ngoài trong tập hợp các đối tuợng Region.
(defun C:ssb(/ ss ss1 boundary e minPt maxPt )  ;select region boundary
(vl-load-com)
(setq ss1 (ssadd))
(if (setq ss (ssget (list (cons 0 "REGION") ) ) )
(progn
(setq boundary (boundarySS ss))
(foreach e (mapcar 'vlax-ename->vla-Object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
(vla-getBoundingBox e 'minPt 'maxPt)
(setq minPt (vlax-safearray->list minPt)
maxPt (vlax-safearray->list maxPt))
(if (equal (list minPt maxPt ) boundary 0.001)
(setq ss1 (ssadd (vlax-vla-object->ename e) ss1))
)
); foreach
(if (>(sslength ss1)0)(sssetfirst nil ss1) )
); progn
); if
)
;ham tra ve 2 diem (LowerLeft TopRight) cua hinh chu nhat bao quanh cac doi tuong
(defun boundarySS (ss / all_max all_min ll maxpt minpt ur);
(setq all_min (list)
all_max (list) )
(foreach x (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
(vla-GetBoundingBox x 'minpt 'maxpt)
(setq all_min (cons (vlax-safearray->list minpt) all_min)
all_max (cons (vlax-safearray->list maxpt) all_max) )
) ;foreach
(setq ll (list (car (vl-sort (mapcar 'car all_min) '<))
(car (vl-sort (mapcar 'cadr all_min) '<))
(car (vl-sort (mapcar 'caddr all_min) '<)) ) ;list
ur (list (last (vl-sort (mapcar 'car all_max) '<))
(last (vl-sort (mapcar 'cadr all_max) '<))
(last (vl-sort (mapcar 'caddr all_max) '<))) ;list
) ;setq
(list ll ur )
)

  • 1

#10 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 11 August 2009 - 10:34 AM

Bạn chạy thử Lisp Highlight đối tuợng Region bao ngoài (nếu có) trong tập hợp các đối tuợng Region.
Sau đó việc erase, move, copy ... bạn tùy nghi xử lý.
Chú ý : Lisp này không tạo ra Region mà chỉ chọn ra Region bao ngoài trong tập hợp các đối tuợng Region.

(defun C:ssb(/ ss ss1 boundary e minPt maxPt )  ;select region boundary
(vl-load-com)
(setq ss1 (ssadd))
(if (setq ss (ssget (list (cons 0 "REGION") ) ) )
(progn
(setq boundary (boundarySS ss))
(foreach e (mapcar 'vlax-ename->vla-Object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
(vla-getBoundingBox e 'minPt 'maxPt)
(setq minPt (vlax-safearray->list minPt)
maxPt (vlax-safearray->list maxPt))
(if (equal (list minPt maxPt ) boundary 0.001)
(setq ss1 (ssadd (vlax-vla-object->ename e) ss1))
)
); foreach
(if (>(sslength ss1)0)(sssetfirst nil ss1) )
); progn
); if
)
;ham tra ve 2 diem (LowerLeft TopRight) cua hinh chu nhat bao quanh cac doi tuong
(defun boundarySS (ss / all_max all_min ll maxpt minpt ur);
(setq all_min (list)
all_max (list) )
(foreach x (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
(vla-GetBoundingBox x 'minpt 'maxpt)
(setq all_min (cons (vlax-safearray->list minpt) all_min)
all_max (cons (vlax-safearray->list maxpt) all_max) )
) ;foreach
(setq ll (list (car (vl-sort (mapcar 'car all_min) '<))
(car (vl-sort (mapcar 'cadr all_min) '<))
(car (vl-sort (mapcar 'caddr all_min) '<)) ) ;list
ur (list (last (vl-sort (mapcar 'car all_max) '<))
(last (vl-sort (mapcar 'cadr all_max) '<))
(last (vl-sort (mapcar 'caddr all_max) '<))) ;list
) ;setq
(list ll ur )
)

Chào anh gia bách
Lisp trên thật hay.
Anh cho Tue_NV hỏi 1 tý : là các hàm vla ... . Ví dụ như hàm vla-getBoundingBox thì đọc Help ở đâu?
Tue_NV đã đọc trong cuốn acad_dev nhưng tìm hoài không thấy các hàm vla. Mong anh hướng dẫn giúp.
Cảm ơn anh
  • 0

#11 gia_bach

gia_bach

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 1432 Bài viết
Điểm đánh giá: 1425 (rất tốt)

Đã gửi 11 August 2009 - 11:02 AM

................
Anh cho Tue_NV hỏi 1 tý : là các hàm vla ... . Ví dụ như hàm vla-getBoundingBox thì đọc Help ở đâu?
Tue_NV đã đọc trong cuốn acad_dev nhưng tìm hoài không thấy các hàm vla. Mong anh hướng dẫn giúp.
..........

Bạn xem trong file acadauto.chm ActiveX and VBA Reference (thông thuờng trong thư mục Help của ACAD) mục Methods
hoặc tại Visual LISP Editor bạn chọn (Highlight) hàm cần xem, vd : vla-GetBoundingBox rồi nhấn F1.
Chú ý : trong ActiveX and VBA Reference chỉ có các Method : GetBoundingBox, IntersectWith ...
khi sử dụng trong Visual LISP bạn nhớ thêm tiền tố vla- truớc các method của ActiveX and VBA Reference.
Hình đã gửi
  • 1

#12 elleHCSC

elleHCSC

    biết lệnh copy

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

Đã gửi 11 August 2009 - 01:24 PM

Bạn chạy thử Lisp Highlight đối tuợng Region bao ngoài (nếu có) trong tập hợp các đối tuợng Region.
Sau đó việc erase, move, copy ... bạn tùy nghi xử lý.
Chú ý : Lisp này không tạo ra Region mà chỉ chọn ra Region bao ngoài trong tập hợp các đối tuợng Region.

(defun C:ssb(/ ss ss1 boundary e minPt maxPt )  ;select region boundary
(vl-load-com)
(setq ss1 (ssadd))
(if (setq ss (ssget (list (cons 0 "REGION") ) ) )
(progn
(setq boundary (boundarySS ss))
(foreach e (mapcar 'vlax-ename->vla-Object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
(vla-getBoundingBox e 'minPt 'maxPt)
(setq minPt (vlax-safearray->list minPt)
maxPt (vlax-safearray->list maxPt))
(if (equal (list minPt maxPt ) boundary 0.001)
(setq ss1 (ssadd (vlax-vla-object->ename e) ss1))
)
); foreach
(if (>(sslength ss1)0)(sssetfirst nil ss1) )
); progn
); if
)
;ham tra ve 2 diem (LowerLeft TopRight) cua hinh chu nhat bao quanh cac doi tuong
(defun boundarySS (ss / all_max all_min ll maxpt minpt ur);
(setq all_min (list)
all_max (list) )
(foreach x (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
(vla-GetBoundingBox x 'minpt 'maxpt)
(setq all_min (cons (vlax-safearray->list minpt) all_min)
all_max (cons (vlax-safearray->list maxpt) all_max) )
) ;foreach
(setq ll (list (car (vl-sort (mapcar 'car all_min) '<))
(car (vl-sort (mapcar 'cadr all_min) '<))
(car (vl-sort (mapcar 'caddr all_min) '<)) ) ;list
ur (list (last (vl-sort (mapcar 'car all_max) '<))
(last (vl-sort (mapcar 'cadr all_max) '<))
(last (vl-sort (mapcar 'caddr all_max) '<))) ;list
) ;setq
(list ll ur )
)


Chào Gia_bach mình đã thử đoạn code trên nhưng nó ko như được ý mình muốn. Kết quả của đoạn code trên nó cũng cho gần giống của TUE_NV nếu như khi chạy chọn tập các region rời rạc (mình chọn "all" region mỗi khi chạy ssb) thì kết quá nó báo là "nil". mình đã thử đi thử lại với nhiều bản vẽ.

Tks bác gia_bach, quả là bác có nhiều chiêu hay quá...
  • 0
Share for all, all will share !

--------------------
HTTP://WWW.HCSC.VN
HTTP://WWW.HCSC.COM.VN

#13 gia_bach

gia_bach

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 1432 Bài viết
Điểm đánh giá: 1425 (rất tốt)

Đã gửi 11 August 2009 - 04:13 PM

........
khi chạy chọn tập các region rời rạc (mình chọn "all" region mỗi khi chạy ssb) thì kết quá nó báo là "nil".
...............

Bạn chạy thử Lisp này.
(defun C:ssb(/ ss ss1 boundary e ll ur )  ;select region boundary
(vl-load-com)
(setq ss1 (ssadd))
(if (setq ss (ssget (list (cons 0 "REGION"))))
(progn
(foreach e (mapcar 'vlax-ename->vla-Object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
(vla-getBoundingBox e 'll 'ur)
(setq ll (vlax-safearray->list ll)
ur (vlax-safearray->list ur)
area (vla-get-Area e )
)
(if (setq ss0 (ssget "_CP" (list ll (list (car ll)(cadr ur)) ur (list (car ur)(cadr ll))) (list (cons 0 "REGION"))))
(progn
(setq areaSS0 0 )
(foreach e1 (mapcar 'vlax-ename->vla-Object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss0))))
(if (not(equal e e1))(setq areaSS0 (+(vla-get-Area e1)areaSS0) ))
)
(if (equal areaSS0 area 0.001)
(setq ss1 (ssadd (vlax-vla-object->ename e) ss1))
)
)
)
); foreach
(if (>(sslength ss1)0)(sssetfirst nil ss1) )
); progn
); if
)

  • 0

#14 elleHCSC

elleHCSC

    biết lệnh copy

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

Đã gửi 11 August 2009 - 04:55 PM

Tks bac Gia_Bach nhiệt tình. Nhưng elle chạy thử trên bản vẽ của mình nó vẫn ko ra dc như yêu cầu nhỉ ?
file vẽ của mình đây:
http://www.cadviet.c...files/2/tv2.rar

có 198 region trên bản vẽ. Cần là tìm ra 6 cái region bao để xóa nó đi (đúng ở đây elle chỉ cần 192 region).
Tks !
  • 0
Share for all, all will share !

--------------------
HTTP://WWW.HCSC.VN
HTTP://WWW.HCSC.COM.VN