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

Học AutoLisp

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

Thanks alot !

Chúc bác có 1 kỳ nghỉ cuối tuần vui vẻ !!!

Hề hề hề

Ở ví dụ của bác, nếu dùng:

(setq l (vlax-safearray->list (vlax-variant-value (vla-intersectwith a1 b1 acextendnone))))

sẽ tương đương với:

(setq l (vlax-invoke a1 'intersectwith b1 0))

Từ đó có thể hiểu nôm na như sau:

Hàm (vla-intersectwith ......) trả về một giá trị được định nghĩa là Variant . Giá trị này được sắp xếp theo một safearray. (theo mình hiểu nôm na tức là một ma trận dạng chữ nhật chứa các tọa độ của các giao điểm). Và để có ma trận này phải sử dụng hàm (vlax-variant-value ....). Từ ma trận này có thể chuyển nó thành một list các tọa độ này theo một trật tự định trước bởi hàm (vlax-safearaay->list ...)

Trong khi hàm (vlax-invoke ......) có khả năng trả trực tiếp về một list các tọa độ này.

Sau khi đã có cái list các tọa độ này thì việc chuyển nó thành list các point sẽ không qua khó nửa và bác DoanVanHa đã chỉ ra một cách rồi đó.

Có nhiều nguyên nhân để người ta tạo ra các hàm trung gian như vậy, nhưng theo mình hiểu thì tác dụng chính của nó là để có thể giao tiếp được với các phần mềm khác.

Với cái ngữ học mót như mình thì chả khoái mấy thằng cò như vầy, cứ chơi kiểu (vlax-invoke ..... ) là hay hơn . Mặc dù muốn vậy nhưng bản thân cái thằng (vlax-invoke .... ) này cũng chả hề đơn giản bởi nó yêu cầu các argument khác nhau đối với mỗi một method. Để thuộc và nhớ hết những thằng này đối với mình cũng là quá sức rồi.

Tìm hiểu về nó thì trong Help của CAD cũng có đề cập đấy. nhưng cái vốn tiếng Anh của mình còn hơi lùn nên cũng chửa thấm được bao nhiêu nên lại càng khó nhớ. nếu bác quan tâm thì cứ chịu khó mở Help ra cày, ắt sẽ có ngày vỡ thôi.

Hề hề hề, mạn phép các bác, múa may mấy đường mèo quào, mong các bác không chấp trá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

Ví dụ hàm này tạo 1 drawing mới:

(vla-add (vla-get-documents (vlax-get-acad-object)) "acad.dwt")

Thanks, giờ em muốn tạo ra và có thể thao tác luôn trên bản vẽ mới này thì sao bác, vì hàm trên tạo ra bản mới nhưng nó vẫn thao tác trên bản vẽ hiện hành  :)

sao hàm vla-addvla-get-documents em tìm trong help của autocad 2007 không thấy bác nhỉ?

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 anh ơi cho em hỏi, nếu em muốn xuất Text ra màn hình là chữ nghiêng thì phải sửa chỗ nào trong đoạn code dưới đây? cảm ơn các anh!

(command "text" "j" "tl" A "" (strcat "(" (rtos (/ (* (GETVAR "AREA") 10) 10) 2 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

Trong đoạn này thì tạm thời mình chịu :D

Song, bạn có thể thay đổi góc nghiêng text (so với phương đứng, tính bằng radian) trong mã dfx 50 của textstyle

p/s: hoặc chọn tuỳ chọn italic trong hộp thoại textstyle (nếu có)

 

VD: chữ nghiêng 75 độ theo phương ngang

(setq e_lst (entget (tblobjname "style" (getvar 'textstyle))))

(entmod (subst (cons 50 0.261799) (setq old (assoc 50 e_lst)) e_lst))

(command "text" "j" "tl" A "" (strcat "(" (rtos (/ (* (GETVAR "AREA") 10) 10) 2 1) ")"))

;;tra lai:

(entmod (subst old (assoc 50 e_lst) e_lst))

(setq e_lst (entget (tblobjname "style" (getvar 'textstyle))))
(entmod (subst (cons 50 0.261799) (setq old (assoc 50 e_lst)) e_lst))
(command "text" "j" "tl" A "" (strcat "(" (rtos (/ (* (GETVAR "AREA") 10) 10) 2 1) ")"))
;;tra lai:
(entmod (subst old (assoc 50 e_lst) e_lst))
(setq e_lst (entget (tblobjname "style" (getvar 'textstyle))))
(entmod (subst (cons 50 0.261799) (setq old (assoc 50 e_lst)) e_lst))
(command "text" "j" "tl" A "" (strcat "(" (rtos (/ (* (GETVAR "AREA") 10) 10) 2 1) ")"))
;;tra lai:
(entmod (subst old (assoc 50 e_lst) e_lst))
  • 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ác anh cho em hỏi là khi viết code cho lệnh qleader thì làm sao để mình lựa chọn được các lựa chọn khác nhau trong hộp thoại settings nhỉ. 121048_20140116_094013.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

các anh cho em hỏi là khi viết code cho lệnh qleader thì làm sao để mình lựa chọn được các lựa chọn khác nhau trong hộp thoại settings nhỉ. 

Namvanvo tham khảo link dưới đây để thấy rằng Qleader settings by lisp là tương đối phức tạp:

http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/Qleader-settings-by-lisp/m-p/844428#M70086

  • 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

Namvanvo tham khảo link dưới đây để thấy rằng Qleader settings by lisp là tương đối phức tạp:

http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/Qleader-settings-by-lisp/m-p/844428#M70086

Đúng là khá phức tạp, k dễ ăn cơm với thịt  :D , chỗ này có biến hệ thống thì ngon, nhưng lại không tìm ra.

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

QLeader là lệnh dành cho người dùng AutoCAD. Khi viết Lisp bạn nên sử dụng lệnh Leader, nó cũng có nhiều tùy chọn và phù hợp hơn với AutoLisp.

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

Namvanvo nghiên cứu lisp này nhé!


;by Juerg Menzi
;----- Get Qleader.
(defun GetQleader ( / CurDic CurItm RetVal)
 (if (setq CurDic (dictsearch (namedobjdict) "AcadDim"))
  (progn
   (foreach memb '(3 40 60 61 62 63 64 65 66 67 68 69 70 71 72 170 340)
    (if (setq CurItm (assoc memb CurDic)) (setq RetVal (cons CurItm RetVal))))
   (reverse RetVal))))
;----- Set Qleader
(defun SetQleader (Lst / DicLst)
 (dictremove (namedobjdict) "AcadDim")
 (setq DicLst (append '((0 . "XRECORD") (100 . "AcDbXrecord") (90 . 990106)) Lst))
 (dictadd (namedobjdict) "AcadDim" (entmakex DicLst))
 (princ))
;-Group codes for settings: '((3 . "") 
; User arrowhead block name (default="") (40 . 0.0) 
; Default text width (default=0.0) (60 . 0) 
; Annotation type (default=0): 
; 0=MText 
; 1=Copy object 
; 2=Tolerance 
; 3=Block 
; 4=None (61 . 0) 
; Annotation reuse (default=0): 
; 0=Off 
; 1=On (62 . 1) 
; Left attachment point (default=1): 
; 0=Top of top line 
; 1=Middle of top line 
; 2=Middle of multiline text 
; 3=Middle of bottom line 
; 4=Bottom of bottom line (63 . 3) 
; Right attachment point (default=3): 
; 0=Top of top line
; 1=Middle of top line 
; 2=Middle of multiline text 
; 3=Middle of bottom line 
; 4=Bottom of bottom line (64 . 0) 
; Underline bottom line (default=0): 
; 0=Off ; 1=On (65 . 0) 
; Use splined leader line (default=0): 
; 0=Off ; 1=On (66 . 0) 
; No limit on points (default=0): 
; 0=Off 
; 1=On (67 . 3) 
; Maximum number of points (default=3) (68 . 1) 
; Prompt for MText width (word wrap) (default=1): 
; 0=Off 
; 1=On (69 . 0) 
; Always left justify (default=0): 
; 0=Off 
; 1=On (70 . 0) 
; Allowed angle, first segment (default=0): 
; 0=Any angle 
; 1=Horizontal 
; 2=90° 
; 3=45° 
; 4=30° 
; 5=15° (71 . 1)
; Allowed angle, second segment (default=0): 
; 0=Any angle 
; 1=Horizontal 
; 2=90° 
; 3=45° 
; 4=30° 
; 5=15° (72 . 0) 
; Frame text (default=0): 
; 0=Off 
; 1=On (170 . 0) 
; Active tab for settings (default=0): 
; 0=Annotation 
; 1=Leader Line & Arrow 
; 2=Attachment 
; (340 . ID) 
; Object ID for annotation reuse 
 

  • 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

em mới vào diễn đàn và mong muốn học list. . . thấy mấy bác thảo luận ầm ầm . . .em cũng ham hố và sàm sồ . . . 

mong các bác chiếu cố và giúp đỡ  :D  :D  :D  :D  :D  :D  :D  :D  :D  :D  :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

Namvanvo nghiên cứu lisp này nhé!

 Thank Bác Hà, em sẽ tiếp tục nghiên cứu cái lisp này sau, level hiện tại thì chưa đủ để hiểu được nó  :mellow:

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 co thể hướng dẫn em viet doan mã lisp nhu hinh vẽ dưới ko a

122369_33.jpg

 

 
với yêu cầu chiều dài lỗ taro có thể xoay được...thao tác trên dòng command như sau: sau khi nhập lệnh M10 , yêu cầu chọn điểm chuẩn (1)  sau đó là chọn điểm (2) để chọn hướng quay...chều dài lỗ ta rô dài hay ngắn sẽ phụ thuộc vào điểm 2.. nếu khoảng cách từ điểm (1) tới (2) >25 thì sẽ vẽ ra hình như hình dưới. rất mong su giúp đỡ của anh em...122369_11_2.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

Em sửa lại xíu cho chuẩn:


Xin lỗi các Bác vì em hỏi cái này ở chỗ này không biết có đúng không? (Em có học theo mấy bài đầu của bac Nguyen Hoanh tưởng đâu tự làm được nhưng vẫn


còn nhiều cục gạch quá nên chịu phải hỏi các sư huynh)


Là vì em tìm trên cadviet có nhiều lisp tính diện tích nhưng không cái  nào là đầy đủ đối với công việc em sử dụng (được cái này thì mất cái kia). Công việc em


(tính diện tích các mcn) cần như thế này ạ :


1. Chọn tập tin lưu số liệu


2. Load lisp, đánh lệnh 


3. Nhập tỉ lệ


4. Chọn font, chiều cao text diện tích xuất ra


5. Khi pick vào vùng kín để tính diện tích (gồm cả line và pline) thì đồng thời bo đối tượng như lệnh boundary và xuất ra text diện tích


6. Tính diện tích các hình tiếp theo chỉ cần chọn điểm giữa (bước 5) mà không phải lặp lại bước 1,2,3,4.


7. Chỉ dừng lại khi ấn esc


Em mong có sư huynh nào viết giúp em còn nếu như không muốn cho em con cá mà cho cần câu thì chỉ cho em cách viết (chỉ tỉ mỉ thì em mới làm được, vì em thì chỉ mới trình độ nhập môn thôi các sư huynh ạ). Cám ơn mấy sư huynh trướ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

đây là bản vẽ chi tiết. xin lỗi mạng yếu ko up được file dwg được.122369_22.jpg

Hề hề hề,

. Nguyen bd1 đã biết nhiều về lisp rồi cơ mà, Việc viết lisp để vẽ được như mô tả đâu phải quá khó khăn với khả năng của nguyenbd1 nhỉ. Bạn mắc chỗ nào khi viết lisp này? Cái lisp như vầy tuy không quá khó nhưng hơi mất công tỷ mỷ chút chút thôi. Bạn cứ mạnh dạn làm thử đi, vấp đâu gỡ đó sẽ nhanh hơn 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

Hề hề hề,

. Nguyen bd1 đã biết nhiều về lisp rồi cơ mà, Việc viết lisp để vẽ được như mô tả đâu phải quá khó khăn với khả năng của nguyenbd1 nhỉ. Bạn mắc chỗ nào khi viết lisp này? Cái lisp như vầy tuy không quá khó nhưng hơi mất công tỷ mỷ chút chút thôi. Bạn cứ mạnh dạn làm thử đi, vấp đâu gỡ đó sẽ nhanh hơn bạn ạ.

anh bình cứ nói thế. em moi chi biết dùng lisp ng ta thi gioj thôi. anh chiếu cố giúp em với ạ. thank anh trướ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

 

Em sửa lại xíu cho chuẩn:

Xin lỗi các Bác vì em hỏi cái này ở chỗ này không biết có đúng không? (Em có học theo mấy bài đầu của bac Nguyen Hoanh tưởng đâu tự làm được nhưng vẫn

còn nhiều cục gạch quá nên chịu phải hỏi các sư huynh)

Là vì em tìm trên cadviet có nhiều lisp tính diện tích nhưng không cái  nào là đầy đủ đối với công việc em sử dụng (được cái này thì mất cái kia). Công việc em

(tính diện tích các mcn) cần như thế này ạ :

1. Chọn tập tin lưu số liệu

2. Load lisp, đánh lệnh 

3. Nhập tỉ lệ

4. Chọn font, chiều cao text diện tích xuất ra

5. Khi pick vào vùng kín để tính diện tích (gồm cả line và pline) thì đồng thời bo đối tượng như lệnh boundary và xuất ra text diện tích

6. Tính diện tích các hình tiếp theo chỉ cần chọn điểm giữa (bước 5) mà không phải lặp lại bước 1,2,3,4.

7. Chỉ dừng lại khi ấn esc

Em mong có sư huynh nào viết giúp em còn nếu như không muốn cho em con cá mà cho cần câu thì chỉ cho em cách viết (chỉ tỉ mỉ thì em mới làm được, vì em thì chỉ mới trình độ nhập môn thôi các sư huynh ạ). Cám ơn mấy sư huynh trước

.Hề hề hề,

Bạn hãy chọn lấy cái lisp gần đạt với yêu cầu của bạn nhất và post lên, Nói rõ chỗ nào cần sửa và cần sửa ra sao, cũng như cần bổ sung thêm những gì, như vậy sẽ thuận lợi hơn cho người muốn giúp bạn. Nên post ngay ở topic có chứa lisp đó để tiện theo dõ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

anh bình cứ nói thế. em moi chi biết dùng lisp ng ta thi gioj thôi. anh chiếu cố giúp em với ạ. thank anh trước.

Hề hề hề, 

Thực ra thì mình đang hơi bù đầu vì công việc làm hàng cho đợt Tết nguyên đán nên chưa rảnh để viết ngay được. Nếu bạn có thể chờ thì thư thư vài hôm nếu chưa có người viết mình sẽ viết nhé. Không khó đâu, chỉ hơi loằng ngoằng khi xác định các điểm chốt thôi do cái đường chuẩn nó không nằm ngay ngắn. Bạn cứ thử sẽ thấy, y như khi vẽ tay thôi mà.

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

Hề hề hề, 

Thực ra thì mình đang hơi bù đầu vì công việc làm hàng cho đợt Tết nguyên đán nên chưa rảnh để viết ngay được. Nếu bạn có thể chờ thì thư thư vài hôm nếu chưa có người viết mình sẽ viết nhé. Không khó đâu, chỉ hơi loằng ngoằng khi xác định các điểm chốt thôi do cái đường chuẩn nó không nằm ngay ngắn. Bạn cứ thử sẽ thấy, y như khi vẽ tay thôi mà.

cảm ơn anh. e chờ su giúp đỡ của anh

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

Patpat lại khích tướng rồi. Xin giới thiệu phần tiếp theo để mọi người khỏi phải chờ, hy vọng là nó có ích.

 

Phần 4:

* Các phần trước, chúng ta đã thực hành được với lệnh lisp tính diện tích của một đối tượng. Phần này, chúng ta sẽ đi vào cải tiến để lệnh tính diện tích sẽ áp dụng cho một tập đối tượng được chọn của chúng ta.

 

* Trong AutoLisp tập đối tượng được lưu trong biến kiểu tập chọn. Với lệnh (ssget), có thể tạo ra một tập chọn chứa các đối tượng chúng ta chọn. Với lệnh (ssname ss index) chúng ta sẽ lấy được entname đối tượng thứ index trong tập đối tượng ss. lệnh (sslength ss) trả về số đối tượng trong tập chọn.

 

* Tính diện tích của một tập đối tượng, ta sẽ tính diện tích của từng đối tượng trong tập này và cộng lại với nhau. Để làm được như vậy, chúng ta sẽ làm một hàm lặp như sau:

(repeat sodoituong

(setq

ent_ht (ssname ssdt index)

index (+ index 1)

dientich (tinhdientich_one ent_ht)

tongdientich (+ tongdientich dientich)

)

Vòng lặp này sẽ quét qua tất cả các đối tượng và cộng dồn diện tích của đối tượng hiện tại vào diện tích tổng. Trong đoạn mã trên, biến sodoituong chứa số đối tượng có trong tập chọn. index là biến chứa chỉ số của đối tượng hiện tại (index có giá trị từ 0 đến sodoituong-1). ent_ht là tên của đối tượng hiện tại. tinhdientich_one là hàm tính diện tích của một đối tượng được chỉ định, hàm này có được bằng cách gom 2 dòng lệnh của phần trước lại với nhau là: (command ".area" "o" ent)(setq dientich (getvar "area")). Tongdientich chính là diện tích của tất cả các đối tượng, giá trị này có được nhờ cộng dồn tất cả các giá trị của biến dientich lại với nhau.

 

* Chương trình tính diện tích sẽ tiếp tục được cải tiến như sau:

--------------------Gốc (xin nhắc lại phần trước):

(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 tap doi tuong vua roi la: ")

(princ dientich)

(princ "\nm2")

(princ)

)

 

--------------------Cải tiến (màu xám là đoạn code bỏ đi, màu xanh là đoạn code thêm mới):

(defun c:tdt( / sel ent dientich)

(princ "\nChao cadviet")

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

(setq ssdt (ssget))

;(setq ent (car sel))

(defun tinhdientich_one(ent)

(command ".area" "o" ent)

(setq dientich (getvar "area"))

)

; khởi tạo các biến

(setq

sodoituong (sslength ssdt)

index 0

tongdientich 0.0

)

 

; vòng lặp quét qua các đối tượng

(repeat sodoituong

(setq

ent_ht (ssname ssdt index)

index (1+ index)

dientich (tinhdientich_one ent_ht)

tongdientich (+ tongdientich dientich)

)

)

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

;(princ dientich)

;in tổng diện tích

(princ tongdientich)

(princ "\nm2")

(princ)

)

 

* Như vậy, chúng ta đã tạo được một đoạn code tính diện tích của một tập đối tượng. Tuy nhiên, đoạn code này hơi rườm rà, do có một lệnh định nghĩa hàm defun tinhdientich_one nằm ngay giữa đoạn code. Bây giờ, chúng ta sẽ làm sạch lại đoạn code trên bằng cách sắp xếp lại mà không thay đổi bất cứ ý nghĩa của một mã nào:

(defun c:tdt( / sel ent dientich)

 

;định nghĩa hàm tính diện tích 1 đối tượng

(defun tinhdientich_one(ent)

(command ".area" "o" ent)

(setq dientich (getvar "area"))

)

 

; viết lời chào và chọn đối tượng

(princ "\nChao cadviet")

(setq ssdt (ssget))

 

; khởi tạo các biến

(setq

sodoituong (sslength ssdt)

index 0

tongdientich 0.0

)

 

; quét qua tất cả các đối tượng trong tập chọn, tính diện tích và cộng dồn diện tích

(repeat sodoituong

(setq

ent_ht (ssname ssdt index)

index (1+ index)

dientich (tinhdientich_one ent_ht)

tongdientich (+ tongdientich dientich)

)

)

 

; xuất kết quả ra màn hình

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

(princ tongdientich)

(princ "\nm2")

(princ)

)

 

--------------------------------------------------------------------------------------------

Phần tiếp theo sẽ trình bày phần tinh chỉnh code để:

- kết xuất kết quả ra đối tượng text

- lọc các đối tượng được chọn

- ẩn các đoạn text trung gian.

 

Cảm ơn các bạn vẫn đang theo dõ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

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

×