Chuyển đến nội dung
Diễn đàn CADViet
heocon0_0

Lisp nối Line thành Pline ?

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

Nhân đề nghị của anh 2 lúa cad nông dân bên trên tôi làm thêm 1 bước nữa, chỉ cần đánh lệnh test nó sẽ tự động nối line,arc.

Nhưng tôi chưa có file line arc số lượng lớn để test, bạn nào có file lớn đưa lên để test thử. File lisp như sau:

 

 

(defun c:test(/ kc L1 L2 tieptuc tm1 tm2 tm ng obj)
  (defun noithem(d v kc tr / tm tm1)
    (if (setq tm (car (vl-remove nil
(mapcar '(lambda(x) (if (and (/= v (cadar x))
    (or (<= (distance d (car x)) kc) (<= (distance d (last x)) kc))) x nil)) L1))))
    (if (or (and tr (<= (distance d (car tm)) kc)) 
            (and (not tr) (<= (distance d (last tm)) kc)))
    (setq ng t tm1 (reverse tm))
    (setq ng nil tm1 tm)))
  )
  
  (defun ssfrom (sl / ss0) (setq ss0 (ssadd)) (foreach v sl (ssadd v ss0)) ss0)
  ;;;
  (setq kc (getreal "\nNhap khoang ho cho phep de noi:")
L1 (mapcar '(lambda(x) (list (vlax-curve-getStartPoint (setq obj (vlax-ename->vla-object x))) x
(vlax-curve-getEndPoint obj))) (acet-ss-to-list (ssget "X" '((0 . "LINE,ARC")))))
L2 (list (car L1))
L1 (cdr L1))
  (setvar "cmdecho" 0)
  (while L1
    (setq tieptuc t)
    (while tieptuc      
      (if (setq tm1 (noithem (caar L2) (cadar L2) kc t))
        (setq L2 (cons tm1 L2) L1 (vl-remove (if ng (reverse tm1) tm1) L1)))
      (if (setq tm2 (noithem (last (last L2)) (cadr (last L2)) kc nil))
        (setq L2 (append L2 (list tm2)) L1 (vl-remove (if ng (reverse tm2) tm2) L1)))
      (if (and (not tm1)(not tm2))
(setq tieptuc nil
     tm (COMMAND ".PEDIT" "M" (ssfrom (mapcar 'cadr L2)) ""  "Y" "J" kc "")
     L2 (list (car L1))
     L1 (cdr L1)))
    )
  )
  (setvar "cmdecho" 1)
)
 
  • 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

hehe, nhiều khi không thể nối được với lệnh PEDIT, kể cả đã nhập khoảng hở lớn (File ví dụ ở #38). Vì vậy, liệu có thể nối các PLINE, LINE và ARC mà không dùng lệnh PEDIT 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

hehe, nhiều khi không thể nối được với lệnh PEDIT, kể cả đã nhập khoảng hở lớn (File ví dụ ở #38). Vì vậy, liệu có thể nối các PLINE, LINE và ARC mà không dùng lệnh PEDIT không?

Ở #38 thì DXF 210 của đường vàng là default  (210 0.0 0.0 1.0), trong lúc của đường đỏ là (210 0.0 0.0 -1.0).

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

File ví dụ ở #38 thì đúng như bác Bình nói, nên không nối được.

Chẳng có cách nào mà không dùng pedit để tạo pline, trừ khi bạn xoá hết rồi entmake cái giống y vậy, nhưng làm thế thì tự chui đầu vào mớ bòng bong rồ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

2 cái vàng đỏ trong #38 không cùng nằm trong 1 hệ trục toạ độ, cho nên 2 đỉnh cuối của nó tuy mắt mình thấy trùng nhưng trong dxf data của nó cách nhau rất xa ~51000 và ~-51000 nên không thể nối đc là vì vậy.

-510941.0 
1.77214e+006

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

File ví dụ ở #38 thì đúng như bác Bình nói, nên không nối được.

Chẳng có cách nào mà không dùng pedit để tạo pline, trừ khi bạn xoá hết rồi entmake cái giống y vậy, nhưng làm thế thì tự chui đầu vào mớ bòng bong rồi.

Mình tin là có thể làm được, với thuật toán như sau:

1. Khoanh vùng chọn (0 . "*LINE,ARC").

2. Convert tất cả các đối tượng không phải là Lwpolyline thành Lwpolyline (bằng lệnh Pedit hoặc Convert hoặc entmake).

3. Lấy ra một Lwpolyline.

4. Tách riêng mã DXF của đối tượng đó ra thành 3 nhóm ds1, ds2 và ds3

  (Trong đó ds2 chứa thông tin các mã 10, 40, 41, 42 của tất cả các đỉnh), ds1 và ds3 và phần còn lại trước và sau của ds2

5. Xử lý ds2 bằng cách thêm vào tất cả các đỉnh của tất cả các đối tượng còn lại.

6. Xóa hết đối tượng chọn, ngoại trừ đối tượng lấy mã DXF

7. Entmod ds1+ds2+ds3.

 

Vấn đề khó nhất nằm ở chỗ sắp xếp các điểm trong ds2 theo kiểu End-to-End.

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

 

2 cái vàng đỏ trong #38 không cùng nằm trong 1 hệ trục toạ độ, cho nên 2 đỉnh cuối của nó tuy mắt mình thấy trùng nhưng trong dxf data của nó cách nhau rất xa ~51000 và ~-51000 nên không thể nối đc là vì vậy.

-510941.0 
1.77214e+006

Mình nghĩ là AutoCAD hiểu được 2 điểm này trùng nhau. Vui lòng xem ảnh.

118851_222.gif

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

 

2 cái vàng đỏ trong #38 không cùng nằm trong 1 hệ trục toạ độ, cho nên 2 đỉnh cuối của nó tuy mắt mình thấy trùng nhưng trong dxf data của nó cách nhau rất xa ~51000 và ~-51000 nên không thể nối đc là vì vậy.

-510941.0 
1.77214e+006

Hề hề hề,

Có cái lạ là khi view, dù xoay view kiểu gì thì hai đường này vẫn dính nhau. nhân tiện mọi người có ai rành về cái mã dxf 210 này xin giải thích giùm

Khi mình dùng subst để thay thế mã dxf 210 của nó về (210 0.0 0.0 -1.0) thì thằng cu này biến mất khỏi màn hình dù zoom all cũng chả thấy nó đâ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

Mình tin là có thể làm được, với thuật toán như sau:

1. Khoanh vùng chọn (0 . "*LINE,ARC").

2. Convert tất cả các đối tượng không phải là Lwpolyline thành Lwpolyline (bằng lệnh Pedit hoặc Convert hoặc entmake).

3. Lấy ra một Lwpolyline.

4. Tách riêng mã DXF của đối tượng đó ra thành 3 nhóm ds1, ds2 và ds3

  (Trong đó ds2 chứa thông tin các mã 10, 40, 41, 42 của tất cả các đỉnh), ds1 và ds3 và phần còn lại trước và sau của ds2

5. Xử lý ds2 bằng cách thêm vào tất cả các đỉnh của tất cả các đối tượng còn lại.

6. Xóa hết đối tượng chọn, ngoại trừ đối tượng lấy mã DXF

7. Entmod ds1+ds2+ds3.

 

Vấn đề khó nhất nằm ở chỗ sắp xếp các điểm trong ds2 theo kiểu End-to-End.

Lấy ví dụ ở bản vẽ mà Polime gởi lên:

Tại điểm mà Polime gọi là trùng nhau đấy, mã 10 của chúng khác nhau xa vời, mặc dầu ID là giống nhau, bởi mỗi thứ được xét trong 1 hệ tọa độ khác nhau. Suy ra, nếu đơn thuần chỉ lấy mã 10 gộp lại để entmod hay entmake thì không thể được.

Phải có cách khác thôi. Và tôi cũng đang hy vọng là có thể đượ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

oh, thật là kỳ lạ! Đúng là mã 10 của nó khác xa nhau, nhưng lệnh ID vẫn trả về cùng một giá trị!

Có lẽ do hai vectơ chỉ hướng đối xứng nhau (210 0 0 1) và (210 0 0 -1) nên dẫn đến tọa độ X ngược dấu nhau.

Như vậy, ngoài mã 10 phải xét đến cả vectơ chỉ hướng nữa.

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ân đề nghị của anh 2 lúa cad nông dân bên trên tôi làm thêm 1 bước nữa, chỉ cần đánh lệnh test nó sẽ tự động nối line,arc.

Nhưng tôi chưa có file line arc số lượng lớn để test, bạn nào có file lớn đưa lên để test thử. File lisp như sau:

 

 

(defun c:test(/ kc L1 L2 tieptuc tm1 tm2 tm ng obj)
  (defun noithem(d v kc tr / tm tm1)
    (if (setq tm (car (vl-remove nil
(mapcar '(lambda(x) (if (and (/= v (cadar x))
    (or (<= (distance d (car x)) kc) (<= (distance d (last x)) kc))) x nil)) L1))))
    (if (or (and tr (<= (distance d (car tm)) kc)) 
            (and (not tr) (<= (distance d (last tm)) kc)))
    (setq ng t tm1 (reverse tm))
    (setq ng nil tm1 tm)))
  )
  
  (defun ssfrom (sl / ss0) (setq ss0 (ssadd)) (foreach v sl (ssadd v ss0)) ss0)
  ;;;
  (setq kc (getreal "\nNhap khoang ho cho phep de noi:")
L1 (mapcar '(lambda(x) (list (vlax-curve-getStartPoint (setq obj (vlax-ename->vla-object x))) x
(vlax-curve-getEndPoint obj))) (acet-ss-to-list (ssget "X" '((0 . "LINE,ARC")))))
L2 (list (car L1))
L1 (cdr L1))
  (setvar "cmdecho" 0)
  (while L1
    (setq tieptuc t)
    (while tieptuc      
      (if (setq tm1 (noithem (caar L2) (cadar L2) kc t))
        (setq L2 (cons tm1 L2) L1 (vl-remove (if ng (reverse tm1) tm1) L1)))
      (if (setq tm2 (noithem (last (last L2)) (cadr (last L2)) kc nil))
        (setq L2 (append L2 (list tm2)) L1 (vl-remove (if ng (reverse tm2) tm2) L1)))
      (if (and (not tm1)(not tm2))
(setq tieptuc nil
     tm (COMMAND ".PEDIT" "M" (ssfrom (mapcar 'cadr L2)) ""  "Y" "J" kc "")
     L2 (list (car L1))
     L1 (cdr L1)))
    )
  )
  (setvar "cmdecho" 1)
)
 

:D :D :D

Đây là file ví dụ:

http://www.cadviet.com/upfiles/3/110802_hoankiempart1.rar

http://www.cadviet.com/upfiles/3/110802_hoankiempart2.rar

2 lúa chỉ cần gõ lệnh, chọn option thì sẽ tự động nối. 

Việc line, arc nào là lề đường, line arc nào là thửa tất nhiên 2 lúa sẽ tự lo;

 

2 lúa đề xuất cái này như 1 dạng option, không phải là 1 lisp riêng. 

Vì nhiều bạn vẫn cần lisp có thể pick được từng line rồi nối lại.

Riêng 2 lúa lại cần tổng thể hơn một chút.

 

Với lisp đã có sẵn, 2 lúa thấy nó chạy rất ổn.

Nhưng với file như trên, 2 lúa phải tốn thêm khoảng 30 ngày mới có thể pick hết các line. :D

:D :D :D

  • Vote giảm 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

Thực sự về mặt vị trí thì nó trùng nhau, nhưng về cơ sở dữ liệu thì khác nhau xa. Cad chỉ quản lý số liệu thôi chứ nó không có khái niệm trùng hay không. Có thể dùng hàm trans để chuyển đổi các điểm về WCS thì ct vẫn nhận ra 2 vật kề nhau, nhưng khi dùng lệnh pedit thì không được, vì trong data của cad hiểu là nó quá xa nhau. 

Bạn thử dùng trans để chuyển ds2 của cái đường đó về WCS xem sao.

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ới bản vẽ Polime gởi lên:

Bạn lần lượt cho vào command 3 dòng code sau:

 

(command "._UCS" "_FRONT")

(command "._MIRROR" "_SI" (ssget"X"'((210 0 0 -1))) '(0 0)'(1 0)"_YES")
(command "._UCS" "_PREVIOUS")

Bây giờ có thể PEDIT.

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ới bản vẽ Polime gởi lên:

Bạn lần lượt cho vào command 3 dòng code sau:

 

(command "._UCS" "_FRONT")

(command "._MIRROR" "_SI" (ssget"X"'((210 0 0 -1))) '(0 0)'(1 0)"_YES")

(command "._UCS" "_PREVIOUS")

Bây giờ có thể PEDIT.

Thì nó cũng như endmod với 2 mã 10 và 210 thôi mà! Mình đọc trong Help của AutoCAD nhưng phần nói về mã 210 rất ít.

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

Thì nó cũng như endmod với 2 mã 10 và 210 thôi mà! Mình đọc trong Help của AutoCAD nhưng phần nói về mã 210 rất ít.

Vậy thì bạn cứ thử làm như chữ "cũng như" đi xem nó ra cái gì 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

Những trị số dxf 10 khi lấy bằng hàm entget đều là ở tọa đô hệ trục WCS.

Khi cad muốn thể hiện vị trí thực của 1 điểm pt  nào đó trên màn hình nó sẽ sử dụng hàm trans như sau :

 

(trans pt 0 '(0.0 0.0 -1.0))

 

trong đó số 0  là tham số chỉ  hệ WCS, còn  '(0.0 0.0 -1.0) chính là cái nằm sau dxf 210 trong entget.

Khi đó nó sẽ cho ra vị trí của điểm trên màn hình (là vị trí mà bạn rê tới rê lui đó). Nhưng thực chất nó nằm tận đâu đâu nếu bạn đổi dxf 210, khi đó nó là vị trí thực trong hệ WCS . 

 

Cái hàm trans trên cũng cho ra trị số tương đương với trị của các hàm vlax-curve-getStartPoint và Endpoint và đó là tọa độ điểm trên màn hình. Nhưng khi pedit thì cad chỉ dùng trị số trong entget cho nên vị trí thật quá xa không nối đượ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ạn dùng hàm này có thể giữ cho cái arc của bạn nằm im không bị văng đi mất sau khi đổi dxf 210.

Trị số dxf 10 thì ok, nhưng còn dxf 42 nếu giữ nguyên thì arc sẽ bị ngược. Tôi lấy giá trị ngược dấu thì nó ok, nhưng tôi không chắc lắm lấy như vậy có đúng không. Bạn thử kiếm thêm vài đối tượng arc để test.

 

 

(defun doiucs(v / L tm)
  (setq L (entget v))
  (entmod (subst '(210 0.0 0.0 1.0) (setq tm (assoc 210 L))
(mapcar '(lambda(x) (cond ((= 10 (car x)) (cons 10 (trans (cdr x) (cdr tm) 0)))
 ((and (= 42 (car x)) (/= 0 (cdr x))) (cons 42 (- (cdr x))))
 (t x))) L)))
)

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ái này đổi UCS mọi đối tượng có DXF 210 là (210 0 0 -1):


(defun C:HA ( / ss)
 (if (setq ss (ssget (list '(210 0 0 -1))))
  (command "ucs" "3p" (trans '(0 0 0) 0 1) (trans '(0 1 0) 0 1) (trans '(0 0 1) 0 1) "mirror" ss "" '(0 0 0) '(1 0 0) "y" "ucs" "p")))
 

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

@Polyline : Cám ơn lời khen của bạn, cũng chẳng phải uyên bác gì đâu. Trước khi trả lời topic này thật sự tôi cũng chẳng biết gì về dxf 210 ( vì có bao giờ đụng tới nó đâu). Nhưng cái gì không biết thì hỏi google, trang trong nước không có thì vào trang nước ngoài, tìm hiểu rồi test, thấy ok thì post lên thô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

Lệnh PEDIT chỉ nối được các đối tượng nằm trên cùng 1 mp.

CAD xem các đối tượng có DXF 210 = (0,0,-1) không cùng mp Oxy của WCS vì hướng của các vector pháp tuyến khác nhau.

Hệ tọa độ OCS được xác định từ vector đơn vị Oz trong DXF 210 và các thành phần khác trong DXF 10, 11, 38...( tùy loại đối tượng)

Cách xác định gốc tọa độ và 2 vector đơn vị còn lại tôi đã đọc nhưng vì Lisp đã có hàm convert nên tôi cũng không nghiên cứu thêm (chưa rãnh để tìm lại link).

Lisp của bạn Tot77:

- Không dùng được cho các đối tượng khác như LINE, ARC ...

- Sai khi DXF 38 /= 0

Lisp của bạn Doan Van Ha:

- Đổi cả các đối tượng không mong muốn như Block

- Sai khi các đối tượng nằm ngoài mp Oxy hoặc block có chứa đối tượng nằm ngoài mp Oxy của WCS

- UCS + MIRROR + UCS  <=> MIRROR3D

  • 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

http://www.cadviet.com/upfiles/4/137702_drawing1.dwgEm xin nhờ anh chị viết hộ lisp tạo đường pline bao vùng giới hạn tạo bởi các line và pline cắt nhau như hình dưới.

Cụ thể: 

+ B1: Chọn các đường line, pline giao nhau

+ B2: Chạy lisp

E chân thành cảm ơn!

untitled_zps87f078e4.png

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ì bạn không post file nên mình không test được, bạn thử làm cách này được không, không cần lisp:

1. Vẽ hình chữ nhật bao quan cái hình trên của bạn (Bao rộng hẳn ra bên ngoài, không chạm vào đường nào)

2. Dùng lệnh Bo pick vào vùng giữa hình của bạn và hình chữ nhật vừa tạo.

3. Bạn sẽ có được đường bo bạn cầ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

Vì bạn không post file nên mình không test được, bạn thử làm cách này được không, không cần lisp:

1. Vẽ hình chữ nhật bao quan cái hình trên của bạn (Bao rộng hẳn ra bên ngoài, không chạm vào đường nào)

2. Dùng lệnh Bo pick vào vùng giữa hình của bạn và hình chữ nhật vừa tạo.

3. Bạn sẽ có được đường bo bạn cần.

Không được bạn à. Cảm ơn bạn 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

×