2020年11月4日 星期三

Autolisp初學感想與筆記

工作上一直有在使用AutoCAD處理圖檔修改與輸出
其實一直很想學這個Autolisp程式語言
因為學會後,可以讓一些作業從每一筆都人工處理
變成一組指令就可以完成
大大減少工作的時間
只是...工作超過10年裡一直沒去學
與其說工作繁忙,不如說難以「輕鬆」跨過那古老,很不一樣的語法
畢竟,這段期間我也多學會了python
但autolisp的教學網頁看沒幾頁就覺得看不太下去 
跟天書一樣,看不懂啊 XDXD

不過,今年也總算跨出了這第一步
因為,遇到了要一口氣改近200張的圖檔的情況
雖然動作很簡單,只要打開圖檔,選擇固定不要的元件,然後刪除後存檔
做這麼無聊的動作200次,還是感覺很浪費時間
不然就拿來學autolisp吧
上呀

不想講歷史了,直接進主題,Autolisp的撰寫
最簡單的作法就是直接在autocad的指令行裡輸入
格式為(指令 引數1 引數2)
用Hello world範例的來說
就是這樣寫
(setq word "Hello world!")
就可以看到指令行裡顯示出Hello world!!的字樣



""引號裡的就是字串,而數字就是直接給就行
計算的話,則要這樣寫
(* 3 2)
可以得到答案6
比較複雜的四則運算 5*2+3的話要寫成這樣
(+ (* 5 2) 3)
如果要寫ans = 5*2+3,就要變成
(setq ans(+ (* 5 2) 3))
每一次的指令,就要用括號包起來
看起來真的很不直觀,很不清爽
很不習慣
不過這就是它的規則

if else的寫法也是不習慣
autolisp上,如果if或else區的程式碼超過一行
要加上progn包住
換言之,要寫如果a大於b
然後連續處理兩行
c等於a * 2
d等於a * 5
要寫成
(if (> a b)
  (progn
    (setq c(* a 2))
    (setq d(* a 5))
  )
)

如果那兩行不加progn包住
那第二行(setq d(* a 5))就會變成else執行
對,就變成a小於等於b時執行
一開始沒看清楚規則,想當然爾寫時
就覺得奇怪,怎麼條件達成時第二行都不執行咧
果然說明要看清楚啊

然後function回傳值的問題也是差不多
為了求快速解決問題,當然是直接上網找參考程式來改比較快
參考來程式碼沒有回傳值
只有條件判斷錯誤算失敗會產生提示,寫成
(defun sample ()
  (if (= a b)
    (progn
    (do_something)
    (prompt "成功")
    )
  ;else的執行
  (prompt "失敗")
  )
 (princ)
)

我在改寫成有回傳值時
一時改不出來,發現都沒有值回傳出來
查了一下可以在princ後加上變數就有輸出
(defun sample ()
(if (= 3 3)
(setq value(* 3 3))
(prompt "失敗")
)
(princ value)
)

可是這樣寫
就會多一個值的顯示在命令列上

是可以用啦
但就是顯示很奇怪的
後來才知道,不使用prompt這功能就正常了
但要return的部分還是要加變數
(defun sample_right()
 (if (> 3 2)
  (setq d 3);這邊不能單純的運算,要加個變數給產生的數值,文字,物件之類的
  (princ "失敗")
 )
)

目前遇到語法上的麻煩到這裡
接下來大多是ssget之類autolisp專用指令的引數使用
還有vlx-object的特殊物件的屬性等問題了
先抄別人可用的來暫時應付
再來慢慢了解那個語法到底是啥鬼

要執行autolisp的話不用編譯成執行檔
只要用純文字檔撰寫,並將存檔的副檔名為lsp的話
就可以在AutoCAD使用appload的指令載入使用
不過,單純寫成函數是不能當指令使用,要繼續包著刮號執行
想要直接打出do_func就能執行的話
函數要這樣寫
(defun c:do_func
  ;函數內容
)

這樣就成啦

但另一個使用上的麻煩就接著來啦
新開一張圖,就是要開appload再載入一次才能用
有沒有辦法能一直用,也就是預設載入呢?
Autodesk官網上有解答,自動載入並執行 AutoLISP 常式
只要照做,開什麼檔案都會預設載入

總算是入門了
還真的不是很好學啊
學習的過程中,腦袋不知道打結了幾次
還好現在有網路,可以馬上找其它人提供的範例與解答
大多的問題很快就迎刃而解
執行程式省下來的時間,繼續拿來學習吧

沒有留言: