Chuyển đến nội dung
Diễn đàn CADViet
  • Thông báo

    • Nguyen Hoanh

      CADViet đã hoàn tất nâng cấp   14/09/2017

      Chào các bạn, CADViet đã hoàn tất việc nâng cấp lên phiên bản mới. Tất cả các chức năng đã hoạt động theo kỳ vọng của ban quản trị. Nếu có vấn đề gì cần phản hồi, các bản post ở đây nhé: Trân trọng, Nguyễn Hoành.
Jin Yong

Hỏi về Lisp (thuật toán, ý tưởng, coding,...)

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

Mục đích em hỏi đoạn lisp trên là để đưa thư mục đó vào Support File Searh Path mà.

Với lại còn phải cắt bớt đi một đoạn nửa.

Ý là có cách nào đọc được các thao tác khi chọn file và lưu thành chuổi hay không.

- Mình ko hiểu ý bạn lắm. nhưng thử dùng hàm (vl-filename-directory str) xem. nếu nó tìm thấy (Str) sẽ trả về đường dẫn đầy đủ (trừ file cuối cùng chứa phần mở rộng). Ví dụ (vl-filename-directory ".....duy/temp/hd6.txt") sẽ trả về kết quả là: ".....duy/temp/"

- Kết hợp hàm trên và hàm appload có thể bạn được đường dẫn đến tệp cuối cùng 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

Chào các bác.

Hôm nay, Tue_NV gặp phải 1 vấn đề rất lạ về vấn đề tìm giao điểm của 2 đối tượng. Rõ ràng là 2 đối tượng cắt nhau tại 2 điểm nhưng sau khi chạy Lisp -> thì nó chỉ báo có 1 giao điểm mà thôi. Thật kì lạ. Các bác có thể giải thích dùm Tue_NV được không? Mình cũng không hiểu là tại vì sao nữa?

Đây là file bị trường hợp tìm giao điểm giữa Line và Pline. Chúng cắt nhau tại 2 giao điểm nhưng tìm chỉ có được 1 giao điểm

Tìm 2 giao điểm nhưng chỉ tìm được 1 giao điểm

Lisp mà Tue_NV đang sử dụng là của bác Hoành

(defun c:giao ()
 (defun GiaoDT	(ent1 ent2)
   (setq ob1 (vlax-ename->vla-object ent1)
  ob2 (vlax-ename->vla-object ent2)
   )
   (setq g (vlax-variant-value
      (vla-IntersectWith ob1 ob2 acExtendNone)
    )
   )
   (if	(/= (vlax-safearray-get-u-bound g 1) -1)
     (setq g (vlax-safearray->list g))
     (setq g nil)
   )
   (if	g
     (progn
(setq kq nil
      sd (fix (/ (length g) 3))
)
(repeat	sd
  (setq	kq (append kq (list (list (car g) (cadr g) (caddr g))))
	g  (cdddr g)
  )
)
kq
     )
     nil
   )
 )
 (setq ent1 (car (entsel "\nVao dt1: ")))
 (redraw ent1 3)
 (setq ent2 (car (entsel "\nVao dt2: ")))
 (redraw ent1 4)
 (setq giao (giaodt ent1 ent2))
 (if giao
   (foreach pp	giao
     (entmake (list (cons 0 "POINT") (cons 10 pp)))
   )
   (alert "2 doi tuong khong giao nhau!")
 )
 (princ)
)

Các bác cho Tue_NV hỏi thêm 1 chút nữa là : Tại sao có 1 file bản vẽ khi sử dụng mã lệnh

(entget(car(entsel)))-> Khi pick vào 1 Polyline thì thấy mã DXF10 chỉ có toạ độ X và Y thôi, còn Z thì không có

 

Ví dụ : ((-1 . ) (0 . "LWPOLYLINE") (330 .

) (5 . "654") (100 . "AcDbEntity") (67 . 0) (410 .

"Model") (8 . "0") (100 . "AcDbPolyline") (90 . 3) (70 . 1) (43 . 0.0) (38 .

0.0) (39 . 0.0) (10 -86.629 -0.254102) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10

-62.472 -16.5098) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 -98.8554 -11.4853) (40 .

0.0) (41 . 0.0) (42 . 0.0) (210 0.0 0.0 1.0))

 

