Chuyển đến nội dung
Diễn đàn CADViet
Đăng nhập để thực hiện theo  
Thaistreetz

Undo trong quá trình chạy lisp

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

Mình thấy đa số các lệnh của cad đều cho phép undo lại 1 buớc nào đó ngay trong quá trình chạy lệnh, nghĩa là lệnh vẫn chưa kết thúc.

Ví dụ khi vẽ 1 pline, nếu ta pick sai 1 điểm nào đó thì có thể undo để loại bỏ điểm vừa pick và lệnh vẫn tiếp tục đuợc thực hiện

Làm cách nào để thực hiện đuợc điều này? ĐK là không dùng hàm grread nhé, hàm này tạo ra những bất tiện nhất định khi áp dụng cho truờng hợp này

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 vật với nó cả buổi tối mà không ra. Có lẽ không thể xây dựng được 1 cách giải quyết tổng quát cho mọi trường hợp.

Giờ mình đưa ra bài toán cụ thể hơn. Nhờ các bác xây dựng giúp mình 1 hàm con có chức năng lấy tọa độ 1 điểm với điều kiện rẽ nhánh: Nếu pick chuột để chọn điểm hàm sẽ trả về tọa độ của điểm đó, nếu thay vì pick chuột ta gõ 1 phím nào đó thì hàm thực hiện 1 công việc khác. (cụ thể ở đây nếu gõ phím U hàm sẽ thực hiện lệnh Undo)

Mình đã thử dùng hàm grread cho trường hợp này nhưng thất bại vì hàm grread không cho bắt điểm. Rất nhiều lệnh của cad cho phép làm điều này nên mình tin chắc là có thể làm được với lisp bằng cách nào đó. :leluoi: :cheers: :s_big:

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 vật với nó cả buổi tối mà không ra. Có lẽ không thể xây dựng được 1 cách giải quyết tổng quát cho mọi trường hợp.

Giờ mình đưa ra bài toán cụ thể hơn. Nhờ các bác xây dựng giúp mình 1 hàm con có chức năng lấy tọa độ 1 điểm với điều kiện rẽ nhánh: Nếu pick chuột để chọn điểm hàm sẽ trả về tọa độ của điểm đó, nếu thay vì pick chuột ta gõ 1 phím nào đó thì hàm thực hiện 1 công việc khác. (cụ thể ở đây nếu gõ phím U hàm sẽ thực hiện lệnh Undo)

Mình đã thử dùng hàm grread cho trường hợp này nhưng thất bại vì hàm grread không cho bắt điểm. Rất nhiều lệnh của cad cho phép làm điều này nên mình tin chắc là có thể làm được với lisp bằng cách nào đó. :cheers: :s_big: :D

Chào buổi sáng :leluoi:

(defun c:cbs(/ p);Chao buoi sang
 (initget 1 "c")
 (setq p (getpoint "Pick point or Press C to say good morning :"))
 (if (= p "c")
   (alert "Chao buoi sang - Good morning") ;user press C
   (alert (vl-princ-to-string p));user pick point
 )
)

  • 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 buổi sáng :leluoi:

(defun c:cbs(/ p);Chao buoi sang
 (initget 1 "c")
 (setq p (getpoint "Pick point or Press C to say good morning :"))
 (if (= p "c")
   (alert "Chao buoi sang - Good morning") ;user press C
   (alert (vl-princ-to-string p));user pick point
 )
)

Haha, Chào buổi sáng anh Tue_NV. Thật là đơn giản đến bất ngờ :cheers:

Truớc đến giờ em cứ nghĩ initget chỉ kiểm soát các hàm getreal, getint và getstring thôi. giờ đọc lại mới biế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
Haha, Chào buổi sáng anh Tue_NV. Thật là đơn giản đến bất ngờ :leluoi:

Truớc đến giờ em cứ nghĩ initget chỉ kiểm soát các hàm getreal, getint và getstring thôi. giờ đọc lại mới biết

Đúng là đơn giản, nhưng việc thực hiện undo cũng phức tạp lắm bác Thaistreetz à, vì mình phải ngắt đoạn chương trình, undo ở các đoạn chương trình phải thêm hàm điều kiện undo. Sau đó lại phải xoá các biến lôi các biến từ đoạn trước ghép vào. Mình nghĩ tới đó là rối cả đầu rồi. Mà muốn undo tới đoạn đầu của chương trình thì số lượng biến phải xoá rất nhiều. Để thực hiện được phải xắp xếp lsp 1 cách hợp lý mới xử lý được hết. Khi nào bạn thực hiện được post 1 đoạn lên cho mình tham khảo với nhé. THANKS

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à đơn giản, nhưng việc thực hiện undo cũng phức tạp lắm bác Thaistreetz à, vì mình phải ngắt đoạn chương trình, undo ở các đoạn chương trình phải thêm hàm điều kiện undo. Sau đó lại phải xoá các biến lôi các biến từ đoạn trước ghép vào. Mình nghĩ tới đó là rối cả đầu rồi. Mà muốn undo tới đoạn đầu của chương trình thì số lượng biến phải xoá rất nhiều. Để thực hiện được phải xắp xếp lsp 1 cách hợp lý mới xử lý được hết. Khi nào bạn thực hiện được post 1 đoạn lên cho mình tham khảo với nhé. THANKS

Thao tác undo trong quá trình chạy lisp tuỳ thuộc vào tính chất và cách làm việc của mỗi lisp. khi đó ta dựa vào các thao tác mà lisp tuơng tác với nguời dùng mà đặt các điểm undo mark cho hợp lý và dễ sử dụng thôi.

Đây là đoạn code để thực hiện việc undo trong quá trình pick lần luợt các điểm. khi pick sai ta gõ u để pick lại điểm đó.

(setq k 0)

(while

(progn

(initget 128 "u")

(setq TD0 (getpoint (strcat"\n Pick diem thu "(rtos (setq k (1+ k)) 2 0) " : "))))

(if (= TD0 "u") (vl-cmdf "undo" "Back") TD0)

);progn

(if (/= TD0 "u")

(progn

(vl-cmdf "undo" "mark")

...... Các hàm cần thực hiện.....

);progn

(progn

(setq k (- k 2)

..... Trả lại giá trị các biến nếu có tại vòng lặp trước .....

);progn

);if

);while

Chú ý là đầu lisp nên khai báo điểm undo begin và cuối lisp điểm undo end để sau khi chạy lệnh xong các điểm undo mark được loại bỏ.

  • 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ại nói về kiểm soát biến mình có 1 file TXT như sau

1 15/12/2010 a

2 16/12/2010 b

3 abc c

Mình sử dụng hàm cons (tham khảo các lsp tiền bối)

dòng 1 cho giá trị (0 . 1)(1 . 15/12/2010) (2 . a)

