Đến nội dung


Hình ảnh
- - - - -

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


  • Please log in to reply
7 replies to this topic

#1 cuongtk2

cuongtk2

    biết vẽ ellipse

  • Members
  • PipPip
  • 59 Bài viết
Điểm đánh giá: 20 (tàm tạm)

Đã gửi 25 June 2008 - 05:17 PM

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.
  • 0

#2 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 4105 Bài viết
Điểm đánh giá: 4495 (đỉnh cao)

Đã gửi 25 June 2008 - 05:34 PM

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)

  • 5

#3 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 26 June 2008 - 07:45 AM

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!
  • 1

#4 cuongtk2

cuongtk2

    biết vẽ ellipse

  • Members
  • PipPip
  • 59 Bài viết
Điểm đánh giá: 20 (tàm tạm)

Đã gửi 26 June 2008 - 02:41 PM

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.
  • 0

#5 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 4105 Bài viết
Điểm đánh giá: 4495 (đỉnh cao)

Đã gửi 26 June 2008 - 03:18 PM

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")))
  • 2

#6 quansla

quansla

    biết lệnh xclip

  • Members
  • PipPipPipPipPipPipPip
  • 642 Bài viết
Điểm đánh giá: 224 (khá)

Đã gửi 29 November 2012 - 05:19 PM

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 :
  • Chuyển layer về layer "0"
  • Cài OSMODE về 0
  • 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)

Bài viết đã được chỉnh sửa nội dung bởi quansla: 29 November 2012 - 05:23 PM

  • 0

#7 ketxu

ketxu

    Copier - Paster - Editor

  • Moderator
  • PipPipPipPipPipPipPip
  • 5679 Bài viết
Điểm đánh giá: 2605 (tuyệt vời)

Đã gửi 29 November 2012 - 05:47 PM

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

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#8 quansla

quansla

    biết lệnh xclip

  • Members
  • PipPipPipPipPipPipPip
  • 642 Bài viết
Điểm đánh giá: 224 (khá)

Đã gửi 29 November 2012 - 05:52 PM

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

Bài viết đã được chỉnh sửa nội dung bởi quansla: 29 November 2012 - 06:01 PM

  • 1