Muốn Lisp hiển thị cả Z nữa thì phải làm thế nào? Trong khi 1 số file khác có cả X, Y và Z. Cái này coi bộ đơn giản nhưng mà mình chưa được biết.

Đây là file dwg : http://www.mediafire.com/?17w8i5c9zgw3blq

Rất mong các bác chỉ giúp

Tue_NV xin chân thành cảm ơ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
Chào các bác.

Hôm nay, Tue_NV gặp phải 1 vấn đề rất lạ về vấn đề tìm giao điểm của 2 đối tượng. Rõ ràng là 2 đối tượng cắt nhau tại 2 điểm nhưng sau khi chạy Lisp -> thì nó chỉ báo có 1 giao điểm mà thôi. Thật kì lạ. Các bác có thể giải thích dùm Tue_NV được không? Mình cũng không hiểu là tại vì sao nữa?

Đây là file bị trường hợp tìm giao điểm giữa Line và Pline. Chúng cắt nhau tại 2 giao điểm nhưng tìm chỉ có được 1 giao điểm

Tìm 2 giao điểm nhưng chỉ tìm được 1 giao điểm

Lisp mà Tue_NV đang sử dụng là của bác Hoành

...................

Các bác cho Tue_NV hỏi thêm 1 chút nữa là : Tại sao có 1 file bản vẽ khi sử dụng mã lệnh

(entget(car(entsel)))-> Khi pick vào 1 Polyline thì thấy mã DXF10 chỉ có toạ độ X và Y thôi, còn Z thì không có

 

Ví dụ : ((-1 . ) (0 . "LWPOLYLINE") (330 .

) (5 . "654") (100 . "AcDbEntity") (67 . 0) (410 .

"Model") (8 . "0") (100 . "AcDbPolyline") (90 . 3) (70 . 1) (43 . 0.0) (38 .

0.0) (39 . 0.0) (10 -86.629 -0.254102) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10

-62.472 -16.5098) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 -98.8554 -11.4853) (40 .

0.0) (41 . 0.0) (42 . 0.0) (210 0.0 0.0 1.0))

 

Muốn Lisp hiển thị cả Z nữa thì phải làm thế nào? Trong khi 1 số file khác có cả X, Y và Z. Cái này coi bộ đơn giản nhưng mà mình chưa được biết.

Đây là file dwg : http://www.mediafire.com/?17w8i5c9zgw3blq

Rất mong các bác chỉ giúp

Tue_NV xin chân thành cảm ơn

1. Ừ, lisp chỉ cho 1 giao điểm ? Anh cũng chưa tìm đuợc nguyên nhân.

 

2. với LWPOLYLINE, Cad đưa cao độ vào DXF=38. (với 3DPOLYLINE thì khác)

Muốn Lisp hiển thị cả Z nữa thì kết hợp giữa DXF10 và 38.

  • 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

Chào các bác.

Hôm nay, Tue_NV gặp phải 1 vấn đề rất lạ về vấn đề tìm giao điểm của 2 đối tượng. Rõ ràng là 2 đối tượng cắt nhau tại 2 điểm nhưng sau khi chạy Lisp -> thì nó chỉ báo có 1 giao điểm mà thôi. Thật kì lạ. Các bác có thể giải thích dùm Tue_NV được không? Mình cũng không hiểu là tại vì sao nữa?

Đây là file bị trường hợp tìm giao điểm giữa Line và Pline. Chúng cắt nhau tại 2 giao điểm nhưng tìm chỉ có được 1 giao điểm

 

Đường LINE của Bạn có tọa độ z/=0.0 (10 791.935 -344.495 -1.0e-008) Bạn sửa lại tọa độ z, z=0.0 là đượ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
1. Ừ, lisp chỉ cho 1 giao điểm ? Anh cũng chưa tìm đuợc nguyên nhân.

 

2. với LWPOLYLINE, Cad đưa cao độ vào DXF=38. (với 3DPOLYLINE thì khác)

Muốn Lisp hiển thị cả Z nữa thì kết hợp giữa DXF10 và 38.