dòng 2 cho giá trị (0 . 2)(1 . 16/12/2010) (2 . :leluoi:

dòng 3 cho giá trị (0 . 3)(1 . abc)(2 . c)

Và bắt đầu lấy biến như sau: (LST là list của từng dòng sau mỗi lần chạy:)

(setq vt1 (cdr(assoc 0 LST)))

(if (or(= vt1 "")(not vt1))(err1)) ;(err1 là hàm alert thông báo dữ liệu sai và kèm theo lệnh quit)

(setq vt2 (cdr(assoc 1 LST)))

(if (or(= vt2 "")(not vt2))(err1))

(setq vt3 (cdr(assoc 2 LST)))

(if (or(= vt3 "")(not vt3))(err1))

Khi đọc đến dòng thứ 3 thì máy sẽ báo lỗi vì định dạng không giống của vt2 không giống vt2 của dòng 1 hoặc dòng 2.

Do học mót của các tiền bối nên chưa được hiểu vì sao như thế tìm toàn bộ lsp không có nhánh sang file lisp khác và không có chỗ nào trong lsp có biến vt2.

Mong các bạn giải thích và nếu được thì viết cho mình đoạn lsp để thực hiện kiểm tra như trên. Cảm ơn các bạ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ú ý là đầu lisp nên khai báo điểm undo begin và cuối lisp điểm undo end để sau khi chạy lệnh xong các điểm undo mark được loại bỏ.

Thật xấu hổ quả khi phải hỏi câu này, nhưng mà em chậm hiểu quá nên mới học hoài vẫn dốt. Anh có thể giải thích rõ hơn về dòng trên không?

Em thấy phần lớn các lisp đều có 2 thao tác này nhưng mà chưa biết tác dụ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
Lại nói về kiểm soát biến mình có 1 file TXT như sau

1 15/12/2010 a

2 16/12/2010 b

3 abc c

Mình sử dụng hàm cons (tham khảo các lsp tiền bối)

dòng 1 cho giá trị (0 . 1)(1 . 15/12/2010) (2 . a)

dòng 2 cho giá trị (0 . 2)(1 . 16/12/2010) (2 . :leluoi:

dòng 3 cho giá trị (0 . 3)(1 . abc)(2 . c)

Và bắt đầu lấy biến như sau: (LST là list của từng dòng sau mỗi lần chạy:)

(setq vt1 (cdr(assoc 0 LST)))

(if (or(= vt1 "")(not vt1))(err1)) ;(err1 là hàm alert thông báo dữ liệu sai và kèm theo lệnh quit)

(setq vt2 (cdr(assoc 1 LST)))

(if (or(= vt2 "")(not vt2))(err1))

(setq vt3 (cdr(assoc 2 LST)))

(if (or(= vt3 "")(not vt3))(err1))

Khi đọc đến dòng thứ 3 thì máy sẽ báo lỗi vì định dạng không giống của vt2 không giống vt2 của dòng 1 hoặc dòng 2.

Do học mót của các tiền bối nên chưa được hiểu vì sao như thế tìm toàn bộ lsp không có nhánh sang file lisp khác và không có chỗ nào trong lsp có biến vt2.

Mong các bạn giải thích và nếu được thì viết cho mình đoạn lsp để thực hiện kiểm tra như trên. Cảm ơn các bạn.

Bạn đọc lại hàm cons. vì nó không hiểu 15/12/2010 thuộc định dạng gì nên nó báo lỗ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
Thật xấu hổ quả khi phải hỏi câu này, nhưng mà em chậm hiểu quá nên mới học hoài vẫn dốt. Anh có thể giải thích rõ hơn về dòng trên không?

Em thấy phần lớn các lisp đều có 2 thao tác này nhưng mà chưa biết tác dụng.

Giải thích đơn giản thì như thế này: trước khi thực hiện các nội dung trong lisp thì đặt undo begin và khi kết thúc lisp thì đặt undo end. Mục đích là khi chạy một loạt các thao tác trong lisp thì người dùng không phải undo từng thao tác mà chỉ cần undo 1 lần là quay lại thời điểm đặt undo begin. giống như undo begin -> undo end có thể thay thế bằng undo mark để xác định mốc cần undo lúc nào muốn undo lại thời điểm này chỉ cần dùng undo back.

  • 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 đọc lại hàm cons. vì nó không hiểu 15/12/2010 thuộc định dạng gì nên nó báo lỗi.

Nó không báo lỗi ở 15/12/2010 mà nó báo lỗi ở abc. Nếu dòng đầu định dạng như thế nào thì dòng sau định dạng phải như thế thì sẽ không bị báo lỗi, ở đây mình không hiểu kt biến so với biến trước.

Lần chạy 1 nhận giá trị biến là 15/12/2010

Lần chạy 2 nhận giá trị biến là 16/12/2010

Lần chạy 3 nhận giá trị biến là abc (báo lỗi vì định dạng không giống 2 lần chạy trước)

có nghĩa sau lần chạy 1 thì biến đã định dạng sẵn. Nếu lần chạy 2 hay 3 định dạng không đúng sẽ báo lỗi ngay.

Chú ý: Tất cả định dạng vào hàm cons đều đã chuyển về string thì làm sao nó báo lỗi được. 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
Nó không báo lỗi ở 15/12/2010 mà nó báo lỗi ở abc. Nếu dòng đầu định dạng như thế nào thì dòng sau định dạng phải như thế thì sẽ không bị báo lỗi, ở đây mình không hiểu kt biến so với biến trước.

Lần chạy 1 nhận giá trị biến là 15/12/2010

Lần chạy 2 nhận giá trị biến là 16/12/2010

Lần chạy 3 nhận giá trị biến là abc (báo lỗi vì định dạng không giống 2 lần chạy trước)

có nghĩa sau lần chạy 1 thì biến đã định dạng sẵn. Nếu lần chạy 2 hay 3 định dạng không đúng sẽ báo lỗi ngay.

Chú ý: Tất cả định dạng vào hàm cons đều đã chuyển về string thì làm sao nó báo lỗi được. Hì hì.

Bạn làm thế nào để tạo được lits vây mình không thể tạo được list sau (list (0 . 1) (1 . 15/12/2010) (2 . 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
Bạn làm thế nào để tạo được lits vây mình không thể tạo được list sau (list (0 . 1) (1 . 15/12/2010) (2 . a))

Bạn tham khảo.

(defun c:thu ()
 (setq a1 (getstring "\Nhap 1: "))
 (setq a2 (getstring "\Nhap 2: "))
 (setq a3 (getstring "\Nhap 3: "))
 (setq lst (list (cons 0 a1)(cons 1 a2)(cons 2 a3)))
 (princ lst)
 (princ)
 )

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
Đăng nhập để thực hiện theo  

×