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

[Nhờ Vả] Xin Sửa Giúp Lisp Dành Cho Vẽ Mũi Tên Dạng Leader Bằng Lwpolyline

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

Chào các bác, em có biết một chút về LISP nên có tự viết 1 lisp sau (mục tiêu của Lisp là vẽ mũi tên ghi chú bằng LWPolyline (không phải Leader của Cad, bởi vì Leader nhiều khi không tạo được hình dáng đẹp như LWPolyline)) có điều LISP đang KHỒNG HOẠT ĐỘNG

xin các bác sửa giúp em để có thể chạy được

(vấn đề gặp phải trong CODE Dòng (command "PLINE") và dòng (alert "Thuc hien chuyen doi") nhẽ ra như mong muốn là phải thực hiện xong lệnh PLINE có đội tượng LWPolyline xong hết rồi, mới làm đến các lệnh kể từ (alert "Thuc hien chuyen doi") đổ đi, nhưng hiện tại dòng (command "PLINE") không chịu hoàn thành trả kết quả trước)

Đây là file, mong các bác giúp em

(defun c:qqtt (/ arr_leng arr_size el en_luu ls ls_10 ls_not10 r2 x)

(vl-load-com)

(setq arr_size 50.0 arr_leng 150.0 el (entlast))

 

(command "Pline")

;(while (> (getvar "cmdactive" ) 0) )

(if (and (/= el (entlast))

(setq en_luu (entget (entlast)))

(= (cdr(assoc 0 en_luu)) "LWPOLYLINE"))

(progn

(alert "\nThuc hien chuyen doi")

(setq ls_10 (vl-remove-if '(lambda(x) (not(member (car x) '(10)))) en_luu)

ls_not10 (vl-remove-if '(lambda(x) (member (car x) '(5 330 -1 8 90 43 10 40 41 42 91))) en_luu))

(setq r2 (append

(list (car ls_10) (cons 40 0.0) (cons 41 arr_size) (cons 42 0.0) (cons 91 0))

(list (cons 10 (polar (cdr(car ls_10)) (angle (cdr(car ls_10)) (cdr(cadr ls_10))) arr_leng))

(cons 40 0.0) (cons 41 0.0) (cons 42 0.0) (cons 91 0))

(apply 'append

(mapcar '(lambda(x)

(list x (cons 40 0.0) (cons 41 0.0) (cons 42 0.0) (cons 91 0)))

(cdr ls_10)))

))

(while (entnext el) (entdel (setq el (entnext el))))

(entmakex

(append

ls_not10

(list (cons 8 "0"))

(list (cons 90 (1+ (length ls_10))))

r2))

;(entmakex (append ls_not10 ls))

)

(princ "nothing do")

))

 

 

Nếu có thể xin hãy giữ lại toàn bộ các lựa chọn vẽ của lệnh LWPOLyline như mặc định của CAD khi thực hiện lệnh vẽ LWpolyline (tức vẫn lựa chọn được "A;C;H;L;U;W;L" trong ([Arc/Close/Halfwidth/Length/Undo/Width] :)

Chỉnh sửa theo quansla

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 mới tìm ra một cách nhưng lại không đảm bảo được việc dùng như nguyen bản của Cad trong khi thực hiện lệnh LWPolyline (yêu cầu 2 ở #1)

(progn
(setq p0 (getpoint))
(command "PLINE" p0
(while (> (getvar "cmdactive") 0)
(progn
(if (setq p0 (getpoint p0 "\nChon diem tiep theo"))
(command p0)
(command "")
)))))

 
 
 
Cách thứ 2 dù chưa hoàn toàn giống nhưng đủ dùng (yêu cầu kiên quyết USER phải nhớ rõ tuỳ chọn của LWPOLYLINE)
(defun c:ttttt()
(setq p0 (getpoint))
(command "PLINE" p0
(while (> (getvar "cmdactive") 0)
(progn
(initget "A H L U W CE LC D C L R S")
(setq p0 (getpoint "\nChon diem tiep theo"))
(cond
((member (type p0) '(LIST STR)) (command p0))
((not p0) (command ""))
)
)
))
)



Cách cuối cùng có thể nghĩ được, ek toàn mình tự hỏi, tự trả lời

 

 

(defun c:ttttt()
(setq lst_str
(list
(cons "A" "Specify endpoint of arc or\n[Angle/CEnter/Direction/Halfwidth/Line/Radius/Second pt/Undo/Width]:")
(cons "L" "Specify next point or [Arc/Close/Halfwidth/Length/Undo/Width]:")
(cons "H" "Specify starting/ending half-width ")
))
(setq p0 (getpoint "\nChon diem thu nhat"))
(setq str "Chon diem tiep theo")
(command "PLINE" p0
(while (> (getvar "cmdactive") 0)
(progn
(initget "A H L U W CE LC D C L R S")
(setq p0 (getpoint (strcat "\n" str)))
(cond
((= (type p0) 'LIST) (command p0))
((= (type p0) 'STR)
(command p0)
(setq str (cdr (assoc p0 lst_str)))
)
((not p0) (command ""))
)
)
))
)
Chỉnh sửa theo quansla

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ành quả cuối cùng, tạm sửa như vầy, mong mọi người tối ưu giùm vì nó còn khá nhiều bất tiện

(defun ve_PLine_q(/ lst_str p0 str)
(setq lst_str
(list
(cons "A" "Specify endpoint of arc or\n[Angle/CEnter/Direction/Halfwidth/Line/Radius/Second pt/Undo/Width]:")
(cons "L" "Specify next point or [Arc/Close/Halfwidth/Length/Undo/Width]:")
(cons "H" "Specify starting/ending half-width ")
))
(setq p0 (getpoint "\nChon diem thu nhat"))
(setq str "Chon diem tiep theo")
(command "PLINE" p0
(while (> (getvar "cmdactive") 0)
(progn
(initget "A H L U W CE LC D C L R S")
(setq p0 (getpoint (getvar "lastpoint") (strcat "\n" str)))
(cond
((= (type p0) 'LIST) (command p0))
((= (type p0) 'STR)
(command p0)
(setq str (cdr (assoc p0 lst_str)))
)
((not p0) (command ""))
)
)
))
)



(defun c:ll2 (/ arr_leng arr_size el en_luu ls_10 ls_10_x1 ls_10_x2 ls_not10 r2)
(vl-load-com)
(setq arr_size 50.0 arr_leng 150.0 el (entlast))

(ve_PLine_q)
(if (and (/= el (entlast))
(setq en_luu (entget (entlast)))
(= (cdr(assoc 0 en_luu)) "LWPOLYLINE"))
(progn
;(alert "\nThuc hien chuyen doi")
(setq ls_10 (vl-remove-if '(lambda(x) (not(member (car x) '(10 40 41 42 91)))) en_luu)
ls_10_x1 (list (car ls_10) (cadr ls_10) (caddr ls_10) (cadddr ls_10) (car(cddddr ls_10)))
ls_10_x2 (cdr(cddddr ls_10))
ls_not10 (vl-remove-if '(lambda(x) (member (car x) '(5 330 -1 8 90 43 10 40 41 42 91))) en_luu))
(setq r2 (append
(subst (cons 41 arr_size) (assoc 41 ls_10_x1)ls_10_x1)
(list
(cons 10 (polar (cdr(car ls_10_x1)) (angle (cdr(car ls_10_x1)) (cdr(car ls_10_x2))) arr_leng))
(cons 40 0.0) (cons 41 0.0) (cons 42 0.0) (cons 91 0))
ls_10_x2))
(while (entnext el) (entdel (setq el (entnext el))))
(entmakex
(append
ls_not10
(list (cons 8 "0"))
(list (cons 90 (1+ (length ls_10))))
r2))
)
(princ "nothing do")
))

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 update liên tục nên cuối cùng không biết bạn muốn nhờ những gì? Những gì chưa làm được?

Hì, xin lỗi bác Hà, vì mới đầu em tìm hiểu không ra, upload lên cadviet xong thi lại có ý tưởng giải quyết, nhưng cuối cùng chỉ dừng lại ở mưc dộ tạm dùng được thôi.

#1. Đưa ra vấn đề: có viết 1 LISP, nhưng không chạy được, do lỗi khi thực hiện lệnh (Command "PLINE") + Yêu cầu 2: giữ lại lựa chọn mặc định của Cad khi thực hiện lệnh PLINE.

#2. Tìm ra 3 cách giải quyết (thực ra là phát triển từ 1 ý tưởng ban đầu),

cách 1: cho phép dongf PLINE hoạt động trả đến kết quả cuối cùng (entlast = LWPolyline đã vẽ) nhưng cách này mới chỉ chấp nhận việc USER nhập giữ liệu đầu vào cho PLINE là Pick điểm

cách 2: giải quyết vấn đề của cách 1 bằng cách thêm vào mở rộng giữ liệu nhập vào của USER (dùng hàm INITGET) nhưng cách nay chưa tối ưu do nó cho phép USERS lựa chọn chữ cái ("A" "L" "C" ...) hoặc PICK nhưng lại không đưa ra gợi ý gì, rất khó cho người sử dụng

cách 3: giải quyết vấn đề của cách 2 bằng cách dùng hàm (cdr(assco p0 lst_str)) trong đó lst_str là một LIST chứa string gợi ý đi kèm khi lựa chọn của PLINE (copy của Cad) cách này tương đối ổn nhưng do yêu cầu rẽ nhãnh của Cad theo mặc định là tương đối lằng nhằng, cần dùng nhiều biến hơn + đầu tư thời gian lớn quá ,nên chỉ dừng lại ở mức độ vài lựa chọn hay dùng của PLINE. Cách này chưa tối ưu vì còn thiếu sót rất nhiều mặc định của Cad, thiếu hiển thị "trước" như CAd làm dươcd,lỗi khi lựa chọn một số lựa chọn OPTION, ....

#3. Tạm chấp nhận #2, đưa vào hàm con và hoàn thiện LISP vẽ LEader bằng PLINE

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. Đưa ra vấn đề muốn nhờ giúp đỡ.

#2. Một phương án em tìm được rồi phát triển nó ra 3 cách, tối ưu dần dần

#3. Áp dụng #2 vào LISP , nhưng LISP chưa thực sự hoàn thiện, vẫn khó dùng, Đến đây thì em chỉ còn muốn nhờ các bác xem giúp đề: 1. Phát trriển nó để hoàn thiện hoặc 2 Dùng cách khác để kết quả tương đương

Xin lỗi bác,em sẽ rút kinh nghiệm lận sau. hì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

Nói chung là tôi vẫn không hiểu, nhất là khái niệm "phát triển để hoàn thiện". Sao bạn không liệt kê những ra những điều bạn muốn nhưng chưa làm được? Ví dụ:

- a là...

- b là...

- c là...

Đừng nhắc lại mấy cái # làm gì!

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ói chung là tôi vẫn không hiểu, nhất là khái niệm "phát triển để hoàn thiện". Sao bạn không liệt kê những ra những điều bạn muốn nhưng chưa làm được? Ví dụ:

- a là...

- b là...

- c là...

Đừng nhắc lại mấy cái # làm gì!

# là thứ tự bài viết, đúng quy định diễn đàn mà bác

Nếu ghi chi tiết thì như thế này:

* Yêu cầu: Vẽ mũi tên (giống dạng Leader) bằng LWPolyline (không dùng Leader vì Leader không bẻ cong được một số vị trí))

ví dụ như ảnh sau:

QaoaTdo.png

 

Trong đó mũi tên có các đặc điểm sau: đầu mũi tên: phân đoạn đầu của LWPolyline (dài 150, rộng - WIDTH: điểm đầu = 0, điểm cuối =50) các phân đoạn sau do tùy chọn của người dùng khi vẽ/ nhập Polyline bằng Lệnh PLINE của Cad, mũi tên có Layer "0"

Các bước thực hiện lệnh: gõ LL2 (enter) Cad cho phép thực hiện lệnh PLINE với ĐẦY ĐÙ TÙY CHỌN CỦA LỆNH PLINE THEO MẶC ĐỊNH, sau đó LISP sẽ entmod (hoặc entmakex) đối tượng mới (vẫn là LWPOlyline) trong đó đã chèn thêm một điểm mới vào đầu của Polyline (tức tạo thêm 1 phân đoạn đầu ở đầu của LWPolyline đã vẽ), rồi gán cho phân đoạn đó chiều dày 50, chiều dài 150 tạo dáng mũi tên.; kết thúc lệnh

Mô tả, em gửi kèm file bên dưới.

* Hướng giải quyết bản thân:

Ngôn ngữ: Dùng LISP

Cú pháp : c:LL2, cho phép ngừoi dùng thực hiện lệnh PLINE (đã sửa đổi cho phù hợp với Code bên dưới- nhưng đồng thời, việc sửa này cũng mất các tùy chọn LWPOLYLINE của Cad- vì thế cần hoàn thiện là đây)

Công việc LISP làm:

1. Lưu đối tượng entlast.

2. Vẽ đối tượng Polyline lưu lại (setq ent_luu (entget..)) của nó

3. Lọc các mã dxf 10 40 41 42 91 của ent_luu (giả sử có 3 phân đoạn A-B;B-C;C-D (tức 4 điểm)

4. Chèn thêm một phân đoạn A-A1 vào đầu ent_luu để có 4 phân đoạn A-A1; A1-B; B-C; C-D (tức 5 điểm) đồng thời gán dxf 10 40 41 42 91 cho phân đoạn này

5. Xóa các đối tượng đã vẽ (kể từ lần (entlast) ở bước 1 đến nay. Sau đó Entmakex lại đối tượng mới theo (entget) có được ở bước 4

6. Kết thúc lệnh

Khó khăn gặp phải.

- Tại cú pháp (CODE) của LISP tự tạo, nếu để mặc định (command ".PLINE") thì LISP không chạy, nếu sửa lại (dùng hàm con như ở bài viết #3 thì Lisp chạy nhưng mất tùy chọn của CAD)

- Yêu cầu: khôi phục tùy chọn của CAD (khi dùng lệnh "PLINE" mà LISP vẫn hoạt động bình thường.

https://mail.google.com/mail/u/1/?ui=2&ik=ab405e2b36&view=att&th=154b2ff07e595231&attid=0.1&disp=safe&realattid=f_io8687gc0&zw

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

Trong cái lísp đầu của bạn, phần ;while ... sửa thành :

 (while (> (getvar "cmdactive" ) 0) (command pause))
  • 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

×