Cảm ơn anh gia_bach, cảm ơn bác DuongTrungHuy rất nhiều, thì ra nguồn gốc của cái này là sự không đồng phẳng. Lúc đó em sử dụng lệnh ID cho Line thì vẫn thấy Z=0.0 bình thường, thì ra là do sai số :lol:

 

Anh gia_bach, các bác có thể nói rõ hơn ý này được không?

Muốn Lisp hiển thị cả Z nữa thì kết hợp giữa DXF10 và 38.. Chỉ đơn giản là Tue_NV muốn sử dụng mã lệnh (entget(car(entsel))) thì Lisp cũng sẽ hiển thị tọa độ Z ở mã DXF10 như 1 số file trước đó. Mã DXF38 thì em chưa sử dụng đến bao giờ cả, vì sử dụng toàn là các file đều có hiển thị tọa độ Z, nay đụng phải mới biết là mình bí :lol:

 

Tue_NV chân thành cảm ơ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
Cảm ơn anh gia_bach, cảm ơn bác DuongTrungHuy rất nhiều, thì ra nguồn gốc của cái này là sự không đồng phẳng. Lúc đó em sử dụng lệnh ID cho Line thì vẫn thấy Z=0.0 bình thường, thì ra là do sai số :lol:

 

Anh gia_bach, các bác có thể nói rõ hơn ý này được không?

Muốn Lisp hiển thị cả Z nữa thì kết hợp giữa DXF10 và 38.. Chỉ đơn giản là Tue_NV muốn sử dụng mã lệnh (entget(car(entsel))) thì Lisp cũng sẽ hiển thị tọa độ Z ở mã DXF10 như 1 số file trước đó. Mã DXF38 thì em chưa sử dụng đến bao giờ cả, vì sử dụng toàn là các file đều có hiển thị tọa độ Z, nay đụng phải mới biết là mình bí :lol:

 

Tue_NV chân thành cảm ơn

Đính chính : Ý của anh là khi cần cao độ Z thì lấy DXF=38 (hay Property=Elevation).

Vì LWPOLYLINE là đối tuợng đồng phẳng, CAD đưa tọa độ các đỉnh duới dạng 2D(X,Y) và cao độ Z về 1 mã DXF cho database nhẹ.

Vì hàm entget chỉ hiển thị database, nên không thể hiển thị tọa độ 3D đuợc.

Muốn có tọa độ 3D : thì kết hợp giữa DXF10 và 38.

 

Nhân tiện các bác tham khảo Lệnh chèn POINT tại giao điểm của 2 Đối tuợng viết bằng AutoCAD .NET với MS Visual C#

http://www.cadviet.com/forum/index.php?sho...st&p=112765

  • 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
Đính chính : Ý của anh là khi cần cao độ Z thì lấy DXF=38 (hay Property=Elevation).

Vì LWPOLYLINE là đối tuợng đồng phẳng, CAD đưa tọa độ các đỉnh duới dạng 2D(X,Y) và cao độ Z về 1 mã DXF cho database nhẹ.

Vì hàm entget chỉ hiển thị database, nên không thể hiển thị tọa độ 3D đuợc.

Muốn có tọa độ 3D : thì kết hợp giữa DXF10 và 38.

 

Nhân tiện các bác tham khảo Lệnh chèn POINT tại giao điểm của 2 Đối tuợng viết bằng AutoCAD .NET với MS Visual C#

http://www.cadviet.com/forum/index.php?sho...st&p=112765

Xin bổ sung thêm là cao độ Z =DXF38 chỉ đúng khi DXF210=(0,0,1)

DXF38 là độ dài đại số của vector từ (0,0,0) của WCS đến mặt phẳng của Polyline, với vector đơn vị là DXF210

  • 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

Các bác cho em hỏi có đoạn code nào để tìm 1 RECTANG lớn nhất thuộc 1 block mà bên trong Rectang đó không chứa bất kỳ một đối tượng nào không 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
Các bác cho em hỏi có đoạn code nào để tìm 1 RECTANG lớn nhất thuộc 1 block mà bên trong Rectang đó không chứa bất kỳ một đối tượng nào không nhỉ!!!!

Hề hề hề,

