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

Làm sao để khi huỷ lệnh lisp không bị đổi lớp

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

Bình thường khi viết lisp có nhiều bạn cứ nghĩ là phải lưu biến CLAYER để goi lại trước khi kết thúc lệnh.

Điều này hoàn toàn không cần thiết, lắm lúc lại gây ra sự khó chịu khi nhấn ESC giữa chừng layer hiện tại lại nhảy sang layer của đối tượng vẽ cuối cùng.

Xử lý điều này rất dễ dàng, khi vẽ xong đối tượng nào là mình đổi mã DXF layer của nó luôn (8 . "layer đối tượng cần áp")

Ưu điểm của việc này là không cần biết trong bản vẽ đã có layer cần đổi hay chưa, nếu chưa có nó sẽ tự tạo layer mới với màu trắng và nét mặc định continue.

Hàm để thay đổi layer của đối tượng được vẽ cuối cùng như sau:

(defun ch_layer_lastobj ( layer / ent ent0)

(setq ent (entlast)

ent0 (entget ent)

ent0 (subst (cons 8 layer) (assoc 8 ent0) ent0)

)

(entmod ent0)

(entupd ent)

)

Nhưng làm thế nào để khi huỷ lệnh không bị thay đổi OSMODE thì mình chưa nghĩ ra được, mong có bạn nào chỉ giúp cho.

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ình thường khi viết lisp có nhiều bạn cứ nghĩ là phải lưu biến CLAYER để goi lại trước khi kết thúc lệnh.

Điều này hoàn toàn không cần thiết, lắm lúc lại gây ra sự khó chịu khi nhấn ESC giữa chừng layer hiện tại lại nhảy sang layer của đối tượng vẽ cuối cùng.

Xử lý điều này rất dễ dàng, khi vẽ xong đối tượng nào là mình đổi mã DXF layer của nó luôn (8 . "layer đối tượng cần áp")

Nhưng làm thế nào để khi huỷ lệnh không bị thay đổi OSMODE thì mình chưa nghĩ ra được, mong có bạn nào chỉ giúp cho.

 

Mình thường không gặp phải trường hợp bạn nêu. Lý do là: Mình thường gọi lệnh entmake để tạo đối tượng. Trong hàm entmake đã có mã DXF (8 . "layer đối tượng") nên không phải change cái gì sất.

 

Cách của bạn cũng là một mẹo dành cho người create đối tượng bằng hàm command.

 

Xét về mặt tổng quát, muốn nhấn esc không làm 'vỡ' lệnh của mình, bạn nên định nghĩa lại hàm *error* như sau:

 

(defun init()
 (setq 
    cadviet_old_er *error*
    *error* cadviet_new_er
 )
)

(defun cadviet_new_er(msg)
 ;;; Lúc nhấn esc, hàm này sẽ được gọi, vì vậy bạn hãy đặt các mã lệnh restore ở đây
 ;;; ví dụ như là setvar "clayer" hay "osmode" về giá trị cũ
 (done)
)

(defun done()
 (if cadviet_old_er (setq *error* cadviet_old_er))
)

và trong mã lệnh của bạn bạn gọi hàm như sau:

 

(init)
;;;mã lệnh của bạn
(done)

  • Vote tăng 5

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

Ssg cũng biết sử dụng kiểu bẫy lỗi này (theo hướng dẫn trong các tài liệu), kết quả thì OK nhưng chưa hiểu nó một cách thấu đáo. Thì ra bản chất của vấn đề là hàm *error* được gọi khi user bấm ESC.

Cám ơn anh Hoà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

Cảm ơn anh Hoành nhiều, nhưng thực ra người mới viết lisp thì vẫn phải xài hàm command trước đã.

Tiện đây cho em hỏi tí : Muốn tính khoảng cách từ 1 điểm đến 1 đường pline thì phải làm NTN? Vì em muốn viết con lisp san nền cần nội suy cao độ theo đường đồng mứ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
Cảm ơn anh Hoành nhiều, nhưng thực ra người mới viết lisp thì vẫn phải xài hàm command trước đã.

Tiện đây cho em hỏi tí : Muốn tính khoảng cách từ 1 điểm đến 1 đường pline thì phải làm NTN? Vì em muốn viết con lisp san nền cần nội suy cao độ theo đường đồng mức.

bạn dùng hàm vlax-curve-getClosestPointTo để tìm điểm gần nhất.

 

Cú pháp: (vlax-curve-getClosestPointTo curve-obj givenPnt [extend])

 

Ví dụ: (command ".point" (vlax-curve-getClosestPointTo (car (entsel "\nDoi tuong: ")) (getpoint "\nDiem")))

  • 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

