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

Học AutoLisp

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

Sau một hồi nghiền ngẫm, đọc tới đọc lui, copy vô chạy thử và... báo lỗi:

Select objects: ; error: bad argument value: AutoCAD command: T

Ket xem giúp mình bị sai cái gì vậy?

Đây là code Chiron đã sửa:

(defun c:tdt (/ oldecho sel ent txtpnt txtht dientich)
 (while (not ent)
(while (not sel) (setq sel (entsel "\nSelect object: ")))
(if (member (cdr (assoc 0 (entget (car sel)))) '("POLYLINE" "LWPOLYLINE" "SPLINE" "CIRCLE" "HATCH"))
 	(setq ent T)
 	(progn
(princ "\nSelected object does not have an area")
(setq sel nil)
)
) ;End if
 ) ;End while
 (command ".area" "o" ent)
 (setq dientich (getvar "area"))
 (if (= dientich nil) (exit))
 (setq txtpnt (getpoint "\nSpecify middle point of text:"))
 (setq txtht
(getdist (strcat "\nSpecify height <" (rtos (getvar "textsize") 2 2) ">: "))
 )
 (if (null txtht) (setq txtht (getvar "textsize")) )
 (command "text" "m" txtpnt txtht 0 (strcat (rtos(/ dientich 1000000) 2 2) "m2"))
 (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

Sau một hồi nghiền ngẫm, đọc tới đọc lui, copy vô chạy thử và... báo lỗi:

Select objects: ; error: bad argument value: AutoCAD command: T

Ket xem giúp mình bị sai cái gì vậy?

Đây là code Chiron đã sửa:

(setq ent T)

(command ".area" "o" ent)

Sao lại dùng ent trong (command "area"...) được, nó bằng T cơ mà, phải (car sel) chứ!

  • 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

Sao lại dùng ent trong (command "area"...) được, nó bằng T cơ mà, phải (car sel) chứ!

A A A... Cảm ơn bác. Lo xem cái lọc mà không xem lại đoạn code ban đầu. Lisp đã chạy ngon lành. :D

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ác ơi em thấy lệnh tính diện tích mà bác lập khi tính với đối tương line mà ko liền mạch thì ko tính được.em toàn phải cắt các đương rồi nối nó lại mới tính được.Liệu có trương trình nào tự nhận diện tích như lệnh hatch ko bá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ác ơi em thấy lệnh tính diện tích mà bác lập khi tính với đối tương line mà ko liền mạch thì ko tính được.em toàn phải cắt các đương rồi nối nó lại mới tính được.Liệu có trương trình nào tự nhận diện tích như lệnh hatch ko bác

Lisp của Chiron viết chỉ áp dụng cho các đối tượng có diện tích thôi (polyline kín, circle...). Yêu cầu của bạn có nhiều trên diễn đàn rồi, bạn chịu khó tìm cái nào tính diện tích có hatch là đượ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

- Tôi xin thử nghiệm một chuỗi bài viết về đào tạo AutoLisp thông qua các dự án thực tế.

Xin mọi người đóng góp ý kiến.

 

thanks anh Hoanh, em đang muốn học cach viết lisp. trước đây em có học về lập trình ( Pascal thôi, vì cấp 3 e học chuyên Tin,còn ĐH thì k tìm hiểu nữa), nay em k biết nên học theo giáo trình VBA nào là dễ hiểu nhất và có thể vận dụng nhanh nhất. mong anh chỉ giúp em vớ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

em chạy cái lisp này vào sao khi pick vào 1 hình sao nó báo diện tich là 0.0 nhỉ :(
 

(defun c:tdt( / sel ent dientich)
(princ "\nChao cadviet")

(setq sel (entsel "\nHay chon doi tuong: "))
(setq ent (car sel))
(command ".area" "o" ent)
(setq dientich (getvar "area"))
(princ "\nDien tich doi tuong vua roi la: ")
(princ dientich)
(princ "\nm2")

(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

em chạy cái lisp này vào sao khi pick vào 1 hình sao nó báo diện tich là 0.0 nhỉ :(

 

(defun c:tdt( / sel ent dientich)

(princ "\nChao cadviet")

 

(setq sel (entsel "\nHay chon doi tuong: "))

(setq ent (car sel))

(command ".area" "o" ent)

(setq dientich (getvar "area"))

(princ "\nDien tich doi tuong vua roi la: ")

(princ dientich)

(princ "\nm2")

 

(princ)

)

Hề hề hề,

Đối tượng chọn phải là một pline kí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

thanks mod em quên mất cái lệnh area là phải pl kin. mình có thể tói ưu nó tính 1 hình bất kì ko nhỉ..tức là không cần phải pl mà chỉ cần các đường line nối nhau cũng co thể tính đượ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ác bác cho mình hỏi tí !

Trong lisp, mình có 2 đoạn thẳng mà mình đã đặt tên cho nó là a; b.

Mình viết thế nào để một lệnh (VD: move) tham chiếu tới 2 thằng đó cùng lúc nhỉ ??? :D

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ác bác giúp mình với !

Mình đang đọc topic này http://www.cadviet.com/forum/topic/10065-hoi-ve-thong-tin-cua-spline-va-mot-so-ham-vl-vlax/

đoạn #5-#6 mình có vướng 1 chổ này mà chưa biết thế nào:

- Như đoạn bác Hoành trích thì hàm (vla-IntersectWith ob1 ob2 acExtendNone) trả về giao điểm của 2 đt ob1, ob2 (ko kéo dài)

- Mình làm VD như sau:

 + vẽ lên cad 1line & 1 pline cắt nhau (hình)

 + Command: (setq a (car (entsel)))--------- chọn a

   Command: (setq b (car (entsel)))--------- chọn b

 + Tiếp:

(setq a1 (vlax-ename->vla-object a))

(setq b1 (vlax-ename->vla-object B))

(setq p (vla-IntersectWith a1 b1 acExtendNone))

Giờ mình nhập lệnh line: (để vẽ từ p -----> thì ra thế này ???)

Command: l LINE Specify first point: !p
#<variant 8197 ...>
Specify first point:

Nhờ các bác chỉ dùm, lỗi chổ nào ạh !

80156_vd1_1.jpg

 

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

Command: l LINE Specify first point: !p

#<variant 8197 ...>

Kết quả trả về (màu đỏ) là danh sách nhưng được biểu diễn dưới dạng Variant. Từ đây, muốn chuyển qua danh sách các điểm dạng (p1 p2... pn) thì còn vài bước nữa, hơi khó hiểu với bạn >> không đơn giản để lấy giao điểm của 2 curve chỉ bằng 1 hàm như vậy.

Tặng bạn 1 hàm lấy danh sách các giao điểm của 2 curve để thấy nó cũng khá phức tạp.

 

;; Get intersection of entity1 and entity2, by flag (flags: acExtendNone ; acExtendThisEntity ; acExtendOtherEntity ; acExtendBoth).
(defun #Inter:2Ent(ent1 ent2 flag / l r)
 (setq l (vlax-invoke (vlax-ename->vla-object ent1) 'intersectwith (vlax-ename->vla-object ent2) flag))
 (repeat (/ (length l) 3)
  (setq r (cons (list (car l) (cadr l) (caddr l)) r)
        l (cdddr l)))
 (reverse r))
 
  • 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

 

Kết quả trả về (màu đỏ) là danh sách nhưng được biểu diễn dưới dạng Variant. Từ đây, muốn chuyển qua danh sách các điểm dạng (p1 p2... pn) thì còn vài bước nữa, hơi khó hiểu với bạn >> không đơn giản để lấy giao điểm của 2 curve chỉ bằng 1 hàm như vậy.

Tặng bạn 1 hàm lấy danh sách các giao điểm của 2 curve để thấy nó cũng khá phức tạp.

 

;; Get intersection of entity1 and entity2, by flag (flags: acExtendNone ; acExtendThisEntity ; acExtendOtherEntity ; acExtendBoth).
(defun #Inter:2Ent(ent1 ent2 flag / l r)
 (setq l (vlax-invoke (vlax-ename->vla-object ent1) 'intersectwith (vlax-ename->vla-object ent2) flag))
 (repeat (/ (length l) 3)
  (setq r (cons (list (car l) (cadr l) (caddr l)) r)
        l (cdddr l)))
 (reverse r))
 

Bác lại "chơi khó" nên mình lạ hỏi :D

1. Mình thấy bác hay dùng dấu nháy ( ' ) để kết hợp 2 hàm đi liền đc với nhau thì phải >>> cách dùng thế nào bác nhỉ ???

2. Bác có thể nói sơ qua cái được biểu diễn dưới dạng Variant là như thế nào ???

Phải chăng cái (vlax-invoke) là để biến dạng Variant thành các thành phần x1, y1, z1,x2, y2, z2,x3, y3, z3... nó xếp liền nhau (mình đọc help mà thấy ghi ko rõ lắm) ?

3. Còn em (reverse)  là gì 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

Bác lại "chơi khó" nên mình lạ hỏi :D

1. Mình thấy bác hay dùng dấu nháy ( ' ) để kết hợp 2 hàm đi liền đc với nhau thì phải >>> cách dùng thế nào bác nhỉ ???

2. Bác có thể nói sơ qua cái được biểu diễn dưới dạng Variant là như thế nào ???

Phải chăng cái (vlax-invoke) là để biến dạng Variant thành các thành phần x1, y1, z1,x2, y2, z2,x3, y3, z3... nó xếp liền nhau (mình đọc help mà thấy ghi ko rõ lắm) ?

3. Còn em (reverse)  là gì nữa ... ??? :(

1). Dấu phẩy (') chẳng có nghĩa gì về mặt kết hợp mà nó để định giá 1 symbol. Chẳng hạn bạn có thể viết (setvar "osmode" 0) hoặc (setvar 'osmode 0).

2). Variant thì chắc từ từ bạn sẽ hiểu. Tôi có hiểu nhưng giải thích khó quá. Hy vọng có bạn khác giải thích rõ hơn.

3). Hàm tìm giao của bạn trả về list dưới dạng variant, còn hàm vlax-invoke trả về list kiểu này: (x1 y1 z1 x2 y2 z2... xn yn zn) >> Điều này quan trọng nè: trong visual lisp có rất nhiều hàm có chức năng gần như nhau (nhìn bề ngoài) nhưng bản chất có thể khác nhau >> cần lựa chọn hàm phù hợp để dùng.

4). Revese là hàm đảo ngược thứ tự 1 list.

@all: do bạn hiepttr đang theo lớp của KX nên tôi mạo muội giải thích vậy, các bác thâm niên đừng cười 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

4). Revese là hàm đảo ngược thứ tự 1 list.

Như vậy, dùng hàm đảo ngược Revese trong đoạn code trên có dụng ý gì bác nhỉ ?!

Và nữa...

hàm vlax-invoke còn dùng để làm gì nữa

(mình nghĩ thay cái "giống khác" vào chổ intersecwith thì cho kết quả về vấn đề khác :D )

hay nói cách khác, ngoài tham số intersecwith hàm vlax-invoke còn có tham số nào khác chă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

Như vậy, dùng hàm đảo ngược Revese trong đoạn code trên có dụng ý gì bác nhỉ ?!

Và nữa...

hàm vlax-invoke còn dùng để làm gì nữa

(mình nghĩ thay cái "giống khác" vào chổ intersecwith thì cho kết quả về vấn đề khác :D )

hay nói cách khác, ngoài tham số intersecwith hàm vlax-invoke còn có tham số nào khác chăng ???

1). Reverse để đảo list lại theo thứ tự các điểm giao, bởi các điểm trên curve cũng được sắp xếp từ startpoint đến endpoint. Nếu không quan tâm đến thứ tự thì bạn thay (reverse r)) bởi r).

2). hàm vlax-invove nói chung là để lấy property của 1 hoặc các đối tượng. Ngoài property là intersecwith thì thêm hàng trăm property khác nữa, ví dụ: color, layer, linetype,... Bạn tham khảo help nhé, tầm khoảng gần 800 lận!

  • 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

1. Dấu (') tương đương hàm quote: Returns an expression without evaluating it
2. vlax là các hàm activeX để Lisp giao tiếp với các ứng dụng khác (kể cả Acad )
Trong lập trình hướng đối tượng  (gọi tắt là OOP, object-oriented programming)
 thì mỗi đối tượng đối tượng đều có các thuộc tính (Properties) và hành vi (Methods)
(xem help phần ActiveX and VBA Reference)
- Để lấy Properties của object dùng hàm vlax-get-property
VD để lấy property Center của Circle
(setq cen (vlax-get-property obj 'Center))
- Để đặt Properties cho object dùng hàm vlax-put-property
(vlax-put-property obj 'Center cen)
- Để gọi Methods của object dùng hàm vlax-invoke-method
cú pháp (vlax-invoke-method obj method arg [arg...])
obj : đối tượng VLA
method: A symbol or string naming the method to be called

          tên hàm, có thể là symbol tức là dấu nháy đơn ' hoặc dùng kiểu chuỗi
arg: các Argument truyền cho hàm.
Tên method và Các Argument có trong help

VD tìm giao điểm của 2 object, theo help phần IntersectWith Method
RetVal = object.IntersectWith(IntersectObject, ExtendOption)
hàm này có 2 arg là IntersectObject, ExtendOption, kết quả trả về là Variant (array of doubles)
=> khi gọi hàm vlax-invoke-method sẽ có 4 arg
(setq RetVal (vlax-invoke-method obj 'IntersectWith IntersectObject ExtendOption))


- Trong help không có vlax-invoke, nhưng dùng vlax-invoke sẽ tiện hơn vì có thể dùng kiểu
của lisp thay cho kiểu variant

3.Trong help chỉ thấy định nghĩa type trong variant
Search trên net nhưng không tìm thấy định nghĩa kiểu cấu trúc variant cho lisp hoặc Autodesk, chỉ có
của MSDN (vì hơi dài nên bạn tham khảo link http://msdn.microsoft.com/en-us/library/windows/desktop/ms221627%28v=vs.85%29.aspx)
Nếu đúng như MSDN định nghĩa thì kiểu variant là kiểu biến tổng quát (để các ứng dụng khác nhau trao  đổi dữ liệu cho nhau).

struct tagVARIANT là 1 union của struct __tagVARIANT và DECIMAL  decVal,
ở đây chỉ xét struct __tagVARIANT gồm:
VARTYPE vt : kiểu biến
3 WORD chưa dùng, mục đích để size của struct tagVARIANT = 16 bytes
1 union là giá trị do VARTYPE định nghĩa, có thể là biến trực tiếp hoặc biến con trỏ (pointer) nếu có dấu * đằng trước
VD theo bài của bạn
(setq p (vla-IntersectWith a1 b1 acExtendNone))
Kết quả trả về: #<variant 8197 ...>
8197 = 8192 (vlax-vbArray ) + 5 (vlax-vbDouble )
=> giao của a1 và b1 là 1 variant kiểu (array of doubles)
hàm vlax-variant-value đọc giá trị VARTYPE là SAFEARRAY*
và ép kiểu trả về giá trị trong union là SAFEARRAY
 

  • 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

Ngày trước em học pascal có cách gán n giá trị cho n biến bằng vòng lặp, kiểu như thế này:

 

from i = 1 to n ; (giá trị n nguyên cho trước hoặc nhập từ chương trình)

    setq p = i ; (hoặc 1 biểu thức khác)

   end;

 

Như vậy ta có n biến là biến: p1 = 1; p2 = 2; p3=3....

 

Trong Autolisp thì phải viết như thế nào ạ?

 

Em đang tập viết lisp lấy thông tin các đầu mút của 1 đường PLINE.

Em cảm ơ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

Các bác cho em hỏi trong autolisp, lệnh tạo bản vẽ mới tương ứng với lệnh new trong cad thì cú pháp thế nào ? mình viết (command ".new") nhưng cad không hiể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

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

×