Có đấy, nhưng bạn nên gửi file chứa block đó lên và thể hiện cái kết quả bạn muốn có nó ra răng thì mới có lisp được bạn ạ. 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
Download

 

cadviet.jpg

 

Đây là file up của e. E cần code lấy entname của cái Rectang màu vàng đó.

Chào bạn nguyentuyen6,

Bạn xài thử cái này nha, mình test trên file bạn gửi thì Ok còn đại trà thì chưa thử bạn ạ.

(defun c:slk (  / elb en els plst ss n i ssp en1 els1 ss1 dt  a b )
(vl-load-com)
(command "undo" "be")
(setq ent (car (entsel "\n Chon block chua khung "))
       elb (entget ent)
       en (cdr (assoc -2 (tblsearch "block" (cdr (assoc 2 elb )))))
       els (entget en)
       plst (list)        
) 
(foreach a els
      (if (= (car a) 10)
         (setq plst (append plst (list (cdr a))))
      )
)
(command "explode" ent )
(setq ss (ssget "wp" plst ))      
(setq n (sslength ss)
        i 0
        ssp (list)
)
      (while (                (setq en1 (ssname ss i)
                       els1 (entget en1)

               )
               (if (= (cdr (assoc 0 els1)) "LWPOLYLINE")
                  (progn
                  (setq  plst (list))
                  (foreach b els1
                         (if (= (car b ) 10)
                             (setq  plst (append plst (list (cdr b ))))
                         )
                   )
                   (setq ss1 (ssget "wp" plst))
                   (if (= ss1 nil)
                       (progn
                       (setq obj (vlax-ename->vla-object en1))
                       (setq dt (vlax-curve-getarea obj))
                       (setq ssp (append ssp (list (list dt en1))))
                       )
                   )
                   )
               )
               (setq i (1+ i))
       )
ssp
(command "undo" "e")
(setq ssp (vl-sort ssp '(lambda (x1 x2) (>= (car x1) (car x2)))))
(setq edt (cadr (car ssp)))
(command "undo" 1)
edt
)

Nếu có gì chưa ổn hãy post lên 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
Chào bạn nguyentuyen6,

Bạn xài thử cái này nha, mình test trên file bạn gửi thì Ok còn đại trà thì chưa thử bạn ạ.

(defun c:slk (  / elb en els plst ss n i ssp en1 els1 ss1 dt  a b )
(vl-load-com)
(command "undo" "be")
(setq ent (car (entsel "\n Chon block chua khung "))
       elb (entget ent)
       en (cdr (assoc -2 (tblsearch "block" (cdr (assoc 2 elb )))))
       els (entget en)
       plst (list)        
) 
(foreach a els
      (if (= (car a) 10)
         (setq plst (append plst (list (cdr a))))
      )
)
(command "explode" ent )
(setq ss (ssget "wp" plst ))      
(setq n (sslength ss)
        i 0
        ssp (list)
)
      (while (                (setq en1 (ssname ss i)
                       els1 (entget en1)

               )
               (if (= (cdr (assoc 0 els1)) "LWPOLYLINE")
                  (progn
                  (setq  plst (list))
                  (foreach b els1
                         (if (= (car b ) 10)
                             (setq  plst (append plst (list (cdr b ))))
                         )
                   )
                   (setq ss1 (ssget "wp" plst))
                   (if (= ss1 nil)
                       (progn
                       (setq obj (vlax-ename->vla-object en1))
                       (setq dt (vlax-curve-getarea obj))
                       (setq ssp (append ssp (list (list dt en1))))
                       )
                   )
                   )
               )
               (setq i (1+ i))
       )
ssp
(command "undo" "e")
(setq ssp (vl-sort ssp '(lambda (x1 x2) (>= (car x1) (car x2)))))
(setq edt (cadr (car ssp)))
(command "undo" 1)
edt
)

Nếu có gì chưa ổn hãy post lên nhé.

Chào bác Bình. Đúng là chưa ổn thiệt. Cái Entity mà bác Lấy đó là đối tượng mà bác đã Explode ra. và bác đã xoa nó bằng lệnh undo

 

Bác kiểm tra lại code 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
Chào bạn nguyentuyen6,

Bạn xài thử cái này nha, mình test trên file bạn gửi thì Ok còn đại trà thì chưa thử bạn ạ.

(defun c:slk (  / elb en els plst ss n i ssp en1 els1 ss1 dt  a b )
(vl-load-com)
(command "undo" "be")
(setq ent (car (entsel "\n Chon block chua khung "))
       elb (entget ent)
       en (cdr (assoc -2 (tblsearch "block" (cdr (assoc 2 elb )))))
       els (entget en)
       plst (list)        
) 
(foreach a els
      (if (= (car a) 10)
         (setq plst (append plst (list (cdr a))))
      )
)
(command "explode" ent )
(setq ss (ssget "wp" plst ))      
(setq n (sslength ss)
        i 0
        ssp (list)
)
      (while (< i n)
               (setq en1 (ssname ss i)
                       els1 (entget en1)

               )
               (if (= (cdr (assoc 0 els1)) "LWPOLYLINE")
                  (progn
                  (setq  plst (list))
                  (foreach b els1
                         (if (= (car b ) 10)
                             (setq  plst (append plst (list (cdr b ))))
                         )
                   )
                   (setq ss1 (ssget "wp" plst))
                   (if (= ss1 nil)
                       (progn
                       (setq obj (vlax-ename->vla-object en1))
                       (setq dt (vlax-curve-getarea obj))
                       (setq ssp (append ssp (list (list dt en1))))
                       )
                   )
                   )
               )
               (setq i (1+ i))
       )
ssp
(command "undo" "e")
(setq ssp (vl-sort ssp '(lambda (x1 x2) (>= (car x1) (car x2)))))
(setq edt (cadr (car ssp)))
(command "undo" 1)
edt
)

Nếu có gì chưa ổn hãy post lên nhé.

Đúng là chưa ổn Bác ạ. Trong trường hợp này không dùng quay ngược thời gian được.

Bác nên duyệt qua block để lấy tên lấy điểm chèn rồi explode ra xong lại block lại như cũ là đượ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
Chào bác Bình. Đúng là chưa ổn thiệt. Cái Entity mà bác Lấy đó là đối tượng mà bác đã Explode ra. và bác đã xoa nó bằng lệnh undo

 

Bác kiểm tra lại code nhé.

Hề hề hê,

Chào bác Tue_NV,

Quả có vậy thiệt, do mình cứ nghĩ là trước hay sau explode thì cái ename của đối tượng vẫn không thay đổi. Mình sẽ kiểm tra lại theo cách khác xem. Vấn đề của nó còn là chạy trên bản vẽ của bạn nguyentuyen6 thì nó trả ra đối tượng được , nhưng khi insert một block khác vô thì nó lại chết ngoéo không chịu chạy, mình đang kiểm tra mà chưa phát hiện lỗi bác ạ.

Thank bác đã giúp đỡ.

@bác Phamngoctukts: Có nhẽ mình sẽ kiếm cách khác chứ không chơi thằng explode nữa bá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
Download

 

cadviet.jpg

 

Đây là file up của e. E cần code lấy entname của cái Rectang màu vàng đó.

Bạn nguyentuyen6, ơi,

Chu choa mình ngu quá, trong lisp đã có sẵn hàm nentsel cho phép bạn truy xuất ename của các đối tượng nằm trong block mà mình quên béng đi nên sinh ra cái củ chả giống ai.

Bạn chỉ cần đơn giản là:

nhập : (setq ent (car (nentsel ))) vào dòng command.

Sau đó enter và chọn vào đối tượng khung màu vàng của bạn là nó cho bạn cái ename của khung liền mà.

Hề hề hề, chúc bạn vui.

  • 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 nguyentuyen6, ơi,

Chu choa mình ngu quá, trong lisp đã có sẵn hàm nentsel cho phép bạn truy xuất ename của các đối tượng nằm trong block mà mình quên béng đi nên sinh ra cái củ chả giống ai.

Bạn chỉ cần đơn giản là:

nhập : (setq ent (car (nentsel ))) vào dòng command.

Sau đó enter và chọn vào đối tượng khung màu vàng của bạn là nó cho bạn cái ename của khung liền mà.

Hề hề hề, chúc bạn vui.

Cái này cũng có thể dúng hàm nentselp cũng được bác ạ. Nhưng yêu cầu ở đây là tìm hình chữ nhật lớn nhất trong Block mà trong nó không chứa đối tượng nào???

Cái trên chỉ đúng khi biết được bằng mắt thường thôi, chứ Lisp đâu có "mắt". Mình tìm cách gắn "mắt" cho nó bác ạ. :lol:

  • 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

Hì hì. cảm ơn bác đã giúp e. Nhưng hàm entsel này mình phải có động tác chọn chính xác nó bác ạ. Ý em là chỉ cần entname của cái block thì nó sẽ trả về Rectang to nhất thuộc block đó mà bên trong rectang này không chứa bất kỳ đối tượng nào cả. Dùng nentsel cũng đc nhưng nó sẽ làm e phải thêm một bước chọn cái rectang đó>> không tiện.

Nghĩa là tạo 1 defun có đối số là entname của block. kqua trả về là entname của rectang kia.

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
Đúng là chưa ổn Bác ạ. Trong trường hợp này không dùng quay ngược thời gian được.

Bác nên duyệt qua block để lấy tên lấy điểm chèn rồi explode ra xong lại block lại như cũ là được.

Không sử dụng cách này được vì chưa thể lấy được Entity của đa giác lớn nhất không chứa đối tượng nào trong Block. Lý do như bác Bình đã nói

 

Hề hề hê,

Chào bác Tue_NV,

Quả có vậy thiệt, do mình cứ nghĩ là trước hay sau explode thì cái ename của đối tượng vẫn không thay đổi. Mình sẽ kiểm tra lại theo cách khác xem. Vấn đề của nó còn là chạy trên bản vẽ của bạn nguyentuyen6 thì nó trả ra đối tượng được , nhưng khi insert một block khác vô thì nó lại chết ngoéo không chịu chạy, mình đang kiểm tra mà chưa phát hiện lỗi bác ạ.

Thank bác đã giúp đỡ.

@bác Phamngoctukts: Có nhẽ mình sẽ kiếm cách khác chứ không chơi thằng explode nữa bác ạ......

Ta vẫn cứ chơi với bạn Explode bác ạ. Vì có bạn Explode thì bác mới chứng tỏ được trong đa giác lớn nhất đó không chứa đối tượng nào. Thể hiện qua code dưới đây :

Các bác thử nhé :

(defun c:gblk(/ plst Ld Ldent blk xp s p e )
(vl-load-com)
(setq plst '() Ld '() ldent '())
(setq blk (car(entsel"\n Chon Block :")))
(if (vl-cmdf "copy" blk "" '(0 0 0) "@")
	(setq xp (acet-explode (entlast)))
)
    (command ".UNDO" "BE") 
    (setq s (cdr (assoc 2 (entget blk))))
    (setq p (cdr (assoc 10 (entget blk))))
            (setq e (cdr (assoc -2 (tblsearch "BLOCK" s))))
            (while e
                (setq el (entget e))
	(setq plst (append plst (list e)))
	(setq dsd (mapcar 'cdr (vl-remove-if '(lambda(y) (/= (car y) 10)) (entget e))))
	(setq Ld '())
	(FOREACH x dsd 
	    (setq Ld (append Ld (list (list (+ (car x) (car p)) (+ (cadr x) (cadr p)) ))))
	)
	(if (and (wcmatch (cdr(assoc 0 el)) "*POLYLINE")
		 (>= (cdr(assoc 90 el)) 3)
		 (vlax-curve-isClosed e)
		 (null (ssget "WP" Ld))
	    )
		 (setq Ldent (append Ldent (list e)))
	)

                (setq e (entnext e))  
            )
(if (> (length Ldent) 0)
 (progn
(setq Ldent (vl-sort Ldent '(lambda(x y) (> (vla-get-area (vlax-ename->vla-object x)) 
					   (vla-get-area (vlax-ename->vla-object y))
					)
			   )
	     ))
   (alert (strcat "Da giac lon nhat ma trong do khong chua doi tuong nao" 
	(vl-princ-to-string (list(car Ldent)))))
 )
   (alert "Khong co Da giac lon nhat ma trong do khong chua doi tuong nao")
)

   (command "erase" xp "")
    (command ".UNDO" "E")
)

  • 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
E test thử và lsp chạy không đúng bác ợ. hihi. Entity name thì ra, nhưng mà chưa đúng

Theo mình nghĩ thì bạn lấy entityname của cái rectang đó để lấy toạ độ đỉnh thôi đúng không. Nếu đúng thì có thể áp dụng cách thứ nhất của bác Bình sau khi đã lấy được toạ độ đỉnh thì undo lại. Nếu không phải thì bạn có thể nêu bạn lấy entity của rectang đó làm gì được khô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
Theo mình nghĩ thì bạn lấy entityname của cái rectang đó để lấy toạ độ đỉnh thôi đúng không. Nếu đúng thì có thể áp dụng cách thứ nhất của bác Bình sau khi đã lấy được toạ độ đỉnh thì undo lại. Nếu không phải thì bạn có thể nêu bạn lấy entity của rectang đó làm gì được không.

Đúng như bác nghĩ. hehe. E muốn lấy dùng hàm acet-ent-geomextents:diem thap nhat trai va cao nhat phai

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
E test thử và lsp chạy không đúng bác ợ. hihi. Entity name thì ra, nhưng mà chưa đúng

Bạn test thử chưa?

Tue_NV đổi độ rrộng của đa giác tìm được cho bạn dễ thấy nhé :

Đa giác tìm được đổi thành độ rộng 100 -> OK


(defun c:gblk(/ plst Ld Ldent blk xp s p e )
(vl-load-com)
(setq plst '() Ld '() ldent '())
(setq blk (car(entsel"\n Chon Block :")))
(if (vl-cmdf "copy" blk "" '(0 0 0) "@")
	(setq xp (acet-explode (entlast)))
)
    (command ".UNDO" "BE") 
    (setq s (cdr (assoc 2 (entget blk))))
    (setq p (cdr (assoc 10 (entget blk))))
            (setq e (cdr (assoc -2 (tblsearch "BLOCK" s))))
            (while e
                (setq el (entget e))
	(setq plst (append plst (list e)))
	(setq dsd (mapcar 'cdr (vl-remove-if '(lambda(y) (/= (car y) 10)) (entget e))))
	(setq Ld '())
	(FOREACH x dsd 
	    (setq Ld (append Ld (list (list (+ (car x) (car p)) (+ (cadr x) (cadr p)) ))))
	)
	(if (and (wcmatch (cdr(assoc 0 el)) "*POLYLINE")
		 (>= (cdr(assoc 90 el)) 3)
		 (vlax-curve-isClosed e)
		 (null (ssget "WP" Ld))
	    )
		 (setq Ldent (append Ldent (list e)))
	)

                (setq e (entnext e))  
            )
(if (> (length Ldent) 0)
 (progn
(setq Ldent (vl-sort Ldent '(lambda(x y) (> (vla-get-area (vlax-ename->vla-object x)) 
					   (vla-get-area (vlax-ename->vla-object y))
					)
			   )
	     ))	
(vla-put-ConstantWidth (vlax-ename->vla-object (car Ldent)) 100)
   (alert (strcat "Da giac lon nhat ma trong do khong chua doi tuong nao" 
	(vl-princ-to-string (list(car Ldent)))))
 )
   (alert "Khong co Da giac lon nhat ma trong do khong chua doi tuong nao")
)
   (command "ReGEN")
   (command "erase" xp "")
    (command ".UNDO" "E")
)

  • 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

Đúng rồi bác a, đc rồi!!Lúc chiều E test rồi!!! tại khi em vào trong block dùng hàm (entsel) để xem lại cái entname của cái rectang ý thì nó lại cho khác với cái thông báo của bác. Tại sao vậy 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
Đúng rồi bác a, đc rồi!!Lúc chiều E test rồi!!! tại khi em vào trong block dùng hàm (entsel) để xem lại cái entname của cái rectang ý thì nó lại cho khác với cái thông báo của bác. Tại sao vậy bác nhở??

Nếu đúng là bạn chỉ cần lấy toạ độ của cái rectang đó thôi thì có nhiều cách đơn giản hơn nhiều. Lúc tạo block bạn gán cho nó một layer khác đi. ngay sau khi explode bạn dùng (ssget "p" (list (cons 0 "lwpolyline") (cons 8 "layer"))) sẽ được cái selectionset của thằng rectang đó. Sau đó lấy toạ độ, sau khi lấy toạ độ thì undo lại. Mình nghĩ như vậy code sẽ ngắn hơn rất nhiều và tiện cho việc quản lý lisp của bạ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
Đúng rồi bác a, đc rồi!!Lúc chiều E test rồi!!! tại khi em vào trong block dùng hàm (entsel) để xem lại cái entname của cái rectang ý thì nó lại cho khác với cái thông báo của bác. Tại sao vậy bác nhở??

Chào bạn nguyentuyen6,

Loay hoay hoài mình mới ra được cái củ..... lisp này. Bạn xài thử xem có ngon không hỉ????

(defun c:slk (  / )
(vl-load-com)

(setq ent (car (entsel "\n Chon block chua khung "))
       elb (entget ent)
       en (cdr (assoc -2 (tblsearch "block" (cdr (assoc 2 elb )))))
       els (entget en)
       plst (list) 
       en1 (entnext en) 
       pg (cdr (assoc 10 elb))      
) 
(while (/= en1 nil)
      (setq els1 (entget en1))
      (if (= (cdr (assoc 0 els1)) "LWPOLYLINE")
          (progn
                  (setq obj (vlax-ename->vla-object en1)
                          dt (vlax-curve-getarea obj)
                          plst (append plst (list (list dt en1)))
                  )
          )
       )
       (setq en1 (entnext en1))
)
(setq plst (vl-sort plst '(lambda (x1 x2) (>= (car x1) (car x2)))))
;;;;;;;;;;(setq enk (cadr (car (cddddr plst))))
(setq ssp (list)
       m (length plst) 
       j 0
)        
(while (     (command "undo" "be")   
    (setq en2 (nth j plst)
            els2 (entget (cadr en2))
            pll (list)

    )
    (foreach a els2
                (if (= (car a) 10)
                   (progn
                   (setq pt (trans (cdr a) ent 0))
                   (setq pt (list (+ (car pt) (car pg)) (+ (cadr pt) (cadr pg)) (+ (caddr pt) (caddr pg))))
                   (setq pll (append pll (list pt )))
                   )
                )
    )
    (command "explode" ent)
    (if (= (setq ss (ssget "wp" pll)) nil)
        (setq ssp (append ssp (list en2)))
    )
    (command "undo" "e")
    (command "undo" 1)
    (setq j (1+ j))
)
(setq ssp (vl-sort ssp '(lambda (y1 y2) (> (car y1) (car y2)))))
(setq enk (cadr (car ssp)))
enk
)

 

Thực tình ban đầu mình định không xài kiểu explode nữa, xong khổ nỗi bạn lại yêu cầu là không chứa đối tượng nào bên trong, thế nên nghĩ hoài chả được cách kiểm tra khi block không bị phá. Bởi vì khi đó toàn bộ khung chỉ có một đối tượng duy nhất. Thế nên cuối cùng lại phải dùng cách củ chuối ấy vậy.

Đến đ6ay lại vướng vì nếu chỉ ở cái bản vẽ bạn post thì Ok ngay nhưng khi insert các khung khác vô thì nó lại không ra. Tìm hoài mới vỡ ra là thằng cu LWPOLYLINE khi trả ra tọa độ đỉnh ở mã DXF10 thì nó trả tọa độ theo hệ tọa độ của đối tượng bạn ạ. Vậy là lại phải bổ sung thêm cái tọa độ của điểm insert block nữa mới ok. Khổ thế, nhưng đúng là cái khó nó lại ló được tí khôn bạn ạ.....

Hy vọng bạn hài lòng vời cái củ lisp này.

 

Mình chưa xem kỹ cái củ của bác Tue_NV cho bạn xong hy vọng cái củ ấy ngon hơn cái của mình và mình sẽ mót thêm được tí gì của bác ấy. Hề hề hề....

 

Bạn dùng hàm entsel thì không thể lấy được các ename của các phần tử bên trong block bạn ạ. Phải dùng hàm nentsel mới được bạ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

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


×