[AutoLISP X ChatGPT] LWポリラインを3Dポリラインに変換するオリジナルコマンドを作成

AutoLisp

こんにちは、ISDです。

前回の記事の通り、
ChatGPTAutoLISP のプログラムを書くことが出来そうなので、色々と試していきたいと思います。

LWポリラインを3Dポリラインに変換する

今回のお題はこれです

「LWポリラインを3Dポリラインに変換する」

3Dモデリングをやっていると、LWポリライン3Dポリラインに変換したいという場面が多々あります。
だが、しか~し!
AutoCAD 標準のコマンドではLWポリライン3Dポリラインに変換する機能がないのです。
当然そのくらいの機能あるだろと思っていたのですが、ないのです……
(いや、私が知らないだけかも知れませんが……その時は AUTODESK さんごめんなさい。)

ChatGPTでオリジナルコマンドを作成する

では、ChatGPT にお願いしてみようと思います。

投げたプロンプトはこちら

AutoCADで 以下の仕様のオリジナルコマンドを作成したい。
使用言語はAutolisp

###
・LWPOLYLINE を 3DPOLYLINE に変換する。
・各頂点の座標は WCS に変換する。

待つこと数分、ChatGPT の返答がこちら

以下のような AutoLISP で実現できます。
LWPOLYLINE を選択 → 各頂点を WCS座標 に変換して 3DPOLYLINE を作成 → 元の LWPOLYLINE は削除します。

;;; LWPOLYLINE → 3DPOLYLINE(頂点座標は WCS)
;;; コマンド名:LW2PL3D

(defun LW2PL3D_one (ent / ed elev flag70 closed pts p2d ptEcs ptWcs props)

  ;; エンティティデータ取得
  (setq ed (entget ent))

  ;; ポリラインの標高(デフォルト 0.0)
  (setq elev (cond ((assoc 38 ed) (cdr (assoc 38 ed)))
                   (T 0.0)))

  ;; 閉じているかどうか
  (setq flag70 (cdr (assoc 70 ed)))
  (setq closed (/= 0 (logand flag70 1)))   ; ビット1が閉じている

  ;; 共通プロパティ(レイヤ・色・線種・線の太さなど)をコピー
  (setq props '())
  (if (assoc 8 ed)   (setq props (cons (assoc 8 ed) props)))   ; レイヤ
  (if (assoc 62 ed)  (setq props (cons (assoc 62 ed) props)))  ; 色
  (if (assoc 6 ed)   (setq props (cons (assoc 6 ed) props)))   ; 線種
  (if (assoc 370 ed) (setq props (cons (assoc 370 ed) props))) ; 線の太さ
  (setq props (reverse props))

  ;; 頂点座標を WCS に変換して取得
  (setq pts '())
  (foreach d ed
    (if (= (car d) 10)                    ; LWPOLYLINE の頂点 (x y)
      (progn
        (setq p2d  (cdr d))               ; (x y)
        (setq ptEcs (list (car p2d) (cadr p2d) elev)) ; ECS 上の 3D点
        (setq ptWcs (trans ptEcs ent 0))  ; ECS → WCS に変換
        (setq pts (cons ptWcs pts))
      )
    )
  )
  (setq pts (reverse pts))

  ;; 3DPOLYLINE 作成
  (if (> (length pts) 0)
    (progn
      ;; POLYLINE ヘッダ(3Dポリライン)
      (entmake
        (append
          (list
            (cons 0   "POLYLINE")
            (cons 100 "AcDbEntity"))
          props
          (list
            (cons 100 "AcDb3dPolyline")
            (cons 66  1)                  ; 頂点が続く
            (cons 10  (list 0.0 0.0 0.0)) ; ダミー頂点
            (cons 70  (if closed 9 8))    ; 8=3Dポリライン, +1=閉じ
          )
        )
      )

      ;; 各頂点の VERTEX
      (foreach p pts
        (entmake
          (append
            (list
              (cons 0   "VERTEX")
              (cons 100 "AcDbEntity"))
            props
            (list
              (cons 100 "AcDbVertex")
              (cons 100 "AcDb3dPolylineVertex")
              (cons 10  p)
              (cons 70  32)               ; 3Dポリライン頂点
            )
          )
        )
      )

      ;; SEQEND
      (entmake
        (append
          (list
            (cons 0   "SEQEND")
            (cons 100 "AcDbEntity"))
          props
        )
      )

      ;; 元の LWPOLYLINE を削除
      (entdel ent)
    )
  )

  (princ)
)

(defun c:LW2PL3D (/ *error* oldcmdecho ss i ent)

  (defun *error* (msg)
    (setvar "cmdecho" oldcmdecho)
    (if (and msg
             (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
        )
      (princ (strcat "\nError: " msg))
    )
    (princ)
  )

  (setq oldcmdecho (getvar "cmdecho"))
  (setvar "cmdecho" 0)

  (if (setq ss (ssget '((0 . "LWPOLYLINE"))))
    (progn
      (repeat (setq i (sslength ss))
        (setq ent (ssname ss (setq i (1- i))))
        (LW2PL3D_one ent)
      )
    )
    (prompt "\nLWPOLYLINE を選択してください。")
  )

  (*error* nil)
  (princ)
)

使い方

  1. 上記コードを LISP ファイルに保存してロードする。
  2. コマンドラインで LW2PL3D と入力。
  3. 変換したい LWPOLYLINE を選択。

選択した LWPOLYLINE が、各頂点座標を WCS に変換した 3DPOLYLINE に置き換わります。
元の線を残したい場合は、関数内の (entdel ent) 行をコメントアウトしてください。

では、実際動くのか試してみましょう。

ChatGPT作成のコマンドを実行してみる

では、ChatGPT が作ってくれたコマンドが問題なく動作するのか、実際に試してみましょう。

まず、ChatGPT が書いたコードを LW2PL3D.lsp という名前(名前は別に何でもよい)で保存します。
そして、LW2PL3D.lsp のファイルを、作図領域にドラッグ&ドロップします。
もしくは、ChatGPT が書いたコードをコマンドラインにコピー&ペーストでも OK です。

すると ChatGPTが作ってくれたLW2PL3D というオリジナルコマンドが定義されます。

取りあえず、適当に作図したLWポリラインを変換してみます。

そして、コマンドラインから LW2PL3D と入力

おお、出来てます。
次に、LWポリラインを3D回転した状態でも試してみます。

結果は、

これも、問題なさそうですね。
頂点の座標を WCS に変換しているので、LWポリラインが3D回転していても大丈夫なようです。

まとめ

ChatGPT AutolLISPLWポリライン3Dポリラインに変換するオリジナルコマンドを作成してもらうことができました。

しかも、一発で動作するコードを出してきたのは予想外でした。
まあ、毎回違うコード出してくるようなので、今回たまたま上手くいっただけなのかもしれませんが…

実は、私が一番初めに AutoLISP で作ったオリジナルコマンドも「LWポリラインを3Dポリラインに変換する」 でした。
当時は、慣れない AutoLISP に悪戦苦闘しながら2日くらいかけて作った覚えがあります。
それが今、ChatGPT が数分で作ってしまう…
何というか…

テクノロジーの進歩、すげぇ~!

コメント

タイトルとURLをコピーしました