Mình thường không gặp phải trường hợp bạn nêu. Lý do là: Mình thường gọi lệnh entmake để tạo đối tượng. Trong hàm entmake đã có mã DXF (8 . "layer đối tượng") nên không phải change cái gì sất.

 

Cách của bạn cũng là một mẹo dành cho người create đối tượng bằng hàm command.

 

Xét về mặt tổng quát, muốn nhấn esc không làm 'vỡ' lệnh của mình, bạn nên định nghĩa lại hàm *error* như sau:

 

Bác Hoành cho em hỏi, em cũng rất thích dùng *error* trong các chương trình lisp, lisp của em là lisp tự viết, khá đơn giản, hầu như chỉ cần việc lưu giữ 3 biến (cmdecho, clayer,osmode) em tận dụng CODE của bác để viết lại như sau

[~CODE]

(defun init()

(setq

old_error *error*

*error* new_error

)

(setq oldos (getvar "osmode")

oldlay(getvar "clayer"))

)

(defun new_error(msg)

(setvar "cmdecho" 1)

(setvar "osmode" oldos)

(setvar "clayer" oldlay)

(done)

)

(defun done()

(setvar "osmode" oldos)

(setvar "clayer" oldlay)

(if old_error (setq *error* old_error))

)

[~/CODE]

 

 

 

Như vậy bằng cách thêm vào các dòng màu đỏ, thì em khi dùng CODE chỉ cần viết như sau:

 

 

 

[~CODE]

(defun c:thu_nghiem()

(setvar "cmdecho" 0)

(init)

;;Noi dung chuong trinh

(setvar "osmode" 0)

(setvar "clayer" "0")

(command "line" pause pause "")

;(command "line" )

;;ket thuc chuong trinh chinh

 

(done)

(princ)

)

[~/CODE]

Như vậy khi viết CODE chỉ cần dùng hàm (init) ở đầu code, (done) ở cuối CODE và trong chương trình chính của LISP thoải mái gán lại (cmdecho,clayer,osmode)

Cách làm này nhìn CODE dễ nhìn hơn, nhưng hiện tại em đang vướng mắc ở điểm sau mong bác (và các mem Cadviet khác) giúp đỡ,

Với việc lập lisp thu_nghiem như trên; thì CODE chạy ngon lành, cho phép :

  1. Chuyển layer về layer "0"
  2. Cài OSMODE về 0
  3. Vẽ 1 đường LINE (đường LINE nối hai điểm duy nhất USER nhập (xem lại CODE dòng màu xanh))

 

 

 

Như vậy nói chung là ổn, có điều bây giờ em không muốn chỉ vẽ một LINE nữa mà muốn vẽ liên tiếp các LINE (giống mặc định của lệnh ".LINE" trong Cad vậy(bằng cách thay dòng màu xanh ở trên bằng dòng màu tím ở dưới(có thêm bớt dấu ";") ). Khi đó CODE của em không chạy đúng nữa.

Hiện tượng là như sau: code không chuyển về layer "0", vẽ các LINE liên tiếp bằng lệnh của CAD (không đổi layer)

Em muốn hỏi nguyên nhân và cách khắc phục lỗi này, cảm ơn bác và mọi người

(do không chuyển màu chữ trong Code được nên e xin phép dùng cách không đặt Code trong box_code nữa xin lỗi mọi người)

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

Bạn thêm đoạn này đằng sau (command "line") : (while (= (getvar "CMDACTIVE") 1) (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

Bạn thêm đoạn này đằng sau (command "line") : (while (= (getvar "CMDACTIVE") 1) (command pause))

Thanks bác, để em thử

Em đã check xong, lisp chạy tốt cảm ơn bác. Share lại cho mọi người.

Trước nay e mới biết khi có Lệnh đang chạy thì biến "cmdactive" nhận giá trị nguyên (số mũ 2) >0

Nhưng không để ý lại có nhiều lựa chọn thế này,up lại lên đây cho các mem cùng tham khảo

Đây là dịch bởi google trans..

 

0 Không có lệnh hoạt động

1 lệnh thông thường là hoạt động

2 Transparent lệnh đang hoạt động

4 Script là hoạt động

8 Hộp thoại đang hoạt động

16 DDE là hoạt động

32 AutoLISP đang hoạt động (chỉ hiển thị một lệnh ObjectARX xác định)

64 ObjectARX lệnh đang hoạt động

Đây là nguyên mẫu

0 No active command

1 Ordinary command is active

2 Transparent command is active

4 Script is active

8 Dialog box is active

16 DDE is active

32 AutoLISP is active (only visible to an ObjectARX-defined command)

64 ObjectARX command is active

Chỉnh sửa theo quansla
  • 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

×