DXFことはじめ


　世の中には、知らずにすむのであれば、その方がよい事も多々あります。

　DXFは、間違いなく、そのうちの一つに含まれます。

　まず、名前からして、Drawing Exchange Formatなのか、Drawing Interchange Format、はたまた、Drawing Interchange Fileなのか、はっきりときまっていません。InterchangeだとしたらDXFのXはどこからきているのか、わけがわかりません(道路のInterchangeが交差しているから、その見た目からきているという説がある)。

　ただ、上記の諸説ある名前の感じからして、図面データの交換用のファイル・フォーマットらしいということがうかがえます。しかし、ここでだまされてしまうようだと、DXFとつきあう事はできません。AutoDesk社の技術者は、おそらく、データの交換のためなどということは、端から考えていません。なぜならば、DXFというのは、ほぼ、AutoCADの内部データをベチャッとダンプしただけの代物だからです。

　そのため、公式のDXFリファレンスマニュアルでさえも、所々、記述が曖昧で、ハンドル、ハードポインタ、ソフトポインタ、リアクタなどという言葉がなんの説明もなく現れ、AutoCADの実行時にしか必要ないはずのフラグにさえ言及されています（つまり、そのフラグもDXFにふくまれているこということ）。

　どうです。ここまでで、既に厭になってしまった人もいるのではないでしょうか。

　DXFについては、漫然とリファレンスマニュアルに目を通しても、理解することは困難です。DXFがAutoCADの内部データのダンプである以上、AutoCAD内部でどのように扱われているのかを推量しながら、ひもといていかなければなりません。

### DXFをのぞいてみよう

　なにか、サンプルになるDXFがあれば、テキストエディタで開いてみてください。DXFはテキストファイルなので、ヒューマンリーダブルなのです。

```
  0
SECTION
  2
HEADER
  9
$ACADVER
  1
AC1015
  9
$ACADMAINTVER
 70
    18
  9
$DWGCODEPAGE
  3
ANSI_932
  9
$INSBASE
 10
0.0
 20
0.0
 30
0.0
  :
こんな感じのデータが延々と続く。
```

　やっぱり、ヒューマンリーダブルではないですね。

　DXFは2行で一組のデータを表します。そこで、奇数行と偶数行を連結してしまいましょう。エディタのキーボード・マクロを使ってもいいですし、スクリプト言語で処理してしまってもいいです。もちろん、大事なデータだったら、コピーしてから修正しましょう。また、連結する際に、タブ区切りにしておくことをおすすめします。そうしておけば、表計算ソフトにコピペしたときに、たいていの場合、それぞれ別の列に分かれてくれますからね。

```
 0 SECTION
 2 HEADER
 9 $ACADVER
 1 AC1015
 9 $ACADMAINTVER
70     18
 9 $DWGCODEPAGE
 3 ANSI_932
 9 $INSBASE
10 0.0
20 0.0
30 0.0
 :
```

　少し、見やすくなりました。数値となにかの値の組になっているようです。このはじめの数値の方をグループコードといい、データの種類（意味）を表します。それに続く文字列がそのデータの値です。値は、文字列や整数値、実数値などがあり、その区別はグループコードが示すデータの種類で使い分けられます。

　DXFは、ちょっとした図面でも軽く数万行のデータになってしまいますが、それらはすべて、このようにグループコードと値の組で構成されています。

### AutoLISP

　EmacsがEmacsLISPの処理系であるのと同じような意味で、AutoCADはAutoLISPの処理系です。
 処理系という言葉がピンとこない場合は、特定のプログラム言語の実行環境とでも考えてください。

　はじめにDXFはAutoCADの内部データをダンプしたものだという話をしましたが、その内部データというのが、AutoLISPのデータなのです。AutoLISPの元になっているLISPというプログラム言語は、かなり歴史のあるリストデータの処理に長けた言語(ListProcesserが名前の由来)で、それ自体について語ると長くなってしまうので、ここでは、LISPの説明はしません。ただし、DXFを理解するには、AutoLISPの知識も必要になるので、ざっとでかまわないので、LISPの勉強をしておいた方が良いと思います。

　さて、DXFの方に話を戻すと、前回、DXFを見たときに、

```
 0 SECTION
 2 HEADER
 9 $ACADVER
 1 AC1015
 9 $ACADMAINTVER
70     18
 9 $DWGCODEPAGE
 3 ANSI_932
 9 $INSBASE
10 0.0
20 0.0
30 0.0
 :
```

のように、グループコードと値の組になっていました。このような、データの持ち方は、LISPでは、ドット対とかドット・ペア(表記方法に由来する呼び方)、あるいは、コンス・セル(このようなデータ構造を作るLISPの関数consに由来する呼び方)といって、

```Lisp
( 0 . SECTION)
( 2 . HEADER)
( 9 . $ACADVER)
( 1 . AC1015)
( 9 . $ACADMAINTVER)
(70 .    18)
( 9 . $DWGCODEPAGE)
( 3 . ANSI_932)
( 9 . $INSBASE)
(10 . 0.0)
(20 . 0.0)
(30 . 0.0)
   ;
```

のように表します。本来、LISPのドット対では、ドットを挟んだ左右の値は、どのような型であってもかまわないのですが、DXFでは、左側は必ずグループコードという16bitの範囲内の整数になっています。

　以降、素のDXFの表記ではなく、このコンス・セルでの表記を用います。

### セクション
　DXFの先頭のコンスセルが、

```Lisp
(0 . SECTION)
```

だったのを、思い出してください。そして、そこからググッと下の方を探すと、

```Lisp
(0 . ENDSEC)
```

というセルが見つかります。

　この(0 . SECTION)と(0 . ENDSEC)の間を、セクションといって、DXF内での最も大きなデータの固まりになっています。 また、DXFファイルの先頭に戻ってみましょう。

```Lisp
(0 . SECTION)
(2 . HEADER)
```

　通常のDXFファイルであれば、２番目のコンスセルは、(2 . HEADER)になっているはずです。 これは、最初のセクションが”HEADER”という名前のセクションであることを表しています。

　現在のDXFファイルは、

1. HEADER
2. CLASSES
3. TABLES
4. BLOCKS
5. ENTITIES
6. OBJECTS
7. THUMBNAILIMAGE

の、７つのセクションからできています、ただし、THUMBNAILIMAGEセクションは、省略可能なので、存在しない場合もあります。また、古いAutoCAD200(R12まで)で作られたDXFファイルの場合、CLASSESセクションとOBJECTSセクションがありません。

　前述のように、セクションはDXFのもっとも大きなデータのくくりなので、これらのセクションに含まれないコンスセルはありません。そのため、セクションの中身を省略すると、DXFファイルは、

```Lisp
(0 . SECTION)
(2 . HEADER)
  ;
(0 . ENDSEC)
(0 . SECTION)
(2 . CLASSES)
  ;
(0 . ENDSEC)
(0 . SECTION)
(2 . TABLES)
  ;
(0 . ENDSEC)
(0 . SECTION)
(2 . BLOCKS)
  ;
(0 . ENDSEC)
(0 . SECTION)
(2 . ENTITIES)
  ;
(0 . ENDSEC)
(0 . SECTION)
(2 . OBJECTS)
  ;
(0 . ENDSEC)
(0 . SECTION)
(2 . THUMBNAILIMAGE)
  ;
(0 . ENDSEC)
```
という、形になっています。